Skip to content

Commit d5282e0

Browse files
committed
chore: prepare release 3.2.2
Signed-off-by: Fernando Macedo <fgmacedo@gmail.com>
1 parent f77d6e0 commit d5282e0

9 files changed

Lines changed: 272 additions & 75 deletions

File tree

‎docs/contributing.md‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,12 @@ Update the version string in **both** files:
192192
- `pyproject.toml` — the `version` field under `[project]`
193193
- `statemachine/__init__.py` — the `__version__` variable
194194

195+
Then refresh the lock file, which records the project's own version:
196+
197+
```shell
198+
uv lock
199+
```
200+
195201
#### 2. Update translations
196202

197203
Extract new translatable strings, merge them into all existing `.po` files, translate the
@@ -204,6 +210,10 @@ uv run pybabel update -i statemachine/locale/statemachine.pot -d statemachine/lo
204210
uv run pybabel compile -d statemachine/locale/ -D statemachine
205211
```
206212

213+
The `en` catalog keeps empty `msgstr` entries: English falls back to the source strings.
214+
When a translation needs the placeholders in a different order, number them (`'{0}'`,
215+
`'{2}'`, `'{1}'`) instead of reordering bare `{}`, which would swap the values.
216+
207217
```{note}
208218
The `.pot` and `.mo` files are git-ignored. Only the `.po` source files are committed.
209219
The compiled `.mo` files may cause test failures if your system locale matches a translated
@@ -213,7 +223,8 @@ verifying translations work: `rm -f statemachine/locale/*/LC_MESSAGES/statemachi
213223

214224
#### 3. Write release notes
215225

216-
Create `docs/releases/X.Y.Z.md` documenting all changes since the previous release. Include
226+
Create `docs/releases/X.Y.Z.md` documenting all changes since the previous release, if
227+
the pull requests did not already start it. Include
217228
sections for new features, bugfixes, performance improvements, and miscellaneous changes.
218229
Reference GitHub issues/PRs where applicable.
219230

@@ -223,6 +234,9 @@ major version section).
223234
Update any related documentation pages (e.g., if a bugfix adds a new behavior that users
224235
should know about).
225236

237+
Replace the `*Not released yet*` line under the title with the release date (e.g.
238+
`*October 13, 2026*`).
239+
226240
#### 4. Run linters and tests
227241

228242
```shell
@@ -237,11 +251,12 @@ All checks must pass before committing.
237251
#### 5. Commit
238252

239253
Stage all changed files and commit. The pre-commit hooks will run ruff, mypy, and pytest
240-
automatically.
254+
automatically. If a hook rewrites a file (e.g. `fix end of files` on the `.po` files), stage
255+
it and commit again.
241256

242257
```shell
243258
git add <files>
244-
git commit -m "chore: prepare release X.Y.Z"
259+
git commit -s -m "chore: prepare release X.Y.Z"
245260
```
246261

247262
#### 6. Tag the release

‎docs/releases/3.2.2.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# python-statemachine 3.2.2
22

3-
*Not released yet*
3+
*October 13, 2026*
44

55
python-statemachine 3.2.2 is a bugfix release that also adds Python 3.15 support and closes
66
denial-of-service gaps in the restricted expression evaluator. Most of its

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "python-statemachine"
3-
version = "3.2.1"
3+
version = "3.2.2"
44
description = "Python Finite State Machines made easy."
55
authors = [{ name = "Fernando Macedo", email = "fgmacedo@gmail.com" }]
66
maintainers = [{ name = "Fernando Macedo", email = "fgmacedo@gmail.com" }]

‎statemachine/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
__author__ = """Fernando Macedo"""
1010
__email__ = "fgmacedo@gmail.com"
11-
__version__ = "3.2.1"
11+
__version__ = "3.2.2"
1212

