Return a function that creates picklable classes inheriting from a mixin. After :: factory = _make_class_factory(FooMixin, fmt, attr_name) FooAxes = factory(Axes) ``Foo`` is a class that inherits from ``FooMixin`` and ``Axes`` and **is picklable** (picklability is
(mixin_class, fmt, attr_name=None)
| 2375 | |
| 2376 | @functools.cache |
| 2377 | def _make_class_factory(mixin_class, fmt, attr_name=None): |
| 2378 | """ |
| 2379 | Return a function that creates picklable classes inheriting from a mixin. |
| 2380 | |
| 2381 | After :: |
| 2382 | |
| 2383 | factory = _make_class_factory(FooMixin, fmt, attr_name) |
| 2384 | FooAxes = factory(Axes) |
| 2385 | |
| 2386 | ``Foo`` is a class that inherits from ``FooMixin`` and ``Axes`` and **is |
| 2387 | picklable** (picklability is what differentiates this from a plain call to |
| 2388 | `type`). Its ``__name__`` is set to ``fmt.format(Axes.__name__)`` and the |
| 2389 | base class is stored in the ``attr_name`` attribute, if not None. |
| 2390 | |
| 2391 | Moreover, the return value of ``factory`` is memoized: calls with the same |
| 2392 | ``Axes`` class always return the same subclass. |
| 2393 | """ |
| 2394 | |
| 2395 | @functools.cache |
| 2396 | def class_factory(axes_class): |
| 2397 | # if we have already wrapped this class, declare victory! |
| 2398 | if issubclass(axes_class, mixin_class): |
| 2399 | return axes_class |
| 2400 | |
| 2401 | # The parameter is named "axes_class" for backcompat but is really just |
| 2402 | # a base class; no axes semantics are used. |
| 2403 | base_class = axes_class |
| 2404 | |
| 2405 | class subcls(mixin_class, base_class): |
| 2406 | # Better approximation than __module__ = "matplotlib.cbook". |
| 2407 | __module__ = mixin_class.__module__ |
| 2408 | |
| 2409 | def __reduce__(self): |
| 2410 | return (_picklable_class_constructor, |
| 2411 | (mixin_class, fmt, attr_name, base_class), |
| 2412 | self.__getstate__()) |
| 2413 | |
| 2414 | subcls.__name__ = subcls.__qualname__ = fmt.format(base_class.__name__) |
| 2415 | if attr_name is not None: |
| 2416 | setattr(subcls, attr_name, base_class) |
| 2417 | return subcls |
| 2418 | |
| 2419 | class_factory.__module__ = mixin_class.__module__ |
| 2420 | return class_factory |
| 2421 | |
| 2422 | |
| 2423 | def _picklable_class_constructor(mixin_class, fmt, attr_name, base_class): |
no outgoing calls
no test coverage detected
searching dependent graphs…