nano-dev-utils 1.6.2__tar.gz → 1.7.1__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 (50) hide show
  1. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/.gitignore +3 -1
  2. nano_dev_utils-1.7.1/.idea/nano_dev_utils.iml +11 -0
  3. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/.idea/workspace.xml +133 -145
  4. nano_dev_utils-1.7.1/PKG-INFO +180 -0
  5. nano_dev_utils-1.7.1/README.md +164 -0
  6. nano_dev_utils-1.7.1/ftd.txt +2126 -0
  7. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/pyproject.toml +4 -3
  8. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/src/nano_dev_utils/__init__.py +0 -5
  9. nano_dev_utils-1.7.1/src/nano_dev_utils/__version__.py +1 -0
  10. nano_dev_utils-1.7.1/src/nano_dev_utils/_constants.py +1 -0
  11. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/src/nano_dev_utils/common.py +14 -12
  12. nano_dev_utils-1.7.1/src_filetree.txt +16 -0
  13. nano_dev_utils-1.7.1/tests_filetree.txt +30 -0
  14. nano_dev_utils-1.7.1/tree.txt +102 -0
  15. nano_dev_utils-1.7.1/uv.lock +838 -0
  16. nano_dev_utils-1.6.2/.idea/nano_dev_utils.iml +0 -10
  17. nano_dev_utils-1.6.2/PKG-INFO +0 -372
  18. nano_dev_utils-1.6.2/README.md +0 -356
  19. nano_dev_utils-1.6.2/benchmark/benchtest.py +0 -52
  20. nano_dev_utils-1.6.2/benchmark/benchtest_bkp.py +0 -91
  21. nano_dev_utils-1.6.2/benchmark/win_tree_wrapper.py +0 -52
  22. nano_dev_utils-1.6.2/src/nano_dev_utils/__main__.py +0 -129
  23. nano_dev_utils-1.6.2/src/nano_dev_utils/__version__.py +0 -1
  24. nano_dev_utils-1.6.2/src/nano_dev_utils/_constants.py +0 -2
  25. nano_dev_utils-1.6.2/src/nano_dev_utils/file_tree_display.py +0 -325
  26. nano_dev_utils-1.6.2/tests/test_file_tree_display.py +0 -256
  27. nano_dev_utils-1.6.2/tests/test_timers/__init__.py +0 -3
  28. nano_dev_utils-1.6.2/update_package.py +0 -19
  29. nano_dev_utils-1.6.2/uv.lock +0 -241
  30. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/.idea/.gitignore +0 -0
  31. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/.idea/encodings.xml +0 -0
  32. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
  33. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/.idea/misc.xml +0 -0
  34. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/.idea/modules.xml +0 -0
  35. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/.idea/vcs.xml +0 -0
  36. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/.pre-commit-config.yaml +0 -0
  37. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/LICENSE +0 -0
  38. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/ruff.toml +0 -0
  39. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/src/nano_dev_utils/dynamic_importer.py +0 -0
  40. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/src/nano_dev_utils/release_ports.py +0 -0
  41. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/src/nano_dev_utils/timers.py +0 -0
  42. {nano_dev_utils-1.6.2/benchmark → nano_dev_utils-1.7.1/tests}/__init__.py +0 -0
  43. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/tests/test_common.py +0 -0
  44. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/tests/test_dynamic_importer.py +0 -0
  45. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/tests/test_release_ports.py +0 -0
  46. {nano_dev_utils-1.6.2/tests → nano_dev_utils-1.7.1/tests/test_timers}/__init__.py +0 -0
  47. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/tests/test_timers/conftest.py +0 -0
  48. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/tests/test_timers/test_duration_formatter.py +0 -0
  49. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/tests/test_timers/test_timer.py +0 -0
  50. {nano_dev_utils-1.6.2 → nano_dev_utils-1.7.1}/tests/test_timers/test_timers_async.py +0 -0
@@ -174,4 +174,6 @@ cython_debug/
174
174
  .pypirc
175
175
 
