Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: tighten AST to call only
Browse files Browse the repository at this point in the history
henryiii committed Jan 23, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent be71178 commit a49bc4c
Showing 3 changed files with 22 additions and 25 deletions.
9 changes: 4 additions & 5 deletions cibuildwheel/__main__.py
Original file line number Diff line number Diff line change
@@ -159,12 +159,11 @@ def main() -> None:
test_extras = get_option_from_environment('CIBW_TEST_EXTRAS', platform=platform, default='')
build_verbosity_str = get_option_from_environment('CIBW_BUILD_VERBOSITY', platform=platform, default='')

setup_py = package_dir / 'setup.py'
setup_cfg = package_dir / 'setup.cfg'
pyproject_toml = package_dir / 'pyproject.toml'
package_files = {'setup.py', 'setup.cfg', 'pyproject.toml'}

if not pyproject_toml.exists() and not setup_cfg.exists() and not setup_py.exists():
print('cibuildwheel: Could not find setup.py, setup.cfg or pyproject.toml at root of package', file=sys.stderr)
if not any(package_dir.joinpath(name).exists() for name in package_files):
names = ', '.join(sorted(package_files, reverse=True))
print(f'cibuildwheel: Could not find any of {{{names}}} at root of package', file=sys.stderr)
sys.exit(2)

# Passing this in as an environment variable will override pyproject.toml, setup.cfg, or setup.py
37 changes: 17 additions & 20 deletions cibuildwheel/projectfiles.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
import sys
from configparser import ConfigParser
from pathlib import Path
from typing import Any, Dict, Optional
from typing import Any, Optional

import toml

@@ -11,6 +11,8 @@

def get_constant(x: ast.Str) -> str:
return x.s


else:
Constant = ast.Constant

@@ -21,24 +23,23 @@ def get_constant(x: ast.Constant) -> Any:
class Analyzer(ast.NodeVisitor):
def __init__(self) -> None:
self.requires_python: Optional[str] = None
self.constants: Dict[str, str] = {}

def visit_Assign(self, node: ast.Assign) -> None:
for target in node.targets:
if (
isinstance(target, ast.Name)
and isinstance(node.value, Constant)
and isinstance(get_constant(node.value), str)
):
self.constants[target.id] = get_constant(node.value)
def visit(self, content: ast.AST) -> None:
for node in ast.walk(content):
for child in ast.iter_child_nodes(node):
child.parent = node # type: ignore
super().visit(content)

def visit_keyword(self, node: ast.keyword) -> None:
self.generic_visit(node)
if node.arg == "python_requires":
if isinstance(node.value, Constant):
# Must not be nested in an if or other structure
# This will be Module -> Expr -> Call -> keyword
if (
not hasattr(node.parent.parent.parent, "parent") # type: ignore
and isinstance(node.value, Constant)
):
self.requires_python = get_constant(node.value)
elif isinstance(node.value, ast.Name):
self.requires_python = self.constants.get(node.value.id)


def setup_py_python_requires(content: str) -> Optional[str]:
@@ -54,27 +55,23 @@ def setup_py_python_requires(content: str) -> Optional[str]:
def get_requires_python_str(package_dir: Path) -> Optional[str]:
"Return the python requires string from the most canonical source available, or None"

setup_py = package_dir / 'setup.py'
setup_cfg = package_dir / 'setup.cfg'
pyproject_toml = package_dir / 'pyproject.toml'

# Read in from pyproject.toml:project.requires-python
try:
info = toml.load(pyproject_toml)
info = toml.load(package_dir / 'pyproject.toml')
return str(info['project']['requires-python'])
except (FileNotFoundError, KeyError, IndexError, TypeError):
pass

# Read in from setup.cfg:options.python_requires
try:
config = ConfigParser()
config.read(setup_cfg)
config.read(package_dir / 'setup.cfg')
return str(config['options']['python_requires'])
except (FileNotFoundError, KeyError, IndexError, TypeError):
pass

try:
with open(setup_py) as f:
with open(package_dir / 'setup.py') as f:
return setup_py_python_requires(f.read())
except FileNotFoundError:
pass
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@ dev =
requests
typing-extensions
rich>=9.6
mypy>=0.800

[options.packages.find]
include =

0 comments on commit a49bc4c

Please sign in to comment.