comparison env/lib/python3.9/site-packages/allure_commons/utils.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 # -*- coding: utf-8 -*-
2
3 import os
4 import sys
5 import six
6 import time
7 import uuid
8 import json
9 import socket
10 import inspect
11 import hashlib
12 import platform
13 import threading
14 import traceback
15 import collections
16
17 from functools import partial
18
19
20 def getargspec(func):
21 """
22 Used because getargspec for python 2.7 does not accept functools.partial
23 which is the type for pytest fixtures.
24
25 getargspec excerpted from:
26
27 sphinx.util.inspect
28 ~~~~~~~~~~~~~~~~~~~
29 Helpers for inspecting Python modules.
30 :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
31 :license: BSD, see LICENSE for details.
32
33 Like inspect.getargspec but supports functools.partial as well.
34 """
35 # noqa: E731 type: (Any) -> Any
36 if inspect.ismethod(func):
37 func = func.__func__
38 parts = 0, () # noqa: E731 type: Tuple[int, Tuple[unicode, ...]]
39 if type(func) is partial:
40 keywords = func.keywords
41 if keywords is None:
42 keywords = {}
43 parts = len(func.args), keywords.keys()
44 func = func.func
45 if not inspect.isfunction(func):
46 raise TypeError('%r is not a Python function' % func)
47 args, varargs, varkw = inspect.getargs(func.__code__)
48 func_defaults = func.__defaults__
49 if func_defaults is None:
50 func_defaults = []
51 else:
52 func_defaults = list(func_defaults)
53 if parts[0]:
54 args = args[parts[0]:]
55 if parts[1]:
56 for arg in parts[1]:
57 i = args.index(arg) - len(args) # type: ignore
58 del args[i]
59 try:
60 del func_defaults[i]
61 except IndexError:
62 pass
63 return inspect.ArgSpec(args, varargs, varkw, func_defaults) # type: ignore
64
65
66 if six.PY3:
67 from traceback import format_exception_only
68 else:
69 from _compat import format_exception_only
70
71
72 def md5(*args):
73 m = hashlib.md5()
74 for arg in args:
75 part = arg.encode('utf-8')
76 m.update(part)
77 return m.hexdigest()
78
79
80 def uuid4():
81 return str(uuid.uuid4())
82
83
84 def now():
85 return int(round(1000 * time.time()))
86
87
88 def platform_label():
89 major_version, _, __ = platform.python_version_tuple()
90 implementation = platform.python_implementation()
91 return '{implementation}{major_version}'.format(implementation=implementation.lower(),
92 major_version=major_version)
93
94
95 def thread_tag():
96 return '{0}-{1}'.format(os.getpid(), threading.current_thread().name)
97
98
99 def host_tag():
100 return socket.gethostname()
101
102
103 def escape_non_unicode_symbols(item):
104 if not (six.PY2 and isinstance(item, str)):
105 return item
106
107 def escape_symbol(s):
108 try:
109 s.decode(encoding='UTF-8')
110 return s
111 except UnicodeDecodeError:
112 return repr(s)[1:-1]
113
114 return ''.join(map(escape_symbol, item))
115
116
117 def represent(item):
118 """
119 >>> represent(None)
120 'None'
121
122 >>> represent(123)
123 '123'
124
125 >>> import six
126 >>> expected = u"'hi'" if six.PY2 else "'hi'"
127 >>> represent('hi') == expected
128 True
129
130 >>> expected = u"'привет'" if six.PY2 else "'привет'"
131 >>> represent(u'привет') == expected
132 True
133
134 >>> represent(bytearray([0xd0, 0xbf])) # doctest: +ELLIPSIS
135 "<... 'bytearray'>"
136
137 >>> from struct import pack
138 >>> result = "<type 'str'>" if six.PY2 else "<class 'bytes'>"
139 >>> represent(pack('h', 0x89)) == result
140 True
141
142 >>> result = "<type 'int'>" if six.PY2 else "<class 'int'>"
143 >>> represent(int) == result
144 True
145
146 >>> represent(represent) # doctest: +ELLIPSIS
147 '<function represent at ...>'
148
149 >>> represent([represent]) # doctest: +ELLIPSIS
150 '[<function represent at ...>]'
151
152 >>> class ClassWithName(object):
153 ... pass
154
155 >>> represent(ClassWithName)
156 "<class 'utils.ClassWithName'>"
157 """
158
159 if six.PY2 and isinstance(item, str):
160 try:
161 item = item.decode(encoding='UTF-8')
162 except UnicodeDecodeError:
163 pass
164
165 if isinstance(item, six.text_type):
166 return u'\'%s\'' % item
167 elif isinstance(item, (bytes, bytearray)):
168 return repr(type(item))
169 else:
170 return repr(item)
171
172
173 def func_parameters(func, *args, **kwargs):
174 """
175 >>> def helper(func):
176 ... def wrapper(*args, **kwargs):
177 ... params = func_parameters(func, *args, **kwargs)
178 ... print(list(params.items()))
179 ... return func(*args, **kwargs)
180 ... return wrapper
181
182 >>> @helper
183 ... def args(a, b):
184 ... pass
185
186 >>> args(1, 2)
187 [('a', '1'), ('b', '2')]
188
189 >>> args(*(1,2))
190 [('a', '1'), ('b', '2')]
191
192 >>> args(1, b=2)
193 [('a', '1'), ('b', '2')]
194
195 >>> @helper
196 ... def kwargs(a=1, b=2):
197 ... pass
198
199 >>> kwargs()
200 [('a', '1'), ('b', '2')]
201
202 >>> kwargs(a=3, b=4)
203 [('a', '3'), ('b', '4')]
204
205 >>> kwargs(b=4, a=3)
206 [('a', '3'), ('b', '4')]
207
208 >>> kwargs(a=3)
209 [('a', '3'), ('b', '2')]
210
211 >>> kwargs(b=4)
212 [('a', '1'), ('b', '4')]
213
214 >>> @helper
215 ... def args_kwargs(a, b, c=3, d=4):
216 ... pass
217
218 >>> args_kwargs(1, 2)
219 [('a', '1'), ('b', '2'), ('c', '3'), ('d', '4')]
220
221 >>> args_kwargs(1, 2, d=5)
222 [('a', '1'), ('b', '2'), ('c', '3'), ('d', '5')]
223
224 >>> args_kwargs(1, 2, 5, 6)
225 [('a', '1'), ('b', '2'), ('c', '5'), ('d', '6')]
226
227 >>> @helper
228 ... def varargs(*a):
229 ... pass
230
231 >>> varargs()
232 []
233
234 >>> varargs(1, 2)
235 [('a', '(1, 2)')]
236
237 >>> @helper
238 ... def keywords(**a):
239 ... pass
240
241 >>> keywords()
242 []
243
244 >>> keywords(a=1, b=2)
245 [('a', '1'), ('b', '2')]
246
247 >>> @helper
248 ... def args_varargs(a, b, *c):
249 ... pass
250
251 >>> args_varargs(1, 2)
252 [('a', '1'), ('b', '2')]
253
254 >>> args_varargs(1, 2, 2)
255 [('a', '1'), ('b', '2'), ('c', '(2,)')]
256
257 >>> @helper
258 ... def args_kwargs_varargs(a, b, c=3, **d):
259 ... pass
260
261 >>> args_kwargs_varargs(1, 2)
262 [('a', '1'), ('b', '2'), ('c', '3')]
263
264 >>> args_kwargs_varargs(1, 2, 4, d=5, e=6)
265 [('a', '1'), ('b', '2'), ('c', '4'), ('d', '5'), ('e', '6')]
266
267 >>> @helper
268 ... def args_kwargs_varargs_keywords(a, b=2, *c, **d):
269 ... pass
270
271 >>> args_kwargs_varargs_keywords(1)
272 [('a', '1'), ('b', '2')]
273
274 >>> args_kwargs_varargs_keywords(1, 2, 4, d=5, e=6)
275 [('a', '1'), ('b', '2'), ('c', '(4,)'), ('d', '5'), ('e', '6')]
276
277 >>> class Class(object):
278 ... @staticmethod
279 ... @helper
280 ... def static_args(a, b):
281 ... pass
282 ...
283 ... @classmethod
284 ... @helper
285 ... def method_args(cls, a, b):
286 ... pass
287 ...
288 ... @helper
289 ... def args(self, a, b):
290 ... pass
291
292 >>> cls = Class()
293
294 >>> cls.args(1, 2)
295 [('a', '1'), ('b', '2')]
296
297 >>> cls.method_args(1, 2)
298 [('a', '1'), ('b', '2')]
299
300 >>> cls.static_args(1, 2)
301 [('a', '1'), ('b', '2')]
302
303 """
304 parameters = {}
305 arg_spec = getargspec(func) if six.PY2 else inspect.getfullargspec(func)
306 arg_order = list(arg_spec.args)
307 args_dict = dict(zip(arg_spec.args, args))
308
309 if arg_spec.defaults:
310 kwargs_defaults_dict = dict(zip(arg_spec.args[len(args):], arg_spec.defaults))
311 parameters.update(kwargs_defaults_dict)
312
313 if arg_spec.varargs:
314 arg_order.append(arg_spec.varargs)
315 varargs = args[len(arg_spec.args):]
316 parameters.update({arg_spec.varargs: varargs} if varargs else {})
317
318 if arg_spec.args and arg_spec.args[0] in ['cls', 'self']:
319 args_dict.pop(arg_spec.args[0], None)
320
321 if kwargs:
322 if sys.version_info < (3, 6):
323 # Sort alphabetically as old python versions does
324 # not preserve call order for kwargs
325 arg_order.extend(sorted(list(kwargs.keys())))
326 else:
327 # Keep py3.6 behaviour to preserve kwargs order
328 arg_order.extend(list(kwargs.keys()))
329 parameters.update(kwargs)
330
331 parameters.update(args_dict)
332
333 items = parameters.iteritems() if six.PY2 else parameters.items()
334 sorted_items = sorted(map(lambda kv: (kv[0], represent(kv[1])), items), key=lambda x: arg_order.index(x[0]))
335
336 return collections.OrderedDict(sorted_items)
337
338
339 def format_traceback(exc_traceback):
340 return ''.join(traceback.format_tb(exc_traceback)) if exc_traceback else None
341
342
343 def format_exception(etype, value):
344 """
345 >>> import sys
346
347 >>> try:
348 ... assert False, u'Привет'
349 ... except AssertionError:
350 ... etype, e, _ = sys.exc_info()
351 ... format_exception(etype, e) # doctest: +ELLIPSIS
352 'AssertionError: ...\\n'
353
354 >>> try:
355 ... assert False, 'Привет'
356 ... except AssertionError:
357 ... etype, e, _ = sys.exc_info()
358 ... format_exception(etype, e) # doctest: +ELLIPSIS
359 'AssertionError: ...\\n'
360
361 >>> try:
362 ... compile("bla u'Привет'", "fake.py", "exec")
363 ... except SyntaxError:
364 ... etype, e, _ = sys.exc_info()
365 ... format_exception(etype, e) # doctest: +ELLIPSIS
366 ' File "fake.py", line 1...SyntaxError: invalid syntax\\n'
367
368 >>> try:
369 ... compile("bla 'Привет'", "fake.py", "exec")
370 ... except SyntaxError:
371 ... etype, e, _ = sys.exc_info()
372 ... format_exception(etype, e) # doctest: +ELLIPSIS
373 ' File "fake.py", line 1...SyntaxError: invalid syntax\\n'
374
375 >>> from hamcrest import assert_that, equal_to
376
377 >>> try:
378 ... assert_that('left', equal_to('right'))
379 ... except AssertionError:
380 ... etype, e, _ = sys.exc_info()
381 ... format_exception(etype, e) # doctest: +ELLIPSIS
382 "AssertionError: \\nExpected:...but:..."
383
384 >>> try:
385 ... assert_that(u'left', equal_to(u'right'))
386 ... except AssertionError:
387 ... etype, e, _ = sys.exc_info()
388 ... format_exception(etype, e) # doctest: +ELLIPSIS
389 "AssertionError: \\nExpected:...but:..."
390 """
391 return '\n'.join(format_exception_only(etype, value)) if etype or value else None
392
393
394 def get_testplan():
395 planned_tests = []
396 file_path = os.environ.get("ALLURE_TESTPLAN_PATH")
397
398 if file_path and os.path.exists(file_path):
399 with open(file_path, 'r') as plan_file:
400 plan = json.load(plan_file)
401 planned_tests = plan.get("tests", [])
402
403 return planned_tests