New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
can't construct dataclass as ABC (or runtime check as data protocol) #83315
Comments
At runtime, we want to check whether objects adhere to a data protocol. This is not possible due to problematic interactions between ABC and @DataClass. The attached file tests all relevant yet impossible cases. Those are:
The problem can be solved in two parts. First allowing to implement @abstractproperty in a dataclass (B). This doesn't involve typing and enables the expected use case of dataclass+ABC. I analysed this problem as follows: Second, eliding the exception of @runtime_checkable Protocols with non-method members if and only if the the the protocol is in its MRO. I didn't think that through fully, but instantiation could e.g. fail for missing implementations as expected from ABC behaviour (see case D in attached file). I'm not sure about the runtime overhead of this suggestion. |
Is dataclasses doing something here that a regular, hand-written class wouldn't do? |
Here, nothing but less boiler plate. Wouldn't it pay off to not rewrite dataclass features like frozen, replace, runtime refelection and the ability to use dataclass aware serialization libraries (e.g. pydantic)? I think @DataClass+@abstractproperty behaviour is yet to be defined. The second part about subclass check is not specific to dataclasses. |
|
Pardon my sloppiness.
|
Thanks. Can you be specific about “modern libraries”? Please clarify your use cases. |
We construct a computational graph and need to validate (or search for possible new) edges at runtime. The data is specific to computer vision. One example is clipping geometry within 2D boundaries. A minimal implementation of this data would be: @dataclass
class FramedGeometry:
width: PositiveInt
height: PositiveInt
geometry: Geometry However, different properties are manifest in different encodings. Height, width can be meta data from an image database or inherent to a decoded image (as np.ndarray.shape). The transform will then The read-only interface ensures that transitions are generic wrt some forms of inputs. The replace interface preserves runtime types. Inputs and outputs are annotated with @DataClass or tuples of them. Those dataclasses are a mixin of base dataclasses that declare concrete properties like a URI of an image and ABCs that declare accessors like get_width(self) -> PositiveInt. We use @pydantic.dataclass to parse, validate and deserialize concrete classes to great extent [0]. In order to not implement accessors on top of dataclasses, we'd want that abstract properties are compatible with dataclasses and issubclass works with data protocols (given the necessary constraints). PS: class EncodedSizedAnnotatedFrame:
width: PositiveInt
height: PositiveInt
image_bin: bytes
geometry: Geometry Thanks! [0] https://pydantic-docs.helpmanual.io/usage/dataclasses/ |
Have you tried dropping ABCMeta? Mypy checks @AbstractMethod regardless. |
Dropping ABCMeta stops at instantiation. This should be in the dataclass code that's been generated. File "<string>", line 2, in __init__ Repro:
Interestingly, frozen=False is giving the same error. |
Try adding a setter to the base class method. |
This results in E(x=None). I'd need to look into that to understand why. |
No doubt because your getter returns None. |
In that case, what should the getter return? It doesn't know about the implementation of x. |
In the example, it should be Anyway, the bug tracker is not a good place to get questions answered. Since this is mostly about type checking, I recommend that you try this Gitter instance: https://gitter.im/python/typing |
I ran into the same "can't define dataclass as ABC" problem and found that using py3.10's
On further testing, |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: