nano-dev-utils 1.4.0__tar.gz → 1.4.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.

Potentially problematic release.


This version of nano-dev-utils might be problematic. Click here for more details.

Files changed (34) hide show
  1. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.idea/workspace.xml +99 -111
  2. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/PKG-INFO +28 -18
  3. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/README.md +27 -17
  4. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/pyproject.toml +37 -37
  5. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/src/nano_dev_utils/common.py +47 -17
  6. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/src/nano_dev_utils/file_tree_display.py +38 -28
  7. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/src/nano_dev_utils/timers.py +21 -9
  8. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/tests/test_common.py +30 -21
  9. nano_dev_utils-1.4.1/tests/test_timers/conftest.py +62 -0
  10. nano_dev_utils-1.4.1/tests/test_timers/test_duration_formatter.py +152 -0
  11. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/tests/test_timers/test_timer.py +10 -7
  12. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/tests/test_timers/test_timers_async.py +15 -4
  13. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/uv.lock +242 -242
  14. nano_dev_utils-1.4.0/tests/test_timers/conftest.py +0 -29
  15. nano_dev_utils-1.4.0/tests/test_timers/test_duration_formatter.py +0 -156
  16. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.gitignore +0 -0
  17. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.idea/.gitignore +0 -0
  18. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.idea/encodings.xml +0 -0
  19. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
  20. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.idea/misc.xml +0 -0
  21. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.idea/modules.xml +0 -0
  22. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.idea/nano_dev_utils.iml +0 -0
  23. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.idea/vcs.xml +0 -0
  24. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/.pre-commit-config.yaml +0 -0
  25. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/LICENSE +0 -0
  26. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/ruff.toml +0 -0
  27. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/src/nano_dev_utils/__init__.py +0 -0
  28. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/src/nano_dev_utils/dynamic_importer.py +0 -0
  29. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/src/nano_dev_utils/release_ports.py +0 -0
  30. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/tests/__init__.py +0 -0
  31. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/tests/test_dynamic_importer.py +0 -0
  32. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/tests/test_file_tree_display.py +0 -0
  33. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/tests/test_release_ports.py +0 -0
  34. {nano_dev_utils-1.4.0 → nano_dev_utils-1.4.1}/tests/test_timers/__init__.py +0 -0
@@ -4,7 +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="bumped to v1.4.0" />
7
+ <list default="true" id="1859e23b-7665-4b92-98cc-65e07a208923" name="Changes" comment="Allow an optional printout to console in addition to logger.&#10;README updates in this regard.&#10;&#10;Bumped minor to v1.4.1" />
8
8
  <option name="SHOW_DIALOG" value="false" />
9
9
  <option name="HIGHLIGHT_CONFLICTS" value="true" />
10
10
  <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@@ -21,7 +21,7 @@
21
21
  <option name="PUSH_AUTO_UPDATE" value="true" />
22
22
  <option name="RECENT_BRANCH_BY_REPOSITORY">
23
23
  <map>
24
- <entry key="$PROJECT_DIR$" value="master" />
24
+ <entry key="$PROJECT_DIR$" value="FI_build_tree_refactor" />
25
25
  </map>
26
26
  </option>
27
27
  <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
@@ -37,28 +37,28 @@
37
37
  <option name="showLibraryContents" value="true" />
38
38
  <option name="showMembers" value="true" />
39
39
  </component>
40
- <component name="PropertiesComponent">{
41
- &quot;keyToString&quot;: {
42
- &quot;Python tests.Python tests in test_dynamic_importer.py.executor&quot;: &quot;Run&quot;,
43
- &quot;Python tests.Python tests in test_file_tree_display.py.executor&quot;: &quot;Run&quot;,
44
- &quot;Python tests.Python tests in test_release_ports.py.executor&quot;: &quot;Run&quot;,
45
- &quot;Python tests.Python tests in test_timer.py.executor&quot;: &quot;Run&quot;,
46
- &quot;Python tests.Python tests in test_timers (1).executor&quot;: &quot;Run&quot;,
47
- &quot;Python tests.Python tests in test_timers.executor&quot;: &quot;Run&quot;,
48
- &quot;Python tests.Python tests in test_timers_async.py.executor&quot;: &quot;Run&quot;,
49
- &quot;Python tests.Python tests in testing_duration_formatter.py.executor&quot;: &quot;Run&quot;,
50
- &quot;Python tests.Python tests in tests.executor&quot;: &quot;Run&quot;,
51
- &quot;Python tests.test_timer prev.executor&quot;: &quot;Run&quot;,
52
- &quot;Python.ftd_main.executor&quot;: &quot;Run&quot;,
53
- &quot;Python.test_timer.executor&quot;: &quot;Run&quot;,
54
- &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
55
- &quot;git-widget-placeholder&quot;: &quot;FI__build__tree__refactor&quot;,
56
- &quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;,
57
- &quot;last_opened_file_path&quot;: &quot;C:/Workspaces/review1&quot;,
58
- &quot;settings.editor.selected.configurable&quot;: &quot;com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable&quot;,
59
- &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.ftd_main.executor": "Run",
53
+ "Python.test_timer.executor": "Run",
54
+ "RunOnceActivity.ShowReadmeOnStart": "true",
55
+ "git-widget-placeholder": "FI-Timer",
56
+ "ignore.virus.scanning.warn.message": "true",
57
+ "last_opened_file_path": "C:/Workspaces/review1",
58
+ "settings.editor.selected.configurable": "com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable",
59
+ "two.files.diff.last.used.file": "C:/Workspaces/review1/tools/file_tree_display/tests/test_file_tree_display.py"
60
60
  }
61
- }</component>
61
+ }]]></component>
62
62
  <component name="RecentsManager">
63
63
  <key name="CopyFile.RECENT_KEYS">
64
64
  <recent name="C:\GitHubWS\nano_dev_utils\src\nano_dev_utils" />
@@ -74,7 +74,7 @@
74
74
  <recent name="C:\GitHubWS\nano_dev_utils" />
75
75
  </key>
76
76
  </component>
77
- <component name="RunManager" selected="Python tests.Python tests in test_file_tree_display.py">
77
+ <component name="RunManager" selected="Python tests.Python tests in tests">
78
78
  <configuration name="ftd_bench" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
79
79
  <module name="nano_dev_utils" />
80
80
  <option name="ENV_FILES" value="" />
@@ -166,9 +166,9 @@
166
166
  </list>
167
167
  <recent_temporary>
168
168
  <list>
169
- <item itemvalue="Python tests.Python tests in test_file_tree_display.py" />
170
169
  <item itemvalue="Python tests.Python tests in tests" />
171
170
  <item itemvalue="Python tests.Python tests in test_timers" />
171
+ <item itemvalue="Python tests.Python tests in test_file_tree_display.py" />
172
172
  <item itemvalue="Python tests.Python tests in test_dynamic_importer.py" />
173
173
  <item itemvalue="Python.ftd_bench" />
174
174
  </list>
@@ -190,70 +190,6 @@
190
190
  <option name="presentableId" value="Default" />
191
191
  <updated>1746126505743</updated>
192
192
  </task>
193
- <task id="LOCAL-00047" summary="const for repeatable text">
194
- <option name="closed" value="true" />
195
- <created>1761690989789</created>
196
- <option name="number" value="00047" />
197
- <option name="presentableId" value="LOCAL-00047" />
198
- <option name="project" value="LOCAL" />
199
- <updated>1761690989789</updated>
200
- </task>
201
- <task id="LOCAL-00048" summary="ongoing async related updates">
202
- <option name="closed" value="true" />
203
- <created>1761693009719</created>
204
- <option name="number" value="00048" />
205
- <option name="presentableId" value="LOCAL-00048" />
206
- <option name="project" value="LOCAL" />
207
- <updated>1761693009719</updated>
208
- </task>
209
- <task id="LOCAL-00049" summary="async test passes, pyright still fails">
210
- <option name="closed" value="true" />
211
- <created>1761694519471</created>
212
- <option name="number" value="00049" />
213
- <option name="presentableId" value="LOCAL-00049" />
214
- <option name="project" value="LOCAL" />
215
- <updated>1761694519471</updated>
216
- </task>
217
- <task id="LOCAL-00050" summary="Pyright issues resolved for both sync and async.">
218
- <option name="closed" value="true" />
219
- <created>1761697688134</created>
220
- <option name="number" value="00050" />
221
- <option name="presentableId" value="LOCAL-00050" />
222
- <option name="project" value="LOCAL" />
223
- <updated>1761697688134</updated>
224
- </task>
225
- <task id="LOCAL-00051" summary="v1.1.1: &#10;Bring all updates from FI branch. &#10;Bug fixes, code improvements, special async support for timing decorator.">
226
- <option name="closed" value="true" />
227
- <created>1761698238462</created>
228
- <option name="number" value="00051" />
229
- <option name="presentableId" value="LOCAL-00051" />
230
- <option name="project" value="LOCAL" />
231
- <updated>1761698238462</updated>
232
- </task>
233
- <task id="LOCAL-00052" summary="+README updates">
234
- <option name="closed" value="true" />
235
- <created>1761699537254</created>
236
- <option name="number" value="00052" />
237
- <option name="presentableId" value="LOCAL-00052" />
238
- <option name="project" value="LOCAL" />
239
- <updated>1761699537254</updated>
240
- </task>
241
- <task id="LOCAL-00053" summary="+README updates">
242
- <option name="closed" value="true" />
243
- <created>1761699713775</created>
244
- <option name="number" value="00053" />
245
- <option name="presentableId" value="LOCAL-00053" />
246
- <option name="project" value="LOCAL" />
247
- <updated>1761699713775</updated>
248
- </task>
249
- <task id="LOCAL-00054" summary="exposing ports_release and importer object instances">
250
- <option name="closed" value="true" />
251
- <created>1761700088854</created>
252
- <option name="number" value="00054" />
253
- <option name="presentableId" value="LOCAL-00054" />
254
- <option name="project" value="LOCAL" />
255
- <updated>1761700088854</updated>
256
- </task>
257
193
  <task id="LOCAL-00055" summary="README updates related to exposed instances">
258
194
  <option name="closed" value="true" />
259
195
  <created>1761700369016</created>
@@ -582,7 +518,71 @@
582
518
  <option name="project" value="LOCAL" />
583
519
  <updated>1762039348920</updated>
584
520
  </task>
585
- <option name="localTasksCounter" value="96" />
521
+ <task id="LOCAL-00096" summary="+build">
522
+ <option name="closed" value="true" />
523
+ <created>1762044026530</created>
524
+ <option name="number" value="00096" />
525
+ <option name="presentableId" value="LOCAL-00096" />
526
+ <option name="project" value="LOCAL" />
527
+ <updated>1762044026530</updated>
528
+ </task>
529
+ <task id="LOCAL-00097" summary="+build">
530
+ <option name="closed" value="true" />
531
+ <created>1762044034034</created>
532
+ <option name="number" value="00097" />
533
+ <option name="presentableId" value="LOCAL-00097" />
534
+ <option name="project" value="LOCAL" />
535
+ <updated>1762044034034</updated>
536
+ </task>
537
+ <task id="LOCAL-00098" summary="Readme updates">
538
+ <option name="closed" value="true" />
539
+ <created>1762078800875</created>
540
+ <option name="number" value="00098" />
541
+ <option name="presentableId" value="LOCAL-00098" />
542
+ <option name="project" value="LOCAL" />
543
+ <updated>1762078800875</updated>
544
+ </task>
545
+ <task id="LOCAL-00099" summary="+res_formatter, a wrapper for the private static _duration_formatter.">
546
+ <option name="closed" value="true" />
547
+ <created>1762081915651</created>
548
+ <option name="number" value="00099" />
549
+ <option name="presentableId" value="LOCAL-00099" />
550
+ <option name="project" value="LOCAL" />
551
+ <updated>1762081915651</updated>
552
+ </task>
553
+ <task id="LOCAL-00100" summary="Timer: +printout option">
554
+ <option name="closed" value="true" />
555
+ <created>1762081953468</created>
556
+ <option name="number" value="00100" />
557
+ <option name="presentableId" value="LOCAL-00100" />
558
+ <option name="project" value="LOCAL" />
559
+ <updated>1762081953468</updated>
560
+ </task>
561
+ <task id="LOCAL-00101" summary="+printout testing (WIP)">
562
+ <option name="closed" value="true" />
563
+ <created>1762084839210</created>
564
+ <option name="number" value="00101" />
565
+ <option name="presentableId" value="LOCAL-00101" />
566
+ <option name="project" value="LOCAL" />
567
+ <updated>1762084839210</updated>
568
+ </task>
569
+ <task id="LOCAL-00102" summary="Pyright corrections;&#10;Timer unit tests - improved code">
570
+ <option name="closed" value="true" />
571
+ <created>1762093068383</created>
572
+ <option name="number" value="00102" />
573
+ <option name="presentableId" value="LOCAL-00102" />
574
+ <option name="project" value="LOCAL" />
575
+ <updated>1762093068383</updated>
576
+ </task>
577
+ <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">
578
+ <option name="closed" value="true" />
579
+ <created>1762093698362</created>
580
+ <option name="number" value="00103" />
581
+ <option name="presentableId" value="LOCAL-00103" />
582
+ <option name="project" value="LOCAL" />
583
+ <updated>1762093698362</updated>
584
+ </task>
585
+ <option name="localTasksCounter" value="104" />
586
586
  <servers />
587
587
  </component>
588
588
  <component name="Vcs.Log.Tabs.Properties">
@@ -610,32 +610,13 @@
610
610
  <map>
611
611
  <entry key="MAIN">
612
612
  <value>
613
- <State>
614
- <option name="FILTERS">
615
- <map>
616
- <entry key="branch">
617
- <value>
618
- <list>
619
- <option value="origin/FI" />
620
- </list>
621
- </value>
622
- </entry>
623
- </map>
624
- </option>
625
- </State>
613
+ <State />
626
614
  </value>
627
615
  </entry>
628
616
  </map>
629
617
  </option>
630
618
  </component>
631
619
  <component name="VcsManagerConfiguration">
632
- <MESSAGE value="fixed result formatting errors" />
633
- <MESSAGE value="linter correction" />
634
- <MESSAGE value="additional unit tests for timer&#10;async - wip" />
635
- <MESSAGE value="rename timer_obj -&gt; timer_mock" />
636
- <MESSAGE value="test-timer refactor: split to tinier modules for better maintenance and separation of concern. WIP" />
637
- <MESSAGE value="corrected file name, importing, preventing ruff undesired mods by &#10;# noqa: F401" />
638
- <MESSAGE value="Bugfixes: moved fixtures to conftest;&#10;removed test_timers_common;&#10;corrected all imports" />
639
620
  <MESSAGE value="timer -&gt; timer_mock" />
640
621
  <MESSAGE value="ruff." />
641
622
  <MESSAGE value="test_timer unit tests complete" />
@@ -654,6 +635,13 @@
654
635
  <MESSAGE value="+PredicateBuilder: creates predicate functions" />
655
636
  <MESSAGE value="README updates IAW recends mods" />
656
637
  <MESSAGE value="bumped to v1.4.0" />
657
- <option name="LAST_COMMIT_MESSAGE" value="bumped to v1.4.0" />
638
+ <MESSAGE value="+build" />
639
+ <MESSAGE value="Readme updates" />
640
+ <MESSAGE value="+res_formatter, a wrapper for the private static _duration_formatter." />
641
+ <MESSAGE value="Timer: +printout option" />
642
+ <MESSAGE value="+printout testing (WIP)" />
643
+ <MESSAGE value="Pyright corrections;&#10;Timer unit tests - improved code" />
644
+ <MESSAGE value="Allow an optional printout to console in addition to logger.&#10;README updates in this regard.&#10;&#10;Bumped minor to v1.4.1" />
645
+ <option name="LAST_COMMIT_MESSAGE" value="Allow an optional printout to console in addition to logger.&#10;README updates in this regard.&#10;&#10;Bumped minor to v1.4.1" />
658
646
  </component>
659
647
  </project>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nano_dev_utils
3
- Version: 1.4.0
3
+ Version: 1.4.1
4
4
  Summary: A collection of small Python utilities for developers.
5
5
  Project-URL: Homepage, https://github.com/yaronday/nano_utils
6
6
  Project-URL: Issues, https://github.com/yaronday/nano_utils/issues
@@ -26,9 +26,10 @@ This module provides a `Timer` class for measuring the execution time of code bl
26
26
 
27
27
  #### `Timer` Class
28
28
 
29
- * **`__init__(self, precision: int = 4, verbose: bool = False)`**: Initializes a `Timer` instance.
29
+ * **`__init__(self, precision: int = 4, verbose: bool = False, printout: bool = False)`**: Initializes a `Timer` instance.
30
30
  * `precision`: The number of decimal places to record and display time durations. Defaults to 4.
31
31
  * `verbose`: Optionally displays the function's positional arguments (args) and keyword arguments (kwargs). Defaults to `False`.
32
+ * `printout`: Allows printing to console.
32
33
 
33
34
  * **`def timeit(
34
35
  self,
@@ -47,15 +48,22 @@ This module provides a `Timer` class for measuring the execution time of code bl
47
48
  * Records execution times
48
49
  * Handles timeout conditions
49
50
  * Calculates average execution time across iterations
50
- * Prints the function name and execution time (with optional arguments)
51
+ * Logs the function name and execution time (with optional arguments)
51
52
  * Returns the result of the original function (unless timeout occurs)
52
53
 
53
54
  #### Example Usage:
54
55
 
55
56
  ```python
56
57
  import time
58
+ import logging
57
59
  from nano_dev_utils import timer
58
60
 
61
+ # This timer version uses a logger but also allows printing (if enabled), so it has to be configured in your app, for instance:
62
+ logging.basicConfig(filename='timer example.log',
63
+ level=logging.INFO, # DEBUG, WARNING, ERROR, CRITICAL
64
+ format='%(asctime)s - %(levelname)s: %(message)s',
65
+ datefmt='%d-%m-%Y %H:%M:%S')
66
+
59
67
  # Basic timing
60
68
  @timer.timeit()
61
69
  def my_function(a, b=10):
@@ -64,17 +72,15 @@ def my_function(a, b=10):
64
72
  return a + b
65
73
 
66
74
  timer.init(precision=6, verbose=True)
67
- '''
68
- Alternatively we could have used the `update` method as well:
75
+ '''Alternative options:
76
+ timer.update({'precision': 6, 'verbose': True}) # 1. Using update method
69
77
 
