jolt 0.9.76__py3-none-any.whl → 0.9.429__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.
Files changed (201) hide show
  1. jolt/__init__.py +88 -7
  2. jolt/__main__.py +9 -1
  3. jolt/bin/fstree-darwin-x86_64 +0 -0
  4. jolt/bin/fstree-linux-x86_64 +0 -0
  5. jolt/cache.py +839 -367
  6. jolt/chroot.py +156 -0
  7. jolt/cli.py +362 -143
  8. jolt/common_pb2.py +63 -0
  9. jolt/common_pb2_grpc.py +4 -0
  10. jolt/config.py +99 -42
  11. jolt/error.py +19 -4
  12. jolt/expires.py +2 -2
  13. jolt/filesystem.py +8 -6
  14. jolt/graph.py +705 -117
  15. jolt/hooks.py +63 -1
  16. jolt/influence.py +129 -6
  17. jolt/loader.py +369 -121
  18. jolt/log.py +225 -63
  19. jolt/manifest.py +28 -38
  20. jolt/options.py +35 -10
  21. jolt/pkgs/abseil.py +42 -0
  22. jolt/pkgs/asio.py +25 -0
  23. jolt/pkgs/autoconf.py +41 -0
  24. jolt/pkgs/automake.py +41 -0
  25. jolt/pkgs/b2.py +31 -0
  26. jolt/pkgs/boost.py +111 -0
  27. jolt/pkgs/boringssl.py +32 -0
  28. jolt/pkgs/busybox.py +39 -0
  29. jolt/pkgs/bzip2.py +43 -0
  30. jolt/pkgs/cares.py +29 -0
  31. jolt/pkgs/catch2.py +36 -0
  32. jolt/pkgs/cbindgen.py +17 -0
  33. jolt/pkgs/cista.py +19 -0
  34. jolt/pkgs/clang.py +44 -0
  35. jolt/pkgs/cli11.py +23 -0
  36. jolt/pkgs/cmake.py +48 -0
  37. jolt/pkgs/cpython.py +196 -0
  38. jolt/pkgs/crun.py +29 -0
  39. jolt/pkgs/curl.py +38 -0
  40. jolt/pkgs/dbus.py +18 -0
  41. jolt/pkgs/double_conversion.py +24 -0
  42. jolt/pkgs/fastfloat.py +21 -0
  43. jolt/pkgs/ffmpeg.py +28 -0
  44. jolt/pkgs/flatbuffers.py +29 -0
  45. jolt/pkgs/fmt.py +27 -0
  46. jolt/pkgs/fstree.py +20 -0
  47. jolt/pkgs/gflags.py +18 -0
  48. jolt/pkgs/glib.py +18 -0
  49. jolt/pkgs/glog.py +25 -0
  50. jolt/pkgs/glslang.py +21 -0
  51. jolt/pkgs/golang.py +16 -11
  52. jolt/pkgs/googlebenchmark.py +18 -0
  53. jolt/pkgs/googletest.py +46 -0
  54. jolt/pkgs/gperf.py +15 -0
  55. jolt/pkgs/grpc.py +73 -0
  56. jolt/pkgs/hdf5.py +19 -0
  57. jolt/pkgs/help2man.py +14 -0
  58. jolt/pkgs/inja.py +28 -0
  59. jolt/pkgs/jsoncpp.py +31 -0
  60. jolt/pkgs/libarchive.py +43 -0
  61. jolt/pkgs/libcap.py +44 -0
  62. jolt/pkgs/libdrm.py +44 -0
  63. jolt/pkgs/libedit.py +42 -0
  64. jolt/pkgs/libevent.py +31 -0
  65. jolt/pkgs/libexpat.py +27 -0
  66. jolt/pkgs/libfastjson.py +21 -0
  67. jolt/pkgs/libffi.py +16 -0
  68. jolt/pkgs/libglvnd.py +30 -0
  69. jolt/pkgs/libogg.py +28 -0
  70. jolt/pkgs/libpciaccess.py +18 -0
  71. jolt/pkgs/libseccomp.py +21 -0
  72. jolt/pkgs/libtirpc.py +24 -0
  73. jolt/pkgs/libtool.py +42 -0
  74. jolt/pkgs/libunwind.py +35 -0
  75. jolt/pkgs/libva.py +18 -0
  76. jolt/pkgs/libvorbis.py +33 -0
  77. jolt/pkgs/libxml2.py +35 -0
  78. jolt/pkgs/libxslt.py +17 -0
  79. jolt/pkgs/libyajl.py +16 -0
  80. jolt/pkgs/llvm.py +81 -0
  81. jolt/pkgs/lua.py +54 -0
  82. jolt/pkgs/lz4.py +26 -0
  83. jolt/pkgs/m4.py +14 -0
  84. jolt/pkgs/make.py +17 -0
  85. jolt/pkgs/mesa.py +81 -0
  86. jolt/pkgs/meson.py +17 -0
  87. jolt/pkgs/mstch.py +28 -0
  88. jolt/pkgs/mysql.py +60 -0
  89. jolt/pkgs/nasm.py +49 -0
  90. jolt/pkgs/ncurses.py +30 -0
  91. jolt/pkgs/ng_log.py +25 -0
  92. jolt/pkgs/ninja.py +45 -0
  93. jolt/pkgs/nlohmann_json.py +25 -0
  94. jolt/pkgs/nodejs.py +19 -11
  95. jolt/pkgs/opencv.py +24 -0
  96. jolt/pkgs/openjdk.py +26 -0
  97. jolt/pkgs/openssl.py +103 -0
  98. jolt/pkgs/paho.py +76 -0
  99. jolt/pkgs/patchelf.py +16 -0
  100. jolt/pkgs/perl.py +42 -0
  101. jolt/pkgs/pkgconfig.py +64 -0
  102. jolt/pkgs/poco.py +39 -0
  103. jolt/pkgs/protobuf.py +77 -0
  104. jolt/pkgs/pugixml.py +27 -0
  105. jolt/pkgs/python.py +19 -0
  106. jolt/pkgs/qt.py +35 -0
  107. jolt/pkgs/rapidjson.py +26 -0
  108. jolt/pkgs/rapidyaml.py +28 -0
  109. jolt/pkgs/re2.py +30 -0
  110. jolt/pkgs/re2c.py +17 -0
  111. jolt/pkgs/readline.py +15 -0
  112. jolt/pkgs/rust.py +41 -0
  113. jolt/pkgs/sdl.py +28 -0
  114. jolt/pkgs/simdjson.py +27 -0
  115. jolt/pkgs/soci.py +46 -0
  116. jolt/pkgs/spdlog.py +29 -0
  117. jolt/pkgs/spirv_llvm.py +21 -0
  118. jolt/pkgs/spirv_tools.py +24 -0
  119. jolt/pkgs/sqlite.py +83 -0
  120. jolt/pkgs/ssl.py +12 -0
  121. jolt/pkgs/texinfo.py +15 -0
  122. jolt/pkgs/tomlplusplus.py +22 -0
  123. jolt/pkgs/wayland.py +26 -0
  124. jolt/pkgs/x11.py +58 -0
  125. jolt/pkgs/xerces_c.py +20 -0
  126. jolt/pkgs/xorg.py +360 -0
  127. jolt/pkgs/xz.py +29 -0
  128. jolt/pkgs/yamlcpp.py +30 -0
  129. jolt/pkgs/zeromq.py +47 -0
  130. jolt/pkgs/zlib.py +69 -0
  131. jolt/pkgs/zstd.py +33 -0
  132. jolt/plugins/alias.py +3 -0
  133. jolt/plugins/allure.py +5 -2
  134. jolt/plugins/autotools.py +66 -0
  135. jolt/plugins/cache.py +133 -0
  136. jolt/plugins/cmake.py +74 -6
  137. jolt/plugins/conan.py +238 -0
  138. jolt/plugins/cxx.py +698 -0
  139. jolt/plugins/cxxinfo.py +7 -0
  140. jolt/plugins/dashboard.py +1 -1
  141. jolt/plugins/docker.py +91 -23
  142. jolt/plugins/email.py +5 -2
  143. jolt/plugins/email.xslt +144 -101
  144. jolt/plugins/environ.py +11 -0
  145. jolt/plugins/fetch.py +141 -0
  146. jolt/plugins/gdb.py +44 -21
  147. jolt/plugins/gerrit.py +1 -14
  148. jolt/plugins/git.py +316 -101
  149. jolt/plugins/googletest.py +522 -1
  150. jolt/plugins/http.py +36 -38
  151. jolt/plugins/libtool.py +63 -0
  152. jolt/plugins/linux.py +990 -0
  153. jolt/plugins/logstash.py +4 -4
  154. jolt/plugins/meson.py +61 -0
  155. jolt/plugins/ninja-compdb.py +107 -31
  156. jolt/plugins/ninja.py +929 -134
  157. jolt/plugins/paths.py +11 -1
  158. jolt/plugins/pkgconfig.py +219 -0
  159. jolt/plugins/podman.py +148 -91
  160. jolt/plugins/python.py +137 -0
  161. jolt/plugins/remote_execution/__init__.py +0 -0
  162. jolt/plugins/remote_execution/administration_pb2.py +46 -0
  163. jolt/plugins/remote_execution/administration_pb2_grpc.py +170 -0
  164. jolt/plugins/remote_execution/log_pb2.py +32 -0
  165. jolt/plugins/remote_execution/log_pb2_grpc.py +68 -0
  166. jolt/plugins/remote_execution/scheduler_pb2.py +41 -0
  167. jolt/plugins/remote_execution/scheduler_pb2_grpc.py +141 -0
  168. jolt/plugins/remote_execution/worker_pb2.py +38 -0
  169. jolt/plugins/remote_execution/worker_pb2_grpc.py +112 -0
  170. jolt/plugins/report.py +12 -2
  171. jolt/plugins/rust.py +25 -0
  172. jolt/plugins/scheduler.py +710 -0
  173. jolt/plugins/selfdeploy/setup.py +9 -4
  174. jolt/plugins/selfdeploy.py +138 -88
  175. jolt/plugins/strings.py +35 -22
  176. jolt/plugins/symlinks.py +26 -11
  177. jolt/plugins/telemetry.py +5 -2
  178. jolt/plugins/timeline.py +13 -3
  179. jolt/plugins/volume.py +46 -48
  180. jolt/scheduler.py +591 -191
  181. jolt/tasks.py +1783 -245
  182. jolt/templates/export.sh.template +12 -6
  183. jolt/templates/timeline.html.template +44 -47
  184. jolt/timer.py +22 -0
  185. jolt/tools.py +749 -302
  186. jolt/utils.py +245 -18
  187. jolt/version.py +1 -1
  188. jolt/version_utils.py +2 -2
  189. jolt/xmldom.py +12 -2
  190. {jolt-0.9.76.dist-info → jolt-0.9.429.dist-info}/METADATA +98 -38
  191. jolt-0.9.429.dist-info/RECORD +207 -0
  192. {jolt-0.9.76.dist-info → jolt-0.9.429.dist-info}/WHEEL +1 -1
  193. jolt/plugins/amqp.py +0 -834
  194. jolt/plugins/debian.py +0 -338
  195. jolt/plugins/ftp.py +0 -181
  196. jolt/plugins/ninja-cache.py +0 -64
  197. jolt/plugins/ninjacli.py +0 -271
  198. jolt/plugins/repo.py +0 -253
  199. jolt-0.9.76.dist-info/RECORD +0 -79
  200. {jolt-0.9.76.dist-info → jolt-0.9.429.dist-info}/entry_points.txt +0 -0
  201. {jolt-0.9.76.dist-info → jolt-0.9.429.dist-info}/top_level.txt +0 -0
jolt/utils.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import contextlib
2
+ import ctypes
2
3
  import fnmatch
3
4
  import re
4
5
  import time
@@ -10,6 +11,9 @@ import os
10
11
  import hashlib
11
12
  from fasteners import lock, process_lock
12
13
  import json
14
+ import platform
15
+ import signal
16
+ import threading
13
17
 
14
18
 
15
19
  read_input = input
@@ -27,9 +31,9 @@ locked = lock.locked
27
31
 
28
32
  def is_str(s):
29
33
  try:
30
- return type(s) == str or type(s) == unicode
34
+ return type(s) is str or type(s) is unicode
31
35
  except NameError:
32
- return type(s) == str
36
+ return type(s) is str
33
37
 
34
38
 
35
39
  def decode_str(s):
@@ -55,7 +59,9 @@ def decorate_prepend(func, extra_func):
55
59
 
56
60
 
57
61
  def as_list(t):
58
- return [t] if type(t) == str or not is_iterable(t) else list(t)
62
+ if t is None:
63
+ return []
64
+ return [t] if type(t) is str or not is_iterable(t) else list(t)
59
65
 
60
66
 
61
67
  def is_iterable(x):
@@ -68,9 +74,9 @@ def is_iterable(x):
68
74
 
69
75
 
70
76
  def as_stable_string_list(o):
71
- if type(o) == list or type(o) == tuple:
77
+ if type(o) is list or type(o) is tuple:
72
78
  return sorted([str(item) for item in o])
73
- elif type(o) == dict:
79
+ elif type(o) is dict:
74
80
  return sorted(["{0}={1}".format(key, as_stable_string_list(val))
75
81
  for key, val in o.items()])
76
82
  else:
@@ -78,13 +84,13 @@ def as_stable_string_list(o):
78
84
 
79
85
 
80
86
  def as_stable_tuple_list(o):
81
- assert type(o) == dict, "as_stable_tuple_list: argument is not a dict"
87
+ assert type(o) is dict, "as_stable_tuple_list: argument is not a dict"
82
88
  list = [(key, value) for key, value in o.items()]
83
89
  return sorted(list, key=lambda x: x[0])
84
90
 
85
91
 
86
92
  def as_human_size(size):
87
- unit_precision = [("B", 0), ("KB", 0), ("MB", 1), ("GB", 2), ("TB", 2), ("PB", 2)]
93
+ unit_precision = [("B", 0), ("KiB", 0), ("MiB", 1), ("GiB", 2), ("TiB", 2), ("PiB", 2), ("EiB", 2)]
88
94
  index = 0
89
95
  while size > 1024:
90
96
  size /= 1024
@@ -125,12 +131,13 @@ def call_and_catch_and_log(f, *args, **kwargs):
125
131
 
126
132
 
127
133
  def parse_aliased_task_name(name):
128
- match = re.match(r"^((?P<alias>[^=:]+)=)?(?P<task>[^:]+)(:(?P<params>.*))?$", name)
134
+ match = re.match(r"^((?P<alias>[^=:]+)=)?((?P<artifact>[^@=:]+)@)?(?P<task>[^:]+)(:(?P<params>.*))?$", name)
129
135
  if not match:
130
136
  from jolt.error import raise_error
131
137
  raise_error("Illegal task name: {}", name)
132
138
  match = match.groupdict()
133
139
  alias = match["alias"]
140
+ artifact = match["artifact"]
134
141
  task = match["task"]
135
142
  params = match["params"] or {}
136
143
 
@@ -146,15 +153,17 @@ def parse_aliased_task_name(name):
146
153
 
147
154
  params = {key: value for key, value in map(_param, params) if key}
148
155
 
149
- return alias, task, params
156
+ return alias, artifact, task, params
150
157
 
151
158
 
152
159
  def parse_task_name(name):
153
- _, task, params = parse_aliased_task_name(name)
160
+ _, _, task, params = parse_aliased_task_name(name)
154
161
  return task, params
155
162
 
156
163
 
157
- def format_task_name(name, params):
164
+ def format_task_name(name, params, artifact=None):
165
+ if artifact:
166
+ name = f"{artifact}@{name}"
158
167
  if not params:
159
168
  return name
160
169
 
@@ -210,8 +219,14 @@ class _SafeDict(object):
210
219
  value = self.values.get(key)
211
220
  if value is None:
212
221
  value = call_and_catch(getattr, self.values.get("_instance", object()), key)
222
+ if value is None and key == "buildroot":
223
+ tools = getattr(self.values.get("_instance", object()), "tools", None)
224
+ if tools:
225
+ value = tools.buildroot
213
226
  if value is None:
214
227
  value = self._envget(key)
228
+ if type(value) is list:
229
+ value = " ".join(value)
215
230
  if value is not None:
216
231
  return value
217
232
  if self.errors:
@@ -227,6 +242,10 @@ class JoltFormatter(Formatter):
227
242
  return str(value).lower()
228
243
  elif conversion == "c":
229
244
  return value()
245
+ elif conversion == "t":
246
+ return str(value).title()
247
+ elif conversion == "j":
248
+ return " ".join(value)
230
249
  return super().convert_field(value, conversion)
231
250
 
232
251
 
@@ -293,7 +312,7 @@ class duration_diff(object):
293
312
  if isinstance(dur, duration):
294
313
  now = duration()
295
314
  self._elapsed += dur.diff(now)._elapsed
296
- if type(dur) == int:
315
+ if type(dur) is int:
297
316
  self._elapsed += dur
298
317
  return self
299
318
 
@@ -307,19 +326,24 @@ class cached:
307
326
 
308
327
  @staticmethod
309
328
  def instance(f):
329
+ f.__cached_mutex = RLock()
330
+
310
331
  def _f(self, *args, **kwargs):
311
332
  attr = "__cached_result_" + str(id(f))
312
- with cached.mutex:
333
+ with f.__cached_mutex:
313
334
  if not hasattr(self, attr):
314
335
  setattr(self, attr, f(self, *args, **kwargs))
315
336
  return getattr(self, attr)
337
+
316
338
  return _f
317
339
 
318
340
  @staticmethod
319
341
  def method(f):
342
+ f.__cached_mutex = RLock()
343
+
320
344
  def _f(*args, **kwargs):
321
345
  attr = "__cached_result_" + str(id(f))
322
- with cached.mutex:
346
+ with f.__cached_mutex:
323
347
  if not hasattr(f, attr):
324
348
  setattr(f, attr, f(*args, **kwargs))
325
349
  return getattr(f, attr)
@@ -351,6 +375,73 @@ def ignore_exception(exc=Exception):
351
375
  return contextlib.suppress(exc)
352
376
 
353
377
 
378
+ class SignalHandler(object):
379
+ def __init__(self, signum):
380
+ self.original_handler = signal.signal(signum, self._handler)
381
+ self.handlers = []
382
+
383
+ def _handler(self, signum, frame):
384
+ for handler in self.handlers:
385
+ handler.add_signal(signum, frame)
386
+ if not self.handlers and self.original_handler:
387
+ self.original_handler(signum, frame)
388
+
389
+ def new_monitor(self):
390
+ class Finalizer(object):
391
+ def __init__(self, handler):
392
+ self.handler = handler
393
+ self.signals = []
394
+
395
+ def add_signal(self, signum, frame):
396
+ self.signals.append((signum, frame))
397
+
398
+ def __call__(self):
399
+ self.handler.handlers.remove(self)
400
+ for signum, frame in self.signals:
401
+ self.handler.original_handler(signum, frame)
402
+
403
+ finalizer = Finalizer(self)
404
+ self.handlers.append(finalizer)
405
+ return finalizer
406
+
407
+
408
+ sigint_handler = SignalHandler(signal.SIGINT)
409
+
410
+
411
+ @contextlib.contextmanager
412
+ def delayed_signal(signum):
413
+ """ A context manager that delays signals until after the code block. """
414
+
415
+ finalize = sigint_handler.new_monitor()
416
+ try:
417
+ yield
418
+ finally:
419
+ finalize()
420
+
421
+
422
+ @contextlib.contextmanager
423
+ def delayed_interrupt():
424
+ if hasattr(signal, 'pthread_sigmask'):
425
+ try:
426
+ # Temporarily block the SIGINT signal
427
+ signal.pthread_sigmask(signal.SIG_BLOCK, {signal.SIGINT})
428
+ yield
429
+ finally:
430
+ # Unblock the SIGINT signal after the code block
431
+ signal.pthread_sigmask(signal.SIG_UNBLOCK, {signal.SIGINT})
432
+ else:
433
+ # Fallback for systems without pthread_sigmask
434
+ yield
435
+
436
+
437
+ def delay_interrupt(func):
438
+ @wraps(func)
439
+ def _f(*args, **kwargs):
440
+ with delayed_interrupt():
441
+ return func(*args, **kwargs)
442
+ return _f
443
+
444
+
354
445
  def Singleton(cls):
355
446
  cls._instance = None
356
447
 
@@ -364,6 +455,28 @@ def Singleton(cls):
364
455
  return cls
365
456
 
366
457
 
458
+ class IdLock(object):
459
+ """ A wrapper for multiple thread locks that are identified by a unique id. """
460
+
461
+ def __init__(self):
462
+ self._lock = RLock()
463
+ self._locks = {}
464
+
465
+ def acquire(self, id, blocking=True):
466
+ with self._lock:
467
+ if id not in self._locks:
468
+ self._locks[id] = RLock()
469
+ lock = self._locks[id]
470
+ return lock.acquire(blocking=blocking)
471
+
472
+ def release(self, id):
473
+ with self._lock:
474
+ if id in self._locks:
475
+ self._locks[id].release()
476
+ else:
477
+ raise RuntimeError("Lock not acquired: {}".format(id))
478
+
479
+
367
480
  class LockFile(object):
368
481
  def __init__(self, path, logfunc=None, *args, **kwargs):
369
482
  self._file = process_lock.InterProcessLock(os.path.join(path, "lock"))
@@ -438,14 +551,31 @@ def tojson(filepath, data, ignore_errors=False, indent=2):
438
551
 
439
552
  def concat_attributes(attrib, postfix, prepend=False):
440
553
  def _decorate(cls):
441
- _orig = getattr(cls, "_" + attrib, lambda self: [])
554
+ _orig = getattr(cls, "_" + attrib, lambda self: getattr(self, attrib, None))
442
555
 
443
556
  def _get(self):
444
557
  orig = _orig(self)
445
- if prepend:
446
- return getattr(self, self.expand(postfix), type(orig)()) + orig
558
+ if attrib != postfix:
559
+ appended = getattr(self, self.expand(postfix), type(orig)() if orig is not None else [])
447
560
  else:
448
- return orig + getattr(self, self.expand(postfix), type(orig)())
561
+ appended = type(orig)() if orig is not None else []
562
+
563
+ if orig is None:
564
+ orig = type(appended)()
565
+
566
+ assert type(orig) is type(appended), \
567
+ f"Cannot append attributes '{attrib}' and '{postfix}': mismatching type"
568
+
569
+ assert type(orig) is list or type(orig) is dict, \
570
+ f"Cannot append attributes '{attrib}' and '{postfix}': unsupported type '{type(orig)}'"
571
+
572
+ if type(orig) is dict:
573
+ value = orig | appended
574
+
575
+ if type(appended) is list:
576
+ value = orig + appended if not prepend else appended + orig
577
+
578
+ return value
449
579
 
450
580
  setattr(cls, "_" + attrib, _get)
451
581
  return cls
@@ -484,3 +614,100 @@ def quote(value, char='"'):
484
614
 
485
615
  def option(prefix, value):
486
616
  return "{}{}".format(prefix, quote(value)) if value else ""
617
+
618
+
619
+ def shorten(string, count=30):
620
+ if len(string) > count:
621
+ keep = int(count / 2 - 1)
622
+ if keep <= 0:
623
+ keep = 1
624
+ return string[:keep] + "..." + string[-keep + 1:]
625
+ return string
626
+
627
+
628
+ def prefix(value, pfx):
629
+ if type(value) is list:
630
+ return [pfx + item for item in value]
631
+ return pfx + value
632
+
633
+
634
+ def suffix(value, sfx):
635
+ if type(value) is list:
636
+ return [item + sfx for item in value]
637
+ return value + sfx
638
+
639
+
640
+ def hostname():
641
+ """ Returns the hostname of the machine. """
642
+ import socket
643
+ return socket.gethostname()
644
+
645
+
646
+ def timeout(seconds, exception_type):
647
+ """ A context manager that enforces a timeout.
648
+
649
+ If the block of code takes longer than the specified timeout,
650
+ the context manager will raise an asyncronous TimeoutError.
651
+ """
652
+
653
+ class TimeoutContext(object):
654
+ def __init__(self, timeout, exception_type):
655
+ self._timer = threading.Timer(timeout, self._raise_timeout)
656
+ self._tid = threading.current_thread().ident
657
+ self._exc = exception_type
658
+
659
+ def _raise_timeout(self):
660
+ tid = ctypes.c_ulong(self._tid)
661
+ ret = ctypes.pythonapi.PyThreadState_SetAsyncExc(
662
+ tid, ctypes.py_object(self._exc))
663
+
664
+ if ret == 0:
665
+ raise ValueError("Invalid thread ID {self._tid}")
666
+ elif ret > 1:
667
+ ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
668
+ raise SystemError("PyThreadState_SetAsyncExc failed")
669
+
670
+ def __enter__(self):
671
+ self._timer.start()
672
+ return self
673
+
674
+ def __exit__(self, exc_type, exc_value, traceback):
675
+ self._timer.cancel()
676
+ return None
677
+
678
+ return TimeoutContext(seconds, exception_type)
679
+
680
+
681
+ def platform_os_arch():
682
+ """
683
+ Returns the name of the operating system and architecture.
684
+
685
+ The values match the GOOS and GOARCH environment variables used by Go.
686
+ """
687
+ _ARCHITECTURE_DICT = {
688
+ "Windows": {
689
+ "AMD64": "amd64",
690
+ "X86": "386",
691
+ "ARM64": "arm64",
692
+ },
693
+ "Linux": {
694
+ "x86_64": "amd64",
695
+ "i686": "386",
696
+ "i386": "386",
697
+ "aarch64": "arm64",
698
+ "armv7l": "armv7",
699
+ },
700
+ "Darwin": {
701
+ "x86_64": "amd64",
702
+ "arm64": "arm64",
703
+ },
704
+ }
705
+ uname = platform.uname()
706
+ try:
707
+ system = uname.system.lower()
708
+ architecture = _ARCHITECTURE_DICT[uname.system][uname.machine]
709
+ except KeyError:
710
+ raise RuntimeError(
711
+ f"Unsupported platform: {uname.system} {uname.machine}"
712
+ ) from None
713
+ return system, architecture
jolt/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.9.76"
1
+ __version__ = "0.9.429"
jolt/version_utils.py CHANGED
@@ -4,7 +4,7 @@ import re
4
4
 
5
5
  class version(object):
6
6
  def __init__(self, verstr):
7
- if type(verstr) == str:
7
+ if type(verstr) is str:
8
8
  match = re.search(r"(?P<major>[\d]+)\.(?P<minor>[\d]+)(\.(?P<patch>[\d]+))?", verstr)
9
9
  if not match:
10
10
  raise ValueError(verstr)
@@ -12,7 +12,7 @@ class version(object):
12
12
  self.major = int(values["major"])
13
13
  self.minor = int(values["minor"])
14
14
  self.patch = int(values["patch"]) if values["patch"] else None
15
- elif type(verstr) == tuple:
15
+ elif type(verstr) is tuple:
16
16
  if len(verstr) < 2 or len(verstr) > 3:
17
17
  raise ValueError(verstr)
18
18
  self.major = verstr[0]
jolt/xmldom.py CHANGED
@@ -49,6 +49,9 @@ class SubElement(object):
49
49
  def iter(self, *args, **kwargs):
50
50
  return self._elem.iter(*args, **kwargs)
51
51
 
52
+ def remove(self, *args, **kwargs):
53
+ return self._elem.remove(*args, **kwargs)
54
+
52
55
 
53
56
  class Attribute(object):
54
57
  def __init__(self, attribute, varname=None, child=False, values=None, base64=False, zlib=False):
@@ -147,8 +150,8 @@ class Composition(object):
147
150
  self.append(child)
148
151
  return child
149
152
 
150
- def remove(self, child, *args, **kwargs):
151
- self.remove(child._elem)
153
+ def remove(self, *args, **kwargs):
154
+ self.remove(*args, **kwargs)
152
155
 
153
156
  @property
154
157
  def get(self):
@@ -156,6 +159,13 @@ class Composition(object):
156
159
  children = [n for n in children if n.tag == name]
157
160
  return [comp_cls(elem=child) for child in children]
158
161
 
162
+ def clear(self):
163
+ children = list(self.getroot()) if isinstance(self, ElementTree) else list(self._elem)
164
+ children = [n for n in children if n.tag == name]
165
+ for child in children:
166
+ getattr(self, "remove_" + name)(child)
167
+
168
+ setattr(cls, 'clear_' + name + "s", clear)
159
169
  setattr(cls, 'create_' + name, create)
160
170
  setattr(cls, 'remove_' + name, remove)
161
171
  setattr(cls, name + 's', get)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: jolt
3
- Version: 0.9.76
3
+ Version: 0.9.429
4
4
  Summary: A task executor
5
5
  Home-page: https://github.com/srand/jolt
6
6
  Author: Robert Andersson
@@ -20,47 +20,107 @@ Classifier: Programming Language :: C++
20
20
  Classifier: Programming Language :: Java
21
21
  Classifier: Programming Language :: JavaScript
22
22
  Classifier: Programming Language :: Python :: 3
23
- Requires-Dist: tqdm (==4.64.1)
24
- Requires-Dist: requests (==2.28.1)
25
- Requires-Dist: idna (==3.4)
26
- Requires-Dist: urllib3 (==1.26.13)
27
- Requires-Dist: certifi (==2022.9.24)
28
- Requires-Dist: charset-normalizer (==2.1.1)
29
- Requires-Dist: pygit2 (==1.11.1)
30
- Requires-Dist: cffi (==1.15.1)
31
- Requires-Dist: pycparser (==2.21)
32
- Requires-Dist: psutil (==5.9.4)
33
- Requires-Dist: ninja-syntax (==1.7.2)
34
- Requires-Dist: multi-key-dict (==2.0.3)
35
- Requires-Dist: lxml (==4.9.1)
36
- Requires-Dist: keyrings.alt (==4.2.0)
37
- Requires-Dist: jaraco.classes (==3.2.3)
38
- Requires-Dist: more-itertools (==9.0.0)
39
- Requires-Dist: keyring (==23.11.0)
40
- Requires-Dist: importlib-metadata (==5.1.0)
41
- Requires-Dist: zipp (==3.11.0)
42
- Requires-Dist: jeepney (==0.8.0)
43
- Requires-Dist: SecretStorage (==3.3.3)
44
- Requires-Dist: cryptography (==38.0.4)
45
- Requires-Dist: Jinja2 (==3.1.2)
46
- Requires-Dist: MarkupSafe (==2.1.1)
47
- Requires-Dist: fasteners (==0.18)
48
- Requires-Dist: colorama (==0.4.6)
49
- Requires-Dist: click (==8.1.3)
50
- Requires-Dist: bz2file (==0.98)
23
+ Requires-Python: >=3.8
24
+ Requires-Dist: Jinja2==3.1.4
25
+ Requires-Dist: Jinja2==3.1.4
26
+ Requires-Dist: MarkupSafe==2.1.5
27
+ Requires-Dist: PyJWT==2.9.0
28
+ Requires-Dist: PyYAML==6.0.2
29
+ Requires-Dist: PyYAML==6.0.2
30
+ Requires-Dist: Pygments==2.18.0
31
+ Requires-Dist: Pygments==2.18.0
32
+ Requires-Dist: SecretStorage==3.3.3
33
+ Requires-Dist: allure-python-commons==2.13.5
34
+ Requires-Dist: attrs==24.2.0
35
+ Requires-Dist: backports.tarfile==1.2.0
36
+ Requires-Dist: bottle==0.12.25
37
+ Requires-Dist: brotli==1.2.0
38
+ Requires-Dist: bz2file==0.98
39
+ Requires-Dist: certifi==2024.8.30
40
+ Requires-Dist: cffi==1.17.1
41
+ Requires-Dist: charset-normalizer==3.3.2
42
+ Requires-Dist: click==8.1.7
43
+ Requires-Dist: colorama==0.4.6
44
+ Requires-Dist: conan==2.10.2
45
+ Requires-Dist: cryptography==43.0.1
46
+ Requires-Dist: distro==1.8.0
47
+ Requires-Dist: docutils==0.21.2
48
+ Requires-Dist: fasteners==0.19
49
+ Requires-Dist: flake8==7.1.1
50
+ Requires-Dist: grpcio==1.66.1
51
+ Requires-Dist: idna==3.10
52
+ Requires-Dist: importlib_metadata==8.5.0
53
+ Requires-Dist: importlib_metadata==8.5.0
54
+ Requires-Dist: inflate64==1.0.4
55
+ Requires-Dist: jaraco.classes==3.4.0
56
+ Requires-Dist: jaraco.context==6.0.1
57
+ Requires-Dist: jaraco.functools==4.0.2
58
+ Requires-Dist: jeepney==0.8.0
59
+ Requires-Dist: keyring==25.4.1
60
+ Requires-Dist: keyrings.alt==5.0.2
61
+ Requires-Dist: lxml==5.3.0
62
+ Requires-Dist: markdown-it-py==3.0.0
63
+ Requires-Dist: mccabe==0.7.0
64
+ Requires-Dist: more-itertools==10.5.0
65
+ Requires-Dist: more-itertools==10.5.0
66
+ Requires-Dist: multi_key_dict==2.0.3
67
+ Requires-Dist: multivolumefile==0.2.3
68
+ Requires-Dist: nh3==0.2.19
69
+ Requires-Dist: ninja==1.11.1.1
70
+ Requires-Dist: packaging==24.2
71
+ Requires-Dist: patch-ng==1.18.1
72
+ Requires-Dist: pip==25.3
73
+ Requires-Dist: pkginfo==1.12.0
74
+ Requires-Dist: pluggy==1.5.0
75
+ Requires-Dist: pluginbase==1.0.1
76
+ Requires-Dist: protobuf==5.28.2
77
+ Requires-Dist: psutil==6.0.0
78
+ Requires-Dist: py7zr==1.0.0
79
+ Requires-Dist: pybcj==1.0.6
80
+ Requires-Dist: pycodestyle==2.12.1
81
+ Requires-Dist: pycparser==2.22
82
+ Requires-Dist: pycryptodomex==3.23.0
83
+ Requires-Dist: pyflakes==3.2.0
84
+ Requires-Dist: pygit2==1.15.1
85
+ Requires-Dist: pyppmd==1.2.0
86
+ Requires-Dist: python-dateutil==2.9.0.post0
87
+ Requires-Dist: pyzstd==0.18.0
88
+ Requires-Dist: readme_renderer==44.0
89
+ Requires-Dist: requests-toolbelt==1.0.0
90
+ Requires-Dist: requests==2.32.3
91
+ Requires-Dist: rfc3986==2.0.0
92
+ Requires-Dist: rich==13.9.4
93
+ Requires-Dist: setuptools==80.9.0
94
+ Requires-Dist: six==1.16.0
95
+ Requires-Dist: texttable==1.7.0
96
+ Requires-Dist: tqdm==4.66.5
97
+ Requires-Dist: twine==6.0.1
98
+ Requires-Dist: typing_extensions==4.15.0
99
+ Requires-Dist: urllib3==1.26.20
100
+ Requires-Dist: wheel==0.45.1
101
+ Requires-Dist: zipp==3.20.2
102
+ Requires-Dist: zstandard==0.23.0
51
103
  Provides-Extra: allure
52
- Requires-Dist: allure-python-commons ; extra == 'allure'
53
- Provides-Extra: amqp
54
- Requires-Dist: pika ; extra == 'amqp'
104
+ Requires-Dist: allure-python-commons; extra == "allure"
55
105
  Provides-Extra: conan
56
- Requires-Dist: conan ; extra == 'conan'
106
+ Requires-Dist: conan>=2.0; extra == "conan"
57
107
  Provides-Extra: dev
58
- Requires-Dist: check-manifest ; extra == 'dev'
108
+ Requires-Dist: check-manifest; extra == "dev"
59
109
  Provides-Extra: doc
60
- Requires-Dist: sphinx-click ; extra == 'doc'
61
- Requires-Dist: sphinx-rtd-theme ; extra == 'doc'
110
+ Requires-Dist: sphinx-click; extra == "doc"
111
+ Requires-Dist: sphinx-rtd-theme; extra == "doc"
62
112
  Provides-Extra: test
63
- Requires-Dist: coverage ; extra == 'test'
113
+ Requires-Dist: coverage; extra == "test"
114
+ Dynamic: author
115
+ Dynamic: author-email
116
+ Dynamic: classifier
117
+ Dynamic: description
118
+ Dynamic: home-page
119
+ Dynamic: keywords
120
+ Dynamic: provides-extra
121
+ Dynamic: requires-dist
122
+ Dynamic: requires-python
123
+ Dynamic: summary
64
124
 
65
125
  Jolt
66
126
  ============================