One function
ExportBinding in PyCQA/pyflakes
The author described this change as “Fix regression with `__all__ = [not, strings]`”. It counts as a record because the check below fails on the code as it stood at 14f28ba02 and passes on 65fdfad26, with nothing else changed between the two runs.
ProjectPyCQA/pyflakes
Fix saved2019-01-23
Sharing licenceMIT · LICENSE
Change size+9 −3
What the code was meant to do, written into the code itself as a docstring
A binding created by an C{__all__} assignment. If the names in the list can be determined statically, they will be treated as names for export and additional checking applied to them. The only recognized C{__all__} assignment via list concatenation is in the following format: __all__ = ['a'] + ['b'] + ['c'] Names which are imported and not otherwise used but appear in the value of C{__all__} will not have an unused import warning reported for them.
The change
| 18 | 18 | self.names = list(scope['__all__'].names) | |
| 19 | 19 | else: | |
| 20 | 20 | self.names = [] | |
| 21 | + | ||
| 22 | + | def _add_to_names(container): | |
| 23 | + | for node in container.elts: | |
| 24 | + | if isinstance(node, ast.Str): | |
| 25 | + | self.names.append(node.s) | |
| 26 | + | ||
| 21 | 27 | if isinstance(source.value, (ast.List, ast.Tuple)): | |
| 22 | - | self.names += ast.literal_eval(source.value) | |
| 28 | + | _add_to_names(source.value) | |
| 23 | 29 | # If concatenating lists | |
| 24 | 30 | elif isinstance(source.value, ast.BinOp): | |
| 25 | 31 | currentValue = source.value | |
| 26 | 32 | while isinstance(currentValue.right, ast.List): | |
| 27 | 33 | left = currentValue.left | |
| 28 | 34 | right = currentValue.right | |
| 29 | - | self.names += ast.literal_eval(right) | |
| 35 | + | _add_to_names(right) | |
| 30 | 36 | # If more lists are being added | |
| 31 | 37 | if isinstance(left, ast.BinOp): | |
| 32 | 38 | currentValue = left | |
| 33 | 39 | # If just two lists are being added | |
| 34 | 40 | elif isinstance(left, ast.List): | |
| 35 | - | self.names += ast.literal_eval(left) | |
| 41 | + | _add_to_names(left) | |
| 36 | 42 | # All lists accounted for - done | |
| 37 | 43 | break | |
| 38 | 44 | # If not list concatenation |
The check that tells the two apart
fail→pass·pyflakes/test/test_imports.py::TestSpecialAll::test_all_mixed_attributes_and_strings
Check file pyflakes/test/test_imports.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.
Origin and history
The code before it14f28ba0279e3547c09b06870f90f01167da08ec
Broken version dated2019-01-21
Modulepyflakes.checker
Units changedExportBinding
Fingerprinte1f174152acb6560
Checked2026-08-18 by goldset/0.1
Every field above is generated by our program. None of it is written by hand.
Other bugs found in PyCQA/pyflakes
- 2023-06-13Reporter
- 2016-05-12Fix TypeError when processing relative imports (#61)
- 2015-11-12Fix global removing all UndefinedName