strawberry-graphql / strawberry

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

print_schema creates multiple directives if a field is used in multiple schemas #3596

Open Speedy1991 opened 2 months ago

Speedy1991 commented 2 months ago
class UnauthorizedException(Exception):
    pass

class FeaturesRequired(BasePermission):
    message = "Keine Rechte"
    error_class = UnauthorizedException
    error_extensions = {"code": 401}

    def __init__(self, *features):
        self.features = features

    async def has_permission(self, source: Any, info: Info, **kwargs) -> bool:
        return 'test' in self.features

@strawberry.type
class MyType:

    @strawberry.field(extensions=[PermissionExtension(permissions=[FeaturesRequired('test')])])
    def hello(self) -> str:
        return 'world'
# schema_1.py

@strawberry.type
class Query1:
  @strawberry.field
  def my_type(self, info: Info) -> MyType:
    return MyType()

schema_1 = Schema(query=Query)
# schema_2.py:

@strawberry.type
class Query2:
  @strawberry.field
  def my_type(self, info: Info) -> MyType:
    return MyType()

schema_2 = Schema(query=Query)

generate the gql file:

from schema_1 import schema_1
from strawberry.printer import print_schema

with open('test.graphql', 'w') as f:
  f.write(print_schema(schema_1))

generates:

hello: String! @featuresRequired @featuresRequired

which leads to errors in vsc like The directive "@featuresRequired" can only be used once at this location. Bug: This code is getting called twice, one time for schema_1 and one time for schema_2

Upvote & Fund

Fund with Polar

Speedy1991 commented 2 months ago

This also happens if you use an interface with an extension on an interface field

image

See this playground example: https://play.strawberry.rocks/?gist=b865d07a2ac9aa6211d4f6bd0d3ec291