Skip to content

Commit e4cf88d

Browse files
committed
Provide specified_directives as ReadOnlyList (#31)
1 parent 27f8152 commit e4cf88d

File tree

7 files changed

+142
-8
lines changed

7 files changed

+142
-8
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ a query language for APIs created by Facebook.
1313
[![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
1414

1515
The current version 1.0.3 of GraphQL-core-next is up-to-date with GraphQL.js version
16-
14.2.1. All parts of the API are covered by an extensive test suite of currently 1753
16+
14.2.1. All parts of the API are covered by an extensive test suite of currently 1758
1717
unit tests.
1818

1919

graphql/pyutils/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from .or_list import or_list
2222
from .quoted_or_list import quoted_or_list
2323
from .suggestion_list import suggestion_list
24+
from .read_only_list import ReadOnlyError, ReadOnlyList
2425

2526
__all__ = [
2627
"camel_to_snake",
@@ -38,4 +39,6 @@
3839
"or_list",
3940
"quoted_or_list",
4041
"suggestion_list",
42+
"ReadOnlyError",
43+
"ReadOnlyList",
4144
]

graphql/pyutils/read_only_list.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
__all__ = ["ReadOnlyError", "ReadOnlyList"]
2+
3+
4+
class ReadOnlyError(TypeError):
5+
"""Error when trying to write to a ReadOnlyList."""
6+
7+
8+
class ReadOnlyList(list):
9+
"""List that can only be read, but not changed."""
10+
11+
def __delitem__(self, key):
12+
raise ReadOnlyError
13+
14+
def __setitem__(self, key, value):
15+
raise ReadOnlyError
16+
17+
def __add__(self, value):
18+
if isinstance(value, tuple):
19+
value = list(value)
20+
return list.__add__(self, value)
21+
22+
def __iadd__(self, value):
23+
raise ReadOnlyError
24+
25+
def __mul__(self, value):
26+
return list.__mul__(self, value)
27+
28+
def __imul__(self, value):
29+
raise ReadOnlyError
30+
31+
def append(self, x):
32+
raise ReadOnlyError
33+
34+
def extend(self, iterable):
35+
raise ReadOnlyError
36+
37+
def insert(self, i, x):
38+
raise ReadOnlyError
39+
40+
def remove(self, x):
41+
raise ReadOnlyError
42+
43+
def pop(self, i=None):
44+
raise ReadOnlyError
45+
46+
def clear(self):
47+
raise ReadOnlyError
48+
49+
def sort(self, *, key=None, reverse=False):
50+
raise ReadOnlyError
51+
52+
def reverse(self):
53+
raise ReadOnlyError

graphql/type/directives.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Any, Dict, Sequence, cast
22

33
from ..language import ast, DirectiveLocation
4-
from ..pyutils import inspect
4+
from ..pyutils import inspect, ReadOnlyList
55
from .definition import GraphQLArgument, GraphQLInputType, GraphQLNonNull, is_input_type
66
from .scalars import GraphQLBoolean, GraphQLString
77

@@ -166,10 +166,8 @@ def assert_directive(directive: Any) -> GraphQLDirective:
166166

167167

168168
# The full list of specified directives.
169-
specified_directives = (
170-
GraphQLIncludeDirective,
171-
GraphQLSkipDirective,
172-
GraphQLDeprecatedDirective,
169+
specified_directives = ReadOnlyList(
170+
[GraphQLIncludeDirective, GraphQLSkipDirective, GraphQLDeprecatedDirective]
173171
)
174172

175173

graphql/type/schema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class GraphQLSchema:
7272
7373
MyAppSchema = GraphQLSchema(
7474
...
75-
directives=specifiedDirectives + [myCustomDirective])
75+
directives=specified_directives + [my_custom_directive])
7676
"""
7777

7878
query_type: Optional[GraphQLObjectType]

tests/pyutils/test_read_only_list.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
from pytest import raises
2+
3+
from graphql.pyutils import ReadOnlyError, ReadOnlyList
4+
5+
6+
def describe_read_only_list():
7+
def can_read():
8+
rol = ReadOnlyList([1, 2, 3])
9+
assert rol == [1, 2, 3]
10+
assert list(i for i in rol) == rol
11+
assert rol.copy() == rol
12+
assert 2 in rol
13+
assert 4 not in rol
14+
assert rol + [4, 5] == [1, 2, 3, 4, 5]
15+
assert [4, 5] + rol == [4, 5, 1, 2, 3]
16+
assert rol * 2 == [1, 2, 3, 1, 2, 3]
17+
assert 2 * rol == [1, 2, 3, 1, 2, 3]
18+
assert rol[1] == 2
19+
with raises(IndexError):
20+
rol[3]
21+
assert rol[1:4] == [2, 3]
22+
assert rol[::2] == [1, 3]
23+
assert len(rol) == 3
24+
assert min(rol) == 1
25+
assert max(rol) == 3
26+
assert sum(rol) == 6
27+
assert rol.index(2) == 1
28+
with raises(ValueError):
29+
rol.index(4)
30+
assert rol.count(2) == 1
31+
assert rol.count(4) == 0
32+
assert list(reversed(rol)) == [3, 2, 1]
33+
assert sorted(rol) == [1, 2, 3]
34+
35+
def cannot_write():
36+
rol = ReadOnlyList([1, 2, 3])
37+
with raises(ReadOnlyError):
38+
rol[1] = 4
39+
with raises(ReadOnlyError):
40+
rol[1:4] = [4]
41+
with raises(ReadOnlyError):
42+
del rol[1]
43+
with raises(ReadOnlyError):
44+
del rol[1:4]
45+
with raises(ReadOnlyError):
46+
rol[1::2] = [4]
47+
with raises(ReadOnlyError):
48+
del rol[::2]
49+
with raises(ReadOnlyError):
50+
rol.append(4)
51+
with raises(ReadOnlyError):
52+
rol.clear()
53+
with raises(ReadOnlyError):
54+
rol.extend([4])
55+
with raises(ReadOnlyError):
56+
rol += [4]
57+
with raises(ReadOnlyError):
58+
rol *= 2
59+
with raises(ReadOnlyError):
60+
rol.insert(1, 4)
61+
with raises(ReadOnlyError):
62+
rol.pop()
63+
with raises(ReadOnlyError):
64+
rol.remove(2)
65+
with raises(ReadOnlyError):
66+
rol.sort()
67+
with raises(ReadOnlyError):
68+
rol.reverse()
69+
70+
def can_add_rol():
71+
rol1 = ReadOnlyList([1, 2])
72+
rol2 = ReadOnlyList([3, 4])
73+
assert rol1 + rol2 == [1, 2, 3, 4]
74+
75+
def can_add_tuple():
76+
rol = ReadOnlyList([1, 2])
77+
assert rol + (3, 4) == [1, 2, 3, 4]
78+
79+
def read_only_error_is_type_error():
80+
assert issubclass(ReadOnlyError, TypeError)

tests/utilities/test_extend_schema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
},
118118
),
119119
types=[FooType, BarType],
120-
directives=specified_directives + (FooDirective,),
120+
directives=specified_directives + [FooDirective],
121121
)
122122

123123

0 commit comments

Comments
 (0)