Skip to content

Commit 8237079

Browse files
authored
docs: general docs update, use mkdocs-api-autonav (#367)
* docs: updating docs * docs: remove containers guide and update references * display * add links * no cover
1 parent d5fd5db commit 8237079

19 files changed

+324
-279
lines changed

docs/API/containers.md

Lines changed: 0 additions & 34 deletions
This file was deleted.

docs/API/evented.md

Lines changed: 0 additions & 8 deletions
This file was deleted.

docs/API/index.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

docs/API/model.md

Lines changed: 0 additions & 12 deletions
This file was deleted.

docs/API/proxy.md

Lines changed: 0 additions & 17 deletions
This file was deleted.

docs/API/utilities.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

docs/dataclasses.md renamed to docs/guides/dataclasses.md

Lines changed: 103 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -116,131 +116,138 @@ with the new value as the first argument.
116116

117117
There are two (related) APIs for adding events to dataclasses:
118118

119-
1. Add a [`SignalGroupDescriptor`][psygnal.SignalGroupDescriptor] as a class attribute.
119+
### 1. Use `SignalGroupDescriptor`
120120

121-
!!! example
121+
[`SignalGroupDescriptor`][psygnal.SignalGroupDescriptor] is designed to be used
122+
as a class attribute on a dataclass-like object, and, when accessed on an
123+
instance of that class, will return a [`SignalGroup`][psygnal.SignalGroup] with
124+
signals for each field in the class.
122125

123-
=== "dataclasses"
126+
!!! example
124127

125-
```python
126-
from typing import ClassVar
127-
from psygnal import SignalGroupDescriptor
128-
from dataclasses import dataclass
128+
=== "dataclasses"
129129

130-
@dataclass
131-
class Person:
132-
name: str
133-
age: int = 0
134-
events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
135-
```
130+
```python
131+
from typing import ClassVar
132+
from psygnal import SignalGroupDescriptor
133+
from dataclasses import dataclass
136134

137-
=== "pydantic"
135+
@dataclass
136+
class Person:
137+
name: str
138+
age: int = 0
139+
events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
140+
```
138141

139-
```python
140-
from typing import ClassVar
141-
from psygnal import SignalGroupDescriptor
142-
from pydantic import BaseModel
142+
=== "pydantic"
143143

144-
class Person(BaseModel):
145-
name: str
146-
age: int = 0
147-
events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
148-
```
144+
```python
145+
from typing import ClassVar
146+
from psygnal import SignalGroupDescriptor
147+
from pydantic import BaseModel
149148

150-
*for a fully evented subclass of pydantic's `BaseModel`, see also
151-
[`EventedModel`](./API/model.md)*
149+
class Person(BaseModel):
150+
name: str
151+
age: int = 0
152+
events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
153+
```
152154

153-
=== "msgspec"
155+
*for a fully evented subclass of pydantic's `BaseModel`, see also
156+
[`EventedModel`](./model.md)*
154157

155-
```python
156-
from typing import ClassVar
157-
from psygnal import SignalGroupDescriptor
158-
import msgspec
158+
=== "msgspec"
159159

160-
class Person(msgspec.Struct):
161-
name: str
162-
age: int = 0
163-
events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
164-
```
160+
```python
161+
from typing import ClassVar
162+
from psygnal import SignalGroupDescriptor
163+
import msgspec
165164

166-
=== "attrs"
165+
class Person(msgspec.Struct):
166+
name: str
167+
age: int = 0
168+
events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
169+
```
167170

168-
```python
169-
from typing import ClassVar
170-
from psygnal import SignalGroupDescriptor
171-
from attrs import define
171+
=== "attrs"
172172

173-
@define
174-
class Person:
175-
name: str
176-
age: int = 0
177-
events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
178-
```
173+
```python
174+
from typing import ClassVar
175+
from psygnal import SignalGroupDescriptor
176+
from attrs import define
179177

180-
2. Decorate the class with the [`@evented` decorator][psygnal.evented].
178+
@define
179+
class Person:
180+
name: str
181+
age: int = 0
182+
events: ClassVar[SignalGroupDescriptor] = SignalGroupDescriptor()
183+
```
181184

182-
> _Under the hood, this just adds the `SignalGroupDescriptor` as a class
183-
> attribute named "events" for you, as shown above). Prefer the class
184-
> attribute pattern to the decorator when in doubt._
185+
### 2. Use the `@evented` decorator
185186

186-
!!! example
187+
The [`@evented`][psygnal.evented] decorator can be added to any dataclass-like
188+
class. Under the hood, this just adds the `SignalGroupDescriptor` as a class
189+
attribute for you (named "events" by default), as shown above. Prefer the class
190+
attribute pattern to the decorator when in doubt, as it is more explicit and
191+
leads to better type checking.
187192

188-
=== "dataclasses"
193+
!!! example
189194

190-
```python
191-
from psygnal import evented
192-
from dataclasses import dataclass
195+
=== "dataclasses"
193196

194-
@evented
195-
@dataclass
196-
class Person:
197-
name: str
198-
age: int = 0
199-
```
197+
```python
198+
from psygnal import evented
199+
from dataclasses import dataclass
200200

201-
=== "pydantic"
201+
@evented
202+
@dataclass
203+
class Person:
204+
name: str
205+
age: int = 0
206+
```
202207

203-
```python
204-
from psygnal import evented
205-
from pydantic import BaseModel
208+
=== "pydantic"
206209

207-
@evented
208-
class Person(BaseModel):
209-
name: str
210-
age: int = 0
211-
```
210+
```python
211+
from psygnal import evented
212+
from pydantic import BaseModel
212213

213-
*for a fully evented subclass of pydantic's `BaseModel`, see also
214-
[`EventedModel`](./API/model.md)*
214+
@evented
215+
class Person(BaseModel):
216+
name: str
217+
age: int = 0
218+
```
215219

216-
=== "msgspec"
220+
*for a fully evented subclass of pydantic's `BaseModel`, see also
221+
[`EventedModel`](./model.md)*
217222

218-
```python
219-
from psygnal import evented
220-
import msgspec
223+
=== "msgspec"
221224

222-
@evented
223-
class Person(msgspec.Struct):
224-
name: str
225-
age: int = 0
226-
```
225+
```python
226+
from psygnal import evented
227+
import msgspec
228+
229+
@evented
230+
class Person(msgspec.Struct):
231+
name: str
232+
age: int = 0
233+
```
227234

228-
=== "attrs"
235+
=== "attrs"
236+
237+
```python
238+
from psygnal import evented
239+
from attrs import define
229240

230-
```python
231-
from psygnal import evented
232-
from attrs import define
241+
@evented
242+
@define
243+
class Person:
244+
name: str
245+
age: int = 0
246+
```
233247

234-
@evented
235-
@define
236-
class Person:
237-
name: str
238-
age: int = 0
239-
```
240-
241-
!!! tip
242-
by default, the `SignalGroup` instance is named `'events'`, but this can be
243-
changed by passing a `events_namespace` argument to the `@evented` decorator)
248+
!!! tip
249+
by default, the `SignalGroup` instance is named `'events'`, but this can be
250+
changed by passing a `events_namespace` argument to the `@evented` decorator)
244251

245252
Using any of the above, you can now connect callbacks to the change events
246253
of any field on the object (there will be a signal instance in the `events`
@@ -270,7 +277,7 @@ def on_any_change(info: EmissionInfo):
270277
print(f"field {info.signal.name!r} changed to {info.args}")
271278
```
272279

273-
see the [API documentation](./API/evented.md) for for more details.
280+
see the [API documentation](reference/psygnal/) for for more details.
274281

275282
## Type annotating evented dataclasses
276283

docs/debugging.md renamed to docs/guides/debugging.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ obj.sig.emit(0)
3737
Here's an example of a standard Python (3.11) stack trace that you
3838
might see when running this code:
3939

40-
[![standard stack trace](img/stdlib.png)](img/stdlib.png)
40+
[![standard stack trace](../img/stdlib.png)](../img/stdlib.png)
4141

4242
All the information is there, but you need to ignore all the
4343
lines that come from psygnal, and focus on the lines that come from your
@@ -62,4 +62,4 @@ attention to the two places in the code that you can do something about:
6262
1. The line in the callback that caused the error: `print(1 / x)`
6363
2. The emission of the event that triggered the callback: `obj.sig.emit(0)`
6464

65-
[![rich stack trace](img/rich.png)](img/rich.png)
65+
[![rich stack trace](../img/rich.png)](../img/rich.png)

docs/guides/model.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Evented Model
2+
3+
This class provides an "evented" version of pydantic's
4+
[`BaseModel`](https://pydantic-docs.helpmanual.io/usage/models/), that emits a
5+
signal whenever a field value is changed
6+
7+
This is an alternative to using the lighter-weight [`@evented` dataclass
8+
decorator](./dataclasses.md). In addition to simply gaining events on all
9+
fields, the [`EventedModel`][psygnal.EventedModel] provides additional features including
10+
`property.setters`, and json encoding features.
11+
12+
```python
13+
from psygnal import EventedModel
14+
15+
class MyModel(EventedModel):
16+
x: int = 1
17+
y: int = 2
18+
19+
# Create an instance of the model
20+
model = MyModel()
21+
22+
# Connect to the `x` field's event
23+
model.events.x.connect(lambda value: print(f"x changed to {value}"))
24+
25+
# Update the `x` field
26+
model.x = 42 # Prints: "x changed to 42"
27+
```
28+
29+
In this example:
30+
31+
- The `EventedModel` automatically creates events for each field.
32+
- You can connect callbacks to these events to respond to changes in field
33+
values.
34+
35+
See documentation for the [`EventedModel`][psygnal.EventedModel] class for
36+
more.

0 commit comments

Comments
 (0)