Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.

Commit b4861c4

Browse files
committed
Update rest of the docs and fix mypy
1 parent 3856856 commit b4861c4

9 files changed

Lines changed: 99 additions & 121 deletions

File tree

docs/fields.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,4 @@ owner = typesystem.Reference(to="User", allow_null=True, definitions=definitions
214214
**Arguments**:
215215

216216
* `to` - Name of schema defined in definitions. **Required**
217+
* `definitions` - `Definitions` instance. **Required**

docs/forms.md

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,21 @@ import typesystem
88

99
forms = typesystem.Jinja2Forms(package="typesystem") # Use the default templates.
1010

11-
class BookingSchema(typesystem.Schema):
12-
start_date = typesystem.Date(title="Start date")
13-
end_date = typesystem.Date(title="End date")
14-
room = typesystem.Choice(title="Room type", choices=[
15-
('double', 'Double room'),
16-
('twin', 'Twin room'),
17-
('single', 'Single room')
18-
])
19-
include_breakfast = typesystem.Boolean(title="Include breakfast", default=False)
20-
21-
form = forms.Form(BookingSchema)
11+
booking_schema = typesystem.Schema(
12+
fields={
13+
"start_date": typesystem.Date(title="Start date"),
14+
"end_date": typesystem.Date(title="End date"),
15+
"room": typesystem.Choice(title="Room type", choices=[
16+
('double', 'Double room'),
17+
('twin', 'Twin room'),
18+
('single', 'Single room')
19+
]),
20+
"include_breakfast": typesystem.Boolean(title="Include breakfast", default=False),
21+
22+
}
23+
)
24+
25+
form = forms.create_form(booking_schema)
2226
print(form)
2327
```
2428

@@ -34,39 +38,39 @@ Notice that only the fields in the form are rendered. The surrounding `<form>`,
3438
```html
3539
<tr>
3640
<td>
37-
<label for="form-bookingschema-start-date">Start date</label>
41+
<label for="">Start date</label>
3842
</td>
3943
<td>
40-
<input type="date" id="form-bookingschema-start-date" name="start_date" required>
44+
<input type="date" id="" name="start_date" required >
4145
</td>
4246
</tr>
4347
<tr>
4448
<td>
45-
<label for="form-bookingschema-end-date">End date</label>
49+
<label for="">End date</label>
4650
</td>
4751
<td>
48-
<input type="date" id="form-bookingschema-end-date" name="end_date" required>
52+
<input type="date" id="" name="end_date" required >
4953
</td>
5054
</tr>
5155
<tr>
5256
<td>
53-
<label for="form-bookingschema-room">Room type</label>
57+
<label for="">Room type</label>
5458
</td>
5559
<td>
56-
<select id="form-bookingschema-room" name="room">
60+
<select id="" name="room">
5761
<option></option>
58-
<option value="double">Double room</option>
59-
<option value="twin">Twin room</option>
60-
<option value="single">Single room</option>
62+
<option value="double" >Double room</option>
63+
<option value="twin" >Twin room</option>
64+
<option value="single" >Single room</option>
6165
</select>
6266
</td>
6367
</tr>
6468
<tr>
6569
<td>
66-
<label for="form-bookingschema-include-breakfast">Include breakfast</label>
70+
<label for="">Include breakfast</label>
6771
</td>
6872
<td>
69-
<input type="checkbox" id="form-bookingschema-include-breakfast" name="include_breakfast" value="true">
73+
<input type="checkbox" id="" name="include_breakfast" value="true" >
7074
</td>
7175
</tr>
7276
```
@@ -92,15 +96,7 @@ We can include values in a form like so:
9296

9397
```python
9498
initial_values = {'room': 'double', 'include_breakfast': True}
95-
form = forms.Form(BookingSchema, values=initial_values)
96-
```
97-
98-
We can also include validation errors:
99-
100-
```python
101-
booking, errors = BookingSchema.validate_or_error(data)
102-
if errors:
103-
form = forms.Form(BookingSchema, values=data, errors=errors)
99+
form = forms.create_form(booking_schema, values=initial_values)
104100
```
105101

106102
## Customizing field rendering

docs/json_schema.md

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
TypeSystem can convert Schema classes or Field instances to/from JSON Schema.
1+
TypeSystem can convert Schema or Field instances to/from JSON Schema.
22

33
!!! note
44
TypeSystem only supports `$ref` pointers that use the standard "definitions"
@@ -15,20 +15,21 @@ Let's define a schema, and dump it out into a JSON schema document:
1515
import json
1616
import typesystem
1717

18-
class BookingSchema(typesystem.Schema):
19-
start_date = typesystem.Date(title="Start date")
20-
end_date = typesystem.Date(title="End date")
21-
room = typesystem.Choice(
22-
title="Room type",
23-
choices=[
24-
("double", "Double room"),
25-
("twin", "Twin room"),
26-
("single", "Single room"),
27-
],
28-
)
29-
include_breakfast = typesystem.Boolean(title="Include breakfast", default=False)
18+
booking_schema = typesystem.Schema(
19+
fields={
20+
"start_date": typesystem.Date(title="Start date"),
21+
"end_date": typesystem.Date(title="End date"),
22+
"room": typesystem.Choice(title="Room type", choices=[
23+
('double', 'Double room'),
24+
('twin', 'Twin room'),
25+
('single', 'Single room')
26+
]),
27+
"include_breakfast": typesystem.Boolean(title="Include breakfast", default=False),
3028

31-
schema = typesystem.to_json_schema(BookingSchema)
29+
}
30+
)
31+
32+
schema = typesystem.to_json_schema(booking_schema)
3233
print(json.dumps(schema, indent=4))
3334
```
3435

docs/references.md

Lines changed: 36 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,72 +5,50 @@ The simplest way to use a reference, is with a schema class as a the target.
55
```python
66
import typesystem
77

8-
class Artist(typesystem.Schema):
9-
name = typesystem.String(max_length=100)
10-
11-
class Album(typesystem.Schema):
12-
title = typesystem.String(max_length=100)
13-
release_date = typesystem.Date()
14-
artist = typesystem.Reference(to=Artist)
15-
```
16-
17-
Using a schema class directly might not always be possible. If you need to
18-
to support back-references or cyclical references, you can use a string-literal
19-
reference and provide a `SchemaDefinitions` instance, which is a dictionary-like
20-
object providing an index of reference lookups.
21-
22-
```python
23-
import typesystem
24-
25-
definitions = typesystem.SchemaDefinitions()
26-
27-
class Artist(typesystem.Schema):
28-
name = typesystem.String(max_length=100)
29-
30-
class Person(typesystem.Schema):
31-
name = typesystem.String(max_length=100)
32-
release_date = typesystem.Date()
33-
artist = typesystem.Reference(to='Artist', definitions=definitions)
34-
35-
definitions['Artist'] = Artist
36-
definitions['Person'] = Person
8+
artist_schema = typesystem.Schema(
9+
fields={
10+
"name": typesystem.String(max_length=100)
11+
}
12+
)
13+
14+
definitions = typesystem.Definitions()
15+
definitions["Artist"] = artist_schema
16+
17+
album_schema = typesystem.Schema(
18+
fields={
19+
"title": typesystem.String(max_length=100),
20+
"release_date": typesystem.Date(),
21+
"artist": typesystem.Reference(to="Artist", definitions=definitions),
22+
}
23+
)
3724
```
3825

39-
A shorthand for including a schema class in the definitions index, and for
40-
setting the `definitions` on any Reference fields, is to declare schema
41-
classes with the `definitions` keyword argument, like so:
42-
43-
```python
44-
import typesystem
45-
46-
definitions = typesystem.SchemaDefinitions()
47-
48-
class Artist(typesystem.Schema, definitions=definitions):
49-
name = typesystem.String(max_length=100)
50-
51-
class Person(typesystem.Schema, definitions=definitions):
52-
name = typesystem.String(max_length=100)
53-
release_date = typesystem.Date()
54-
artist = typesystem.Reference(to='Artist')
55-
```
56-
57-
Registering schema classes against a `SchemaDefinitions` instance is particularly
26+
Registering schema instances against a `Definitions` instance is particularly
5827
useful if you're using JSON schema to document the input and output types of
5928
a Web API, since you can easily dump all the type definitions:
6029

6130
```python
6231
import json
6332
import typesystem
6433

65-
definitions = typesystem.SchemaDefinitions()
34+
definitions = typesystem.Definitions()
6635

67-
class Artist(typesystem.Schema, definitions=definitions):
68-
name = typesystem.String(max_length=100)
36+
artist_schema = typesystem.Schema(
37+
fields={
38+
"name": typesystem.String(max_length=100)
39+
}
40+
)
6941

70-
class Person(typesystem.Schema, definitions=definitions):
71-
name = typesystem.String(max_length=100)
72-
release_date = typesystem.Date()
73-
artist = typesystem.Reference(to='Artist')
42+
album_schema = typesystem.Schema(
43+
fields={
44+
"title": typesystem.String(max_length=100),
45+
"release_date": typesystem.Date(),
46+
"artist": typesystem.Reference(to="Artist", definitions=definitions),
47+
}
48+
)
49+
50+
definitions["Artist"] = artist_schema
51+
definitions["Album"] = album_schema
7452

7553
document = typesystem.to_json_schema(definitions)
7654
print(json.dumps(document, indent=4))
@@ -89,10 +67,10 @@ print(json.dumps(document, indent=4))
8967
# "name"
9068
# ]
9169
# },
92-
# "Person": {
70+
# "Album": {
9371
# "type": "object",
9472
# "properties": {
95-
# "name": {
73+
# "title": {
9674
# "type": "string",
9775
# "minLength": 1,
9876
# "maxLength": 100
@@ -107,7 +85,7 @@ print(json.dumps(document, indent=4))
10785
# }
10886
# },
10987
# "required": [
110-
# "name",
88+
# "title",
11189
# "release_date",
11290
# "artist"
11391
# ]

docs/tokenized_errors.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@ indicators showing exactly where the error occurred in the raw textual content.
44
```python
55
import typesystem
66

7-
class Config(typesystem.Schema):
8-
num_worker_processes = typesystem.Integer()
9-
enable_auto_reload = typesystem.Boolean()
7+
8+
config_schema = typesystem.Schema(
9+
fields={
10+
"num_worker_processes": typesystem.Integer(),
11+
"enable_auto_reload": typesystem.Boolean(),
12+
}
13+
)
1014

1115
text = '''{
1216
"num_worker_processes": "x",
1317
"enable_auto_reload": "true"
1418
}'''
1519

1620
try:
17-
typesystem.validate_json(text, validator=Config)
21+
typesystem.validate_json(text, validator=config_schema)
1822
except (typesystem.ValidationError, typesystem.ParseError) as exc:
1923
for message in exc.messages():
2024
line_no = message.start_position.line_no
@@ -28,4 +32,4 @@ The two functions for parsing content and providing positional error messages ar
2832
* `validate_json(text_or_bytes, validator)`
2933
* `validate_yaml(text_or_bytes, validator)`
3034

31-
In both cases `validator` may either be a `Schema` class, or a `Field` instance.
35+
In both cases `validator` may either be a `Schema` or a `Field` instance.

scripts/check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ export SOURCE_FILES="typesystem tests"
1313
${PREFIX}isort --check --diff --project=typesystem $SOURCE_FILES
1414
${PREFIX}black --check --diff $SOURCE_FILES
1515
${PREFIX}flake8 $SOURCE_FILES
16-
${PREFIX}mypy
16+
${PREFIX}mypy typesystem

setup.cfg

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ max-line-length = 88
55
[mypy]
66
disallow_untyped_defs = True
77
ignore_missing_imports = True
8-
files =
9-
typesystem/*.py,
10-
typesystem/tokenize/positional_validation.py,
11-
typesystem/tokenize/tokenize_json.py,
12-
typesystem/tokenize/tokens.py
138

149
[tool:isort]
1510
profile = black

typesystem/forms.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,11 @@ def __init__(
3535
*,
3636
env: "jinja2.Environment",
3737
schema: Schema,
38-
instance: typing.Any = None,
38+
values: typing.Dict[str, typing.Any] = None,
3939
) -> None:
4040
self.env = env
4141
self.schema = schema
42-
self.instance = instance
43-
self.values = None if instance is None else self.schema.serialize(instance)
42+
self.values = self.schema.serialize(values)
4443
self.errors: typing.Optional[typing.Dict[str, typing.Any]] = None
4544
self._validate_called = False
4645

@@ -156,5 +155,7 @@ def load_template_env(
156155
)
157156
return jinja2.Environment(loader=loader, autoescape=True)
158157

159-
def create_form(self, schema: Schema, instance: typing.Any = None) -> Form:
160-
return Form(env=self.env, schema=schema, instance=instance)
158+
def create_form(
159+
self, schema: Schema, values: typing.Dict[str, typing.Any] = None
160+
) -> Form:
161+
return Form(env=self.env, schema=schema, values=values)

typesystem/tokenize/tokenize_yaml.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def construct_sequence(loader: "yaml.Loader", node: "yaml.Node") -> ListToken:
5353
def construct_scalar(loader: "yaml.Loader", node: "yaml.Node") -> ScalarToken:
5454
start = node.start_mark.index
5555
end = node.end_mark.index
56-
value = loader.construct_scalar(node)
56+
value = loader.construct_scalar(node) # type: ignore
5757
return ScalarToken(value, start, end - 1, content=str_content)
5858

5959
def construct_int(loader: "yaml.Loader", node: "yaml.Node") -> ScalarToken:
@@ -104,14 +104,16 @@ def construct_null(loader: "yaml.Loader", node: "yaml.Node") -> ScalarToken:
104104
return yaml.load(str_content, CustomSafeLoader)
105105
except (yaml.scanner.ScannerError, yaml.parser.ParserError) as exc: # type: ignore
106106
# Handle cases that result in a YAML parse error.
107+
assert exc.problem is not None
108+
assert exc.problem_mark is not None
107109
text = exc.problem + "."
108110
position = _get_position(str_content, index=exc.problem_mark.index)
109111
raise ParseError(text=text, code="parse_error", position=position)
110112

111113

112114
def validate_yaml(
113115
content: typing.Union[str, bytes],
114-
validator: typing.Union[Field, typing.Type[Schema]],
116+
validator: typing.Union[Field, Schema],
115117
) -> typing.Any:
116118
"""
117119
Parse and validate a YAML string, returning positionally marked error

0 commit comments

Comments
 (0)