stm32loader 0.7.0__tar.gz → 1.0.0.dev2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {stm32loader-0.7.0 → stm32loader-1.0.0.dev2}/PKG-INFO +74 -43
  2. {stm32loader-0.7.0 → stm32loader-1.0.0.dev2}/README.md +53 -25
  3. stm32loader-1.0.0.dev2/pyproject.toml +149 -0
  4. stm32loader-0.7.0/pyproject.toml → stm32loader-1.0.0.dev2/pyproject.toml.orig +72 -42
  5. stm32loader-1.0.0.dev2/src/stm32loader/__init__.py +8 -0
  6. {stm32loader-0.7.0 → stm32loader-1.0.0.dev2/src}/stm32loader/args.py +85 -13
  7. {stm32loader-0.7.0 → stm32loader-1.0.0.dev2/src}/stm32loader/bootloader.py +494 -144
  8. stm32loader-1.0.0.dev2/src/stm32loader/device_family.py +243 -0
  9. stm32loader-1.0.0.dev2/src/stm32loader/device_info.py +177 -0
  10. stm32loader-1.0.0.dev2/src/stm32loader/devices.py +1184 -0
  11. stm32loader-1.0.0.dev2/src/stm32loader/emulated/fake.py +174 -0
  12. stm32loader-1.0.0.dev2/src/stm32loader/main.py +410 -0
  13. {stm32loader-0.7.0 → stm32loader-1.0.0.dev2/src}/stm32loader/uart.py +1 -2
  14. stm32loader-0.7.0/.flake8 +0 -25
  15. stm32loader-0.7.0/.github/workflows/lint.yaml +0 -61
  16. stm32loader-0.7.0/.github/workflows/test.yaml +0 -33
  17. stm32loader-0.7.0/.gitignore +0 -8
  18. stm32loader-0.7.0/.pylintrc +0 -16
  19. stm32loader-0.7.0/.travis.yml +0 -32
  20. stm32loader-0.7.0/ALTERNATIVES.md +0 -58
  21. stm32loader-0.7.0/CHANGELOG.md +0 -133
  22. stm32loader-0.7.0/DEVELOP.md +0 -56
  23. stm32loader-0.7.0/EXTEND.md +0 -64
  24. stm32loader-0.7.0/MANIFEST.in +0 -7
  25. stm32loader-0.7.0/RUN.md +0 -52
  26. stm32loader-0.7.0/noxfile.py +0 -49
  27. stm32loader-0.7.0/stm32loader/__init__.py +0 -4
  28. stm32loader-0.7.0/stm32loader/main.py +0 -256
  29. stm32loader-0.7.0/tests/data/small.hex +0 -2
  30. stm32loader-0.7.0/tests/integration/test_stm32bootloader.py +0 -63
  31. stm32loader-0.7.0/tests/integration/test_stm32loader.py +0 -132
  32. stm32loader-0.7.0/tests/unit/test_arguments.py +0 -45
  33. stm32loader-0.7.0/tests/unit/test_bootloader.py +0 -256
  34. stm32loader-0.7.0/tests/unit/test_hexfile.py +0 -14
  35. stm32loader-0.7.0/tox.ini +0 -22
  36. {stm32loader-0.7.0 → stm32loader-1.0.0.dev2}/LICENSE +0 -0
  37. {stm32loader-0.7.0 → stm32loader-1.0.0.dev2/src}/stm32loader/.gitignore +0 -0
  38. {stm32loader-0.7.0 → stm32loader-1.0.0.dev2/src}/stm32loader/__main__.py +0 -0
  39. {stm32loader-0.7.0 → stm32loader-1.0.0.dev2/src}/stm32loader/hexfile.py +0 -0
@@ -1,44 +1,48 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: stm32loader
3
- Version: 0.7.0
3
+ Version: 1.0.0.dev2
4
4
  Summary: Flash firmware to STM32 microcontrollers using Python.
5
- Author: jsnyder
5
+ Author: jsnyder, Floris Lambrechts
6
6
  Author-email: Floris Lambrechts <florisla@gmail.com>
7
- Requires-Python: >=3.9
8
- Description-Content-Type: text/markdown
9
- Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
7
+ License-Expression: GPL-3.0-or-later
8
+ License-File: LICENSE
10
9
  Classifier: Programming Language :: Python
