From e9c64168d9fb9c3d0ce94b537eb7cd9728abd379 Mon Sep 17 00:00:00 2001 From: hauntsaninja <> Date: Tue, 22 Feb 2022 12:49:07 -0800 Subject: [PATCH] Import packaging.version in torch_version, if available (#71902) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Resolves https://github.com/pytorch/pytorch/issues/71280 We used to use `from pkg_resources import packaging`. To recap, this has three potential problems: 1) `pkg_resources` is a really slow import 2) We have an undeclared runtime dependency on `setuptools` 3) We're relying on `pkg_resources`'s secret vendored copy of `packaging`. This is obviously not part of the public API of `pkg_resources`. In https://github.com/pytorch/pytorch/issues/71345 this was made a lazy import, which is great! It means we don't run into these problems as long as users don't use `torch.__version__`. This change additionally helps further address problems 1 and 3, by directly importing `packaging`, if present, and only falling back to the vendored copy in `pkg_resources`. Benchmark for speed difference in a virtual environment with a couple hundred packages installed: ``` λ hyperfine -w 2 'python -c "from pkg_resources import packaging"' 'python -c "import packaging.version"' Benchmark 1: python -c "from pkg_resources import packaging" Time (mean ± σ): 706.7 ms ± 77.1 ms [User: 266.5 ms, System: 156.8 ms] Range (min … max): 627.9 ms … 853.2 ms 10 runs Benchmark 2: python -c "import packaging.version" Time (mean ± σ): 53.8 ms ± 8.5 ms [User: 34.8 ms, System: 14.4 ms] Range (min … max): 46.3 ms … 72.3 ms 53 runs 'python -c "import packaging.version"' ran 13.14 ± 2.52 times faster than 'python -c "from pkg_resources import packaging"' ``` Pull Request resolved: https://github.com/pytorch/pytorch/pull/71902 Reviewed By: mikaylagawarecki Differential Revision: D34343145 Pulled By: malfet fbshipit-source-id: a6bd7ecf0cbb6b5c20ab18a22576aa2df9eb3324 (cherry picked from commit 0a249044c8f83ecbc81b6d1e7a16541b82b74243) --- torch/torch_version.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/torch/torch_version.py b/torch/torch_version.py index a7aa6764b5d..9fd989a44ff 100644 --- a/torch/torch_version.py +++ b/torch/torch_version.py @@ -8,7 +8,7 @@ class _LazyImport: def v(): return Version('1.2.3') and - Versoin = _LazyImport('Version') + Version = _LazyImport('Version') def v(): return Version('1.2.3') The difference here is that in later example imports @@ -18,7 +18,12 @@ class _LazyImport: self._cls_name = cls_name def get_cls(self): - from pkg_resources import packaging # type: ignore[attr-defined] + try: + import packaging.version # type: ignore[import] + except ImportError: + # If packaging isn't installed, try and use the vendored copy + # in pkg_resources + from pkg_resources import packaging # type: ignore[attr-defined] return getattr(packaging.version, self._cls_name) def __call__(self, *args, **kwargs):