"examples/cpp/vscode:/vscode.git/clone" did not exist on "fe46dac2c2ea1a988929fba05e9d3d3c9b11dfd7"
Use module-level `__getattr__` to implement delayed initialization (#2377)
Summary:
This commit updates the lazy module initialization logic for
`torchaudio.prototype.io` and `torchaudio.prototype.ctc_decoder`.
- The modules are importable regarless of optional dependencies.
i.e. `import torchaudio.prototype.io` does not trigger the check for
optional dependencies.
- Optional dependencies are checked when the actual
API is imported for the first time.
i.e. `from torchaudio.prototype.io import Streamer` triggers the check
for optional dependencies.
The downside is that;
- `import torchaudio.prototype.io.Streamer` no longer works.
## Details:
Starting from Python 3.7, modules can bave `__getattr__` function,
which serves as a fallback if the import mechanism cannot find the
attribute.
This can be used to implement lazy import.
```python
def __getattr__(name):
global pi
if name == 'pi':
import math
pi = math.pi
return pi
raise AttributeError(...)
```
Ref: https://twitter.com/raymondh/status/1094686528440168453
The implementation performs lazy import for the APIs that work with
external/optional dependencies. In addition, it also check if the
binding is initialized only once.
## Why is this preferable approach?
Previously, the optional dependencies were checked at the tiem module
is imported;
https://github.com/pytorch/audio/blob/2f4eb4ac2f48a597825d3631a840afd855fe6b39/torchaudio/prototype/io/__init__.py#L1-L5
As long as this module is in `prototype`, which we ask users to import
explictly, users had control whether they want/do not want to install
the optional dependencies.
This approach only works for one optional dependencies per one module.
Say, we add different I/O library as an optional dependency, we need to
put all the APIs in dedicated submodule. This prevents us from having
flat namespace.
i.e. the I/O modules with multiple optional dependencies would look like
```python
# Client code
from torchaudio.io.foo import FooFeature
from torchaudio.io.bar import BarFeature
```
where the new approach would allow
```python
#client code
from torchaudio.io import FooFeature, BarFeature
```
Pull Request resolved: https://github.com/pytorch/audio/pull/2377
Reviewed By: nateanl
Differential Revision: D36305603
Pulled By: mthrok
fbshipit-source-id: c1eb6cac203f6dd0026d99f9a1de1af590a535ae
Showing
File moved
Please register or sign in to comment