stouputils 1.2.0__tar.gz → 1.2.2__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.2/PKG-INFO +70 -0
- stouputils-1.2.2/README.md +51 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/pyproject.toml +2 -1
- stouputils-1.2.2/stouputils/__init__.py +31 -0
- stouputils-1.2.2/stouputils/applications/__init__.py +15 -0
- stouputils-1.2.2/stouputils/applications/automatic_docs.py +507 -0
- stouputils-1.2.2/stouputils/continuous_delivery/__init__.py +24 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/continuous_delivery/cd_utils.py +55 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/continuous_delivery/github.py +1 -54
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/print.py +27 -8
- stouputils-1.2.0/PKG-INFO +0 -60
- stouputils-1.2.0/README.md +0 -42
- stouputils-1.2.0/stouputils/__init__.py +0 -15
- stouputils-1.2.0/stouputils/continuous_delivery/__init__.py +0 -7
- {stouputils-1.2.0 → stouputils-1.2.2}/.gitignore +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/LICENSE +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/all_doctests.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/archive.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/backup.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/collections.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/continuous_delivery/pypi.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/continuous_delivery/pyproject.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/ctx.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/decorators.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/dont_look/zip_file_override.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/io.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/parallel.py +0 -0
- {stouputils-1.2.0 → stouputils-1.2.2}/stouputils/py.typed +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stouputils
|
|
3
|
+
Version: 1.2.2
|
|
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
|
+
Project-URL: Homepage, https://github.com/Stoupy51/stouputils
|
|
6
|
+
Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
|
|
7
|
+
Author-email: Stoupy51 <stoupy51@gmail.com>
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Requires-Dist: m2r2>=0.3.3.post2
|
|
14
|
+
Requires-Dist: pyyaml>=6.0.0
|
|
15
|
+
Requires-Dist: requests>=2.30.0
|
|
16
|
+
Requires-Dist: toml>=0.10.0
|
|
17
|
+
Requires-Dist: tqdm>=4.66.0
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# 🛠️ Project Badges
|
|
22
|
+
[](https://github.com/Stoupy51/stouputils/releases/latest)
|
|
23
|
+
[](https://pypi.org/project/stouputils/)
|
|
24
|
+
[](https://stoupy51.github.io/stouputils/latest/)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# 📚 Project Overview
|
|
28
|
+
Stouputils is a collection of utility modules designed to simplify and enhance the development process.<br>
|
|
29
|
+
It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# 🚀 Project File Tree
|
|
33
|
+
```bash
|
|
34
|
+
stouputils/
|
|
35
|
+
├── applications/
|
|
36
|
+
│ ├── automatic_docs.py # 📚 Documentation generation utilities (used to create this documentation)
|
|
37
|
+
│ └── ...
|
|
38
|
+
│
|
|
39
|
+
├── continuous_delivery/
|
|
40
|
+
│ ├── cd_utils.py # 🔧 Common utilities for continuous delivery
|
|
41
|
+
│ ├── github.py # 📦 GitHub utilities (upload_to_github)
|
|
42
|
+
│ ├── pypi.py # 📦 PyPI utilities (pypi_full_routine)
|
|
43
|
+
│ ├── pyproject.py # 📝 Pyproject.toml utilities
|
|
44
|
+
│ └── ...
|
|
45
|
+
│
|
|
46
|
+
├── print.py # 🖨️ Display utilities (info, debug, warning, error)
|
|
47
|
+
├── io.py # 💻 I/O utilities (file management, json)
|
|
48
|
+
├── decorators.py # 🎯 Decorators (silent, measure_time, error_handler, simple_cache)
|
|
49
|
+
├── ctx.py # 🚫 Context managers (Muffle, LogToFile)
|
|
50
|
+
├── archive.py # 📦 Archive utilities (zip, repair_zip)
|
|
51
|
+
├── parallel.py # 🧑🤝🧑 Parallel processing (multiprocessing, multithreading)
|
|
52
|
+
├── collections.py # 🧰 Collection utilities (unique_list)
|
|
53
|
+
├── all_doctests.py # ✅ Execution of all doctests for a given path
|
|
54
|
+
├── backup.py # 📦 Backup utilities (delta backup, consolidate)
|
|
55
|
+
└── ...
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## ⭐ Star History
|
|
60
|
+
|
|
61
|
+
<html>
|
|
62
|
+
<a href="https://star-history.com/#Stoupy51/stouputils&Date">
|
|
63
|
+
<picture>
|
|
64
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
|
|
65
|
+
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
66
|
+
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
67
|
+
</picture>
|
|
68
|
+
</a>
|
|
69
|
+
</html>
|
|
70
|
+
|
|
@@ -0,0 +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
|
+
|
|
@@ -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.2"
|
|
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"
|
|
@@ -19,6 +19,7 @@ dependencies = [
|
|
|
19
19
|
"requests>=2.30.0",
|
|
20
20
|
"pyyaml>=6.0.0",
|
|
21
21
|
"toml>=0.10.0",
|
|
22
|
+
"m2r2>=0.3.3.post2",
|
|
22
23
|
]
|
|
23
24
|
[[project.authors]]
|
|
24
25
|
name = "Stoupy51"
|
|
@@ -0,0 +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
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
""" Application-specific utilities and tools.
|
|
2
|
+
|
|
3
|
+
This module provides higher-level utilities for specific application needs:
|
|
4
|
+
|
|
5
|
+
Key Features:
|
|
6
|
+
- Automatic documentation generation with Sphinx: `update_documentation(...)`
|
|
7
|
+
- Support for multi-version documentation
|
|
8
|
+
- GitHub Pages integration
|
|
9
|
+
- Markdown to RST conversion
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# Imports
|
|
14
|
+
from .automatic_docs import *
|
|
15
|
+
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
""" Sphinx documentation generation utilities.
|
|
2
|
+
|
|
3
|
+
This module provides a comprehensive set of utilities for automatically generating
|
|
4
|
+
and managing Sphinx documentation for Python projects. It handles the creation
|
|
5
|
+
of configuration files, index pages, version management, and HTML generation.
|
|
6
|
+
|
|
7
|
+
Example of usage:
|
|
8
|
+
|
|
9
|
+
.. code-block:: python
|
|
10
|
+
|
|
11
|
+
import stouputils as stp
|
|
12
|
+
from stouputils.applications import automatic_docs
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
automatic_docs.update_documentation(
|
|
16
|
+
root_path=stp.get_root_path(__file__, go_up=1),
|
|
17
|
+
project="stouputils",
|
|
18
|
+
author="Stoupy",
|
|
19
|
+
copyright="2025, Stoupy",
|
|
20
|
+
html_logo="https://avatars.githubusercontent.com/u/35665974",
|
|
21
|
+
html_favicon="https://avatars.githubusercontent.com/u/35665974",
|
|
22
|
+
github_user="Stoupy51",
|
|
23
|
+
github_repo="stouputils",
|
|
24
|
+
version="1.2.0",
|
|
25
|
+
skip_undocumented=True,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
.. image:: https://raw.githubusercontent.com/Stoupy51/stouputils/refs/heads/main/assets/applications/automatic_docs.gif
|
|
29
|
+
:alt: stouputils automatic_docs examples
|
|
30
|
+
|
|
31
|
+
Note:
|
|
32
|
+
This module requires Sphinx and its dependencies to be installed.
|
|
33
|
+
It also requires the 'm2r2' package for Markdown to RST conversion.
|
|
34
|
+
|
|
35
|
+
Example of GitHub Actions workflow:
|
|
36
|
+
|
|
37
|
+
.. code-block:: yaml
|
|
38
|
+
|
|
39
|
+
name: documentation
|
|
40
|
+
|
|
41
|
+
on:
|
|
42
|
+
push:
|
|
43
|
+
branches:
|
|
44
|
+
- main
|
|
45
|
+
tags:
|
|
46
|
+
- 'v*'
|
|
47
|
+
pull_request:
|
|
48
|
+
workflow_dispatch:
|
|
49
|
+
|
|
50
|
+
permissions:
|
|
51
|
+
contents: write
|
|
52
|
+
|
|
53
|
+
jobs:
|
|
54
|
+
docs:
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@v4
|
|
58
|
+
- uses: actions/setup-python@v5
|
|
59
|
+
- name: Install dependencies
|
|
60
|
+
run: |
|
|
61
|
+
pip install hatch stouputils sphinx sphinx_rtd_theme myst_parser furo m2r2
|
|
62
|
+
hatch build
|
|
63
|
+
- name: Build latest docs
|
|
64
|
+
if: github.ref == 'refs/heads/main'
|
|
65
|
+
run: |
|
|
66
|
+
python scripts/create_docs.py
|
|
67
|
+
- name: Build version docs
|
|
68
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
69
|
+
run: |
|
|
70
|
+
python scripts/create_docs.py ${GITHUB_REF#refs/tags/v}
|
|
71
|
+
- name: Deploy to GitHub Pages
|
|
72
|
+
uses: peaceiris/actions-gh-pages@v3
|
|
73
|
+
if: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') || startsWith(github.ref, 'refs/tags/v') }}
|
|
74
|
+
with:
|
|
75
|
+
publish_branch: gh-pages
|
|
76
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
77
|
+
publish_dir: docs/build/html
|
|
78
|
+
keep_files: true
|
|
79
|
+
force_orphan: false
|
|
80
|
+
"""
|
|
81
|
+
# Imports
|
|
82
|
+
import os
|
|
83
|
+
import shutil
|
|
84
|
+
import subprocess
|
|
85
|
+
import sys
|
|
86
|
+
from typing import Any, Callable
|
|
87
|
+
|
|
88
|
+
from ..io import clean_path, super_open, super_json_dump
|
|
89
|
+
from ..decorators import handle_error, simple_cache
|
|
90
|
+
from ..continuous_delivery import version_to_float
|
|
91
|
+
from ..print import info
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_sphinx_conf_content(
|
|
95
|
+
project: str,
|
|
96
|
+
author: str,
|
|
97
|
+
current_version: str,
|
|
98
|
+
copyright: str,
|
|
99
|
+
html_logo: str,
|
|
100
|
+
html_favicon: str,
|
|
101
|
+
github_user: str,
|
|
102
|
+
github_repo: str,
|
|
103
|
+
version_list: list[str] | None = None,
|
|
104
|
+
skip_undocumented: bool = True,
|
|
105
|
+
) -> str:
|
|
106
|
+
""" Get the content of the Sphinx configuration file.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
project (str): Name of the project
|
|
110
|
+
author (str): Author of the project
|
|
111
|
+
current_version (str): Current version
|
|
112
|
+
copyright (str): Copyright information
|
|
113
|
+
html_logo (str): URL to the logo
|
|
114
|
+
html_favicon (str): URL to the favicon
|
|
115
|
+
github_user (str): GitHub username
|
|
116
|
+
github_repo (str): GitHub repository name
|
|
117
|
+
version_list (list[str] | None): List of versions. Defaults to None
|
|
118
|
+
skip_undocumented (bool): Whether to skip undocumented members. Defaults to True
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
str: Content of the Sphinx configuration file
|
|
122
|
+
"""
|
|
123
|
+
conf_content: str = f"""
|
|
124
|
+
# Imports
|
|
125
|
+
import os
|
|
126
|
+
import sys
|
|
127
|
+
from typing import Any
|
|
128
|
+
|
|
129
|
+
# Project information
|
|
130
|
+
project: str = "{project}"
|
|
131
|
+
copyright: str = "{copyright}"
|
|
132
|
+
author: str = "{author}"
|
|
133
|
+
release: str = "{current_version}"
|
|
134
|
+
|
|
135
|
+
# General configuration
|
|
136
|
+
extensions: list[str] = [
|
|
137
|
+
"sphinx.ext.autodoc",
|
|
138
|
+
"sphinx.ext.napoleon",
|
|
139
|
+
"sphinx.ext.viewcode",
|
|
140
|
+
"sphinx.ext.githubpages",
|
|
141
|
+
"sphinx.ext.intersphinx",
|
|
142
|
+
"furo.sphinxext",
|
|
143
|
+
"m2r2",
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
templates_path: list[str] = ["_templates"]
|
|
147
|
+
exclude_patterns: list[str] = []
|
|
148
|
+
|
|
149
|
+
# HTML output options
|
|
150
|
+
html_theme: str = "furo"
|
|
151
|
+
html_static_path: list[str] = ["_static"]
|
|
152
|
+
html_logo: str = "{html_logo}"
|
|
153
|
+
html_title: str = "{project}"
|
|
154
|
+
html_favicon: str = "{html_favicon}"
|
|
155
|
+
|
|
156
|
+
# Theme options
|
|
157
|
+
html_theme_options: dict[str, Any] = {{
|
|
158
|
+
"light_css_variables": {{
|
|
159
|
+
"color-brand-primary": "#2980B9",
|
|
160
|
+
"color-brand-content": "#2980B9",
|
|
161
|
+
"color-admonition-background": "#E8F0F8",
|
|
162
|
+
}},
|
|
163
|
+
"dark_css_variables": {{
|
|
164
|
+
"color-brand-primary": "#56B4E9",
|
|
165
|
+
"color-brand-content": "#56B4E9",
|
|
166
|
+
"color-admonition-background": "#1F262B",
|
|
167
|
+
}},
|
|
168
|
+
"sidebar_hide_name": False,
|
|
169
|
+
"navigation_with_keys": True,
|
|
170
|
+
"announcement": "This is the latest documentation of {project}",
|
|
171
|
+
"footer_icons": [
|
|
172
|
+
{{
|
|
173
|
+
"name": "GitHub",
|
|
174
|
+
"url": "https://github.com/{github_user}/{github_repo}",
|
|
175
|
+
"html": "<i class='fab fa-github-square'></i>",
|
|
176
|
+
"class": "",
|
|
177
|
+
}},
|
|
178
|
+
],
|
|
179
|
+
}}
|
|
180
|
+
"""
|
|
181
|
+
# Create base html_context dictionary
|
|
182
|
+
html_context: dict[str, Any] = {
|
|
183
|
+
"display_github": True,
|
|
184
|
+
"github_user": github_user,
|
|
185
|
+
"github_repo": github_repo,
|
|
186
|
+
"github_version": "main",
|
|
187
|
+
"conf_py_path": "/docs/source/",
|
|
188
|
+
"source_suffix": [".rst", ".md"],
|
|
189
|
+
"default_mode": "dark",
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# Add version selector if versions are provided
|
|
193
|
+
if version_list and current_version:
|
|
194
|
+
html_context.update({
|
|
195
|
+
"versions": version_list,
|
|
196
|
+
"current_version": current_version,
|
|
197
|
+
})
|
|
198
|
+
html_context_str: str = super_json_dump(html_context, max_level=1).replace("true", "True").replace("false", "False")
|
|
199
|
+
|
|
200
|
+
conf_content += f"""
|
|
201
|
+
html_context = {html_context_str}
|
|
202
|
+
|
|
203
|
+
# Autodoc settings
|
|
204
|
+
autodoc_default_options: dict[str, bool | str] = {{
|
|
205
|
+
"members": True,
|
|
206
|
+
"member-order": "bysource",
|
|
207
|
+
"special-members": False,
|
|
208
|
+
"undoc-members": False,
|
|
209
|
+
"private-members": False,
|
|
210
|
+
"show-inheritance": True,
|
|
211
|
+
"ignore-module-all": True,
|
|
212
|
+
"exclude-members": "__weakref__",
|
|
213
|
+
}}
|
|
214
|
+
|
|
215
|
+
# Tell autodoc to prefer source code over installed package
|
|
216
|
+
autodoc_mock_imports = []
|
|
217
|
+
always_document_param_types = True
|
|
218
|
+
add_module_names = False
|
|
219
|
+
"""
|
|
220
|
+
|
|
221
|
+
if skip_undocumented:
|
|
222
|
+
conf_content += """
|
|
223
|
+
# Only document items with docstrings
|
|
224
|
+
def skip_undocumented(app: Any, what: str, name: str, obj: Any, skip: bool, *args: Any, **kwargs: Any) -> bool:
|
|
225
|
+
if not obj.__doc__:
|
|
226
|
+
return True
|
|
227
|
+
return skip
|
|
228
|
+
|
|
229
|
+
def setup(app: Any) -> None:
|
|
230
|
+
app.connect("autodoc-skip-member", skip_undocumented)
|
|
231
|
+
"""
|
|
232
|
+
return conf_content
|
|
233
|
+
|
|
234
|
+
@simple_cache()
|
|
235
|
+
def get_versions_from_github(github_user: str, github_repo: str) -> list[str]:
|
|
236
|
+
""" Get list of versions from GitHub gh-pages branch.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
github_user (str): GitHub username
|
|
240
|
+
github_repo (str): GitHub repository name
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
list[str]: List of versions, with 'latest' as first element
|
|
244
|
+
"""
|
|
245
|
+
import requests
|
|
246
|
+
version_list: list[str] = []
|
|
247
|
+
try:
|
|
248
|
+
response = requests.get(f"https://api.github.com/repos/{github_user}/{github_repo}/contents?ref=gh-pages")
|
|
249
|
+
if response.status_code == 200:
|
|
250
|
+
contents = response.json()
|
|
251
|
+
version_list = ["latest"] + sorted(
|
|
252
|
+
[d["name"].replace("v", "") for d in contents
|
|
253
|
+
if d["type"] == "dir" and d["name"].startswith("v")],
|
|
254
|
+
key=version_to_float,
|
|
255
|
+
reverse=True
|
|
256
|
+
)
|
|
257
|
+
except Exception as e:
|
|
258
|
+
info(f"Failed to get versions from GitHub: {e}")
|
|
259
|
+
version_list = ["latest"]
|
|
260
|
+
return version_list
|
|
261
|
+
|
|
262
|
+
def markdown_to_rst(markdown_content: str) -> str:
|
|
263
|
+
""" Convert markdown content to RST format.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
markdown_content (str): Markdown content
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
str: RST content
|
|
270
|
+
"""
|
|
271
|
+
if not markdown_content:
|
|
272
|
+
return ""
|
|
273
|
+
|
|
274
|
+
# Convert markdown to RST and return it
|
|
275
|
+
import m2r2 # type: ignore
|
|
276
|
+
return m2r2.convert(markdown_content) # type: ignore
|
|
277
|
+
|
|
278
|
+
def generate_index_rst(
|
|
279
|
+
readme_path: str,
|
|
280
|
+
index_path: str,
|
|
281
|
+
project: str,
|
|
282
|
+
github_user: str,
|
|
283
|
+
github_repo: str,
|
|
284
|
+
get_versions_function: Callable[[str, str], list[str]] = get_versions_from_github,
|
|
285
|
+
) -> None:
|
|
286
|
+
""" Generate index.rst from README.md content.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
readme_path (str): Path to the README.md file
|
|
290
|
+
index_path (str): Path where index.rst should be created
|
|
291
|
+
project (str): Name of the project
|
|
292
|
+
github_user (str): GitHub username
|
|
293
|
+
github_repo (str): GitHub repository name
|
|
294
|
+
get_versions_function (Callable[[str, str], list[str]]): Function to get versions from GitHub
|
|
295
|
+
"""
|
|
296
|
+
# Read README content
|
|
297
|
+
with open(readme_path, "r", encoding="utf-8") as f:
|
|
298
|
+
readme_content: str = f.read()
|
|
299
|
+
|
|
300
|
+
# Generate version selector
|
|
301
|
+
version_selector: str = "\n\n**Versions**: "
|
|
302
|
+
|
|
303
|
+
# Get versions from GitHub
|
|
304
|
+
version_list: list[str] = get_versions_function(github_user, github_repo)
|
|
305
|
+
|
|
306
|
+
# Create version links
|
|
307
|
+
version_links: list[str] = []
|
|
308
|
+
for version in version_list:
|
|
309
|
+
if version == "latest":
|
|
310
|
+
version_links.append("`latest <../latest/index.html>`_")
|
|
311
|
+
else:
|
|
312
|
+
version_links.append(f"`v{version} <../v{version}/index.html>`_")
|
|
313
|
+
version_selector += ", ".join(version_links)
|
|
314
|
+
|
|
315
|
+
# Generate module documentation section
|
|
316
|
+
module_docs: str = f"""
|
|
317
|
+
.. toctree::
|
|
318
|
+
:maxdepth: 10
|
|
319
|
+
|
|
320
|
+
modules/{project}
|
|
321
|
+
"""
|
|
322
|
+
|
|
323
|
+
# Convert markdown to RST
|
|
324
|
+
rst_content: str = f"""
|
|
325
|
+
🛠️ Welcome to {project.capitalize()} Documentation
|
|
326
|
+
{'=' * 100}
|
|
327
|
+
{version_selector}
|
|
328
|
+
|
|
329
|
+
{markdown_to_rst(readme_content)}
|
|
330
|
+
|
|
331
|
+
📖 Module Documentation
|
|
332
|
+
{'-' * 100}
|
|
333
|
+
{module_docs}
|
|
334
|
+
"""
|
|
335
|
+
|
|
336
|
+
# Write the RST file
|
|
337
|
+
with open(index_path, "w", encoding="utf-8") as f:
|
|
338
|
+
f.write(rst_content)
|
|
339
|
+
|
|
340
|
+
def generate_documentation(
|
|
341
|
+
source_dir: str,
|
|
342
|
+
modules_dir: str,
|
|
343
|
+
project_dir: str,
|
|
344
|
+
build_dir: str,
|
|
345
|
+
) -> None:
|
|
346
|
+
""" Generate documentation using Sphinx.
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
source_dir (str): Source directory
|
|
350
|
+
modules_dir (str): Modules directory
|
|
351
|
+
project_dir (str): Project directory
|
|
352
|
+
build_dir (str): Build directory
|
|
353
|
+
"""
|
|
354
|
+
# Generate module documentation using sphinx-apidoc
|
|
355
|
+
subprocess.run([
|
|
356
|
+
sys.executable,
|
|
357
|
+
"-m", "sphinx.ext.apidoc",
|
|
358
|
+
"-o", modules_dir,
|
|
359
|
+
"-f", "-e", "-M",
|
|
360
|
+
"--no-toc",
|
|
361
|
+
"-P",
|
|
362
|
+
"--implicit-namespaces",
|
|
363
|
+
"--module-first",
|
|
364
|
+
project_dir,
|
|
365
|
+
], check=True)
|
|
366
|
+
|
|
367
|
+
# Build HTML documentation
|
|
368
|
+
subprocess.run([
|
|
369
|
+
sys.executable,
|
|
370
|
+
"-m", "sphinx",
|
|
371
|
+
"-b", "html",
|
|
372
|
+
"-a",
|
|
373
|
+
source_dir,
|
|
374
|
+
build_dir,
|
|
375
|
+
], check=True)
|
|
376
|
+
|
|
377
|
+
def generate_redirect_html(filepath: str) -> None:
|
|
378
|
+
""" Generate HTML content for redirect page.
|
|
379
|
+
|
|
380
|
+
Args:
|
|
381
|
+
filepath (str): Path to the file where the HTML content should be written
|
|
382
|
+
"""
|
|
383
|
+
with super_open(filepath, "w", encoding="utf-8") as f:
|
|
384
|
+
f.write("""<!DOCTYPE html>
|
|
385
|
+
<html lang="en">
|
|
386
|
+
<head>
|
|
387
|
+
<meta charset="UTF-8">
|
|
388
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
389
|
+
<meta http-equiv="refresh" content="0;url=./latest/">
|
|
390
|
+
<title>Redirecting...</title>
|
|
391
|
+
</head>
|
|
392
|
+
<body>
|
|
393
|
+
<p>If you are not redirected automatically, <a href="./latest/">click here</a>.</p>
|
|
394
|
+
</body>
|
|
395
|
+
</html>
|
|
396
|
+
""")
|
|
397
|
+
|
|
398
|
+
@handle_error()
|
|
399
|
+
def update_documentation(
|
|
400
|
+
root_path: str,
|
|
401
|
+
project: str,
|
|
402
|
+
author: str = "Author",
|
|
403
|
+
copyright: str = "2025, Author",
|
|
404
|
+
html_logo: str = "",
|
|
405
|
+
html_favicon: str = "",
|
|
406
|
+
github_user: str = "",
|
|
407
|
+
github_repo: str = "",
|
|
408
|
+
version: str | None = None,
|
|
409
|
+
skip_undocumented: bool = True,
|
|
410
|
+
|
|
411
|
+
get_versions_function: Callable[[str, str], list[str]] = get_versions_from_github,
|
|
412
|
+
generate_index_function: Callable[..., None] = generate_index_rst,
|
|
413
|
+
generate_docs_function: Callable[..., None] = generate_documentation,
|
|
414
|
+
generate_redirect_function: Callable[[str], None] = generate_redirect_html,
|
|
415
|
+
get_conf_content_function: Callable[..., str] = get_sphinx_conf_content
|
|
416
|
+
) -> None:
|
|
417
|
+
""" Update the Sphinx documentation.
|
|
418
|
+
|
|
419
|
+
Args:
|
|
420
|
+
root_path (str): Root path of the project
|
|
421
|
+
project (str): Name of the project
|
|
422
|
+
author (str): Author of the project
|
|
423
|
+
copyright (str): Copyright information
|
|
424
|
+
html_logo (str): URL to the logo
|
|
425
|
+
html_favicon (str): URL to the favicon
|
|
426
|
+
github_user (str): GitHub username
|
|
427
|
+
github_repo (str): GitHub repository name
|
|
428
|
+
version (str | None): Version to build documentation for (e.g. "1.0.0", defaults to "latest")
|
|
429
|
+
skip_undocumented (bool): Whether to skip undocumented members. Defaults to True
|
|
430
|
+
|
|
431
|
+
get_versions_function (Callable[[str, str], list[str]]): Function to get versions from GitHub
|
|
432
|
+
generate_index_function (Callable[..., None]): Function to generate index.rst
|
|
433
|
+
generate_docs_function (Callable[..., None]): Function to generate documentation
|
|
434
|
+
generate_redirect_function (Callable[[str], None]): Function to create redirect file
|
|
435
|
+
get_conf_content_function (Callable[..., str]): Function to get Sphinx conf.py content
|
|
436
|
+
"""
|
|
437
|
+
# Setup paths
|
|
438
|
+
root_path = clean_path(root_path)
|
|
439
|
+
docs_dir: str = f"{root_path}/docs"
|
|
440
|
+
source_dir: str = f"{docs_dir}/source"
|
|
441
|
+
modules_dir: str = f"{source_dir}/modules"
|
|
442
|
+
static_dir: str = f"{source_dir}/_static"
|
|
443
|
+
templates_dir: str = f"{source_dir}/_templates"
|
|
444
|
+
html_dir: str = f"{docs_dir}/build/html"
|
|
445
|
+
|
|
446
|
+
# Remove "v" from version if it is a string (just in case)
|
|
447
|
+
version = version.replace("v", "") if isinstance(version, str) else version
|
|
448
|
+
|
|
449
|
+
# Modify build directory if version is specified
|
|
450
|
+
build_dir: str = f"{html_dir}/latest" if not version else f"{html_dir}/v{version}"
|
|
451
|
+
|
|
452
|
+
# Create directories if they don't exist
|
|
453
|
+
for dir in [modules_dir, static_dir, templates_dir]:
|
|
454
|
+
os.makedirs(dir, exist_ok=True)
|
|
455
|
+
|
|
456
|
+
# Generate index.rst from README.md
|
|
457
|
+
readme_path: str = f"{root_path}/README.md"
|
|
458
|
+
index_path: str = f"{source_dir}/index.rst"
|
|
459
|
+
generate_index_function(
|
|
460
|
+
readme_path=readme_path,
|
|
461
|
+
index_path=index_path,
|
|
462
|
+
project=project,
|
|
463
|
+
github_user=github_user,
|
|
464
|
+
github_repo=github_repo,
|
|
465
|
+
get_versions_function=get_versions_function,
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
# Clean up old module documentation
|
|
469
|
+
if os.path.exists(modules_dir):
|
|
470
|
+
shutil.rmtree(modules_dir)
|
|
471
|
+
os.makedirs(modules_dir)
|
|
472
|
+
|
|
473
|
+
# Get versions and current version for conf.py
|
|
474
|
+
version_list: list[str] = get_versions_function(github_user, github_repo)
|
|
475
|
+
current_version: str = version if version else "latest"
|
|
476
|
+
|
|
477
|
+
# Generate conf.py
|
|
478
|
+
conf_path: str = f"{source_dir}/conf.py"
|
|
479
|
+
conf_content: str = get_conf_content_function(
|
|
480
|
+
project=project,
|
|
481
|
+
author=author,
|
|
482
|
+
current_version=current_version,
|
|
483
|
+
copyright=copyright,
|
|
484
|
+
html_logo=html_logo,
|
|
485
|
+
html_favicon=html_favicon,
|
|
486
|
+
github_user=github_user,
|
|
487
|
+
github_repo=github_repo,
|
|
488
|
+
version_list=version_list,
|
|
489
|
+
skip_undocumented=skip_undocumented,
|
|
490
|
+
)
|
|
491
|
+
with open(conf_path, "w", encoding="utf-8") as f:
|
|
492
|
+
f.write(conf_content)
|
|
493
|
+
|
|
494
|
+
# Generate documentation
|
|
495
|
+
generate_docs_function(
|
|
496
|
+
source_dir=source_dir,
|
|
497
|
+
modules_dir=modules_dir,
|
|
498
|
+
project_dir=f"{root_path}/{project}",
|
|
499
|
+
build_dir=build_dir,
|
|
500
|
+
)
|
|
501
|
+
|
|
502
|
+
# Add index.html to the build directory that redirects to the latest version
|
|
503
|
+
generate_redirect_function(f"{html_dir}/index.html")
|
|
504
|
+
|
|
505
|
+
info(f"Documentation updated successfully!")
|
|
506
|
+
info(f"You can view the documentation by opening {build_dir}/index.html")
|
|
507
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
""" Continuous delivery and deployment utilities.
|
|
2
|
+
|
|
3
|
+
This module provides tools for automating software delivery and deployment:
|
|
4
|
+
|
|
5
|
+
Key Features:
|
|
6
|
+
- GitHub release management and uploads
|
|
7
|
+
- PyPI package publishing utilities
|
|
8
|
+
- pyproject.toml file management
|
|
9
|
+
- Common CD/CI utilities
|
|
10
|
+
|
|
11
|
+
Components:
|
|
12
|
+
- cd_utils: Common utilities for continuous delivery
|
|
13
|
+
- github: GitHub-specific utilities (upload_to_github)
|
|
14
|
+
- pypi: PyPI publishing tools (pypi_full_routine)
|
|
15
|
+
- pyproject: pyproject.toml file management
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
# Imports
|
|
20
|
+
from .cd_utils import *
|
|
21
|
+
from .github import *
|
|
22
|
+
from .pypi import *
|
|
23
|
+
from .pyproject import *
|
|
24
|
+
|
|
@@ -78,3 +78,58 @@ def handle_response(response: requests.Response, error_message: str) -> None:
|
|
|
78
78
|
except requests.exceptions.JSONDecodeError:
|
|
79
79
|
raise ValueError(f"{error_message}, response code {response.status_code} with response {response.text}")
|
|
80
80
|
|
|
81
|
+
# Clean a version string
|
|
82
|
+
def clean_version(version: str, keep: str = "") -> str:
|
|
83
|
+
""" Clean a version string
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
version (str): The version string to clean
|
|
87
|
+
keep (str): The characters to keep in the version string
|
|
88
|
+
Returns:
|
|
89
|
+
str: The cleaned version string
|
|
90
|
+
|
|
91
|
+
>>> clean_version("v1.e0.zfezf0.1.2.3zefz")
|
|
92
|
+
'1.0.0.1.2.3'
|
|
93
|
+
>>> clean_version("v1.e0.zfezf0.1.2.3zefz", keep="v")
|
|
94
|
+
'v1.0.0.1.2.3'
|
|
95
|
+
>>> clean_version("v1.2.3b", keep="ab")
|
|
96
|
+
'1.2.3b'
|
|
97
|
+
"""
|
|
98
|
+
return "".join(c for c in version if c in "0123456789." + keep)
|
|
99
|
+
|
|
100
|
+
# Convert a version string to a float
|
|
101
|
+
def version_to_float(version: str) -> float:
|
|
102
|
+
""" Converts a version string into a float for comparison purposes.
|
|
103
|
+
The version string is expected to follow the format of major.minor.patch.something_else....,
|
|
104
|
+
where each part is separated by a dot and can be extended indefinitely.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
version (str): The version string to convert. (e.g. "v1.0.0.1.2.3")
|
|
108
|
+
Returns:
|
|
109
|
+
float: The float representation of the version. (e.g. 0)
|
|
110
|
+
|
|
111
|
+
>>> version_to_float("v1.0.0")
|
|
112
|
+
1.0
|
|
113
|
+
>>> version_to_float("v1.0.0.1")
|
|
114
|
+
1.000000001
|
|
115
|
+
>>> version_to_float("v2.3.7")
|
|
116
|
+
2.003007
|
|
117
|
+
>>> version_to_float("v1.0.0.1.2.3")
|
|
118
|
+
1.0000000010020031
|
|
119
|
+
>>> version_to_float("v2.0") > version_to_float("v1.0.0.1")
|
|
120
|
+
True
|
|
121
|
+
"""
|
|
122
|
+
# Clean the version string by keeping only the numbers and dots
|
|
123
|
+
version = clean_version(version)
|
|
124
|
+
|
|
125
|
+
# Split the version string into parts
|
|
126
|
+
version_parts: list[str] = version.split(".")
|
|
127
|
+
total: float = 0.0
|
|
128
|
+
multiplier: float = 1.0
|
|
129
|
+
|
|
130
|
+
# Iterate over the parts and add lesser and lesser weight to each part
|
|
131
|
+
for part in version_parts:
|
|
132
|
+
total += int(part) * multiplier
|
|
133
|
+
multiplier /= 1_000
|
|
134
|
+
return total
|
|
135
|
+
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
from ..print import info, warning, progress
|
|
11
11
|
from ..decorators import measure_time, handle_error
|
|
12
12
|
from ..io import clean_path
|
|
13
|
-
from .cd_utils import handle_response
|
|
13
|
+
from .cd_utils import handle_response, version_to_float, clean_version
|
|
14
14
|
from typing import Any
|
|
15
15
|
import requests
|
|
16
16
|
import os
|
|
@@ -140,59 +140,6 @@ def delete_existing_tag(tag_url: str, headers: dict[str, str]) -> None:
|
|
|
140
140
|
handle_response(delete_response, "Failed to delete existing tag")
|
|
141
141
|
info("Deleted existing tag")
|
|
142
142
|
|
|
143
|
-
def clean_version(version: str, keep: str = "") -> str:
|
|
144
|
-
""" Clean a version string
|
|
145
|
-
|
|
146
|
-
Args:
|
|
147
|
-
version (str): The version string to clean
|
|
148
|
-
keep (str): The characters to keep in the version string
|
|
149
|
-
Returns:
|
|
150
|
-
str: The cleaned version string
|
|
151
|
-
|
|
152
|
-
>>> clean_version("v1.e0.zfezf0.1.2.3zefz")
|
|
153
|
-
'1.0.0.1.2.3'
|
|
154
|
-
>>> clean_version("v1.e0.zfezf0.1.2.3zefz", keep="v")
|
|
155
|
-
'v1.0.0.1.2.3'
|
|
156
|
-
>>> clean_version("v1.2.3b", keep="ab")
|
|
157
|
-
'1.2.3b'
|
|
158
|
-
"""
|
|
159
|
-
return "".join(c for c in version if c in "0123456789." + keep)
|
|
160
|
-
|
|
161
|
-
def version_to_float(version: str) -> float:
|
|
162
|
-
""" Converts a version string into a float for comparison purposes.
|
|
163
|
-
The version string is expected to follow the format of major.minor.patch.something_else....,
|
|
164
|
-
where each part is separated by a dot and can be extended indefinitely.
|
|
165
|
-
|
|
166
|
-
Args:
|
|
167
|
-
version (str): The version string to convert. (e.g. "v1.0.0.1.2.3")
|
|
168
|
-
Returns:
|
|
169
|
-
float: The float representation of the version. (e.g. 0)
|
|
170
|
-
|
|
171
|
-
>>> version_to_float("v1.0.0")
|
|
172
|
-
1.0
|
|
173
|
-
>>> version_to_float("v1.0.0.1")
|
|
174
|
-
1.000000001
|
|
175
|
-
>>> version_to_float("v2.3.7")
|
|
176
|
-
2.003007
|
|
177
|
-
>>> version_to_float("v1.0.0.1.2.3")
|
|
178
|
-
1.0000000010020031
|
|
179
|
-
>>> version_to_float("v2.0") > version_to_float("v1.0.0.1")
|
|
180
|
-
True
|
|
181
|
-
"""
|
|
182
|
-
# Clean the version string by keeping only the numbers and dots
|
|
183
|
-
version = clean_version(version)
|
|
184
|
-
|
|
185
|
-
# Split the version string into parts
|
|
186
|
-
version_parts: list[str] = version.split(".")
|
|
187
|
-
total: float = 0.0
|
|
188
|
-
multiplier: float = 1.0
|
|
189
|
-
|
|
190
|
-
# Iterate over the parts and add lesser and lesser weight to each part
|
|
191
|
-
for part in version_parts:
|
|
192
|
-
total += int(part) * multiplier
|
|
193
|
-
multiplier /= 1_000
|
|
194
|
-
return total
|
|
195
|
-
|
|
196
143
|
def get_latest_tag(owner: str, project_name: str, version: str, headers: dict[str, str]) -> tuple[str, str] | tuple[None, None]:
|
|
197
144
|
""" Get latest tag information
|
|
198
145
|
|
|
@@ -83,15 +83,23 @@ def info(*values: Any, color: str = GREEN, text: str = "INFO ", prefix: str = ""
|
|
|
83
83
|
print(remove_colors(message), *(remove_colors(str(v)) for v in values), file=log_file, **print_kwargs)
|
|
84
84
|
|
|
85
85
|
def debug(*values: Any, **print_kwargs: Any) -> None:
|
|
86
|
-
""" Print a debug message looking like "[DEBUG HH:MM:SS] message" """
|
|
86
|
+
""" Print a debug message looking like "[DEBUG HH:MM:SS] message" in blue by default. """
|
|
87
87
|
if "text" not in print_kwargs:
|
|
88
88
|
print_kwargs["text"] = "DEBUG"
|
|
89
89
|
if "color" not in print_kwargs:
|
|
90
90
|
print_kwargs["color"] = BLUE
|
|
91
91
|
info(*values, **print_kwargs)
|
|
92
92
|
|
|
93
|
+
def alt_debug(*values: Any, **print_kwargs: Any) -> None:
|
|
94
|
+
""" Print a debug message looking like "[DEBUG HH:MM:SS] message" in cyan by default. """
|
|
95
|
+
if "text" not in print_kwargs:
|
|
96
|
+
print_kwargs["text"] = "DEBUG"
|
|
97
|
+
if "color" not in print_kwargs:
|
|
98
|
+
print_kwargs["color"] = CYAN
|
|
99
|
+
info(*values, **print_kwargs)
|
|
100
|
+
|
|
93
101
|
def suggestion(*values: Any, **print_kwargs: Any) -> None:
|
|
94
|
-
""" Print a suggestion message looking like "[SUGGESTION HH:MM:SS] message" """
|
|
102
|
+
""" Print a suggestion message looking like "[SUGGESTION HH:MM:SS] message" in cyan by default. """
|
|
95
103
|
if "text" not in print_kwargs:
|
|
96
104
|
print_kwargs["text"] = "SUGGESTION"
|
|
97
105
|
if "color" not in print_kwargs:
|
|
@@ -99,7 +107,7 @@ def suggestion(*values: Any, **print_kwargs: Any) -> None:
|
|
|
99
107
|
info(*values, **print_kwargs)
|
|
100
108
|
|
|
101
109
|
def progress(*values: Any, **print_kwargs: Any) -> None:
|
|
102
|
-
""" Print a progress message looking like "[PROGRESS HH:MM:SS] message" """
|
|
110
|
+
""" Print a progress message looking like "[PROGRESS HH:MM:SS] message" in magenta by default. """
|
|
103
111
|
if "text" not in print_kwargs:
|
|
104
112
|
print_kwargs["text"] = "PROGRESS"
|
|
105
113
|
if "color" not in print_kwargs:
|
|
@@ -107,7 +115,7 @@ def progress(*values: Any, **print_kwargs: Any) -> None:
|
|
|
107
115
|
info(*values, **print_kwargs)
|
|
108
116
|
|
|
109
117
|
def warning(*values: Any, **print_kwargs: Any) -> None:
|
|
110
|
-
""" Print a warning message looking like "[WARNING HH:MM:SS] message" in sys.stderr """
|
|
118
|
+
""" Print a warning message looking like "[WARNING HH:MM:SS] message" in yellow by default and in sys.stderr. """
|
|
111
119
|
if "file" not in print_kwargs:
|
|
112
120
|
print_kwargs["file"] = sys.stderr
|
|
113
121
|
if "text" not in print_kwargs:
|
|
@@ -117,7 +125,7 @@ def warning(*values: Any, **print_kwargs: Any) -> None:
|
|
|
117
125
|
info(*values, **print_kwargs)
|
|
118
126
|
|
|
119
127
|
def error(*values: Any, exit: bool = True, **print_kwargs: Any) -> None:
|
|
120
|
-
""" Print an error message (in sys.stderr) and optionally ask the user to continue or stop the program
|
|
128
|
+
""" Print an error message (in sys.stderr and in red by default) and optionally ask the user to continue or stop the program.
|
|
121
129
|
|
|
122
130
|
Args:
|
|
123
131
|
values (Any): Values to print (like the print function)
|
|
@@ -144,7 +152,7 @@ def error(*values: Any, exit: bool = True, **print_kwargs: Any) -> None:
|
|
|
144
152
|
print(file=file)
|
|
145
153
|
sys.exit(1)
|
|
146
154
|
|
|
147
|
-
def whatisit(*values: Any, print_function: Callable[..., None] = debug, max_length: int = 250, **print_kwargs: Any) -> None:
|
|
155
|
+
def whatisit(*values: Any, print_function: Callable[..., None] = debug, max_length: int = 250, color: str = CYAN, **print_kwargs: Any) -> None:
|
|
148
156
|
""" Print the type of each value and the value itself, with its id and length/shape.
|
|
149
157
|
|
|
150
158
|
The output format is: "type, <id id_number>: (length/shape) value"
|
|
@@ -153,10 +161,13 @@ def whatisit(*values: Any, print_function: Callable[..., None] = debug, max_leng
|
|
|
153
161
|
values (Any): Values to print
|
|
154
162
|
print_function (Callable): Function to use to print the values (default: debug())
|
|
155
163
|
max_length (int): Maximum length of the value string to print (default: 250)
|
|
164
|
+
color (str): Color of the message (default: CYAN)
|
|
156
165
|
print_kwargs (dict): Keyword arguments to pass to the print function
|
|
157
166
|
"""
|
|
158
167
|
def _internal(value: Any) -> str:
|
|
159
168
|
""" Get the string representation of the value, with length or shape instead of length if shape is available """
|
|
169
|
+
|
|
170
|
+
# Get the length or shape of the value
|
|
160
171
|
length: str = ""
|
|
161
172
|
try:
|
|
162
173
|
length = f"(length: {len(value)}) "
|
|
@@ -166,14 +177,22 @@ def whatisit(*values: Any, print_function: Callable[..., None] = debug, max_leng
|
|
|
166
177
|
length = f"(shape: {value.shape}) "
|
|
167
178
|
except (AttributeError, TypeError):
|
|
168
179
|
pass
|
|
180
|
+
|
|
181
|
+
# Get the string representation of the value
|
|
169
182
|
value_str: str = str(value)
|
|
170
183
|
if len(value_str) > max_length:
|
|
171
184
|
value_str = value_str[:max_length] + "..."
|
|
172
185
|
if "\n" in value_str:
|
|
173
|
-
|
|
186
|
+
value_str = "\n" + value_str # Add a newline before the value if there is a newline in it.
|
|
187
|
+
|
|
188
|
+
# Return the formatted string
|
|
174
189
|
return f"{type(value)}, <id {id(value)}>: {length}{value_str}"
|
|
175
190
|
|
|
176
|
-
#
|
|
191
|
+
# Add the color to the message
|
|
192
|
+
if "color" not in print_kwargs:
|
|
193
|
+
print_kwargs["color"] = color
|
|
194
|
+
|
|
195
|
+
# Print the values
|
|
177
196
|
if len(values) > 1:
|
|
178
197
|
print_function("(What is it?)", **print_kwargs)
|
|
179
198
|
for value in values:
|
stouputils-1.2.0/PKG-INFO
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: stouputils
|
|
3
|
-
Version: 1.2.0
|
|
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
|
-
Project-URL: Homepage, https://github.com/Stoupy51/stouputils
|
|
6
|
-
Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
|
|
7
|
-
Author-email: Stoupy51 <stoupy51@gmail.com>
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
|
12
|
-
Requires-Python: >=3.10
|
|
13
|
-
Requires-Dist: pyyaml>=6.0.0
|
|
14
|
-
Requires-Dist: requests>=2.30.0
|
|
15
|
-
Requires-Dist: toml>=0.10.0
|
|
16
|
-
Requires-Dist: tqdm>=4.66.0
|
|
17
|
-
Description-Content-Type: text/markdown
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# 🛠️ Project Badges
|
|
21
|
-
[](https://github.com/Stoupy51/stouputils/releases/latest)
|
|
22
|
-
[](https://pypi.org/project/stouputils/)
|
|
23
|
-
[](https://stoupy51.github.io/stouputils/latest/)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# 📚 Project Overview
|
|
27
|
-
Stouputils is a collection of utility modules designed to simplify and enhance the development process.<br>
|
|
28
|
-
It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
# 🚀 Project File Tree
|
|
32
|
-
```bash
|
|
33
|
-
stouputils/
|
|
34
|
-
├── continuous_delivery/
|
|
35
|
-
│ ├── github.py # 📦 GitHub utilities that are very specific (upload_to_github)
|
|
36
|
-
│ └── ...
|
|
37
|
-
│
|
|
38
|
-
├── print.py # 🖨️ Display utilities
|
|
39
|
-
├── io.py # 💻 I/O utilities (for file management, json, etc.)
|
|
40
|
-
├── decorators.py # 🎯 Decorators (silent, measure_time, error_handler, simple_cache, deprecated)
|
|
41
|
-
├── ctx.py # 🚫 Context managers (Muffle)
|
|
42
|
-
├── archive.py # 📦 Archive utilities (zip, unzip)
|
|
43
|
-
├── parallel.py # 🧑🤝🧑 Parallel processing (multiprocessing, multithreading)
|
|
44
|
-
├── collections.py # 🧰 Collection utilities (unique_list)
|
|
45
|
-
├── all_doctests.py # ✅ Execution of all doctests of all modules for a given path
|
|
46
|
-
├── backup.py # 📦 Backup utilities (create_delta_backup, consolidate_backups, backup_cli)
|
|
47
|
-
└── ...
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
## ⭐ Star History
|
|
52
|
-
|
|
53
|
-
<a href="https://star-history.com/#Stoupy51/stouputils&Date">
|
|
54
|
-
<picture>
|
|
55
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
|
|
56
|
-
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
57
|
-
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
58
|
-
</picture>
|
|
59
|
-
</a>
|
|
60
|
-
|
stouputils-1.2.0/README.md
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
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
|
-
├── continuous_delivery/
|
|
17
|
-
│ ├── github.py # 📦 GitHub utilities that are very specific (upload_to_github)
|
|
18
|
-
│ └── ...
|
|
19
|
-
│
|
|
20
|
-
├── print.py # 🖨️ Display utilities
|
|
21
|
-
├── io.py # 💻 I/O utilities (for file management, json, etc.)
|
|
22
|
-
├── decorators.py # 🎯 Decorators (silent, measure_time, error_handler, simple_cache, deprecated)
|
|
23
|
-
├── ctx.py # 🚫 Context managers (Muffle)
|
|
24
|
-
├── archive.py # 📦 Archive utilities (zip, unzip)
|
|
25
|
-
├── parallel.py # 🧑🤝🧑 Parallel processing (multiprocessing, multithreading)
|
|
26
|
-
├── collections.py # 🧰 Collection utilities (unique_list)
|
|
27
|
-
├── all_doctests.py # ✅ Execution of all doctests of all modules for a given path
|
|
28
|
-
├── backup.py # 📦 Backup utilities (create_delta_backup, consolidate_backups, backup_cli)
|
|
29
|
-
└── ...
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
## ⭐ Star History
|
|
34
|
-
|
|
35
|
-
<a href="https://star-history.com/#Stoupy51/stouputils&Date">
|
|
36
|
-
<picture>
|
|
37
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
|
|
38
|
-
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
39
|
-
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
|
|
40
|
-
</picture>
|
|
41
|
-
</a>
|
|
42
|
-
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
# Imports
|
|
3
|
-
from .print import *
|
|
4
|
-
from .archive import *
|
|
5
|
-
from .io import *
|
|
6
|
-
from .decorators import *
|
|
7
|
-
from .ctx import *
|
|
8
|
-
from .parallel import *
|
|
9
|
-
from .all_doctests import *
|
|
10
|
-
from .collections import *
|
|
11
|
-
from .backup import *
|
|
12
|
-
|
|
13
|
-
# Folders
|
|
14
|
-
from .continuous_delivery import *
|
|
15
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|