strawberry-graphql / strawberry

A GraphQL library for Python that leverages type annotations 🍓
https://strawberry.rocks
MIT License
4.01k stars 531 forks source link

Add support for `__slots__` in python 3.10 #1893

Open patrick91 opened 2 years ago

patrick91 commented 2 years ago

In python 3.10 you can use slots=True when applying the dataclasses decorator

see https://docs.python.org/3.10/whatsnew/3.10.html#slots

from dataclasses import dataclass

@dataclass(slots=True)
class Birthday:
    name: str
    birthday: datetime.date

we should think about whether we expose this to end users, like so:

import strawberry

@strawberry.type(slots=True)
class Birthday:
    name: str
    birthday: datetime.date

or if we enable it automatically (but we should still allow to disable it if that's the case)

Upvote & Fund

Fund with Polar

nrbnlulu commented 2 years ago

hey @patrick91 I was trying my luck with adding __slots__ to strawberry.type and I have a question. Does strawberry requires all of the queries / mutations / subscription to be under one huge child that is inheriting from all other? or they are composed and does not require inheritance. If the first is the case I'm afraid it would be impossible unless you have all unique field names and do some hacks, see this SO for more detail

patrick91 commented 2 years ago

@nrbnlulu we could still allow to users to enable slots manually maybe :)

field names have to be unique, so maybe we are fine? also maybe we could find a way to prevent slots from being applied to root level types (maybe types that extend other types?)

nrbnlulu commented 2 years ago

we could still allow to users to enable slots manually maybe :)

Sure, that is not the problem though hehe... but if you mentioned this, I thought to do somthing like this:

def _gte_310() -> bool:
    return sys.version_info >= (3, 10)

# inside strawberry.type we expose the slots argument
def _wrap_dataclass(cls: Type, slots: bool = _gte_310()):
    """Wrap a strawberry.type class with a dataclass and check for any issues
    before doing so"""

    # Ensure all Fields have been properly type-annotated
    _check_field_annotations(cls)

    return dataclasses.dataclass(slots=slots)(cls)

This would prevent to do pytest.mark.parameterize all over the place. What are your thoughts?


field names have to be unique, so maybe we are fine?

Unique where? at all the schema? does fields get renamed implicitly by strawberry?

patrick91 commented 2 years ago

we could still allow to users to enable slots manually maybe :)

Sure, that is not the problem though hehe... but if you mentioned this, I thought to do somthing like this:

def _gte_310() -> bool:
    return sys.version_info >= (3, 10)

# inside strawberry.type we expose the slots argument
def _wrap_dataclass(cls: Type, slots: bool = _gte_310()):
    """Wrap a strawberry.type class with a dataclass and check for any issues
    before doing so"""

    # Ensure all Fields have been properly type-annotated
    _check_field_annotations(cls)

    return dataclasses.dataclass(slots=slots)(cls)

This would prevent to do pytest.mark.parameterize all over the place. What are your thoughts?

I think we can backport this feature to older versions of python :)

field names have to be unique, so maybe we are fine?

Unique where? at all the schema? does fields get renamed implicitly by strawberry?

Unique per type :) we don't do any renaming when extending, I can't remember if we error out, if that's not the case we should :)

nrbnlulu commented 2 years ago

lets continue the discussion on the PR