Commit 931598c1 authored by moto's avatar moto Committed by Facebook GitHub Bot
Browse files

Fix backward compatibility layer in backend module (#3595)

Summary:
The PR https://github.com/pytorch/audio/issues/3549 re-organized the backend implementations and deprecated the direct access to torchaudio.backend.

The change was supposed to be BC-compatible while issuing a warning to users, but the implementation of module-level `__getattr__` was not quite right.

See an issue https://github.com/pyannote/pyannote-audio/pull/1456.

This commit fixes it so that the following imports work;

```python
from torchaudio.backend.common import AudioMetaData

from torchaudio.backend import sox_io_backend
from torchaudio.backend.sox_io_backend import save, load, info

from torchaudio.backend import no_backend
from torchaudio.backend.no_backend import save, load, info

from torchaudio.backend import soundfile_backend
from torchaudio.backend.soundfile_backend import save, load, info
```

Pull Request resolved: https://github.com/pytorch/audio/pull/3595

Reviewed By: nateanl

Differential Revision: D48957446

Pulled By: mthrok

fbshipit-source-id: ebb256461dd3032025fd27d0455ce980888f7778
parent 454418d2
...@@ -117,7 +117,6 @@ class TestInfo(TempDirMixin, PytorchTestCase): ...@@ -117,7 +117,6 @@ class TestInfo(TempDirMixin, PytorchTestCase):
with patch("soundfile.info", _mock_info_func): with patch("soundfile.info", _mock_info_func):
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
info = soundfile_backend.info("foo") info = soundfile_backend.info("foo")
assert len(w) == 1
assert "UNSEEN_SUBTYPE subtype is unknown to TorchAudio" in str(w[-1].message) assert "UNSEEN_SUBTYPE subtype is unknown to TorchAudio" in str(w[-1].message)
assert info.bits_per_sample == 0 assert info.bits_per_sample == 0
......
# Initialize extension and backend first # Initialize extension and backend first
from . import ( # noqa # usort: skip from . import _extension # noqa # usort: skip
_extension, from ._backend import ( # noqa # usort: skip
_backend, AudioMetaData,
get_audio_backend,
info,
list_audio_backends,
load,
save,
set_audio_backend,
) )
from . import ( # noqa: F401 from . import ( # noqa: F401
backend, # For BC
compliance, compliance,
datasets, datasets,
functional, functional,
...@@ -16,7 +22,9 @@ from . import ( # noqa: F401 ...@@ -16,7 +22,9 @@ from . import ( # noqa: F401
transforms, transforms,
utils, utils,
) )
from ._backend import AudioMetaData, get_audio_backend, info, list_audio_backends, load, save, set_audio_backend
# For BC
from . import backend # noqa # usort: skip
try: try:
from .version import __version__, git_version # noqa: F401 from .version import __version__, git_version # noqa: F401
......
...@@ -3,35 +3,6 @@ ...@@ -3,35 +3,6 @@
# New things should be added to `torchaudio._backend`. # New things should be added to `torchaudio._backend`.
# Only things related to backward compatibility should be placed here. # Only things related to backward compatibility should be placed here.
from . import common, no_backend, soundfile_backend, sox_io_backend # noqa
def __getattr__(name: str): __all__ = []
if name == "common":
from . import _common
return _common
if name in ["no_backend", "sox_io_backend", "soundfile_backend"]:
import warnings
warnings.warn(
"Torchaudio's I/O functions now support par-call bakcend dispatch. "
"Importing backend implementation directly is no longer guaranteed to work. "
"Please use `backend` keyword with load/save/info function, instead of "
"calling the udnerlying implementation directly.",
stacklevel=2,
)
if name == "sox_io_backend":
from . import _sox_io_backend
return _sox_io_backend
if name == "soundfile_backend":
from torchaudio._backend import soundfile_backend
return soundfile_backend
if name == "no_backend":
from . import _no_backend
return _no_backend
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
...@@ -2,6 +2,7 @@ from pathlib import Path ...@@ -2,6 +2,7 @@ from pathlib import Path
from typing import Callable, Optional, Tuple, Union from typing import Callable, Optional, Tuple, Union
from torch import Tensor from torch import Tensor
from torchaudio import AudioMetaData
def load( def load(
...@@ -20,5 +21,5 @@ def save(filepath: str, src: Tensor, sample_rate: int, precision: int = 16, chan ...@@ -20,5 +21,5 @@ def save(filepath: str, src: Tensor, sample_rate: int, precision: int = 16, chan
raise RuntimeError("No audio I/O backend is available.") raise RuntimeError("No audio I/O backend is available.")
def info(filepath: str) -> None: def info(filepath: str) -> AudioMetaData:
raise RuntimeError("No audio I/O backend is available.") raise RuntimeError("No audio I/O backend is available.")
def __getattr__(name: str): def __getattr__(name: str):
import warnings
if name == "AudioMetaData": if name == "AudioMetaData":
import warnings
warnings.warn( warnings.warn(
"`torchaudio.backend.common.AudioMetaData` has been moved to " "`torchaudio.backend.common.AudioMetaData` has been moved to "
"`torchaudio.AudioMetaData`. Please update the import path.", "`torchaudio.AudioMetaData`. Please update the import path.",
......
def __getattr__(name: str):
import warnings
warnings.warn(
"Torchaudio's I/O functions now support par-call bakcend dispatch. "
"Importing backend implementation directly is no longer guaranteed to work. "
"Please use `backend` keyword with load/save/info function, instead of "
"calling the udnerlying implementation directly.",
stacklevel=2,
)
from . import _no_backend
return getattr(_no_backend, name)
def __getattr__(name: str):
import warnings
warnings.warn(
"Torchaudio's I/O functions now support par-call bakcend dispatch. "
"Importing backend implementation directly is no longer guaranteed to work. "
"Please use `backend` keyword with load/save/info function, instead of "
"calling the udnerlying implementation directly.",
stacklevel=2,
)
from torchaudio._backend import soundfile_backend
return getattr(soundfile_backend, name)
def __getattr__(name: str):
import warnings
warnings.warn(
"Torchaudio's I/O functions now support par-call bakcend dispatch. "
"Importing backend implementation directly is no longer guaranteed to work. "
"Please use `backend` keyword with load/save/info function, instead of "
"calling the udnerlying implementation directly.",
stacklevel=2,
)
from . import _sox_io_backend
return getattr(_sox_io_backend, name)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment