-
-
Notifications
You must be signed in to change notification settings - Fork 10
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
Support for Enums #73
Comments
I think that the regex approach might become problematic. It might work for this case but there are maybe usecases in the future where the repr string is missing some information. A custom repr implementation which you can specialize for your type with a generic fallback to a singledispatch might be useful here. |
I can do a first implementation today in the evening. |
Just some thoughts. I just mentioned plain enums above, but my actual usecase of enums is within pydantic objects. I haven't not worked with So if you planning to add support to use custom But I am not sure on what we could do to handle objects with user/client specified custom |
did you wrote the enum class or is it from a other library? you could do the following, if it is your own. from enum import Enum
from inline_snapshot import snapshot
class SomeEnum(Enum):
VAL1 = "val1"
def __repr__(self):
return type(self).__name__ + "." + self._name_
def test_snap():
a = SomeEnum.VAL1
assert a == snapshot(SomeEnum.VAL1) |
another more generic approach might be this from enum import Enum
from functools import singledispatch
from pydantic import BaseModel
class SomeEnum(Enum):
VAL1 = "val1"
a = SomeEnum.VAL1
class PydanticContainer(BaseModel):
v: SomeEnum
class Container:
def __init__(self, v):
self.v = v
def __repr__(self):
# this does not work, because the f-string does no lookup of repr in the global/builtin namespase
# return f"{self.v}"
# repr from __builtins__ is our code_repr
# this means that a __repr__ which uses repr()
return repr(self.v)
real_repr = repr
@singledispatch
def code_repr(v):
return real_repr(v)
@code_repr.register
def _(v: Enum):
return type(v).__name__ + "." + v._name_
@code_repr.register
def _(v: list):
return "[" + ",".join(map(repr, v)) + "]"
# this would be only changed when we convert the value to source code
__builtins__.__dict__["repr"] = code_repr
# does work for a simple Container which uses repr()
print(repr([Container(a), a, 5]))
# does not work for PydanticContainer out of the box,
# because pydantic does not look up our mocked repr
print(repr(PydanticContainer(v=a)))
# special handling for pydantic BaseModel which uses repr()
@code_repr.register
def _(model: BaseModel):
return (
type(model).__name__
+ "("
+ ", ".join(
e + "=" + repr(getattr(model, e)) for e in model.__pydantic_fields_set__
)
+ ")"
)
# now it works
print(repr(PydanticContainer(v=a))) output (Python 3.12.1): [SomeEnum.VAL1,SomeEnum.VAL1,5]
PydanticContainer(v=<SomeEnum.VAL1: 'val1'>)
PydanticContainer(v=SomeEnum.VAL1) But I would like to know if it is possible for you to add a |
Some of them are under my control and some are not. I could make the enums under my control to have the custom repr. But how should I go about patching the ones from other libraries? Is there any way I could tell |
yes, this would become a never ending story. Allowing to customize This has the drawback that I also have to provide custom Enums would be supported by default, also inside a
You will also be able to register custom from inline_snapshot import register_repr
@register_repr
def _(obj: MyCustomType):
return "MyCustomType(...)" This is currently only a plan and not implemented. But I'm confident that it will work. |
hi, @RazCrimson you can test the #85 if you want. |
Cool, I'll test it out tomorrow morning and let you know if I find any issues. |
I also stepped on this issue and traced it to Enum after some debugging. Maybe we can report something to the user if the parsing fails here? inline-snapshot/inline_snapshot/_inline_snapshot.py Lines 719 to 722 in 56de34b
|
As for #85, it didn't fix my use case of enums inside dataclasses:
The resulting snapshot: The assertion fails (after importing HasRepr):
|
Thank you for trying this feature branch. The good thing about the approach is that you can replace repr if you want, the bad thing is that you have to replace it sometimes if you don't want. What is missing in your case is a custom repr implementation for data classes which recursively uses repr() for the attributes. You can try to build one or wait a bit because I have other things to do for the next two days. Auto import of missing names is also something I want to implement. |
Currently Inline snapshot doesn't seem to support working with Enums.
Example:
Running
pytest --inline-snapshot=create
states that the snapshot were defined, but they are actually not. I presume this is due to the behavior ofrepr
with Enums:I am not sure as to how it can be handled, but maybe some regex filtering could be applied over reprs of only Enum objects and just use the Enum value for the snapshot. Would really love this.
P.S. I am not really confident, but I'll try taking a stab at this if you fine with accepting a PRs.
The text was updated successfully, but these errors were encountered: