Skip to content

Commit

Permalink
fix(compare_singleton_primitives_by_is): compare Name directly instea…
Browse files Browse the repository at this point in the history
…d of QualifiedName

fixes #378 and #375 which are caused by Instagram/LibCST#389.

Qualifying a name will never make some thing that wasn't already
True/False/None into a True/False/None:

```python
import libcst as cst
from libcst.metadata.name_provider import QualifiedNameProvider
from textwrap import dedent

wrapper = cst.MetadataWrapper(
    cst.parse_module(dedent(
    '''
        x = None
        x()
    '''
    ))
)
x_ref = wrapper.module.body[1].body[0].value
print(wrapper.resolve(QualifiedNameProvider)[x_ref]())
```
prints:
```python
{QualifiedName(name='x', source=<QualifiedNameSource.LOCAL: 3>)}
```
  • Loading branch information
llllvvuu committed Sep 7, 2023
1 parent 84378a8 commit acf37ec
Showing 1 changed file with 7 additions and 12 deletions.
19 changes: 7 additions & 12 deletions src/fixit/rules/compare_singleton_primitives_by_is.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class CompareSingletonPrimitivesByIs(LintRule):
Valid("False is x"),
Valid("x == 2"),
Valid("2 != x"),
Valid('"True" == "True"'),
Valid('"True" != "False".lower()'),
]
INVALID = [
Invalid(
Expand Down Expand Up @@ -69,12 +71,10 @@ class CompareSingletonPrimitivesByIs(LintRule):
),
]

QUALIFIED_SINGLETON_PRIMITIVES: FrozenSet[QualifiedName] = frozenset(
{
QualifiedName(name=f"builtins.{name}", source=QualifiedNameSource.BUILTIN)
for name in ("True", "False", "None")
}
)
SINGLETON_PRIMITIVES: FrozenSet[str] = frozenset(["True", "False", "None"])

def is_singleton(self, node: cst.BaseExpression):
return isinstance(node, cst.Name) and node.value in self.SINGLETON_PRIMITIVES

def visit_Comparison(self, node: cst.Comparison) -> None:
# Initialize the needs_report flag as False to begin with
Expand All @@ -84,12 +84,7 @@ def visit_Comparison(self, node: cst.Comparison) -> None:
for target in node.comparisons:
operator, right_comp = target.operator, target.comparator
if isinstance(operator, (cst.Equal, cst.NotEqual)) and (
not self.QUALIFIED_SINGLETON_PRIMITIVES.isdisjoint(
self.get_metadata(QualifiedNameProvider, left_comp, set())
)
or not self.QUALIFIED_SINGLETON_PRIMITIVES.isdisjoint(
self.get_metadata(QualifiedNameProvider, right_comp, set())
)
self.is_singleton(left_comp) or self.is_singleton(right_comp)
):
needs_report = True
altered_comparisons.append(
Expand Down

0 comments on commit acf37ec

Please sign in to comment.