Repository: dask/distributed

Issue:
importing distributed runs 4 `git` subprocesses in CI (when installed with -e)
I noticed that tests that run a dask subprocess are often flakey on CI (especially so on low performance macos runners)

https://github.com/dask/distributed/runs/4922796526?check_suite_focus=true#step:12:1849
This is an example of a process taking more than 5 seconds to boot on a mac in `test_dask_worker::test_memory_limit`:

```pytb
Traceback (most recent call last):
  File "/Users/runner/miniconda3/envs/dask-distributed/bin/dask-worker", line 33, in <module>
    sys.exit(load_entry_point('distributed', 'console_scripts', 'dask-worker')())
  File "/Users/runner/miniconda3/envs/dask-distributed/bin/dask-worker", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/Users/runner/miniconda3/envs/dask-distributed/lib/python3.9/importlib/metadata.py", line 77, in load
    module = import_module(match.group('module'))
  File "/Users/runner/miniconda3/envs/dask-distributed/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 972, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 850, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/Users/runner/work/distributed/distributed/distributed/__init__.py", line 49, in <module>
    versions = get_versions()
  File "/Users/runner/work/distributed/distributed/distributed/_version.py", line 534, in get_versions
    pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
  File "/Users/runner/work/distributed/distributed/distributed/_version.py", line 265, in git_pieces_from_vcs
    full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
  File "/Users/runner/work/distributed/distributed/distributed/_version.py", line 78, in run_command
    p = subprocess.Popen(
  File "/Users/runner/miniconda3/envs/dask-distributed/lib/python3.9/subprocess.py", line 951, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/Users/runner/miniconda3/envs/dask-distributed/lib/python3.9/subprocess.py", line 1777, in _execute_child
    part = os.read(errpipe_read, 50000)
KeyboardInterrupt
```

Discussion:
github-actions[bot]: ## Unit Test Results
       15 files  +       15         15 suites  +15   8h 33m 55s [:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "duration of all tests") + 8h 33m 55s
  2 603 tests +  2 603    2 525 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "passed tests") +  2 525       78 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "skipped / disabled tests") +     78  0 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "failed tests") ±0 
19 521 runs  +19 521  18 194 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "passed tests") +18 194  1 327 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "skipped / disabled tests") +1 327  0 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "failed tests") ±0 

Results for commit 02941db2. ± Comparison against base commit 8d0df89b.

fjetter: Your file formatting is a bit off. I would suggest to install pre-commit, see http://distributed.dask.org/en/stable/develop.html#code-formatting


Patch:
diff --git a/distributed/__init__.py b/distributed/__init__.py
index e44a119c..d33514ab 100644
--- a/distributed/__init__.py
+++ b/distributed/__init__.py
@@ -1,10 +1,12 @@
 from . import config  # isort:skip; load distributed configuration first
 from . import widgets  # isort:skip; load distributed widgets second
+
+
 import dask
 from dask.config import config  # type: ignore
 
 from ._version import get_versions
-from .actor import Actor, BaseActorFuture
+from .actor import Actor, ActorFuture, BaseActorFuture
 from .client import (
     Client,
     CompatibleExecutor,
@@ -46,7 +48,20 @@ from .variable import Variable
 from .worker import Reschedule, Worker, get_client, get_worker, print, secede, warn
 from .worker_client import local_client, worker_client
 
-versions = get_versions()
-__version__ = versions["version"]
-__git_revision__ = versions["full-revisionid"]
-del get_versions, versions
+
+def __getattr__(name):
+    global __version__, __git_revision__
+
+    if name == "__version__":
+        from importlib.metadata import version
+
+        __version__ = version("distributed")
+        return __version__
+
+    if name == "__git_revision__":
+        from ._version import get_versions
+
+        __git_revision__ = get_versions()["full-revisionid"]
+        return __git_revision__
+
+    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


Test patch:
diff --git a/distributed/tests/test_init.py b/distributed/tests/test_init.py
new file mode 100644
index 00000000..c8e3f986
--- /dev/null
+++ b/distributed/tests/test_init.py
@@ -0,0 +1,13 @@
+from __future__ import annotations
+
+import importlib.metadata
+
+import distributed
+
+
+def test_version() -> None:
+    assert distributed.__version__ == importlib.metadata.version("distributed")
+
+
+def test_git_revision() -> None:
+    assert isinstance(distributed.__git_revision__, str)