Skip to content

Commit a49bc4c

Browse files
committed
fix: tighten AST to call only
1 parent be71178 commit a49bc4c

File tree

3 files changed

+22
-25
lines changed

3 files changed

+22
-25
lines changed

cibuildwheel/__main__.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,11 @@ def main() -> None:
159159
test_extras = get_option_from_environment('CIBW_TEST_EXTRAS', platform=platform, default='')
160160
build_verbosity_str = get_option_from_environment('CIBW_BUILD_VERBOSITY', platform=platform, default='')
161161

162-
setup_py = package_dir / 'setup.py'
163-
setup_cfg = package_dir / 'setup.cfg'
164-
pyproject_toml = package_dir / 'pyproject.toml'
162+
package_files = {'setup.py', 'setup.cfg', 'pyproject.toml'}
165163

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

170169
# Passing this in as an environment variable will override pyproject.toml, setup.cfg, or setup.py

cibuildwheel/projectfiles.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import sys
33
from configparser import ConfigParser
44
from pathlib import Path
5-
from typing import Any, Dict, Optional
5+
from typing import Any, Optional
66

77
import toml
88

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

1212
def get_constant(x: ast.Str) -> str:
1313
return x.s
14+
15+
1416
else:
1517
Constant = ast.Constant
1618

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

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

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

4344

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

57-
setup_py = package_dir / 'setup.py'
58-
setup_cfg = package_dir / 'setup.cfg'
59-
pyproject_toml = package_dir / 'pyproject.toml'
60-
6158
# Read in from pyproject.toml:project.requires-python
6259
try:
63-
info = toml.load(pyproject_toml)
60+
info = toml.load(package_dir / 'pyproject.toml')
6461
return str(info['project']['requires-python'])
6562
except (FileNotFoundError, KeyError, IndexError, TypeError):
6663
pass
6764

6865
# Read in from setup.cfg:options.python_requires
6966
try:
7067
config = ConfigParser()
71-
config.read(setup_cfg)
68+
config.read(package_dir / 'setup.cfg')
7269
return str(config['options']['python_requires'])
7370
except (FileNotFoundError, KeyError, IndexError, TypeError):
7471
pass
7572

7673
try:
77-
with open(setup_py) as f:
74+
with open(package_dir / 'setup.py') as f:
7875
return setup_py_python_requires(f.read())
7976
except FileNotFoundError:
8077
pass

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ dev =
5454
requests
5555
typing-extensions
5656
rich>=9.6
57+
mypy>=0.800
5758

5859
[options.packages.find]
5960
include =

0 commit comments

Comments
 (0)