Skip to content
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

Allow typing.Self as a hint-type. #46

Merged
merged 2 commits into from
Mar 24, 2024
Merged

Allow typing.Self as a hint-type. #46

merged 2 commits into from
Mar 24, 2024

Conversation

lojack5
Copy link
Owner

@lojack5 lojack5 commented Mar 14, 2024

Initial implementation for allowing typing.Self as a hint-type for Structured classes.

Note there are no safeguards to prevent hitting the recursion limit. I'm thinking of just allowing it, with the warning in the readme.

Should be backwards-compatible with < Python 3.11 via typing-extensions.

@lojack5 lojack5 added the enhancement New feature or request label Mar 14, 2024
@lojack5 lojack5 self-assigned this Mar 14, 2024
@lojack5 lojack5 force-pushed the typing.Self branch 2 times, most recently from fdc11b1 to 7ca3806 Compare March 14, 2024 01:39
@lojack5
Copy link
Owner Author

lojack5 commented Mar 14, 2024

@davidcurie Implementing the typing.Self typehint as a Serializable type wasn't too bad (had to troubleshoot some CI stuff due to the last 3.12 tests running when 3.12 was still in RC stage).

You can check out this branch and let me know if it suits your needs (as mentioned in #2 ), I'm guessing you can at least get unpacking to work with this. It's ready to go into main, just wanted to run it by you in case there was anything you wanted added/changed in this aspect.

@davidcurie
Copy link

In my use case, I'm using typing.Self as a conditional unpacking based on LookbackDecider.

from typing import Self, Union
from structured import Structured, LookbackDecider, uint16  # and other types

dtype_map = {
    0: Self,
    1: uint16,
    ⋮
}

class MyStruct(Structured):
    key: unicode[uint32]
    dtype: uint32
    start: uint64
    stop: uint64
    value: Annotated[Union[dtype_map.values], LookbackDecider(attrgetter("dtype"), dtype_map)]

The sanitation check taking place in serializers/unions.py prevents me from using this structure.

Traceback:
  File "path/to/my/example_test-self.py", line 39, in MyStruct
    value: Annotated[Union[dtype_map.values], LookbackDecider(attrgetter("dtype"), dtype_map)]
                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/anaconda3/envs/testing-env/lib/python3.11/site-packages/structured/serializers/unions.py", line 120, in __init__
    super().__init__(result_map, default)
  File "/opt/anaconda3/envs/witec-testing/lib/python3.11/site-packages/structured/serializers/unions.py", line 47, in __init__
    self.result_map = {
                      ^
  File "/opt/anaconda3/envs/testing-env/lib/python3.11/site-packages/structured/serializers/unions.py", line 48, in <dictcomp>
    key: self.validate_serializer(serializer)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/anaconda3/envs/witec-testing/lib/python3.11/site-packages/structured/serializers/unions.py", line 57, in validate_serializer
    raise TypeError(f'Union results must be serializable types, got {hint!r}.')
TypeError: Union results must be serializable types, got typing.Self.

Am I understanding the intended implementation incorrectly?

@lojack5
Copy link
Owner Author

lojack5 commented Mar 16, 2024

Ah, thanks for the test. Nope that is supposed to work, but I forgot to dig into the method than handles transforms for all other types. Will push a fix for that in a bit.

@lojack5
Copy link
Owner Author

lojack5 commented Mar 16, 2024

Might take a while longer than I thought. Some added tests revealed issues brought up due to the recursive possibilities. Thought I had it, everything was working except for array[Header[...], Self]. Now I gotta think carefully about recursion - probably brought on that the serializer on a Structured object is actually a class variable (and so shared between instances).

- Required rewriting some of the container serializers (Array, Union) to properly
  handle the fact that recursion (and thus re-use mid-pack/unpack) of a serializer
  can happen now.
@lojack5
Copy link
Owner Author

lojack5 commented Mar 21, 2024

Ok, took another pass at this, should be good to go for testing on your end. typing.Self should now be properly handled in all container-type hints (unions, arrays, etc).

@davidcurie
Copy link

I haven't explored all edge cases, but I can confirm that the error I described above no longer shows up. At the Structured level, this seems to work with how I would use it.

@lojack5 lojack5 merged commit 8a5e6a8 into main Mar 24, 2024
12 checks passed
@lojack5
Copy link
Owner Author

lojack5 commented Mar 24, 2024

Sounds good, if you run into any issues let me know.

@lojack5 lojack5 deleted the typing.Self branch October 8, 2024 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants