stouputils 1.6.6__tar.gz → 1.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stouputils-1.6.6 → stouputils-1.7.1}/PKG-INFO +1 -1
- {stouputils-1.6.6 → stouputils-1.7.1}/pyproject.toml +1 -1
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/all_doctests.py +12 -4
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/automatic_docs.py +46 -14
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/automatic_docs.pyi +13 -8
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/cd_utils.py +94 -1
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/cd_utils.pyi +49 -1
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/io.py +45 -33
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/io.pyi +2 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/.gitignore +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/LICENSE +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/README.md +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/__init__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/__init__.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/__main__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/all_doctests.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/__init__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/__init__.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/upscaler/__init__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/upscaler/__init__.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/upscaler/config.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/upscaler/config.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/upscaler/image.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/upscaler/image.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/upscaler/video.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/applications/upscaler/video.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/archive.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/archive.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/backup.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/backup.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/collections.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/collections.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/__init__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/__init__.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/github.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/github.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/pypi.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/pypi.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/pyproject.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/pyproject.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/stubs.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/continuous_delivery/stubs.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/ctx.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/ctx.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/config/get.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/config/set.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/__init__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/auto_contrast.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/axis_flip.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/bias_field_correction.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/binary_threshold.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/blur.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/brightness.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/canny.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/clahe.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/common.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/contrast.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/curvature_flow_filter.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/denoise.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/histogram_equalization.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/invert.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/laplacian.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/median_blur.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/noise.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/normalize.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/random_erase.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/resize.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/rotation.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/salt_pepper.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/sharpening.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/shearing.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/threshold.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/translation.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/zoom.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image_augmentation.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image_preprocess.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/prosthesis_detection.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/technique.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/dataset/__init__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/dataset/dataset.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/dataset/dataset_loader.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/dataset/grouping_strategy.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/dataset/image_loader.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/dataset/xy_tuple.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/metric_dictionnary.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/metric_utils.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/mlflow_utils.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/abstract_model.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/all.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/base_keras.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras/all.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras/convnext.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras/densenet.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras/efficientnet.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras/mobilenet.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras/resnet.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras/squeezenet.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras/vgg.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras/xception.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/callbacks/__init__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/callbacks/colored_progress_bar.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/callbacks/learning_rate_finder.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/callbacks/model_checkpoint_v2.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/callbacks/progressive_unfreezing.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/callbacks/warmup_scheduler.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/losses/__init__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/losses/next_generation_loss.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/visualizations.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/model_interface.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/sandbox.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/range_tuple.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/scripts/augment_dataset.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/scripts/exhaustive_process.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/scripts/preprocess_dataset.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/scripts/routine.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/utils.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/decorators.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/decorators.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/image.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/image.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/__init__.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/__init__.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/common.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/common.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/downloader.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/downloader.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/linux.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/linux.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/main.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/main.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/windows.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/installer/windows.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/parallel.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/parallel.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/print.py +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/print.pyi +0 -0
- {stouputils-1.6.6 → stouputils-1.7.1}/stouputils/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: stouputils
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.1
|
|
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
|
|
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "stouputils"
|
|
8
|
-
version = "1.
|
|
8
|
+
version = "1.7.1"
|
|
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"
|
|
@@ -119,17 +119,25 @@ def launch_tests(root_dir: str, strict: bool = True) -> int:
|
|
|
119
119
|
]
|
|
120
120
|
|
|
121
121
|
# Display any error lines for each module at the end of the script
|
|
122
|
-
|
|
122
|
+
total_failed: int = 0
|
|
123
123
|
for module, result in zip(modules, results, strict=False):
|
|
124
124
|
if result.failed > 0:
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
successful_tests: int = result.attempted - result.failed
|
|
126
|
+
error(f"Errors in module {module.__name__} ({successful_tests}/{result.attempted} tests passed)", exit=False)
|
|
127
|
+
total_failed += result.failed
|
|
127
128
|
|
|
128
129
|
# Reset force_raise_exception back
|
|
129
130
|
decorators.force_raise_exception = strict
|
|
130
131
|
|
|
132
|
+
# Final info
|
|
133
|
+
total_tests: int = sum(result.attempted for result in results)
|
|
134
|
+
successful_tests: int = total_tests - total_failed
|
|
135
|
+
if total_failed == 0:
|
|
136
|
+
info(f"All tests passed for all {len(modules)} modules! ({total_tests}/{total_tests} tests passed)")
|
|
137
|
+
else:
|
|
138
|
+
error(f"Some tests failed: {successful_tests}/{total_tests} tests passed in total across {len(modules)} modules", exit=False)
|
|
131
139
|
# Return the number of failed tests
|
|
132
|
-
return
|
|
140
|
+
return total_failed
|
|
133
141
|
|
|
134
142
|
|
|
135
143
|
def test_module_with_progress(module: ModuleType, separator: str) -> TestResults:
|
|
@@ -251,12 +251,15 @@ def setup(app: Any) -> None:
|
|
|
251
251
|
return conf_content
|
|
252
252
|
|
|
253
253
|
@simple_cache()
|
|
254
|
-
def get_versions_from_github(github_user: str, github_repo: str) -> list[str]:
|
|
254
|
+
def get_versions_from_github(github_user: str, github_repo: str, recent_minor_versions: int = 2) -> list[str]:
|
|
255
255
|
""" Get list of versions from GitHub gh-pages branch.
|
|
256
|
+
Only shows detailed versions for the last N minor versions, and keeps only
|
|
257
|
+
the latest patch version for older minor versions.
|
|
256
258
|
|
|
257
259
|
Args:
|
|
258
|
-
github_user
|
|
259
|
-
github_repo
|
|
260
|
+
github_user (str): GitHub username
|
|
261
|
+
github_repo (str): GitHub repository name
|
|
262
|
+
recent_minor_versions (int): Number of recent minor versions to show all patches for (-1 for all).
|
|
260
263
|
|
|
261
264
|
Returns:
|
|
262
265
|
list[str]: List of versions, with 'latest' as first element
|
|
@@ -266,13 +269,37 @@ def get_versions_from_github(github_user: str, github_repo: str) -> list[str]:
|
|
|
266
269
|
try:
|
|
267
270
|
response = requests.get(f"https://api.github.com/repos/{github_user}/{github_repo}/contents?ref=gh-pages")
|
|
268
271
|
if response.status_code == 200:
|
|
269
|
-
contents = response.json()
|
|
270
|
-
|
|
272
|
+
contents: list[dict[str, str]] = response.json()
|
|
273
|
+
all_versions: list[str] = sorted([
|
|
271
274
|
d["name"].replace("v", "")
|
|
272
275
|
for d in contents
|
|
273
276
|
if d["type"] == "dir" and d["name"].startswith("v")
|
|
274
277
|
], key=version_to_float, reverse=True
|
|
275
|
-
)
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Group versions by major.minor
|
|
281
|
+
from collections import defaultdict
|
|
282
|
+
minor_versions: dict[str, list[str]] = defaultdict(list)
|
|
283
|
+
for version in all_versions:
|
|
284
|
+
parts = version.split(".")
|
|
285
|
+
if len(parts) >= 2:
|
|
286
|
+
minor_key = f"{parts[0]}.{parts[1]}"
|
|
287
|
+
minor_versions[minor_key].append(version)
|
|
288
|
+
|
|
289
|
+
# Get the sorted minor version keys
|
|
290
|
+
sorted_minors = sorted(minor_versions.keys(), key=version_to_float, reverse=True)
|
|
291
|
+
|
|
292
|
+
# Build final version list
|
|
293
|
+
final_versions: list[str] = []
|
|
294
|
+
for i, minor_key in enumerate(sorted_minors):
|
|
295
|
+
if recent_minor_versions == -1 or i < recent_minor_versions:
|
|
296
|
+
# Keep all patch versions for the recent minor versions
|
|
297
|
+
final_versions.extend(minor_versions[minor_key])
|
|
298
|
+
else:
|
|
299
|
+
# Keep only the latest patch version for older minor versions
|
|
300
|
+
final_versions.append(minor_versions[minor_key][0])
|
|
301
|
+
|
|
302
|
+
version_list = ["latest", *final_versions]
|
|
276
303
|
except Exception as e:
|
|
277
304
|
info(f"Failed to get versions from GitHub: {e}")
|
|
278
305
|
version_list = ["latest"]
|
|
@@ -300,17 +327,19 @@ def generate_index_rst(
|
|
|
300
327
|
project: str,
|
|
301
328
|
github_user: str,
|
|
302
329
|
github_repo: str,
|
|
303
|
-
get_versions_function: Callable[[str, str], list[str]] = get_versions_from_github,
|
|
330
|
+
get_versions_function: Callable[[str, str, int], list[str]] = get_versions_from_github,
|
|
331
|
+
recent_minor_versions: int = 2,
|
|
304
332
|
) -> None:
|
|
305
333
|
""" Generate index.rst from README.md content.
|
|
306
334
|
|
|
307
335
|
Args:
|
|
308
|
-
readme_path
|
|
336
|
+
readme_path (str): Path to the README.md file
|
|
309
337
|
index_path (str): Path where index.rst should be created
|
|
310
338
|
project (str): Name of the project
|
|
311
339
|
github_user (str): GitHub username
|
|
312
340
|
github_repo (str): GitHub repository name
|
|
313
|
-
get_versions_function (Callable[[str, str], list[str]]): Function to get versions from GitHub
|
|
341
|
+
get_versions_function (Callable[[str, str, int], list[str]]): Function to get versions from GitHub
|
|
342
|
+
recent_minor_versions (int): Number of recent minor versions to show all patches for. Defaults to 2
|
|
314
343
|
"""
|
|
315
344
|
# Read README content
|
|
316
345
|
with open(readme_path, encoding="utf-8") as f:
|
|
@@ -320,7 +349,7 @@ def generate_index_rst(
|
|
|
320
349
|
version_selector: str = "\n\n**Versions**: "
|
|
321
350
|
|
|
322
351
|
# Get versions from GitHub
|
|
323
|
-
version_list: list[str] = get_versions_function(github_user, github_repo)
|
|
352
|
+
version_list: list[str] = get_versions_function(github_user, github_repo, recent_minor_versions)
|
|
324
353
|
|
|
325
354
|
# Create version links
|
|
326
355
|
version_links: list[str] = []
|
|
@@ -429,8 +458,9 @@ def update_documentation(
|
|
|
429
458
|
github_repo: str = "",
|
|
430
459
|
version: str | None = None,
|
|
431
460
|
skip_undocumented: bool = True,
|
|
461
|
+
recent_minor_versions: int = 2,
|
|
432
462
|
|
|
433
|
-
get_versions_function: Callable[[str, str], list[str]] = get_versions_from_github,
|
|
463
|
+
get_versions_function: Callable[[str, str, int], list[str]] = get_versions_from_github,
|
|
434
464
|
generate_index_function: Callable[..., None] = generate_index_rst,
|
|
435
465
|
generate_docs_function: Callable[..., None] = generate_documentation,
|
|
436
466
|
generate_redirect_function: Callable[[str], None] = generate_redirect_html,
|
|
@@ -451,8 +481,9 @@ def update_documentation(
|
|
|
451
481
|
github_repo (str): GitHub repository name
|
|
452
482
|
version (str | None): Version to build documentation for (e.g. "1.0.0", defaults to "latest")
|
|
453
483
|
skip_undocumented (bool): Whether to skip undocumented members. Defaults to True
|
|
484
|
+
recent_minor_versions (int): Number of recent minor versions to show all patches for. Defaults to 2
|
|
454
485
|
|
|
455
|
-
get_versions_function (Callable[[str, str], list[str]]): Function to get versions from GitHub
|
|
486
|
+
get_versions_function (Callable[[str, str, int], list[str]]): Function to get versions from GitHub
|
|
456
487
|
generate_index_function (Callable[..., None]): Function to generate index.rst
|
|
457
488
|
generate_docs_function (Callable[..., None]): Function to generate documentation
|
|
458
489
|
generate_redirect_function (Callable[[str], None]): Function to create redirect file
|
|
@@ -490,15 +521,16 @@ def update_documentation(
|
|
|
490
521
|
github_user=github_user,
|
|
491
522
|
github_repo=github_repo,
|
|
492
523
|
get_versions_function=get_versions_function,
|
|
524
|
+
recent_minor_versions=recent_minor_versions,
|
|
493
525
|
)
|
|
494
526
|
|
|
495
527
|
# Clean up old module documentation
|
|
496
528
|
if os.path.exists(modules_dir):
|
|
497
529
|
shutil.rmtree(modules_dir)
|
|
498
|
-
|
|
530
|
+
os.makedirs(modules_dir, exist_ok=True)
|
|
499
531
|
|
|
500
532
|
# Get versions and current version for conf.py
|
|
501
|
-
version_list: list[str] = get_versions_function(github_user, github_repo)
|
|
533
|
+
version_list: list[str] = get_versions_function(github_user, github_repo, recent_minor_versions)
|
|
502
534
|
current_version: str = version if version else "latest"
|
|
503
535
|
|
|
504
536
|
# Generate conf.py
|
|
@@ -31,12 +31,15 @@ def get_sphinx_conf_content(project: str, project_dir: str, author: str, current
|
|
|
31
31
|
\tReturns:
|
|
32
32
|
\t\tstr: Content of the Sphinx configuration file
|
|
33
33
|
\t"""
|
|
34
|
-
def get_versions_from_github(github_user: str, github_repo: str) -> list[str]:
|
|
34
|
+
def get_versions_from_github(github_user: str, github_repo: str, recent_minor_versions: int = 2) -> list[str]:
|
|
35
35
|
""" Get list of versions from GitHub gh-pages branch.
|
|
36
|
+
\tOnly shows detailed versions for the last N minor versions, and keeps only
|
|
37
|
+
\tthe latest patch version for older minor versions.
|
|
36
38
|
|
|
37
39
|
\tArgs:
|
|
38
|
-
\t\tgithub_user
|
|
39
|
-
\t\tgithub_repo
|
|
40
|
+
\t\tgithub_user (str): GitHub username
|
|
41
|
+
\t\tgithub_repo (str): GitHub repository name
|
|
42
|
+
\t\trecent_minor_versions (int): Number of recent minor versions to show all patches for (-1 for all).
|
|
40
43
|
|
|
41
44
|
\tReturns:
|
|
42
45
|
\t\tlist[str]: List of versions, with 'latest' as first element
|
|
@@ -50,16 +53,17 @@ def markdown_to_rst(markdown_content: str) -> str:
|
|
|
50
53
|
\tReturns:
|
|
51
54
|
\t\tstr: RST content
|
|
52
55
|
\t"""
|
|
53
|
-
def generate_index_rst(readme_path: str, index_path: str, project: str, github_user: str, github_repo: str, get_versions_function: Callable[[str, str], list[str]] =
|
|
56
|
+
def generate_index_rst(readme_path: str, index_path: str, project: str, github_user: str, github_repo: str, get_versions_function: Callable[[str, str, int], list[str]] = ..., recent_minor_versions: int = 2) -> None:
|
|
54
57
|
""" Generate index.rst from README.md content.
|
|
55
58
|
|
|
56
59
|
\tArgs:
|
|
57
|
-
\t\treadme_path
|
|
60
|
+
\t\treadme_path (str): Path to the README.md file
|
|
58
61
|
\t\tindex_path (str): Path where index.rst should be created
|
|
59
62
|
\t\tproject (str): Name of the project
|
|
60
63
|
\t\tgithub_user (str): GitHub username
|
|
61
64
|
\t\tgithub_repo (str): GitHub repository name
|
|
62
|
-
\t\tget_versions_function (Callable[[str, str], list[str]]): Function to get versions from GitHub
|
|
65
|
+
\t\tget_versions_function (Callable[[str, str, int], list[str]]): Function to get versions from GitHub
|
|
66
|
+
\t\trecent_minor_versions (int): Number of recent minor versions to show all patches for. Defaults to 2
|
|
63
67
|
\t"""
|
|
64
68
|
def generate_documentation(source_dir: str, modules_dir: str, project_dir: str, build_dir: str) -> None:
|
|
65
69
|
""" Generate documentation using Sphinx.
|
|
@@ -76,7 +80,7 @@ def generate_redirect_html(filepath: str) -> None:
|
|
|
76
80
|
\tArgs:
|
|
77
81
|
\t\tfilepath (str): Path to the file where the HTML content should be written
|
|
78
82
|
\t"""
|
|
79
|
-
def update_documentation(root_path: str, project: str, project_dir: str = '', author: str = 'Author', copyright: str = '2025, Author', html_logo: str = '', html_favicon: str = '', html_theme: str = 'breeze', github_user: str = '', github_repo: str = '', version: str | None = None, skip_undocumented: bool = True, get_versions_function: Callable[[str, str], list[str]] = ..., generate_index_function: Callable[..., None] = ..., generate_docs_function: Callable[..., None] = ..., generate_redirect_function: Callable[[str], None] = ..., get_conf_content_function: Callable[..., str] = ...) -> None:
|
|
83
|
+
def update_documentation(root_path: str, project: str, project_dir: str = '', author: str = 'Author', copyright: str = '2025, Author', html_logo: str = '', html_favicon: str = '', html_theme: str = 'breeze', github_user: str = '', github_repo: str = '', version: str | None = None, skip_undocumented: bool = True, recent_minor_versions: int = 2, get_versions_function: Callable[[str, str, int], list[str]] = ..., generate_index_function: Callable[..., None] = ..., generate_docs_function: Callable[..., None] = ..., generate_redirect_function: Callable[[str], None] = ..., get_conf_content_function: Callable[..., str] = ...) -> None:
|
|
80
84
|
''' Update the Sphinx documentation.
|
|
81
85
|
|
|
82
86
|
\tArgs:
|
|
@@ -92,8 +96,9 @@ def update_documentation(root_path: str, project: str, project_dir: str = '', au
|
|
|
92
96
|
\t\tgithub_repo (str): GitHub repository name
|
|
93
97
|
\t\tversion (str | None): Version to build documentation for (e.g. "1.0.0", defaults to "latest")
|
|
94
98
|
\t\tskip_undocumented (bool): Whether to skip undocumented members. Defaults to True
|
|
99
|
+
\t\trecent_minor_versions (int): Number of recent minor versions to show all patches for. Defaults to 2
|
|
95
100
|
|
|
96
|
-
\t\tget_versions_function (Callable[[str, str], list[str]]): Function to get versions from GitHub
|
|
101
|
+
\t\tget_versions_function (Callable[[str, str, int], list[str]]): Function to get versions from GitHub
|
|
97
102
|
\t\tgenerate_index_function (Callable[..., None]): Function to generate index.rst
|
|
98
103
|
\t\tgenerate_docs_function (Callable[..., None]): Function to generate documentation
|
|
99
104
|
\t\tgenerate_redirect_function (Callable[[str], None]): Function to create redirect file
|
|
@@ -108,9 +108,11 @@ def version_to_float(version: str) -> float:
|
|
|
108
108
|
""" Converts a version string into a float for comparison purposes.
|
|
109
109
|
The version string is expected to follow the format of major.minor.patch.something_else....,
|
|
110
110
|
where each part is separated by a dot and can be extended indefinitely.
|
|
111
|
+
Supports pre-release suffixes with numbers: devN/dN (dev), aN (alpha), bN (beta), rcN/cN (release candidate).
|
|
112
|
+
Ordering: 1.0.0 > 1.0.0rc2 > 1.0.0rc1 > 1.0.0b2 > 1.0.0b1 > 1.0.0a2 > 1.0.0a1 > 1.0.0dev1
|
|
111
113
|
|
|
112
114
|
Args:
|
|
113
|
-
version (str): The version string to convert. (e.g. "v1.0.0.1.2.3")
|
|
115
|
+
version (str): The version string to convert. (e.g. "v1.0.0.1.2.3", "v2.0.0b2", "v1.0.0rc1")
|
|
114
116
|
Returns:
|
|
115
117
|
float: The float representation of the version. (e.g. 0)
|
|
116
118
|
|
|
@@ -124,7 +126,88 @@ def version_to_float(version: str) -> float:
|
|
|
124
126
|
1.0000000010020031
|
|
125
127
|
>>> version_to_float("v2.0") > version_to_float("v1.0.0.1")
|
|
126
128
|
True
|
|
129
|
+
>>> version_to_float("v2.0.0") > version_to_float("v2.0.0rc") > version_to_float("v2.0.0b") > version_to_float("v2.0.0a") > version_to_float("v2.0.0dev")
|
|
130
|
+
True
|
|
131
|
+
>>> version_to_float("v1.0.0b") > version_to_float("v1.0.0a")
|
|
132
|
+
True
|
|
133
|
+
>>> version_to_float("v1.0.0") > version_to_float("v1.0.0b")
|
|
134
|
+
True
|
|
135
|
+
>>> version_to_float("v3.0.0a") > version_to_float("v2.9.9")
|
|
136
|
+
True
|
|
137
|
+
>>> version_to_float("v1.2.3b") < version_to_float("v1.2.3")
|
|
138
|
+
True
|
|
139
|
+
>>> version_to_float("1.0.0") == version_to_float("v1.0.0")
|
|
140
|
+
True
|
|
141
|
+
>>> version_to_float("2.0.0.0.0.0.1b") > version_to_float("2.0.0.0.0.0.1a")
|
|
142
|
+
True
|
|
143
|
+
>>> version_to_float("2.0.0.0.0.0.1") > version_to_float("2.0.0.0.0.0.1b")
|
|
144
|
+
True
|
|
145
|
+
>>> version_to_float("v1.0.0rc") == version_to_float("v1.0.0c")
|
|
146
|
+
True
|
|
147
|
+
>>> version_to_float("v1.0.0c") > version_to_float("v1.0.0b")
|
|
148
|
+
True
|
|
149
|
+
>>> version_to_float("v1.0.0d") < version_to_float("v1.0.0a")
|
|
150
|
+
True
|
|
151
|
+
>>> version_to_float("v1.0.0dev") < version_to_float("v1.0.0a")
|
|
152
|
+
True
|
|
153
|
+
>>> version_to_float("v1.0.0dev") == version_to_float("v1.0.0d")
|
|
154
|
+
True
|
|
155
|
+
>>> version_to_float("v1.0.0rc2") > version_to_float("v1.0.0rc1")
|
|
156
|
+
True
|
|
157
|
+
>>> version_to_float("v1.0.0b2") > version_to_float("v1.0.0b1")
|
|
158
|
+
True
|
|
159
|
+
>>> version_to_float("v1.0.0a2") > version_to_float("v1.0.0a1")
|
|
160
|
+
True
|
|
161
|
+
>>> version_to_float("v1.0.0dev2") > version_to_float("v1.0.0dev1")
|
|
162
|
+
True
|
|
163
|
+
>>> version_to_float("v1.0.0") > version_to_float("v1.0.0rc2") > version_to_float("v1.0.0rc1")
|
|
164
|
+
True
|
|
165
|
+
>>> version_to_float("v1.0.0rc1") > version_to_float("v1.0.0b2")
|
|
166
|
+
True
|
|
167
|
+
>>> version_to_float("v1.0.0b1") > version_to_float("v1.0.0a2")
|
|
168
|
+
True
|
|
169
|
+
>>> version_to_float("v1.0.0a1") > version_to_float("v1.0.0dev2")
|
|
170
|
+
True
|
|
171
|
+
>>> versions = ["v1.0.0", "v1.0.0rc2", "v1.0.0rc1", "v1.0.0b2", "v1.0.0b1", "v1.0.0a2", "v1.0.0a1", "v1.0.0dev2", "v1.0.0dev1"]
|
|
172
|
+
>>> sorted_versions = sorted(versions, key=version_to_float, reverse=True)
|
|
173
|
+
>>> sorted_versions == versions
|
|
174
|
+
True
|
|
127
175
|
"""
|
|
176
|
+
# Check for pre-release suffixes and calculate suffix modifier
|
|
177
|
+
# Suffixes are ordered from longest to shortest to avoid partial matches
|
|
178
|
+
suffix_modifiers: dict[str, int] = {
|
|
179
|
+
"dev": 4, # dev is lowest
|
|
180
|
+
"d": 4, # d (dev) is lowest
|
|
181
|
+
"a": 3, # alpha
|
|
182
|
+
"b": 2, # beta
|
|
183
|
+
"rc": 1, # rc is highest pre-release
|
|
184
|
+
"c": 1, # c (release candidate)
|
|
185
|
+
}
|
|
186
|
+
suffix_type: int = 0 # 0 = no suffix, 1-4 = rc/c, b, a, dev/d
|
|
187
|
+
suffix_number: int = 0
|
|
188
|
+
|
|
189
|
+
# Check for suffixes with optional numbers
|
|
190
|
+
for suffix, modifier in suffix_modifiers.items():
|
|
191
|
+
if suffix in version:
|
|
192
|
+
# Find the suffix position
|
|
193
|
+
suffix_pos: int = version.rfind(suffix)
|
|
194
|
+
after_suffix: str = version[suffix_pos + len(suffix):]
|
|
195
|
+
|
|
196
|
+
# Check if there's a number after the suffix
|
|
197
|
+
if after_suffix.isdigit():
|
|
198
|
+
suffix_number = int(after_suffix)
|
|
199
|
+
version = version[:suffix_pos]
|
|
200
|
+
elif after_suffix == "":
|
|
201
|
+
# Suffix at the end without number
|
|
202
|
+
version = version[:suffix_pos]
|
|
203
|
+
else:
|
|
204
|
+
# Not a valid suffix match, continue searching
|
|
205
|
+
continue
|
|
206
|
+
|
|
207
|
+
# Found a valid suffix, set the type and break
|
|
208
|
+
suffix_type = modifier
|
|
209
|
+
break
|
|
210
|
+
|
|
128
211
|
# Clean the version string by keeping only the numbers and dots
|
|
129
212
|
version = clean_version(version)
|
|
130
213
|
|
|
@@ -137,5 +220,15 @@ def version_to_float(version: str) -> float:
|
|
|
137
220
|
for part in version_parts:
|
|
138
221
|
total += int(part) * multiplier
|
|
139
222
|
multiplier /= 1_000
|
|
223
|
+
|
|
224
|
+
# Apply pre-release modifier
|
|
225
|
+
# Pre-releases are represented as negative offsets from the base version
|
|
226
|
+
# Lower suffix_type = closer to release (rc=1 is closest, dev=4 is furthest)
|
|
227
|
+
# Higher suffix_number = closer to release within the same suffix type
|
|
228
|
+
# Formula: base_version - (suffix_type * 1000 - suffix_number) * 1e-9
|
|
229
|
+
# This ensures: 1.0.0 > 1.0.0rc2 > 1.0.0rc1 > 1.0.0b2 > 1.0.0a2 > 1.0.0dev2
|
|
230
|
+
if suffix_type > 0:
|
|
231
|
+
total -= (suffix_type * 1000 - suffix_number) * 1e-9
|
|
232
|
+
|
|
140
233
|
return total
|
|
141
234
|
|
|
@@ -61,9 +61,11 @@ def version_to_float(version: str) -> float:
|
|
|
61
61
|
''' Converts a version string into a float for comparison purposes.
|
|
62
62
|
\tThe version string is expected to follow the format of major.minor.patch.something_else....,
|
|
63
63
|
\twhere each part is separated by a dot and can be extended indefinitely.
|
|
64
|
+
\tSupports pre-release suffixes with numbers: devN/dN (dev), aN (alpha), bN (beta), rcN/cN (release candidate).
|
|
65
|
+
\tOrdering: 1.0.0 > 1.0.0rc2 > 1.0.0rc1 > 1.0.0b2 > 1.0.0b1 > 1.0.0a2 > 1.0.0a1 > 1.0.0dev1
|
|
64
66
|
|
|
65
67
|
\tArgs:
|
|
66
|
-
\t\tversion (str): The version string to convert. (e.g. "v1.0.0.1.2.3")
|
|
68
|
+
\t\tversion (str): The version string to convert. (e.g. "v1.0.0.1.2.3", "v2.0.0b2", "v1.0.0rc1")
|
|
67
69
|
\tReturns:
|
|
68
70
|
\t\tfloat: The float representation of the version. (e.g. 0)
|
|
69
71
|
|
|
@@ -77,4 +79,50 @@ def version_to_float(version: str) -> float:
|
|
|
77
79
|
\t1.0000000010020031
|
|
78
80
|
\t>>> version_to_float("v2.0") > version_to_float("v1.0.0.1")
|
|
79
81
|
\tTrue
|
|
82
|
+
\t>>> version_to_float("v2.0.0") > version_to_float("v2.0.0rc") > version_to_float("v2.0.0b") > version_to_float("v2.0.0a") > version_to_float("v2.0.0dev")
|
|
83
|
+
\tTrue
|
|
84
|
+
\t>>> version_to_float("v1.0.0b") > version_to_float("v1.0.0a")
|
|
85
|
+
\tTrue
|
|
86
|
+
\t>>> version_to_float("v1.0.0") > version_to_float("v1.0.0b")
|
|
87
|
+
\tTrue
|
|
88
|
+
\t>>> version_to_float("v3.0.0a") > version_to_float("v2.9.9")
|
|
89
|
+
\tTrue
|
|
90
|
+
\t>>> version_to_float("v1.2.3b") < version_to_float("v1.2.3")
|
|
91
|
+
\tTrue
|
|
92
|
+
\t>>> version_to_float("1.0.0") == version_to_float("v1.0.0")
|
|
93
|
+
\tTrue
|
|
94
|
+
\t>>> version_to_float("2.0.0.0.0.0.1b") > version_to_float("2.0.0.0.0.0.1a")
|
|
95
|
+
\tTrue
|
|
96
|
+
\t>>> version_to_float("2.0.0.0.0.0.1") > version_to_float("2.0.0.0.0.0.1b")
|
|
97
|
+
\tTrue
|
|
98
|
+
\t>>> version_to_float("v1.0.0rc") == version_to_float("v1.0.0c")
|
|
99
|
+
\tTrue
|
|
100
|
+
\t>>> version_to_float("v1.0.0c") > version_to_float("v1.0.0b")
|
|
101
|
+
\tTrue
|
|
102
|
+
\t>>> version_to_float("v1.0.0d") < version_to_float("v1.0.0a")
|
|
103
|
+
\tTrue
|
|
104
|
+
\t>>> version_to_float("v1.0.0dev") < version_to_float("v1.0.0a")
|
|
105
|
+
\tTrue
|
|
106
|
+
\t>>> version_to_float("v1.0.0dev") == version_to_float("v1.0.0d")
|
|
107
|
+
\tTrue
|
|
108
|
+
\t>>> version_to_float("v1.0.0rc2") > version_to_float("v1.0.0rc1")
|
|
109
|
+
\tTrue
|
|
110
|
+
\t>>> version_to_float("v1.0.0b2") > version_to_float("v1.0.0b1")
|
|
111
|
+
\tTrue
|
|
112
|
+
\t>>> version_to_float("v1.0.0a2") > version_to_float("v1.0.0a1")
|
|
113
|
+
\tTrue
|
|
114
|
+
\t>>> version_to_float("v1.0.0dev2") > version_to_float("v1.0.0dev1")
|
|
115
|
+
\tTrue
|
|
116
|
+
\t>>> version_to_float("v1.0.0") > version_to_float("v1.0.0rc2") > version_to_float("v1.0.0rc1")
|
|
117
|
+
\tTrue
|
|
118
|
+
\t>>> version_to_float("v1.0.0rc1") > version_to_float("v1.0.0b2")
|
|
119
|
+
\tTrue
|
|
120
|
+
\t>>> version_to_float("v1.0.0b1") > version_to_float("v1.0.0a2")
|
|
121
|
+
\tTrue
|
|
122
|
+
\t>>> version_to_float("v1.0.0a1") > version_to_float("v1.0.0dev2")
|
|
123
|
+
\tTrue
|
|
124
|
+
\t>>> versions = ["v1.0.0", "v1.0.0rc2", "v1.0.0rc1", "v1.0.0b2", "v1.0.0b1", "v1.0.0a2", "v1.0.0a1", "v1.0.0dev2", "v1.0.0dev1"]
|
|
125
|
+
\t>>> sorted_versions = sorted(versions, key=version_to_float, reverse=True)
|
|
126
|
+
\t>>> sorted_versions == versions
|
|
127
|
+
\tTrue
|
|
80
128
|
\t'''
|
|
@@ -190,48 +190,58 @@ def super_csv_dump(
|
|
|
190
190
|
if isinstance(data, str | bytes | dict):
|
|
191
191
|
raise ValueError("Data must be a list of lists, list of dicts, pandas DataFrame, or Polars DataFrame")
|
|
192
192
|
output = StringIO()
|
|
193
|
+
done: bool = False
|
|
193
194
|
|
|
194
195
|
# Handle Polars DataFrame
|
|
195
196
|
try:
|
|
196
|
-
import polars as pl # type: ignore
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
197
|
+
import polars as pl # type: ignore
|
|
198
|
+
if isinstance(data, pl.DataFrame):
|
|
199
|
+
copy_kwargs = kwargs.copy()
|
|
200
|
+
copy_kwargs.setdefault("separator", delimiter)
|
|
201
|
+
copy_kwargs.setdefault("include_header", has_header)
|
|
202
|
+
data.write_csv(output, *args, **copy_kwargs)
|
|
203
|
+
done = True
|
|
202
204
|
except Exception:
|
|
203
205
|
pass
|
|
204
206
|
|
|
205
207
|
# Handle pandas DataFrame
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
208
|
+
if not done:
|
|
209
|
+
try:
|
|
210
|
+
import pandas as pd # type: ignore
|
|
211
|
+
if isinstance(data, pd.DataFrame):
|
|
212
|
+
copy_kwargs = kwargs.copy()
|
|
213
|
+
copy_kwargs.setdefault("index", index)
|
|
214
|
+
copy_kwargs.setdefault("sep", delimiter)
|
|
215
|
+
copy_kwargs.setdefault("header", has_header)
|
|
216
|
+
data.to_csv(output, *args, **copy_kwargs)
|
|
217
|
+
except Exception:
|
|
218
|
+
pass
|
|
219
|
+
|
|
220
|
+
if not done:
|
|
221
|
+
# Handle list of dicts
|
|
222
|
+
if isinstance(data[0], dict):
|
|
223
|
+
fieldnames = list(data[0].keys()) # type: ignore
|
|
224
|
+
kwargs.setdefault("fieldnames", fieldnames)
|
|
225
|
+
kwargs.setdefault("delimiter", delimiter)
|
|
226
|
+
dict_writer = csv.DictWriter(output, *args, **kwargs)
|
|
227
|
+
if has_header:
|
|
228
|
+
dict_writer.writeheader()
|
|
229
|
+
dict_writer.writerows(data) # type: ignore
|
|
230
|
+
done = True
|
|
216
231
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
dict_writer = csv.DictWriter(output, *args, **kwargs)
|
|
224
|
-
if has_header:
|
|
225
|
-
dict_writer.writeheader()
|
|
226
|
-
dict_writer.writerows(data) # type: ignore
|
|
227
|
-
|
|
228
|
-
# Handle list of lists
|
|
229
|
-
else:
|
|
230
|
-
kwargs.setdefault("delimiter", delimiter)
|
|
231
|
-
kwargs.setdefault("lineterminator", "\r\n")
|
|
232
|
-
list_writer = csv.writer(output, *args, **kwargs)
|
|
233
|
-
list_writer.writerows(data)
|
|
232
|
+
# Handle list of lists
|
|
233
|
+
else:
|
|
234
|
+
kwargs.setdefault("delimiter", delimiter)
|
|
235
|
+
list_writer = csv.writer(output, *args, **kwargs)
|
|
236
|
+
list_writer.writerows(data) # type: ignore
|
|
237
|
+
done = True
|
|
234
238
|
|
|
239
|
+
# If still not done, raise error
|
|
240
|
+
if not done:
|
|
241
|
+
output.close()
|
|
242
|
+
raise ValueError(f"Data must be a list of lists, list of dicts, pandas DataFrame, or Polars DataFrame, got {type(data)} instead")
|
|
243
|
+
|
|
244
|
+
# Get content and write to file if needed
|
|
235
245
|
content: str = output.getvalue()
|
|
236
246
|
if file:
|
|
237
247
|
if isinstance(file, str):
|
|
@@ -274,6 +284,8 @@ def super_csv_load(file_path: str, delimiter: str = ',', has_header: bool = True
|
|
|
274
284
|
0 1 2 3
|
|
275
285
|
1 4 5 6
|
|
276
286
|
|
|
287
|
+
.. code-block:: console
|
|
288
|
+
|
|
277
289
|
> super_csv_load("test.csv", as_dataframe=True, use_polars=True)
|
|
278
290
|
shape: (2, 3)
|
|
279
291
|
┌─────┬─────┬─────┐
|
|
@@ -119,6 +119,8 @@ def super_csv_load(file_path: str, delimiter: str = ',', has_header: bool = True
|
|
|
119
119
|
\t\t\t0 1 2 3
|
|
120
120
|
\t\t\t1 4 5 6
|
|
121
121
|
|
|
122
|
+
\t\t.. code-block:: console
|
|
123
|
+
|
|
122
124
|
\t\t\t> super_csv_load("test.csv", as_dataframe=True, use_polars=True)
|
|
123
125
|
\t\t\tshape: (2, 3)
|
|
124
126
|
\t\t\t┌─────┬─────┬─────┐
|
|
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
|
|
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
|
|
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
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/__init__.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/auto_contrast.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/axis_flip.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/brightness.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/canny.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/clahe.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/common.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/contrast.py
RENAMED
|
File without changes
|
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/denoise.py
RENAMED
|
File without changes
|
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/invert.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/laplacian.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/median_blur.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/noise.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/normalize.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/random_erase.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/resize.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/rotation.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/salt_pepper.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/sharpening.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/shearing.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/threshold.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image/translation.py
RENAMED
|
File without changes
|
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image_augmentation.py
RENAMED
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/data_processing/image_preprocess.py
RENAMED
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/losses/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{stouputils-1.6.6 → stouputils-1.7.1}/stouputils/data_science/models/keras_utils/visualizations.py
RENAMED
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|