Add a class to the _decl_class_registry associated with the given declarative class.
(
classname: str, cls: Type[_T], decl_class_registry: _ClsRegistryType
)
| 63 | |
| 64 | |
| 65 | def _add_class( |
| 66 | classname: str, cls: Type[_T], decl_class_registry: _ClsRegistryType |
| 67 | ) -> None: |
| 68 | """Add a class to the _decl_class_registry associated with the |
| 69 | given declarative class. |
| 70 | |
| 71 | """ |
| 72 | if classname in decl_class_registry: |
| 73 | # class already exists. |
| 74 | existing = decl_class_registry[classname] |
| 75 | if not isinstance(existing, _MultipleClassMarker): |
| 76 | decl_class_registry[classname] = _MultipleClassMarker( |
| 77 | [cls, cast("Type[Any]", existing)] |
| 78 | ) |
| 79 | else: |
| 80 | decl_class_registry[classname] = cls |
| 81 | |
| 82 | try: |
| 83 | root_module = cast( |
| 84 | _ModuleMarker, decl_class_registry["_sa_module_registry"] |
| 85 | ) |
| 86 | except KeyError: |
| 87 | decl_class_registry["_sa_module_registry"] = root_module = ( |
| 88 | _ModuleMarker("_sa_module_registry", None) |
| 89 | ) |
| 90 | |
| 91 | tokens = cls.__module__.split(".") |
| 92 | |
| 93 | # build up a tree like this: |
| 94 | # modulename: myapp.snacks.nuts |
| 95 | # |
| 96 | # myapp->snack->nuts->(classes) |
| 97 | # snack->nuts->(classes) |
| 98 | # nuts->(classes) |
| 99 | # |
| 100 | # this allows partial token paths to be used. |
| 101 | while tokens: |
| 102 | token = tokens.pop(0) |
| 103 | module = root_module.get_module(token) |
| 104 | for token in tokens: |
| 105 | module = module.get_module(token) |
| 106 | |
| 107 | try: |
| 108 | module.add_class(classname, cls) |
| 109 | except AttributeError as ae: |
| 110 | if not isinstance(module, _ModuleMarker): |
| 111 | raise exc.InvalidRequestError( |
| 112 | f'name "{classname}" matches both a ' |
| 113 | "class name and a module name" |
| 114 | ) from ae |
| 115 | else: |
| 116 | raise |
| 117 | |
| 118 | |
| 119 | def _remove_class( |
nothing calls this directly
no test coverage detected