Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/vine/five.py : 3%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2"""Python 2/3 compatibility.
4Compatibility implementations of features
5only available in newer Python versions.
6"""
7from __future__ import absolute_import, unicode_literals
9import errno
10import io
11import sys
13try:
14 from collections import Counter
15except ImportError: # pragma: no cover
16 from collections import defaultdict
18 def Counter(): # noqa
19 """Create counter."""
20 return defaultdict(int)
22try:
23 buffer_t = buffer
24except NameError: # pragma: no cover
25 # Py3 does not have buffer, only use this for isa checks.
27 class buffer_t(object): # noqa
28 """Python 3 does not have a buffer type."""
30bytes_t = bytes
32__all__ = [
33 'Counter', 'reload', 'UserList', 'UserDict',
34 'Callable', 'Iterable', 'Mapping',
35 'Queue', 'Empty', 'Full', 'LifoQueue', 'builtins', 'array',
36 'zip_longest', 'map', 'zip', 'string', 'string_t', 'bytes_t',
37 'bytes_if_py2', 'long_t', 'text_t', 'int_types', 'module_name_t',
38 'range', 'items', 'keys', 'values', 'nextfun', 'reraise',
39 'WhateverIO', 'with_metaclass', 'StringIO', 'getfullargspec',
40 'THREAD_TIMEOUT_MAX', 'format_d', 'monotonic', 'buffer_t',
41 'python_2_unicode_compatible',
42]
45# ############# py3k ########################################################
46PY3 = sys.version_info[0] >= 3
47PY2 = sys.version_info[0] < 3
49try:
50 reload = reload # noqa
51except NameError: # pragma: no cover
52 try:
53 from importlib import reload # noqa
54 except ImportError: # pragma: no cover
55 from imp import reload # noqa
57try:
58 from collections import UserList # noqa
59except ImportError: # pragma: no cover
60 from UserList import UserList # noqa
62try:
63 from collections import UserDict # noqa
64except ImportError: # pragma: no cover
65 from UserDict import UserDict # noqa
67try:
68 from collections.abc import Callable # noqa
69except ImportError: # pragma: no cover
70 from collections import Callable # noqa
72try:
73 from collections.abc import Iterable # noqa
74except ImportError: # pragma: no cover
75 from collections import Iterable # noqa
77try:
78 from collections.abc import Mapping # noqa
79except ImportError: # pragma: no cover
80 from collections import Mapping # noqa
82# ############# time.monotonic #############################################
84if sys.version_info < (3, 3):
86 import platform
87 SYSTEM = platform.system()
89 try:
90 import ctypes
91 except ImportError: # pragma: no cover
92 ctypes = None # noqa
94 if SYSTEM == 'Darwin' and ctypes is not None:
95 from ctypes.util import find_library
96 libSystem = ctypes.CDLL(find_library('libSystem.dylib'))
97 CoreServices = ctypes.CDLL(find_library('CoreServices'),
98 use_errno=True)
99 mach_absolute_time = libSystem.mach_absolute_time
100 mach_absolute_time.restype = ctypes.c_uint64
101 absolute_to_nanoseconds = CoreServices.AbsoluteToNanoseconds
102 absolute_to_nanoseconds.restype = ctypes.c_uint64
103 absolute_to_nanoseconds.argtypes = [ctypes.c_uint64]
105 def _monotonic():
106 return absolute_to_nanoseconds(mach_absolute_time()) * 1e-9
108 elif SYSTEM == 'Linux' and ctypes is not None:
109 # from stackoverflow:
110 # questions/1205722/how-do-i-get-monotonic-time-durations-in-python
111 import os
113 CLOCK_MONOTONIC = 1 # see <linux/time.h>
115 class timespec(ctypes.Structure):
116 _fields_ = [
117 ('tv_sec', ctypes.c_long),
118 ('tv_nsec', ctypes.c_long),
119 ]
121 try:
122 librt = ctypes.CDLL('librt.so.1', use_errno=True)
123 except Exception:
124 try:
125 librt = ctypes.CDLL('librt.so.0', use_errno=True)
126 except Exception as exc:
127 error = OSError(
128 "Could not detect working librt library: {0}".format(
129 exc))
130 error.errno = errno.ENOENT
131 raise error
132 clock_gettime = librt.clock_gettime
133 clock_gettime.argtypes = [
134 ctypes.c_int, ctypes.POINTER(timespec),
135 ]
137 def _monotonic(): # noqa
138 t = timespec()
139 if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) != 0:
140 errno_ = ctypes.get_errno()
141 raise OSError(errno_, os.strerror(errno_))
142 return t.tv_sec + t.tv_nsec * 1e-9
143 else:
144 from time import time as _monotonic
145try:
146 from time import monotonic
147except ImportError:
148 monotonic = _monotonic # noqa
150# ############# Py3 <-> Py2 #################################################
152if PY3: # pragma: no cover
153 import builtins
155 from array import array
156 from queue import Queue, Empty, Full, LifoQueue
157 from itertools import zip_longest
159 map = map
160 zip = zip
161 string = str
162 string_t = str
163 long_t = int
164 text_t = str
165 range = range
166 int_types = (int,)
167 module_name_t = str
169 def bytes_if_py2(s):
170 """Convert str to bytes if running under Python 2."""
171 return s
173 def items(d):
174 """Get dict items iterator."""
175 return d.items()
177 def keys(d):
178 """Get dict keys iterator."""
179 return d.keys()
181 def values(d):
182 """Get dict values iterator."""
183 return d.values()
185 def nextfun(it):
186 """Get iterator next method."""
187 return it.__next__
189 exec_ = getattr(builtins, 'exec')
191 def reraise(tp, value, tb=None):
192 """Reraise exception."""
193 if value.__traceback__ is not tb:
194 raise value.with_traceback(tb)
195 raise value
197else:
198 import __builtin__ as builtins # noqa
199 from array import array as _array
200 from Queue import Queue, Empty, Full, LifoQueue # noqa
201 from itertools import ( # noqa
202 imap as map,
203 izip as zip,
204 izip_longest as zip_longest,
205 )
207 string = unicode # noqa
208 string_t = basestring # noqa
209 text_t = unicode
210 long_t = long # noqa
211 range = xrange
212 module_name_t = str
213 int_types = (int, long)
215 def array(typecode, *args, **kwargs):
216 """Create array."""
217 if isinstance(typecode, unicode):
218 typecode = typecode.encode()
219 return _array(typecode, *args, **kwargs)
221 def bytes_if_py2(s):
222 """Convert str to bytes if running under Python 2."""
223 if isinstance(s, unicode):
224 return s.encode()
225 return s
227 def items(d): # noqa
228 """Return dict items iterator."""
229 return d.iteritems()
231 def keys(d): # noqa
232 """Return dict key iterator."""
233 return d.iterkeys()
235 def values(d): # noqa
236 """Return dict values iterator."""
237 return d.itervalues()
239 def nextfun(it): # noqa
240 """Return iterator next method."""
241 return it.next
243 def exec_(code, globs=None, locs=None): # pragma: no cover
244 """Execute code in a namespace."""
245 if globs is None:
246 frame = sys._getframe(1)
247 globs = frame.f_globals
248 if locs is None:
249 locs = frame.f_locals
250 del frame
251 elif locs is None:
252 locs = globs
253 exec("""exec code in globs, locs""")
255 exec_("""def reraise(tp, value, tb=None): raise tp, value, tb""")
258def with_metaclass(Type, skip_attrs=None):
259 """Class decorator to set metaclass.
261 Works with both Python 2 and Python 3 and it does not add
262 an extra class in the lookup order like ``six.with_metaclass`` does
263 (that is -- it copies the original class instead of using inheritance).
265 """
266 if skip_attrs is None:
267 skip_attrs = {'__dict__', '__weakref__'}
269 def _clone_with_metaclass(Class):
270 attrs = {key: value for key, value in items(vars(Class))
271 if key not in skip_attrs}
272 return Type(Class.__name__, Class.__bases__, attrs)
274 return _clone_with_metaclass
277# ############# threading.TIMEOUT_MAX ########################################
278try:
279 from threading import TIMEOUT_MAX as THREAD_TIMEOUT_MAX
280except ImportError:
281 THREAD_TIMEOUT_MAX = 1e10 # noqa
283# ############# format(int, ',d') ############################################
285if sys.version_info >= (2, 7): # pragma: no cover
286 def format_d(i):
287 """Format number."""
288 return format(i, ',d')
289else: # pragma: no cover
290 def format_d(i): # noqa
291 """Format number."""
292 s = '%d' % i
293 groups = []
294 while s and s[-1].isdigit():
295 groups.append(s[-3:])
296 s = s[:-3]
297 return s + ','.join(reversed(groups))
299StringIO = io.StringIO
300_SIO_write = StringIO.write
301_SIO_init = StringIO.__init__
304class WhateverIO(StringIO):
305 """StringIO that takes bytes or str."""
307 def __init__(self, v=None, *a, **kw):
308 _SIO_init(self, v.decode() if isinstance(v, bytes) else v, *a, **kw)
310 def write(self, data):
311 _SIO_write(self, data.decode() if isinstance(data, bytes) else data)
314def python_2_unicode_compatible(cls):
315 """Class decorator to ensure class is compatible with Python 2."""
316 return python_2_non_unicode_str(python_2_non_unicode_repr(cls))
319def python_2_non_unicode_repr(cls):
320 """Ensure cls.__repr__ returns unicode.
322 A class decorator that ensures ``__repr__`` returns non-unicode
323 when running under Python 2.
324 """
325 if PY2:
326 try:
327 cls.__dict__['__repr__']
328 except KeyError:
329 pass
330 else:
331 def __repr__(self, *args, **kwargs):
332 return self.__unicode_repr__(*args, **kwargs).encode(
333 'utf-8', 'replace')
334 cls.__unicode_repr__, cls.__repr__ = cls.__repr__, __repr__
335 return cls
338def python_2_non_unicode_str(cls):
339 """Python 2 class string compatibility.
341 A class decorator that defines ``__unicode__`` and ``__str__`` methods
342 under Python 2. Under Python 3 it does nothing.
344 To support Python 2 and 3 with a single code base, define a ``__str__``
345 method returning text and apply this decorator to the class.
346 """
347 if PY2:
348 try:
349 cls.__dict__['__str__']
350 except KeyError:
351 pass
352 else:
353 def __str__(self, *args, **kwargs):
354 return self.__unicode__(*args, **kwargs).encode(
355 'utf-8', 'replace')
356 cls.__unicode__, cls.__str__ = cls.__str__, __str__
357 return cls
360try: # pragma: no cover
361 from inspect import formatargspec, getfullargspec
362except ImportError: # Py2
363 from collections import namedtuple
364 from inspect import formatargspec, getargspec as _getargspec # noqa
366 FullArgSpec = namedtuple('FullArgSpec', (
367 'args', 'varargs', 'varkw', 'defaults',
368 'kwonlyargs', 'kwonlydefaults', 'annotations',
369 ))
371 def getfullargspec(fun, _fill=(None, ) * 3): # noqa
372 """For compatibility with Python 3."""
373 s = _getargspec(fun)
374 return FullArgSpec(*s + _fill)