11
10
  Classifier: Programming Language :: Python :: 3
12
11
  Classifier: Programming Language :: Python :: 3.9
13
12
  Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Programming Language :: Python :: 3.15
15
18
  Classifier: Programming Language :: Python :: Implementation :: CPython
16
19
  Classifier: Programming Language :: Python :: Implementation :: PyPy
17
20
  Classifier: Natural Language :: English
18
21
  Classifier: Operating System :: OS Independent
19
22
  Requires-Dist: pyserial
20
23
  Requires-Dist: progress
21
- Requires-Dist: wheel ; extra == "dev"
22
- Requires-Dist: twine ; extra == "dev"
23
- Requires-Dist: pylint ; extra == "dev"
24
- Requires-Dist: flake8 ; extra == "dev"
25
- Requires-Dist: flake8-isort ; extra == "dev"
26
- Requires-Dist: black ; extra == "dev"
27
- Requires-Dist: bump-my-version ; extra == "dev"
28
- Requires-Dist: nox ; extra == "dev"
29
- Requires-Dist: cogapp ; extra == "dev"
30
- Requires-Dist: intelhex ; extra == "hex"
31
- Project-URL: BugTracker, https://github.com/florisla/stm32loader/issues
24
+ Requires-Dist: intelhex ; extra == 'dev'
25
+ Requires-Dist: pytest ; extra == 'dev'
26
+ Requires-Dist: nox>=2026.2.9 ; extra == 'dev'
27
+ Requires-Dist: nox-uv>=0.7.1 ; extra == 'dev'
28
+ Requires-Dist: ruff ; extra == 'dev'
29
+ Requires-Dist: pylint ; extra == 'dev'
30
+ Requires-Dist: bump-my-version ; extra == 'dev'
31
+ Requires-Dist: cogapp ; extra == 'dev'
32
+ Requires-Dist: intelhex ; extra == 'hex'
33
+ Requires-Python: >=3.9
32
34
  Project-URL: Home, https://github.com/florisla/stm32loader
35
+ Project-URL: BugTracker, https://github.com/florisla/stm32loader/issues
33
36
  Project-URL: SourceCode, https://github.com/florisla/stm32loader
34
37
  Provides-Extra: dev
35
38
  Provides-Extra: hex
39
+ Description-Content-Type: text/markdown
36
40
 
37
41
  # STM32Loader
38
42
 
