Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-130428: Add tests for delattr suggestions #130455

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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 89 additions & 18 deletions Lib/test/test_traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -3976,7 +3976,7 @@ def callable():
)
return result_lines[0]

def test_getattr_suggestions(self):
def run_suggestion_tests(self, operation):
class Substitution:
noise = more_noise = a = bc = None
blech = None
Expand Down Expand Up @@ -4016,62 +4016,133 @@ class CaseChangeOverSubstitution:
(EliminationOverAddition, "'bluc'?"),
(CaseChangeOverSubstitution, "'BLuch'?"),
]:
actual = self.get_suggestion(cls(), 'bluch')
obj = cls()

if operation == "getattr":
actual = self.get_suggestion(obj, 'bluch')
elif operation == "delattr":
actual = self.get_suggestion(lambda: delattr(obj, 'bluch'))
else:
raise ValueError(f"operation '{operation}' not recognized")

self.assertIn(suggestion, actual)

def test_getattr_suggestions_underscored(self):
def test_getattr_suggestions(self):
self.run_suggestion_tests("getattr")

def test_delattr_suggestions(self):
self.run_suggestion_tests("delattr")

def run_underscored_tests(self, operation):
class A:
bluch = None

self.assertIn("'bluch'", self.get_suggestion(A(), 'blach'))
self.assertIn("'bluch'", self.get_suggestion(A(), '_luch'))
self.assertIn("'bluch'", self.get_suggestion(A(), '_bluch'))
obj = A()
if operation == "getattr":
self.assertIn("'bluch'", self.get_suggestion(obj, 'blach'))
self.assertIn("'bluch'", self.get_suggestion(obj, '_luch'))
self.assertIn("'bluch'", self.get_suggestion(obj, '_bluch'))
elif operation == "delattr":
self.assertIn("'bluch'", self.get_suggestion(lambda: delattr(obj, 'blach')))
self.assertIn("'bluch'", self.get_suggestion(lambda: delattr(obj, '_luch')))
self.assertIn("'bluch'", self.get_suggestion(lambda: delattr(obj, '_bluch')))
else:
raise ValueError(f"operation '{operation}' not recognized")

class B:
_bluch = None
def method(self, name):
getattr(self, name)

self.assertIn("'_bluch'", self.get_suggestion(B(), '_blach'))
self.assertIn("'_bluch'", self.get_suggestion(B(), '_luch'))
self.assertNotIn("'_bluch'", self.get_suggestion(B(), 'bluch'))
obj = B()
if operation == "getattr":
self.assertIn("'_bluch'", self.get_suggestion(obj, '_blach'))
self.assertIn("'_bluch'", self.get_suggestion(obj, '_luch'))
self.assertNotIn("'_bluch'", self.get_suggestion(obj, 'bluch'))
self.assertIn("'_bluch'", self.get_suggestion(partial(obj.method, '_blach')))
self.assertIn("'_bluch'", self.get_suggestion(partial(obj.method, '_luch')))
self.assertIn("'_bluch'", self.get_suggestion(partial(obj.method, 'bluch')))
elif operation == "delattr":
self.assertIn("'_bluch'", self.get_suggestion(lambda: delattr(obj, '_blach')))
self.assertIn("'_bluch'", self.get_suggestion(lambda: delattr(obj, '_luch')))
self.assertNotIn("'_bluch'", self.get_suggestion(lambda: delattr(obj, 'bluch')))
else:
raise ValueError(f"operation '{operation}' not recognized")

self.assertIn("'_bluch'", self.get_suggestion(partial(B().method, '_blach')))
self.assertIn("'_bluch'", self.get_suggestion(partial(B().method, '_luch')))
self.assertIn("'_bluch'", self.get_suggestion(partial(B().method, 'bluch')))
def test_getattr_suggestions_underscored(self):
self.run_underscored_tests("getattr")

def test_getattr_suggestions_do_not_trigger_for_long_attributes(self):
def test_delattr_suggestions_underscored(self):
self.run_underscored_tests("delattr")

def run_do_not_trigger_for_long_attributes_tests(self, operation):
class A:
blech = None

actual = self.get_suggestion(A(), 'somethingverywrong')
obj = A()
if operation == "getattr":
actual = self.get_suggestion(obj, 'somethingverywrong')
elif operation == "delattr":
actual = self.get_suggestion(lambda: delattr(obj, 'somethingverywrong'))
else:
raise ValueError(f"operation '{operation}' not recognized")
self.assertNotIn("blech", actual)

def test_getattr_error_bad_suggestions_do_not_trigger_for_small_names(self):
def test_getattr_suggestions_do_not_trigger_for_long_attributes(self):
self.run_do_not_trigger_for_long_attributes_tests("getattr")

def test_delattr_suggestions_do_not_trigger_for_long_attributes(self):
self.run_do_not_trigger_for_long_attributes_tests("delattr")

def run_do_not_trigger_for_small_names_tests(self, operation):
class MyClass:
vvv = mom = w = id = pytho = None

obj = MyClass()
for name in ("b", "v", "m", "py"):
with self.subTest(name=name):
actual = self.get_suggestion(MyClass, name)
if operation == "getattr":
actual = self.get_suggestion(MyClass, name)
elif operation == "delattr":
actual = self.get_suggestion(lambda: delattr(obj, name))
else:
raise ValueError(f"operation '{operation}' not recognized")
self.assertNotIn("Did you mean", actual)
self.assertNotIn("'vvv", actual)
self.assertNotIn("'mom'", actual)
self.assertNotIn("'id'", actual)
self.assertNotIn("'w'", actual)
self.assertNotIn("'pytho'", actual)

def test_getattr_suggestions_do_not_trigger_for_big_dicts(self):
def test_getattr_error_bad_suggestions_do_not_trigger_for_small_names(self):
self.run_do_not_trigger_for_small_names_tests("getattr")

def test_delattr_error_bad_suggestions_do_not_trigger_for_small_names(self):
self.run_do_not_trigger_for_small_names_tests("delattr")

def run_do_not_trigger_for_big_dicts_tests(self, operation):
class A:
blech = None
# A class with a very big __dict__ will not be considered
# for suggestions.
for index in range(2000):
setattr(A, f"index_{index}", None)

actual = self.get_suggestion(A(), 'bluch')
obj = A()
if operation == "getattr":
actual = self.get_suggestion(obj, 'bluch')
elif operation == "delattr":
actual = self.get_suggestion(lambda: delattr(obj, 'bluch'))
else:
raise ValueError(f"operation '{operation}' not recognized")
self.assertNotIn("blech", actual)

def test_getattr_suggestions_do_not_trigger_for_big_dicts(self):
self.run_do_not_trigger_for_big_dicts_tests("getattr")

def test_delattr_suggestions_do_not_trigger_for_big_dicts(self):
self.run_do_not_trigger_for_big_dicts_tests("delattr")

def test_getattr_suggestions_no_args(self):
class A:
blech = None
Expand Down
Loading