subtask-manager 0.1.0__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 (37) hide show
  1. subtask_manager-0.1.0/.gitattributes +7 -0
  2. subtask_manager-0.1.0/.gitignore +5 -0
  3. subtask_manager-0.1.0/.python-version +1 -0
  4. subtask_manager-0.1.0/Cargo.lock +276 -0
  5. subtask_manager-0.1.0/Cargo.toml +20 -0
  6. subtask_manager-0.1.0/PKG-INFO +11 -0
  7. subtask_manager-0.1.0/README.md +0 -0
  8. subtask_manager-0.1.0/REFACTORING_SUMMARY.md +180 -0
  9. subtask_manager-0.1.0/main.py +44 -0
  10. subtask_manager-0.1.0/pyproject.toml +33 -0
  11. subtask_manager-0.1.0/python/common/enums.py +119 -0
  12. subtask_manager-0.1.0/python/common/models.py +15 -0
  13. subtask_manager-0.1.0/python/file_manager/file_classifier.py +63 -0
  14. subtask_manager-0.1.0/python/file_manager/file_loader.py +17 -0
  15. subtask_manager-0.1.0/python/file_manager/file_scanner.py +31 -0
  16. subtask_manager-0.1.0/python/subtask_manager.py +71 -0
  17. subtask_manager-0.1.0/ruff.toml +77 -0
  18. subtask_manager-0.1.0/src/enums.rs +390 -0
  19. subtask_manager-0.1.0/src/file_classifier.rs +136 -0
  20. subtask_manager-0.1.0/src/file_loader.rs +9 -0
  21. subtask_manager-0.1.0/src/file_scanner.rs +59 -0
  22. subtask_manager-0.1.0/src/lib.rs +348 -0
  23. subtask_manager-0.1.0/src/models.rs +54 -0
  24. subtask_manager-0.1.0/subtask_manager/__init__.py +19 -0
  25. subtask_manager-0.1.0/subtask_manager/_core.pyi +216 -0
  26. subtask_manager-0.1.0/tests/test_data/subtasks/attach_pg_to_duckdb.sql +1 -0
  27. subtask_manager-0.1.0/tests/test_data/subtasks/customers/01_extract/extract_data.sql +2 -0
  28. subtask_manager-0.1.0/tests/test_data/subtasks/transactions/load_transactions.sql +2 -0
  29. subtask_manager-0.1.0/tests/test_data/subtasks/transactions/read_transactions.sql +2 -0
  30. subtask_manager-0.1.0/tests/test_enums.py +61 -0
  31. subtask_manager-0.1.0/tests/test_enums_rs.py +61 -0
  32. subtask_manager-0.1.0/tests/test_file_classifier.py +49 -0
  33. subtask_manager-0.1.0/tests/test_file_classifier_rs.py +47 -0
  34. subtask_manager-0.1.0/tests/test_file_scanner.py +61 -0
  35. subtask_manager-0.1.0/tests/test_file_scanner_rs.py +29 -0
  36. subtask_manager-0.1.0/tests/test_subtask_manager.py +142 -0
  37. subtask_manager-0.1.0/uv.lock +271 -0
@@ -0,0 +1,7 @@
1
+ # .gitattributes
2
+ * text=auto
3
+ *.rs text
4
+ *.js text
5
+ *.html text
6
+ *.css text
7
+ # Add other file types as needed
@@ -0,0 +1,5 @@
1
+ target/
2
+ .venv
3
+ .ruff_cache
4
+ __pycache__
5
+ .env
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,276 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "anyhow"
7
+ version = "1.0.100"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
10
+
11
+ [[package]]
12
+ name = "autocfg"
13
+ version = "1.5.0"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
16
+
17
+ [[package]]
18
+ name = "cfg-if"
19
+ version = "1.0.3"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
22
+
23
+ [[package]]
24
+ name = "heck"
25
+ version = "0.5.0"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
28
+
29
+ [[package]]
30
+ name = "indoc"
31
+ version = "2.0.6"
32
+ source = "registry+https://github.com/rust-lang/crates.io-index"
33
+ checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
34
+
35
+ [[package]]
36
+ name = "libc"
37
+ version = "0.2.176"
38
+ source = "registry+https://github.com/rust-lang/crates.io-index"
39
+ checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
40
+
41
+ [[package]]
42
+ name = "memoffset"
43
+ version = "0.9.1"
44
+ source = "registry+https://github.com/rust-lang/crates.io-index"
45
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
46
+ dependencies = [
47
+ "autocfg",
48
+ ]
49
+
50
+ [[package]]
51
+ name = "once_cell"
52
+ version = "1.21.3"
53
+ source = "registry+https://github.com/rust-lang/crates.io-index"
54
+ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
55
+
56
+ [[package]]
57
+ name = "portable-atomic"
58
+ version = "1.11.1"
59
+ source = "registry+https://github.com/rust-lang/crates.io-index"
60
+ checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
61
+
62
+ [[package]]
63
+ name = "proc-macro2"
64
+ version = "1.0.101"
65
+ source = "registry+https://github.com/rust-lang/crates.io-index"
66
+ checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
67
+ dependencies = [
68
+ "unicode-ident",
69
+ ]
70
+
71
+ [[package]]
72
+ name = "pyo3"
73
+ version = "0.22.6"
74
+ source = "registry+https://github.com/rust-lang/crates.io-index"
75
+ checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
76
+ dependencies = [
77
+ "cfg-if",
78
+ "indoc",
79
+ "libc",
80
+ "memoffset",
81
+ "once_cell",
82
+ "portable-atomic",
83
+ "pyo3-build-config",
84
+ "pyo3-ffi",
85
+ "pyo3-macros",
86
+ "unindent",
87
+ ]
88
+
89
+ [[package]]
90
+ name = "pyo3-build-config"
91
+ version = "0.22.6"
92
+ source = "registry+https://github.com/rust-lang/crates.io-index"
93
+ checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
94
+ dependencies = [
95
+ "once_cell",
96
+ "target-lexicon",
97
+ ]
98
+
99
+ [[package]]
100
+ name = "pyo3-ffi"
101
+ version = "0.22.6"
102
+ source = "registry+https://github.com/rust-lang/crates.io-index"
103
+ checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
104
+ dependencies = [
105
+ "libc",
106
+ "pyo3-build-config",
107
+ ]
108
+
109
+ [[package]]
110
+ name = "pyo3-macros"
111
+ version = "0.22.6"
112
+ source = "registry+https://github.com/rust-lang/crates.io-index"
113
+ checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453"
114
+ dependencies = [
115
+ "proc-macro2",
116
+ "pyo3-macros-backend",
117
+ "quote",
118
+ "syn",
119
+ ]
120
+
121
+ [[package]]
122
+ name = "pyo3-macros-backend"
123
+ version = "0.22.6"
124
+ source = "registry+https://github.com/rust-lang/crates.io-index"
125
+ checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe"
126
+ dependencies = [
127
+ "heck",
128
+ "proc-macro2",
129
+ "pyo3-build-config",
130
+ "quote",
131
+ "syn",
132
+ ]
133
+
134
+ [[package]]
135
+ name = "quote"
136
+ version = "1.0.40"
137
+ source = "registry+https://github.com/rust-lang/crates.io-index"
138
+ checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
139
+ dependencies = [
140
+ "proc-macro2",
141
+ ]
142
+
143
+ [[package]]
144
+ name = "same-file"
145
+ version = "1.0.6"
146
+ source = "registry+https://github.com/rust-lang/crates.io-index"
147
+ checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
148
+ dependencies = [
149
+ "winapi-util",
150
+ ]
151
+
152
+ [[package]]
153
+ name = "serde"
154
+ version = "1.0.228"
155
+ source = "registry+https://github.com/rust-lang/crates.io-index"
156
+ checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
157
+ dependencies = [
158
+ "serde_core",
159
+ "serde_derive",
160
+ ]
161
+
162
+ [[package]]
163
+ name = "serde_core"
164
+ version = "1.0.228"
165
+ source = "registry+https://github.com/rust-lang/crates.io-index"
166
+ checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
167
+ dependencies = [
168
+ "serde_derive",
169
+ ]
170
+
171
+ [[package]]
172
+ name = "serde_derive"
173
+ version = "1.0.228"
174
+ source = "registry+https://github.com/rust-lang/crates.io-index"
175
+ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
176
+ dependencies = [
177
+ "proc-macro2",
178
+ "quote",
179
+ "syn",
180
+ ]
181
+
182
+ [[package]]
183
+ name = "strum"
184
+ version = "0.27.2"
185
+ source = "registry+https://github.com/rust-lang/crates.io-index"
186
+ checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
187
+ dependencies = [
188
+ "strum_macros",
189
+ ]
190
+
191
+ [[package]]
192
+ name = "strum_macros"
193
+ version = "0.27.2"
194
+ source = "registry+https://github.com/rust-lang/crates.io-index"
195
+ checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
196
+ dependencies = [
197
+ "heck",
198
+ "proc-macro2",
199
+ "quote",
200
+ "syn",
201
+ ]
202
+
203
+ [[package]]
204
+ name = "subtask_manager"
205
+ version = "0.1.0"
206
+ dependencies = [
207
+ "anyhow",
208
+ "pyo3",
209
+ "serde",
210
+ "strum",
211
+ "strum_macros",
212
+ "walkdir",
213
+ ]
214
+
215
+ [[package]]
216
+ name = "syn"
217
+ version = "2.0.106"
218
+ source = "registry+https://github.com/rust-lang/crates.io-index"
219
+ checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
220
+ dependencies = [
221
+ "proc-macro2",
222
+ "quote",
223
+ "unicode-ident",
224
+ ]
225
+
226
+ [[package]]
227
+ name = "target-lexicon"
228
+ version = "0.12.16"
229
+ source = "registry+https://github.com/rust-lang/crates.io-index"
230
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
231
+
232
+ [[package]]
233
+ name = "unicode-ident"
234
+ version = "1.0.19"
235
+ source = "registry+https://github.com/rust-lang/crates.io-index"
236
+ checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
237
+
238
+ [[package]]
239
+ name = "unindent"
240
+ version = "0.2.4"
241
+ source = "registry+https://github.com/rust-lang/crates.io-index"
242
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
243
+
244
+ [[package]]
245
+ name = "walkdir"
246
+ version = "2.5.0"
247
+ source = "registry+https://github.com/rust-lang/crates.io-index"
248
+ checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
249
+ dependencies = [
250
+ "same-file",
251
+ "winapi-util",
252
+ ]
253
+
254
+ [[package]]
255
+ name = "winapi-util"
256
+ version = "0.1.11"
257
+ source = "registry+https://github.com/rust-lang/crates.io-index"
258
+ checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
259
+ dependencies = [
260
+ "windows-sys",
261
+ ]
262
+
263
+ [[package]]
264
+ name = "windows-link"
265
+ version = "0.2.0"
266
+ source = "registry+https://github.com/rust-lang/crates.io-index"
267
+ checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
268
+
269
+ [[package]]
270
+ name = "windows-sys"
271
+ version = "0.61.1"
272
+ source = "registry+https://github.com/rust-lang/crates.io-index"
273
+ checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f"
274
+ dependencies = [
275
+ "windows-link",
276
+ ]
@@ -0,0 +1,20 @@
1
+ [package]
2
+ name = "subtask_manager"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ readme = "README.md"
6
+
7
+ [lib]
8
+ name = "_core"
9
+ # "cdylib" is necessary to produce a shared library for Python to import from.
10
+ crate-type = ["cdylib"]
11
+
12
+ [dependencies]
13
+ anyhow = "1.0.100"
14
+ # "extension-module" tells pyo3 we want to build an extension module (skips linking against libpython.so)
15
+ # "abi3-py39" tells pyo3 (and maturin) to build using the stable ABI with minimum Python version 3.9
16
+ pyo3 = { version = "0.22.4", features = ["extension-module", "abi3-py39"] }
17
+ serde = { version = "1.0.228", features = ["derive"] }
18
+ strum = { version = "0.27.2", features = ["derive"] }
19
+ strum_macros = "0.27.2"
20
+ walkdir = "2.5.0"
@@ -0,0 +1,11 @@
1
+ Metadata-Version: 2.4
2
+ Name: subtask-manager
3
+ Version: 0.1.0
4
+ Requires-Dist: pydantic>=2.11.9
5
+ Summary: ETL Subtask management library written in Rust
6
+ Author-email: Din Gior <dingior10@gmail.com>
7
+ License: MIT
8
+ Requires-Python: >=3.11
9
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
10
+
11
+
File without changes
@@ -0,0 +1,180 @@
1
+ # Refactoring Summary: Type-Safe Enum Parameters
2
+
3
+ ## Overview
4
+ Refactored the `get_tasks()` method in `SubtaskManager` to accept enum types (`EtlStage`, `SystemType`, `TaskType`) instead of strings, improving type safety and API usability.
5
+
6
+ ## Changes Made
7
+
8
+ ### Before
9
+ ```python
10
+ # String-based API (error-prone)
11
+ tasks = manager.get_tasks(
12
+ etl_stage="extract", # String - typos caught only at runtime
13
+ system_type="postgres", # String - no IDE autocomplete
14
+ task_type="sql" # String - magic values
15
+ )
16
+ ```
17
+
18
+ ### After
19
+ ```python
20
+ # Enum-based API (type-safe)
21
+ tasks = manager.get_tasks(
22
+ etl_stage=EtlStage.Extract, # Enum - IDE autocomplete
23
+ system_type=SystemType.PostgreSQL, # Enum - compile-time safety
24
+ task_type=TaskType.Sql # Enum - self-documenting
25
+ )
26
+ ```
27
+
28
+ ## Technical Details
29
+
30
+ ### Function Signature Change
31
+
32
+ **Previous signature:**
33
+ ```rust
34
+ fn get_tasks(
35
+ &mut self,
36
+ py: Python,
37
+ etl_stage: Option<String>,
38
+ entity: Option<String>,
39
+ system_type: Option<String>,
40
+ task_type: Option<String>,
41
+ is_common: Option<bool>,
42
+ include_common: Option<bool>,
43
+ ) -> PyResult<Py<PyList>>
44
+ ```
45
+
46
+ **New signature:**
47
+ ```rust
48
+ fn get_tasks(
49
+ &mut self,
50
+ py: Python,
51
+ etl_stage: Option<EtlStage>,
52
+ entity: Option<String>,
53
+ system_type: Option<SystemType>,
54
+ task_type: Option<TaskType>,
55
+ is_common: Option<bool>,
56
+ include_common: Option<bool>,
57
+ ) -> PyResult<Py<PyList>>
58
+ ```
59
+
60
+ ### Code Simplification
61
+
62
+ **Removed conversion logic:**
63
+ ```rust
64
+ // OLD: Had to convert strings to enums
65
+ let input_etl_stage = etl_stage
66
+ .as_ref()
67
+ .and_then(|es| EtlStage::from_alias(es).ok());
68
+
69
+ let input_system_type = system_type
70
+ .as_ref()
71
+ .and_then(|st| SystemType::from_alias(st).ok());
72
+
73
+ let input_task_type = task_type
74
+ .as_ref()
75
+ .and_then(|tt| TaskType::from_extension(tt).ok());
76
+ ```
77
+
78
+ **NEW: Direct enum usage:**
79
+ ```rust
80
+ // NEW: Use enums directly
81
+ if let Some(ref es) = etl_stage {
82
+ if subtask.stage.as_ref() != Some(es) {
83
+ continue;
84
+ }
85
+ }
86
+ ```
87
+
88
+ ## Benefits
89
+
90
+ ### 1. **Type Safety**
91
+ - Compile-time checking prevents invalid values
92
+ - No need to validate string inputs at runtime
93
+ - Eliminates typos and magic strings
94
+
95
+ ### 2. **Better Developer Experience**
96
+ - IDE autocomplete for all enum variants
97
+ - Self-documenting code - clear what values are valid
98
+ - Easier refactoring - renaming enums updates all usages
99
+
100
+ ### 3. **Performance**
101
+ - Eliminates string-to-enum conversion overhead
102
+ - More efficient comparison operations
103
+ - Reduced runtime error handling
104
+
105
+ ### 4. **Cleaner Code**
106
+ - Removed ~15 lines of conversion logic
107
+ - Simplified filtering logic
108
+ - More readable and maintainable
109
+
110
+ ## Migration Guide
111
+
112
+ ### For Python Users
113
+
114
+ **Old usage (still works via `from_alias`):**
115
+ ```python
116
+ # If you have strings from configuration files
117
+ stage_str = "extract"
118
+ stage_enum = EtlStage.from_alias(stage_str)
119
+ tasks = manager.get_tasks(etl_stage=stage_enum)
120
+ ```
121
+
122
+ **Recommended new usage:**
123
+ ```python
124
+ from subtask_manager import SubtaskManager, EtlStage, SystemType, TaskType
125
+
126
+ manager = SubtaskManager("./tasks")
127
+
128
+ # Direct enum usage
129
+ tasks = manager.get_tasks(
130
+ etl_stage=EtlStage.Extract,
131
+ system_type=SystemType.PostgreSQL,
132
+ task_type=TaskType.Sql
133
+ )
134
+ ```
135
+
136
+ ### Enum Properties Available
137
+
138
+ All enums expose these properties:
139
+ - `.name` - Human-readable name
140
+ - `.id` - Numeric identifier
141
+ - `.aliases` (EtlStage, SystemType) - List of valid aliases
142
+ - `.extensions` (TaskType) - List of file extensions
143
+
144
+ Static methods:
145
+ - `EtlStage.from_alias(str)` - Convert alias to enum
146
+ - `SystemType.from_alias(str)` - Convert alias to enum
147
+ - `TaskType.from_extension(str)` - Convert extension to enum
148
+
149
+ ## Examples
150
+
151
+ See `example_enum_usage.py` for comprehensive examples including:
152
+ - Basic filtering by enum
153
+ - Combining multiple filters
154
+ - Using enum properties
155
+ - Converting strings to enums when needed
156
+
157
+ ## Backward Compatibility
158
+
159
+ This is a **breaking change** for Python users who were passing strings directly to `get_tasks()`.
160
+
161
+ To maintain compatibility with existing code, consider:
162
+ 1. Using `from_alias()` to convert strings to enums
163
+ 2. Updating all call sites to use enum types
164
+ 3. Creating wrapper functions if needed
165
+
166
+ ## Testing
167
+
168
+ Verified compilation with:
169
+ ```bash
170
+ cargo check
171
+ ```
172
+
173
+ All type checks pass successfully.
174
+
175
+ ## Future Improvements
176
+
177
+ Consider similar refactoring for:
178
+ - Other methods that accept string parameters
179
+ - Configuration file parsing to return enums
180
+ - Validation helpers that work with enums
@@ -0,0 +1,44 @@
1
+ from pathlib import Path
2
+
3
+ from subtask_manager import (
4
+ EtlStage,
5
+ FileClassifier,
6
+ FileScanner,
7
+ Subtask,
8
+ SubtaskManager,
9
+ SystemType,
10
+ TaskType,
11
+ )
12
+
13
+ sm: SubtaskManager = SubtaskManager(
14
+ base_path="tests/test_data/subtasks",
15
+ )
16
+ for subtask in sm.subtasks:
17
+ print(subtask.entity)
18
+
19
+ print(EtlStage.Postprocessing.aliases)
20
+
21
+ print(SystemType.PostgreSQL.aliases)
22
+ print(SystemType.PostgreSQL.id)
23
+ print(EtlStage.Cleanup.id)
24
+
25
+ print(SystemType.from_alias("pg") == SystemType.PostgreSQL)
26
+ print(type(SystemType.from_alias("pg")))
27
+ print(type(SystemType.PostgreSQL))
28
+
29
+ print(TaskType.Graphql.extensions)
30
+
31
+ fs = FileScanner(["py"])
32
+ print(fs.extensions)
33
+
34
+
35
+ # Using string path
36
+ manager1 = SubtaskManager("tests/test_data/subtasks")
37
+ print(manager1.base_path)
38
+
39
+ # Using pathlib.Path
40
+ manager2 = SubtaskManager(Path("tests/test_data/subtasks"))
41
+ print(manager2.base_path)
42
+
43
+ fcs = FileClassifier(Path("tests/test_data/subtasks"))
44
+ print(fcs.base_path)
@@ -0,0 +1,33 @@
1
+ [project]
2
+ name = "subtask-manager"
3
+ version = "0.1.0"
4
+ description = "ETL Subtask management library written in Rust"
5
+ readme = "README.md"
6
+ license = { text = "MIT" }
7
+ authors = [
8
+ { name = "Din Gior", email = "dingior10@gmail.com" }
9
+ ]
10
+ requires-python = ">=3.11"
11
+ dependencies = [
12
+ "pydantic>=2.11.9",
13
+ ]
14
+
15
+ [project.scripts]
16
+ subtask-manager = "subtask_manager:main"
17
+
18
+ [tool.maturin]
19
+ module-name = "subtask_manager._core"
20
+ python-packages = ["subtask_manager"]
21
+ python-source = ""
22
+
23
+ [build-system]
24
+ requires = ["maturin>=1.0,<2.0"]
25
+ build-backend = "maturin"
26
+
27
+ [dependency-groups]
28
+ dev = [
29
+ "maturin>=1.9.5",
30
+ "pyo3-stubgen>=0.3.0",
31
+ "pytest>=8.4.2",
32
+ "ruff>=0.13.2",
33
+ ]