-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Python: Modernize 3 quality queries for comparison methods #20038
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Python: Modernize 3 quality queries for comparison methods #20038
Conversation
…here; total order doesn't define eq or ne methods at all)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR modernizes three Python quality queries for comparison methods: py/incomplete-ordering
, py/inconsistent-equality
, and py/equals-hash-mismatch
. The modernization removes dependency on the legacy pointsTo analysis, eliminates Python 2-specific cases to focus on Python 3, and updates documentation with clearer examples and explanations.
Key changes include:
- Complete rewrite of the three comparison queries using modern CodeQL libraries
- Migration of query files from
Classes/
toClasses/Comparisons/
directory structure - Updated test cases with inline expectations format and comprehensive examples
- Enhanced documentation with Python 3-focused guidance and improved examples
Reviewed Changes
Copilot reviewed 36 out of 37 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
python/ql/src/Classes/Comparisons/*.ql | New modernized query implementations using current CodeQL libraries |
python/ql/src/Classes/Comparisons/*.qhelp | Updated documentation with Python 3 focus and clearer examples |
python/ql/test/query-tests/Classes/*/**.py | Enhanced test cases with comprehensive comparison method scenarios |
python/ql/src/Classes/Equality.qll | Extended DelegatingEqualityMethod to handle method call delegation patterns |
python/ql/lib/semmle/python/Class.qll | Added getMethod convenience predicate for retrieving methods by name |
python/ql/src/Classes/Comparisons/examples/EqualsOrNotEquals2.py
Outdated
Show resolved
Hide resolved
python/ql/src/Classes/Comparisons/examples/IncompleteOrdering.py
Outdated
Show resolved
Hide resolved
QHelp previews: python/ql/src/Classes/Comparisons/EqualsOrHash.qhelpInconsistent equality and hashingA hashable class has an Note that defining an RecommendationIf a To explicitly declare a class as unhashable, set ExampleIn the following example, the class A:
def __init__(self, a, b):
self.a = a
self.b = b
# No equality method is defined
def __hash__(self):
return hash((self.a, self.b)) References
python/ql/src/Classes/Comparisons/EqualsOrNotEquals.qhelpInconsistent equality and inequalityIn order to ensure the In Python 3, if the However, if the Additionally, if the RecommendationEnsure that when an ExampleIn the following example, class A:
def __init__(self, a):
self.a = a
# BAD: ne is defined, but not eq.
def __ne__(self, other):
if not isinstance(other, A):
return NotImplemented
return self.a != other.a
x = A(1)
y = A(1)
print(x == y) # Prints False (potentially unexpected - object identity is used)
print(x != y) # Prints False In the following example, class B:
def __init__(self, b):
self.b = b
def __eq__(self, other):
return self.b == other.b
def __ne__(self, other):
return self.b != other.b
class C(B):
def __init__(self, b, c):
super().__init__(b)
self.c = c
# BAD: eq is defined, but != will use superclass ne method, which is not consistent
def __eq__(self, other):
return self.b == other.b and self.c == other.c
print(C(1,2) == C(1,3)) # Prints False
print(C(1,2) != C(1,3)) # Prints False (potentially unexpected) References
python/ql/src/Classes/Comparisons/IncompleteOrdering.qhelpIncomplete orderingA class that implements the rich comparison operators ( RecommendationEnsure that at least one of The ExampleIn the following example, only the class A:
def __init__(self, i):
self.i = i
# BAD: le is not defined, so `A(1) <= A(2)` would result in an error.
def __lt__(self, other):
return self.i < other.i
References
|
Modernizes
py/incomplete-ordering
,py/inconsistent-equality
, andpy/equals-hash-mismatch
No longer uses pointsTo, removes python 2 specific cases, and updates documentation.