70
- timer.update({'precision': 6, 'verbose': True})
71
-
72
- The above config could be also achieved via explicit instantiation:
73
-
74
- from nano_dev_utils.timers import Timer
75
- timer = Timer(precision=6, verbose=True)
78
+ from nano_dev_utils.timers import Timer # 2. explicit instantiation
79
+ timer = Timer(precision=6, verbose=True)
76
80
  '''
77
81
 
82
+ timer.update({'printout': True}) # allow printing to console
83
+
78
84
  # Advanced usage with timeout and iterations
79
85
  @timer.timeit(iterations=5, timeout=0.5, per_iteration=True)
80
86
  def critical_function(x):
@@ -151,7 +157,7 @@ import logging
151
157
  from nano_dev_utils import ports_release, PortsRelease
152
158
 
153
159
 
154
- # For configuration of logging level and format (supported already):
160
+ # configure the logger
155
161
  logging.basicConfig(filename='port release.log',
156
162
  level=logging.INFO, # DEBUG, WARNING, ERROR, CRITICAL
157
163
  format='%(asctime)s - %(levelname)s: %(message)s',
@@ -170,8 +176,9 @@ ports_release.release_all()
170
176
 
171
177
  ### `file_tree_display.py`
172
178
 
173
- This module provides a class-based utility for generating a visually structured directory tree.
174
- It supports recursive traversal, customizable hierarchy styles, and exclusion patterns for directories and files.
179
+ This module provides a utility for generating a visually structured directory tree.
180
+ It supports recursive traversal, customizable hierarchy styles, and inclusion / exclusion
181
+ patterns for directories and files.
175
182
  Output can be displayed in the console or saved to a file.
176
183
 
177
184
 
@@ -180,11 +187,12 @@ Output can be displayed in the console or saved to a file.
180
187
  - Recursively displays and logs directory trees
181
188
  - Efficient directory traversal
182
189
  - Blazing fast (see Benchmarks below)
183
- - Generates human-readable file tree structure
190
+ - Generates human-readable file tree structure
191
+ - Supports including / ignoring specific directories or files via pattern matching
184
192
  - Customizable tree display output
185
193
  - Optionally saves the resulting tree to a text file
186
- - Supports ignoring specific directories or files via pattern matching
187
- - Handles permission and read/write errors gracefully
194
+ - Lightweight, flexible and easily configurable
195
+
188
196
 
189
197
  ## Benchmarks
190
198
 
@@ -244,11 +252,13 @@ filepath = str(Path(target_path, filename))
244
252
 
245
253
  ftd = FileTreeDisplay(root_dir=root,
246
254
  ignore_dirs=['.git', 'node_modules', '.idea'],
247
- ignore_files={'.gitignore', '*.toml'}, style='—',
255
+ ignore_files=['.gitignore', '*.toml'],
256
+ style='—',
248
257
  include_dirs=['src', 'tests', 'snapshots'],
249
258
  filepath=filepath,
250
259
  sort_key_name='custom',
251
260
  custom_sort=(lambda x: any(ext in x.lower() for ext in ('jpg', 'png'))),
261
+ files_first=True,
252
262
  reverse=True
253
263
  )
254
264
  ftd.file_tree_display()
@@ -10,9 +10,10 @@ This module provides a `Timer` class for measuring the execution time of code bl
10
10
 
11
11
  #### `Timer` Class
12
12
 
13
- * **`__init__(self, precision: int = 4, verbose: bool = False)`**: Initializes a `Timer` instance.
13
+ * **`__init__(self, precision: int = 4, verbose: bool = False, printout: bool = False)`**: Initializes a `Timer` instance.
14
14
  * `precision`: The number of decimal places to record and display time durations. Defaults to 4.
15
15
  * `verbose`: Optionally displays the function's positional arguments (args) and keyword arguments (kwargs). Defaults to `False`.
16
+ * `printout`: Allows printing to console.
16
17
 
17
18
  * **`def timeit(
18
19
  self,
@@ -31,15 +32,22 @@ This module provides a `Timer` class for measuring the execution time of code bl
31
32
  * Records execution times
32
33
  * Handles timeout conditions
33
34
  * Calculates average execution time across iterations
34
- * Prints the function name and execution time (with optional arguments)
35
+ * Logs the function name and execution time (with optional arguments)
35
36
  * Returns the result of the original function (unless timeout occurs)
36
37
 
37
38
  #### Example Usage:
38
39
 
39
40
  ```python
40
41
  import time
42
+ import logging
41
43
  from nano_dev_utils import timer
42
44
 
45
+ # This timer version uses a logger but also allows printing (if enabled), so it has to be configured in your app, for instance:
46
+ logging.basicConfig(filename='timer example.log',
47
+ level=logging.INFO, # DEBUG, WARNING, ERROR, CRITICAL
48
+ format='%(asctime)s - %(levelname)s: %(message)s',
49
+ datefmt='%d-%m-%Y %H:%M:%S')
50
+
43
51
  # Basic timing
44
52
  @timer.timeit()
45
53
  def my_function(a, b=10):
@@ -48,17 +56,15 @@ def my_function(a, b=10):
48
56
  return a + b
49
57
 
50
58
  timer.init(precision=6, verbose=True)
51
- '''
52
- Alternatively we could have used the `update` method as well:
59
+ '''Alternative options:
60
+ timer.update({'precision': 6, 'verbose': True}) # 1. Using update method
53
61
 
54
- timer.update({'precision': 6, 'verbose': True})
55
-
56
- The above config could be also achieved via explicit instantiation:
57
-
58
- from nano_dev_utils.timers import Timer
59
- timer = Timer(precision=6, verbose=True)
62
+ from nano_dev_utils.timers import Timer # 2. explicit instantiation
63
+ timer = Timer(precision=6, verbose=True)
60
64
  '''
61
65
 
66
+ timer.update({'printout': True}) # allow printing to console
67
+
62
68
  # Advanced usage with timeout and iterations
63
69
  @timer.timeit(iterations=5, timeout=0.5, per_iteration=True)
64
70
  def critical_function(x):
@@ -135,7 +141,7 @@ import logging
135
141
  from nano_dev_utils import ports_release, PortsRelease
136
142
 
137
143
 
