Repository: dask/dask
Pull request #8184 (2021-09-27 18:59:40)

Bump `RAPIDS_VER` for gpuCI
With cudf 21.12 nightlies out, we can now bump gpuCI here to use `RAPIDS_VER=21.12`. Note that this shouldn't be merged until rapidsai/dask-build-environment#8 is merged and the new images built.




Patch:
diff --git a/continuous_integration/gpuci/axis.yaml b/continuous_integration/gpuci/axis.yaml
index 587b193b0..da4a725bd 100644
--- a/continuous_integration/gpuci/axis.yaml
+++ b/continuous_integration/gpuci/axis.yaml
@@ -8,6 +8,6 @@ LINUX_VER:
 - ubuntu18.04
 
 RAPIDS_VER:
-- "21.10"
+- "21.12"
 
-excludes:
\ No newline at end of file
+excludes:
diff --git a/dask/utils.py b/dask/utils.py
index ef2571bc5..afd10bd30 100644
--- a/dask/utils.py
+++ b/dask/utils.py
@@ -544,28 +544,26 @@ class Dispatch:
 
     def dispatch(self, cls):
         """Return the function implementation for the given ``cls``"""
-        # Fast path with direct lookup on cls
         lk = self._lookup
-        try:
-            impl = lk[cls]
-        except KeyError:
-            pass
-        else:
-            return impl
-        # Is a lazy registration function present?
-        toplevel, _, _ = cls.__module__.partition(".")
-        try:
-            register = self._lazy.pop(toplevel)
-        except KeyError:
-            pass
-        else:
-            register()
-            return self.dispatch(cls)  # recurse
-        # Walk the MRO and cache the lookup result
-        for cls2 in inspect.getmro(cls)[1:]:
-            if cls2 in lk:
-                lk[cls] = lk[cls2]
-                return lk[cls2]
+        for cls2 in cls.__mro__:
+            try:
+                impl = lk[cls2]
+            except KeyError:
+                pass
+            else:
+                if cls is not cls2:
+                    # Cache lookup
+                    lk[cls] = impl
+                return impl
+            # Is a lazy registration function present?
+            toplevel, _, _ = cls2.__module__.partition(".")
+            try:
+                register = self._lazy.pop(toplevel)
+            except KeyError:
+                pass
+            else:
+                register()
+                return self.dispatch(cls)  # recurse
         raise TypeError("No dispatch for {0}".format(cls))
 
     def __call__(self, arg, *args, **kwargs):
diff --git a/docs/source/setup/ssh.rst b/docs/source/setup/ssh.rst
index 0c4fceb5b..ce6cd7c79 100644
--- a/docs/source/setup/ssh.rst
+++ b/docs/source/setup/ssh.rst
@@ -7,6 +7,13 @@ Dask :doc:`command line interface <cli>`,
 or automatically using either the ``SSHCluster`` Python command or the
 ``dask-ssh`` command line tool. This document describes both of these options.
 
+.. note::
+   Before instaniating a ``SSHCluster`` it is recommended to configure keyless SSH
+   for your local machine and other machines. For example, on a Mac to SSH into
+   localhost (local machine) you need to ensure the Remote Login option is set in
+   System Preferences -> Sharing. In addition, ``id_rsa.pub`` should be in
+   ``authorized_keys`` for keyless login.
+
 Python Interface
 ----------------
 


Test patch:
diff --git a/dask/tests/test_utils.py b/dask/tests/test_utils.py
index 5b71881a0..6e7bf9a5d 100644
--- a/dask/tests/test_utils.py
+++ b/dask/tests/test_utils.py
@@ -161,6 +161,38 @@ def test_dispatch_lazy():
     assert foo(1) == 1
 
 
+def test_dispatch_lazy_walks_mro():
+    """Check that subclasses of classes with lazily registered handlers still
+    use their parent class's handler by default"""
+    import decimal
+
+    class Lazy(decimal.Decimal):
+        pass
+
+    class Eager(Lazy):
+        pass
+
+    foo = Dispatch()
+
+    @foo.register(Eager)
+    def eager_handler(x):
+        return "eager"
+
+    def lazy_handler(a):
+        return "lazy"
+
+    @foo.register_lazy("decimal")
+    def register_decimal():
+        foo.register(decimal.Decimal, lazy_handler)
+
+    assert foo.dispatch(Lazy) == lazy_handler
+    assert foo(Lazy(1)) == "lazy"
+    assert foo.dispatch(decimal.Decimal) == lazy_handler
+    assert foo(decimal.Decimal(1)) == "lazy"
+    assert foo.dispatch(Eager) == eager_handler
+    assert foo(Eager(1)) == "eager"
+
+
 def test_random_state_data():
     np = pytest.importorskip("numpy")
     seed = 37