uarray.determine_backend(value, dispatch_type, *, domain, only=True, coerce=False)[source]

Set the backend to the first active backend that supports value

This is useful for functions that call multimethods without any dispatchable arguments. You can use determine_backend() to ensure the same backend is used everywhere in a block of multimethod calls.

  • value – The value being tested

  • dispatch_type – The dispatch type associated with value, aka “marking”.

  • domain (string) – The domain to query for backends and set.

  • coerce (bool) – Whether or not to allow coercion to the backend’s types. Implies only.

  • only (bool) – Whether or not this should be the last backend to try.

See also


For when you know which backend to set


Support is determined by the __ua_convert__ protocol. Backends not supporting the type must return NotImplemented from their __ua_convert__ if they don’t support input of that type.


Suppose we have two backends BackendA and BackendB each supporting different types, TypeA and TypeB. Neither supporting the other type:

>>> with ua.set_backend(ex.BackendA):
...     ex.call_multimethod(ex.TypeB(), ex.TypeB())
Traceback (most recent call last):
uarray.BackendNotImplementedError: ...

Now consider a multimethod that creates a new object of TypeA, or TypeB depending on the active backend.

>>> with ua.set_backend(ex.BackendA), ua.set_backend(ex.BackendB):
...         res = ex.creation_multimethod()
...         ex.call_multimethod(res, ex.TypeA())
Traceback (most recent call last):
uarray.BackendNotImplementedError: ...

res is an object of TypeB because BackendB is set in the innermost with statement. So, call_multimethod fails since the types don’t match.

Instead, we need to first find a backend suitable for all of our objects.

>>> with ua.set_backend(ex.BackendA), ua.set_backend(ex.BackendB):
...     x = ex.TypeA()
...     with ua.determine_backend(x, "mark", domain="ua_examples"):
...         res = ex.creation_multimethod()
...         ex.call_multimethod(res, x)