robotframework-pabot 5.2.0b1__py3-none-any.whl → 5.2.0rc2__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.
pabot/result_merger.py CHANGED
@@ -32,6 +32,7 @@ except ImportError:
32
32
  from robot.result.testsuite import TestSuite
33
33
 
34
34
  from robot.model import SuiteVisitor
35
+ from .writer import get_writer
35
36
 
36
37
 
37
38
  class ResultMerger(SuiteVisitor):
@@ -45,6 +46,7 @@ class ResultMerger(SuiteVisitor):
45
46
  self._out_dir = out_dir
46
47
  self.legacy_output = legacy_output
47
48
  self.timestamp_id = timestamp_id
49
+ self.writer = get_writer()
48
50
 
49
51
  self._patterns = []
50
52
  regexp_template = (
@@ -62,7 +64,10 @@ class ResultMerger(SuiteVisitor):
62
64
  if self.errors != merged.errors:
63
65
  self.errors.add(merged.errors)
64
66
  except:
65
- print("Error while merging result %s" % merged.source)
67
+ if self.writer:
68
+ self.writer.write("Error while merging result %s" % merged.source, level="error")
69
+ else:
70
+ print("Error while merging result %s" % merged.source)
66
71
  raise
67
72
 
68
73
  def _set_prefix(self, source):
@@ -214,12 +219,17 @@ def prefix(source, timestamp_id):
214
219
 
215
220
  def group_by_root(results, critical_tags, non_critical_tags, invalid_xml_callback):
216
221
  groups = {}
222
+ writer = get_writer()
217
223
  for src in results:
218
224
  try:
219
225
  res = ExecutionResult(src)
220
226
  except DataError as err:
221
- print(err.message)
222
- print("Skipping '%s' from final result" % src)
227
+ if writer:
228
+ writer.write(err.message, level="error")
229
+ writer.write("Skipping '%s' from final result" % src, level="warning")
230
+ else:
231
+ print(err.message)
232
+ print("Skipping '%s' from final result" % src)
223
233
  invalid_xml_callback()
224
234
  continue
225
235
  if ROBOT_VERSION < "4.0":
@@ -280,12 +290,6 @@ def merge(
280
290
  rebot_options.get('legacyoutput')
281
291
  )
282
292
  if len(merged) == 1:
283
- if not merged[0].suite.doc:
284
- merged[
285
- 0
286
- ].suite.doc = "[https://pabot.org/?ref=log|Pabot] result from %d executions." % len(
287
- result_files
288
- )
289
293
  return merged[0]
290
294
  else:
291
295
  return ResultsCombiner(merged)
pabot/writer.py CHANGED
@@ -12,15 +12,91 @@ class Color:
12
12
  SUPPORTED_OSES = {"posix"} # Only Unix terminals support ANSI colors
13
13
 
14
14
 
15
+ class DottedConsole:
16
+ def __init__(self):
17
+ self._on_line = False
18
+
19
+ def dot(self, char):
20
+ print(char, end="", flush=True)
21
+ self._on_line = True
22
+
23
+ def newline(self):
24
+ if self._on_line:
25
+ print()
26
+ self._on_line = False
27
+
28
+
29
+ class BufferingWriter:
30
+ """
31
+ Buffers partial writes until a newline is encountered.
32
+ Useful for handling output that comes in fragments (e.g., from stderr).
33
+ """
34
+ def __init__(self, writer, level="info", original_stderr_name=None):
35
+ self._writer = writer
36
+ self._level = level
37
+ self.original_stderr_name = original_stderr_name
38
+ self._buffer = ""
39
+ self._lock = threading.Lock()
40
+
41
+ def write(self, msg):
42
+ with self._lock:
43
+ if not msg:
44
+ return
45
+
46
+ self._buffer += msg
47
+
48
+ # Check if buffer contains newline(s)
49
+ while "\n" in self._buffer:
50
+ line, self._buffer = self._buffer.split("\n", 1)
51
+ if line: # Only write non-empty lines
52
+ if self.original_stderr_name:
53
+ line = f"From {self.original_stderr_name}: {line}"
54
+ try:
55
+ self._writer.write(line, level=self._level)
56
+ except (RuntimeError, ValueError):
57
+ # Writer/stdout already closed
58
+ break
59
+
60
+ # If buffer ends with partial content (no newline), keep it buffered
61
+
62
+ def flush(self):
63
+ with self._lock:
64
+ if self._buffer:
65
+ try:
66
+ self._writer.write(self._buffer, level=self._level)
67
+ except (RuntimeError, ValueError):
68
+ pass
69
+ self._buffer = ""
70
+
71
+
72
+ class ThreadSafeWriter:
73
+ def __init__(self, writer, level="info"):
74
+ self._writer = writer
75
+ self._lock = threading.Lock()
76
+ self._level = level # Default level for this writer instance
77
+
78
+ def write(self, msg, level=None):
79
+ # Use provided level or fall back to instance default
80
+ msg_level = level if level is not None else self._level
81
+ with self._lock:
82
+ self._writer.write(msg, level=msg_level)
83
+
84
+ def flush(self):
85
+ with self._lock:
86
+ self._writer.flush()
87
+
88
+
15
89
  class MessageWriter:
16
- def __init__(self, log_file=None):
17
- self.queue = queue.Queue()
90
+ def __init__(self, log_file=None, console_type="verbose"):
91
+ self.queue = queue.Queue(maxsize=10000)
18
92
  self.log_file = log_file
93
+ self.console_type = console_type
94
+ self.console = DottedConsole() if console_type == "dotted" else None
19
95
  if log_file:
20
96
  os.makedirs(os.path.dirname(log_file), exist_ok=True)
21
97
  self._stop_event = threading.Event()
22
98
  self.thread = threading.Thread(target=self._writer)
23
- self.thread.daemon = True
99
+ self.thread.daemon = False
24
100
  self.thread.start()
25
101
 
26
102
  def _is_output_coloring_supported(self):
@@ -31,59 +107,129 @@ class MessageWriter:
31
107
  return f"{color}{message}{Color.ENDC}"
32
108
  return message
33
109
 
34
- def _writer(self):
35
- while not self._stop_event.is_set():
36
- try:
37
- message, color = self.queue.get(timeout=0.1)
38
- except queue.Empty:
39
- continue
40
- if message is None:
41
- self.queue.task_done()
42
- break
43
- print(self._wrap_with(color, message))
44
- sys.stdout.flush()
45
- if self.log_file:
46
- with open(self.log_file, "a", encoding="utf-8") as f:
47
- f.write(message + "\n")
48
- self.queue.task_done()
49
-
50
- def write(self, message, color=None):
51
- self.queue.put((f"{message}", color))
52
110
 
53
- def flush(self, timeout=5):
111
+ def _should_print_to_console(self, console_type=None, level="debug"):
54
112
  """
55
- Wait until all queued messages have been written.
56
-
57
- :param timeout: Optional timeout in seconds. If None, wait indefinitely.
58
- :return: True if queue drained before timeout (or no timeout), False if timed out.
113
+ Determine if message should be printed to console based on console_type and level.
114
+ Always write to log file.
115
+
116
+ Args:
117
+ console_type: The console type mode. If None, uses instance default.
118
+ level: Message level (debug, info, warning, error, and spesial results infos: info_passed, info_failed, info_skipped, info_ignored). Defaults to debug.
59
119
  """
60
- start = time.time()
120
+ ct = console_type if console_type is not None else self.console_type
121
+
122
+ # Map levels to importance: debug < info_passed/info_ignored/info_skipped < info_failed < info < warning < error
123
+ level_map = {"debug": 0, "info_passed": 1, "info_ignored": 1, "info_skipped": 1, "info_failed": 2, "info": 3, "warning": 4, "error": 5}
124
+ message_level = level_map.get(level, 0) # default to debug
125
+
126
+ if ct == "none":
127
+ return False
128
+ elif ct == "quiet":
129
+ # In quiet mode, show only warning and error level messages
130
+ return message_level >= 3
131
+ elif ct == "dotted":
132
+ # In dotted mode, show test result indicators (info_passed/failed/skipped/ignored) and warnings/errors
133
+ return message_level >= 1
134
+ # verbose mode - print everything
135
+ return True
136
+
137
+ def _flush_batch(self, batch, log_f):
138
+ for message, color, level in batch:
139
+ # Log file
140
+ if log_f:
141
+ lvl = f"[{level.split('_')[0].upper()}]".ljust(9)
142
+ log_f.write(f"{lvl} {message}\n")
143
+
144
+ # Console
145
+ if self._should_print_to_console(level=level):
146
+ if self.console:
147
+ if level == "info_passed":
148
+ self.console.dot(self._wrap_with(color, "."))
149
+ elif level == "info_failed":
150
+ self.console.dot(self._wrap_with(color, "F"))
151
+ elif level in ("info_ignored", "info_skipped"):
152
+ self.console.dot(self._wrap_with(color, "s"))
153
+ else:
154
+ self.console.newline()
155
+ print(self._wrap_with(color, message))
156
+ else:
157
+ print(self._wrap_with(color, message))
158
+
159
+ def _writer(self):
160
+ log_f = None
61
161
  try:
62
- # Loop until Queue reports no unfinished tasks
162
+ if self.log_file:
163
+ log_f = open(self.log_file, "a", encoding="utf-8", buffering=1)
164
+
165
+ buffer = []
166
+ last_flush = time.time()
167
+ FLUSH_INTERVAL = 0.2 # secs
168
+ BATCH_SIZE = 50 # rows
169
+
63
170
  while True:
64
- # If writer thread died, break to avoid infinite loop
65
- if not self.thread.is_alive():
66
- # Give one last moment for potential in-flight task_done()
67
- time.sleep(0.01)
68
- # If still unfinished, we can't do more
69
- return getattr(self.queue, "unfinished_tasks", 0) == 0
70
-
71
- unfinished = getattr(self.queue, "unfinished_tasks", None)
72
- if unfinished is None:
73
- # Fallback: call join once and return
74
- try:
75
- self.queue.join()
76
- return True
77
- except Exception:
78
- return False
171
+ try:
172
+ item = self.queue.get(timeout=0.1)
173
+ except queue.Empty:
174
+ # Timebased flush
175
+ if buffer and (time.time() - last_flush) > FLUSH_INTERVAL:
176
+ self._flush_batch(buffer, log_f)
177
+ buffer.clear()
178
+ last_flush = time.time()
179
+ if self._stop_event.is_set():
180
+ break
181
+ continue
79
182
 
80
- if unfinished == 0:
81
- return True
183
+ message, color, level = item
184
+
185
+ if message is None:
186
+ self.queue.task_done()
187
+ break
188
+
189
+ message = message.rstrip("\n")
190
+
191
+ buffer.append((message, color, level))
192
+ self.queue.task_done()
193
+
194
+ # Batch full → flush
195
+ if len(buffer) >= BATCH_SIZE:
196
+ self._flush_batch(buffer, log_f)
197
+ buffer.clear()
198
+ last_flush = time.time()
82
199
 
83
- if timeout is not None and (time.time() - start) > timeout:
84
- return False
200
+ # Final flush
201
+ if buffer:
202
+ self._flush_batch(buffer, log_f)
85
203
 
204
+ except Exception:
205
+ import traceback
206
+ traceback.print_exc()
207
+
208
+ finally:
209
+ if log_f:
210
+ try:
211
+ log_f.flush()
212
+ log_f.close()
213
+ except Exception:
214
+ pass
215
+
216
+
217
+ def write(self, message, color=None, level="info"):
218
+ if self._stop_event.is_set():
219
+ return
220
+ try:
221
+ self.queue.put((f"{message}", color, level), timeout=0.1)
222
+ except queue.Full:
223
+ pass # drop
224
+
225
+ def flush(self, timeout=5):
226
+ end = time.time() + timeout
227
+ try:
228
+ while time.time() < end:
229
+ if self.queue.unfinished_tasks == 0:
230
+ return True
86
231
  time.sleep(0.05)
232
+ return False
87
233
  except KeyboardInterrupt:
88
234
  # Allow tests/cli to interrupt flushing
89
235
  return False
@@ -92,19 +238,31 @@ class MessageWriter:
92
238
  """
93
239
  Gracefully stop the writer thread and flush remaining messages.
94
240
  """
95
- self.flush()
96
241
  self._stop_event.set()
97
- self.queue.put((None, None)) # sentinel to break thread loop
98
- self.thread.join(timeout=1.0)
242
+ try:
243
+ self.queue.put_nowait((None, None, None))
244
+ except queue.Full:
245
+ pass
246
+ self.thread.join(timeout=2)
99
247
 
100
248
 
101
249
  _writer_instance = None
102
250
 
103
- def get_writer(log_dir=None):
251
+ def get_writer(log_dir=None, console_type="verbose"):
104
252
  global _writer_instance
105
253
  if _writer_instance is None:
106
254
  if log_dir:
107
255
  os.makedirs(log_dir, exist_ok=True)
108
256
  log_file = os.path.join(log_dir or ".", "pabot_manager.log")
109
- _writer_instance = MessageWriter(log_file=log_file)
257
+ _writer_instance = MessageWriter(log_file=log_file, console_type=console_type)
110
258
  return _writer_instance
259
+
260
+ def get_stdout_writer(log_dir=None, console_type="verbose"):
261
+ """Get a writer configured for stdout with 'info' level"""
262
+ return ThreadSafeWriter(get_writer(log_dir, console_type), level="info")
263
+
264
+ def get_stderr_writer(log_dir=None, console_type="verbose", original_stderr_name: str = None):
265
+ """Get a writer configured for stderr with 'error' level, buffered to handle partial writes"""
266
+ # Use BufferingWriter to combine fragments that come without newlines
267
+ buffering_writer = BufferingWriter(get_writer(log_dir, console_type), level="error", original_stderr_name=original_stderr_name)
268
+ return buffering_writer
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotframework-pabot
3
- Version: 5.2.0b1
3
+ Version: 5.2.0rc2
4
4
  Summary: Parallel test runner for Robot Framework
5
5
  Home-page: https://pabot.org
6
6
  Download-URL: https://pypi.python.org/pypi/robotframework-pabot
@@ -118,10 +118,11 @@ pabot [--verbose|--testlevelsplit|--command .. --end-command|
118
118
  --shard i/n|
119
119
  --artifacts extensions|--artifactsinsubfolders|
120
120
  --resourcefile file|--argumentfile[num] file|--suitesfrom file
121
- --ordering <FILENAME> [static|dynamic] [skip|run_all]|
121
+ --ordering file [static|dynamic] [skip|run_all]|
122
122
  --chunk|
123
123
  --pabotprerunmodifier modifier|
124
124
  --no-rebot|
125
+ --pabotconsole [verbose|dotted|quiet|none]|
125
126
  --help|--version]
126
127
  [robot options] [path ...]
127
128
  ```
@@ -193,7 +194,7 @@ Supports all [Robot Framework command line options](https://robotframework.org/r
193
194
 
194
195
  **--resourcefile [FILEPATH]**
195
196
  Indicator for a file that can contain shared variables for distributing resources. This needs to be used together with
196
- pabotlib option. Resource file syntax is same as Windows ini files. Where a section is a shared set of variables.
197
+ pabotlib option. Resource file syntax is same as Windows ini files where a section is a shared set of variables.
197
198
 
198
199
  **--argumentfile[INTEGER] [FILEPATH]**
199
200
  Run same suites with multiple [argumentfile](http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#argument-files) options.
@@ -206,10 +207,10 @@ Supports all [Robot Framework command line options](https://robotframework.org/r
206
207
  Optionally read suites from output.xml file. Failed suites will run first and longer running ones will be executed
207
208
  before shorter ones.
208
209
 
209
- **--ordering [FILE PATH] [MODE] [FAILURE POLICY]**
210
+ **--ordering [FILEPATH] [MODE] [FAILURE POLICY]**
210
211
  Optionally give execution order from a file. See README.md section: [Controlling execution order, mode and level of parallelism](#controlling-execution-order-mode-and-level-of-parallelism)
211
- - MODE (optional): [static (default)|dynamic]
212
- - FAILURE POLICY (optional, only in dynamic mode): [skip|run_all (default)]
212
+ - MODE (optional): [ static (default) | dynamic ]
213
+ - FAILURE POLICY (optional, only in dynamic mode): [ skip | run_all (default) ]
213
214
 
214
215
  **--chunk**
215
216
  Optionally chunk tests to PROCESSES number of robot runs. This can save time because all the suites will share the same
@@ -226,6 +227,28 @@ Supports all [Robot Framework command line options](https://robotframework.org/r
226
227
  for scenarios where Rebot should be run later due to large log files, ensuring better memory and resource availability.
227
228
  Subprocess results are stored in the pabot_results folder.
228
229
 
230
+ **--pabotconsole [MODE]**
231
+ The --pabotconsole option controls how much output is printed to the console.
232
+ Note that all Pabot’s own messages are always logged to pabot_manager.log, regardless of the selected console mode.
233
+
234
+ The available options are:
235
+ - verbose (default):
236
+ Prints all messages to the console, corresponding closely to what is written to the log file.
237
+ - dotted:
238
+ Prints important messages, warnings, and errors to the console, along with execution progress using the following notation:
239
+
240
+ - PASS = .
241
+ - FAIL = F
242
+ - SKIP = s
243
+
244
+ Note that each Robot Framework process is represented by a single character.
245
+ Depending on the execution parameters, individual tests may not have their own status character;
246
+ instead, the status may represent an entire suite or a group of tests.
247
+ - quiet:
248
+ Similar to dotted, but suppresses execution progress output.
249
+ - none:
250
+ Produces no console output at all.
251
+
229
252
  **--help**
230
253
  Print usage instructions.
231
254
 
@@ -491,7 +514,7 @@ pabot_results/
491
514
  │ ├── robot_stdout.out
492
515
  │ ├── robot_stderr.out
493
516
  │ └── artifacts...
494
- pabot_manager.log # Pabot's own main log. Basically same than prints in console
517
+ └── pabot_manager.log # Pabot's own main log.
495
518
  ```
496
519
 
497
520
  Each `PABOTQUEUEINDEX` folder contains as default:
@@ -0,0 +1,23 @@
1
+ pabot/ProcessManager.py,sha256=Y4SUOLJ-AmQCc1Y49IYjZS34uqRUnlDt-G2AGymAdHg,13627
2
+ pabot/SharedLibrary.py,sha256=mIipGs3ZhKYEakKprcbrMI4P_Un6qI8gE7086xpHaLY,2552
3
+ pabot/__init__.py,sha256=Q8E5VA1T7yYCUTZrCg3pEtcKl4AAA1EhUA-PRA3RnRk,203
4
+ pabot/arguments.py,sha256=UAJyCb3F1--4qpYTuG6SL7rafPC3lLtQIEr9zJ0JNwU,12229
5
+ pabot/clientwrapper.py,sha256=yz7battGs0exysnDeLDWJuzpb2Q-qSjitwxZMO2TlJw,231
6
+ pabot/coordinatorwrapper.py,sha256=nQQ7IowD6c246y8y9nsx0HZbt8vS2XODhPVDjm-lyi0,195
7
+ pabot/execution_items.py,sha256=zDVGW0AAeVbM-scC3Yui2TxvIPx1wYyFKHTPU2BkJkY,13329
8
+ pabot/pabot.py,sha256=oHIvEHz1l27IIFjoAcU9bQw9Tf-m6o_v_mjAnTWKxKw,99944
9
+ pabot/pabotlib.py,sha256=vHbqV7L7mIvDzXBh9UcdULrwhBHNn70EDXF_31MNFO4,22320
10
+ pabot/result_merger.py,sha256=eqsF5FBqU_7N1Ti34nD2mrjVAr0uWTk67Ix582vCOaE,9963
11
+ pabot/robotremoteserver.py,sha256=BdeIni9Q4LJKVDBUlG2uJ9tiyAjrPXwU_YsPq1THWoo,23296
12
+ pabot/workerwrapper.py,sha256=BdELUVDs5BmEkdNBcYTlnP22Cj0tUpZEunYQMAKyKWU,185
13
+ pabot/writer.py,sha256=91HrYV8fLOYYxGycTnO4h18EsCppLtwKTn2R4mfxKMk,9391
14
+ pabot/py3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ pabot/py3/client.py,sha256=Od9L4vZ0sozMHq_W_ITQHBBt8kAej40DG58wnxmbHGM,1434
16
+ pabot/py3/coordinator.py,sha256=kBshCzA_1QX_f0WNk42QBJyDYSwSlNM-UEBxOReOj6E,2313
17
+ pabot/py3/messages.py,sha256=7mFr4_0x1JHm5sW8TvKq28Xs_JoeIGku2bX7AyO0kng,2557
18
+ pabot/py3/worker.py,sha256=5rfp4ZiW6gf8GRz6eC0-KUkfx847A91lVtRYpLAv2sg,1612
19
+ robotframework_pabot-5.2.0rc2.dist-info/METADATA,sha256=81x6M9TGs27yKenKnTkaloq8nUQS52kzVQF9SNvq_0Y,24791
20
+ robotframework_pabot-5.2.0rc2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
21
+ robotframework_pabot-5.2.0rc2.dist-info/entry_points.txt,sha256=JpAIFADTeFOQWdwmn56KpAil8V3-41ZC5ICXCYm3Ng0,43
22
+ robotframework_pabot-5.2.0rc2.dist-info/top_level.txt,sha256=t3OwfEAsSxyxrhjy_GCJYHKbV_X6AIsgeLhYeHvObG4,6
23
+ robotframework_pabot-5.2.0rc2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
pabot/skip_listener.py DELETED
@@ -1,7 +0,0 @@
1
- ROBOT_LISTENER_API_VERSION = 3
2
-
3
- def end_test(data, result):
4
- # data: TestCase object
5
- # result: TestCaseResult object
6
- result.status = 'SKIP'
7
- result.message = "Pabot skip logic: this test was skipped due to dependencies and failure policy."
pabot/timeout_listener.py DELETED
@@ -1,5 +0,0 @@
1
- ROBOT_LISTENER_API_VERSION = 3
2
-
3
- def end_test(data, result):
4
- result.status = 'FAIL'
5
- result.message = "Pabot's --processtimeout option has been reached."
@@ -1,25 +0,0 @@
1
- pabot/ProcessManager.py,sha256=w3dgtEKGhn4rj3nQ1EEQFAPeiIv6OF-KU6R3WZwQxPs,11739
2
- pabot/SharedLibrary.py,sha256=mIipGs3ZhKYEakKprcbrMI4P_Un6qI8gE7086xpHaLY,2552
3
- pabot/__init__.py,sha256=KuCXsD2BDgEFiQAxVRLN3SXkkyCULXtW06tTTqCEuRo,202
4
- pabot/arguments.py,sha256=6MBXKnbDgWNdu7NnRqqd2_GNOs-u8QOxCz9wHhyfUVI,11404
5
- pabot/clientwrapper.py,sha256=yz7battGs0exysnDeLDWJuzpb2Q-qSjitwxZMO2TlJw,231
6
- pabot/coordinatorwrapper.py,sha256=nQQ7IowD6c246y8y9nsx0HZbt8vS2XODhPVDjm-lyi0,195
7
- pabot/execution_items.py,sha256=zDVGW0AAeVbM-scC3Yui2TxvIPx1wYyFKHTPU2BkJkY,13329
8
- pabot/pabot.py,sha256=hfMZdMYmeZEo3mNAVrvmuPU9vGhKpIBEVq5R8BI5ovE,87438
9
- pabot/pabotlib.py,sha256=vHbqV7L7mIvDzXBh9UcdULrwhBHNn70EDXF_31MNFO4,22320
10
- pabot/result_merger.py,sha256=g4mm-BhhMK57Z6j6dpvfL5El1g5onOtfV4RByNrO8g0,9744
11
- pabot/robotremoteserver.py,sha256=BdeIni9Q4LJKVDBUlG2uJ9tiyAjrPXwU_YsPq1THWoo,23296
12
- pabot/skip_listener.py,sha256=xv7wH-yB_nfc_AT1oZh3C0iu8hS67g5a28x8hwSrYsE,254
13
- pabot/timeout_listener.py,sha256=twZFiJEyn9tAqI1K6JDBGaZrxRqVLFDVWvyxa6d8Lb0,160
14
- pabot/workerwrapper.py,sha256=BdELUVDs5BmEkdNBcYTlnP22Cj0tUpZEunYQMAKyKWU,185
15
- pabot/writer.py,sha256=_sRN_EqIhaMwPYmTkN4NzO2Mj6tggcaxgYkqJKatb_c,3639
16
- pabot/py3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- pabot/py3/client.py,sha256=Od9L4vZ0sozMHq_W_ITQHBBt8kAej40DG58wnxmbHGM,1434
18
- pabot/py3/coordinator.py,sha256=kBshCzA_1QX_f0WNk42QBJyDYSwSlNM-UEBxOReOj6E,2313
19
- pabot/py3/messages.py,sha256=7mFr4_0x1JHm5sW8TvKq28Xs_JoeIGku2bX7AyO0kng,2557
20
- pabot/py3/worker.py,sha256=5rfp4ZiW6gf8GRz6eC0-KUkfx847A91lVtRYpLAv2sg,1612
21
- robotframework_pabot-5.2.0b1.dist-info/METADATA,sha256=_7b2wWKxeuFlEbRCz_sHwmrWQCwp85v-rl9HX-mScyo,23811
22
- robotframework_pabot-5.2.0b1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- robotframework_pabot-5.2.0b1.dist-info/entry_points.txt,sha256=JpAIFADTeFOQWdwmn56KpAil8V3-41ZC5ICXCYm3Ng0,43
24
- robotframework_pabot-5.2.0b1.dist-info/top_level.txt,sha256=t3OwfEAsSxyxrhjy_GCJYHKbV_X6AIsgeLhYeHvObG4,6
25
- robotframework_pabot-5.2.0b1.dist-info/RECORD,,