feat: requires-python (#536)

* feat: requires-python

refactor: updating to current proposal

fix: add tests and fix a few issues

docs: Update mostly from @joerick

docs: update README from readthedocs

* refactor: pull out config file reading

* fix: always assume highest Python patch version

* refactor: try new design

* refactor: function and bump MyPy to 0.800

* fix: tighten AST to call only, add docs

* fix: address review points from @joerick
This commit is contained in:
Henry Schreiner
2021-01-31 17:14:15 -05:00
committed by GitHub
parent b95dca50aa
commit eb700a164c
17 changed files with 591 additions and 30 deletions
+19 -2
View File
@@ -13,12 +13,15 @@ from typing import Dict, List, NamedTuple, Optional, Set
import bracex
import certifi
import toml
from packaging.specifiers import SpecifierSet
from packaging.version import Version
from .architecture import Architecture
from .environment import ParsedEnvironment
from .typing import PathOrStr, PlatformName
resources_dir = Path(__file__).parent / 'resources'
get_pip_script = resources_dir / 'get-pip.py'
install_certifi_script = resources_dir / "install_certifi.py"
@@ -53,13 +56,25 @@ class IdentifierSelector:
"""
This class holds a set of build/skip patterns. You call an instance with a
build identifier, and it returns True if that identifier should be
included.
included. Only call this on valid identifiers, ones that have at least 2
numeric digits before the first dash.
"""
def __init__(self, *, build_config: str, skip_config: str):
def __init__(self, *, build_config: str, skip_config: str, requires_python: Optional[SpecifierSet] = None):
self.build_patterns = build_config.split()
self.skip_patterns = skip_config.split()
self.requires_python = requires_python
def __call__(self, build_id: str) -> bool:
# Filter build selectors by python_requires if set
if self.requires_python is not None:
py_ver_str = build_id.split('-')[0]
major = int(py_ver_str[2])
minor = int(py_ver_str[3:])
version = Version(f"{major}.{minor}.99")
if not self.requires_python.contains(version):
return False
build_patterns = itertools.chain.from_iterable(bracex.expand(p) for p in self.build_patterns)
skip_patterns = itertools.chain.from_iterable(bracex.expand(p) for p in self.skip_patterns)
@@ -78,6 +93,8 @@ class BuildSelector(IdentifierSelector):
pass
# Note that requires-python is not needed for TestSelector, as you can't test
# what you can't build.
class TestSelector(IdentifierSelector):
def __init__(self, *, skip_config: str):
super().__init__(build_config="*", skip_config=skip_config)