I am wondering if there is a mechanism in python to fetch the "public" path to a class object in python (PEP8
, __all__
, "explicit reexport", ...).
To provide a minimal example, let's assume the following package structure:
|-- my_package
| |-- __init__.py
| |-- _my_module.py
Let this be the file contents of my_package.__my_module.py
:
class MyObject: ...
Let this be the file contents of my_package.__init__.py
:
from ._my_module import MyObject
__all__ = [
"MyObject"
]
Is there a 'canonical' way of fetching the public path to MyObject
- which should be my_package.MyObject
(rather than my_package._my_module.MyObject
)?
The following snippet works in the above example, but obviously bears a high risk of error (especially if you might want to use the returned string to do a programmatic import later on)
from typing import Any
from typing import Type
def get_public_path(to: Type[Any]) -> str:
module = ".".join(list(filter(lambda k: not str(k).startswith("_"), to.__module__.split("."))))
name = to.__qualname__
return ".".join([module, name])
if __name__ == '__main__':
from my_package import MyObject
print(get_public_path(MyObject))
The example is a pretty common pattern, where the exact code location of MyObejct
is considered an internal implementation detail of the package, which may change at any time without further note. Users of the package must import the object via from my_package import MyObject
, which is considered the public api.
I would hope, that there is a clean and obvious way of getting the "public" class path without a huge bunch of meta-programming inspection (e.g. iterating the "private" module path, recursively looking for __all__
sections inside the module path etc.)