ruff UP029
labelled unknown
Analysis Nemotron 3 Super
Flags imports of Python 3 builtins from compatibility modules like 'builtins' or 'six.moves' when they are unused after removing the import.
Fix: Removes the import statement and leaves all usages of the imported builtin unchanged, relying on the Python 3 builtin being available by default.
10 hazards
- Removing 'from builtins import str' may break code if a local variable named 'str' was intended to shadow the builtin but the import removal causes the builtin to be used instead.
- If 'six.moves.range' is imported and later reassigned to a non-callable, removing the import may cause a NameError when the builtin 'range' is used where a different object was expected.
- The fix does not account for conditional imports; if the import is inside a function or conditional block, removing it may cause a NameError when the builtin is used outside that scope.
- If the imported name is used as a string in eval() or exec(), removing the import may change behavior if the name resolution depends on the import being present.
- Removing the import may break code that relies on the specific type or behavior of the shimmed builtin (e.g., 'past.builtins.map' returning a list in Python 2 style), even if the code is run on Python 3.
- If the import is aliased (e.g., 'from six.moves import range as r'), the fix may not trigger or may leave the alias unused, but if it did, removing the import would break uses of the alias.
- The fix may remove a comment attached to the import line (e.g., '# needed for old Python'), which is considered unsafe and could lead to loss of documentation.
- If the module defining the shim (e.g., 'six') has side effects on import (e.g., registers plugins), removing the import may alter program behavior even if the imported name is not used.
- In rare cases, if a third-party module defines a 'builtins' attribute that shadows the import, removing the import may cause a NameError due to missing attribute access.
- If the code is run under a restricted environment where __builtins__ is modified, removing the import may bypass intentional builtin overrides provided by the shim.
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | fired, no fix | Conditional Import Scope Hazard | Import removal ignores conditional/function scope; using builtin outside scope causes NameError. |
| r1-p002 | silent | Star Import and __all__ Side Effect | Star import may rely on __all__ from module; removing import breaks star-imported name resolution. |
| r1-p003 | fired, no fix prediction off | Dict Ordering and Hash Hazard | Removing import changes dict key resolution if __hash__/__eq__ overridden and ordering matters. |
| r1-p004 | silent | Exception Handling Interaction | Rewritten code inside try/except/finally may change exception flow if import removal alters name binding. |
| r1-p005 | fired, no fix prediction off | Eval Exec String Dependency | Imported name used as string in eval/exec; removing import changes resolution if name not in builtins. |
| r1-p006 | fired, no fix prediction off | Module Side Effect on Import | Importing six.moves has side effects (e.g., plugin registration); removing import alters behavior. |
| r1-p007 | fired, no fix prediction off | Reassignment to Non-Callable | Imported name reassigned to non-callable; later use expects callable but gets non-callable or missing. |
| r1-p008 | silent | Truthiness and Identity Comparison | __bool__/__len__ or None vs falsy interacts with 'is' vs '==' after import removal changes binding. |
| r2-p001 | fired, no fix | Runtime-evaluated type annotation using forward reference | type annotations evaluated at runtime, typing-only imports |
| r2-p002 | fired, no fix | Generator consumed twice after import removal | generators vs lists, iterators consumed once, lazy vs eager evaluation |
| r2-p003 | silent | Third-party module with conflicting 'builtins' attribute | In rare cases, if a third-party module defines a 'builtins' attribute that shadows the import, removing the import may cause a NameError due to missing attribute access. |
| r2-p004 | fired, no fix | Star import with side effect in __init__ | star-imports, module-level side effects, __all__ |
| r2-p005 | fired, no fix | Conditional import inside function, used outside | The fix does not account for conditional imports; if the import is inside a function or conditional block, removing it may cause a NameError when the builtin is used outside that scope. |
| r2-p006 | fired, no fix | Import removed but used in duplicated expression with side effect | evaluation order and side effects when expressions are merged, duplicated or deleted |
| r2-p007 | silent prediction off | past.builtins.map returns list in Py2, but used as iterator | Removing the import may break code that relies on the specific type or behavior of the shimmed builtin (e.g., 'past.builtins.map' returning a list in Python 2 style), even if the code is run on Python |
| r2-p008 | fired, no fix | Context manager with write but no close, used in with-block | context managers that are not files, objects with write() but no close() |
Sources
r1-p001 · Conditional Import Scope Hazard
1def f():
2 if True:
3 from builtins import str
4 return str(42)
5try:
6 print(f())
7except Exception as e:
8 print(type(e).__name__, str(e))
42
r1-p002 · Star Import and __all__ Side Effect
1from six.moves import *
2print(range.__module__)
r1-p003 · Dict Ordering and Hash Hazard
1class A:
2 def __hash__(self): return 1
3 def __eq__(self, other): return isinstance(other, A)
4from builtins import dict
5d = {A(): 1, A(): 2}
6print(len(d))
1
r1-p004 · Exception Handling Interaction
1try:
2 from builtins import len
3 x = len([1,2,3])
4except NameError:
5 x = 0
6finally:
7 print('finally', x)
finally 3
r1-p005 · Eval Exec String Dependency
1from builtins import str
2code = 'str(123)'
3print(eval(code))
123
r1-p006 · Module Side Effect on Import
1import sys
2if 'six' not in sys.modules:
3 print('six not loaded')
4from six.moves import range
5print('six loaded')
six not loaded
r1-p007 · Reassignment to Non-Callable
1from six.moves import range
2range = 5
3try:
4 print(range(3))
5except Exception as e:
6 print(type(e).__name__, str(e))
r1-p008 · Truthiness and Identity Comparison
1class X:
2 def __bool__(self): return False
3 def __len__(self): return 0
4from builtins import bool
5b = bool(X())
6print(b, b is False, b == False)
False True True
r2-p001 · Runtime-evaluated type annotation using forward reference
1from typing import List
2from builtins import str
3
4def f(x: 'List[str]') -> None:
5 print(len(x))
6
7f(['a', 'b'])
2
r2-p002 · Generator consumed twice after import removal
1from builtins import range
2
3gen = range(3)
4first = list(gen)
5second = list(gen)
6print('first:', first, 'second:', second)
first: [0, 1, 2] second: [0, 1, 2]
r2-p003 · Third-party module with conflicting 'builtins' attribute
1class DummyModule:
2 builtins = 'shadow'
3
4import sys
5sys.modules['dummy'] = DummyModule()
6
7from dummy import builtins
8print(builtins)
shadow
r2-p004 · Star import with side effect in __init__
1from builtins import *
2print(str('hello'))
hello
r2-p005 · Conditional import inside function, used outside
1def setup():
2 from builtins import str
3
4setup()
5print(str('test'))
test
r2-p006 · Import removed but used in duplicated expression with side effect
1from builtins import str
2
3x = str(input := '42') or 0
4print(x, input)
42 42
r2-p007 · past.builtins.map returns list in Py2, but used as iterator
1from past.builtins import map
2
3result = map(lambda x: x*2, [1, 2, 3])
4print('type:', type(result), 'list:', list(result))
r2-p008 · Context manager with write but no close, used in with-block
1from builtins import str
2
3class Logger:
4 def write(self, msg):
5 self.last = msg
6 def __enter__(self):
7 return self
8 def __exit__(self, *args):
9 pass
10
11with Logger() as log:
12 log.write(str(123))
13print(log.last)
123