Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError during fetching __orig_bases__ on non-generic protocol implementation. #374

Closed
nekitdev opened this issue Jun 2, 2023 · 6 comments · Fixed by #436
Closed
Assignees
Labels
Milestone

Comments

@nekitdev
Copy link

nekitdev commented Jun 2, 2023

  • cattrs version: 23.1.2
  • python version: 3.11.3
  • operating system: windows 11

Description

I wanted to register an unstructure hook for an Entity type derived from the non-generic Binary protocol.

What I Did

CONVERTER.register_unstructure_hook(
    Entity, make_dict_unstructure_fn(Entity, CONVERTER, client_unchecked=override(omit=True))
)

Which caused an error:

  File ".../cattrs/gen/__init__.py", line 82, in make_dict_unstructure_fn
    mapping = generate_mapping(cl, mapping)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../cattrs/gen/_generics.py", line 32, in generate_mapping
    orig_bases = cl.__orig_bases__
                 ^^^^^^^^^^^^^^^^^
AttributeError: type object 'Entity' has no attribute '__orig_bases__'
@Tinche
Copy link
Member

Tinche commented Jun 2, 2023

Can you show me the Entity class? Or a minimal example of it that reproduces the issue.

@Tinche Tinche added the bug label Jun 2, 2023
@nekitdev
Copy link
Author

nekitdev commented Jun 2, 2023

Will do so a bit later, thanks for responding!

@nekitdev
Copy link
Author

nekitdev commented Jun 2, 2023

Here is an example I came up with; importing Protocol from typing does not change anything.
If the Protocol was generic, everything would work just fine.

from attrs import define
from cattrs import Converter
from cattrs.gen import make_dict_unstructure_fn
from typing_extensions import Protocol

CONVERTER = Converter()


class SomeProtocol(Protocol):
    ...


@define()
class Entity(SomeProtocol):
    ...


CONVERTER.register_unstructure_hook(Entity, make_dict_unstructure_fn(Entity, CONVERTER))

@nekitdev nekitdev changed the title AttributeError during fetching of __orig_bases__ on non-generic protocol implementation. AttributeError during fetching __orig_bases__ on non-generic protocol implementation. Jun 2, 2023
@shadchin
Copy link

I have the same error :-(

@Tinche Tinche added this to the 23.2 milestone Jun 20, 2023
@waweber
Copy link

waweber commented Aug 6, 2023

Also seeing this error.

There's a couple workarounds I tried that seem to work:

Adding a no-op protocol as a base:

_T = TypeVar("_T", covariant=True)

class _Protocol(Protocol[_T]):
    ...

class SomeProtocol(_Protocol[Any], Protocol):
    ...


@define()
class Entity(SomeProtocol):
    ...

Adding a fake __orig_bases__ attribute (this one might have unknown consequences):

class SomeProtocol(Protocol):

    __orig_bases__: ClassVar[tuple] = ()

    ...


@define()
class Entity(SomeProtocol):
    ...

@Tinche Tinche self-assigned this Oct 22, 2023
@Tinche
Copy link
Member

Tinche commented Oct 22, 2023

Alright, starting on this before wrapping up the next release.

I think the problem is Protocol is a subclass of Generic, even though it's not necessarily generic. Should be an easy fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants