uplink icon indicating copy to clipboard operation
uplink copied to clipboard

Optional Field args don't work as expected

Open mure opened this issue 3 years ago • 2 comments

Describe the bug When using the Field annotation on an arg to be converted into a JSON field, nullable types don't work as expected. Using Optional directly throws an error, but you can work around this by using the x | None syntax instead. However, this is causing the request body to include unintended nulls.

To Reproduce

@json
@args(Field("a"))
@patch("route")
def patch(self, a: Optional[str] = None):
   pass

Result: TypeError: issubclass() arg 1 must be a class

@json
@args(Field("a"))
@patch("route")
def patch(self, a: str | None = None):
   pass

client.patch()

Result

{ "a": null }

It would be nice if this had the same behavior as Query params.

mure avatar Sep 30 '22 22:09 mure

Hi @mure found any workaround for this?

mateochr avatar Aug 07 '24 12:08 mateochr

I have been using the code below:

# reusable sentinel class
# https://peps.python.org/pep-0661/
NOT_SET = Sentinel("NOT_SET")

class OptionalField(Field):
    """Extend the `uplink.Field` class to make it optional.

    It is used to handle optional fields by not setting them if not
    provided.
    """

    def _modify_request(self, request_builder, value):
        if value is not NOT_SET:
            super()._modify_request(request_builder, value)

And then you can have any optional arg equal to NOT_SET

mateochr avatar Aug 08 '24 15:08 mateochr