3RNN/Lib/site-packages/namex/export.py
2024-05-26 19:49:15 +02:00

69 lines
2.2 KiB
Python

class export:
"""Decorator to export a public API in a given package.
Example usage:
```python
@export(package="keras_tuner", path="keras_tuner.applications.HyperResNet")
class HyperResNet:
...
```
You can also pass a list of paths as `path`, to make
the same symbol visible under various aliases:
```python
@export(
package="keras_tuner",
path=[
"keras_tuner.applications.HyperResNet",
"keras_tuner.applications.resnet.HyperResNet",
])
class HyperResNet:
...
```
**Note:** All export packages must start with the package name.
Yes, that is redundant, but that is a helpful sanity check.
The expectation is that each package will customize
`export_api` to provide a default value for `package`,
which will serve to validate all `path` values
and avoid users inadvertendly ending up with non-exported
symbols due to a bad path (e.g. `path="applications.HyperResNet"`
instead of `path="keras_tuner.applications.HyperResNet"`).
"""
def __init__(self, package, path):
if isinstance(path, str):
export_paths = [path]
elif isinstance(path, list):
export_paths = path
else:
raise ValueError(
f"Invalid type for `path` argument: "
f"Received '{path}' "
f"of type {type(path)}"
)
for p in export_paths:
if not p.startswith(package + "."):
raise ValueError(
f"All `export_path` values should start with '{package}.'. "
f"Received: path={path}"
)
self.package = package
self.path = path
def __call__(self, symbol):
if hasattr(symbol, "_api_export_path") and symbol._api_export_symbol_id == id(
symbol
):
raise ValueError(
f"Symbol {symbol} is already exported as '{symbol._api_export_path}'. "
f"Cannot also export it to '{self.path}'."
)
symbol._api_export_path = self.path
symbol._api_export_symbol_id = id(symbol)
return symbol