@@ -1484,17 +1484,23 @@ def _substitution_cost(ch_a, ch_b):
14841484 return _MOVE_COST
14851485
14861486
1487+ def _get_safe___dir__ (obj ):
1488+ # Use obj.__dir__() to avoid a TypeError when calling dir(obj).
1489+ # See gh-131001 and gh-139933.
1490+ try :
1491+ d = obj .__dir__ ()
1492+ except TypeError : # when obj is a class
1493+ d = type (obj ).__dir__ (obj )
1494+ return sorted (x for x in d if isinstance (x , str ))
1495+
1496+
14871497def _compute_suggestion_error (exc_value , tb , wrong_name ):
14881498 if wrong_name is None or not isinstance (wrong_name , str ):
14891499 return None
14901500 if isinstance (exc_value , AttributeError ):
14911501 obj = exc_value .obj
14921502 try :
1493- try :
1494- d = dir (obj )
1495- except TypeError : # Attributes are unsortable, e.g. int and str
1496- d = list (obj .__class__ .__dict__ .keys ()) + list (obj .__dict__ .keys ())
1497- d = sorted ([x for x in d if isinstance (x , str )])
1503+ d = _get_safe___dir__ (obj )
14981504 hide_underscored = (wrong_name [:1 ] != '_' )
14991505 if hide_underscored and tb is not None :
15001506 while tb .tb_next is not None :
@@ -1509,11 +1515,7 @@ def _compute_suggestion_error(exc_value, tb, wrong_name):
15091515 elif isinstance (exc_value , ImportError ):
15101516 try :
15111517 mod = __import__ (exc_value .name )
1512- try :
1513- d = dir (mod )
1514- except TypeError : # Attributes are unsortable, e.g. int and str
1515- d = list (mod .__dict__ .keys ())
1516- d = sorted ([x for x in d if isinstance (x , str )])
1518+ d = _get_safe___dir__ (mod )
15171519 if wrong_name [:1 ] != '_' :
15181520 d = [x for x in d if x [:1 ] != '_' ]
15191521 except Exception :
0 commit comments