Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/psutil/_compat.py @ 1:56ad4e20f292 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
| author | guerler |
|---|---|
| date | Fri, 31 Jul 2020 00:32:28 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:d30785e31577 | 1:56ad4e20f292 |
|---|---|
| 1 # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """Module which provides compatibility with older Python versions. | |
| 6 This is more future-compatible rather than the opposite (prefer latest | |
| 7 Python 3 way of doing things). | |
| 8 """ | |
| 9 | |
| 10 import collections | |
| 11 import errno | |
| 12 import functools | |
| 13 import os | |
| 14 import sys | |
| 15 import types | |
| 16 | |
| 17 __all__ = [ | |
| 18 # constants | |
| 19 "PY3", | |
| 20 # builtins | |
| 21 "long", "range", "super", "unicode", "basestring", | |
| 22 # literals | |
| 23 "u", "b", | |
| 24 # collections module | |
| 25 "lru_cache", | |
| 26 # shutil module | |
| 27 "which", "get_terminal_size", | |
| 28 # python 3 exceptions | |
| 29 "FileNotFoundError", "PermissionError", "ProcessLookupError", | |
| 30 "InterruptedError", "ChildProcessError", "FileExistsError"] | |
| 31 | |
| 32 | |
| 33 PY3 = sys.version_info[0] == 3 | |
| 34 _SENTINEL = object() | |
| 35 | |
| 36 if PY3: | |
| 37 long = int | |
| 38 xrange = range | |
| 39 unicode = str | |
| 40 basestring = str | |
| 41 range = range | |
| 42 | |
| 43 def u(s): | |
| 44 return s | |
| 45 | |
| 46 def b(s): | |
| 47 return s.encode("latin-1") | |
| 48 else: | |
| 49 long = long | |
| 50 range = xrange | |
| 51 unicode = unicode | |
| 52 basestring = basestring | |
| 53 | |
| 54 def u(s): | |
| 55 return unicode(s, "unicode_escape") | |
| 56 | |
| 57 def b(s): | |
| 58 return s | |
| 59 | |
| 60 | |
| 61 # --- builtins | |
| 62 | |
| 63 | |
| 64 # Python 3 super(). | |
| 65 # Taken from "future" package. | |
| 66 # Credit: Ryan Kelly | |
| 67 if PY3: | |
| 68 super = super | |
| 69 else: | |
| 70 _builtin_super = super | |
| 71 | |
| 72 def super(type_=_SENTINEL, type_or_obj=_SENTINEL, framedepth=1): | |
| 73 """Like Python 3 builtin super(). If called without any arguments | |
| 74 it attempts to infer them at runtime. | |
| 75 """ | |
| 76 if type_ is _SENTINEL: | |
| 77 f = sys._getframe(framedepth) | |
| 78 try: | |
| 79 # Get the function's first positional argument. | |
| 80 type_or_obj = f.f_locals[f.f_code.co_varnames[0]] | |
| 81 except (IndexError, KeyError): | |
| 82 raise RuntimeError('super() used in a function with no args') | |
| 83 try: | |
| 84 # Get the MRO so we can crawl it. | |
| 85 mro = type_or_obj.__mro__ | |
| 86 except (AttributeError, RuntimeError): | |
| 87 try: | |
| 88 mro = type_or_obj.__class__.__mro__ | |
| 89 except AttributeError: | |
| 90 raise RuntimeError('super() used in a non-newstyle class') | |
| 91 for type_ in mro: | |
| 92 # Find the class that owns the currently-executing method. | |
| 93 for meth in type_.__dict__.values(): | |
| 94 # Drill down through any wrappers to the underlying func. | |
| 95 # This handles e.g. classmethod() and staticmethod(). | |
| 96 try: | |
| 97 while not isinstance(meth, types.FunctionType): | |
| 98 if isinstance(meth, property): | |
| 99 # Calling __get__ on the property will invoke | |
| 100 # user code which might throw exceptions or | |
| 101 # have side effects | |
| 102 meth = meth.fget | |
| 103 else: | |
| 104 try: | |
| 105 meth = meth.__func__ | |
| 106 except AttributeError: | |
| 107 meth = meth.__get__(type_or_obj, type_) | |
| 108 except (AttributeError, TypeError): | |
| 109 continue | |
| 110 if meth.func_code is f.f_code: | |
| 111 break # found | |
| 112 else: | |
| 113 # Not found. Move onto the next class in MRO. | |
| 114 continue | |
| 115 break # found | |
| 116 else: | |
| 117 raise RuntimeError('super() called outside a method') | |
| 118 | |
| 119 # Dispatch to builtin super(). | |
| 120 if type_or_obj is not _SENTINEL: | |
| 121 return _builtin_super(type_, type_or_obj) | |
| 122 return _builtin_super(type_) | |
| 123 | |
| 124 | |
| 125 # --- exceptions | |
| 126 | |
| 127 | |
| 128 if PY3: | |
| 129 FileNotFoundError = FileNotFoundError # NOQA | |
| 130 PermissionError = PermissionError # NOQA | |
| 131 ProcessLookupError = ProcessLookupError # NOQA | |
| 132 InterruptedError = InterruptedError # NOQA | |
| 133 ChildProcessError = ChildProcessError # NOQA | |
| 134 FileExistsError = FileExistsError # NOQA | |
| 135 else: | |
| 136 # https://github.com/PythonCharmers/python-future/blob/exceptions/ | |
| 137 # src/future/types/exceptions/pep3151.py | |
| 138 import platform | |
| 139 | |
| 140 def _instance_checking_exception(base_exception=Exception): | |
| 141 def wrapped(instance_checker): | |
| 142 class TemporaryClass(base_exception): | |
| 143 | |
| 144 def __init__(self, *args, **kwargs): | |
| 145 if len(args) == 1 and isinstance(args[0], TemporaryClass): | |
| 146 unwrap_me = args[0] | |
| 147 for attr in dir(unwrap_me): | |
| 148 if not attr.startswith('__'): | |
| 149 setattr(self, attr, getattr(unwrap_me, attr)) | |
| 150 else: | |
| 151 super(TemporaryClass, self).__init__(*args, **kwargs) | |
| 152 | |
| 153 class __metaclass__(type): | |
| 154 def __instancecheck__(cls, inst): | |
| 155 return instance_checker(inst) | |
| 156 | |
| 157 def __subclasscheck__(cls, classinfo): | |
| 158 value = sys.exc_info()[1] | |
| 159 return isinstance(value, cls) | |
| 160 | |
| 161 TemporaryClass.__name__ = instance_checker.__name__ | |
| 162 TemporaryClass.__doc__ = instance_checker.__doc__ | |
| 163 return TemporaryClass | |
| 164 | |
| 165 return wrapped | |
| 166 | |
| 167 @_instance_checking_exception(EnvironmentError) | |
| 168 def FileNotFoundError(inst): | |
| 169 return getattr(inst, 'errno', _SENTINEL) == errno.ENOENT | |
| 170 | |
| 171 @_instance_checking_exception(EnvironmentError) | |
| 172 def ProcessLookupError(inst): | |
| 173 return getattr(inst, 'errno', _SENTINEL) == errno.ESRCH | |
| 174 | |
| 175 @_instance_checking_exception(EnvironmentError) | |
| 176 def PermissionError(inst): | |
| 177 return getattr(inst, 'errno', _SENTINEL) in ( | |
| 178 errno.EACCES, errno.EPERM) | |
| 179 | |
| 180 @_instance_checking_exception(EnvironmentError) | |
| 181 def InterruptedError(inst): | |
| 182 return getattr(inst, 'errno', _SENTINEL) == errno.EINTR | |
| 183 | |
| 184 @_instance_checking_exception(EnvironmentError) | |
| 185 def ChildProcessError(inst): | |
| 186 return getattr(inst, 'errno', _SENTINEL) == errno.ECHILD | |
| 187 | |
| 188 @_instance_checking_exception(EnvironmentError) | |
| 189 def FileExistsError(inst): | |
| 190 return getattr(inst, 'errno', _SENTINEL) == errno.EEXIST | |
| 191 | |
| 192 if platform.python_implementation() != "CPython": | |
| 193 try: | |
| 194 raise OSError(errno.EEXIST, "perm") | |
| 195 except FileExistsError: | |
| 196 pass | |
| 197 except OSError: | |
| 198 raise RuntimeError( | |
| 199 "broken or incompatible Python implementation, see: " | |
| 200 "https://github.com/giampaolo/psutil/issues/1659") | |
| 201 | |
| 202 | |
| 203 # --- stdlib additions | |
| 204 | |
| 205 | |
| 206 # py 3.2 functools.lru_cache | |
| 207 # Taken from: http://code.activestate.com/recipes/578078 | |
| 208 # Credit: Raymond Hettinger | |
| 209 try: | |
| 210 from functools import lru_cache | |
| 211 except ImportError: | |
| 212 try: | |
| 213 from threading import RLock | |
| 214 except ImportError: | |
| 215 from dummy_threading import RLock | |
| 216 | |
| 217 _CacheInfo = collections.namedtuple( | |
| 218 "CacheInfo", ["hits", "misses", "maxsize", "currsize"]) | |
| 219 | |
| 220 class _HashedSeq(list): | |
| 221 __slots__ = 'hashvalue' | |
| 222 | |
| 223 def __init__(self, tup, hash=hash): | |
| 224 self[:] = tup | |
| 225 self.hashvalue = hash(tup) | |
| 226 | |
| 227 def __hash__(self): | |
| 228 return self.hashvalue | |
| 229 | |
| 230 def _make_key(args, kwds, typed, | |
| 231 kwd_mark=(object(), ), | |
| 232 fasttypes=set((int, str, frozenset, type(None))), | |
| 233 sorted=sorted, tuple=tuple, type=type, len=len): | |
| 234 key = args | |
| 235 if kwds: | |
| 236 sorted_items = sorted(kwds.items()) | |
| 237 key += kwd_mark | |
| 238 for item in sorted_items: | |
| 239 key += item | |
| 240 if typed: | |
| 241 key += tuple(type(v) for v in args) | |
| 242 if kwds: | |
| 243 key += tuple(type(v) for k, v in sorted_items) | |
| 244 elif len(key) == 1 and type(key[0]) in fasttypes: | |
| 245 return key[0] | |
| 246 return _HashedSeq(key) | |
| 247 | |
| 248 def lru_cache(maxsize=100, typed=False): | |
| 249 """Least-recently-used cache decorator, see: | |
| 250 http://docs.python.org/3/library/functools.html#functools.lru_cache | |
| 251 """ | |
| 252 def decorating_function(user_function): | |
| 253 cache = dict() | |
| 254 stats = [0, 0] | |
| 255 HITS, MISSES = 0, 1 | |
| 256 make_key = _make_key | |
| 257 cache_get = cache.get | |
| 258 _len = len | |
| 259 lock = RLock() | |
| 260 root = [] | |
| 261 root[:] = [root, root, None, None] | |
| 262 nonlocal_root = [root] | |
| 263 PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 | |
| 264 if maxsize == 0: | |
| 265 def wrapper(*args, **kwds): | |
| 266 result = user_function(*args, **kwds) | |
| 267 stats[MISSES] += 1 | |
| 268 return result | |
| 269 elif maxsize is None: | |
| 270 def wrapper(*args, **kwds): | |
| 271 key = make_key(args, kwds, typed) | |
| 272 result = cache_get(key, root) | |
| 273 if result is not root: | |
| 274 stats[HITS] += 1 | |
| 275 return result | |
| 276 result = user_function(*args, **kwds) | |
| 277 cache[key] = result | |
| 278 stats[MISSES] += 1 | |
| 279 return result | |
| 280 else: | |
| 281 def wrapper(*args, **kwds): | |
| 282 if kwds or typed: | |
| 283 key = make_key(args, kwds, typed) | |
| 284 else: | |
| 285 key = args | |
| 286 lock.acquire() | |
| 287 try: | |
| 288 link = cache_get(key) | |
| 289 if link is not None: | |
| 290 root, = nonlocal_root | |
| 291 link_prev, link_next, key, result = link | |
| 292 link_prev[NEXT] = link_next | |
| 293 link_next[PREV] = link_prev | |
| 294 last = root[PREV] | |
| 295 last[NEXT] = root[PREV] = link | |
| 296 link[PREV] = last | |
| 297 link[NEXT] = root | |
| 298 stats[HITS] += 1 | |
| 299 return result | |
| 300 finally: | |
| 301 lock.release() | |
| 302 result = user_function(*args, **kwds) | |
| 303 lock.acquire() | |
| 304 try: | |
| 305 root, = nonlocal_root | |
| 306 if key in cache: | |
| 307 pass | |
| 308 elif _len(cache) >= maxsize: | |
| 309 oldroot = root | |
| 310 oldroot[KEY] = key | |
| 311 oldroot[RESULT] = result | |
| 312 root = nonlocal_root[0] = oldroot[NEXT] | |
| 313 oldkey = root[KEY] | |
| 314 root[KEY] = root[RESULT] = None | |
| 315 del cache[oldkey] | |
| 316 cache[key] = oldroot | |
| 317 else: | |
| 318 last = root[PREV] | |
| 319 link = [last, root, key, result] | |
| 320 last[NEXT] = root[PREV] = cache[key] = link | |
| 321 stats[MISSES] += 1 | |
| 322 finally: | |
| 323 lock.release() | |
| 324 return result | |
| 325 | |
| 326 def cache_info(): | |
| 327 """Report cache statistics""" | |
| 328 lock.acquire() | |
| 329 try: | |
| 330 return _CacheInfo(stats[HITS], stats[MISSES], maxsize, | |
| 331 len(cache)) | |
| 332 finally: | |
| 333 lock.release() | |
| 334 | |
| 335 def cache_clear(): | |
| 336 """Clear the cache and cache statistics""" | |
| 337 lock.acquire() | |
| 338 try: | |
| 339 cache.clear() | |
| 340 root = nonlocal_root[0] | |
| 341 root[:] = [root, root, None, None] | |
| 342 stats[:] = [0, 0] | |
| 343 finally: | |
| 344 lock.release() | |
| 345 | |
| 346 wrapper.__wrapped__ = user_function | |
| 347 wrapper.cache_info = cache_info | |
| 348 wrapper.cache_clear = cache_clear | |
| 349 return functools.update_wrapper(wrapper, user_function) | |
| 350 | |
| 351 return decorating_function | |
| 352 | |
| 353 | |
| 354 # python 3.3 | |
| 355 try: | |
| 356 from shutil import which | |
| 357 except ImportError: | |
| 358 def which(cmd, mode=os.F_OK | os.X_OK, path=None): | |
| 359 """Given a command, mode, and a PATH string, return the path which | |
| 360 conforms to the given mode on the PATH, or None if there is no such | |
| 361 file. | |
| 362 | |
| 363 `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result | |
| 364 of os.environ.get("PATH"), or can be overridden with a custom search | |
| 365 path. | |
| 366 """ | |
| 367 def _access_check(fn, mode): | |
| 368 return (os.path.exists(fn) and os.access(fn, mode) and | |
| 369 not os.path.isdir(fn)) | |
| 370 | |
| 371 if os.path.dirname(cmd): | |
| 372 if _access_check(cmd, mode): | |
| 373 return cmd | |
| 374 return None | |
| 375 | |
| 376 if path is None: | |
| 377 path = os.environ.get("PATH", os.defpath) | |
| 378 if not path: | |
| 379 return None | |
| 380 path = path.split(os.pathsep) | |
| 381 | |
| 382 if sys.platform == "win32": | |
| 383 if os.curdir not in path: | |
| 384 path.insert(0, os.curdir) | |
| 385 | |
| 386 pathext = os.environ.get("PATHEXT", "").split(os.pathsep) | |
| 387 if any(cmd.lower().endswith(ext.lower()) for ext in pathext): | |
| 388 files = [cmd] | |
| 389 else: | |
| 390 files = [cmd + ext for ext in pathext] | |
| 391 else: | |
| 392 files = [cmd] | |
| 393 | |
| 394 seen = set() | |
| 395 for dir in path: | |
| 396 normdir = os.path.normcase(dir) | |
| 397 if normdir not in seen: | |
| 398 seen.add(normdir) | |
| 399 for thefile in files: | |
| 400 name = os.path.join(dir, thefile) | |
| 401 if _access_check(name, mode): | |
| 402 return name | |
| 403 return None | |
| 404 | |
| 405 | |
| 406 # python 3.3 | |
| 407 try: | |
| 408 from shutil import get_terminal_size | |
| 409 except ImportError: | |
| 410 def get_terminal_size(fallback=(80, 24)): | |
| 411 try: | |
| 412 import fcntl | |
| 413 import termios | |
| 414 import struct | |
| 415 except ImportError: | |
| 416 return fallback | |
| 417 else: | |
| 418 try: | |
| 419 # This should work on Linux. | |
| 420 res = struct.unpack( | |
| 421 'hh', fcntl.ioctl(1, termios.TIOCGWINSZ, '1234')) | |
| 422 return (res[1], res[0]) | |
| 423 except Exception: | |
| 424 return fallback |
