@@ -1589,17 +1589,23 @@ def _substitution_cost(ch_a, ch_b):
15891589 return _MOVE_COST
15901590
15911591
1592+ def _get_safe___dir__ (obj ):
1593+ # Use obj.__dir__() to avoid a TypeError when calling dir(obj).
1594+ # See gh-131001 and gh-139933.
1595+ try :
1596+ d = obj .__dir__ ()
1597+ except TypeError : # when obj is a class
1598+ d = type (obj ).__dir__ (obj )
1599+ return sorted (x for x in d if isinstance (x , str ))
1600+
1601+
15921602def _compute_suggestion_error (exc_value , tb , wrong_name ):
15931603 if wrong_name is None or not isinstance (wrong_name , str ):
15941604 return None
15951605 if isinstance (exc_value , AttributeError ):
15961606 obj = exc_value .obj
15971607 try :
1598- try :
1599- d = dir (obj )
1600- except TypeError : # Attributes are unsortable, e.g. int and str
1601- d = list (obj .__class__ .__dict__ .keys ()) + list (obj .__dict__ .keys ())
1602- d = sorted ([x for x in d if isinstance (x , str )])
1608+ d = _get_safe___dir__ (obj )
16031609 hide_underscored = (wrong_name [:1 ] != '_' )
16041610 if hide_underscored and tb is not None :
16051611 while tb .tb_next is not None :
@@ -1614,11 +1620,7 @@ def _compute_suggestion_error(exc_value, tb, wrong_name):
16141620 elif isinstance (exc_value , ImportError ):
16151621 try :
16161622 mod = __import__ (exc_value .name )
1617- try :
1618- d = dir (mod )
1619- except TypeError : # Attributes are unsortable, e.g. int and str
1620- d = list (mod .__dict__ .keys ())
1621- d = sorted ([x for x in d if isinstance (x , str )])
1623+ d = _get_safe___dir__ (mod )
16221624 if wrong_name [:1 ] != '_' :
16231625 d = [x for x in d if x [:1 ] != '_' ]
16241626 except Exception :
0 commit comments