Skip to content

Commit

Permalink
inspection: use pep517.meta.build from shell
Browse files Browse the repository at this point in the history
With change we execute pep517 metadata build from within a new venv
retaining old `python setup.py egg_info` behaviour. We fallback to the
old behaviour if pep517 metadata build fails.
  • Loading branch information
abn committed Jul 10, 2020
1 parent 35c0332 commit 4a2712d
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 67 deletions.
93 changes: 50 additions & 43 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

85 changes: 68 additions & 17 deletions poetry/inspection/info.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import glob
import logging
import subprocess
import os
import tarfile
import zipfile

Expand All @@ -12,8 +12,6 @@

import pkginfo

from pep517.build import compat_system as pep517_compat_system
from pep517.meta import build as pep517_metadata_build
from poetry.core.factory import Factory
from poetry.core.packages import Package
from poetry.core.packages import ProjectPackage
Expand All @@ -23,12 +21,26 @@
from poetry.core.utils.helpers import parse_requires
from poetry.core.utils.helpers import temporary_directory
from poetry.core.version.markers import InvalidMarker
from poetry.utils.env import EnvCommandError
from poetry.utils.env import EnvManager
from poetry.utils.env import VirtualEnv
from poetry.utils.setup_reader import SetupReader
from poetry.utils.toml_file import TomlFile


logger = logging.getLogger(__name__)

PEP517_META_BUILD = """\
import pep517.build
import pep517.meta
path='{source}'
system=pep517.build.compat_system(path)
pep517.meta.build(source_dir=path, dest='{dest}', system=system)
"""

PEP517_META_BUILD_DEPS = ["pep517===0.8.2", "toml==0.10.1"]


class PackageInfoError(ValueError):
def __init__(self, path): # type: (Union[Path, str]) -> None
Expand Down Expand Up @@ -255,6 +267,10 @@ def _from_sdist_file(cls, path): # type: (Path) -> PackageInfo

return info.update(new_info)

@staticmethod
def has_setup_files(path): # type: (Path) -> bool
return any((path / f).exists() for f in SetupReader.FILES)

@classmethod
def from_setup_files(cls, path): # type: (Path) -> PackageInfo
"""
Expand All @@ -264,7 +280,7 @@ def from_setup_files(cls, path): # type: (Path) -> PackageInfo
:param path: Path to `setup.py` file
"""
if not any((path / f).exists() for f in SetupReader.FILES):
if not cls.has_setup_files(path):
raise PackageInfoError(path)

try:
Expand Down Expand Up @@ -416,21 +432,56 @@ def _pep517_metadata(cls, path): # type (Path) -> PackageInfo
except PackageInfoError:
pass

try:
with temporary_directory() as tmp_dir:
pep517_metadata_build(
source_dir=path.as_posix(),
dest=tmp_dir,
system=pep517_compat_system(source_dir=path.as_posix()),
with temporary_directory() as tmp_dir:
# TODO: cache PEP 517 build environment corresponding to each project venv
venv_dir = Path(tmp_dir) / ".venv"
EnvManager.build_venv(venv_dir.as_posix())
venv = VirtualEnv(venv_dir, venv_dir)

dest_dir = Path(tmp_dir) / "dist"
dest_dir.mkdir()

try:
venv.run(
"python",
"-m",
"pip",
"install",
"--disable-pip-version-check",
"--ignore-installed",
*PEP517_META_BUILD_DEPS
)
return cls.from_metadata(Path(tmp_dir))
except subprocess.CalledProcessError:
cls._log("PEP 517 metadata build failed for {}".format(path), "debug")
if info:
cls._log(
"Falling back to parsed setup.py file for {}".format(path), "debug"
venv.run(
"python",
"-",
input_=PEP517_META_BUILD.format(
source=path.as_posix(), dest=dest_dir.as_posix()
),
)
return info
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("PEP517 build failed: {}".format(e), level="debug")
setup_py = path / "setup.py"
if not setup_py.exists():
raise PackageInfoError(path)

cwd = Path.cwd()
os.chdir(path.as_posix())
try:
venv.run("python", "setup.py", "egg_info")
return cls.from_metadata(path)
except EnvCommandError:
raise PackageInfoError(path)
finally:
os.chdir(cwd.as_posix())

if info:
cls._log(
"Falling back to parsed setup.py file for {}".format(path), "debug"
)
return info

# if we reach here, everything has failed and all hope is lost
raise PackageInfoError(path)
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ keyring = [
# Use subprocess32 for Python 2.7
subprocess32 = { version = "^3.5", python = "~2.7" }
importlib-metadata = {version = "^1.6.0", python = "<3.8"}
pep517 = "^0.8.2"

[tool.poetry.dev-dependencies]
pytest = [
Expand Down
Loading

0 comments on commit 4a2712d

Please sign in to comment.