Skip to content

Commit 70f9ab2

Browse files
committed
Merge branch 'master' of https://github.com/graphql-python/gql into custom-scalar-types
2 parents 598acd8 + ecb9e9b commit 70f9ab2

File tree

7 files changed

+63
-21
lines changed

7 files changed

+63
-21
lines changed

gql/dsl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def select(self, *fields):
8484
added_selections = selections(*fields)
8585
if selection_set:
8686
selection_set.selections = FrozenList(
87-
selection_set.selections + added_selections
87+
selection_set.selections + list(added_selections)
8888
)
8989
else:
9090
self.ast_field.selection_set = SelectionSetNode(

gql/transport/local_schema.py

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from inspect import isawaitable
2-
from typing import Any, AsyncGenerator, AsyncIterator, Awaitable, Coroutine, cast
2+
from typing import AsyncGenerator, Awaitable, cast
33

44
from graphql import DocumentNode, ExecutionResult, GraphQLSchema, execute, subscribe
55

@@ -50,27 +50,16 @@ async def execute(
5050
async def subscribe(
5151
self, document: DocumentNode, *args, **kwargs,
5252
) -> AsyncGenerator[ExecutionResult, None]:
53-
"""Send a query and receive the results using an async generator
54-
55-
The query can be a graphql query, mutation or subscription
53+
"""Send a subscription and receive the results using an async generator
5654
5755
The results are sent as an ExecutionResult object
5856
"""
5957

60-
subscribe_result = subscribe(self.schema, document, *args, **kwargs)
58+
subscribe_result = await subscribe(self.schema, document, *args, **kwargs)
6159

6260
if isinstance(subscribe_result, ExecutionResult):
63-
yield ExecutionResult
61+
yield subscribe_result
6462

6563
else:
66-
# if we don't get an ExecutionResult, then we should receive
67-
# a Coroutine returning an AsyncIterator[ExecutionResult]
68-
69-
subscribe_coro = cast(
70-
Coroutine[Any, Any, AsyncIterator[ExecutionResult]], subscribe_result
71-
)
72-
73-
subscribe_generator = await subscribe_coro
74-
75-
async for result in subscribe_generator:
64+
async for result in subscribe_result:
7665
yield result

gql/transport/transport.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def execute(self, document: DocumentNode, *args, **kwargs) -> ExecutionResult:
2020
def connect(self):
2121
"""Establish a session with the transport.
2222
"""
23-
pass
23+
pass # pragma: no cover
2424

2525
def close(self):
2626
"""Close the transport

tests/starwars/fixtures.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
from collections import namedtuple
23

34
Human = namedtuple("Human", "id name friends appearsIn homePlanet")
@@ -94,6 +95,11 @@ def getHero(episode):
9495
return artoo
9596

9697

98+
async def getHeroAsync(episode):
99+
await asyncio.sleep(0.001)
100+
return getHero(episode)
101+
102+
97103
def getHuman(id):
98104
return humanData.get(id)
99105

tests/starwars/schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
getCharacters,
2525
getDroid,
2626
getFriends,
27-
getHero,
27+
getHeroAsync,
2828
getHuman,
2929
reviews,
3030
)
@@ -146,7 +146,7 @@
146146
type_=episodeEnum, # type: ignore
147147
)
148148
},
149-
resolve=lambda root, info, **args: getHero(args.get("episode")),
149+
resolve=lambda root, info, **args: getHeroAsync(args.get("episode")),
150150
),
151151
"human": GraphQLField(
152152
humanType,

tests/starwars/test_dsl.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ def test_hero_name_and_friends_query(ds):
5353
assert query == str(query_dsl)
5454

5555

56+
def test_hero_id_and_name(ds):
57+
query = """
58+
hero {
59+
id
60+
name
61+
}
62+
""".strip()
63+
query_dsl = ds.Query.hero.select(ds.Character.id)
64+
query_dsl = query_dsl.select(ds.Character.name)
65+
assert query == str(query_dsl)
66+
67+
5668
def test_nested_query(ds):
5769
query = """
5870
hero {

tests/starwars/test_subscription.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import pytest
2-
from graphql import subscribe
2+
from graphql import ExecutionResult, GraphQLError, subscribe
33

44
from gql import Client, gql
55

@@ -57,3 +57,38 @@ async def test_subscription_support_using_client():
5757
]
5858

5959
assert results == expected
60+
61+
62+
subscription_invalid_str = """
63+
subscription ListenEpisodeReviews($ep: Episode!) {
64+
qsdfqsdfqsdf
65+
}
66+
"""
67+
68+
69+
@pytest.mark.asyncio
70+
async def test_subscription_support_using_client_invalid_field():
71+
72+
subs = gql(subscription_invalid_str)
73+
74+
params = {"ep": "JEDI"}
75+
76+
async with Client(schema=StarWarsSchema) as session:
77+
78+
# We subscribe directly from the transport to avoid local validation
79+
results = [
80+
result
81+
async for result in session.transport.subscribe(
82+
subs, variable_values=params
83+
)
84+
]
85+
86+
assert len(results) == 1
87+
result = results[0]
88+
assert isinstance(result, ExecutionResult)
89+
assert result.data is None
90+
assert isinstance(result.errors, list)
91+
assert len(result.errors) == 1
92+
error = result.errors[0]
93+
assert isinstance(error, GraphQLError)
94+
assert error.message == "The subscription field 'qsdfqsdfqsdf' is not defined."

0 commit comments

Comments
 (0)