Commit 141d9ebb by Arun Babu Neelicattu Committed by Bjorn Neergaard

info: cache get metadata from pep517

parent 4423fd6a
from __future__ import annotations from __future__ import annotations
import functools
import glob import glob
import logging import logging
import os import os
...@@ -450,76 +451,6 @@ class PackageInfo: ...@@ -450,76 +451,6 @@ class PackageInfo:
return None return None
@classmethod @classmethod
def _pep517_metadata(cls, path: Path) -> PackageInfo:
"""
Helper method to use PEP-517 library to build and read package metadata.
:param path: Path to package source to build and read metadata for.
"""
info = None
try:
info = cls.from_setup_files(path)
if all([info.version, info.name, info.requires_dist]):
return info
except PackageInfoError:
pass
with ephemeral_environment(
flags={"no-pip": False, "no-setuptools": False, "no-wheel": False}
) as venv:
# TODO: cache PEP 517 build environment corresponding to each project venv
dest_dir = venv.path.parent / "dist"
dest_dir.mkdir()
pep517_meta_build_script = PEP517_META_BUILD.format(
source=path.as_posix(), dest=dest_dir.as_posix()
)
try:
venv.run_pip(
"install",
"--disable-pip-version-check",
"--ignore-installed",
*PEP517_META_BUILD_DEPS,
)
venv.run(
"python",
"-",
input_=pep517_meta_build_script,
)
return cls.from_metadata(dest_dir)
except EnvCommandError as e:
# something went wrong while attempting pep517 metadata build
# fallback to egg_info if setup.py available
cls._log(f"PEP517 build failed: {e}", level="debug")
setup_py = path / "setup.py"
if not setup_py.exists():
raise PackageInfoError(
path,
e,
"No fallback setup.py file was found to generate egg_info.",
)
cwd = Path.cwd()
os.chdir(path.as_posix())
try:
venv.run("python", "setup.py", "egg_info")
return cls.from_metadata(path)
except EnvCommandError as fbe:
raise PackageInfoError(
path, "Fallback egg_info generation failed.", fbe
)
finally:
os.chdir(cwd.as_posix())
if info:
cls._log(f"Falling back to parsed setup.py file for {path}", "debug")
return info
# if we reach here, everything has failed and all hope is lost
raise PackageInfoError(path, "Exhausted all core metadata sources.")
@classmethod
def from_directory(cls, path: Path, disable_build: bool = False) -> PackageInfo: def from_directory(cls, path: Path, disable_build: bool = False) -> PackageInfo:
""" """
Generate package information from a package source directory. If `disable_build` Generate package information from a package source directory. If `disable_build`
...@@ -542,7 +473,7 @@ class PackageInfo: ...@@ -542,7 +473,7 @@ class PackageInfo:
if disable_build: if disable_build:
info = cls.from_setup_files(path) info = cls.from_setup_files(path)
else: else:
info = cls._pep517_metadata(path) info = get_pep517_metadata(path)
except PackageInfoError: except PackageInfoError:
if not info: if not info:
raise raise
...@@ -609,3 +540,74 @@ class PackageInfo: ...@@ -609,3 +540,74 @@ class PackageInfo:
return cls.from_bdist(path=path) return cls.from_bdist(path=path)
except PackageInfoError: except PackageInfoError:
return cls.from_sdist(path=path) return cls.from_sdist(path=path)
@functools.lru_cache(maxsize=None)
def get_pep517_metadata(path: Path) -> PackageInfo:
"""
Helper method to use PEP-517 library to build and read package metadata.
:param path: Path to package source to build and read metadata for.
"""
info = None
try:
info = PackageInfo.from_setup_files(path)
if all([info.version, info.name, info.requires_dist]):
return info
except PackageInfoError:
pass
with ephemeral_environment(
flags={"no-pip": False, "no-setuptools": False, "no-wheel": False}
) as venv:
# TODO: cache PEP 517 build environment corresponding to each project venv
dest_dir = venv.path.parent / "dist"
dest_dir.mkdir()
pep517_meta_build_script = PEP517_META_BUILD.format(
source=path.as_posix(), dest=dest_dir.as_posix()
)
try:
venv.run_pip(
"install",
"--disable-pip-version-check",
"--ignore-installed",
*PEP517_META_BUILD_DEPS,
)
venv.run(
"python",
"-",
input_=pep517_meta_build_script,
)
info = PackageInfo.from_metadata(dest_dir)
except EnvCommandError as e:
# something went wrong while attempting pep517 metadata build
# fallback to egg_info if setup.py available
logger.debug("PEP517 build failed: %s", e)
setup_py = path / "setup.py"
if not setup_py.exists():
raise PackageInfoError(
path,
e,
"No fallback setup.py file was found to generate egg_info.",
)
cwd = Path.cwd()
os.chdir(path.as_posix())
try:
venv.run("python", "setup.py", "egg_info")
info = PackageInfo.from_metadata(path)
except EnvCommandError as fbe:
raise PackageInfoError(
path, "Fallback egg_info generation failed.", fbe
)
finally:
os.chdir(cwd.as_posix())
if info:
logger.debug("Falling back to parsed setup.py file for %s", path)
return info
# if we reach here, everything has failed and all hope is lost
raise PackageInfoError(path, "Exhausted all core metadata sources.")
...@@ -233,15 +233,14 @@ def download_mock(mocker: MockerFixture) -> None: ...@@ -233,15 +233,14 @@ def download_mock(mocker: MockerFixture) -> None:
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def pep517_metadata_mock(mocker: MockerFixture) -> None: def pep517_metadata_mock(mocker: MockerFixture) -> None:
@classmethod def get_pep517_metadata(path: Path) -> PackageInfo:
def _pep517_metadata(cls: PackageInfo, path: Path) -> PackageInfo:
with suppress(PackageInfoError): with suppress(PackageInfoError):
return PackageInfo.from_setup_files(path) return PackageInfo.from_setup_files(path)
return PackageInfo(name="demo", version="0.1.2") return PackageInfo(name="demo", version="0.1.2")
mocker.patch( mocker.patch(
"poetry.inspection.info.PackageInfo._pep517_metadata", "poetry.inspection.info.get_pep517_metadata",
_pep517_metadata, get_pep517_metadata,
) )
......
...@@ -144,7 +144,7 @@ def test_search_for_vcs_read_setup_raises_error_if_no_version( ...@@ -144,7 +144,7 @@ def test_search_for_vcs_read_setup_raises_error_if_no_version(
provider: Provider, mocker: MockerFixture provider: Provider, mocker: MockerFixture
): ):
mocker.patch( mocker.patch(
"poetry.inspection.info.PackageInfo._pep517_metadata", "poetry.inspection.info.get_pep517_metadata",
return_value=PackageInfo(name="demo", version=None), return_value=PackageInfo(name="demo", version=None),
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment