progress-table 1.3.1__tar.gz → 1.3.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.
- {progress-table-1.3.1 → progress-table-1.3.2}/PKG-INFO +1 -1
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table/__init__.py +1 -1
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table.egg-info/PKG-INFO +1 -1
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table.egg-info/SOURCES.txt +3 -1
- progress-table-1.3.2/tests/test_docs_automated.py +61 -0
- progress-table-1.3.2/tests/test_examples_automated.py +63 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/LICENSE.txt +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/README.md +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table/v0/__init__.py +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table/v0/progress_table.py +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table/v0/symbols.py +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table/v1/__init__.py +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table/v1/progress_table.py +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table/v1/styles.py +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table.egg-info/PKG-INFO.sync-conflict-20240314-015933-NXTV2IO +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table.egg-info/dependency_links.txt +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table.egg-info/requires.txt +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/progress_table.egg-info/top_level.txt +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/pyproject.toml +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/setup.cfg +0 -0
- {progress-table-1.3.1 → progress-table-1.3.2}/setup.py +0 -0
|
@@ -15,4 +15,6 @@ progress_table/v0/progress_table.py
|
|
|
15
15
|
progress_table/v0/symbols.py
|
|
16
16
|
progress_table/v1/__init__.py
|
|
17
17
|
progress_table/v1/progress_table.py
|
|
18
|
-
progress_table/v1/styles.py
|
|
18
|
+
progress_table/v1/styles.py
|
|
19
|
+
tests/test_docs_automated.py
|
|
20
|
+
tests/test_examples_automated.py
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Copyright (c) 2022-2024 Szymon Mikler
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
import pathlib
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_header(msg):
|
|
10
|
+
msg_len = len(msg)
|
|
11
|
+
header = [
|
|
12
|
+
"#" * (msg_len + 6),
|
|
13
|
+
"## " + msg + " ##",
|
|
14
|
+
"#" * (msg_len + 6),
|
|
15
|
+
]
|
|
16
|
+
return "\n".join(header) + "\n"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def scan_for_code_blobs(text):
|
|
20
|
+
# Capture code blocks starting with py or python
|
|
21
|
+
blobs = re.findall(r"```(py|python)\n([\s\S]+?)\n```", text)
|
|
22
|
+
|
|
23
|
+
new_blobs = []
|
|
24
|
+
for mode, blob in blobs:
|
|
25
|
+
if "..." in blob:
|
|
26
|
+
continue
|
|
27
|
+
header = get_header(f"Generated ({mode})")
|
|
28
|
+
blob = header + blob
|
|
29
|
+
|
|
30
|
+
# For `py` code blocks, we append them to previous existing block
|
|
31
|
+
# But `python` block starts a new scope and finishes the previous block
|
|
32
|
+
# They usually need to include imports
|
|
33
|
+
if mode == "py" and new_blobs:
|
|
34
|
+
new_blobs[-1] = new_blobs[-1] + "\n" + blob
|
|
35
|
+
else:
|
|
36
|
+
new_blobs.append(blob)
|
|
37
|
+
return new_blobs
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_all_code_blobs():
|
|
41
|
+
# Testing whether code blobs from the documentation run without errors
|
|
42
|
+
all_code_blobs = []
|
|
43
|
+
|
|
44
|
+
for root, dirs, files in os.walk(""):
|
|
45
|
+
for file in files:
|
|
46
|
+
path = pathlib.Path(os.path.join(root, file))
|
|
47
|
+
if path.suffix == ".md":
|
|
48
|
+
code_blobs = scan_for_code_blobs(path.open("r").read())
|
|
49
|
+
for blob in code_blobs:
|
|
50
|
+
all_code_blobs.append(blob)
|
|
51
|
+
|
|
52
|
+
logging.warning(f"Detected {len(all_code_blobs)} code examples!")
|
|
53
|
+
|
|
54
|
+
for idx, blob in enumerate(all_code_blobs):
|
|
55
|
+
try:
|
|
56
|
+
globals_temp = {}
|
|
57
|
+
exec(blob, globals_temp)
|
|
58
|
+
except Exception as e:
|
|
59
|
+
print(f"Exception during automated documentation testing {idx}/{len(all_code_blobs)}:")
|
|
60
|
+
print(blob)
|
|
61
|
+
raise e
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Copyright (c) 2022-2024 Szymon Mikler
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import importlib
|
|
5
|
+
import random
|
|
6
|
+
import sys
|
|
7
|
+
from glob import glob
|
|
8
|
+
from io import StringIO
|
|
9
|
+
|
|
10
|
+
EXPECTED_OUTPUTS = {
|
|
11
|
+
"examples.nn_training": "7e50cfd539e3e1799ecd5a7e7b7a7e18",
|
|
12
|
+
"examples.cumulating": "b5b7bc9b8232545ebfd5ca777bddacb4",
|
|
13
|
+
"examples.fibonacci": "bae5411af4bf8a4326f1bce59ca9aad9",
|
|
14
|
+
"examples.features": "474d4aff94a3070d2300d78d4159e0a6",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def set_seed():
|
|
19
|
+
random.seed(42)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def capture_example_stdout(main_fn):
|
|
23
|
+
# To eliminate run to run variation of the example outputs we need to be independent from the execution speed
|
|
24
|
+
# This includes removing the influence of:
|
|
25
|
+
# * refresh rate
|
|
26
|
+
# * throughput display
|
|
27
|
+
override_kwds = dict(
|
|
28
|
+
refresh_rate=1000000000,
|
|
29
|
+
pbar_show_throughput=False,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# We will replace stdout with custom StringIO and check whether example stdout is as expected
|
|
33
|
+
out_buffer = StringIO()
|
|
34
|
+
sys.stdout = out_buffer
|
|
35
|
+
set_seed()
|
|
36
|
+
main_fn(**override_kwds)
|
|
37
|
+
sys.stdout = sys.__stdout__
|
|
38
|
+
return out_buffer.getvalue()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_all_examples():
|
|
42
|
+
# Testing whether examples run exactly as intended
|
|
43
|
+
|
|
44
|
+
outputs = {}
|
|
45
|
+
for module in glob("examples/*"):
|
|
46
|
+
module = module.replace(".py", "").replace("/", ".")
|
|
47
|
+
print(f"Running example: {module}")
|
|
48
|
+
main_fn = importlib.import_module(module).main
|
|
49
|
+
out_str = capture_example_stdout(main_fn)
|
|
50
|
+
|
|
51
|
+
md5hash = hashlib.md5(out_str.encode()).hexdigest()
|
|
52
|
+
outputs[module] = md5hash
|
|
53
|
+
|
|
54
|
+
err_msg = []
|
|
55
|
+
for key in EXPECTED_OUTPUTS:
|
|
56
|
+
output = outputs.get(key, None)
|
|
57
|
+
expected = EXPECTED_OUTPUTS[key]
|
|
58
|
+
if output != expected:
|
|
59
|
+
err_msg.append(f" {output} instead of {expected} in {key}")
|
|
60
|
+
err_msg = "\n".join(err_msg)
|
|
61
|
+
|
|
62
|
+
if err_msg:
|
|
63
|
+
assert False, f"Errors in example outputs\n{err_msg}"
|
|
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
|