adamboche / python-marshmallow-union

Union fields for marshmallow.
MIT License
19 stars 5 forks source link

union field type without instantiation ? #26

Open asmodehn opened 4 years ago

asmodehn commented 4 years ago

I have just used Union and I found one issue with the way it works currently...

This code is here for illustration purposes only.

from marshmallow import fields

# the class to use as field for type 'int'
fields.Integer
# the class to use as field for type 'str'
fields.String

# a field must be instantiated when used in a schema 
class MySchema(marshmallow.Schema):
    f1 = fields.Integer()

# However for a Union, the specification of the type and the instantiation happen at the same step:

from marshmallow_union import Union

# the class for the field does NOT contains the possible types:
Union 

# the possible types must be specified at instantiation:
Union(fields=[fields.Integer(), fields.String()])

I believe this is probably fine for simple usecases, where you just want to have a union in a schema.

In my case I am manipulating schemas and fields dynamically, along with python type hints, and this becomes quite troublesome...

Instead I would expect that to be:

# the type of the field
Union[fields.Integer, fields.String]

# the instantiation of the field
Union[fields.Integer, fields.String]()

Thoughts ?

adamboche commented 4 years ago

That's an interesting point. Union is behaving similarly to fields.List(fields.Int()) and differs from the Generic[T] syntax of typing.Union[...] and typing.List[int].

In my case I am manipulating schemas and fields dynamically, along with python type hints, and this becomes quite troublesome...

Sounds cool! Is your project online somewhere?

asmodehn commented 4 years ago

I was currently thinking of using a union to define a "payload" schema, that can accept various types (union) of content data. This is a current use case you can find here : https://github.com/asmodehn/aiokraken/blob/develop/aiokraken/rest/schemas/payload.py, where I currently build schemas via a pydef... If you're interested to look into that, you'll need to have a look at kraken's API structure as well ( I want to validate all incoming/outgoing data via schemas for the whole API - somewhat a non-trivial task )

Previously I built a very simple "typechecker" to verify network message data content between ROS and a REST backend, more strictly than the default libraries, and attempted to match with python types via marshmallow. I had issues dealing with with Optional types (but I can't remember exactly, it was a while ago..) you can find that there : https://github.com/pyros-dev/pyros-schemas and you need also https://github.com/pyros-dev/pyros-msgs. I believe at the time I also had similar issues with marshmallow (having to know and define all types upfront in the class declaration), and I dealt with it via function calls as well to build somewhat complex schemas dynamically https://github.com/pyros-dev/pyros-schemas/blob/master/pyros_schemas/ros/schemagic.py#L54

phyrwork commented 3 years ago

I got caught out by this one earlier. +1!