1313
__all__ = [
1414
"StateChart",

‎statemachine/locale/en/LC_MESSAGES/statemachine.po‎

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ msgid ""
55
msgstr ""
66
"Project-Id-Version: 3.1.1\n"
77
"Report-Msgid-Bugs-To: fgmacedo@gmail.com\n"
8-
"POT-Creation-Date: 2026-06-16 23:00-0300\n"
8+
"POT-Creation-Date: 2026-10-13 21:26-0300\n"
99
"PO-Revision-Date: 2026-02-24 14:31-0300\n"
1010
"Last-Translator: Fernando Macedo <fgmacedo@gmail.com>\n"
1111
"Language: en\n"
@@ -16,7 +16,7 @@ msgstr ""
1616
"Content-Transfer-Encoding: 8bit\n"
1717
"Generated-By: Babel 2.18.0\n"
1818

19-
#: statemachine/callbacks.py:398 statemachine/callbacks.py:403
19+
#: statemachine/callbacks.py:409 statemachine/callbacks.py:414
2020
#, python-brace-format
2121
msgid "Did not found name '{}' from model or statemachine"
2222
msgstr "Did not found name '{}' from model or statemachine"
@@ -29,12 +29,20 @@ msgstr ""
2929
"There's no current state set. In async code, did you activate the initial"
3030
" state? (e.g., `await sm.activate_initial_state()`)"
3131

32-
#: statemachine/dispatcher.py:123
32+
#: statemachine/dispatcher.py:127
3333
#, python-brace-format
3434
msgid "Failed to parse boolean expression '{}'"
3535
msgstr "Failed to parse boolean expression '{}'"
3636

37-
#: statemachine/event.py:94
37+
#: statemachine/event.py:56
38+
#, python-brace-format
39+
msgid ""
40+
"Event {id!r} cannot be both delayed and internal: the internal queue runs"
41+
" within the current macrostep, which takes no time. Drop 'internal' to "
42+
"deliver it later on the external queue, or drop 'delay' to run it now."
43+
msgstr ""
44+
45+
#: statemachine/event.py:108
3846
#, python-brace-format
3947
msgid ""
4048
"Event() received a non-string 'id' ({cls_name}). To combine multiple "
@@ -43,12 +51,12 @@ msgstr ""
4351
"Event() received a non-string 'id' ({cls_name}). To combine multiple "
4452
"transitions under one event, use the | operator: t1 | t2."
4553

46-
#: statemachine/event.py:130
54+
#: statemachine/event.py:147
4755
#, python-brace-format
4856
msgid "Cannot add callback '{}' to an event with no transitions."
4957
msgstr "Cannot add callback '{}' to an event with no transitions."
5058

51-
#: statemachine/event.py:163
59+
#: statemachine/event.py:182
5260
#, python-brace-format
5361
msgid "Event {} cannot be called without a SM instance"
5462
msgstr "Event {} cannot be called without a SM instance"
@@ -63,7 +71,7 @@ msgstr "{!r} is not a valid state value."
6371
msgid "Can't {} when in {}."
6472
msgstr "Can't {} when in {}."
6573

66-
#: statemachine/factory.py:77
74+
#: statemachine/factory.py:91
6775
#, python-brace-format
6876
msgid ""
6977
"There should be one and only one initial state. Your currently have "
@@ -72,7 +80,34 @@ msgstr ""
7280
"There should be one and only one initial state. Your currently have "
7381
"these: {0}"
7482

75-
#: statemachine/factory.py:194
83+
#: statemachine/factory.py:249
84+
#, python-brace-format
85+
msgid "is declared in both the '{}' and the '{}' state bodies"
86+
msgstr ""
87+
88+
#: statemachine/factory.py:253
89+
#, python-brace-format
90+
msgid "in the '{}' state body clashes with the event '{}'"
91+
msgstr ""
92+
93+
#: statemachine/factory.py:257
94+
#, python-brace-format
95+
msgid "is declared in both the '{}' state body and the '{}' class body"
96+
msgstr ""
97+
98+
#: statemachine/factory.py:261
99+
#, python-brace-format
100+
msgid "in the '{}' state body clashes with the '{}' attribute of '{}'"
101+
msgstr ""
102+
103+
#: statemachine/factory.py:267
104+
#, python-brace-format
105+
msgid ""
106+
"Callback '{}' {}. Nested state bodies share the class namespace. Rename "
107+
"one of them."
108+
msgstr ""
109+
110+
#: statemachine/factory.py:291
76111
#, python-brace-format
77112
msgid ""
78113
"There should be one and only one initial state. You currently have these:"
@@ -81,12 +116,12 @@ msgstr ""
81116
"There should be one and only one initial state. You currently have these:"
82117
" {!r}"
83118

84-
#: statemachine/factory.py:209
119+
#: statemachine/factory.py:306
85120
#, python-brace-format
86121
msgid "Cannot declare transitions from final state. Invalid state(s): {}"
87122
msgstr "Cannot declare transitions from final state. Invalid state(s): {}"
88123

89-
#: statemachine/factory.py:221
124+
#: statemachine/factory.py:318
90125
#, python-brace-format
91126
msgid ""
92127
"All non-final states should have at least one outgoing transition. These "
@@ -95,7 +130,7 @@ msgstr ""
95130
"All non-final states should have at least one outgoing transition. These "
96131
"states have no outgoing transition: {!r}"
97132

98-
#: statemachine/factory.py:235
133+
#: statemachine/factory.py:332
99134
#, python-brace-format
100135
msgid ""
101136
"All non-final states should have at least one path to a final state. "
@@ -104,7 +139,7 @@ msgstr ""
104139
"All non-final states should have at least one path to a final state. "
105140
"These states have no path to a final state: {!r}"
106141

107-
#: statemachine/factory.py:248
142+
#: statemachine/factory.py:345
108143
#, python-brace-format
109144
msgid ""
110145
"There are unreachable states. The statemachine graph should have a single"
@@ -113,7 +148,7 @@ msgstr ""
113148
"There are unreachable states. The statemachine graph should have a single"
114149
" component. Disconnected states: {}"
115150

116-
#: statemachine/factory.py:285
151+
#: statemachine/factory.py:382
117152
#, python-brace-format
118153
msgid ""
119154
"Invalid entry in 'listeners': {!r}. Expected a class, callable, or "
@@ -122,7 +157,7 @@ msgstr ""
122157
"Invalid entry in 'listeners': {!r}. Expected a class, callable, or "
123158
"listener instance."
124159

125-
#: statemachine/factory.py:384
160+
#: statemachine/factory.py:481
126161
#, python-brace-format
127162
msgid "An event in the '{}' has no id."
128163
msgstr "An event in the '{}' has no id."
@@ -132,15 +167,15 @@ msgstr "An event in the '{}' has no id."
132167
msgid "{!r} is not a valid state machine name."
133168
msgstr "{!r} is not a valid state machine name."
134169

135-
#: statemachine/state.py:249
170+
#: statemachine/state.py:273
136171
msgid "'donedata' can only be specified on final states."
137172
msgstr "'donedata' can only be specified on final states."
138173

139-
#: statemachine/statemachine.py:167
174+
#: statemachine/statemachine.py:168
140175
msgid "There are no states or transitions."
141176
msgstr "There are no states or transitions."
142177

143-
#: statemachine/statemachine.py:237
178+
#: statemachine/statemachine.py:242
144179
#, python-brace-format
145180
msgid "State overriding is not allowed. Trying to add '{}' to {}"
146181
msgstr "State overriding is not allowed. Trying to add '{}' to {}"
@@ -158,3 +193,9 @@ msgstr ""
158193
#, python-brace-format
159194
msgid "{} only supports the decorator syntax to register callbacks."
160195
msgstr "{} only supports the decorator syntax to register callbacks."
196+
197+
#: statemachine/engines/async_.py:50
198+
msgid ""
199+
"The task running the processing loop was cancelled while it processed "
200+
"this event."
201+
msgstr ""

0 commit comments

Comments
 (0)