stouputils 1.2.3__tar.gz → 1.2.5__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.
- {stouputils-1.2.3 → stouputils-1.2.5}/.gitignore +14 -14
- {stouputils-1.2.3 → stouputils-1.2.5}/LICENSE +21 -21
- {stouputils-1.2.3 → stouputils-1.2.5}/PKG-INFO +6 -1
- {stouputils-1.2.3 → stouputils-1.2.5}/README.md +51 -51
- {stouputils-1.2.3 → stouputils-1.2.5}/pyproject.toml +6 -1
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/__init__.py +31 -31
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/all_doctests.py +98 -98
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/applications/automatic_docs.py +8 -1
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/archive.py +119 -119
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/backup.py +314 -314
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/collections.py +61 -61
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/continuous_delivery/__init__.py +24 -24
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/continuous_delivery/cd_utils.py +135 -135
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/continuous_delivery/github.py +416 -416
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/continuous_delivery/pypi.py +85 -85
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/continuous_delivery/pyproject.py +121 -121
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/ctx.py +107 -107
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/decorators.py +313 -313
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/dont_look/zip_file_override.py +108 -108
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/io.py +219 -219
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/parallel.py +190 -190
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/print.py +252 -252
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/py.typed +1 -1
- {stouputils-1.2.3 → stouputils-1.2.5}/stouputils/applications/__init__.py +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
# Python
|
|
3
|
-
*__pycache__/
|
|
4
|
-
|
|
5
|
-
# Miscellaneous
|
|
6
|
-
__temporary__/
|
|
7
|
-
output.log
|
|
8
|
-
|
|
9
|
-
# Documentation
|
|
10
|
-
docs/source/_static/
|
|
11
|
-
docs/source/_templates/
|
|
12
|
-
docs/source/modules/
|
|
13
|
-
docs/source/index.rst
|
|
14
|
-
|
|
1
|
+
|
|
2
|
+
# Python
|
|
3
|
+
*__pycache__/
|
|
4
|
+
|
|
5
|
+
# Miscellaneous
|
|
6
|
+
__temporary__/
|
|
7
|
+
output.log
|
|
8
|
+
|
|
9
|
+
# Documentation
|
|
10
|
+
docs/source/_static/
|
|
11
|
+
docs/source/_templates/
|
|
12
|
+
docs/source/modules/
|
|
13
|
+
docs/source/index.rst
|
|
14
|
+
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Alexandre Collignon
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Alexandre Collignon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stouputils
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.5
|
|
4
4
|
Summary: Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Stoupy51/stouputils
|
|
6
6
|
Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
|
|
@@ -10,9 +10,14 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Requires-Python: >=3.10
|
|
13
|
+
Requires-Dist: furo>=2024.8.6
|
|
14
|
+
Requires-Dist: hatch>=1.14.0
|
|
13
15
|
Requires-Dist: m2r2>=0.3.3.post2
|
|
16
|
+
Requires-Dist: myst-parser>=4.0.1
|
|
14
17
|
Requires-Dist: pyyaml>=6.0.0
|
|
15
18
|
Requires-Dist: requests>=2.30.0
|
|
19
|
+
Requires-Dist: sphinx-rtd-theme>=3.0.2
|
|
20
|
+
Requires-Dist: sphinx>=8.1.3
|
|
16
21
|
Requires-Dist: toml>=0.10.0
|
|
17
22
|
Requires-Dist: tqdm>=4.66.0
|
|
18
23
|
Description-Content-Type: text/markdown
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
# 🛠️ Project Badges
|
|
3
|
-
[](https://github.com/Stoupy51/stouputils/releases/latest)
|
|
4
|
-
[](https://pypi.org/project/stouputils/)
|
|
5
|
-
[](https://stoupy51.github.io/stouputils/latest/)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# 📚 Project Overview
|
|
9
|
-
Stouputils is a collection of utility modules designed to simplify and enhance the development process.<br>
|
|
10
|
-
It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
# 🚀 Project File Tree
|
|
14
|
-
```bash
|
|
15
|
-
stouputils/
|
|
16
|
-
├── applications/
|
|
17
|
-
│ ├── automatic_docs.py # 📚 Documentation generation utilities (used to create this documentation)
|
|
18
|
-
│ └── ...
|
|
19
|
-
│
|
|
20
|
-
├── continuous_delivery/
|
|
21
|
-
│ ├── cd_utils.py # 🔧 Common utilities for continuous delivery
|
|
22
|
-
│ ├── github.py # 📦 GitHub utilities (upload_to_github)
|
|
23
|
-
│ ├── pypi.py # 📦 PyPI utilities (pypi_full_routine)
|
|
24
|
-
│ ├── pyproject.py # 📝 Pyproject.toml utilities
|
|
25
|
-
│ └── ...
|
|
26
|
-
│
|
|
27
|
-
├── print.py # 🖨️ Display utilities (info, debug, warning, error)
|
|
28
|
-
├── io.py # 💻 I/O utilities (file management, json)
|
|
29
|
-
├── decorators.py # 🎯 Decorators (silent, measure_time, error_handler, simple_cache)
|
|
30
|
-
├── ctx.py # 🚫 Context managers (Muffle, LogToFile)
|
|
31
|
-
├── archive.py # 📦 Archive utilities (zip, repair_zip)
|
|
32
|
-
├── parallel.py # 🧑🤝🧑 Parallel processing (multiprocessing, multithreading)
|
|
33
|
-
├── collections.py # 🧰 Collection utilities (unique_list)
|
|
34
|
-
├── all_doctests.py # ✅ Execution of all doctests for a given path
|
|
35
|
-
├── backup.py # 📦 Backup utilities (delta backup, consolidate)
|
|
36
|
-
└── ...
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
## ⭐ Star History
|
|
41
|
-
|
|
42
|
-
<html>
|
|
43
|
-
<a href="https://star-history.com/#Stoupy51/stouputils&Date">
|
|
44
|
-
<picture>
|
|
45
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
|
|
46
|
-
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
47
|
-
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
48
|
-
</picture>
|
|
49
|
-
</a>
|
|
50
|
-
</html>
|
|
51
|
-
|
|
1
|
+
|
|
2
|
+
# 🛠️ Project Badges
|
|
3
|
+
[](https://github.com/Stoupy51/stouputils/releases/latest)
|
|
4
|
+
[](https://pypi.org/project/stouputils/)
|
|
5
|
+
[](https://stoupy51.github.io/stouputils/latest/)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# 📚 Project Overview
|
|
9
|
+
Stouputils is a collection of utility modules designed to simplify and enhance the development process.<br>
|
|
10
|
+
It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# 🚀 Project File Tree
|
|
14
|
+
```bash
|
|
15
|
+
stouputils/
|
|
16
|
+
├── applications/
|
|
17
|
+
│ ├── automatic_docs.py # 📚 Documentation generation utilities (used to create this documentation)
|
|
18
|
+
│ └── ...
|
|
19
|
+
│
|
|
20
|
+
├── continuous_delivery/
|
|
21
|
+
│ ├── cd_utils.py # 🔧 Common utilities for continuous delivery
|
|
22
|
+
│ ├── github.py # 📦 GitHub utilities (upload_to_github)
|
|
23
|
+
│ ├── pypi.py # 📦 PyPI utilities (pypi_full_routine)
|
|
24
|
+
│ ├── pyproject.py # 📝 Pyproject.toml utilities
|
|
25
|
+
│ └── ...
|
|
26
|
+
│
|
|
27
|
+
├── print.py # 🖨️ Display utilities (info, debug, warning, error)
|
|
28
|
+
├── io.py # 💻 I/O utilities (file management, json)
|
|
29
|
+
├── decorators.py # 🎯 Decorators (silent, measure_time, error_handler, simple_cache)
|
|
30
|
+
├── ctx.py # 🚫 Context managers (Muffle, LogToFile)
|
|
31
|
+
├── archive.py # 📦 Archive utilities (zip, repair_zip)
|
|
32
|
+
├── parallel.py # 🧑🤝🧑 Parallel processing (multiprocessing, multithreading)
|
|
33
|
+
├── collections.py # 🧰 Collection utilities (unique_list)
|
|
34
|
+
├── all_doctests.py # ✅ Execution of all doctests for a given path
|
|
35
|
+
├── backup.py # 📦 Backup utilities (delta backup, consolidate)
|
|
36
|
+
└── ...
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## ⭐ Star History
|
|
41
|
+
|
|
42
|
+
<html>
|
|
43
|
+
<a href="https://star-history.com/#Stoupy51/stouputils&Date">
|
|
44
|
+
<picture>
|
|
45
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
|
|
46
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
47
|
+
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
48
|
+
</picture>
|
|
49
|
+
</a>
|
|
50
|
+
</html>
|
|
51
|
+
|
|
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "stouputils"
|
|
8
|
-
version = "1.2.
|
|
8
|
+
version = "1.2.5"
|
|
9
9
|
description = "Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more."
|
|
10
10
|
readme = "README.md"
|
|
11
11
|
requires-python = ">=3.10"
|
|
@@ -20,6 +20,11 @@ dependencies = [
|
|
|
20
20
|
"pyyaml>=6.0.0",
|
|
21
21
|
"toml>=0.10.0",
|
|
22
22
|
"m2r2>=0.3.3.post2",
|
|
23
|
+
"sphinx>=8.1.3",
|
|
24
|
+
"sphinx-rtd-theme>=3.0.2",
|
|
25
|
+
"myst-parser>=4.0.1",
|
|
26
|
+
"furo>=2024.8.6",
|
|
27
|
+
"hatch>=1.14.0",
|
|
23
28
|
]
|
|
24
29
|
[[project.authors]]
|
|
25
30
|
name = "Stoupy51"
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
""" A collection of utility modules designed to simplify and enhance the development process.
|
|
2
|
-
|
|
3
|
-
This package provides various tools and utilities for common development tasks including:
|
|
4
|
-
|
|
5
|
-
Key Features:
|
|
6
|
-
- Continuous delivery utilities (GitHub, PyPI)
|
|
7
|
-
- Display and logging utilities (print)
|
|
8
|
-
- File and I/O management (io)
|
|
9
|
-
- Decorators for common patterns
|
|
10
|
-
- Context managers
|
|
11
|
-
- Archive and backup tools
|
|
12
|
-
- Parallel processing helpers
|
|
13
|
-
- Collection utilities
|
|
14
|
-
- Doctests utilities
|
|
15
|
-
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
# Imports
|
|
19
|
-
from .print import *
|
|
20
|
-
from .archive import *
|
|
21
|
-
from .io import *
|
|
22
|
-
from .decorators import *
|
|
23
|
-
from .ctx import *
|
|
24
|
-
from .parallel import *
|
|
25
|
-
from .all_doctests import *
|
|
26
|
-
from .collections import *
|
|
27
|
-
from .backup import *
|
|
28
|
-
|
|
29
|
-
# Folders
|
|
30
|
-
from .continuous_delivery import *
|
|
31
|
-
|
|
1
|
+
""" A collection of utility modules designed to simplify and enhance the development process.
|
|
2
|
+
|
|
3
|
+
This package provides various tools and utilities for common development tasks including:
|
|
4
|
+
|
|
5
|
+
Key Features:
|
|
6
|
+
- Continuous delivery utilities (GitHub, PyPI)
|
|
7
|
+
- Display and logging utilities (print)
|
|
8
|
+
- File and I/O management (io)
|
|
9
|
+
- Decorators for common patterns
|
|
10
|
+
- Context managers
|
|
11
|
+
- Archive and backup tools
|
|
12
|
+
- Parallel processing helpers
|
|
13
|
+
- Collection utilities
|
|
14
|
+
- Doctests utilities
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# Imports
|
|
19
|
+
from .print import *
|
|
20
|
+
from .archive import *
|
|
21
|
+
from .io import *
|
|
22
|
+
from .decorators import *
|
|
23
|
+
from .ctx import *
|
|
24
|
+
from .parallel import *
|
|
25
|
+
from .all_doctests import *
|
|
26
|
+
from .collections import *
|
|
27
|
+
from .backup import *
|
|
28
|
+
|
|
29
|
+
# Folders
|
|
30
|
+
from .continuous_delivery import *
|
|
31
|
+
|
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This module is used to run all the doctests for all the modules in a given directory.
|
|
3
|
-
|
|
4
|
-
.. image:: https://raw.githubusercontent.com/Stoupy51/stouputils/refs/heads/main/assets/all_doctests_module.gif
|
|
5
|
-
:alt: stouputils all_doctests examples
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
# Imports
|
|
9
|
-
import os
|
|
10
|
-
import sys
|
|
11
|
-
from .print import info, error, progress
|
|
12
|
-
from .decorators import measure_time, handle_error, LogLevels
|
|
13
|
-
from . import decorators
|
|
14
|
-
from doctest import TestResults, testmod
|
|
15
|
-
from types import ModuleType
|
|
16
|
-
import importlib
|
|
17
|
-
import pkgutil
|
|
18
|
-
|
|
19
|
-
def test_module_with_progress(module: ModuleType, separator: str) -> TestResults:
|
|
20
|
-
@measure_time(progress, message=f"Testing module '{module.__name__}' {separator}took")
|
|
21
|
-
def internal() -> TestResults:
|
|
22
|
-
return testmod(m=module)
|
|
23
|
-
return internal()
|
|
24
|
-
|
|
25
|
-
# Main program
|
|
26
|
-
def launch_tests(root_dir: str, importing_errors: LogLevels = LogLevels.WARNING_TRACEBACK, strict: bool = True) -> None:
|
|
27
|
-
""" Main function to launch tests for all modules in the given directory.
|
|
28
|
-
|
|
29
|
-
Args:
|
|
30
|
-
root_dir (str): Root directory to search for modules
|
|
31
|
-
importing_errors (LogLevels): Log level for the errors when importing modules
|
|
32
|
-
strict (bool): Modify the force_raise_exception variable to True in the decorators module
|
|
33
|
-
|
|
34
|
-
Examples:
|
|
35
|
-
>>> launch_tests("unknown_dir")
|
|
36
|
-
Traceback (most recent call last):
|
|
37
|
-
...
|
|
38
|
-
ValueError: No modules found in 'unknown_dir'
|
|
39
|
-
|
|
40
|
-
.. code-block:: python
|
|
41
|
-
|
|
42
|
-
> launch_tests("/path/to/source")
|
|
43
|
-
[PROGRESS HH:MM:SS] Importing module 'module1' took 0.001s
|
|
44
|
-
[PROGRESS HH:MM:SS] Importing module 'module2' took 0.002s
|
|
45
|
-
[PROGRESS HH:MM:SS] Importing module 'module3' took 0.003s
|
|
46
|
-
[PROGRESS HH:MM:SS] Importing module 'module4' took 0.004s
|
|
47
|
-
[INFO HH:MM:SS] Testing 4 modules...
|
|
48
|
-
[PROGRESS HH:MM:SS] Testing module 'module1' took 0.005s
|
|
49
|
-
[PROGRESS HH:MM:SS] Testing module 'module2' took 0.006s
|
|
50
|
-
[PROGRESS HH:MM:SS] Testing module 'module3' took 0.007s
|
|
51
|
-
[PROGRESS HH:MM:SS] Testing module 'module4' took 0.008s
|
|
52
|
-
"""
|
|
53
|
-
if strict:
|
|
54
|
-
old_value: bool = strict
|
|
55
|
-
decorators.force_raise_exception = True
|
|
56
|
-
strict = old_value
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# Get all modules from folder
|
|
60
|
-
sys.path.insert(0, root_dir)
|
|
61
|
-
modules_file_paths: list[str] = []
|
|
62
|
-
for directory_path, _, _ in os.walk(root_dir):
|
|
63
|
-
for module_info in pkgutil.walk_packages([directory_path]):
|
|
64
|
-
absolute_module_path: str = os.path.join(directory_path, module_info.name)
|
|
65
|
-
path: str = absolute_module_path.split(root_dir, 1)[1].replace(os.sep, ".")[1:]
|
|
66
|
-
if path not in modules_file_paths:
|
|
67
|
-
modules_file_paths.append(path)
|
|
68
|
-
if not modules_file_paths:
|
|
69
|
-
raise ValueError(f"No modules found in '{root_dir}'")
|
|
70
|
-
|
|
71
|
-
# Find longest module path for alignment
|
|
72
|
-
max_length: int = max(len(path) for path in modules_file_paths)
|
|
73
|
-
|
|
74
|
-
# Dynamically import all modules from iacob package recursively using pkgutil and importlib
|
|
75
|
-
modules: list[ModuleType] = []
|
|
76
|
-
separators: list[str] = []
|
|
77
|
-
for module_path in modules_file_paths:
|
|
78
|
-
separator: str = " " * (max_length - len(module_path))
|
|
79
|
-
@handle_error(error_log=importing_errors)
|
|
80
|
-
@measure_time(progress, message=f"Importing module '{module_path}' {separator}took")
|
|
81
|
-
def internal() -> None:
|
|
82
|
-
modules.append(importlib.import_module(module_path))
|
|
83
|
-
separators.append(separator)
|
|
84
|
-
internal()
|
|
85
|
-
|
|
86
|
-
# Run tests for each module
|
|
87
|
-
info(f"Testing {len(modules)} modules...")
|
|
88
|
-
separators = [s + " "*(len("Importing") - len("Testing")) for s in separators]
|
|
89
|
-
results: list[TestResults] = [test_module_with_progress(module, separator) for module, separator in zip(modules, separators)]
|
|
90
|
-
|
|
91
|
-
# Display any error lines for each module at the end of the script
|
|
92
|
-
for module, result in zip(modules, results):
|
|
93
|
-
if result.failed > 0:
|
|
94
|
-
error(f"Errors in module {module.__name__}", exit=False)
|
|
95
|
-
|
|
96
|
-
# Reset force_raise_exception back
|
|
97
|
-
decorators.force_raise_exception = strict
|
|
98
|
-
|
|
1
|
+
"""
|
|
2
|
+
This module is used to run all the doctests for all the modules in a given directory.
|
|
3
|
+
|
|
4
|
+
.. image:: https://raw.githubusercontent.com/Stoupy51/stouputils/refs/heads/main/assets/all_doctests_module.gif
|
|
5
|
+
:alt: stouputils all_doctests examples
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
# Imports
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
from .print import info, error, progress
|
|
12
|
+
from .decorators import measure_time, handle_error, LogLevels
|
|
13
|
+
from . import decorators
|
|
14
|
+
from doctest import TestResults, testmod
|
|
15
|
+
from types import ModuleType
|
|
16
|
+
import importlib
|
|
17
|
+
import pkgutil
|
|
18
|
+
|
|
19
|
+
def test_module_with_progress(module: ModuleType, separator: str) -> TestResults:
|
|
20
|
+
@measure_time(progress, message=f"Testing module '{module.__name__}' {separator}took")
|
|
21
|
+
def internal() -> TestResults:
|
|
22
|
+
return testmod(m=module)
|
|
23
|
+
return internal()
|
|
24
|
+
|
|
25
|
+
# Main program
|
|
26
|
+
def launch_tests(root_dir: str, importing_errors: LogLevels = LogLevels.WARNING_TRACEBACK, strict: bool = True) -> None:
|
|
27
|
+
""" Main function to launch tests for all modules in the given directory.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
root_dir (str): Root directory to search for modules
|
|
31
|
+
importing_errors (LogLevels): Log level for the errors when importing modules
|
|
32
|
+
strict (bool): Modify the force_raise_exception variable to True in the decorators module
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
>>> launch_tests("unknown_dir")
|
|
36
|
+
Traceback (most recent call last):
|
|
37
|
+
...
|
|
38
|
+
ValueError: No modules found in 'unknown_dir'
|
|
39
|
+
|
|
40
|
+
.. code-block:: python
|
|
41
|
+
|
|
42
|
+
> launch_tests("/path/to/source")
|
|
43
|
+
[PROGRESS HH:MM:SS] Importing module 'module1' took 0.001s
|
|
44
|
+
[PROGRESS HH:MM:SS] Importing module 'module2' took 0.002s
|
|
45
|
+
[PROGRESS HH:MM:SS] Importing module 'module3' took 0.003s
|
|
46
|
+
[PROGRESS HH:MM:SS] Importing module 'module4' took 0.004s
|
|
47
|
+
[INFO HH:MM:SS] Testing 4 modules...
|
|
48
|
+
[PROGRESS HH:MM:SS] Testing module 'module1' took 0.005s
|
|
49
|
+
[PROGRESS HH:MM:SS] Testing module 'module2' took 0.006s
|
|
50
|
+
[PROGRESS HH:MM:SS] Testing module 'module3' took 0.007s
|
|
51
|
+
[PROGRESS HH:MM:SS] Testing module 'module4' took 0.008s
|
|
52
|
+
"""
|
|
53
|
+
if strict:
|
|
54
|
+
old_value: bool = strict
|
|
55
|
+
decorators.force_raise_exception = True
|
|
56
|
+
strict = old_value
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# Get all modules from folder
|
|
60
|
+
sys.path.insert(0, root_dir)
|
|
61
|
+
modules_file_paths: list[str] = []
|
|
62
|
+
for directory_path, _, _ in os.walk(root_dir):
|
|
63
|
+
for module_info in pkgutil.walk_packages([directory_path]):
|
|
64
|
+
absolute_module_path: str = os.path.join(directory_path, module_info.name)
|
|
65
|
+
path: str = absolute_module_path.split(root_dir, 1)[1].replace(os.sep, ".")[1:]
|
|
66
|
+
if path not in modules_file_paths:
|
|
67
|
+
modules_file_paths.append(path)
|
|
68
|
+
if not modules_file_paths:
|
|
69
|
+
raise ValueError(f"No modules found in '{root_dir}'")
|
|
70
|
+
|
|
71
|
+
# Find longest module path for alignment
|
|
72
|
+
max_length: int = max(len(path) for path in modules_file_paths)
|
|
73
|
+
|
|
74
|
+
# Dynamically import all modules from iacob package recursively using pkgutil and importlib
|
|
75
|
+
modules: list[ModuleType] = []
|
|
76
|
+
separators: list[str] = []
|
|
77
|
+
for module_path in modules_file_paths:
|
|
78
|
+
separator: str = " " * (max_length - len(module_path))
|
|
79
|
+
@handle_error(error_log=importing_errors)
|
|
80
|
+
@measure_time(progress, message=f"Importing module '{module_path}' {separator}took")
|
|
81
|
+
def internal() -> None:
|
|
82
|
+
modules.append(importlib.import_module(module_path))
|
|
83
|
+
separators.append(separator)
|
|
84
|
+
internal()
|
|
85
|
+
|
|
86
|
+
# Run tests for each module
|
|
87
|
+
info(f"Testing {len(modules)} modules...")
|
|
88
|
+
separators = [s + " "*(len("Importing") - len("Testing")) for s in separators]
|
|
89
|
+
results: list[TestResults] = [test_module_with_progress(module, separator) for module, separator in zip(modules, separators)]
|
|
90
|
+
|
|
91
|
+
# Display any error lines for each module at the end of the script
|
|
92
|
+
for module, result in zip(modules, results):
|
|
93
|
+
if result.failed > 0:
|
|
94
|
+
error(f"Errors in module {module.__name__}", exit=False)
|
|
95
|
+
|
|
96
|
+
# Reset force_raise_exception back
|
|
97
|
+
decorators.force_raise_exception = strict
|
|
98
|
+
|
|
@@ -447,7 +447,8 @@ def update_documentation(
|
|
|
447
447
|
version = version.replace("v", "") if isinstance(version, str) else version
|
|
448
448
|
|
|
449
449
|
# Modify build directory if version is specified
|
|
450
|
-
|
|
450
|
+
latest_dir: str = f"{html_dir}/latest"
|
|
451
|
+
build_dir: str = latest_dir if not version else f"{html_dir}/v{version}"
|
|
451
452
|
|
|
452
453
|
# Create directories if they don't exist
|
|
453
454
|
for dir in [modules_dir, static_dir, templates_dir]:
|
|
@@ -502,6 +503,12 @@ def update_documentation(
|
|
|
502
503
|
# Add index.html to the build directory that redirects to the latest version
|
|
503
504
|
generate_redirect_function(f"{html_dir}/index.html")
|
|
504
505
|
|
|
506
|
+
# If version is specified, copy the build directory to latest too
|
|
507
|
+
# This is useful for GitHub Actions to prevent re-building the documentation from scratch without the version
|
|
508
|
+
if version:
|
|
509
|
+
shutil.rmtree(latest_dir)
|
|
510
|
+
shutil.copytree(build_dir, latest_dir)
|
|
511
|
+
|
|
505
512
|
info(f"Documentation updated successfully!")
|
|
506
513
|
info(f"You can view the documentation by opening {build_dir}/index.html")
|
|
507
514
|
|