def test_wheel_c_extension(): module_path = fixtures_dir / "extended" builder = Builder(Factory().create_poetry(module_path)) builder.build(fmt="all") sdist = fixtures_dir / "extended" / "dist" / "extended-0.1.tar.gz" assert sdist.exists() with tarfile.open(str(sdist), "r") as tar: assert "extended-0.1/build.py" in tar.getnames() assert "extended-0.1/extended/extended.c" in tar.getnames() whl = list((module_path / "dist").glob("extended-0.1-cp*-cp*-*.whl"))[0] assert whl.exists() zip = zipfile.ZipFile(str(whl)) has_compiled_extension = False for name in zip.namelist(): if name.startswith("extended/extended") and name.endswith((".so", ".pyd")): has_compiled_extension = True assert has_compiled_extension try: wheel_data = decode(zip.read("extended-0.1.dist-info/WHEEL")) assert ( re.match( """(?m)^\ Wheel-Version: 1.0 Generator: poetry {} Root-Is-Purelib: false Tag: cp[23]_?\\d+-cp[23]_?\\d+m?u?-.+ $""".format( __version__ ), wheel_data, ) is not None ) records = decode(zip.read("extended-0.1.dist-info/RECORD")) assert re.search(r"\s+extended/extended.*\.(so|pyd)", records) is not None finally: zip.close()
def executable(): global _executable if _executable is not None: return _executable if WINDOWS and PY36: # Finding git via where.exe where = "%WINDIR%\\System32\\where.exe" paths = decode( subprocess.check_output([where, "git"], shell=True, encoding="oem")).split("\n") for path in paths: if not path: continue path = Path(path.strip()) try: path.relative_to(Path.cwd()) except ValueError: _executable = str(path) break else: _executable = "git" if _executable is None: raise RuntimeError("Unable to find a valid git executable") return _executable
def test_pyproject_toml_file_invalid(pyproject_toml): with pyproject_toml.open(mode="a") as f: f.write(decode("<<<<<<<<<<<")) with pytest.raises(PyProjectException) as excval: _ = PyProjectTOMLFile(pyproject_toml).read() assert "Invalid TOML file {}".format(pyproject_toml.as_posix()) in str(excval.value)
def build_system_section(pyproject_toml): # type: (Path) -> str content = """ [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" """ with pyproject_toml.open(mode="a") as f: f.write(decode(content)) return content
def poetry_section(pyproject_toml): # type: (Path) -> str content = """ [tool.poetry] name = "poetry" [tool.poetry.dependencies] python = "^3.5" """ with pyproject_toml.open(mode="a") as f: f.write(decode(content)) return content
def run(self, *args, **kwargs): # type: (...) -> str folder = kwargs.pop("folder", None) if folder: args = ( "--git-dir", (folder / ".git").as_posix(), "--work-tree", folder.as_posix(), ) + args return decode( subprocess.check_output(["git"] + list(args), stderr=subprocess.STDOUT)).strip()
def setup_py(self): # type: () -> Iterator[Path] setup = self._path / "setup.py" has_setup = setup.exists() if has_setup: logger.warning("A setup.py file already exists. Using it.") else: with setup.open("w", encoding="utf-8") as f: f.write(decode(self.build_setup())) yield setup if not has_setup: setup.unlink()
def __init__(self, requires_git_presence=False): self._config = {} try: config_list = decode( subprocess.check_output(["git", "config", "-l"], stderr=subprocess.STDOUT)) m = re.findall("(?ms)^([^=]+)=(.*?)$", config_list) if m: for group in m: self._config[group[0]] = group[1] except (subprocess.CalledProcessError, OSError): if requires_git_presence: raise
def get_vcs(directory): # type: (Path) -> Git working_dir = Path.cwd() os.chdir(str(directory.resolve())) try: git_dir = decode( subprocess.check_output(["git", "rev-parse", "--show-toplevel"], stderr=subprocess.STDOUT)).strip() vcs = Git(Path(git_dir)) except (subprocess.CalledProcessError, OSError): vcs = None finally: os.chdir(str(working_dir)) return vcs
def _write_record(self, wheel): # Write a record of the files in the wheel with self._write_to_zip(wheel, self.dist_info + "/RECORD") as f: record = StringIO() if not PY2 else BytesIO() csv_writer = csv.writer( record, delimiter=csv.excel.delimiter, quotechar=csv.excel.quotechar, lineterminator="\n", ) for path, hash, size in self._records: csv_writer.writerow((path, "sha256={}".format(hash), size)) # RECORD itself is recorded with no hash or size csv_writer.writerow((self.dist_info + "/RECORD", "", "")) f.write(decode(record.getvalue()))
def _write_metadata_file(self, fp): """ Write out metadata in the 2.x format (email like) """ fp.write(decode(self.get_metadata_content()))
def test_prepare_metadata_for_build_wheel(): entry_points = """\ [console_scripts] extra-script=my_package.extra:main[time] my-2nd-script=my_package:main2 my-script=my_package:main """ wheel_data = """\ Wheel-Version: 1.0 Generator: poetry {} Root-Is-Purelib: true Tag: py3-none-any """.format(__version__) metadata = """\ 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: 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 ========== """ with temporary_directory() as tmp_dir, cwd( os.path.join(fixtures, "complete")): dirname = api.prepare_metadata_for_build_wheel(tmp_dir) assert "my_package-1.2.3.dist-info" == dirname dist_info = Path(tmp_dir, dirname) assert (dist_info / "entry_points.txt").exists() assert (dist_info / "WHEEL").exists() assert (dist_info / "METADATA").exists() with (dist_info / "entry_points.txt").open(encoding="utf-8") as f: assert entry_points == decode(f.read()) with (dist_info / "WHEEL").open(encoding="utf-8") as f: assert wheel_data == decode(f.read()) with (dist_info / "METADATA").open(encoding="utf-8") as f: assert metadata == decode(f.read())
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()
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()