Fix RecursionError when serializing Enum/IntFlag parameter values#140
Merged
marcosfrenkel merged 2 commits intoJun 11, 2026
Merged
Conversation
marcosfrenkel
commented
Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Station snapshots (and parameter gets) containing
IntFlag/Enumvalues crashedthe server with
RecursionError: maximum recursion depth exceededon the sendpath. This happens with real drivers such as the Yokogawa GS200, whose
status/event-register parameters return
IntFlaginstances.Root cause
Starting with Python 3.11,
Flag/IntFlagmembers are iterable, and asingle-bit member iterates to a one-element sequence containing itself:
The serializers (
dict_to_serialized_dict/iterable_to_serialized_dict)recurse into anything that is a non-
strIterable. A flag value matched thatcheck and recursed into itself forever, raising
RecursionErrorfromencode()on the server's send path — so the client never got a response.
Fix
blueprints.py:Enumas a scalar indict_to_serialized_dictanditerable_to_serialized_dict(serialize its.value), placed before thegeneric
Iterablecheck so flag members never recurse.Enum/IntFlagmessage (the return of a parameter get),serialize it with its
_class_typevia the new_convert_enum_to_dicthelperso the client reconstructs the actual enum instance — not just a bare int.
Tests
New
test/pytest/test_enum_serialization.py:value without recursion.
encode(ServerResponse(...))over a snapshot reproduces the original failingpath and asserts valid JSON.
enum type.
snapshot) using a new
DummyInstrumentWithFlagsdummy instrument that mirrorsthe GS200 status registers.
Notes
A nested flag inside a snapshot is serialized lossily to its integer value
(snapshots are display-oriented), whereas a parameter get round-trips back to
the actual enum type via
_class_type.