Content-Length: 369734 | pFad | https://github.com/fastplotlib/fastplotlib/issues/389

56 consider descriptor pattern for `GraphicFeature`. · Issue #389 · fastplotlib/fastplotlib · GitHub
Skip to content

consider descriptor pattern for GraphicFeature. #389

Closed
@tlambert03

Description

@tlambert03

While playing around with some examples, I saw this type error reported by mypy:

Screenshot 2023-12-04 at 12 01 06 PM

I dug into a bit and learned about the Graphic/GraphicFeature relationship. Apologies if you already know this and specifically decided against it... but the general pattern of an abstract _set method on GraphicFeature objects that retain a pointer to some parent object looks very much like it could be replaced/improved with python descriptors.

For example, the current pattern (highly simplified) is:

class GraphicFeature:
    def __init__(self, parent):
        self._parent = weakref.proxy(parent)

    def _set(self, value):
        raise NotImplementedError


class SomeFeature(GraphicFeature):
    def _set(self, value):
        print(f"setting {self.name!r} on {self._parent} to {value!r}")


class Graphic:
    def __setattr__(self, key, value):
        if hasattr(self, key):
            attr = getattr(self, key)
            if isinstance(attr, GraphicFeature):
                attr._set(value)
                return

        super().__setattr__(key, value)


class SomeGraphic(Graphic):
    def __init__(self) -> None:
        self.feature = SomeFeature()

with the descriptor pattern, that all reduces to

class SomeFeature:
    def __get__(self, instance, owner):
        ...

    def __set__(self, obj, value):
        print(f"setting feature on {obj} to {value!r}")


class SomeGraphic:
    feature = SomeFeature()

and when you set the feature attribute on an instance of SomeGraphic, then SomeFeature.__set__ will be called with the instance and value:

In [18]: g = SomeGraphic()

In [19]: g.feature = 1
setting feature on <__main__.SomeGraphic object at 0x106c33750> to 1

this also works very nicely for typing:

Screenshot 2023-12-04 at 12 11 15 PM

note that it neither complains when setting .feature = [1,2,3], and it also recognizes that accessing .feature will return a str (i.e. it's been coerced from list to some internal value), based on the type hints of __set__ and __get__

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions









      ApplySandwichStrip

      pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


      --- a PPN by Garber Painting Akron. With Image Size Reduction included!

      Fetched URL: https://github.com/fastplotlib/fastplotlib/issues/389

      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy