pyallel 1.3.1__tar.gz → 1.3.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyallel
3
- Version: 1.3.1
3
+ Version: 1.3.3
4
4
  Summary: Run and handle the output of multiple executables in pyallel (as in parallel)
5
5
  Home-page: https://github.com/Danthewaann/pyallel
6
6
  License: MIT
@@ -66,7 +66,7 @@ positional arguments:
66
66
  --------------
67
67
  commands can be grouped using the group separator symbol (:::)
68
68
 
69
- %(prog)s "echo boil kettle" "sleep 1" ::: "echo make coffee"
69
+ pyallel "echo boil kettle" "sleep 1" ::: "echo make coffee"
70
70
 
71
71
  the above will print "boil kettle" and sleep for 1 second first before printing "make coffee"
72
72
 
@@ -79,8 +79,8 @@ positional arguments:
79
79
 
80
80
  lines (only used in interactive mode):
81
81
  the lines modifier allows you to specify how many lines the command output can take up on the screen
82
-
83
- %(prog)s "lines=90 :: echo running long command..." "echo running other command..."
82
+
83
+ pyallel "lines=90 :: echo running long command..." "echo running other command..."
84
84
 
85
85
  90 is expressed as a percentage value, which must be between 1 and 100 inclusive
86
86
 
@@ -42,7 +42,7 @@ positional arguments:
42
42
  --------------
43
43
  commands can be grouped using the group separator symbol (:::)
44
44
 
45
- %(prog)s "echo boil kettle" "sleep 1" ::: "echo make coffee"
45
+ pyallel "echo boil kettle" "sleep 1" ::: "echo make coffee"
46
46
 
47
47
  the above will print "boil kettle" and sleep for 1 second first before printing "make coffee"
48
48
 
@@ -55,8 +55,8 @@ positional arguments:
55
55
 
56
56
  lines (only used in interactive mode):
57
57
  the lines modifier allows you to specify how many lines the command output can take up on the screen
58
-
59
- %(prog)s "lines=90 :: echo running long command..." "echo running other command..."
58
+
59
+ pyallel "lines=90 :: echo running long command..." "echo running other command..."
60
60
 
61
61
  90 is expressed as a percentage value, which must be between 1 and 100 inclusive
62
62
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pyallel"
3
- version = "1.3.1"
3
+ version = "1.3.3"
4
4
  description = "Run and handle the output of multiple executables in pyallel (as in parallel)"
5
5
  authors = ["Daniel Black <danielcrblack@gmail.com>"]
6
6
  license = "MIT"
@@ -259,46 +259,69 @@ def set_process_lines(
259
259
  lines -= 2
260
260
 
261
261
  # Allocate lines to processes that have a fixed percentage of lines set
262
+ allocated_process_lines = lines // len(output.processes)
263
+ processes_with_dynamic_lines: list[ProcessOutput] = []
262
264
  used_lines = 0
263
- process_with_most_lines: ProcessOutput | None = None
264
- other_processes: list[ProcessOutput] = []
265
- for out in output.processes:
266
- if not out.process.percentage_lines:
267
- other_processes.append(out)
265
+ for process_output in output.processes:
266
+ # This process output doesn't have percentage_lines set, so skip it
267
+ if not process_output.process.percentage_lines:
268
+ processes_with_dynamic_lines.append(process_output)
268
269
  continue
269
270
 
270
- out.process.lines = int(lines * out.process.percentage_lines)
271
- used_lines += out.process.lines
272
-
273
- if (
274
- process_with_most_lines is None
275
- or process_with_most_lines.process.lines < out.process.lines
276
- ):
277
- process_with_most_lines = out
271
+ process_output.process.lines = int(
272
+ lines * process_output.process.percentage_lines
273
+ )
274
+ used_lines += process_output.process.lines
278
275
 
276
+ # Remove the used lines from the total available lines
279
277
  lines -= used_lines
280
278
 
281
- # Allocate the rest of the available lines to the other processes that don't have fixed lines set
282
- num_dynamic_processes = len(other_processes)
283
- if num_dynamic_processes:
284
- remainder = lines % num_dynamic_processes
285
- tail = lines // num_dynamic_processes
286
-
287
- for out in other_processes:
288
- out.process.lines = tail
279
+ while lines:
280
+ # Calculate how many lines each process should have based on how many processes and lines are left
281
+ num_processes = len(processes_with_dynamic_lines) or 1
282
+ allocated_process_lines = lines // num_processes
283
+ processes_with_excess_output: list[ProcessOutput] = []
284
+ recalculate_lines = False
285
+ for process_output in processes_with_dynamic_lines:
286
+ # If the number of lines in this process output is less than how many terminal lines we would allocate it,
287
+ # Set it's allocated terminal lines to the exact number of lines in its output and remove this number from
288
+ # the total available terminal lines
289
+ if process_output.lines < allocated_process_lines:
290
+ process_output.process.lines = process_output.lines
291
+ lines -= process_output.process.lines
292
+ recalculate_lines = True
293
+ continue
294
+
295
+ processes_with_excess_output.append(process_output)
296
+
297
+ # We need to re-calcuate how many terminal lines we can allocate to each process if the output of at least one process
298
+ # contains less lines than what we would normally allocate it. This is done so we can allocate these extra lines to the
299
+ # other processes that contain more lines of output.
300
+ if recalculate_lines:
301
+ processes_with_dynamic_lines = processes_with_excess_output
302
+ else:
303
+ # All remaining processes exceed the number of terminal lines we will allocate them, so allocate them
304
+ # their terminal lines as normal and break out of the while loop
305
+ for process_output in processes_with_excess_output:
306
+ process_output.process.lines = allocated_process_lines
307
+ lines -= allocated_process_lines
308
+
309
+ # If there is any lines left, allocate them to the process that currently contains the most lines in its output, or
310
+ # allocate them to the first process if no process contains enough lines
311
+ if lines:
312
+ process_with_most_lines: ProcessOutput | None = None
313
+ most_lines = 0
314
+ for process_output in output.processes:
315
+ if process_output.process.lines > most_lines:
316
+ process_with_most_lines = process_output
317
+ most_lines = process_output.process.lines
318
+
319
+ if not process_with_most_lines:
320
+ output.processes[0].process.lines += lines
321
+ else:
322
+ process_with_most_lines.process.lines += lines
289
323
 
290
- # If we have lines left to allocate, we give all of them to the process with the highest
291
- # allocated lines or to the last process
292
- if remainder:
293
- if process_with_most_lines:
294
- process_with_most_lines.process.lines += remainder
295
- else:
296
- other_processes[-1].process.lines += remainder
297
- else:
298
- # Otherwise allocate remaining lines to the process with the highest allocated lines
299
- remainder = lines
300
- if remainder and process_with_most_lines:
301
- process_with_most_lines.process.lines += remainder
324
+ break
302
325
 
303
326
 
304
327
  def get_num_lines(line: str, columns: int | None = None) -> int:
@@ -13,10 +13,12 @@ class ProcessOutput:
13
13
  def __init__(self, id: int, process: Process, data: str = "") -> None:
14
14
  self.id = id
15
15
  self.data = data
16
+ self.lines = len(data.splitlines()) + 1
16
17
  self.process = process
17
18
 
18
19
  def merge(self, other: ProcessOutput) -> None:
19
20
  self.data += other.data
21
+ self.lines += len(other.data.splitlines())
20
22
 
21
23
 
22
24
  class Process:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes