strawberry-graphql / strawberry

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

Better pyright support for pydantic conversion #1834

Open thejaminator opened 2 years ago

thejaminator commented 2 years ago

Makes sense, do you think we can also add this? https://github.com/strawberry-graphql/strawberry/blob/main/strawberry/object_type.py#L152-L153 this should make it work slightly better with pyright

does that work out of the box for the pydantic conversion? not familar with how that works but i think the init for the dataclass wouldn't work well because not all the fields are in the class getting decorated.

e.g.

class UserCreate(BaseModel):
    email: str

@strawberry.experimental.pydantic.input(model=UserCreate, all_fields=True)
class UserCreateInput:
    pass # the fields aren't here

if it doesn't and gives false positives i'll settle it in another issue

it only works with fields that are defined, so yeah, let's do it in another issue :)

Originally posted by @patrick91 in https://github.com/strawberry-graphql/strawberry/issues/1832#issuecomment-1105318146

Upvote & Fund

Fund with Polar

bugzpodder commented 2 years ago

I have a similar issue:

@strawberry.experimental.pydantic.type(
    model= UserCreate, all_fields=True
)
class UserCreateType:
    @strawberry.field
    async def domain(self) -> str:
        return self.email.split('@')[1]

This gives the mypy error: "UserCreateType" has no attribute "email"

thejaminator commented 2 years ago

I have a similar issue:

@strawberry.experimental.pydantic.type(
    model= UserCreate, all_fields=True
)
class UserCreateType:
    @strawberry.field
    async def domain(self) -> str:
        return self.email.split('@')[1]

This gives the mypy error: "UserCreateType" has no attribute "email"

@bugzpodder could i understand abit more of your usecase? could domain be a property on the pydantic type instead? or is that just an example, and domain would actually send a request.

bugzpodder commented 2 years ago

@thejaminator

This is just an example. In my case, I have two microservices A and B. The main object is fetched from microservice A. I've attached a new field to the graphql type (in this case UserCreatedType) that would make a call to microservice B and fetch this piece of additional data if requested. I might have a way around this by putting email: strawberry.auto in UserCreateType I think so it might be ok. I do get a UserWarning: Using all_fields overrides any explicitly defined fields in the model, using both is likely a bug warning though.

mecampbellsoup commented 2 weeks ago

Same issue here.

class CurrentUser(pydantic.BaseModel):
    email: str

@strawberry.experimental.pydantic.type(model=CurrentUserPyd, all_fields=True)
class CurrentUser:
    pass
    assert isinstance(registered_user, CurrentUser)
    result: ExecutionResult = await schema.execute(
        mutation,
        variable_values={"form": {"email": registered_user.email}},
        context_value={"request": request, "response": response, "username": None},
    )

Pyright complains it doesn't know the CurrentUser has an attribute email:


/home/mcampbell/code/coreweave/cloud-console/tests/gql/resolvers/test_password.py
  /home/mcampbell/code/coreweave/cloud-console/tests/gql/resolvers/test_password.py:227:60 - error: Cannot access attribute "email" for class "StrawberryTypeFromPydantic[CurrentUserPyd]"
    Attribute "email" is unknown (reportAttributeAccessIssue)
  /home/mcampbell/code/coreweave/cloud-console/tests/gql/resolvers/test_password.py:236:53 - error: Cannot access attribute "email" for class "StrawberryTypeFromPydantic[CurrentUserPyd]"
    Attribute "email" is unknown (reportAttributeAccessIssue)
2 errors, 0 warnings, 0 informations
patrick91 commented 2 weeks ago

@mecampbellsoup I don't think we can fix this unfortunately :(

This might be fixed/worked-around by supporting this (which we want to do in #2181)

@strawberry.pydantic.type
class CurrentUser(pydantic.BaseModel):
    email: str