Python type hinting - circular imports - enum serialization bug

Hi @izzylys, @m-clare,

Have two issues to discuss, first one is solved, but might be nice to have your opinion. Second one seems to be a bug, that was introduced in specklepy version 2.6.0.

  1. Have been working a bit more on the auto-generated Python classes from the Structural namespaces. When I started applying them, I got into a lot of circular import errors, caused by the import of classes required for providing proper type hints. I guess that these circular references are not an issue in C#, but in Python they are of course. In the end, I was able to solve it using the __future__ annotations functionality that delays resolving the type hints until everything is imported. Also, I had to import all Structural Speckle classes by module, so it doesn’t already scan through all classes at import (which would give the same circular import error). In the end, that gives a class definition as:


    With this class definition, all classes are properly imported, type hints are able to resolve and objects can be created. So it does work, but I’m still interested to hear what you think of this approach, or if you have ideas or remarks to improve?

  2. There is an issue with serialization of Python enumeration classes, of which there are quite some in the Structural definition. Problem is that the possibility of having a Python Enum class is currently not caught by the traverse_value() method in base_object_serializer.py. That means an enumeration value will enter below else: statement:


    As an enumeration value has no dict() method defined, it enters the except: statement, where it seems that the warn function can only deal with Warning subclasses as category, not with a SerializationException, which throws a TypeError. A nice solution would be to include an if-statement for isinstance(obj, Enum) and return a string value.
    As mentioned above, this issue was introduced in specklepy version 2.6.0, by this commit.

4 Likes

hey @Rob!

re 1), the way you’ve done it is prob the way to go to keep it as automated as possible. if you wanna go the more manual route like @Reynold_Chan did for the currently bundled structural stuff, you’ll need to do a bit of crafting to adapt to python as you’re totally right that the structure doesn’t always translate well from c# to py

good catch re 2) - i guess we aren’t supporting enums so I will have a test and add handling for that. super soz about that and thanks for bringing this to my attention! re the commit you linked - it’s just a change from SpeckleException to a warning so that is an unrelated issue and is not the cause of this. the serialisation logic hasn’t actually changed so if the enum serialisation isn’t working now, it was never working - oooops :sweat_smile:

i’ve asked the lovely @Reynold_Chan to add some unit tests for the structural py stuff to make sure we don’t have any other bugs hiding there and to prevent stuff like this from slipping under the radar in the future!

2 Likes

Thanks!

Agree that the issue with the warning was essentially unrelated. I will check if it’s solved when a new version is released, but I don’t expect any issues there :slight_smile:

heya, i’ve just pushed 2.6.3 out so lemme know how you get on w that!

note that for consistency w sharp, enums are serialised as ints. this means that you need enums to be typed members on your classes (which looks like will usually be the case for you since you’re using the generated classes). dynamic members will be deserialised as ints as for now there isn’t a way to know that they should be enums if they aren’t typed memebers

3 Likes

Had a quick check today, and it indeed solves the problem!

Also good to know that the integer value is used for storing. And indeed, all enumerations are directly included in the classes as typed members, so don’t expect any problems there, but thanks for the heads up :smile:

2 Likes