diff --git a/src/poetry/packages/locker.py b/src/poetry/packages/locker.py index e57e60b83b7..6225c17af9a 100644 --- a/src/poetry/packages/locker.py +++ b/src/poetry/packages/locker.py @@ -24,6 +24,7 @@ from poetry.core.version.markers import parse_marker from poetry.core.version.requirements import InvalidRequirement from tomlkit import array +from tomlkit import comment from tomlkit import document from tomlkit import inline_table from tomlkit import item @@ -47,6 +48,11 @@ from poetry.repositories import Repository logger = logging.getLogger(__name__) +_GENERATED_IDENTIFIER = "@" + "generated" +GENERATED_COMMENT = ( + f"This file is automatically {_GENERATED_IDENTIFIER} by Poetry and should not be" + " changed by hand." +) class Locker: @@ -398,6 +404,7 @@ def set_lock_data(self, root: Package, packages: list[Package]) -> bool: del package["files"] lock = document() + lock.add(comment(GENERATED_COMMENT)) lock["package"] = package_specs if root.extras: diff --git a/tests/packages/test_locker.py b/tests/packages/test_locker.py index 0e79817d4f3..0b7233544cf 100644 --- a/tests/packages/test_locker.py +++ b/tests/packages/test_locker.py @@ -17,6 +17,7 @@ from poetry.core.semver.version import Version from poetry.factory import Factory +from poetry.packages.locker import GENERATED_COMMENT from poetry.packages.locker import Locker from tests.helpers import get_dependency from tests.helpers import get_package @@ -81,7 +82,9 @@ def test_lock_file_data_is_ordered(locker: Locker, root: ProjectPackage): with locker.lock.open(encoding="utf-8") as f: content = f.read() - expected = """\ + expected = f"""\ +# {GENERATED_COMMENT} + [[package]] name = "A" version = "1.0.0" @@ -155,20 +158,22 @@ def test_lock_file_data_is_ordered(locker: Locker, root: ProjectPackage): [metadata.files] A = [ - {file = "bar", hash = "123"}, - {file = "foo", hash = "456"}, - {file = "baz", hash = "345"}, + {{file = "bar", hash = "123"}}, + {{file = "foo", hash = "456"}}, + {{file = "baz", hash = "345"}}, ] B = [] git-package = [] url-package = [] -""" +""" # noqa: E800 assert content == expected def test_locker_properly_loads_extras(locker: Locker): - content = """\ + content = f"""\ +# {GENERATED_COMMENT} + [[package]] name = "cachecontrol" version = "0.12.5" @@ -196,7 +201,7 @@ def test_locker_properly_loads_extras(locker: Locker): [metadata.files] cachecontrol = [] -""" +""" # noqa: E800 locker.lock.write(tomlkit.parse(content)) @@ -213,7 +218,9 @@ def test_locker_properly_loads_extras(locker: Locker): def test_locker_properly_loads_nested_extras(locker: Locker): - content = """\ + content = f"""\ +# {GENERATED_COMMENT} + [[package]] name = "a" version = "1.0" @@ -223,7 +230,7 @@ def test_locker_properly_loads_nested_extras(locker: Locker): python-versions = "*" [package.dependencies] -b = {version = "^1.0", optional = true, extras = "c"} +b = {{version = "^1.0", optional = true, extras = "c"}} [package.extras] b = ["b[c] (>=1.0,<2.0)"] @@ -237,7 +244,7 @@ def test_locker_properly_loads_nested_extras(locker: Locker): python-versions = "*" [package.dependencies] -c = {version = "^1.0", optional = true} +c = {{version = "^1.0", optional = true}} [package.extras] c = ["c (>=1.0,<2.0)"] @@ -259,7 +266,7 @@ def test_locker_properly_loads_nested_extras(locker: Locker): "a" = [] "b" = [] "c" = [] -""" +""" # noqa: E800 locker.lock.write(tomlkit.parse(content)) @@ -293,7 +300,9 @@ def test_locker_properly_loads_nested_extras(locker: Locker): def test_locker_properly_loads_extras_legacy(locker: Locker): - content = """\ + content = f"""\ +# {GENERATED_COMMENT} + [[package]] name = "a" version = "1.0" @@ -303,7 +312,7 @@ def test_locker_properly_loads_extras_legacy(locker: Locker): python-versions = "*" [package.dependencies] -b = {version = "^1.0", optional = true} +b = {{version = "^1.0", optional = true}} [package.extras] b = ["b (^1.0)"] @@ -324,7 +333,7 @@ def test_locker_properly_loads_extras_legacy(locker: Locker): [metadata.files] "a" = [] "b" = [] -""" +""" # noqa: E800 locker.lock.write(tomlkit.parse(content)) @@ -351,7 +360,10 @@ def test_lock_packages_with_null_description(locker: Locker, root: ProjectPackag with locker.lock.open(encoding="utf-8") as f: content = f.read() - expected = """[[package]] + expected = f"""\ +# {GENERATED_COMMENT} + +[[package]] name = "A" version = "1.0.0" description = "" @@ -366,7 +378,7 @@ def test_lock_packages_with_null_description(locker: Locker, root: ProjectPackag [metadata.files] A = [] -""" +""" # noqa: E800 assert content == expected @@ -382,7 +394,10 @@ def test_lock_file_should_not_have_mixed_types(locker: Locker, root: ProjectPack locker.set_lock_data(root, [package_a]) - expected = """[[package]] + expected = f"""\ +# {GENERATED_COMMENT} + +[[package]] name = "A" version = "1.0.0" description = "" @@ -392,8 +407,8 @@ def test_lock_file_should_not_have_mixed_types(locker: Locker, root: ProjectPack [package.dependencies] B = [ - {version = "^1.0.0"}, - {version = ">=1.0.0", optional = true}, + {{version = "^1.0.0"}}, + {{version = ">=1.0.0", optional = true}}, ] [package.extras] @@ -406,7 +421,7 @@ def test_lock_file_should_not_have_mixed_types(locker: Locker, root: ProjectPack [metadata.files] A = [] -""" +""" # noqa: E800 with locker.lock.open(encoding="utf-8") as f: content = f.read() @@ -415,7 +430,10 @@ def test_lock_file_should_not_have_mixed_types(locker: Locker, root: ProjectPack def test_reading_lock_file_should_raise_an_error_on_invalid_data(locker: Locker): - content = """[[package]] + content = f"""\ +# {GENERATED_COMMENT} + +[[package]] name = "A" version = "1.0.0" description = "" @@ -436,7 +454,7 @@ def test_reading_lock_file_should_raise_an_error_on_invalid_data(locker: Locker) [metadata.files] A = [] -""" +""" # noqa: E800 with locker.lock.open("w", encoding="utf-8") as f: f.write(content) @@ -463,7 +481,10 @@ def test_locking_legacy_repository_package_should_include_source_section( with locker.lock.open(encoding="utf-8") as f: content = f.read() - expected = """[[package]] + expected = f"""\ +# {GENERATED_COMMENT} + +[[package]] name = "A" version = "1.0.0" description = "" @@ -483,7 +504,7 @@ def test_locking_legacy_repository_package_should_include_source_section( [metadata.files] A = [] -""" +""" # noqa: E800 assert content == expected @@ -522,14 +543,16 @@ def test_locker_should_emit_warnings_if_lock_version_is_newer_but_allowed( def test_locker_should_raise_an_error_if_lock_version_is_newer_and_not_allowed( locker: Locker, caplog: LogCaptureFixture ): - content = """\ + content = f"""\ +# {GENERATED_COMMENT} + [metadata] lock-version = "2.0" python-versions = "~2.7 || ^3.4" content-hash = "c3d07fca33fba542ef2b2a4d75bf5b48d892d21a830e2ad9c952ba5123a52f77" [metadata.files] -""" +""" # noqa: E800 caplog.set_level(logging.WARNING, logger="poetry.packages.locker") locker.lock.write(tomlkit.parse(content)) @@ -549,7 +572,10 @@ def test_extras_dependencies_are_ordered(locker: Locker, root: ProjectPackage): locker.set_lock_data(root, [package_a]) - expected = """[[package]] + expected = f"""\ +# {GENERATED_COMMENT} + +[[package]] name = "A" version = "1.0.0" description = "" @@ -558,7 +584,7 @@ def test_extras_dependencies_are_ordered(locker: Locker, root: ProjectPackage): python-versions = "*" [package.dependencies] -B = {version = "^1.0.0", extras = ["a", "b", "c"], optional = true} +B = {{version = "^1.0.0", extras = ["a", "b", "c"], optional = true}} [metadata] lock-version = "1.1" @@ -567,7 +593,7 @@ def test_extras_dependencies_are_ordered(locker: Locker, root: ProjectPackage): [metadata.files] A = [] -""" +""" # noqa: E800 with locker.lock.open(encoding="utf-8") as f: content = f.read() @@ -639,7 +665,9 @@ def test_locker_dumps_dependency_information_correctly( with locker.lock.open(encoding="utf-8") as f: content = f.read() - expected = """[[package]] + expected = f"""# {GENERATED_COMMENT} + +[[package]] name = "A" version = "1.0.0" description = "" @@ -648,11 +676,11 @@ def test_locker_dumps_dependency_information_correctly( python-versions = "*" [package.dependencies] -B = {path = "project_with_extras", develop = true} -C = {path = "directory/project_with_transitive_directory_dependencies"} -D = {path = "distributions/demo-0.1.0.tar.gz"} -E = {url = "https://python-poetry.org/poetry-1.2.0.tar.gz"} -F = {git = "https://github.com/python-poetry/poetry.git", branch = "foo"} +B = {{path = "project_with_extras", develop = true}} +C = {{path = "directory/project_with_transitive_directory_dependencies"}} +D = {{path = "distributions/demo-0.1.0.tar.gz"}} +E = {{url = "https://python-poetry.org/poetry-1.2.0.tar.gz"}} +F = {{git = "https://github.com/python-poetry/poetry.git", branch = "foo"}} [metadata] lock-version = "1.1" @@ -669,7 +697,9 @@ def test_locker_dumps_dependency_information_correctly( def test_locked_repository_uses_root_dir_of_package( locker: Locker, mocker: MockerFixture ): - content = """\ + content = f"""\ +# {GENERATED_COMMENT} + [[package]] name = "lib-a" version = "0.1.0" @@ -680,7 +710,7 @@ def test_locked_repository_uses_root_dir_of_package( develop = true [package.dependencies] -lib-b = {path = "../libB", develop = true} +lib-b = {{path = "../libB", develop = true}} [package.source] type = "directory" @@ -694,7 +724,7 @@ def test_locked_repository_uses_root_dir_of_package( [metadata.files] lib-a = [] lib-b = [] -""" +""" # noqa: E800 locker.lock.write(tomlkit.parse(content)) create_dependency_patch = mocker.patch(