ScriptCollection 3.5.61__py3-none-any.whl → 3.5.63__py3-none-any.whl

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.
@@ -937,3 +937,16 @@ class GeneralUtilities:
937
937
  GeneralUtilities.assert_condition(not (amount_of_attempts < amount_of_fails))
938
938
  if amount_of_fails == amount_of_attempts:
939
939
  raise
940
+
941
+ @staticmethod
942
+ @check_arguments
943
+ def int_to_string(number: int, leading_zeroplaces: int, trailing_zeroplaces: int) -> str:
944
+ return GeneralUtilities.float_to_string(float(number), leading_zeroplaces, trailing_zeroplaces)
945
+
946
+ @staticmethod
947
+ @check_arguments
948
+ def float_to_string(number: float, leading_zeroplaces: int, trailing_zeroplaces: int) -> str:
949
+ plain_str = str(number)
950
+ GeneralUtilities.assert_condition("." in plain_str)
951
+ splitted: list[str] = plain_str.split(".")
952
+ return splitted[0].zfill(leading_zeroplaces)+"."+splitted[1].ljust(trailing_zeroplaces, '0')
@@ -31,7 +31,7 @@ from .ProgramRunnerBase import ProgramRunnerBase
31
31
  from .ProgramRunnerPopen import ProgramRunnerPopen
32
32
  from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
33
33
 
34
- version = "3.5.61"
34
+ version = "3.5.63"
35
35
  __version__ = version
36
36
 
37
37
 
@@ -1291,7 +1291,7 @@ class ScriptCollectionCore:
1291
1291
  return False
1292
1292
 
1293
1293
  @staticmethod
1294
- def __read_popen_pipes(p: Popen):
1294
+ def __read_popen_pipes(p: Popen) -> tuple[list[str], list[str]]:
1295
1295
  p_id = p.pid
1296
1296
  with ThreadPoolExecutor(2) as pool:
1297
1297
  q_stdout = Queue()
@@ -1301,32 +1301,32 @@ class ScriptCollectionCore:
1301
1301
  pool.submit(ScriptCollectionCore.__enqueue_output, p.stderr, q_stderr)
1302
1302
  reading_stdout_last_time_resulted_in_exception: bool = False
1303
1303
  reading_stderr_last_time_resulted_in_exception: bool = False
1304
+
1305
+ stdout_result: list[str] = []
1306
+ stderr_result: list[str] = []
1307
+
1304
1308
  while (ScriptCollectionCore.__continue_process_reading(p_id, p, q_stdout, q_stderr, reading_stdout_last_time_resulted_in_exception, reading_stderr_last_time_resulted_in_exception)):
1305
- out_line = None
1306
- err_line = None
1309
+
1307
1310
  try:
1308
- out_line = q_stdout.get_nowait() # TODO read all avaliable lines
1309
- reading_stdout_last_time_resulted_in_exception = False
1311
+ while not q_stdout.empty():
1312
+ stdout_result.append(q_stdout.get_nowait())
1313
+ reading_stdout_last_time_resulted_in_exception = False
1310
1314
  except Empty:
1311
1315
  reading_stdout_last_time_resulted_in_exception = True
1312
1316
 
1313
1317
  try:
1314
- err_line = q_stderr.get_nowait() # TODO read all avaliable lines
1315
- reading_stderr_last_time_resulted_in_exception = False
1318
+ while not q_stderr.empty():
1319
+ stderr_result.append(q_stderr.get_nowait())
1320
+ reading_stderr_last_time_resulted_in_exception = False
1316
1321
  except Empty:
1317
1322
  reading_stderr_last_time_resulted_in_exception = True
1318
1323
 
1319
1324
  time.sleep(0.01) # this is required to not finish too early
1320
1325
 
1321
- yield (out_line, err_line)
1326
+ return (stdout_result, stderr_result)
1322
1327
 
1323
- # Return-values program_runner: Exitcode, StdOut, StdErr, Pid
1324
1328
  @GeneralUtilities.check_arguments
1325
- def run_program_argsasarray(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, verbosity: int = 1, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, throw_exception_if_exitcode_is_not_zero: bool = True, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
1326
- # verbosity 1: No output will be logged.
1327
- # verbosity 2: If the exitcode of the executed program is not 0 then the StdErr will be logged. This is supposed to be the default verbosity-level.
1328
- # verbosity 3: Logs and prints StdOut and StdErr of the executed program in realtime.
1329
- # verbosity 4: Same as loglevel 3 but with some more overhead-information.
1329
+ def run_program_argsasarray(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, verbosity: int = 0, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, throw_exception_if_exitcode_is_not_zero: bool = True, custom_argument: object = None, interactive: bool = False, print_live_output: bool = False) -> tuple[int, str, str, int]:
1330
1330
  if self.call_program_runner_directly:
1331
1331
  return self.program_runner.run_program_argsasarray(program, arguments_as_array, working_directory, custom_argument, interactive)
1332
1332
  try:
@@ -1348,11 +1348,10 @@ class ScriptCollectionCore:
1348
1348
  else:
1349
1349
  info_for_log = title
1350
1350
 
1351
- if verbosity >= 3:
1351
+ verbose = verbosity > 0
1352
+ if verbose:
1352
1353
  GeneralUtilities.write_message_to_stdout(f"Run '{info_for_log}'.")
1353
1354
 
1354
- print_live_output = 1 < verbosity
1355
-
1356
1355
  exit_code: int = None
1357
1356
  stdout: str = ""
1358
1357
  stderr: str = ""
@@ -1363,8 +1362,10 @@ class ScriptCollectionCore:
1363
1362
  if log_file is not None:
1364
1363
  GeneralUtilities.ensure_file_exists(log_file)
1365
1364
  pid = process.pid
1366
- for out_line_plain, err_line_plain in ScriptCollectionCore.__read_popen_pipes(process): # see https://stackoverflow.com/a/57084403/3905529
1367
1365
 
1366
+ outputs: tuple[list[str], list[str]] = ScriptCollectionCore.__read_popen_pipes(process)
1367
+
1368
+ for out_line_plain in outputs[0]:
1368
1369
  if out_line_plain is not None:
1369
1370
  out_line: str = None
1370
1371
  if isinstance(out_line_plain, str):
@@ -1385,6 +1386,7 @@ class ScriptCollectionCore:
1385
1386
  if log_file is not None:
1386
1387
  GeneralUtilities.append_line_to_file(log_file, out_line)
1387
1388
 
1389
+ for err_line_plain in outputs[1]:
1388
1390
  if err_line_plain is not None:
1389
1391
  err_line: str = None
1390
1392
  if isinstance(err_line_plain, str):
@@ -1405,11 +1407,16 @@ class ScriptCollectionCore:
1405
1407
  GeneralUtilities.append_line_to_file(log_file, err_line)
1406
1408
 
1407
1409
  exit_code = process.returncode
1410
+ GeneralUtilities.assert_condition(exit_code is not None, f"Exitcode of program-run of '{info_for_log}' is None.")
1411
+
1412
+ result_message = f"Program '{info_for_log}' resulted in exitcode {exit_code}."
1413
+
1414
+ if verbose:
1415
+ GeneralUtilities.write_message_to_stdout(result_message)
1408
1416
 
1409
1417
  if throw_exception_if_exitcode_is_not_zero and exit_code != 0:
1410
- raise ValueError(f"Program '{working_directory}>{program} {arguments_for_log_as_string}' resulted in exitcode {exit_code}. (StdOut: '{stdout}', StdErr: '{stderr}')")
1418
+ raise ValueError(f"{result_message} (StdOut: '{stdout}', StdErr: '{stderr}')")
1411
1419
 
1412
- GeneralUtilities.assert_condition(exit_code is not None, f"Exitcode of program-run of '{info_for_log}' is None.")
1413
1420
  result = (exit_code, stdout, stderr, pid)
1414
1421
  return result
1415
1422
  except Exception as e:
@@ -1417,10 +1424,10 @@ class ScriptCollectionCore:
1417
1424
 
1418
1425
  # Return-values program_runner: Exitcode, StdOut, StdErr, Pid
1419
1426
  @GeneralUtilities.check_arguments
1420
- def run_program(self, program: str, arguments: str = "", working_directory: str = None, verbosity: int = 1, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, throw_exception_if_exitcode_is_not_zero: bool = True, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
1427
+ def run_program(self, program: str, arguments: str = "", working_directory: str = None, verbosity: int = 1, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, throw_exception_if_exitcode_is_not_zero: bool = True, custom_argument: object = None, interactive: bool = False, print_live_output: bool = False) -> tuple[int, str, str, int]:
1421
1428
  if self.call_program_runner_directly:
1422
1429
  return self.program_runner.run_program(program, arguments, working_directory, custom_argument, interactive)
1423
- return self.run_program_argsasarray(program, GeneralUtilities.arguments_to_array(arguments), working_directory, verbosity, print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, throw_exception_if_exitcode_is_not_zero, custom_argument, interactive)
1430
+ return self.run_program_argsasarray(program, GeneralUtilities.arguments_to_array(arguments), working_directory, verbosity, print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, throw_exception_if_exitcode_is_not_zero, custom_argument, interactive, print_live_output)
1424
1431
 
1425
1432
  # Return-values program_runner: Pid
1426
1433
  @GeneralUtilities.check_arguments
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ScriptCollection
3
- Version: 3.5.61
3
+ Version: 3.5.63
4
4
  Summary: The ScriptCollection is the place for reusable scripts.
5
5
  Home-page: https://github.com/anionDev/ScriptCollection
6
6
  Author: Marius Göcke
@@ -23,19 +23,19 @@ Classifier: Topic :: Utilities
23
23
  Requires-Python: >=3.10
24
24
  Description-Content-Type: text/markdown
25
25
  Requires-Dist: build>=1.2.2.post1
26
- Requires-Dist: coverage>=7.6.11
26
+ Requires-Dist: coverage>=7.6.12
27
27
  Requires-Dist: cyclonedx-bom>=5.1.2
28
28
  Requires-Dist: defusedxml>=0.7.1
29
29
  Requires-Dist: keyboard>=0.13.5
30
30
  Requires-Dist: lcov-cobertura>=2.0.2
31
- Requires-Dist: lxml>=5.3.0
31
+ Requires-Dist: lxml>=5.3.1
32
32
  Requires-Dist: ntplib>=0.4.0
33
33
  Requires-Dist: Pillow>=11.1.0
34
34
  Requires-Dist: pycdlib>=1.14.0
35
35
  Requires-Dist: Pygments>=2.19.1
36
36
  Requires-Dist: pylint>=3.3.4
37
37
  Requires-Dist: pyOpenSSL>=25.0.0
38
- Requires-Dist: PyPDF>=5.2.0
38
+ Requires-Dist: PyPDF>=5.3.0
39
39
  Requires-Dist: pytest>=8.3.4
40
40
  Requires-Dist: PyYAML>=6.0.2
41
41
  Requires-Dist: qrcode>=8.0
@@ -1,16 +1,16 @@
1
1
  ScriptCollection/Executables.py,sha256=kON_jatJe84iCJj60uUjA-Aj0ytERRe0FUDWbOWUe6s,28089
2
- ScriptCollection/GeneralUtilities.py,sha256=nlSZSsQVHWxf0Yzz4PjgZm39rgvIltVof8gL2YPgR7s,38805
2
+ ScriptCollection/GeneralUtilities.py,sha256=Ah-quoBRLNO3iTCfZaAlN0fhOC42b-UEGYRMW_XxgO0,39438
3
3
  ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
4
4
  ScriptCollection/ProgramRunnerBase.py,sha256=2kMIAqdc65UjBAddOZkzy_aFx9h5roZ5a4bQNM6RV6Y,2480
5
5
  ScriptCollection/ProgramRunnerEpew.py,sha256=4pjEd0r9Fcz3TTDv0MdTSd5KkigYXcWUVI1X43regfU,6477
6
6
  ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
7
7
  ScriptCollection/RPStream.py,sha256=NRRHL3YSP3D9MuAV2jB_--0KUKCsvJGxeKnxgrRZ9kY,1545
8
- ScriptCollection/ScriptCollectionCore.py,sha256=gmFAw9p9gVi4Z4vCtAsCS7bQUDLVMHJ66AEtuoaLx1o,111227
8
+ ScriptCollection/ScriptCollectionCore.py,sha256=MmquG7F2-HqTLfdIh3i5fTFWoYGVW6VYDYLCKL7cf0c,111127
9
9
  ScriptCollection/TasksForCommonProjectStructure.py,sha256=B3-KSAZOR_UKSeLsdAxyZu2ylsRSjDvlj0272TXSEfA,213090
10
10
  ScriptCollection/UpdateCertificates.py,sha256=Eynbgu7k9jLxApP2D_8Il77B6BFjJap6K7oTeEAZYbk,7790
11
11
  ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- ScriptCollection-3.5.61.dist-info/METADATA,sha256=lrV7TcbmII8Mz2Bd7CFXv46tw-XIr8YozP5sfDCOgbk,7664
13
- ScriptCollection-3.5.61.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
14
- ScriptCollection-3.5.61.dist-info/entry_points.txt,sha256=wspYVXWH8kon-wRQTAFEO11JoLJ0fEnOIG7tE7R-xtQ,3502
15
- ScriptCollection-3.5.61.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
16
- ScriptCollection-3.5.61.dist-info/RECORD,,
12
+ ScriptCollection-3.5.63.dist-info/METADATA,sha256=z5ogco0bttHzdHE8RCxBd_0QyvCLmBCnvcHNSJ3A2xk,7664
13
+ ScriptCollection-3.5.63.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
14
+ ScriptCollection-3.5.63.dist-info/entry_points.txt,sha256=wspYVXWH8kon-wRQTAFEO11JoLJ0fEnOIG7tE7R-xtQ,3502
15
+ ScriptCollection-3.5.63.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
16
+ ScriptCollection-3.5.63.dist-info/RECORD,,