wyfo / apischema

JSON (de)serialization, GraphQL and JSON schema generation using Python typing.

Home Page:https://wyfo.github.io/apischema/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lazy deserialiser not found depending on order of registration

DiamondJoseph opened this issue · comments

When registering a lazy deserialiser for a type that extends Protocol, the type can be made not findable by the addition of an unrelated type. The following code correctly finds the deserialiser, unless Bar is registered before Foo- Bar can also be found if baz is removed.

from typing import Protocol, runtime_checkable

from apischema import deserialize, deserializer
from apischema.conversions import Conversion


@runtime_checkable
class Foo(Protocol):
    ...


@runtime_checkable
class Bar(Protocol):
    def baz(self):
        ...


for protocol in [Foo, Bar]:
    deserializer(
        lazy=lambda: Conversion(lambda as_str: ..., source=str, target=protocol),
        target=protocol,
    )


assert deserialize(Bar, "foo") == ...

I'm not sure to understand the issue, but there is a bug in your example: lambda: Conversion(lambda as_str: ..., source=str, target=protocol) should be lambda protocol=protocol: Conversion(lambda as_str: ..., source=str, target=protocol) (see https://stackoverflow.com/questions/7546285/creating-lambda-inside-a-loop for example)

By fixing your example, I can either write for protocol in [Foo, Bar] or for protocol in [Bar, Foo] and both works, so I cannot reproduce your issue. Am I missing something?