Skip to content

Commit

Permalink
compat: create separate importlib, tarfile and tomllib shims
Browse files Browse the repository at this point in the history
  • Loading branch information
layday committed Feb 27, 2024
1 parent 894998a commit 42231a7
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 46 deletions.
7 changes: 1 addition & 6 deletions src/build/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import pyproject_hooks

from . import env
from ._compat import tomllib
from ._exceptions import (
BuildBackendException,
BuildException,
Expand All @@ -34,12 +35,6 @@
from ._util import check_dependency, parse_wheel_filename


if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib


RunnerType = Callable[[Sequence[str], Optional[str], Optional[Mapping[str, str]]], None]
ConfigSettingsType = Mapping[str, Union[str, Sequence[str]]]
PathType = Union[str, 'os.PathLike[str]']
Expand Down
4 changes: 2 additions & 2 deletions src/build/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def build_package_via_sdist(
:param isolation: Isolate the build in a separate environment
:param skip_dependency_check: Do not perform the dependency check
"""
from ._util import TarFile
from ._compat import tarfile

if 'sdist' in distributions:
msg = 'Only binary distributions are allowed but sdist was specified'
Expand All @@ -243,7 +243,7 @@ def build_package_via_sdist(
built: list[str] = []
if distributions:
# extract sdist
with TarFile.open(sdist) as t:
with tarfile.TarFile.open(sdist) as t:
t.extractall(sdist_out)
try:
_ProjectBuilder.log(f'Building {_natural_language_list(distributions)} from sdist')
Expand Down
Empty file added src/build/_compat/__init__.py
Empty file.
7 changes: 6 additions & 1 deletion src/build/_importlib.py → src/build/_compat/importlib.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import sys


Expand All @@ -12,4 +14,7 @@
# helps bootstrapping when dependencies aren't installed
from importlib import metadata

__all__ = ['metadata']

__all__ = [
'metadata',
]
32 changes: 32 additions & 0 deletions src/build/_compat/tarfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from __future__ import annotations

import sys
import tarfile
import typing


if typing.TYPE_CHECKING:
TarFile = tarfile.TarFile

else:
# Per https://peps.python.org/pep-0706/, the "data" filter will become
# the default in Python 3.14. The first series of releases with the filter
# had a broken filter that could not process symlinks correctly.
if (
(3, 8, 18) <= sys.version_info < (3, 9)
or (3, 9, 18) <= sys.version_info < (3, 10)
or (3, 10, 13) <= sys.version_info < (3, 11)
or (3, 11, 5) <= sys.version_info < (3, 12)
or (3, 12) <= sys.version_info < (3, 14)
):

class TarFile(tarfile.TarFile):
extraction_filter = staticmethod(tarfile.data_filter)

else:
TarFile = tarfile.TarFile


__all__ = [
'TarFile',
]
16 changes: 16 additions & 0 deletions src/build/_compat/tomllib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from __future__ import annotations

import sys


if sys.version_info >= (3, 11):
from tomllib import TOMLDecodeError, load, loads
else:
from tomli import TOMLDecodeError, load, loads


__all__ = [
'TOMLDecodeError',
'load',
'loads',
]
31 changes: 3 additions & 28 deletions src/build/_util.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
from __future__ import annotations

import re
import sys
import tarfile
import typing

from collections.abc import Iterator, Set

Expand All @@ -27,7 +24,7 @@ def check_dependency(
"""
import packaging.requirements

from ._importlib import metadata
from ._compat import importlib

req = packaging.requirements.Requirement(req_string)
normalised_req_string = str(req)
Expand All @@ -48,8 +45,8 @@ def check_dependency(
return

try:
dist = metadata.distribution(req.name)
except metadata.PackageNotFoundError:
dist = importlib.metadata.distribution(req.name)
except importlib.metadata.PackageNotFoundError:
# dependency is not installed in the environment.
yield (*ancestral_req_strings, normalised_req_string)
else:
Expand All @@ -64,25 +61,3 @@ def check_dependency(

def parse_wheel_filename(filename: str) -> re.Match[str] | None:
return _WHEEL_FILENAME_REGEX.match(filename)


if typing.TYPE_CHECKING:
TarFile = tarfile.TarFile

else:
# Per https://peps.python.org/pep-0706/, the "data" filter will become
# the default in Python 3.14. The first series of releases with the filter
# had a broken filter that could not process symlinks correctly.
if (
(3, 8, 18) <= sys.version_info < (3, 9)
or (3, 9, 18) <= sys.version_info < (3, 10)
or (3, 10, 13) <= sys.version_info < (3, 11)
or (3, 11, 5) <= sys.version_info < (3, 12)
or (3, 12) <= sys.version_info < (3, 14)
):

class TarFile(tarfile.TarFile):
extraction_filter = staticmethod(tarfile.data_filter)

else:
TarFile = tarfile.TarFile
4 changes: 2 additions & 2 deletions src/build/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ def _has_valid_pip(**distargs: object) -> bool:

import packaging.version

from ._importlib import metadata
from ._compat import importlib

name = 'pip'

try:
pip_distribution = next(iter(metadata.distributions(name=name, **distargs)))
pip_distribution = next(iter(importlib.metadata.distributions(name=name, **distargs)))
except StopIteration:
raise ModuleNotFoundError(name) from None

Expand Down
8 changes: 4 additions & 4 deletions src/build/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@
import pyproject_hooks

from . import PathType, ProjectBuilder, RunnerType
from ._importlib import metadata
from ._compat import importlib
from .env import DefaultIsolatedEnv


def _project_wheel_metadata(builder: ProjectBuilder) -> metadata.PackageMetadata:
def _project_wheel_metadata(builder: ProjectBuilder) -> importlib.metadata.PackageMetadata:
with tempfile.TemporaryDirectory() as tmpdir:
path = pathlib.Path(builder.metadata_path(tmpdir))
return metadata.PathDistribution(path).metadata
return importlib.metadata.PathDistribution(path).metadata


def project_wheel_metadata(
source_dir: PathType,
isolated: bool = True,
*,
runner: RunnerType = pyproject_hooks.quiet_subprocess_runner,
) -> metadata.PackageMetadata:
) -> importlib.metadata.PackageMetadata:
"""
Return the wheel metadata for a project.
Expand Down
2 changes: 1 addition & 1 deletion tests/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def test_pip_needs_upgrade_mac_os_11(mocker, pip_version, arch):
mocker.patch('platform.system', return_value='Darwin')
mocker.patch('platform.machine', return_value=arch)
mocker.patch('platform.mac_ver', return_value=('11.0', ('', '', ''), ''))
mocker.patch('build._importlib.metadata.distributions', return_value=(SimpleNamespace(version=pip_version),))
mocker.patch('build._compat.importlib.metadata.distributions', return_value=(SimpleNamespace(version=pip_version),))

min_version = Version('20.3' if arch == 'x86_64' else '21.0.1')
with build.env.DefaultIsolatedEnv():
Expand Down
2 changes: 1 addition & 1 deletion tests/test_projectbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

import build

from build import _importlib
from build._compat import importlib as _importlib


build_open_owner = 'builtins'
Expand Down
6 changes: 5 additions & 1 deletion tests/test_self_packaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
sdist_patterns = {
'docs/*.rst',
'src/build/*.py',
'src/build/_compat/*.py',
'tests/*.py',
'tests/packages/*/*.py',
'tests/packages/*/*/*.py',
Expand All @@ -46,8 +47,11 @@
wheel_files = {
'build/__init__.py',
'build/__main__.py',
'build/_compat/__init__.py',
'build/_compat/importlib.py',
'build/_compat/tarfile.py',
'build/_compat/tomllib.py',
'build/_exceptions.py',
'build/_importlib.py',
'build/_util.py',
'build/env.py',
'build/py.typed',
Expand Down

0 comments on commit 42231a7

Please sign in to comment.