39
43
  [![PyPI package](https://badge.fury.io/py/stm32loader.svg)](https://badge.fury.io/py/stm32loader)
40
- [![GitHub Actions](https://img.shields.io/github/workflow/status/florisla/stm32loader/Test?label=tests)](https://github.com/florisla/stm32loader/actions/workflows/test.yaml)
41
- [![GitHub Actions](https://img.shields.io/github/workflow/status/florisla/stm32loader/Lint?label=lint)](https://github.com/florisla/stm32loader/actions/workflows/lint.yaml)
44
+ [![Test](https://github.com/florisla/stm32loader/actions/workflows/test.yaml/badge.svg)](https://github.com/florisla/stm32loader/actions/workflows/test.yaml)
45
+ [![Lint](https://github.com/florisla/stm32loader/actions/workflows/lint.yaml/badge.svg)](https://github.com/florisla/stm32loader/actions/workflows/lint.yaml)
42
46
  [![License](https://img.shields.io/pypi/l/stm32loader.svg)](https://pypi.org/project/stm32loader/)
43
47
  [![Downloads](https://pepy.tech/badge/stm32loader)](https://pepy.tech/project/stm32loader)
44
48
 
@@ -48,13 +52,22 @@ ST Microelectronics STM32 microcontrollers over UART.
48
52
  Also supports ST BlueNRG devices, and the SweetPeas bootloader
49
53
  for Wiznet W7500.
50
54
 
51
- Compatible with Python version 3.9 to 3.11 and PyPy 3.9.
55
+ Compatible with Python version 3.9-3.15 and PyPy 3.10-3.11.
56
+
57
+
58
+ ## Run using `uvx`
52
59
 
60
+ uvx stm32loader
53
61
 
54
- ## Installation
62
+
63
+ ## Installation with pip
55
64
 
56
65
  pip install stm32loader
57
66
 
67
+ To also support loading `.hex` files:
68
+
69
+ pip install stm32loader[hex]
70
+
58
71
  To install the latest development version:
59
72
 
60
73
  pip install git+https://github.com/florisla/stm32loader.git
@@ -78,7 +91,9 @@ sys.stdout.close()
78
91
  sys.stdout = sys.__stdout__
79
92
  ]]] -->
80
93
  ```
81
- usage: stm32loader [-h] [-e] [-u] [-x] [-w] [-v] [-r] [-l LENGTH] -p PORT [-b BAUD] [-a ADDRESS] [-g ADDRESS] [-f FAMILY]
94
+ usage: stm32loader [-h] [-e] [-E] [-u] [-x] [--write-unprotect]
95
+ [--write-protect] [-w] [-v] [-r] [-l LENGTH] -p PORT
96
+ [-b BAUD] [-a ADDRESS | -o OFFSET] [-g ADDRESS] [-f FAMILY]
82
97
  [-V] [-q] [-s] [-R] [-B] [-n] [-P {even,none}] [--version]
83
98
  [FILE.BIN]
84
99
 
@@ -89,23 +104,35 @@ positional arguments:
89
104
 
90
105
  options:
91
106
  -h, --help show this help message and exit
92
- -e, --erase Erase (note: this is required on previously written memory).
107
+ -e, --erase Erase the full flash memory or a specific region
108
+ (support --address and --length). Note: this is
109
+ required on previously written memory.
110
+ -E, --auto-erase Before writing, erase only the flash pages that the
111
+ written data covers.
93
112
  -u, --unprotect Unprotect flash from readout.
94
113
  -x, --protect Protect flash against readout.
114
+ --write-unprotect Disable write protection before flashing
115
+ --write-protect Enable write protection after flashing
95
116
  -w, --write Write file content to flash.
96
117
  -v, --verify Verify flash content versus local file (recommended).
97
118
  -r, --read Read from flash and store in local file.
98
- -l LENGTH, --length LENGTH
99
- Length of read or erase.
100
- -p PORT, --port PORT Serial port (default: $STM32LOADER_SERIAL_PORT).
101
- -b BAUD, --baud BAUD Baudrate. (default: 115200)
102
- -a ADDRESS, --address ADDRESS
103
- Target address for read, write or erase. (default: 134217728)
104
- -g ADDRESS, --go-address ADDRESS
119
+ -l, --length LENGTH Length of read or erase. For write and verify, use
120
+ only this many bytes of the file.
121
+ -p, --port PORT Serial port (default: $STM32LOADER_SERIAL_PORT).
122
+ -b, --baud BAUD Baudrate. (default: 115200)
123
+ -a, --address ADDRESS
124
+ Target address for read or write. For erase, this is
125
+ used when you supply --length. Default: the start of
126
+ flash memory.
127
+ -o, --offset OFFSET Alternative to --address: an offset from the start of
128
+ flash memory.
129
+ -g, --go-address ADDRESS
105
130
  Start executing from address (0x08000000, usually).
106
- -f FAMILY, --family FAMILY
107
- Device family to read out device UID and flash size; e.g F1 for STM32F1xx. Possible values: F0,
108
- F1, F3, F4, F7, H7, L4, L0, G0, NRG. (default: $STM32LOADER_FAMILY).
131
+ -f, --family FAMILY Device family to read out device UID and flash size;
132
+ e.g F1 for STM32F1xx. Possible values: C0, F0, F1, F2,
133
+ F3, F4, F7, G0, G4, H5, H7, L0, L1, L4, L5, WBA, WB0,
134
+ WB, WL, U5, W, NRG, WIZ, GD32VW55X (default:
135
+ $STM32LOADER_FAMILY).
109
136
  -V, --verbose Verbose mode.
110
137
  -q, --quiet Quiet mode.
111
138
  -s, --swap-rts-dtr Swap RTS and DTR: use RTS for reset and DTR for boot0.
@@ -114,8 +141,9 @@ options:
114
141
  -B, --boot0-active-low
115
142
  Make BOOT0 active low.
116
143
  -n, --no-progress Don't show progress bar.
117
- -P {even,none}, --parity {even,none}
118
- Parity: "even" for STM32, "none" for BlueNRG. (default: even)
144
+ -P, --parity {even,none}
145
+ Parity: "even" for STM32, "none" for BlueNRG.
146
+ (default: even)
119
147
  --version show program's version number and exit
120
148
 
121
149
  examples:
@@ -133,6 +161,16 @@ stm32loader --port /dev/tty.usbserial-ftCYPMYJ --erase --write --verify somefile
133
161
  This will pre-erase flash, write `somefile.bin` to the flash on the device, and then
134
162
  perform a verification after writing is finished.
135
163
 
164
+ To erase only the flash pages that the new data will occupy, use `--auto-erase`
165
+ instead of `--erase`:
166
+
167
+ ```
168
+ stm32loader --port /dev/tty.usbserial-ftCYPMYJ --auto-erase --write --verify somefile.bin
169
+ ```
170
+
171
+ The erased range is rounded out to whole pages (sectors), following the device's
172
+ flash layout. This also works on devices with mixed sector sizes.
173
+
136
174
  You can skip the `--port` option by configuring environment variable
137
175
  `STM32LOADER_SERIAL_PORT`.
138
176
  Similarly, `--family` may be supplied through `STM32LOADER_FAMILY`.
@@ -223,13 +261,6 @@ adapter (it needs to toggle, whereas `BOOT0` does not).
223
261
 
224
262
  ## Not currently supported
225
263
 
226
- * Command-line argument for write protection/unprotection.
264
+ * Command-line argument for write protection for some devices (e.g. those with dual-bank flash).
227
265
  * STM8 devices (ST `UM0560`).
228
266
  * Other bootloader protocols (e.g. I2C, HEX -> implemented in `stm32flash`).
229
-
230
-
231
- ## Future work
232
-
233
- * Use f-strings.
234
- * Use proper logging instead of print statements.
235
-
@@ -1,8 +1,8 @@
1
1
  # STM32Loader
2
2
 
3
3
  [![PyPI package](https://badge.fury.io/py/stm32loader.svg)](https://badge.fury.io/py/stm32loader)
4
- [![GitHub Actions](https://img.shields.io/github/workflow/status/florisla/stm32loader/Test?label=tests)](https://github.com/florisla/stm32loader/actions/workflows/test.yaml)
5
- [![GitHub Actions](https://img.shields.io/github/workflow/status/florisla/stm32loader/Lint?label=lint)](https://github.com/florisla/stm32loader/actions/workflows/lint.yaml)
4
+ [![Test](https://github.com/florisla/stm32loader/actions/workflows/test.yaml/badge.svg)](https://github.com/florisla/stm32loader/actions/workflows/test.yaml)
5
+ [![Lint](https://github.com/florisla/stm32loader/actions/workflows/lint.yaml/badge.svg)](https://github.com/florisla/stm32loader/actions/workflows/lint.yaml)
6
6
  [![License](https://img.shields.io/pypi/l/stm32loader.svg)](https://pypi.org/project/stm32loader/)
7
7
  [![Downloads](https://pepy.tech/badge/stm32loader)](https://pepy.tech/project/stm32loader)
8
8
 
@@ -12,13 +12,22 @@ ST Microelectronics STM32 microcontrollers over UART.
12
12
  Also supports ST BlueNRG devices, and the SweetPeas bootloader
13
13
  for Wiznet W7500.
14
14
 
15
- Compatible with Python version 3.9 to 3.11 and PyPy 3.9.
15
+ Compatible with Python version 3.9-3.15 and PyPy 3.10-3.11.
16
16
 
17
17
 
18
- ## Installation
18
+ ## Run using `uvx`
19
+
20
+ uvx stm32loader
21
+
22
+
23
+ ## Installation with pip
19
24
 
20
25
  pip install stm32loader
21
26
 
27
+ To also support loading `.hex` files:
28
+
29
+ pip install stm32loader[hex]
30
+
22
31
  To install the latest development version:
23
32
 
24
33
  pip install git+https://github.com/florisla/stm32loader.git
@@ -42,7 +51,9 @@ sys.stdout.close()
42
51
  sys.stdout = sys.__stdout__
43
52
  ]]] -->
44
53
  ```
45
- usage: stm32loader [-h] [-e] [-u] [-x] [-w] [-v] [-r] [-l LENGTH] -p PORT [-b BAUD] [-a ADDRESS] [-g ADDRESS] [-f FAMILY]
54
+ usage: stm32loader [-h] [-e] [-E] [-u] [-x] [--write-unprotect]
55
+ [--write-protect] [-w] [-v] [-r] [-l LENGTH] -p PORT
56
+ [-b BAUD] [-a ADDRESS | -o OFFSET] [-g ADDRESS] [-f FAMILY]
46
57
  [-V] [-q] [-s] [-R] [-B] [-n] [-P {even,none}] [--version]
47
58
  [FILE.BIN]
48
59
 
@@ -53,23 +64,35 @@ positional arguments:
53
64
 
54
65
  options:
55
66
  -h, --help show this help message and exit
56
- -e, --erase Erase (note: this is required on previously written memory).
67
+ -e, --erase Erase the full flash memory or a specific region
68
+ (support --address and --length). Note: this is
69
+ required on previously written memory.
70
+ -E, --auto-erase Before writing, erase only the flash pages that the
71
+ written data covers.
57
72
  -u, --unprotect Unprotect flash from readout.
58
73
  -x, --protect Protect flash against readout.
74
+ --write-unprotect Disable write protection before flashing
75
+ --write-protect Enable write protection after flashing
59
76
  -w, --write Write file content to flash.
60
77
  -v, --verify Verify flash content versus local file (recommended).
61
78
  -r, --read Read from flash and store in local file.
62
- -l LENGTH, --length LENGTH
63
- Length of read or erase.
64
- -p PORT, --port PORT Serial port (default: $STM32LOADER_SERIAL_PORT).
65
- -b BAUD, --baud BAUD Baudrate. (default: 115200)
66
- -a ADDRESS, --address ADDRESS
67
- Target address for read, write or erase. (default: 134217728)
68
- -g ADDRESS, --go-address ADDRESS
79
+ -l, --length LENGTH Length of read or erase. For write and verify, use
80
+ only this many bytes of the file.
81
+ -p, --port PORT Serial port (default: $STM32LOADER_SERIAL_PORT).
82
+ -b, --baud BAUD Baudrate. (default: 115200)
83
+ -a, --address ADDRESS
84
+ Target address for read or write. For erase, this is
85
+ used when you supply --length. Default: the start of
86
+ flash memory.
87
+ -o, --offset OFFSET Alternative to --address: an offset from the start of
88
+ flash memory.
89
+ -g, --go-address ADDRESS
69
90
  Start executing from address (0x08000000, usually).
70
- -f FAMILY, --family FAMILY
71
- Device family to read out device UID and flash size; e.g F1 for STM32F1xx. Possible values: F0,
72
- F1, F3, F4, F7, H7, L4, L0, G0, NRG. (default: $STM32LOADER_FAMILY).
91
+ -f, --family FAMILY Device family to read out device UID and flash size;
92
+ e.g F1 for STM32F1xx. Possible values: C0, F0, F1, F2,
93
+ F3, F4, F7, G0, G4, H5, H7, L0, L1, L4, L5, WBA, WB0,
94
+ WB, WL, U5, W, NRG, WIZ, GD32VW55X (default:
95
+ $STM32LOADER_FAMILY).
73
96
  -V, --verbose Verbose mode.
74
97
  -q, --quiet Quiet mode.
75
98
  -s, --swap-rts-dtr Swap RTS and DTR: use RTS for reset and DTR for boot0.
@@ -78,8 +101,9 @@ options:
78
101
  -B, --boot0-active-low
79
102
  Make BOOT0 active low.
80
103
  -n, --no-progress Don't show progress bar.
81
- -P {even,none}, --parity {even,none}
82
- Parity: "even" for STM32, "none" for BlueNRG. (default: even)
104
+ -P, --parity {even,none}
105
+ Parity: "even" for STM32, "none" for BlueNRG.
106
+ (default: even)
83
107
  --version show program's version number and exit
84
108
 
85
109
  examples:
@@ -97,6 +121,16 @@ stm32loader --port /dev/tty.usbserial-ftCYPMYJ --erase --write --verify somefile
97
121
  This will pre-erase flash, write `somefile.bin` to the flash on the device, and then
98
122
  perform a verification after writing is finished.
99
123
 
124
+ To erase only the flash pages that the new data will occupy, use `--auto-erase`
125
+ instead of `--erase`:
126
+
127
+ ```
128
+ stm32loader --port /dev/tty.usbserial-ftCYPMYJ --auto-erase --write --verify somefile.bin
129
+ ```
130
+
131
+ The erased range is rounded out to whole pages (sectors), following the device's
132
+ flash layout. This also works on devices with mixed sector sizes.
133
+
100
134
  You can skip the `--port` option by configuring environment variable
101
135
  `STM32LOADER_SERIAL_PORT`.
102
136
  Similarly, `--family` may be supplied through `STM32LOADER_FAMILY`.
@@ -187,12 +221,6 @@ adapter (it needs to toggle, whereas `BOOT0` does not).
187
221
 
188
222
  ## Not currently supported
189
223
 
190
- * Command-line argument for write protection/unprotection.
224
+ * Command-line argument for write protection for some devices (e.g. those with dual-bank flash).
191
225
  * STM8 devices (ST `UM0560`).
192
226
  * Other bootloader protocols (e.g. I2C, HEX -> implemented in `stm32flash`).
193
-
194
-
195
- ## Future work
196
-
197
- * Use f-strings.
198
- * Use proper logging instead of print statements.
@@ -0,0 +1,149 @@
1
+ [project]
2
+ name = "stm32loader"
3
+ description = "Flash firmware to STM32 microcontrollers using Python."
4
+ version = "1.0.0-dev2"
5
+ readme = "README.md"
6
+ requires-python = ">=3.9"
7
+ license = "GPL-3.0-or-later"
8
+ license-files = ["LICENSE"]
9
+ classifiers = [
10
+ "Programming Language :: Python",
11
+ "Programming Language :: Python :: 3",
12
+ "Programming Language :: Python :: 3.9",
13
+ "Programming Language :: Python :: 3.10",
14
+ "Programming Language :: Python :: 3.11",
15
+ "Programming Language :: Python :: 3.12",
16
+ "Programming Language :: Python :: 3.13",
17
+ "Programming Language :: Python :: 3.14",
18
+ "Programming Language :: Python :: 3.15",
19
+ "Programming Language :: Python :: Implementation :: CPython",
20
+ "Programming Language :: Python :: Implementation :: PyPy",
21
+ "Natural Language :: English",
22
+ "Operating System :: OS Independent",
23
+ ]
24
+ dependencies = [
25
+ "pyserial",
26
+ "progress",
27
+ ]
28
+
29
+ [[project.authors]]
30
+ name = "jsnyder"
31
+
32
+ [[project.authors]]
33
+ name = "Floris Lambrechts"
34
+ email = "florisla@gmail.com"
35
+
36
+ [project.optional-dependencies]
37
+ hex = ["intelhex"]
38
+ dev = [
39
+ "intelhex",
40
+ "pytest",
41
+ "nox>=2026.2.9",
42
+ "nox-uv>=0.7.1",
43
+ "ruff",
44
+ "pylint",
45
+ "bump-my-version",
46
+ "cogapp",
47
+ ]
48
+
49
+ [project.scripts]
50
+ stm32loader = "stm32loader.__main__:main"
51
+
52
+ [project.urls]
53
+ Home = "https://github.com/florisla/stm32loader"
54
+ BugTracker = "https://github.com/florisla/stm32loader/issues"
55
+ SourceCode = "https://github.com/florisla/stm32loader"
56
+
57
+ [build-system]
58
+ requires = ["uv_build>=0.13.5,<0.14.0"]
59
+ build-backend = "uv_build"
60
+
61
+ [dependency-groups]
62
+ hex = ["intelhex"]
63
+ lint = [
64
+ "ruff",
65
+ "pylint",
66
+ ]
67
+ test = [
68
+ "pytest",
69
+ "intelhex",
70
+ "nox>=2026.2.9",
71
+ "nox-uv>=0.7.1",
72
+ ]
73
+ release = [
74
+ "bump-my-version",
75
+ "cogapp",
76
+ ]
77
+
78
+ [tool.uv]
79
+ default-groups = [
80
+ "test",
81
+ "hex",
82
+ "lint",
83
+ "release",
84
+ ]
85
+
86
+ [tool.bumpversion]
87
+ commit = true
88
+ tag = true
89
+ message = "release: Bump version number from v{current_version} to v{new_version}"
90
+ parse = '(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(-(?P<release>[^\d]+)(?P<devrelease>\d+))?'
91
+ serialize = [
92
+ "{major}.{minor}.{patch}-{release}{devrelease}",
93
+ "{major}.{minor}.{patch}",
94
+ ]
95
+
96
+ [tool.bumpversion.parts.release]
97
+ optional_value = "release"
98
+ values = [
99
+ "dev",
100
+ "release",
101
+ ]
102
+
103
+ [[tool.bumpversion.files]]
104
+ filename = "src/stm32loader/__init__.py"
105
+ parse = '\((?P<major>\d+),\s(?P<minor>\d+),\s(?P<patch>\d+)(\s*,\s*"(?P<release>[^"]+)"\s*,\s*(?P<devrelease>\d+))?\)'
106
+ serialize = [
107
+ '({major}, {minor}, {patch}, "{release}", {devrelease})',
108
+ "({major}, {minor}, {patch})",
109
+ ]
110
+ search = "__version_info__ = {current_version}"
111
+ replace = "__version_info__ = {new_version}"
112
+
113
+ [[tool.bumpversion.files]]
114
+ filename = "src/stm32loader/__init__.py"
115
+ search = '__version__ = "{current_version}"'
116
+ replace = '__version__ = "{new_version}"'
117
+
118
+ [tool.ruff]
119
+ line-length = 98
120
+ target-version = "py39"
121
+ exclude = [
122
+ ".git",
123
+ ".idea",
124
+ "__pycache__",
125
+ "build",
126
+ "dist",
127
+ "*.egg-info",
128
+ ]
129
+
130
+ [tool.ruff.lint]
131
+ select = [
132
+ "E",
133
+ "F",
134
+ "W",
135
+ "I",
136
+ ]
137
+
138
+ [tool.ruff.lint.pycodestyle]
139
+ max-doc-length = 78
140
+
141
+ [tool.ruff.format]
142
+ docstring-code-format = true
143
+
144
+ [tool.pytest.ini_options]
145
+ addopts = "--strict-markers -m 'not (hardware or missing_hardware)'"
146
+ markers = [
147
+ "hardware",
148
+ "missing_hardware",
149
+ ]
@@ -1,48 +1,70 @@
1
- [build-system]
2
- requires = ["flit_core >=3.2,<4"]
3
- build-backend = "flit_core.buildapi"
4
-
5
1
  [project]
6
2
  name = "stm32loader"
3
+ description = "Flash firmware to STM32 microcontrollers using Python."
4
+ version = "1.0.0-dev2"
5
+ readme = "README.md"
7
6
  authors = [
8
7
  {name = "jsnyder"},
9
8
  {name = "Floris Lambrechts", email = "florisla@gmail.com"},
10
9
  ]
11
- readme = "README.md"
12
- description = "Flash firmware to STM32 microcontrollers using Python."
13
- license = {file = "LICENSE"}
14
10
  requires-python = ">=3.9"
15
- dependencies = [
16
- "pyserial",
17
- "progress",
18
- ]
11
+ license = "GPL-3.0-or-later"
12
+ license-files = ["LICENSE"]
19
13
  classifiers = [
20
- "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
21
14
  "Programming Language :: Python",
22
15
  "Programming Language :: Python :: 3",
23
16
  "Programming Language :: Python :: 3.9",
24
17
  "Programming Language :: Python :: 3.10",
25
18
  "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Programming Language :: Python :: 3.14",
22
+ "Programming Language :: Python :: 3.15",
26
23
  "Programming Language :: Python :: Implementation :: CPython",
27
24
  "Programming Language :: Python :: Implementation :: PyPy",
28
25
  "Natural Language :: English",
29
26
  "Operating System :: OS Independent",
30
27
  ]
31
- dynamic = ["version"]
28
+ dependencies = [
29
+ "pyserial",
30
+ "progress",
31
+ ]
32
32
 
33
33
  [project.optional-dependencies]
34
34
  hex = [
35
35
  "intelhex",
36
36
  ]
37
37
  dev = [
38
- "wheel",
39
- "twine",
38
+ "intelhex",
39
+ "pytest",
40
+ "nox>=2026.2.9",
41
+ "nox-uv>=0.7.1",
42
+ "ruff",
40
43
  "pylint",
41
- "flake8",
42
- "flake8-isort",
43
- "black",
44
44
  "bump-my-version",
45
- "nox",
45
+ "cogapp",
46
+ ]
47
+
48
+ [build-system]
49
+ requires = ["uv_build>=0.13.5,<0.14.0"]
50
+ build-backend = "uv_build"
51
+
52
+ [dependency-groups]
53
+ hex = [
54
+ "intelhex",
55
+ ]
56
+ lint = [
57
+ "ruff",
58
+ "pylint",
59
+ ]
60
+ test = [
61
+ "pytest",
62
+ "intelhex",
63
+ "nox>=2026.2.9",
64
+ "nox-uv>=0.7.1",
65
+ ]
66
+ release = [
67
+ "bump-my-version",
46
68
  "cogapp",
47
69
  ]
48
70
 
@@ -55,8 +77,11 @@ BugTracker = "https://github.com/florisla/stm32loader/issues"
55
77
  SourceCode = "https://github.com/florisla/stm32loader"
56
78
 
57
79
 
80
+ [tool.uv]
81
+ default-groups = ["test", "hex", "lint", "release"]
82
+
83
+
58
84
  [tool.bumpversion]
59
- current_version = "0.7.0"
60
85
  commit = true
61
86
  tag = true
62
87
  message = "release: Bump version number from v{current_version} to v{new_version}"
@@ -74,7 +99,7 @@ values = [
74
99
  ]
75
100
 
76
101
  [[tool.bumpversion.files]]
77
- filename = "stm32loader/__init__.py"
102
+ filename = "src/stm32loader/__init__.py"
78
103
  parse = "\\((?P<major>\\d+),\\s(?P<minor>\\d+),\\s(?P<patch>\\d+)(\\s*,\\s*\"(?P<release>[^\"]+)\"\\s*,\\s*(?P<devrelease>\\d+))?\\)"
79
104
  serialize = [
80
105
  "({major}, {minor}, {patch}, \"{release}\", {devrelease})",
@@ -83,34 +108,39 @@ serialize = [
83
108
  search = "__version_info__ = {current_version}"
84
109
  replace = "__version_info__ = {new_version}"
85
110
 
111
+ [[tool.bumpversion.files]]
112
+ filename = "src/stm32loader/__init__.py"
113
+ search = "__version__ = \"{current_version}\""
114
+ replace = "__version__ = \"{new_version}\""
86
115
 
87
- [tool.black]
116
+
117
+ [tool.ruff]
88
118
  line-length = 98
89
- target-version = [
90
- "py39",
91
- "py310",
92
- "py311",
119
+ target-version = "py39"
120
+ exclude = [
121
+ ".git",
122
+ ".idea",
123
+ "__pycache__",
124
+ "build",
125
+ "dist",
126
+ "*.egg-info",
93
127
  ]
94
- exclude = '''
95
- /(
96
- \.git
97
- | \.idea
98
- | __pycache__
99
- | build
100
- | dist
101
- | .*\.egg-info
102
- )/
103
- '''
128
+
129
+ [tool.ruff.lint]
130
+ # E/W: pycodestyle, F: pyflakes, I: isort
131
+ # Replaces flake8 + flake8-isort; ruff format replaces black
132
+ select = ["E", "F", "W", "I"]
133
+
134
+ [tool.ruff.lint.pycodestyle]
135
+ max-doc-length = 78
136
+
137
+ [tool.ruff.format]
138
+ docstring-code-format = true
104
139
 
105
140
 
106
141
  [tool.pytest.ini_options]
107
- addopts = "--strict-markers -m 'not (hardware or hardware_missing)'"
142
+ addopts = "--strict-markers -m 'not (hardware or missing_hardware)'"
108
143
  markers = [
109
144
  "hardware",
110
145
  "missing_hardware",
111
146
  ]
112
-
113
-
114
- [tool.isort]
115
- line_length = 98
116
- multi_line_output = 2
@@ -0,0 +1,8 @@
1
+ """Flash firmware to STM32 microcontrollers over a serial connection."""
2
+
3
+ import logging
4
+
5
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
6
+
7
+ __version_info__ = (1, 0, 0, "dev", 1)
8
+ __version__ = "1.0.0-dev1"