(name: str)
| 51 | |
| 52 | |
| 53 | def resolve(name: str) -> object: |
| 54 | # Simplified from zope.dottedname. |
| 55 | parts = name.split(".") |
| 56 | |
| 57 | used = parts.pop(0) |
| 58 | found = __import__(used) |
| 59 | for part in parts: |
| 60 | used += "." + part |
| 61 | try: |
| 62 | found = getattr(found, part) |
| 63 | except AttributeError: |
| 64 | pass |
| 65 | else: |
| 66 | continue |
| 67 | # We use explicit un-nesting of the handling block in order |
| 68 | # to avoid nested exceptions. |
| 69 | try: |
| 70 | __import__(used) |
| 71 | except ImportError as ex: |
| 72 | expected = str(ex).split()[-1] |
| 73 | if expected == used: |
| 74 | raise |
| 75 | else: |
| 76 | raise ImportError(f"import error in {used}: {ex}") from ex |
| 77 | found = annotated_getattr(found, part, used) |
| 78 | return found |
| 79 | |
| 80 | |
| 81 | def annotated_getattr(obj: object, name: str, ann: str) -> object: |
no test coverage detected