def prepare_metadata_for_build_wheel( metadata_directory: str, config_settings: dict[str, Any] | None = None ) -> str: poetry = Factory().create_poetry(Path(".").resolve(), with_groups=False) builder = WheelBuilder(poetry) dist_info = Path(metadata_directory, builder.dist_info) dist_info.mkdir(parents=True, exist_ok=True) if "scripts" in poetry.local_config or "plugins" in poetry.local_config: with (dist_info / "entry_points.txt").open("w", encoding="utf-8") as f: builder._write_entry_points(f) with (dist_info / "WHEEL").open("w", encoding="utf-8") as f: builder._write_wheel_file(f) with (dist_info / "METADATA").open("w", encoding="utf-8") as f: builder._write_metadata_file(f) return dist_info.name
def test_wheel_excluded_nested_data(): module_path = fixtures_dir / "exclude_nested_data_toml" poetry = Factory().create_poetry(module_path) WheelBuilder.make(poetry) whl = module_path / "dist" / "my_package-1.2.3-py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: assert "my_package/__init__.py" in z.namelist() assert "my_package/data/sub_data/data2.txt" not in z.namelist() assert "my_package/data/sub_data/data3.txt" not in z.namelist() assert "my_package/data/data1.txt" not in z.namelist() assert "my_package/data/data2.txt" in z.namelist() assert "my_package/puplic/publicdata.txt" in z.namelist() assert "my_package/public/item1/itemdata1.txt" not in z.namelist() assert "my_package/public/item1/subitem/subitemdata.txt" not in z.namelist( ) assert "my_package/public/item2/itemdata2.txt" not in z.namelist()
def test_create_poetry_with_packages_and_includes(): poetry = Factory().create_poetry( fixtures_dir.parent / "masonry" / "builders" / "fixtures" / "with-include" ) package = poetry.package assert package.packages == [ {"include": "extra_dir/**/*.py"}, {"include": "extra_dir/**/*.py"}, {"include": "my_module.py"}, {"include": "package_with_include"}, {"include": "tests", "format": "sdist"}, {"include": "for_wheel_only", "format": ["wheel"]}, {"include": "src_package", "from": "src"}, ] assert package.include == [ {"path": "extra_dir/vcs_excluded.txt", "format": []}, {"path": "notes.txt", "format": []}, ]
def test_dist_info_file_permissions(): module_path = fixtures_dir / "complete" WheelBuilder.make(Factory().create_poetry(module_path)) whl = module_path / "dist" / "my_package-1.2.3-py3-none-any.whl" with zipfile.ZipFile(str(whl)) as z: assert ( z.getinfo("my_package-1.2.3.dist-info/WHEEL").external_attr == 0o644 << 16 ) assert ( z.getinfo("my_package-1.2.3.dist-info/METADATA").external_attr == 0o644 << 16 ) assert ( z.getinfo("my_package-1.2.3.dist-info/RECORD").external_attr == 0o644 << 16 ) assert ( z.getinfo("my_package-1.2.3.dist-info/entry_points.txt").external_attr == 0o644 << 16 )
def test_default_src_with_excluded_data(mocker): # Patch git module to return specific excluded files p = mocker.patch("poetry.core.vcs.git.Git.get_ignored_files") p.return_value = [ ( ( Path(__file__).parent / "fixtures" / "default_src_with_excluded_data" / "src" / "my_package" / "data" / "sub_data" / "data2.txt" ) .relative_to(project("default_src_with_excluded_data")) .as_posix() ) ] poetry = Factory().create_poetry(project("default_src_with_excluded_data")) builder = WheelBuilder(poetry) builder.build() whl = ( fixtures_dir / "default_src_with_excluded_data" / "dist" / "my_package-1.2.3-py3-none-any.whl" ) assert whl.exists() with zipfile.ZipFile(str(whl)) as z: names = z.namelist() assert "my_package/__init__.py" in names assert "my_package/data/data1.txt" in names assert "my_package/data/sub_data/data2.txt" not in names assert "my_package/data/sub_data/data3.txt" in names
def test_respect_format_for_explicit_included_files(): module_path = fixtures_dir / "exclude-whl-include-sdist" builder = Builder(Factory().create_poetry(module_path)) builder.build(fmt="all") sdist = module_path / "dist" / "exclude-whl-include-sdist-0.1.0.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: names = tar.getnames() assert ( "exclude-whl-include-sdist-0.1.0/exclude_whl_include_sdist/__init__.py" in names) assert ( "exclude-whl-include-sdist-0.1.0/exclude_whl_include_sdist/compiled/source.c" in names) assert ( "exclude-whl-include-sdist-0.1.0/exclude_whl_include_sdist/compiled/source.h" in names) assert ( "exclude-whl-include-sdist-0.1.0/exclude_whl_include_sdist/cython_code.pyx" in names) assert "exclude-whl-include-sdist-0.1.0/pyproject.toml" in names assert "exclude-whl-include-sdist-0.1.0/setup.py" in names assert "exclude-whl-include-sdist-0.1.0/PKG-INFO" in names whl = module_path / "dist" / "exclude_whl_include_sdist-0.1.0-py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: names = z.namelist() assert "exclude_whl_include_sdist/__init__.py" in names assert "exclude_whl_include_sdist/compiled/source.c" not in names assert "exclude_whl_include_sdist/compiled/source.h" not in names assert "exclude_whl_include_sdist/cython_code.pyx" not in names pass
def test_module_src(): module_path = fixtures_dir / "source_file" builder = Builder(Factory().create_poetry(module_path)) builder.build(fmt="all") sdist = module_path / "dist" / "module-src-0.1.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: assert "module-src-0.1/src/module_src.py" in tar.getnames() whl = module_path / "dist" / "module_src-0.1-py2.py3-none-any.whl" assert whl.exists() zip = zipfile.ZipFile(str(whl)) try: assert "module_src.py" in zip.namelist() finally: zip.close()
def test_with_src_module_file(): poetry = Factory().create_poetry(project("source_file")) builder = SdistBuilder(poetry) # Check setup.py setup = builder.build_setup() setup_ast = ast.parse(setup) setup_ast.body = [n for n in setup_ast.body if isinstance(n, ast.Assign)] ns = {} exec(compile(setup_ast, filename="setup.py", mode="exec"), ns) assert ns["package_dir"] == {"": "src"} assert ns["modules"] == ["module_src"] builder.build() sdist = fixtures_dir / "source_file" / "dist" / "module-src-0.1.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: assert "module-src-0.1/src/module_src.py" in tar.getnames()
def test_setup_py_context(): poetry = Factory().create_poetry(project("complete")) builder = SdistBuilder(poetry) project_setup_py = poetry.file.parent / "setup.py" assert not project_setup_py.exists() try: with builder.setup_py() as setup: assert setup.exists() assert project_setup_py == setup with open(str(setup), "rb") as f: # we convert to string and replace line endings here for compatibility data = to_str(encode(f.read())).replace("\r\n", "\n") assert data == to_str(builder.build_setup()) assert not project_setup_py.exists() finally: if project_setup_py.exists(): project_setup_py.unlink()
def test_split_source() -> None: module_path = fixtures_dir / "split_source" builder = Builder(Factory().create_poetry(module_path)) builder.build(fmt="all") sdist = module_path / "dist" / "split-source-0.1.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: assert "split-source-0.1/lib_a/module_a/__init__.py" in tar.getnames() assert "split-source-0.1/lib_b/module_b/__init__.py" in tar.getnames() whl = module_path / "dist" / "split_source-0.1-py3-none-any.whl" assert whl.exists() zip = zipfile.ZipFile(str(whl)) try: assert "module_a/__init__.py" in zip.namelist() assert "module_b/__init__.py" in zip.namelist() finally: zip.close()
def f(): # type: () -> Factory return Factory()
def test_validate() -> None: complete = TOMLFile(fixtures_dir / "complete.toml") doc: dict[str, Any] = complete.read() content = doc["tool"]["poetry"] assert Factory.validate(content) == {"errors": [], "warnings": []}
def test_create_poetry_omits_dev_dependencies_iff_with_dev_is_false(): poetry = Factory().create_poetry(fixtures_dir / "sample_project", with_dev=False) assert not any(r for r in poetry.package.dev_requires if "pytest" in str(r)) poetry = Factory().create_poetry(fixtures_dir / "sample_project") assert any(r for r in poetry.package.dev_requires if "pytest" in str(r))
def f() -> Factory: return Factory()
try: try: from poetry.core.factory import Factory from poetry.core.masonry.builders.sdist import SdistBuilder except (ImportError, ModuleNotFoundError): from poetry.masonry.builders.sdist import SdistBuilder from poetry.factory import Factory from poetry.__version__ import __version__ except (ImportError, ModuleNotFoundError) as ee: raise ImportError( "install poetry by doing pip install poetry to use " f"this script: {ee}" ) # Generate a Poetry object that knows about the metadata in pyproject.toml factory = Factory() poetry = factory.create_poetry(".") # Use the SdistBuilder to genrate a blob for setup.py if StrictVersion(__version__) >= StrictVersion("1.1.0b1"): sdist_builder = SdistBuilder(poetry, None) else: sdist_builder = SdistBuilder(poetry, None, None) setuppy_blob = sdist_builder.build_setup() with open("setup.py", "wb") as unit: unit.write(setuppy_blob) unit.write(b"\n# This setup.py was autogenerated by https://github.com/jvansanten/poetry-export-to-legacy-action. Do not edit!\n")
def test_builder_convert_script_files(fixture: str, result: list[Path]) -> None: project_root = Path(__file__).parent / "fixtures" / fixture script_files = Builder( Factory().create_poetry(project_root)).convert_script_files() assert [p.relative_to(project_root) for p in script_files] == result
def test_create_poetry(): poetry = Factory().create_poetry(fixtures_dir / "sample_project") package = poetry.package assert package.name == "my-package" assert package.version.text == "1.2.3" assert package.description == "Some description." assert package.authors == ["Sébastien Eustace <*****@*****.**>"] assert package.license.id == "MIT" assert (package.readme.relative_to(fixtures_dir).as_posix() == "sample_project/README.rst") assert package.homepage == "https://python-poetry.org" assert package.repository_url == "https://github.com/python-poetry/poetry" assert package.keywords == ["packaging", "dependency", "poetry"] assert package.python_versions == "~2.7 || ^3.6" assert str(package.python_constraint) == ">=2.7,<2.8 || >=3.6,<4.0" dependencies = {} for dep in package.requires: dependencies[dep.name] = dep cleo = dependencies["cleo"] assert cleo.pretty_constraint == "^0.6" assert not cleo.is_optional() pendulum = dependencies["pendulum"] assert pendulum.pretty_constraint == "branch 2.0" assert pendulum.is_vcs() assert pendulum.vcs == "git" assert pendulum.branch == "2.0" assert pendulum.source == "https://github.com/sdispater/pendulum.git" assert pendulum.allows_prereleases() assert not pendulum.develop tomlkit = dependencies["tomlkit"] assert tomlkit.pretty_constraint == "rev 3bff550" assert tomlkit.is_vcs() assert tomlkit.vcs == "git" assert tomlkit.rev == "3bff550" assert tomlkit.source == "https://github.com/sdispater/tomlkit.git" assert tomlkit.allows_prereleases() assert not tomlkit.develop requests = dependencies["requests"] assert requests.pretty_constraint == "^2.18" assert not requests.is_vcs() assert not requests.allows_prereleases() assert requests.is_optional() assert requests.extras == frozenset({"security"}) pathlib2 = dependencies["pathlib2"] assert pathlib2.pretty_constraint == "^2.2" assert pathlib2.python_versions == "~2.7" assert not pathlib2.is_optional() demo = dependencies["demo"] assert demo.is_file() assert not demo.is_vcs() assert demo.name == "demo" assert demo.pretty_constraint == "*" demo = dependencies["my-package"] assert not demo.is_file() assert demo.is_directory() assert not demo.is_vcs() assert demo.name == "my-package" assert demo.pretty_constraint == "*" simple_project = dependencies["simple-project"] assert not simple_project.is_file() assert simple_project.is_directory() assert not simple_project.is_vcs() assert simple_project.name == "simple-project" assert simple_project.pretty_constraint == "*" functools32 = dependencies["functools32"] assert functools32.name == "functools32" assert functools32.pretty_constraint == "^3.2.3" assert ( str(functools32.marker) == 'python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5"' ) assert "db" in package.extras classifiers = package.classifiers assert classifiers == [ "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules", ] assert package.all_classifiers == [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Libraries :: Python Modules", ]
def test_package_with_include(mocker): module_path = fixtures_dir / "with-include" # Patch git module to return specific excluded files p = mocker.patch("poetry.core.vcs.git.Git.get_ignored_files") p.return_value = [ str( Path(__file__).parent / "fixtures" / "with-include" / "extra_dir" / "vcs_excluded.txt"), str( Path(__file__).parent / "fixtures" / "with-include" / "extra_dir" / "sub_pkg" / "vcs_excluded.txt"), ] builder = Builder(Factory().create_poetry(module_path)) builder.build(fmt="all") sdist = fixtures_dir / "with-include" / "dist" / "with-include-1.2.3.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: names = tar.getnames() assert len(names) == len(set(names)) assert "with-include-1.2.3/LICENSE" in names assert "with-include-1.2.3/README.rst" in names assert "with-include-1.2.3/extra_dir/__init__.py" in names assert "with-include-1.2.3/extra_dir/vcs_excluded.txt" in names assert "with-include-1.2.3/extra_dir/sub_pkg/__init__.py" in names assert "with-include-1.2.3/extra_dir/sub_pkg/vcs_excluded.txt" not in names assert "with-include-1.2.3/my_module.py" in names assert "with-include-1.2.3/notes.txt" in names assert "with-include-1.2.3/package_with_include/__init__.py" in names assert "with-include-1.2.3/tests/__init__.py" in names assert "with-include-1.2.3/pyproject.toml" in names assert "with-include-1.2.3/setup.py" in names assert "with-include-1.2.3/PKG-INFO" in names assert "with-include-1.2.3/for_wheel_only/__init__.py" not in names assert "with-include-1.2.3/src/src_package/__init__.py" in names setup = tar.extractfile("with-include-1.2.3/setup.py").read() setup_ast = ast.parse(setup) setup_ast.body = [ n for n in setup_ast.body if isinstance(n, ast.Assign) ] ns = {} exec(compile(setup_ast, filename="setup.py", mode="exec"), ns) assert ns["package_dir"] == {"": "src"} assert ns["packages"] == [ "extra_dir", "extra_dir.sub_pkg", "package_with_include", "src_package", "tests", ] assert ns["package_data"] == {"": ["*"]} assert ns["modules"] == ["my_module"] whl = module_path / "dist" / "with_include-1.2.3-py3-none-any.whl" assert whl.exists() with zipfile.ZipFile(str(whl)) as z: names = z.namelist() assert len(names) == len(set(names)) assert "with_include-1.2.3.dist-info/LICENSE" in names assert "extra_dir/__init__.py" in names assert "extra_dir/vcs_excluded.txt" in names assert "extra_dir/sub_pkg/__init__.py" in names assert "extra_dir/sub_pkg/vcs_excluded.txt" not in names assert "for_wheel_only/__init__.py" in names assert "my_module.py" in names assert "notes.txt" in names assert "package_with_include/__init__.py" in names assert "tests/__init__.py" not in names assert "src_package/__init__.py" in names
def test_complete_no_vcs(): # Copy the complete fixtures dir to a temporary directory module_path = fixtures_dir / "complete" temporary_dir = Path(tempfile.mkdtemp()) / "complete" shutil.copytree(module_path.as_posix(), temporary_dir.as_posix()) builder = Builder(Factory().create_poetry(temporary_dir)) builder.build(fmt="all") whl = temporary_dir / "dist" / "my_package-1.2.3-py3-none-any.whl" assert whl.exists() zip = zipfile.ZipFile(str(whl)) # Check the zipped file to be sure that included and excluded files are # correctly taken account of without vcs expected_name_list = [ "my_package/__init__.py", "my_package/data1/test.json", "my_package/sub_pkg1/__init__.py", "my_package/sub_pkg2/__init__.py", "my_package/sub_pkg2/data2/data.json", "my_package/sub_pkg3/foo.py", "my_package-1.2.3.dist-info/entry_points.txt", "my_package-1.2.3.dist-info/LICENSE", "my_package-1.2.3.dist-info/WHEEL", "my_package-1.2.3.dist-info/METADATA", "my_package-1.2.3.dist-info/RECORD", ] assert sorted(zip.namelist()) == sorted(expected_name_list) try: entry_points = zip.read("my_package-1.2.3.dist-info/entry_points.txt") assert (decode(entry_points.decode()) == """\ [console_scripts] extra-script=my_package.extra:main[time] my-2nd-script=my_package:main2 my-script=my_package:main """) wheel_data = decode(zip.read("my_package-1.2.3.dist-info/WHEEL")) assert (wheel_data == """\ Wheel-Version: 1.0 Generator: poetry {} Root-Is-Purelib: true Tag: py3-none-any """.format(__version__)) wheel_data = decode(zip.read("my_package-1.2.3.dist-info/METADATA")) assert (wheel_data == """\ Metadata-Version: 2.1 Name: my-package Version: 1.2.3 Summary: Some description. Home-page: https://python-poetry.org/ License: MIT Keywords: packaging,dependency,poetry Author: Sébastien Eustace Author-email: [email protected] Maintainer: People Everywhere Maintainer-email: [email protected] Requires-Python: >=3.6,<4.0 Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries :: Python Modules Provides-Extra: time Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0) Requires-Dist: cleo (>=0.6,<0.7) Requires-Dist: pendulum (>=1.4,<2.0); (python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5") and (extra == "time") Project-URL: Documentation, https://python-poetry.org/docs Project-URL: Issue Tracker, https://github.com/python-poetry/poetry/issues Project-URL: Repository, https://github.com/python-poetry/poetry Description-Content-Type: text/x-rst My Package ========== """) finally: zip.close()
sys.path.insert(0, lib) sys.path.insert(0, current_vendors) try: try: from poetry.core.factory import Factory from poetry.core.masonry.builders.sdist import SdistBuilder except (ImportError, ModuleNotFoundError): from poetry.masonry.builders.sdist import SdistBuilder from poetry.factory import Factory from poetry.__version__ import __version__ except (ImportError, ModuleNotFoundError) as ee: raise ImportError( f"install poetry by doing pip install poetry to use this script: {ee}") # Generate a Poetry object that knows about the metadata in pyproject.toml factory = Factory() poetry = factory.create_poetry(os.path.dirname(__file__)) # Use the SdistBuilder to genrate a blob for setup.py if StrictVersion(__version__) >= StrictVersion("1.1.0b1"): sdist_builder = SdistBuilder(poetry, None) else: sdist_builder = SdistBuilder(poetry, None, None) setuppy_blob = sdist_builder.build_setup() with open("setup.py", "wb") as unit: unit.write(setuppy_blob) unit.write(b"\n# This setup.py was autogenerated using poetry.\n")
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): """Builds a wheel, places it in wheel_directory""" poetry = Factory().create_poetry(Path(".").resolve(), with_dev=False) return unicode(WheelBuilder.make_in(poetry, Path(wheel_directory)))
def test_complete(): module_path = fixtures_dir / "complete" builder = Builder(Factory().create_poetry(module_path)) builder.build(fmt="all") whl = module_path / "dist" / "my_package-1.2.3-py3-none-any.whl" assert whl.exists() if sys.platform != "win32": assert (os.stat(str(whl)).st_mode & 0o777) == 0o644 zip = zipfile.ZipFile(str(whl)) try: assert "my_package/sub_pgk1/extra_file.xml" not in zip.namelist() entry_points = zip.read("my_package-1.2.3.dist-info/entry_points.txt") assert (decode(entry_points.decode()) == """\ [console_scripts] extra-script=my_package.extra:main[time] my-2nd-script=my_package:main2 my-script=my_package:main """) wheel_data = decode(zip.read("my_package-1.2.3.dist-info/WHEEL")) assert (wheel_data == """\ Wheel-Version: 1.0 Generator: poetry {} Root-Is-Purelib: true Tag: py3-none-any """.format(__version__)) wheel_data = decode(zip.read("my_package-1.2.3.dist-info/METADATA")) assert (wheel_data == """\ Metadata-Version: 2.1 Name: my-package Version: 1.2.3 Summary: Some description. Home-page: https://python-poetry.org/ License: MIT Keywords: packaging,dependency,poetry Author: Sébastien Eustace Author-email: [email protected] Maintainer: People Everywhere Maintainer-email: [email protected] Requires-Python: >=3.6,<4.0 Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries :: Python Modules Provides-Extra: time Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0) Requires-Dist: cleo (>=0.6,<0.7) Requires-Dist: pendulum (>=1.4,<2.0); (python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5") and (extra == "time") Project-URL: Documentation, https://python-poetry.org/docs Project-URL: Issue Tracker, https://github.com/python-poetry/poetry/issues Project-URL: Repository, https://github.com/python-poetry/poetry Description-Content-Type: text/x-rst My Package ========== """) finally: zip.close()
def build_setup_py(): return SdistBuilder(Factory().create_poetry( Path(".").resolve())).build_setup()
def test_builder_convert_entry_points(fixture, result): entry_points = Builder(Factory().create_poetry( Path(__file__).parent / "fixtures" / fixture)).convert_entry_points() assert entry_points == result
def test_entrypoint_scripts_legacy_warns(fixture: str) -> None: with pytest.warns(DeprecationWarning): Builder(Factory().create_poetry( Path(__file__).parent / "fixtures" / fixture)).convert_entry_points()
def _get_poetry_package(path: Path) -> Optional[ProjectPackage]: # Note: we ignore any setup.py file at this step # TODO: add support for handling non-poetry PEP-517 builds if PyProjectTOML(path.joinpath("pyproject.toml")).is_poetry_project(): return Factory().create_poetry(path).package
def test_builder_convert_entry_points(fixture: str, result: dict[str, list[str]]) -> None: entry_points = Builder(Factory().create_poetry( Path(__file__).parent / "fixtures" / fixture)).convert_entry_points() assert entry_points == result
def test_validate(): complete = PyProjectTOMLFile(fixtures_dir / "complete.toml") content = complete.read()["tool"]["poetry"] assert Factory.validate(content) == {"errors": [], "warnings": []}
def test_complete() -> None: module_path = fixtures_dir / "complete" builder = Builder(Factory().create_poetry(module_path)) builder.build(fmt="all") whl = module_path / "dist" / "my_package-1.2.3-py3-none-any.whl" assert whl.exists() if sys.platform != "win32": assert (os.stat(str(whl)).st_mode & 0o777) == 0o644 zip = zipfile.ZipFile(str(whl)) try: assert "my_package/sub_pgk1/extra_file.xml" not in zip.namelist() assert "my-package-1.2.3.data/scripts/script.sh" in zip.namelist() assert ( "Hello World" in zip.read("my-package-1.2.3.data/scripts/script.sh").decode()) entry_points = zip.read("my_package-1.2.3.dist-info/entry_points.txt") assert (entry_points.decode() == """\ [console_scripts] extra-script=my_package.extra:main[time] my-2nd-script=my_package:main2 my-script=my_package:main """) wheel_data = zip.read("my_package-1.2.3.dist-info/WHEEL").decode() assert (wheel_data == f"""\ Wheel-Version: 1.0 Generator: poetry {__version__} Root-Is-Purelib: true Tag: py3-none-any """) wheel_data = zip.read("my_package-1.2.3.dist-info/METADATA").decode() assert (wheel_data == """\ Metadata-Version: 2.1 Name: my-package Version: 1.2.3 Summary: Some description. Home-page: https://python-poetry.org/ License: MIT Keywords: packaging,dependency,poetry Author: Sébastien Eustace Author-email: [email protected] Maintainer: People Everywhere Maintainer-email: [email protected] Requires-Python: >=3.6,<4.0 Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Programming Language :: Python :: 3.10 Classifier: Topic :: Software Development :: Build Tools Classifier: Topic :: Software Development :: Libraries :: Python Modules Provides-Extra: time Requires-Dist: cachy[msgpack] (>=0.2.0,<0.3.0) Requires-Dist: cleo (>=0.6,<0.7) Requires-Dist: pendulum (>=1.4,<2.0); (python_version ~= "2.7" and sys_platform == "win32" or python_version in "3.4 3.5") and (extra == "time") Project-URL: Documentation, https://python-poetry.org/docs Project-URL: Issue Tracker, https://github.com/python-poetry/poetry/issues Project-URL: Repository, https://github.com/python-poetry/poetry Description-Content-Type: text/x-rst My Package ========== """) actual_records = zip.read("my_package-1.2.3.dist-info/RECORD").decode() # For some reason, the ordering of the files and the SHA hashes # vary per operating systems and Python versions. # So instead of 1:1 assertion, let's do a bit clunkier one: expected_records = [ "my_package/__init__.py", "my_package/data1/test.json", "my_package/sub_pkg1/__init__.py", "my_package/sub_pkg2/__init__.py", "my_package/sub_pkg2/data2/data.json", "my_package-1.2.3.dist-info/entry_points.txt", "my_package-1.2.3.dist-info/LICENSE", "my_package-1.2.3.dist-info/WHEEL", "my_package-1.2.3.dist-info/METADATA", ] for expected_record in expected_records: assert expected_record in actual_records finally: zip.close()