138
- # For configuration of logging level and format (supported already):
144
+ # configure the logger
139
145
  logging.basicConfig(filename='port release.log',
140
146
  level=logging.INFO, # DEBUG, WARNING, ERROR, CRITICAL
141
147
  format='%(asctime)s - %(levelname)s: %(message)s',
@@ -154,8 +160,9 @@ ports_release.release_all()
154
160
 
155
161
  ### `file_tree_display.py`
156
162
 
157
- This module provides a class-based utility for generating a visually structured directory tree.
158
- It supports recursive traversal, customizable hierarchy styles, and exclusion patterns for directories and files.
163
+ This module provides a utility for generating a visually structured directory tree.
164
+ It supports recursive traversal, customizable hierarchy styles, and inclusion / exclusion
165
+ patterns for directories and files.
159
166
  Output can be displayed in the console or saved to a file.
160
167
 
161
168
 
@@ -164,11 +171,12 @@ Output can be displayed in the console or saved to a file.
164
171
  - Recursively displays and logs directory trees
165
172
  - Efficient directory traversal
166
173
  - Blazing fast (see Benchmarks below)
167
- - Generates human-readable file tree structure
174
+ - Generates human-readable file tree structure
175
+ - Supports including / ignoring specific directories or files via pattern matching
168
176
  - Customizable tree display output
169
177
  - Optionally saves the resulting tree to a text file
170
- - Supports ignoring specific directories or files via pattern matching
171
- - Handles permission and read/write errors gracefully
178
+ - Lightweight, flexible and easily configurable
179
+
172
180
 
173
181
  ## Benchmarks
174
182
 
@@ -228,11 +236,13 @@ filepath = str(Path(target_path, filename))
228
236
 
229
237
  ftd = FileTreeDisplay(root_dir=root,
230
238
  ignore_dirs=['.git', 'node_modules', '.idea'],
231
- ignore_files={'.gitignore', '*.toml'}, style='—',
239
+ ignore_files=['.gitignore', '*.toml'],
240
+ style='—',
232
241
  include_dirs=['src', 'tests', 'snapshots'],
233
242
  filepath=filepath,
234
243
  sort_key_name='custom',
235
244
  custom_sort=(lambda x: any(ext in x.lower() for ext in ('jpg', 'png'))),
245
+ files_first=True,
236
246
  reverse=True
237
247
  )
238
248
  ftd.file_tree_display()
@@ -1,37 +1,37 @@
1
- [project]
2
- name = "nano_dev_utils"
3
- version = "1.4.0"
4
- authors = [
5
- { name="Yaron Dayan", email="yaronday77@gmail.com" },
6
- ]
7
- description = "A collection of small Python utilities for developers."
8
- readme = "README.md"
9
- requires-python = ">=3.10"
10
- classifiers = [
11
- "Programming Language :: Python :: 3",
12
- "Operating System :: OS Independent",
13
- ]
14
- license = { text = "MIT" }
15
- dependencies = [
16
- "build>=1.3.0",
17
- ]
18
-
19
- [project.urls]
20
- Homepage = "https://github.com/yaronday/nano_utils"
21
- Issues = "https://github.com/yaronday/nano_utils/issues"
22
- license = "https://github.com/yaronday/nano_dev_utils/blob/master/LICENSE"
23
-
24
- [project.files]
25
- license = { path = "LICENSE" }
26
-
27
- [dependency-groups]
28
- test = [
29
- "pytest>=8.2.0",
30
- "pytest-mock>=3.14.0",
31
- "pytest-asyncio>=1.2.0",
32
- ]
33
-
34
- [build-system]
35
- requires = ["hatchling >= 1.26"]
36
- build-backend = "hatchling.build"
37
-
1
+ [project]
2
+ name = "nano_dev_utils"
3
+ version = "1.4.1"
4
+ authors = [
5
+ { name="Yaron Dayan", email="yaronday77@gmail.com" },
6
+ ]
7
+ description = "A collection of small Python utilities for developers."
8
+ readme = "README.md"
9
+ requires-python = ">=3.10"
10
+ classifiers = [
11
+ "Programming Language :: Python :: 3",
12
+ "Operating System :: OS Independent",
13
+ ]
14
+ license = { text = "MIT" }
15
+ dependencies = [
16
+ "build>=1.3.0",
17
+ ]
18
+
19
+ [project.urls]
20
+ Homepage = "https://github.com/yaronday/nano_utils"
21
+ Issues = "https://github.com/yaronday/nano_utils/issues"
22
+ license = "https://github.com/yaronday/nano_dev_utils/blob/master/LICENSE"
23
+
24
+ [project.files]
25
+ license = { path = "LICENSE" }
26
+
27
+ [dependency-groups]
28
+ test = [
29
+ "pytest>=8.2.0",
30
+ "pytest-mock>=3.14.0",
31
+ "pytest-asyncio>=1.2.0",
32
+ ]
33
+
34
+ [build-system]
35
+ requires = ["hatchling >= 1.26"]
36
+ build-backend = "hatchling.build"
37
+