-
Notifications
You must be signed in to change notification settings - Fork 90
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
msgspec.Struct cannot be used together with abc #806
Comments
That makes sense, since Funny, I tried to do the same thing just days ago, but I didn't know how to pass both metaclass parameters and two base classes. Didn't occur to me ABC brings a metaclass too. |
Did anyone find a solution to this? Any plans to make it compatible, somehow (e.g. introducing an |
You can't get rid of msgspec metaclass, you can only replace ab.ABC with another solution. What's your use case for it? I'm not even sure what using abc.ABC does specifically, just guessing it's Notice that msgspec doesn't directly support abstract classes - can't do msgspec.convert(..., AbstractClass)
# instead you need
msgspec.convert(..., ConcreteClass1 | ConcreteClass2) so in no scenario msgspec will try to instantiate your abstract class. |
Allow me to chime in again- with regard to the use case. Please take another look at the initial example: If msgspec supported abstract base classes, a runtime error would be raised at exactly the same point in time (just be a different one than currently), meaning when the class is supposed to be instantiated. |
The type-checker would raise an error if your user tries to implement your class without implementing all the methods. Sounds like a non-issue. |
@winstxnhdw: It is an issue... Your statement was true, if I could use abc as a meta-class (exactly what I asked for!).
The problem is, that an exception only appears once some_func() of Child1 instance is called - so in the last line of the code - and not when any code checker is run (because without abc, the code checker doesn't see that children need to implement the function and instances cannot be created) |
Use a |
@winstxnhdw: Thanks for the hint regarding Here's what I have currently:
When running mypy, I actually get the warning in line 11 ( |
Hey @777michael777, so I tried your example and I am all the more confused why you need any of this in the first place. Even without using a from __future__ import annotations
from msgspec import Struct
from msgspec.yaml import decode
class Elements(Struct):
elements: dict[str, Child1 | Child2] = {}
class Child1(Struct, tag=True):
pass
class Child2(Struct, tag=True):
def some_func(self) -> None:
print("Really implemented")
if __name__ == "__main__":
my_yaml = b"""elements:
child1:
name: "Me"
type: "Child1"
child2:
name: "You"
type: "Child2"
"""
elements: Elements = decode(my_yaml, type=Elements)
print(elements.elements)
elements.elements["child2"].some_func()
elements.elements["child1"].some_func() And it makes sense because the type checker can clearly see that you have not implemented |
Hi @winstxnhdw, Ok, let me try to explain what I had in mind: Apart from the configuration file, the users don't really care about the concrete type of spectrum analyzer, they just need to know which functions they can call for any of the spectrum analyzers - like "init", "configure_measurement_type1", etc. So my thinking was "I need an abstract class |
Description
I am trying to create a Struct that is also an abstract class and run into the metaclass conflict.
Here's an example:
When executing above code, I get
Also tried with not using the metaclass, but inherit Base from abc.ABC directly, with the same result.
The text was updated successfully, but these errors were encountered: