Refactor and add tests
This commit is contained in:
		
							parent
							
								
									e6c1981103
								
							
						
					
					
						commit
						50645e10a3
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -0,0 +1 @@ | |||||||
|  | __pycache__/ | ||||||
| @ -45,6 +45,10 @@ We plan to preserve existing Python flags in shebangs, but the work is not yet f | |||||||
| The PEPs don't (yet) define a way to specify test dependencies and test runners. | The PEPs don't (yet) define a way to specify test dependencies and test runners. | ||||||
| That means you still need to handle test dependencies and `%check` on your own. | That means you still need to handle test dependencies and `%check` on your own. | ||||||
| 
 | 
 | ||||||
|  | Extras are currently ignored. | ||||||
|  | 
 | ||||||
|  | Some valid Python version specifiers are not supported. | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| [PEP 517]: https://www.python.org/dev/peps/pep-0517/ | [PEP 517]: https://www.python.org/dev/peps/pep-0517/ | ||||||
| [PEP 518]: https://www.python.org/dev/peps/pep-0518/ | [PEP 518]: https://www.python.org/dev/peps/pep-0518/ | ||||||
|  | |||||||
| @ -23,6 +23,6 @@ echo 'python3dist(packaging)' | |||||||
| echo 'python3dist(pip) >= 19' | echo 'python3dist(pip) >= 19' | ||||||
| echo 'python3dist(pytoml)' | echo 'python3dist(pytoml)' | ||||||
| if [ -f %{__python3} ]; then | if [ -f %{__python3} ]; then | ||||||
|   %{__python3} -I %{_rpmconfigdir}/redhat/pyproject_buildrequires.py |   %{__python3} -I %{_rpmconfigdir}/redhat/pyproject_buildrequires.py %{?*} | ||||||
| fi | fi | ||||||
| } | } | ||||||
|  | |||||||
| @ -12,6 +12,9 @@ Source1:        pyproject_buildrequires.py | |||||||
| Source8:        README.md | Source8:        README.md | ||||||
| Source9:        LICENSE | Source9:        LICENSE | ||||||
| 
 | 
 | ||||||
|  | Source10:       test_pyproject_buildrequires.py | ||||||
|  | Source11:       testcases.yaml | ||||||
|  | 
 | ||||||
| URL:            https://src.fedoraproject.org/rpms/pyproject-rpm-macros | URL:            https://src.fedoraproject.org/rpms/pyproject-rpm-macros | ||||||
| 
 | 
 | ||||||
| BuildArch:      noarch | BuildArch:      noarch | ||||||
| @ -23,6 +26,14 @@ BuildArch:      noarch | |||||||
| Requires: python3-pip >= 19 | Requires: python3-pip >= 19 | ||||||
| Requires: python3-devel | Requires: python3-devel | ||||||
| 
 | 
 | ||||||
|  | # Test dependencies | ||||||
|  | BuildRequires: python3dist(pytest) | ||||||
|  | BuildRequires: python3dist(pyyaml) | ||||||
|  | BuildRequires: python3dist(packaging) | ||||||
|  | BuildRequires: python3dist(pytoml) | ||||||
|  | BuildRequires: python3dist(pip) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| %description | %description | ||||||
| This is a provisional implementation of pyproject RPM macros for Fedora 30+. | This is a provisional implementation of pyproject RPM macros for Fedora 30+. | ||||||
| These macros are useful for packaging Python projects that use the PEP 517 | These macros are useful for packaging Python projects that use the PEP 517 | ||||||
| @ -45,6 +56,10 @@ mkdir -p %{buildroot}%{_rpmconfigdir}/redhat | |||||||
| install -m 644 macros.pyproject %{buildroot}%{_rpmmacrodir}/ | install -m 644 macros.pyproject %{buildroot}%{_rpmmacrodir}/ | ||||||
| install -m 644 pyproject_buildrequires.py %{buildroot}%{_rpmconfigdir}/redhat/ | install -m 644 pyproject_buildrequires.py %{buildroot}%{_rpmconfigdir}/redhat/ | ||||||
| 
 | 
 | ||||||
|  | %check | ||||||
|  | %{__python3} -m pytest -vv | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| %files | %files | ||||||
| %{_rpmmacrodir}/macros.pyproject | %{_rpmmacrodir}/macros.pyproject | ||||||
| %{_rpmconfigdir}/redhat/pyproject_buildrequires.py | %{_rpmconfigdir}/redhat/pyproject_buildrequires.py | ||||||
|  | |||||||
| @ -1,84 +1,216 @@ | |||||||
| import sys | import sys | ||||||
| import importlib | import importlib | ||||||
|  | import argparse | ||||||
|  | import functools | ||||||
|  | import traceback | ||||||
|  | import contextlib | ||||||
|  | from io import StringIO | ||||||
|  | import subprocess | ||||||
|  | import pathlib | ||||||
|  | import re | ||||||
|  | 
 | ||||||
|  | print_err = functools.partial(print, file=sys.stderr) | ||||||
|  | 
 | ||||||
|  | # Some valid Python version specifiers are not supported. | ||||||
|  | # Whitelist characters we can handle. | ||||||
|  | VERSION_RE = re.compile('[a-zA-Z0-9.-]+') | ||||||
|  | 
 | ||||||
|  | class EndPass(Exception): | ||||||
|  |     """End current pass of generating requirements""" | ||||||
| 
 | 
 | ||||||
| try: | try: | ||||||
|     import pytoml |     import pytoml | ||||||
|     from packaging.requirements import Requirement, InvalidRequirement |     from packaging.requirements import Requirement, InvalidRequirement | ||||||
|  |     from packaging.version import Version | ||||||
|     from packaging.utils import canonicalize_name, canonicalize_version |     from packaging.utils import canonicalize_name, canonicalize_version | ||||||
| except ImportError: |     import pip | ||||||
|  | except ImportError as e: | ||||||
|  |     print_err('Import error:', e) | ||||||
|     # already echoed by the %pyproject_buildrequires macro |     # already echoed by the %pyproject_buildrequires macro | ||||||
|     sys.exit(0) |     sys.exit(0) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| try: | @contextlib.contextmanager | ||||||
|     f = open("pyproject.toml") as f | def hook_call(): | ||||||
| except FileNotFoundError: |     captured_out = StringIO() | ||||||
|     pyproject_data = {} |     with contextlib.redirect_stdout(captured_out): | ||||||
| else: |         yield | ||||||
|     with f: |     for line in captured_out.getvalue().splitlines(): | ||||||
|         pyproject_data = pytoml.load(f) |         print_err('HOOK STDOUT:', line) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Requirements: | ||||||
|  |     """Requirement printer""" | ||||||
|  |     def __init__(self, freeze_output): | ||||||
|  |         self.installed_packages = {} | ||||||
|  |         for line in freeze_output.splitlines(): | ||||||
|  |             line = line.strip() | ||||||
|  |             if line.startswith('#'): | ||||||
|  |                 continue | ||||||
|  |             name, version = line.split('==') | ||||||
|  |             self.installed_packages[name.strip()] = Version(version) | ||||||
|  | 
 | ||||||
|  |         self.missing_requirements = False | ||||||
|  | 
 | ||||||
|  |     def add(self, requirement_str, *, source=None): | ||||||
|  |         """Output a Python-style requirement string as RPM dep""" | ||||||
|  |         print_err(f'Handling {requirement_str} from {source}') | ||||||
| 
 | 
 | ||||||
|     try: |  | ||||||
|         backend_name = pyproject_data["build-system"]["build-backend"] |  | ||||||
|     except KeyError: |  | ||||||
|         try: |         try: | ||||||
|             import setuptools.build_meta |             requirement = Requirement(requirement_str) | ||||||
|         except ImportError: |         except InvalidRequirement as e: | ||||||
|             print("python3dist(setuptools) >= 40.8") |             print_err( | ||||||
|             print("python3dist(wheel)") |                 f'"WARNING: Skipping invalid requirement: {requirement_str}\n' | ||||||
|             sys.exit(0) |                 + f'    {e}', | ||||||
| 
 |  | ||||||
|         backend = setuptools.build_meta |  | ||||||
|     else: |  | ||||||
|         try: |  | ||||||
|             backend = importlib.import_module(backend_name) |  | ||||||
|         except ImportError: |  | ||||||
|             backend = None |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| requirements = set() |  | ||||||
| rpm_requirements = set() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def add_requirement(requirement): |  | ||||||
|     try: |  | ||||||
|         requirements.add(Requirement(requirement)) |  | ||||||
|     except InvalidRequirement as e: |  | ||||||
|         print( |  | ||||||
|             f"WARNING: Skipping invalid requirement: {requirement}\n         {e}", |  | ||||||
|             file=sys.stderr, |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| if "requires" in pyproject_data.get("build-system", {}): |  | ||||||
|     for requirement in pyproject_data["build-system"]["requires"]: |  | ||||||
|         add_requirement(requirement) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| get_requires = getattr(backend, "get_requires_for_build_wheel", None) |  | ||||||
| if get_requires: |  | ||||||
|     for requirement in get_requires(): |  | ||||||
|         add_requirement(requirement) |  | ||||||
| 
 |  | ||||||
| for requirement in requirements: |  | ||||||
|     name = canonicalize_name(requirement.name) |  | ||||||
|     if requirement.marker is not None and not requirement.marker.evaluate(): |  | ||||||
|         continue |  | ||||||
|     together = [] |  | ||||||
|     for specifier in requirement.specifier: |  | ||||||
|         version = canonicalize_version(specifier.version) |  | ||||||
|         if specifier.operator == "!=": |  | ||||||
|             together.append( |  | ||||||
|                 f"(python3dist({name}) < {version} or python3dist({name}) >= {version}.0)" |  | ||||||
|             ) |             ) | ||||||
|  |             return | ||||||
|  | 
 | ||||||
|  |         name = canonicalize_name(requirement.name) | ||||||
|  |         if requirement.marker is not None and not requirement.marker.evaluate(): | ||||||
|  |             print_err(f'Ignoring alien requirement:', requirement_str) | ||||||
|  |             return | ||||||
|  | 
 | ||||||
|  |         installed = self.installed_packages.get(requirement.name) | ||||||
|  |         if installed and installed in requirement.specifier: | ||||||
|  |             print_err(f'Requirement satisfied: {requirement_str}') | ||||||
|  |             print_err(f'   (installed: {requirement.name} {installed})') | ||||||
|         else: |         else: | ||||||
|             together.append(f"python3dist({name}) {specifier.operator} {version}") |             self.missing_requirements = True | ||||||
|     if len(together) == 0: | 
 | ||||||
|         rpm_requirements.add(f"python3dist({name})") |         together = [] | ||||||
|     if len(together) == 1: |         for specifier in sorted( | ||||||
|         rpm_requirements.add(together[0]) |             requirement.specifier, | ||||||
|     elif len(together) > 1: |             key=lambda s: (s.operator, s.version), | ||||||
|         rpm_requirements.add(f"({' and '.join(together)})") |         ): | ||||||
|  |             version = canonicalize_version(specifier.version) | ||||||
|  |             print_err(version) | ||||||
|  |             if not VERSION_RE.fullmatch(str(specifier.version)): | ||||||
|  |                 raise ValueError( | ||||||
|  |                     f'Unknown character in version: {specifier.version}. ' | ||||||
|  |                     + '(This is probably a bug in pyproject-rpm-macros.)', | ||||||
|  |                 ) | ||||||
|  |             if specifier.operator == "!=": | ||||||
|  |                 lower = python3dist(name, '<', version) | ||||||
|  |                 higher = python3dist(name, '>', f'{version}.0') | ||||||
|  |                 together.append( | ||||||
|  |                     f"({lower} or {higher})" | ||||||
|  |                 ) | ||||||
|  |             else: | ||||||
|  |                 together.append(python3dist(name, specifier.operator, version)) | ||||||
|  |         if len(together) == 0: | ||||||
|  |             print(python3dist(name)) | ||||||
|  |         elif len(together) == 1: | ||||||
|  |             print(together[0]) | ||||||
|  |         else: | ||||||
|  |             print(f"({' and '.join(together)})") | ||||||
|  | 
 | ||||||
|  |     def check(self, *, source=None): | ||||||
|  |         """End current pass if any unsatisfied dependencies were output""" | ||||||
|  |         if self.missing_requirements: | ||||||
|  |             print_err(f'Exiting dependency generation pass: {source}') | ||||||
|  |             raise EndPass(source) | ||||||
|  | 
 | ||||||
|  |     def extend(self, requirement_strs, *, source=None): | ||||||
|  |         """add() several requirements""" | ||||||
|  |         for req_str in requirement_strs: | ||||||
|  |             self.add(req_str, source=source) | ||||||
|  | 
 | ||||||
|  | def get_backend(requirements): | ||||||
|  |     try: | ||||||
|  |         f = open('pyproject.toml') | ||||||
|  |     except FileNotFoundError: | ||||||
|  |         pyproject_data = {} | ||||||
|  |     else: | ||||||
|  |         with f: | ||||||
|  |             pyproject_data = pytoml.load(f) | ||||||
|  | 
 | ||||||
|  |     buildsystem_data = pyproject_data.get("build-system", {}) | ||||||
|  |     requirements.extend( | ||||||
|  |         buildsystem_data.get("requires", ()), | ||||||
|  |         source='build-system.requires', | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     backend_name = buildsystem_data.get('build-backend') | ||||||
|  |     if not backend_name: | ||||||
|  |         requirements.add("setuptools >= 40.8", source='default build backend') | ||||||
|  |         requirements.add("wheel", source='default build backend') | ||||||
|  | 
 | ||||||
|  |         backend_name = 'setuptools.build_meta' | ||||||
|  | 
 | ||||||
|  |     requirements.check(source='build backend') | ||||||
|  | 
 | ||||||
|  |     backend_path = buildsystem_data.get('backend-path') | ||||||
|  |     if backend_path: | ||||||
|  |         sys.path.insert(0, backend_path) | ||||||
|  | 
 | ||||||
|  |     return importlib.import_module(backend_name) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| print(*sorted(rpm_requirements), sep="\n") | def generate_build_requirements(backend, requirements): | ||||||
|  |     get_requires = getattr(backend, "get_requires_for_build_wheel", None) | ||||||
|  |     if get_requires: | ||||||
|  |         with hook_call(): | ||||||
|  |             new_reqs = get_requires() | ||||||
|  |         requirements.extend(new_reqs, source='get_requires_for_build_wheel') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def python3dist(name, op=None, version=None): | ||||||
|  |     if op is None: | ||||||
|  |         if version is not None: | ||||||
|  |             raise AssertionError('op and version go together') | ||||||
|  |         return f'python3dist({name})' | ||||||
|  |     else: | ||||||
|  |         return f'python3dist({name}) {op} {version}' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def generate_requires(freeze_output): | ||||||
|  |     requirements = Requirements(freeze_output) | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         backend = get_backend(requirements) | ||||||
|  |         generate_build_requirements(backend, requirements) | ||||||
|  |     except EndPass: | ||||||
|  |         return 0 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def main(argv): | ||||||
|  |     parser = argparse.ArgumentParser( | ||||||
|  |         description='Generate BuildRequires for a Python project.' | ||||||
|  |     ) | ||||||
|  |     parser.add_argument( | ||||||
|  |         '--runtime', action='store_true', | ||||||
|  |         help='Generate run-time requirements (not implemented)', | ||||||
|  |     ) | ||||||
|  |     parser.add_argument( | ||||||
|  |         '--toxenv', metavar='TOXENVS', | ||||||
|  |         help='generate test tequirements from tox environment ' | ||||||
|  |             + '(not implemented; implies --runtime)', | ||||||
|  |     ) | ||||||
|  |     parser.add_argument( | ||||||
|  |         '--pyproject-file', default='pyproject.toml', | ||||||
|  |         help='override project file (default: pyproject.toml)', | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     args = parser.parse_args(argv) | ||||||
|  |     if args.toxenv: | ||||||
|  |         args.runtime = True | ||||||
|  |     if args.runtime: | ||||||
|  |         print_err('--runtime is not implemented') | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  |     freeze_output = subprocess.run( | ||||||
|  |         ['pip', 'freeze', '--all'], | ||||||
|  |         stdout=subprocess.PIPE, | ||||||
|  |         check=True, | ||||||
|  |     ).stdout | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         generate_requires(freeze_output) | ||||||
|  |     except Exception as e: | ||||||
|  |         # Log the traceback explicitly (it's useful debug info) | ||||||
|  |         traceback.print_exc() | ||||||
|  |         exit(1) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     main(sys.argv[1:]) | ||||||
|  | |||||||
							
								
								
									
										40
									
								
								test_pyproject_buildrequires.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								test_pyproject_buildrequires.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | |||||||
|  | from pathlib import Path | ||||||
|  | import io | ||||||
|  | 
 | ||||||
|  | import pytest | ||||||
|  | import yaml | ||||||
|  | 
 | ||||||
|  | from pyproject_buildrequires import generate_requires | ||||||
|  | 
 | ||||||
|  | testcases = {} | ||||||
|  | with Path(__file__).parent.joinpath('testcases.yaml').open() as f: | ||||||
|  |     testcases = yaml.safe_load(f) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @pytest.mark.parametrize('case_name', testcases) | ||||||
|  | def test_data(case_name, capsys, tmp_path, monkeypatch): | ||||||
|  |     case = testcases[case_name] | ||||||
|  | 
 | ||||||
|  |     cwd = tmp_path.joinpath('cwd') | ||||||
|  |     cwd.mkdir() | ||||||
|  |     monkeypatch.chdir(cwd) | ||||||
|  | 
 | ||||||
|  |     if 'pyproject.toml' in case: | ||||||
|  |         cwd.joinpath('pyproject.toml').write_text(case['pyproject.toml']) | ||||||
|  | 
 | ||||||
|  |     if 'setup.py' in case: | ||||||
|  |         cwd.joinpath('setup.py').write_text(case['setup.py']) | ||||||
|  | 
 | ||||||
|  |     try: | ||||||
|  |         generate_requires( | ||||||
|  |             case['freeze_output'], | ||||||
|  |         ) | ||||||
|  |     except SystemExit as e: | ||||||
|  |         assert e.code == case['result'] | ||||||
|  |     except Exception as e: | ||||||
|  |         assert type(e).__name__ == case['except'] | ||||||
|  |     else: | ||||||
|  |         assert 0 == case['result'] | ||||||
|  | 
 | ||||||
|  |         captured = capsys.readouterr() | ||||||
|  |         assert captured.out == case['expected'] | ||||||
							
								
								
									
										119
									
								
								testcases.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								testcases.yaml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,119 @@ | |||||||
|  | No pyproject.toml, nothing installed: | ||||||
|  |   freeze_output: | | ||||||
|  |     # empty | ||||||
|  |   expected: | | ||||||
|  |     python3dist(setuptools) >= 40.8 | ||||||
|  |     python3dist(wheel) | ||||||
|  |   result: 0 | ||||||
|  | 
 | ||||||
|  | Nothing installed yet: | ||||||
|  |   freeze_output: | | ||||||
|  |     # empty | ||||||
|  |   pyproject.toml: | | ||||||
|  |     # empty | ||||||
|  |   expected: | | ||||||
|  |     python3dist(setuptools) >= 40.8 | ||||||
|  |     python3dist(wheel) | ||||||
|  |   result: 0 | ||||||
|  | 
 | ||||||
|  | Insufficient version of setuptools: | ||||||
|  |   freeze_output: | | ||||||
|  |     setuptools==5 | ||||||
|  |     wheel==1 | ||||||
|  |   pyproject.toml: | | ||||||
|  |     # empty | ||||||
|  |   expected: | | ||||||
|  |     python3dist(setuptools) >= 40.8 | ||||||
|  |     python3dist(wheel) | ||||||
|  |   result: 0 | ||||||
|  | 
 | ||||||
|  | Empty pyproject.toml, empty setup.py: | ||||||
|  |   freeze_output: | | ||||||
|  |     setuptools==50 | ||||||
|  |     wheel==1 | ||||||
|  |   setup.py: | | ||||||
|  |   expected: | | ||||||
|  |     python3dist(setuptools) >= 40.8 | ||||||
|  |     python3dist(wheel) | ||||||
|  |     python3dist(wheel) | ||||||
|  |   result: 0 | ||||||
|  | 
 | ||||||
|  | Default build system, empty setup.py: | ||||||
|  |   freeze_output: | | ||||||
|  |     setuptools==50 | ||||||
|  |     wheel==1 | ||||||
|  |   pyproject.toml: | | ||||||
|  |     # empty | ||||||
|  |   setup.py: | | ||||||
|  |   expected: | | ||||||
|  |     python3dist(setuptools) >= 40.8 | ||||||
|  |     python3dist(wheel) | ||||||
|  |     python3dist(wheel) | ||||||
|  |   result: 0 | ||||||
|  | 
 | ||||||
|  | Erroring setup.py: | ||||||
|  |   freeze_output: | | ||||||
|  |     setuptools==50 | ||||||
|  |     wheel==1 | ||||||
|  |   setup.py: | | ||||||
|  |     exit(77) | ||||||
|  |   result: 77 | ||||||
|  | 
 | ||||||
|  | Bad character in version: | ||||||
|  |   freeze_output: | | ||||||
|  |   pyproject.toml: | | ||||||
|  |     [build-system] | ||||||
|  |     requires = ["pkg == 0.$.^.*"] | ||||||
|  |   except: ValueError | ||||||
|  | 
 | ||||||
|  | Build system dependencies in pyproject.toml: | ||||||
|  |   freeze_output: | | ||||||
|  |     setuptools==50 | ||||||
|  |     wheel==1 | ||||||
|  |   pyproject.toml: | | ||||||
|  |     [build-system] | ||||||
|  |     requires = [ | ||||||
|  |         "foo", | ||||||
|  |         "ne!=1", | ||||||
|  |         "ge>=1.2", | ||||||
|  |         "le <= 1.2.3", | ||||||
|  |         "lt < 1.2.3.4      ", | ||||||
|  |         "    gt > 1.2.3.4.5", | ||||||
|  |         "combo >2, <5, != 3.0.0", | ||||||
|  |         "invalid!!ignored", | ||||||
|  |         "py2 ; python_version < '2.7'", | ||||||
|  |         "py3 ; python_version > '3.0'", | ||||||
|  |         "pkg [extra-currently-ignored]", | ||||||
|  |     ] | ||||||
|  |   expected: | | ||||||
|  |     python3dist(foo) | ||||||
|  |     (python3dist(ne) < 1 or python3dist(ne) > 1.0) | ||||||
|  |     python3dist(ge) >= 1.2 | ||||||
|  |     python3dist(le) <= 1.2.3 | ||||||
|  |     python3dist(lt) < 1.2.3.4 | ||||||
|  |     python3dist(gt) > 1.2.3.4.5 | ||||||
|  |     ((python3dist(combo) < 3 or python3dist(combo) > 3.0) and python3dist(combo) < 5 and python3dist(combo) > 2) | ||||||
|  |     python3dist(py3) | ||||||
|  |     python3dist(pkg) | ||||||
|  |     python3dist(setuptools) >= 40.8 | ||||||
|  |     python3dist(wheel) | ||||||
|  |   result: 0 | ||||||
|  | 
 | ||||||
|  | Default build system, dependencies in setup.py: | ||||||
|  |   freeze_output: | | ||||||
|  |     setuptools==50 | ||||||
|  |     wheel==1 | ||||||
|  |   setup.py: | | ||||||
|  |     from setuptools import setup | ||||||
|  |     setup( | ||||||
|  |         name='test', | ||||||
|  |         version='0.1', | ||||||
|  |         setup_requires=['foo', 'bar!=2'], | ||||||
|  |     ) | ||||||
|  |   expected: | | ||||||
|  |     python3dist(setuptools) >= 40.8 | ||||||
|  |     python3dist(wheel) | ||||||
|  |     python3dist(wheel) | ||||||
|  |     python3dist(foo) | ||||||
|  |     (python3dist(bar) < 2 or python3dist(bar) > 2.0) | ||||||
|  |   result: 0 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user