(exc_value, tb, wrong_name)
| 1725 | |
| 1726 | |
| 1727 | def _compute_suggestion_error(exc_value, tb, wrong_name): |
| 1728 | if wrong_name is None or not isinstance(wrong_name, str): |
| 1729 | return None |
| 1730 | not_normalized = False |
| 1731 | if not wrong_name.isascii(): |
| 1732 | from unicodedata import normalize |
| 1733 | normalized_name = normalize('NFKC', wrong_name) |
| 1734 | if normalized_name != wrong_name: |
| 1735 | not_normalized = True |
| 1736 | wrong_name = normalized_name |
| 1737 | if isinstance(exc_value, AttributeError): |
| 1738 | obj = exc_value.obj |
| 1739 | try: |
| 1740 | d = _get_safe___dir__(obj) |
| 1741 | hide_underscored = (wrong_name[:1] != '_') |
| 1742 | if hide_underscored and tb is not None: |
| 1743 | while tb.tb_next is not None: |
| 1744 | tb = tb.tb_next |
| 1745 | frame = tb.tb_frame |
| 1746 | if 'self' in frame.f_locals and frame.f_locals['self'] is obj: |
| 1747 | hide_underscored = False |
| 1748 | if hide_underscored: |
| 1749 | d = [x for x in d if x[:1] != '_'] |
| 1750 | except Exception: |
| 1751 | return None |
| 1752 | elif isinstance(exc_value, ModuleNotFoundError): |
| 1753 | try: |
| 1754 | if parent_name := wrong_name.rpartition('.')[0]: |
| 1755 | parent = importlib.util.find_spec(parent_name) |
| 1756 | else: |
| 1757 | parent = None |
| 1758 | d = [] |
| 1759 | for finder in sys.meta_path: |
| 1760 | if discover := getattr(finder, 'discover', None): |
| 1761 | d += [spec.name for spec in discover(parent)] |
| 1762 | except Exception: |
| 1763 | return None |
| 1764 | elif isinstance(exc_value, ImportError): |
| 1765 | try: |
| 1766 | mod = __import__(exc_value.name) |
| 1767 | d = _get_safe___dir__(mod) |
| 1768 | if wrong_name[:1] != '_': |
| 1769 | d = [x for x in d if x[:1] != '_'] |
| 1770 | except Exception: |
| 1771 | return None |
| 1772 | else: |
| 1773 | assert isinstance(exc_value, NameError) |
| 1774 | # find most recent frame |
| 1775 | if tb is None: |
| 1776 | return None |
| 1777 | while tb.tb_next is not None: |
| 1778 | tb = tb.tb_next |
| 1779 | frame = tb.tb_frame |
| 1780 | d = ( |
| 1781 | list(frame.f_locals) |
| 1782 | + list(frame.f_globals) |
| 1783 | + list(frame.f_builtins) |
| 1784 | ) |
no test coverage detected
searching dependent graphs…