176
176
  /src/*/debug.py
177
- /src/*/*.log
177
+ /src/*/*.log
178
+
179
+ update_package.py
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module external.system.id="pyproject.toml" type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <sourceFolder url="file://$MODULE_DIR$/src" />
6
+ <excludeFolder url="file://$MODULE_DIR$/.venv" />
7
+ </content>
8
+ <orderEntry type="jdk" jdkName="C:\GitHubWS\nano_dev_utils\.venv" jdkType="Python SDK" />
9
+ <orderEntry type="sourceFolder" forTests="false" />
10
+ </component>
11
+ </module>
@@ -4,10 +4,7 @@
4
4
  <option name="autoReloadType" value="SELECTIVE" />
5
5
  </component>
6
6
  <component name="ChangeListManager">
7
- <list default="true" id="1859e23b-7665-4b92-98cc-65e07a208923" name="Changes" comment="versioning updates;&#10;load_cfg_file minor update;&#10;v1.6.1">
8
- <change beforePath="$PROJECT_DIR$/src/nano_dev_utils/__main__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/nano_dev_utils/__main__.py" afterDir="false" />
9
- <change beforePath="$PROJECT_DIR$/src/nano_dev_utils/__version__.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/nano_dev_utils/__version__.py" afterDir="false" />
10
- </list>
7
+ <list default="true" id="1859e23b-7665-4b92-98cc-65e07a208923" name="Changes" comment="bumped minor" />
11
8
  <option name="SHOW_DIALOG" value="false" />
12
9
  <option name="HIGHLIGHT_CONFLICTS" value="true" />
13
10
  <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@@ -24,7 +21,7 @@
24
21
  <option name="PUSH_AUTO_UPDATE" value="true" />
25
22
  <option name="RECENT_BRANCH_BY_REPOSITORY">
26
23
  <map>
27
- <entry key="$PROJECT_DIR$" value="FI-CLI" />
24
+ <entry key="$PROJECT_DIR$" value="master" />
28
25
  </map>
29
26
  </option>
30
27
  <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@@ -40,32 +37,36 @@
40
37
  <option name="showLibraryContents" value="true" />
41
38
  <option name="showMembers" value="true" />
42
39
  </component>
43
- <component name="PropertiesComponent">{
44
- &quot;keyToString&quot;: {
45
- &quot;Python tests.Python tests in test_dynamic_importer.py.executor&quot;: &quot;Run&quot;,
46
- &quot;Python tests.Python tests in test_file_tree_display.py.executor&quot;: &quot;Run&quot;,
47
- &quot;Python tests.Python tests in test_release_ports.py.executor&quot;: &quot;Run&quot;,
48
- &quot;Python tests.Python tests in test_timer.py.executor&quot;: &quot;Run&quot;,
49
- &quot;Python tests.Python tests in test_timers (1).executor&quot;: &quot;Run&quot;,
50
- &quot;Python tests.Python tests in test_timers.executor&quot;: &quot;Run&quot;,
51
- &quot;Python tests.Python tests in test_timers_async.py.executor&quot;: &quot;Run&quot;,
52
- &quot;Python tests.Python tests in testing_duration_formatter.py.executor&quot;: &quot;Run&quot;,
53
- &quot;Python tests.Python tests in tests.executor&quot;: &quot;Run&quot;,
54
- &quot;Python tests.test_timer prev.executor&quot;: &quot;Run&quot;,
55
- &quot;Python.__main__.executor&quot;: &quot;Debug&quot;,
56
- &quot;Python.benchtest.executor&quot;: &quot;Run&quot;,
57
- &quot;Python.benchtest_bkp.executor&quot;: &quot;Run&quot;,
58
- &quot;Python.ftd_main.executor&quot;: &quot;Run&quot;,
59
- &quot;Python.test_timer.executor&quot;: &quot;Run&quot;,
60
- &quot;Python.update_package.executor&quot;: &quot;Run&quot;,
61
- &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
62
- &quot;git-widget-placeholder&quot;: &quot;master&quot;,
63
- &quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;,
64
- &quot;last_opened_file_path&quot;: &quot;C:/GitHubWS/nano_dev_utils/src&quot;,
65
- &quot;settings.editor.selected.configurable&quot;: &quot;com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable&quot;,
66
- &quot;two.files.diff.last.used.file&quot;: &quot;C:/Workspaces/review1/tools/file_tree_display/tests/test_file_tree_display.py&quot;
40
+ <component name="PropertiesComponent"><![CDATA[{
41
+ "keyToString": {
42
+ "Python tests.Python tests in test_dynamic_importer.py.executor": "Run",
43
+ "Python tests.Python tests in test_file_tree_display.py.executor": "Run",
44
+ "Python tests.Python tests in test_release_ports.py.executor": "Run",
45
+ "Python tests.Python tests in test_timer.py.executor": "Run",
46
+ "Python tests.Python tests in test_timers (1).executor": "Run",
47
+ "Python tests.Python tests in test_timers.executor": "Run",
48
+ "Python tests.Python tests in test_timers_async.py.executor": "Run",
49
+ "Python tests.Python tests in testing_duration_formatter.py.executor": "Run",
50
+ "Python tests.Python tests in tests.executor": "Run",
51
+ "Python tests.test_timer prev.executor": "Run",
52
+ "Python.__main__.executor": "Debug",
53
+ "Python.benchtest.executor": "Run",
54
+ "Python.benchtest_bkp.executor": "Run",
55
+ "Python.ftd_main.executor": "Run",
56
+ "Python.test_timer.executor": "Run",
57
+ "Python.update_package.executor": "Run",
58
+ "RunOnceActivity.ShowReadmeOnStart": "true",
59
+ "RunOnceActivity.typescript.service.memoryLimit.init": "true",
60
+ "codeWithMe.voiceChat.enabledByDefault": "false",
61
+ "git-widget-placeholder": "yd__caseBugFix",
62
+ "ignore.virus.scanning.warn.message": "true",
63
+ "last_opened_file_path": "C:/GitHubWS/nano_dev_utils",
64
+ "nodejs_package_manager_path": "npm",
65
+ "python.packages.toolwindow.project.migrated.to.right.top.v2": "true",
66
+ "settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable",
67
+ "two.files.diff.last.used.file": "C:/Workspaces/review1/tools/file_tree_display/tests/test_file_tree_display.py"
67
68
  }
68
- }</component>
69
+ }]]></component>
69
70
  <component name="RecentsManager">
70
71
  <key name="CopyFile.RECENT_KEYS">
71
72
  <recent name="C:\GitHubWS\nano_dev_utils\src" />
@@ -81,7 +82,7 @@
81
82
  <recent name="C:\GitHubWS\nano_dev_utils\tests" />
82
83
  </key>
83
84
  </component>
84
- <component name="RunManager" selected="Python.benchtest_bkp">
85
+ <component name="RunManager" selected="Python.update_package">
85
86
  <configuration name="benchtest_bkp" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
86
87
  <module name="nano_dev_utils" />
87
88
  <option name="ENV_FILES" value="" />
@@ -95,6 +96,9 @@
95
96
  <option name="IS_MODULE_SDK" value="true" />
96
97
  <option name="ADD_CONTENT_ROOTS" value="true" />
97
98
  <option name="ADD_SOURCE_ROOTS" value="true" />
99
+ <option name="DEBUG_JUST_MY_CODE" value="true" />
100
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
101
+ <option name="RUN_TOOL" value="" />
98
102
  <option name="SCRIPT_NAME" value="$PROJECT_DIR$/benchmark/benchtest_bkp.py" />
99
103
  <option name="PARAMETERS" value="" />
100
104
  <option name="SHOW_COMMAND_LINE" value="false" />
@@ -117,6 +121,9 @@
117
121
  <option name="IS_MODULE_SDK" value="true" />
118
122
  <option name="ADD_CONTENT_ROOTS" value="true" />
119
123
  <option name="ADD_SOURCE_ROOTS" value="true" />
124
+ <option name="DEBUG_JUST_MY_CODE" value="true" />
125
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
126
+ <option name="RUN_TOOL" value="" />
120
127
  <option name="SCRIPT_NAME" value="$PROJECT_DIR$/update_package.py" />
121
128
  <option name="PARAMETERS" value="" />
122
129
  <option name="SHOW_COMMAND_LINE" value="false" />
@@ -126,21 +133,6 @@
126
133
  <option name="INPUT_FILE" value="" />
127
134
  <method v="2" />
128
135
  </configuration>
129
- <configuration name="Python tests in test_file_tree_display.py" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
130
- <module name="nano_dev_utils" />
131
- <option name="ENV_FILES" value="" />
132
- <option name="INTERPRETER_OPTIONS" value="" />
133
- <option name="PARENT_ENVS" value="true" />
134
- <option name="SDK_HOME" value="" />
135
- <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/tests" />
136
- <option name="IS_MODULE_SDK" value="true" />
137
- <option name="ADD_CONTENT_ROOTS" value="true" />
138
- <option name="ADD_SOURCE_ROOTS" value="true" />
139
- <option name="_new_additionalArguments" value="&quot;&quot;" />
140
- <option name="_new_target" value="&quot;$PROJECT_DIR$/tests/test_file_tree_display.py&quot;" />
141
- <option name="_new_targetType" value="&quot;PATH&quot;" />
142
- <method v="2" />
143
- </configuration>
144
136
  <configuration name="Python tests in tests" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
145
137
  <module name="nano_dev_utils" />
146
138
  <option name="ENV_FILES" value="" />
@@ -151,6 +143,9 @@
151
143
  <option name="IS_MODULE_SDK" value="true" />
152
144
  <option name="ADD_CONTENT_ROOTS" value="true" />
153
145
  <option name="ADD_SOURCE_ROOTS" value="true" />
146
+ <option name="DEBUG_JUST_MY_CODE" value="true" />
147
+ <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
148
+ <option name="RUN_TOOL" value="true" />
154
149
  <option name="_new_additionalArguments" value="&quot;&quot;" />
155
150
  <option name="_new_target" value="&quot;$PROJECT_DIR$/tests&quot;" />
156
151
  <option name="_new_targetType" value="&quot;PATH&quot;" />
@@ -159,7 +154,6 @@
159
154
  <list>
160
155
  <item itemvalue="Python.update_package" />
161
156
  <item itemvalue="Python.benchtest_bkp" />
162
- <item itemvalue="Python tests.Python tests in test_file_tree_display.py" />
163
157
  <item itemvalue="Python tests.Python tests in tests" />
164
158
  </list>
165
159
  <recent_temporary>
@@ -167,14 +161,13 @@
167
161
  <item itemvalue="Python.update_package" />
168
162
  <item itemvalue="Python tests.Python tests in tests" />
169
163
  <item itemvalue="Python.benchtest_bkp" />
170
- <item itemvalue="Python tests.Python tests in test_file_tree_display.py" />
171
164
  </list>
172
165
  </recent_temporary>
173
166
  </component>
174
167
  <component name="SharedIndexes">
175
168
  <attachedChunks>
176
169
  <set>
177
- <option value="bundled-python-sdk-5b207ade9991-746f403e7f0c-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-241.17890.14" />
170
+ <option value="bundled-python-sdk-73a66231627c-5bd6d13a2a75-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-262.10968.92" />
178
171
  </set>
179
172
  </attachedChunks>
180
173
  </component>
@@ -186,78 +179,7 @@
186
179
  <option name="number" value="Default" />
187
180
  <option name="presentableId" value="Default" />
188
181
  <updated>1746126505743</updated>
189
- </task>
190
- <task id="LOCAL-00098" summary="Readme updates">
191
- <option name="closed" value="true" />
192
- <created>1762078800875</created>
193
- <option name="number" value="00098" />
194
- <option name="presentableId" value="LOCAL-00098" />
195
- <option name="project" value="LOCAL" />
196
- <updated>1762078800875</updated>
197
- </task>
198
- <task id="LOCAL-00099" summary="+res_formatter, a wrapper for the private static _duration_formatter.">
199
- <option name="closed" value="true" />
200
- <created>1762081915651</created>
201
- <option name="number" value="00099" />
202
- <option name="presentableId" value="LOCAL-00099" />
203
- <option name="project" value="LOCAL" />
204
- <updated>1762081915651</updated>
205
- </task>
206
- <task id="LOCAL-00100" summary="Timer: +printout option">
207
- <option name="closed" value="true" />
208
- <created>1762081953468</created>
209
- <option name="number" value="00100" />
210
- <option name="presentableId" value="LOCAL-00100" />
211
- <option name="project" value="LOCAL" />
212
- <updated>1762081953468</updated>
213
- </task>
214
- <task id="LOCAL-00101" summary="+printout testing (WIP)">
215
- <option name="closed" value="true" />
216
- <created>1762084839210</created>
217
- <option name="number" value="00101" />
218
- <option name="presentableId" value="LOCAL-00101" />
219
- <option name="project" value="LOCAL" />
220
- <updated>1762084839210</updated>
221
- </task>
222
- <task id="LOCAL-00102" summary="Pyright corrections;&#10;Timer unit tests - improved code">
223
- <option name="closed" value="true" />
224
- <created>1762093068383</created>
225
- <option name="number" value="00102" />
226
- <option name="presentableId" value="LOCAL-00102" />
227
- <option name="project" value="LOCAL" />
228
- <updated>1762093068383</updated>
229
- </task>
230
- <task id="LOCAL-00103" summary="Allow an optional printout to console in addition to logger.&#10;README updates in this regard.&#10;&#10;Bumped minor to v1.4.1">
231
- <option name="closed" value="true" />
232
- <created>1762093698362</created>
233
- <option name="number" value="00103" />
234
- <option name="presentableId" value="LOCAL-00103" />
235
- <option name="project" value="LOCAL" />
236
- <updated>1762093698362</updated>
237
- </task>
238
- <task id="LOCAL-00104" summary="+blank space before time unit&#10;&#10;Bumped minor to v1.4.2">
239
- <option name="closed" value="true" />
240
- <created>1762096472993</created>
241
- <option name="number" value="00104" />
242
- <option name="presentableId" value="LOCAL-00104" />
243
- <option name="project" value="LOCAL" />
244
- <updated>1762096472993</updated>
245
- </task>
246
- <task id="LOCAL-00105" summary="+link to PYPI package&#10;Benchmark data, Tree(a built-in windows utility) vs my FTD">
247
- <option name="closed" value="true" />
248
- <created>1762135842965</created>
249
- <option name="number" value="00105" />
250
- <option name="presentableId" value="LOCAL-00105" />
251
- <option name="project" value="LOCAL" />
252
- <updated>1762135842965</updated>
253
- </task>
254
- <task id="LOCAL-00106" summary="applying precision upon request">
255
- <option name="closed" value="true" />
256
- <created>1762136721863</created>
257
- <option name="number" value="00106" />
258
- <option name="presentableId" value="LOCAL-00106" />
259
- <option name="project" value="LOCAL" />
260
- <updated>1762136721863</updated>
182
+ <workItem from="1792508470918" duration="2158000" />
261
183
  </task>
262
184
  <task id="LOCAL-00107" summary="timers refactor">
263
185
  <option name="closed" value="true" />
@@ -579,9 +501,84 @@
579
501
  <option name="project" value="LOCAL" />
580
502
  <updated>1762712425856</updated>
581
503
  </task>
582
- <option name="localTasksCounter" value="147" />
504
+ <task id="LOCAL-00147" summary="minor bugfix (cfg); &#10;Bumped minor version&#10;v1.6.2">
505
+ <option name="closed" value="true" />
506
+ <created>1762716808091</created>
507
+ <option name="number" value="00147" />
508
+ <option name="presentableId" value="LOCAL-00147" />
509
+ <option name="project" value="LOCAL" />
510
+ <updated>1762716808091</updated>
511
+ </task>
512
+ <task id="LOCAL-00148" summary="removing ftd since it has its own package.">
513
+ <option name="closed" value="true" />
514
+ <created>1762853900126</created>
515
+ <option name="number" value="00148" />
516
+ <option name="presentableId" value="LOCAL-00148" />
517
+ <option name="project" value="LOCAL" />
518
+ <updated>1762853900126</updated>
519
+ </task>
520
+ <task id="LOCAL-00149" summary="removing benchtest (only related to ftd)">
521
+ <option name="closed" value="true" />
522
+ <created>1762853964111</created>
523
+ <option name="number" value="00149" />
524
+ <option name="presentableId" value="LOCAL-00149" />
525
+ <option name="project" value="LOCAL" />
526
+ <updated>1762853964111</updated>
527
+ </task>
528
+ <task id="LOCAL-00150" summary=".">
529
+ <option name="closed" value="true" />
530
+ <created>1762854113345</created>
531
+ <option name="number" value="00150" />
532
+ <option name="presentableId" value="LOCAL-00150" />
533
+ <option name="project" value="LOCAL" />
534
+ <updated>1762854113345</updated>
535
+ </task>
536
+ <task id="LOCAL-00151" summary="case sensitivity bugfix">
537
+ <option name="closed" value="true" />
538
+ <created>1792509006160</created>
539
+ <option name="number" value="00151" />
540
+ <option name="presentableId" value="LOCAL-00151" />
541
+ <option name="project" value="LOCAL" />
542
+ <updated>1792509006161</updated>
543
+ </task>
544
+ <task id="LOCAL-00152" summary="build_predicate: improve signature matching for type checker; adding an explicit fallback">
545
+ <option name="closed" value="true" />
546
+ <created>1792509795158</created>
547
+ <option name="number" value="00152" />
548
+ <option name="presentableId" value="LOCAL-00152" />
549
+ <option name="project" value="LOCAL" />
550
+ <updated>1792509795158</updated>
551
+ </task>
552
+ <task id="LOCAL-00153" summary="update: improved error message">
553
+ <option name="closed" value="true" />
554
+ <created>1792509982461</created>
555
+ <option name="number" value="00153" />
556
+ <option name="presentableId" value="LOCAL-00153" />
557
+ <option name="project" value="LOCAL" />
558
+ <updated>1792509982461</updated>
559
+ </task>
560
+ <task id="LOCAL-00154" summary="update: improved error message">
561
+ <option name="closed" value="true" />
562
+ <created>1792510231518</created>
563
+ <option name="number" value="00154" />
564
+ <option name="presentableId" value="LOCAL-00154" />
565
+ <option name="project" value="LOCAL" />
566
+ <updated>1792510231518</updated>
567
+ </task>
568
+ <task id="LOCAL-00155" summary="bumped minor">
569
+ <option name="closed" value="true" />
570
+ <created>1792510400660</created>
571
+ <option name="number" value="00155" />
572
+ <option name="presentableId" value="LOCAL-00155" />
573
+ <option name="project" value="LOCAL" />
574
+ <updated>1792510400660</updated>
575
+ </task>
576
+ <option name="localTasksCounter" value="156" />
583
577
  <servers />
584
578
  </component>
579
+ <component name="TypeScriptGeneratedFilesManager">
580
+ <option name="version" value="3" />
581
+ </component>
585
582
  <component name="Vcs.Log.Tabs.Properties">
586
583
  <option name="RECENT_FILTERS">
587
584
  <map>
@@ -617,33 +614,13 @@
617
614
  <map>
618
615
  <entry key="MAIN">
619
616
  <value>
620
- <State>
621
- <option name="FILTERS">
622
- <map>
623
- <entry key="branch">
624
- <value>
625
- <list>
626
- <option value="origin/master" />
627
- </list>
628
- </value>
629
- </entry>
630
- </map>
631
- </option>
632
- </State>
617
+ <State />
633
618
  </value>
634
619
  </entry>
635
620
  </map>
636
621
  </option>
637
622
  </component>
638
623
  <component name="VcsManagerConfiguration">
639
- <MESSAGE value="upgrading connector style (WIP)" />
640
- <MESSAGE value="optimizing performance:&#10;-reduced alloc &amp; overhead;&#10;-precomputed style dict and sorting outside the recursive _build_tree;&#10;-improved string ops:&#10;used StringIO for better memory efficiency&#10;-improved traversal&#10;&#10;Unit tests updates" />
641
- <MESSAGE value="-removing single char old style fallback &#10;+ unit test for custom styles dynamically added by user" />
642
- <MESSAGE value="README updates related to FTD" />
643
- <MESSAGE value="bugfix! simultaneously enabling printout and save2file is now possible" />
644
- <MESSAGE value="README update regarding custom connector style" />
645
- <MESSAGE value="reminder" />
646
- <MESSAGE value="bumped to v1.5.0" />
647
624
  <MESSAGE value="typo (+CRLF)" />
648
625
  <MESSAGE value="Ruff &amp; Pyright updates" />
649
626
  <MESSAGE value="v1.5.1" />
@@ -655,12 +632,23 @@
655
632
  <MESSAGE value="precommit update" />
656
633
  <MESSAGE value="minor updates" />
657
634
  <MESSAGE value="minor updates:&#10;benchtest-removed old style&#10;FTD: +skip_sorting&#10;README: FTD doc updates" />
658
- <MESSAGE value="." />
659
635
  <MESSAGE value="+load_cfg_file: loading configuration from a JSON file (e.g. for CLI version)." />
660
636
  <MESSAGE value="ftd: +get_num_of_entries (total number of scanned files and folders)" />
661
637
  <MESSAGE value="+ftd cli version" />
662
638
  <MESSAGE value="pyproject.toml: &#10;dynamic version; &#10;ftd cli shortcut;&#10;hatch.version path according to __version__ &#10;v1.6.0" />
663
639
  <MESSAGE value="versioning updates;&#10;load_cfg_file minor update;&#10;v1.6.1" />
664
- <option name="LAST_COMMIT_MESSAGE" value="versioning updates;&#10;load_cfg_file minor update;&#10;v1.6.1" />
640
+ <MESSAGE value="minor bugfix (cfg); &#10;Bumped minor version&#10;v1.6.2" />
641
+ <MESSAGE value="removing ftd since it has its own package." />
642
+ <MESSAGE value="removing benchtest (only related to ftd)" />
643
+ <MESSAGE value="." />
644
+ <MESSAGE value="case sensitivity bugfix" />
645
+ <MESSAGE value="build_predicate: improve signature matching for type checker; adding an explicit fallback" />
646
+ <MESSAGE value="fixed warning" />
647
+ <MESSAGE value="fixed warning" />
648
+ <MESSAGE value="bumped minor" />
649
+ <option name="LAST_COMMIT_MESSAGE" value="bumped minor" />
650
+ </component>
651
+ <component name="com.intellij.coverage.CoverageDataManagerImpl">
652
+ <SUITE FILE_PATH="coverage/nano_dev_utils$.coverage" NAME=" Coverage Results" MODIFIED="1792509575145" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/tests" />
665
653
  </component>
666
654
  </project>
@@ -0,0 +1,180 @@
1
+ Metadata-Version: 2.5
2
+ Name: nano_dev_utils
3
+ Version: 1.7.1
4
+ Summary: A collection of small Python utilities for developers.
5
+ Project-URL: Homepage, https://github.com/yaronday/nano_utils
6
+ Project-URL: Issues, https://github.com/yaronday/nano_utils/issues
7
+ Project-URL: license, https://github.com/yaronday/nano_dev_utils/blob/master/LICENSE
8
+ Author-email: Yaron Dayan <yaronday77@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Python: >=3.10
14
+ Requires-Dist: build>=1.3.0
15
+ Description-Content-Type: text/markdown
16
+
17
+ # nano_dev_utils
18
+
19
+ A collection of small Python utilities for developers.
20
+ [PYPI package: nano-dev-utils](https://pypi.org/project/nano-dev-utils)
21
+
22
+ ## Modules
23
+
24
+ ### `timers.py`
25
+
26
+ This module provides a `Timer` class for measuring the execution time of code blocks and functions with additional features like timeout control and multi-iteration averaging.
27
+
28
+ #### `Timer` Class
29
+
30
+ * **`__init__(self, precision: int = 4, verbose: bool = False, printout: bool = False)`**: Initializes a `Timer` instance.
31
+ * `precision`: The number of decimal places to record and display time durations. Defaults to 4.
32
+ * `verbose`: Optionally displays the function's positional arguments (args) and keyword arguments (kwargs). Defaults to `False`.
33
+ * `printout`: Allows printing to console.
34
+
35
+ * **`def timeit(
36
+ self,
37
+ iterations: int = 1,
38
+ timeout: float | None = None,
39
+ per_iteration: bool = False,
40
+ ) -> Callable[[Callable[P, Any]], Callable[P, Any]]:`**:
41
+ Decorator that times either **sync** or **async** function execution with advanced features:
42
+ * `iterations`: Number of times to run the function (for averaging). Defaults to 1.
43
+ * `timeout`: Maximum allowed execution time in seconds. When exceeded:
44
+ * Raises `TimeoutError` immediately
45
+ * **Warning:** The function execution will be aborted mid-operation
46
+ * No return value will be available if timeout occurs
47
+ * `per_iteration`: If True, applies timeout check to each iteration; otherwise checks total time across all iterations.
48
+ * Features:
49
+ * Records execution times
50
+ * Handles timeout conditions
51
+ * Calculates average execution time across iterations
52
+ * Logs the function name and execution time (with optional arguments)
53
+ * Returns the result of the original function (unless timeout occurs)
54
+
55
+ #### Example Usage:
56
+
57
+ ```python
58
+ import time
59
+ import logging
60
+ from nano_dev_utils import timer
61
+
62
+ # if printout is not enabled, a logger must be configured in order to see timing results
63
+ logging.basicConfig(filename='timer example.log',
64
+ level=logging.INFO, # DEBUG, WARNING, ERROR, CRITICAL
65
+ format='%(asctime)s - %(levelname)s: %(message)s',
66
+ datefmt='%d-%m-%Y %H:%M:%S')
67
+
68
+ # Basic timing
69
+ @timer.timeit()
70
+ def my_function(a, b=10):
71
+ """A sample function."""
72
+ time.sleep(0.1)
73
+ return a + b
74
+
75
+ timer.init(precision=6, verbose=True)
76
+ '''Alternative options:
77
+ timer.update({'precision': 6, 'verbose': True}) # 1. Using update method
78
+
79
+ from nano_dev_utils.timers import Timer # 2. explicit instantiation
80
+ timer = Timer(precision=6, verbose=True)
81
+ '''
82
+
83
+ timer.update({'printout': True}) # allow printing to console
84
+
85
+ # Advanced usage with timeout and iterations
86
+ @timer.timeit(iterations=5, timeout=0.5, per_iteration=True)
87
+ def critical_function(x):
88
+ """Function with timeout check per iteration."""
89
+ time.sleep(0.08)
90
+ return x * 2
91
+
92
+ result1 = my_function(5, b=20) # Shows args/kwargs and timing
93
+ result2 = critical_function(10) # Runs 5 times with per-iteration timeout
94
+ ```
95
+
96
+ ### `dynamic_importer.py`
97
+
98
+ This module provides an `Importer` class for lazy loading and caching module imports.
99
+
100
+ #### `Importer` Class
101
+
102
+ * **`__init__(self)`**: Initializes an `Importer` instance with an empty dictionary `imported_modules` to cache imported modules.
103
+
104
+ * **`import_mod_from_lib(self, library: str, module_name: str) -> ModuleType | Any`**: Lazily imports a module from a specified library and caches it.
105
+ * `library` (str): The name of the library (e.g., "os", "requests").
106
+ * `module_name` (str): The name of the module to import within the library (e.g., "path", "get").
107
+ * Returns the imported module. If the module has already been imported, it returns a cached instance.
108
+ * Raises `ImportError` if the module cannot be found.
109
+
110
+ #### Example Usage:
111
+
112
+ ```python
113
+ from nano_dev_utils import importer
114
+
115
+ os_path = importer.import_mod_from_lib("os", "path")
116
+ print(f"Imported os.path: {os_path}")
117
+
118
+ requests_get = importer.import_mod_from_lib("requests", "get")
119
+ print(f"Imported requests.get: {requests_get}")
120
+
121
+ # Subsequent calls will return the cached module
122
+ os_path_again = importer.import_mod_from_lib("os", "path")
123
+ print(f"Imported os.path again (cached): {os_path_again}")
124
+ ```
125
+
126
+ ### `release_ports.py`
127
+
128
+ This module provides a `PortsRelease` class to identify and release processes
129
+ listening on specified TCP ports.
130
+ It supports Windows, Linux, and macOS.
131
+
132
+ #### `PortsRelease` Class
133
+
134
+ * **`__init__(self, default_ports: list[int] | None = None)`**:
135
+ * Initializes a `PortsRelease` instance.
136
+ * `default_ports`: A list of default ports to manage. If not provided, it defaults to `[6277, 6274]`.
137
+
138
+ * **`get_pid_by_port(self, port: int) -> int | None`**: A static method that attempts to find
139
+ a process ID (PID) listening on a given `port`.
140
+ * It uses platform-specific commands (`netstat`, `ss`, `lsof`).
141
+ * Returns the PID if found, otherwise `None`.
142
+
143
+ * **`kill_process(self, pid: int) -> bool`**: A static method that attempts to kill the process
144
+ with the given `pid`.
145
+ * It uses platform-specific commands (`taskkill`, `kill -9`).
146
+ * Returns `True` if the process was successfully killed, `False` otherwise.
147
+
148
+ * **`release_all(self, ports: list[int] | None = None) -> None`**: Releases all processes listening on the specified `ports`.
149
+ * `ports`: A list of ports to release.
150
+ * If `None`, it uses the `default_ports` defined during initialization.
151
+ * For each port, it first tries to get the PID and then attempts to kill the process.
152
+ * It logs the actions and any errors encountered. Invalid port numbers in the provided list are skipped.
153
+
154
+ #### Example Usage:
155
+
156
+ ```python
157
+ import logging
158
+ from nano_dev_utils import ports_release, PortsRelease
159
+
160
+
161
+ logging.basicConfig(filename='port release.log',
162
+ level=logging.INFO, # DEBUG, WARNING, ERROR, CRITICAL
163
+ format='%(asctime)s - %(levelname)s: %(message)s',
164
+ datefmt='%d-%m-%Y %H:%M:%S')
165
+
166
+
167
+ ports_release.release_all()
168
+
169
+ # Create an instance with custom ports
170
+ custom_ports_releaser = PortsRelease(default_ports=[8080, 9000, 6274])
171
+ custom_ports_releaser.release_all(ports=[8080, 9000])
172
+
173
+ # Release only the default ports
174
+ ports_release.release_all()
175
+ ```
176
+
177
+
178
+ ## License
179
+ This project is licensed under the MIT License.
180
+ See [LICENSE](https://github.com/yaronday/nano_dev_utils/blob/master/LICENSE) for details.