diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000000..d2d655506e --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,25 @@ +Release type: minor + +Remove deprecated `info.field_nodes` property, deprecated since [0.73.1](https://github.com/strawberry-graphql/strawberry/releases/tag/0.73.1). + +### Migration guide + +**Before (deprecated):** +```python +@strawberry.type +class Query: + @strawberry.field + def example(self, info: strawberry.Info) -> str: + field_nodes = info.field_nodes + ... +``` + +**After:** +```python +@strawberry.type +class Query: + @strawberry.field + def example(self, info: strawberry.Info) -> str: + selected_fields = info.selected_fields + ... +``` diff --git a/strawberry/types/info.py b/strawberry/types/info.py index d7130f523e..b06fe64995 100644 --- a/strawberry/types/info.py +++ b/strawberry/types/info.py @@ -1,7 +1,6 @@ from __future__ import annotations import dataclasses -import warnings from functools import cached_property from typing import ( TYPE_CHECKING, @@ -14,7 +13,6 @@ if TYPE_CHECKING: from graphql import GraphQLResolveInfo, OperationDefinitionNode - from graphql.language import FieldNode from graphql.pyutils.path import Path from strawberry.schema import Schema @@ -86,16 +84,6 @@ def schema(self) -> Schema: """The schema of the current execution.""" return self._raw_info.schema._strawberry_schema # type: ignore - @property - def field_nodes(self) -> list[FieldNode]: # deprecated - warnings.warn( - "`info.field_nodes` is deprecated, use `selected_fields` instead", - DeprecationWarning, - stacklevel=2, - ) - - return self._raw_info.field_nodes - @cached_property def selected_fields(self) -> list[Selection]: """The fields that were selected on the current field's type.""" diff --git a/tests/schema/test_info.py b/tests/schema/test_info.py index 817ea55772..b4c9c54504 100644 --- a/tests/schema/test_info.py +++ b/tests/schema/test_info.py @@ -1,13 +1,11 @@ import dataclasses import json from typing import Annotated, Optional -from unittest.mock import MagicMock import pytest import strawberry from strawberry.types.base import StrawberryOptional -from strawberry.types.info import Info from strawberry.types.nodes import FragmentSpread, InlineFragment, SelectedField from strawberry.types.unset import UNSET @@ -339,169 +337,6 @@ class Query: assert result.data["field"] == 0 -def test_field_nodes_deprecation(): - def resolver(info: strawberry.Info): - info.field_nodes - return 0 - - @strawberry.type - class Query: - field: int = strawberry.field(resolver=resolver) - - schema = strawberry.Schema(query=Query) - - with pytest.deprecated_call(): - result = schema.execute_sync("{ field }") - - assert not result.errors - assert result.data - assert result.data["field"] == 0 - - -def test_info_query(): - graphql_query = None - - @strawberry.type - class Query: - @strawberry.field - def hello(self, info: strawberry.Info) -> str: - nonlocal graphql_query - graphql_query = info.query - return "world" - - schema = strawberry.Schema(query=Query) - query = "{ hello }" - result = schema.execute_sync(query) - - assert not result.errors - assert graphql_query == query - - -def test_info_query_with_variables(): - graphql_query = None - - @strawberry.type - class Query: - @strawberry.field - def hello(self, info: strawberry.Info, name: str = "world") -> str: - nonlocal graphql_query - graphql_query = info.query - return f"hello {name}" - - schema = strawberry.Schema(query=Query) - query = """query Hello($name: String!) { - hello(name: $name) - }""" - result = schema.execute_sync(query, variable_values={"name": "test"}) - - assert not result.errors - assert graphql_query == query - - -def test_info_query_with_fragments(): - graphql_query = None - - @strawberry.type - class User: - name: str - age: int - - @strawberry.type - class Query: - @strawberry.field - def user(self, info: strawberry.Info) -> User: - nonlocal graphql_query - graphql_query = info.query - return User(name="Alice", age=30) - - schema = strawberry.Schema(query=Query) - query = """query { - user { - ...UserFields - } - } - - fragment UserFields on User { - name - age - }""" - result = schema.execute_sync(query) - - assert not result.errors - assert graphql_query == query - - -def test_info_query_with_mutation(): - graphql_query = None - - @strawberry.type - class Query: - @strawberry.field - def hello(self) -> str: - return "world" - - @strawberry.type - class Mutation: - @strawberry.mutation - def create_user(self, info: strawberry.Info, name: str) -> str: - nonlocal graphql_query - graphql_query = info.query - return name - - schema = strawberry.Schema(query=Query, mutation=Mutation) - query = """mutation CreateUser($name: String!) { - createUser(name: $name) - }""" - result = schema.execute_sync(query, variable_values={"name": "Alice"}) - - assert not result.errors - assert graphql_query == query - - -def test_info_query_with_multiple_operations(): - graphql_query = None - - @strawberry.type - class Query: - @strawberry.field - def hello(self, info: strawberry.Info) -> str: - nonlocal graphql_query - graphql_query = info.query - return "world" - - @strawberry.field - def goodbye(self, info: strawberry.Info) -> str: - nonlocal graphql_query - graphql_query = info.query - return "farewell" - - schema = strawberry.Schema(query=Query) - query = """query FirstOp { - hello - } - - query SecondOp { - goodbye - }""" - result = schema.execute_sync(query, operation_name="SecondOp") - - assert not result.errors - # info.query returns the full document, including all operations - assert graphql_query == query - assert "FirstOp" in graphql_query - assert "SecondOp" in graphql_query - - -def test_info_query_returns_none_without_loc(): - mock_raw_info = MagicMock() - mock_raw_info.operation.loc = None - - mock_field = MagicMock() - - info = Info(_raw_info=mock_raw_info, _field=mock_field) - assert info.query is None - - def test_get_argument_defintion_helper(): @strawberry.input class TestInput: