From 06eebb45facdb3089b8aee27b0b776fccc60368e Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Thu, 29 Sep 2022 12:16:54 -0700 Subject: [PATCH 1/6] add constraints support --- README.md | 6 +- docs/_index.md | 4 +- src/poetry_plugin_export/command.py | 3 +- src/poetry_plugin_export/exporter.py | 22 ++++- tests/test_exporter.py | 133 +++++++++++++++++++++++++++ 5 files changed, 161 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6dd88af..3b3c4b0 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This package is a plugin that allows the export of locked packages to various formats. -**Note**: For now, only the `requirements.txt` format is available. +**Note**: For now, only the `constraints.txt` and `requirements.txt` formats are available. This plugin provides the same features as the existing `export` command of Poetry which it will eventually replace. @@ -36,11 +36,11 @@ The plugin provides an `export` command to export to the desired format. poetry export -f requirements.txt --output requirements.txt ``` -**Note**: Only the `requirements.txt` format is currently supported. +**Note**: Only the `constraints.txt` and `requirements.txt` formats are currently supported. ### Available options -* `--format (-f)`: The format to export to (default: `requirements.txt`). Currently, only `requirements.txt` is supported. +* `--format (-f)`: The format to export to (default: `requirements.txt`). Currently, only `constraints.txt` and `requirements.txt` are supported. * `--output (-o)`: The name of the output file. If omitted, print to standard output. * `--without`: The dependency groups to ignore when exporting. * `--with`: The optional dependency groups to include when exporting. diff --git a/docs/_index.md b/docs/_index.md index 6849144..cd34c3d 100644 --- a/docs/_index.md +++ b/docs/_index.md @@ -14,7 +14,7 @@ menu: The export plugin allows the export of locked packages to various formats. {{% note %}} -Only the `requirements.txt` format is currently supported. +Only the `constraints.txt` and `requirements.txt` formats are currently supported. {{% /note %}} ## Exporting packages @@ -65,7 +65,7 @@ poetry export --only test,docs ### Available options -* `--format (-f)`: The format to export to (default: `requirements.txt`). Currently, only `requirements.txt` is supported. +* `--format (-f)`: The format to export to (default: `requirements.txt`). Currently, only `constraints.txt` and `requirements.txt` are supported. * `--output (-o)`: The name of the output file. If omitted, print to standard output. * `--without`: The dependency groups to ignore when exporting. * `--with`: The optional dependency groups to include when exporting. diff --git a/src/poetry_plugin_export/command.py b/src/poetry_plugin_export/command.py index ee60220..1deadd0 100644 --- a/src/poetry_plugin_export/command.py +++ b/src/poetry_plugin_export/command.py @@ -15,7 +15,8 @@ class ExportCommand(GroupCommand): option( "format", "f", - "Format to export to. Currently, only requirements.txt is supported.", + "Format to export to. Currently, only constraints.txt and requirements.txt" + " are supported.", flag=False, default=Exporter.FORMAT_REQUIREMENTS_TXT, ), diff --git a/src/poetry_plugin_export/exporter.py b/src/poetry_plugin_export/exporter.py index cacb439..f117db3 100644 --- a/src/poetry_plugin_export/exporter.py +++ b/src/poetry_plugin_export/exporter.py @@ -23,10 +23,14 @@ class Exporter: Exporter class to export a lock file to alternative formats. """ + FORMAT_CONSTRAINTS_TXT = "constraints.txt" FORMAT_REQUIREMENTS_TXT = "requirements.txt" ALLOWED_HASH_ALGORITHMS = ("sha256", "sha384", "sha512") - EXPORT_METHODS = {FORMAT_REQUIREMENTS_TXT: "_export_requirements_txt"} + EXPORT_METHODS = { + FORMAT_CONSTRAINTS_TXT: "_export_constraints_txt", + FORMAT_REQUIREMENTS_TXT: "_export_requirements_txt", + } def __init__(self, poetry: Poetry) -> None: self._poetry = poetry @@ -71,7 +75,15 @@ def export(self, fmt: str, cwd: Path, output: IO | str) -> None: getattr(self, self.EXPORT_METHODS[fmt])(cwd, output) + def _export_constraints_txt(self, cwd: Path, output: IO | str) -> None: + return self._export_generic_txt(cwd, output, export_as_constraints=True) + def _export_requirements_txt(self, cwd: Path, output: IO | str) -> None: + return self._export_generic_txt(cwd, output, export_as_constraints=False) + + def _export_generic_txt( + self, cwd: Path, output: IO | str, export_as_constraints: bool + ) -> None: from poetry.core.packages.utils.utils import path_to_url indexes = set() @@ -90,10 +102,18 @@ def _export_requirements_txt(self, cwd: Path, output: IO | str) -> None: ): line = "" + if export_as_constraints: + dependency_package = dependency_package.without_features() + dependency = dependency_package.dependency package = dependency_package.package if package.develop: + if export_as_constraints: + raise RuntimeError( + f"{package.pretty_name} is configured for develop mode" + " which is incompatible with the constraints format." + ) line += "-e " requirement = dependency.to_pep_508(with_extras=False) diff --git a/tests/test_exporter.py b/tests/test_exporter.py index 85d041f..72e12d6 100644 --- a/tests/test_exporter.py +++ b/tests/test_exporter.py @@ -107,6 +107,139 @@ def set_package_requires(poetry: Poetry, skip: set[str] | None = None) -> None: poetry._package = package +def test_exporter_keeps_extras_for_requirements_txt( + tmp_dir: str, poetry: Poetry +) -> None: + poetry.locker.mock_lock_data( # type: ignore[attr-defined] + { + "package": [ + { + "name": "foo", + "version": "1.2.3", + "category": "main", + "optional": False, + "python-versions": "*", + "dependencies": { + "bar": { + "extras": ["baz"], + "version": ">=0.1.0", + } + }, + }, + { + "name": "bar", + "version": "4.5.6", + "category": "main", + "optional": False, + "python-versions": "*", + "dependencies": { + "baz": { + "version": ">=0.1.0", + "optional": True, + "markers": "extra == 'baz'", + } + }, + "extras": {"baz": ["baz (>=0.1.0)"]}, + }, + { + "name": "baz", + "version": "7.8.9", + "category": "main", + "optional": False, + "python-versions": "*", + }, + ], + "metadata": { + "python-versions": "*", + "content-hash": "123456789", + "files": {"foo": [], "bar": [], "baz": []}, + }, + } + ) + set_package_requires(poetry) + + exporter = Exporter(poetry) + exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt") + + with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: + content = f.read() + + expected = f"""\ +bar==4.5.6 ; {MARKER_PY} +bar[baz]==4.5.6 ; {MARKER_PY} +baz==7.8.9 ; {MARKER_PY} +foo==1.2.3 ; {MARKER_PY} +""" + + assert content == expected + + +def test_exporter_removes_extras_for_constraints_txt( + tmp_dir: str, poetry: Poetry +) -> None: + poetry.locker.mock_lock_data( # type: ignore[attr-defined] + { + "package": [ + { + "name": "foo", + "version": "1.2.3", + "category": "main", + "optional": False, + "python-versions": "*", + "dependencies": { + "bar": { + "extras": ["baz"], + "version": ">=0.1.0", + } + }, + }, + { + "name": "bar", + "version": "4.5.6", + "category": "main", + "optional": False, + "python-versions": "*", + "dependencies": { + "baz": { + "version": ">=0.1.0", + "optional": True, + "markers": "extra == 'baz'", + } + }, + "extras": {"baz": ["baz (>=0.1.0)"]}, + }, + { + "name": "baz", + "version": "7.8.9", + "category": "main", + "optional": False, + "python-versions": "*", + }, + ], + "metadata": { + "python-versions": "*", + "content-hash": "123456789", + "files": {"foo": [], "bar": [], "baz": []}, + }, + } + ) + set_package_requires(poetry) + + exporter = Exporter(poetry) + exporter.export("constraints.txt", Path(tmp_dir), "constraints.txt") + + with (Path(tmp_dir) / "constraints.txt").open(encoding="utf-8") as f: + content = f.read() + + expected = f"""\ +bar==4.5.6 ; {MARKER_PY} +baz==7.8.9 ; {MARKER_PY} +foo==1.2.3 ; {MARKER_PY} +""" + + assert content == expected + + def test_exporter_can_export_requirements_txt_with_standard_packages( tmp_dir: str, poetry: Poetry ) -> None: From 1c2f9b98fffa9357d92cabd0e290d8661c1dc1ac Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Thu, 29 Sep 2022 17:53:36 -0700 Subject: [PATCH 2/6] address some review comments --- src/poetry_plugin_export/exporter.py | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/poetry_plugin_export/exporter.py b/src/poetry_plugin_export/exporter.py index f117db3..38d5d81 100644 --- a/src/poetry_plugin_export/exporter.py +++ b/src/poetry_plugin_export/exporter.py @@ -1,5 +1,6 @@ from __future__ import annotations +import functools import urllib.parse from typing import TYPE_CHECKING @@ -27,10 +28,9 @@ class Exporter: FORMAT_REQUIREMENTS_TXT = "requirements.txt" ALLOWED_HASH_ALGORITHMS = ("sha256", "sha384", "sha512") - EXPORT_METHODS = { - FORMAT_CONSTRAINTS_TXT: "_export_constraints_txt", - FORMAT_REQUIREMENTS_TXT: "_export_requirements_txt", - } + # Entries are inserted into this dict below after the relevant methods are + # defined. + EXPORT_METHODS = {} def __init__(self, poetry: Poetry) -> None: self._poetry = poetry @@ -73,16 +73,10 @@ def export(self, fmt: str, cwd: Path, output: IO | str) -> None: if not self.is_format_supported(fmt): raise ValueError(f"Invalid export format: {fmt}") - getattr(self, self.EXPORT_METHODS[fmt])(cwd, output) - - def _export_constraints_txt(self, cwd: Path, output: IO | str) -> None: - return self._export_generic_txt(cwd, output, export_as_constraints=True) - - def _export_requirements_txt(self, cwd: Path, output: IO | str) -> None: - return self._export_generic_txt(cwd, output, export_as_constraints=False) + self.EXPORT_METHODS[fmt](self, cwd, output) def _export_generic_txt( - self, cwd: Path, output: IO | str, export_as_constraints: bool + self, cwd: Path, output: IO | str, with_extras: bool, allow_editable: bool ) -> None: from poetry.core.packages.utils.utils import path_to_url @@ -102,14 +96,14 @@ def _export_generic_txt( ): line = "" - if export_as_constraints: + if not with_extras: dependency_package = dependency_package.without_features() dependency = dependency_package.dependency package = dependency_package.package if package.develop: - if export_as_constraints: + if not allow_editable: raise RuntimeError( f"{package.pretty_name} is configured for develop mode" " which is incompatible with the constraints format." @@ -204,6 +198,13 @@ def _export_generic_txt( self._output(content, cwd, output) + EXPORT_METHODS[FORMAT_CONSTRAINTS_TXT] = functools.partial( + _export_generic_txt, with_extras=False, allow_editable=False + ) + EXPORT_METHODS[FORMAT_REQUIREMENTS_TXT] = functools.partial( + _export_generic_txt, with_extras=True, allow_editable=True + ) + def _output(self, content: str, cwd: Path, output: IO | str) -> None: if isinstance(output, IO): output.write(content) From 4bd6fd665fadfcf34094f2196cab12501e7755f5 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Fri, 30 Sep 2022 14:23:57 -0700 Subject: [PATCH 3/6] parametrize test to reduce redundancy --- tests/test_exporter.py | 103 +++++++++++------------------------------ 1 file changed, 26 insertions(+), 77 deletions(-) diff --git a/tests/test_exporter.py b/tests/test_exporter.py index 72e12d6..0694379 100644 --- a/tests/test_exporter.py +++ b/tests/test_exporter.py @@ -107,75 +107,30 @@ def set_package_requires(poetry: Poetry, skip: set[str] | None = None) -> None: poetry._package = package -def test_exporter_keeps_extras_for_requirements_txt( - tmp_dir: str, poetry: Poetry -) -> None: - poetry.locker.mock_lock_data( # type: ignore[attr-defined] - { - "package": [ - { - "name": "foo", - "version": "1.2.3", - "category": "main", - "optional": False, - "python-versions": "*", - "dependencies": { - "bar": { - "extras": ["baz"], - "version": ">=0.1.0", - } - }, - }, - { - "name": "bar", - "version": "4.5.6", - "category": "main", - "optional": False, - "python-versions": "*", - "dependencies": { - "baz": { - "version": ">=0.1.0", - "optional": True, - "markers": "extra == 'baz'", - } - }, - "extras": {"baz": ["baz (>=0.1.0)"]}, - }, - { - "name": "baz", - "version": "7.8.9", - "category": "main", - "optional": False, - "python-versions": "*", - }, +@pytest.mark.parametrize( + ["fmt", "expected"], + [ + ( + "constraints.txt", + [ + f"bar==4.5.6 ; {MARKER_PY}", + f"baz==7.8.9 ; {MARKER_PY}", + f"foo==1.2.3 ; {MARKER_PY}", ], - "metadata": { - "python-versions": "*", - "content-hash": "123456789", - "files": {"foo": [], "bar": [], "baz": []}, - }, - } - ) - set_package_requires(poetry) - - exporter = Exporter(poetry) - exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt") - - with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: - content = f.read() - - expected = f"""\ -bar==4.5.6 ; {MARKER_PY} -bar[baz]==4.5.6 ; {MARKER_PY} -baz==7.8.9 ; {MARKER_PY} -foo==1.2.3 ; {MARKER_PY} -""" - - assert content == expected - - -def test_exporter_removes_extras_for_constraints_txt( - tmp_dir: str, poetry: Poetry + ), + ( + "requirements.txt", + [ + f"bar==4.5.6 ; {MARKER_PY}", + f"bar[baz]==4.5.6 ; {MARKER_PY}", + f"baz==7.8.9 ; {MARKER_PY}", + f"foo==1.2.3 ; {MARKER_PY}", + ], + ), + ], +) +def test_exporter_handles_extras_for_txt_formats( + tmp_dir: str, poetry: Poetry, fmt: str, expected: list[str] ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { @@ -226,18 +181,12 @@ def test_exporter_removes_extras_for_constraints_txt( set_package_requires(poetry) exporter = Exporter(poetry) - exporter.export("constraints.txt", Path(tmp_dir), "constraints.txt") + exporter.export(fmt, Path(tmp_dir), "exported.txt") - with (Path(tmp_dir) / "constraints.txt").open(encoding="utf-8") as f: + with (Path(tmp_dir) / "exported.txt").open(encoding="utf-8") as f: content = f.read() - expected = f"""\ -bar==4.5.6 ; {MARKER_PY} -baz==7.8.9 ; {MARKER_PY} -foo==1.2.3 ; {MARKER_PY} -""" - - assert content == expected + assert content == "\n".join(expected) + "\n" def test_exporter_can_export_requirements_txt_with_standard_packages( From df5ad95c0562c18a63c6cde6df5d3cefd14c9769 Mon Sep 17 00:00:00 2001 From: Bjorn Neergaard Date: Fri, 30 Sep 2022 22:22:14 -0600 Subject: [PATCH 4/6] refactor(exporter): implement partialmethod as per code review --- src/poetry_plugin_export/exporter.py | 30 +++++++++++++--------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/poetry_plugin_export/exporter.py b/src/poetry_plugin_export/exporter.py index 38d5d81..cfa7c13 100644 --- a/src/poetry_plugin_export/exporter.py +++ b/src/poetry_plugin_export/exporter.py @@ -1,8 +1,8 @@ from __future__ import annotations -import functools import urllib.parse +from functools import partialmethod from typing import TYPE_CHECKING from typing import Iterable @@ -28,9 +28,10 @@ class Exporter: FORMAT_REQUIREMENTS_TXT = "requirements.txt" ALLOWED_HASH_ALGORITHMS = ("sha256", "sha384", "sha512") - # Entries are inserted into this dict below after the relevant methods are - # defined. - EXPORT_METHODS = {} + EXPORT_METHODS = { + FORMAT_CONSTRAINTS_TXT: "_export_constraints_txt", + FORMAT_REQUIREMENTS_TXT: "_export_requirements_txt", + } def __init__(self, poetry: Poetry) -> None: self._poetry = poetry @@ -73,7 +74,7 @@ def export(self, fmt: str, cwd: Path, output: IO | str) -> None: if not self.is_format_supported(fmt): raise ValueError(f"Invalid export format: {fmt}") - self.EXPORT_METHODS[fmt](self, cwd, output) + getattr(self, self.EXPORT_METHODS[fmt])(cwd, output) def _export_generic_txt( self, cwd: Path, output: IO | str, with_extras: bool, allow_editable: bool @@ -196,19 +197,16 @@ def _export_generic_txt( content = indexes_header + "\n" + content - self._output(content, cwd, output) + if isinstance(output, IO): + output.write(content) + else: + with (cwd / output).open("w", encoding="utf-8") as txt: + txt.write(content) - EXPORT_METHODS[FORMAT_CONSTRAINTS_TXT] = functools.partial( + _export_constraints_txt = partialmethod( _export_generic_txt, with_extras=False, allow_editable=False ) - EXPORT_METHODS[FORMAT_REQUIREMENTS_TXT] = functools.partial( + + _export_requirements_txt = partialmethod( _export_generic_txt, with_extras=True, allow_editable=True ) - - def _output(self, content: str, cwd: Path, output: IO | str) -> None: - if isinstance(output, IO): - output.write(content) - else: - filepath = cwd / output - with filepath.open("w", encoding="utf-8") as f: - f.write(content) From 99e6c470cb4425a6f2881028b64469d251330114 Mon Sep 17 00:00:00 2001 From: Bjorn Neergaard Date: Fri, 30 Sep 2022 22:57:59 -0600 Subject: [PATCH 5/6] test(exporter): rearrange tests and add editable test per code review --- tests/test_exporter.py | 215 +++++++++++++++++++++++++---------------- 1 file changed, 132 insertions(+), 83 deletions(-) diff --git a/tests/test_exporter.py b/tests/test_exporter.py index 0694379..2f86e9b 100644 --- a/tests/test_exporter.py +++ b/tests/test_exporter.py @@ -107,88 +107,6 @@ def set_package_requires(poetry: Poetry, skip: set[str] | None = None) -> None: poetry._package = package -@pytest.mark.parametrize( - ["fmt", "expected"], - [ - ( - "constraints.txt", - [ - f"bar==4.5.6 ; {MARKER_PY}", - f"baz==7.8.9 ; {MARKER_PY}", - f"foo==1.2.3 ; {MARKER_PY}", - ], - ), - ( - "requirements.txt", - [ - f"bar==4.5.6 ; {MARKER_PY}", - f"bar[baz]==4.5.6 ; {MARKER_PY}", - f"baz==7.8.9 ; {MARKER_PY}", - f"foo==1.2.3 ; {MARKER_PY}", - ], - ), - ], -) -def test_exporter_handles_extras_for_txt_formats( - tmp_dir: str, poetry: Poetry, fmt: str, expected: list[str] -) -> None: - poetry.locker.mock_lock_data( # type: ignore[attr-defined] - { - "package": [ - { - "name": "foo", - "version": "1.2.3", - "category": "main", - "optional": False, - "python-versions": "*", - "dependencies": { - "bar": { - "extras": ["baz"], - "version": ">=0.1.0", - } - }, - }, - { - "name": "bar", - "version": "4.5.6", - "category": "main", - "optional": False, - "python-versions": "*", - "dependencies": { - "baz": { - "version": ">=0.1.0", - "optional": True, - "markers": "extra == 'baz'", - } - }, - "extras": {"baz": ["baz (>=0.1.0)"]}, - }, - { - "name": "baz", - "version": "7.8.9", - "category": "main", - "optional": False, - "python-versions": "*", - }, - ], - "metadata": { - "python-versions": "*", - "content-hash": "123456789", - "files": {"foo": [], "bar": [], "baz": []}, - }, - } - ) - set_package_requires(poetry) - - exporter = Exporter(poetry) - exporter.export(fmt, Path(tmp_dir), "exported.txt") - - with (Path(tmp_dir) / "exported.txt").open(encoding="utf-8") as f: - content = f.read() - - assert content == "\n".join(expected) + "\n" - - def test_exporter_can_export_requirements_txt_with_standard_packages( tmp_dir: str, poetry: Poetry ) -> None: @@ -746,7 +664,7 @@ def test_exporter_can_export_requirements_txt_with_standard_packages_and_sorted_ assert content == expected -def test_exporter_requirements_txt_with_standard_packages_and_hashes_disabled( +def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes_disabled( # noqa: E501 tmp_dir: str, poetry: Poetry ) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] @@ -2561,6 +2479,137 @@ def test_exporter_omits_unwanted_extras( assert io.fetch_output() == "\n".join(expected) + "\n" +@pytest.mark.parametrize( + ["fmt", "expected"], + [ + ( + "constraints.txt", + [ + f"bar==4.5.6 ; {MARKER_PY}", + f"baz==7.8.9 ; {MARKER_PY}", + f"foo==1.2.3 ; {MARKER_PY}", + ], + ), + ( + "requirements.txt", + [ + f"bar==4.5.6 ; {MARKER_PY}", + f"bar[baz]==4.5.6 ; {MARKER_PY}", + f"baz==7.8.9 ; {MARKER_PY}", + f"foo==1.2.3 ; {MARKER_PY}", + ], + ), + ], +) +def test_exporter_omits_and_includes_extras_for_txt_formats( + tmp_dir: str, poetry: Poetry, fmt: str, expected: list[str] +) -> None: + poetry.locker.mock_lock_data( # type: ignore[attr-defined] + { + "package": [ + { + "name": "foo", + "version": "1.2.3", + "category": "main", + "optional": False, + "python-versions": "*", + "dependencies": { + "bar": { + "extras": ["baz"], + "version": ">=0.1.0", + } + }, + }, + { + "name": "bar", + "version": "4.5.6", + "category": "main", + "optional": False, + "python-versions": "*", + "dependencies": { + "baz": { + "version": ">=0.1.0", + "optional": True, + "markers": "extra == 'baz'", + } + }, + "extras": {"baz": ["baz (>=0.1.0)"]}, + }, + { + "name": "baz", + "version": "7.8.9", + "category": "main", + "optional": False, + "python-versions": "*", + }, + ], + "metadata": { + "python-versions": "*", + "content-hash": "123456789", + "files": {"foo": [], "bar": [], "baz": []}, + }, + } + ) + set_package_requires(poetry) + + exporter = Exporter(poetry) + exporter.export(fmt, Path(tmp_dir), "exported.txt") + + with (Path(tmp_dir) / "exported.txt").open(encoding="utf-8") as f: + content = f.read() + + assert content == "\n".join(expected) + "\n" + + +def test_exporter_raises_exception_for_constraints_txt_with_editable_packages( + tmp_dir: str, poetry: Poetry +) -> None: + poetry.locker.mock_lock_data( # type: ignore[attr-defined] + { + "package": [ + { + "name": "foo", + "version": "1.2.3", + "category": "main", + "optional": False, + "python-versions": "*", + "source": { + "type": "git", + "url": "https://github.com/foo/foo.git", + "reference": "123456", + }, + "develop": True, + }, + { + "name": "bar", + "version": "4.5.6", + "category": "main", + "optional": False, + "python-versions": "*", + "source": { + "type": "directory", + "url": "tests/fixtures/sample_project", + "reference": "", + }, + "develop": True, + }, + ], + "metadata": { + "python-versions": "*", + "content-hash": "123456789", + "files": {"foo": [], "bar": []}, + }, + } + ) + set_package_requires(poetry) + + with pytest.raises(RuntimeError): + exporter = Exporter(poetry) + exporter.export("constraints.txt", Path(tmp_dir), "constraints.txt") + + assert not (Path(tmp_dir) / "constraints.txt").exists() + + def test_exporter_respects_package_sources(tmp_dir: str, poetry: Poetry) -> None: poetry.locker.mock_lock_data( # type: ignore[attr-defined] { From ae3c8fcbde10f6d0340cb0303033efc346c34f0f Mon Sep 17 00:00:00 2001 From: Bjorn Neergaard Date: Fri, 30 Sep 2022 23:07:18 -0600 Subject: [PATCH 6/6] fix(exporter): tweak exception phrasing --- src/poetry_plugin_export/exporter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/poetry_plugin_export/exporter.py b/src/poetry_plugin_export/exporter.py index cfa7c13..135ebd2 100644 --- a/src/poetry_plugin_export/exporter.py +++ b/src/poetry_plugin_export/exporter.py @@ -106,8 +106,8 @@ def _export_generic_txt( if package.develop: if not allow_editable: raise RuntimeError( - f"{package.pretty_name} is configured for develop mode" - " which is incompatible with the constraints format." + f"{package.pretty_name} is locked in develop (editable) mode," + " which is incompatible with the constraints.txt format." ) line += "-e "