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):
with patch("soundfile.info", _mock_info_func):
with warnings.catch_warnings(record=True) as w:
info = soundfile_backend.info("foo")
assert len(w) == 1
assert "UNSEEN_SUBTYPE subtype is unknown to TorchAudio" in str(w[-1].message)
assert info.bits_per_sample == 0
......
# Initialize extension and backend first
from . import ( # noqa # usort: skip
_extension,
_backend,
from . import _extension # noqa # usort: skip
from ._backend import ( # noqa # usort: skip
AudioMetaData,
get_audio_backend,
info,
list_audio_backends,
load,
save,
set_audio_backend,
)
from . import ( # noqa: F401
backend, # For BC
compliance,
datasets,
functional,
......@@ -16,7 +22,9 @@ from . import ( # noqa: F401
transforms,
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:
from .version import __version__, git_version # noqa: F401
......
......@@ -3,35 +3,6 @@
# New things should be added to `torchaudio._backend`.
# 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):
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}")
__all__ = []
......@@ -2,6 +2,7 @@ from pathlib import Path
from typing import Callable, Optional, Tuple, Union
from torch import Tensor
from torchaudio import AudioMetaData
def load(
......@@ -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.")
def info(filepath: str) -> None:
def info(filepath: str) -> AudioMetaData:
raise RuntimeError("No audio I/O backend is available.")
def __getattr__(name: str):
import warnings
if name == "AudioMetaData":
import warnings
warnings.warn(
"`torchaudio.backend.common.AudioMetaData` has been moved to "
"`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