Skip to content

Commit 12e07ac

Browse files
committed
Add DSLSchema.__call__ shortcuts for DSLMetafield, DSLInlineFragment, and DSLFragment
1 parent 1247877 commit 12e07ac

File tree

2 files changed

+54
-14
lines changed

2 files changed

+54
-14
lines changed

gql/dsl.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -334,25 +334,38 @@ def __call__(self, shortcut: Any) -> "DSLDirective": ... # pragma: no cover
334334
def __call__(
335335
self, shortcut: str, name: Optional[str] = None
336336
) -> Union["DSLMetaField", "DSLInlineFragment", "DSLFragment", "DSLDirective"]:
337-
"""Factory method for creating DSL objects.
337+
"""Factory method for creating DSL objects from a shortcut string.
338338
339-
Currently, supports creating DSLDirective instances when name starts with '@'.
340-
Future support planned for meta-fields (__typename), inline fragments (...),
341-
and fragment definitions (fragment).
339+
The shortcut determines which DSL object is created:
342340
343-
:param shortcut: the name of the object to create
341+
* "__typename", "__schema", "__type" -> :class:`DSLMetaField`
342+
* "..." -> :class:`DSLInlineFragment`
343+
* "fragment" -> :class:`DSLFragment` (requires ``name`` to be a string)
344+
* "@<name>" -> :class:`DSLDirective`
345+
346+
:param shortcut: The shortcut string identifying the DSL object.
344347
:type shortcut: str
345348
346-
:return: :class:`DSLDirective` instance
349+
:param name: The fragment name, required when ``shortcut == "fragment"``.
350+
:type name: Optional[str]
351+
352+
:return: A DSL object corresponding to the given shortcut.
353+
:rtype: DSLMetaField | DSLInlineFragment | DSLFragment | DSLDirective
347354
348-
:raises ValueError: if shortcut format is not supported
355+
:raises ValueError: If the shortcut is not recognized,
356+
or if ``name`` is missing for a fragment shortcut.
349357
"""
358+
359+
if shortcut in ("__typename", "__schema", "__type"):
360+
return DSLMetaField(name=shortcut)
361+
if shortcut == "...":
362+
return DSLInlineFragment()
363+
if shortcut == "fragment":
364+
if not isinstance(name, str):
365+
raise ValueError(f"Missing name: {name} for fragment shortcut")
366+
return DSLFragment(name=name)
350367
if shortcut.startswith("@"):
351368
return DSLDirective(name=shortcut[1:], dsl_schema=self)
352-
# Future support:
353-
# if name.startswith("__"): return DSLMetaField(name)
354-
# if name == "...": return DSLInlineFragment()
355-
# if name.startswith("fragment "): return DSLFragment(name[9:])
356369

357370
raise ValueError(f"Unsupported shortcut: {shortcut}")
358371

tests/starwars/test_dsl.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from gql import Client, gql
2525
from gql.dsl import (
26+
DSLDirective,
2627
DSLField,
2728
DSLFragment,
2829
DSLFragmentSpread,
@@ -1297,9 +1298,35 @@ def test_legacy_fragment_with_variables(ds):
12971298
assert print_ast(query.document) == expected
12981299

12991300

1300-
def test_dsl_schema_call_validation(ds):
1301-
with pytest.raises(ValueError, match="(?i)unsupported shortcut"):
1302-
ds("foo")
1301+
@pytest.mark.parametrize(
1302+
"shortcut,expected",
1303+
[
1304+
("__typename", DSLMetaField("__typename")),
1305+
("__schema", DSLMetaField("__schema")),
1306+
("__type", DSLMetaField("__type")),
1307+
("...", DSLInlineFragment()),
1308+
("@skip", DSLDirective(name="skip", dsl_schema=DSLSchema(StarWarsSchema))),
1309+
],
1310+
)
1311+
def test_dsl_schema_call_shortcuts(ds, shortcut, expected):
1312+
actual = ds(shortcut)
1313+
assert getattr(actual, "name", None) == getattr(expected, "name", None)
1314+
assert isinstance(actual, type(expected))
1315+
1316+
1317+
def test_dsl_schema_call_fragment(ds):
1318+
fragment = ds("fragment", "foo")
1319+
assert fragment.name == "foo"
1320+
assert isinstance(fragment, DSLFragment)
1321+
1322+
1323+
@pytest.mark.parametrize(
1324+
"shortcut,match",
1325+
[("foo", "(?i)unsupported shortcut"), ("fragment", "(?i)missing name")],
1326+
)
1327+
def test_dsl_schema_call_validation(ds, shortcut, match):
1328+
with pytest.raises(ValueError, match=match):
1329+
ds(shortcut)
13031330

13041331

13051332
def test_executable_directives(ds, var):

0 commit comments

Comments
 (0)