ÿØÿà JFIF    ÿÛ „ ( %!1!%*+...983,7(-.- lib64/python3.6/wsgiref/__init__.py000064400000001113152343437210013013 0ustar00"""wsgiref -- a WSGI (PEP 3333) Reference Library Current Contents: * util -- Miscellaneous useful functions and wrappers * headers -- Manage response headers * handlers -- base classes for server/gateway implementations * simple_server -- a simple BaseHTTPServer that supports WSGI * validate -- validation wrapper that sits between an app and a server to detect errors in either To-Do: * cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard) * cgi_wrapper -- Run CGI apps under WSGI * router -- a simple middleware component that handles URL traversal """ lib64/python3.12/ctypes/__init__.py000064400000043442152343612040012740 0ustar00"""create and manipulate C data types in Python""" import os as _os, sys as _sys import types as _types __version__ = "1.1.0" from _ctypes import Union, Structure, Array from _ctypes import _Pointer from _ctypes import CFuncPtr as _CFuncPtr from _ctypes import __version__ as _ctypes_version from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import ArgumentError from _ctypes import SIZEOF_TIME_T from struct import calcsize as _calcsize if __version__ != _ctypes_version: raise Exception("Version number mismatch", __version__, _ctypes_version) if _os.name == "nt": from _ctypes import FormatError DEFAULT_MODE = RTLD_LOCAL if _os.name == "posix" and _sys.platform == "darwin": # On OS X 10.3, we use RTLD_GLOBAL as default mode # because RTLD_LOCAL does not work at least on some # libraries. OS X 10.3 is Darwin 7, so we check for # that. if int(_os.uname().release.split('.')[0]) < 8: DEFAULT_MODE = RTLD_GLOBAL from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \ FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \ FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR # WINOLEAPI -> HRESULT # WINOLEAPI_(type) # # STDMETHODCALLTYPE # # STDMETHOD(name) # STDMETHOD_(type, name) # # STDAPICALLTYPE def create_string_buffer(init, size=None): """create_string_buffer(aBytes) -> character array create_string_buffer(anInteger) -> character array create_string_buffer(aBytes, anInteger) -> character array """ if isinstance(init, bytes): if size is None: size = len(init)+1 _sys.audit("ctypes.create_string_buffer", init, size) buftype = c_char * size buf = buftype() buf.value = init return buf elif isinstance(init, int): _sys.audit("ctypes.create_string_buffer", None, init) buftype = c_char * init buf = buftype() return buf raise TypeError(init) # Alias to create_string_buffer() for backward compatibility c_buffer = create_string_buffer _c_functype_cache = {} def CFUNCTYPE(restype, *argtypes, **kw): """CFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) -> function prototype. restype: the result type argtypes: a sequence specifying the argument types The function prototype can be called in different ways to create a callable object: prototype(integer address) -> foreign function prototype(callable) -> create and return a C callable function from callable prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal prototype((function name, dll object)[, paramflags]) -> foreign function exported by name """ flags = _FUNCFLAG_CDECL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _c_functype_cache[(restype, argtypes, flags)] except KeyError: pass class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _c_functype_cache[(restype, argtypes, flags)] = CFunctionType return CFunctionType if _os.name == "nt": from _ctypes import LoadLibrary as _dlopen from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL _win_functype_cache = {} def WINFUNCTYPE(restype, *argtypes, **kw): # docstring set later (very similar to CFUNCTYPE.__doc__) flags = _FUNCFLAG_STDCALL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _win_functype_cache[(restype, argtypes, flags)] except KeyError: pass class WinFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType return WinFunctionType if WINFUNCTYPE.__doc__: WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE") elif _os.name == "posix": from _ctypes import dlopen as _dlopen from _ctypes import sizeof, byref, addressof, alignment, resize from _ctypes import get_errno, set_errno from _ctypes import _SimpleCData def _check_size(typ, typecode=None): # Check if sizeof(ctypes_type) against struct.calcsize. This # should protect somewhat against a misconfigured libffi. from struct import calcsize if typecode is None: # Most _type_ codes are the same as used in struct typecode = typ._type_ actual, required = sizeof(typ), calcsize(typecode) if actual != required: raise SystemError("sizeof(%s) wrong: %d instead of %d" % \ (typ, actual, required)) class py_object(_SimpleCData): _type_ = "O" def __repr__(self): try: return super().__repr__() except ValueError: return "%s()" % type(self).__name__ _check_size(py_object, "P") class c_short(_SimpleCData): _type_ = "h" _check_size(c_short) class c_ushort(_SimpleCData): _type_ = "H" _check_size(c_ushort) class c_long(_SimpleCData): _type_ = "l" _check_size(c_long) class c_ulong(_SimpleCData): _type_ = "L" _check_size(c_ulong) if _calcsize("i") == _calcsize("l"): # if int and long have the same size, make c_int an alias for c_long c_int = c_long c_uint = c_ulong else: class c_int(_SimpleCData): _type_ = "i" _check_size(c_int) class c_uint(_SimpleCData): _type_ = "I" _check_size(c_uint) class c_float(_SimpleCData): _type_ = "f" _check_size(c_float) class c_double(_SimpleCData): _type_ = "d" _check_size(c_double) class c_longdouble(_SimpleCData): _type_ = "g" if sizeof(c_longdouble) == sizeof(c_double): c_longdouble = c_double if _calcsize("l") == _calcsize("q"): # if long and long long have the same size, make c_longlong an alias for c_long c_longlong = c_long c_ulonglong = c_ulong else: class c_longlong(_SimpleCData): _type_ = "q" _check_size(c_longlong) class c_ulonglong(_SimpleCData): _type_ = "Q" ## def from_param(cls, val): ## return ('d', float(val), val) ## from_param = classmethod(from_param) _check_size(c_ulonglong) class c_ubyte(_SimpleCData): _type_ = "B" c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte # backward compatibility: ##c_uchar = c_ubyte _check_size(c_ubyte) class c_byte(_SimpleCData): _type_ = "b" c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte _check_size(c_byte) class c_char(_SimpleCData): _type_ = "c" c_char.__ctype_le__ = c_char.__ctype_be__ = c_char _check_size(c_char) class c_char_p(_SimpleCData): _type_ = "z" def __repr__(self): return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) _check_size(c_char_p, "P") class c_void_p(_SimpleCData): _type_ = "P" c_voidp = c_void_p # backwards compatibility (to a bug) _check_size(c_void_p) class c_bool(_SimpleCData): _type_ = "?" from _ctypes import POINTER, pointer, _pointer_type_cache class c_wchar_p(_SimpleCData): _type_ = "Z" def __repr__(self): return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) class c_wchar(_SimpleCData): _type_ = "u" def _reset_cache(): _pointer_type_cache.clear() _c_functype_cache.clear() if _os.name == "nt": _win_functype_cache.clear() # _SimpleCData.c_wchar_p_from_param POINTER(c_wchar).from_param = c_wchar_p.from_param # _SimpleCData.c_char_p_from_param POINTER(c_char).from_param = c_char_p.from_param _pointer_type_cache[None] = c_void_p def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array create_unicode_buffer(aString, anInteger) -> character array """ if isinstance(init, str): if size is None: if sizeof(c_wchar) == 2: # UTF-16 requires a surrogate pair (2 wchar_t) for non-BMP # characters (outside [U+0000; U+FFFF] range). +1 for trailing # NUL character. size = sum(2 if ord(c) > 0xFFFF else 1 for c in init) + 1 else: # 32-bit wchar_t (1 wchar_t per Unicode character). +1 for # trailing NUL character. size = len(init) + 1 _sys.audit("ctypes.create_unicode_buffer", init, size) buftype = c_wchar * size buf = buftype() buf.value = init return buf elif isinstance(init, int): _sys.audit("ctypes.create_unicode_buffer", None, init) buftype = c_wchar * init buf = buftype() return buf raise TypeError(init) # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: raise RuntimeError("This type already exists in the cache") if id(pointer) not in _pointer_type_cache: raise RuntimeError("What's this???") pointer.set_type(cls) _pointer_type_cache[cls] = pointer del _pointer_type_cache[id(pointer)] # XXX Deprecated def ARRAY(typ, len): return typ * len ################################################################ class CDLL(object): """An instance of this class represents a loaded dll/shared library, exporting functions using the standard C calling convention (named 'cdecl' on Windows). The exported functions can be accessed as attributes, or by indexing with the function name. Examples: .qsort -> callable object ['qsort'] -> callable object Calling the functions releases the Python GIL during the call and reacquires it afterwards. """ _func_flags_ = _FUNCFLAG_CDECL _func_restype_ = c_int # default values for repr _name = '' _handle = 0 _FuncPtr = None def __init__(self, name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None): if name: name = _os.fspath(name) self._name = name flags = self._func_flags_ if use_errno: flags |= _FUNCFLAG_USE_ERRNO if use_last_error: flags |= _FUNCFLAG_USE_LASTERROR if _sys.platform.startswith("aix"): """When the name contains ".a(" and ends with ")", e.g., "libFOO.a(libFOO.so)" - this is taken to be an archive(member) syntax for dlopen(), and the mode is adjusted. Otherwise, name is presented to dlopen() as a file argument. """ if name and name.endswith(")") and ".a(" in name: mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW ) if _os.name == "nt": if winmode is not None: mode = winmode else: import nt mode = nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS if '/' in name or '\\' in name: self._name = nt._getfullpathname(self._name) mode |= nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR class _FuncPtr(_CFuncPtr): _flags_ = flags _restype_ = self._func_restype_ self._FuncPtr = _FuncPtr if handle is None: self._handle = _dlopen(self._name, mode) else: self._handle = handle def __repr__(self): return "<%s '%s', handle %x at %#x>" % \ (self.__class__.__name__, self._name, (self._handle & (_sys.maxsize*2 + 1)), id(self) & (_sys.maxsize*2 + 1)) def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): raise AttributeError(name) func = self.__getitem__(name) setattr(self, name, func) return func def __getitem__(self, name_or_ordinal): func = self._FuncPtr((name_or_ordinal, self)) if not isinstance(name_or_ordinal, int): func.__name__ = name_or_ordinal return func class PyDLL(CDLL): """This class represents the Python library itself. It allows accessing Python API functions. The GIL is not released, and Python exceptions are handled correctly. """ _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI if _os.name == "nt": class WinDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention. """ _func_flags_ = _FUNCFLAG_STDCALL # XXX Hm, what about HRESULT as normal parameter? # Mustn't it derive from c_long then? from _ctypes import _check_HRESULT, _SimpleCData class HRESULT(_SimpleCData): _type_ = "l" # _check_retval_ is called with the function's result when it # is used as restype. It checks for the FAILED bit, and # raises an OSError if it is set. # # The _check_retval_ method is implemented in C, so that the # method definition itself is not included in the traceback # when it raises an error - that is what we want (and Python # doesn't have a way to raise an exception in the caller's # frame). _check_retval_ = _check_HRESULT class OleDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention, and returning HRESULT. HRESULT error values are automatically raised as OSError exceptions. """ _func_flags_ = _FUNCFLAG_STDCALL _func_restype_ = HRESULT class LibraryLoader(object): def __init__(self, dlltype): self._dlltype = dlltype def __getattr__(self, name): if name[0] == '_': raise AttributeError(name) try: dll = self._dlltype(name) except OSError: raise AttributeError(name) setattr(self, name, dll) return dll def __getitem__(self, name): return getattr(self, name) def LoadLibrary(self, name): return self._dlltype(name) __class_getitem__ = classmethod(_types.GenericAlias) cdll = LibraryLoader(CDLL) pydll = LibraryLoader(PyDLL) if _os.name == "nt": pythonapi = PyDLL("python dll", None, _sys.dllhandle) elif _sys.platform == "cygwin": pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) else: pythonapi = PyDLL(None) if _os.name == "nt": windll = LibraryLoader(WinDLL) oledll = LibraryLoader(OleDLL) GetLastError = windll.kernel32.GetLastError from _ctypes import get_last_error, set_last_error def WinError(code=None, descr=None): if code is None: code = GetLastError() if descr is None: descr = FormatError(code).strip() return OSError(None, descr, None, code) if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int elif sizeof(c_ulong) == sizeof(c_void_p): c_size_t = c_ulong c_ssize_t = c_long elif sizeof(c_ulonglong) == sizeof(c_void_p): c_size_t = c_ulonglong c_ssize_t = c_longlong # functions from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr ## void *memmove(void *, const void *, size_t); memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) ## void *memset(void *, int, size_t) memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) def PYFUNCTYPE(restype, *argtypes): class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI return CFunctionType _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) def cast(obj, typ): return _cast(obj, obj, typ) _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) def string_at(ptr, size=-1): """string_at(ptr[, size]) -> string Return the byte string at void *ptr.""" return _string_at(ptr, size) try: from _ctypes import _wstring_at_addr except ImportError: pass else: _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) def wstring_at(ptr, size=-1): """wstring_at(ptr[, size]) -> string Return the wide-character string at void *ptr.""" return _wstring_at(ptr, size) if _os.name == "nt": # COM stuff def DllGetClassObject(rclsid, riid, ppv): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return -2147221231 # CLASS_E_CLASSNOTAVAILABLE else: return ccom.DllGetClassObject(rclsid, riid, ppv) def DllCanUnloadNow(): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return 0 # S_OK return ccom.DllCanUnloadNow() from ctypes._endian import BigEndianStructure, LittleEndianStructure from ctypes._endian import BigEndianUnion, LittleEndianUnion # Fill in specifically-sized types c_int8 = c_byte c_uint8 = c_ubyte for kind in [c_short, c_int, c_long, c_longlong]: if sizeof(kind) == 2: c_int16 = kind elif sizeof(kind) == 4: c_int32 = kind elif sizeof(kind) == 8: c_int64 = kind for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]: if sizeof(kind) == 2: c_uint16 = kind elif sizeof(kind) == 4: c_uint32 = kind elif sizeof(kind) == 8: c_uint64 = kind del(kind) if SIZEOF_TIME_T == 8: c_time_t = c_int64 elif SIZEOF_TIME_T == 4: c_time_t = c_int32 else: raise SystemError(f"Unexpected sizeof(time_t): {SIZEOF_TIME_T=}") _reset_cache() lib64/python3.12/re/__init__.py000064400000037673152343612420012052 0ustar00# # Secret Labs' Regular Expression Engine # # re-compatible interface for the sre matching engine # # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # # This version of the SRE library can be redistributed under CNRI's # Python 1.6 license. For any other use, please contact Secret Labs # AB (info@pythonware.com). # # Portions of this engine have been developed in cooperation with # CNRI. Hewlett-Packard provided funding for 1.6 integration and # other compatibility work. # r"""Support for regular expressions (RE). This module provides regular expression matching operations similar to those found in Perl. It supports both 8-bit and Unicode strings; both the pattern and the strings being processed can contain null bytes and characters outside the US ASCII range. Regular expressions can contain both special and ordinary characters. Most ordinary characters, like "A", "a", or "0", are the simplest regular expressions; they simply match themselves. You can concatenate ordinary characters, so last matches the string 'last'. The special characters are: "." Matches any character except a newline. "^" Matches the start of the string. "$" Matches the end of the string or just before the newline at the end of the string. "*" Matches 0 or more (greedy) repetitions of the preceding RE. Greedy means that it will match as many repetitions as possible. "+" Matches 1 or more (greedy) repetitions of the preceding RE. "?" Matches 0 or 1 (greedy) of the preceding RE. *?,+?,?? Non-greedy versions of the previous three special characters. {m,n} Matches from m to n repetitions of the preceding RE. {m,n}? Non-greedy version of the above. "\\" Either escapes special characters or signals a special sequence. [] Indicates a set of characters. A "^" as the first character indicates a complementing set. "|" A|B, creates an RE that will match either A or B. (...) Matches the RE inside the parentheses. The contents can be retrieved or matched later in the string. (?aiLmsux) The letters set the corresponding flags defined below. (?:...) Non-grouping version of regular parentheses. (?P...) The substring matched by the group is accessible by name. (?P=name) Matches the text matched earlier by the group named name. (?#...) A comment; ignored. (?=...) Matches if ... matches next, but doesn't consume the string. (?!...) Matches if ... doesn't match next. (?<=...) Matches if preceded by ... (must be fixed length). (?= _MAXCACHE: # Drop the least recently used item. # next(iter(_cache)) is known to have linear amortized time, # but it is used here to avoid a dependency from using OrderedDict. # For the small _MAXCACHE value it doesn't make much of a difference. try: del _cache[next(iter(_cache))] except (StopIteration, RuntimeError, KeyError): pass # Append to the end. _cache[key] = p if len(_cache2) >= _MAXCACHE2: # Drop the oldest item. try: del _cache2[next(iter(_cache2))] except (StopIteration, RuntimeError, KeyError): pass _cache2[key] = p return p @functools.lru_cache(_MAXCACHE) def _compile_template(pattern, repl): # internal: compile replacement pattern return _sre.template(pattern, _parser.parse_template(repl, pattern)) # register myself for pickling import copyreg def _pickle(p): return _compile, (p.pattern, p.flags) copyreg.pickle(Pattern, _pickle, _compile) # -------------------------------------------------------------------- # experimental stuff (see python-dev discussions for details) class Scanner: def __init__(self, lexicon, flags=0): from ._constants import BRANCH, SUBPATTERN if isinstance(flags, RegexFlag): flags = flags.value self.lexicon = lexicon # combine phrases into a compound pattern p = [] s = _parser.State() s.flags = flags for phrase, action in lexicon: gid = s.opengroup() p.append(_parser.SubPattern(s, [ (SUBPATTERN, (gid, 0, 0, _parser.parse(phrase, flags))), ])) s.closegroup(gid, p[-1]) p = _parser.SubPattern(s, [(BRANCH, (None, p))]) self.scanner = _compiler.compile(p) def scan(self, string): result = [] append = result.append match = self.scanner.scanner(string).match i = 0 while True: m = match() if not m: break j = m.end() if i == j: break action = self.lexicon[m.lastindex-1][1] if callable(action): self.match = m action = action(self, m.group()) if action is not None: append(action) i = j return result, string[i:] lib64/python3.12/encodings/__init__.py000064400000013374152343624650013415 0ustar00""" Standard "encodings" Package Standard Python encoding modules are stored in this package directory. Codec modules must have names corresponding to normalized encoding names as defined in the normalize_encoding() function below, e.g. 'utf-8' must be implemented by the module 'utf_8.py'. Each codec module must export the following interface: * getregentry() -> codecs.CodecInfo object The getregentry() API must return a CodecInfo object with encoder, decoder, incrementalencoder, incrementaldecoder, streamwriter and streamreader attributes which adhere to the Python Codec Interface Standard. In addition, a module may optionally also define the following APIs which are then used by the package's codec search function: * getaliases() -> sequence of encoding name strings to use as aliases Alias names returned by getaliases() must be normalized encoding names as defined by normalize_encoding(). Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" import codecs import sys from . import aliases _cache = {} _unknown = '--unknown--' _import_tail = ['*'] _aliases = aliases.aliases class CodecRegistryError(LookupError, SystemError): pass def normalize_encoding(encoding): """ Normalize an encoding name. Normalization works as follows: all non-alphanumeric characters except the dot used for Python package names are collapsed and replaced with a single underscore, e.g. ' -;#' becomes '_'. Leading and trailing underscores are removed. Note that encoding names should be ASCII only. """ if isinstance(encoding, bytes): encoding = str(encoding, "ascii") chars = [] punct = False for c in encoding: if c.isalnum() or c == '.': if punct and chars: chars.append('_') if c.isascii(): chars.append(c) punct = False else: punct = True return ''.join(chars) def search_function(encoding): # Cache lookup entry = _cache.get(encoding, _unknown) if entry is not _unknown: return entry # Import the module: # # First try to find an alias for the normalized encoding # name and lookup the module using the aliased name, then try to # lookup the module using the standard import scheme, i.e. first # try in the encodings package, then at top-level. # norm_encoding = normalize_encoding(encoding) aliased_encoding = _aliases.get(norm_encoding) or \ _aliases.get(norm_encoding.replace('.', '_')) if aliased_encoding is not None: modnames = [aliased_encoding, norm_encoding] else: modnames = [norm_encoding] for modname in modnames: if not modname or '.' in modname: continue try: # Import is absolute to prevent the possibly malicious import of a # module with side-effects that is not in the 'encodings' package. mod = __import__('encodings.' + modname, fromlist=_import_tail, level=0) except ImportError: # ImportError may occur because 'encodings.(modname)' does not exist, # or because it imports a name that does not exist (see mbcs and oem) pass else: break else: mod = None try: getregentry = mod.getregentry except AttributeError: # Not a codec module mod = None if mod is None: # Cache misses _cache[encoding] = None return None # Now ask the module for the registry entry entry = getregentry() if not isinstance(entry, codecs.CodecInfo): if not 4 <= len(entry) <= 7: raise CodecRegistryError('module "%s" (%s) failed to register' % (mod.__name__, mod.__file__)) if not callable(entry[0]) or not callable(entry[1]) or \ (entry[2] is not None and not callable(entry[2])) or \ (entry[3] is not None and not callable(entry[3])) or \ (len(entry) > 4 and entry[4] is not None and not callable(entry[4])) or \ (len(entry) > 5 and entry[5] is not None and not callable(entry[5])): raise CodecRegistryError('incompatible codecs in module "%s" (%s)' % (mod.__name__, mod.__file__)) if len(entry)<7 or entry[6] is None: entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],) entry = codecs.CodecInfo(*entry) # Cache the codec registry entry _cache[encoding] = entry # Register its aliases (without overwriting previously registered # aliases) try: codecaliases = mod.getaliases() except AttributeError: pass else: for alias in codecaliases: if alias not in _aliases: _aliases[alias] = modname # Return the registry entry return entry # Register the search_function in the Python codec registry codecs.register(search_function) if sys.platform == 'win32': # bpo-671666, bpo-46668: If Python does not implement a codec for current # Windows ANSI code page, use the "mbcs" codec instead: # WideCharToMultiByte() and MultiByteToWideChar() functions with CP_ACP. # Python does not support custom code pages. def _alias_mbcs(encoding): try: import _winapi ansi_code_page = "cp%s" % _winapi.GetACP() if encoding == ansi_code_page: import encodings.mbcs return encodings.mbcs.getregentry() except ImportError: # Imports may fail while we are shutting down pass codecs.register(_alias_mbcs) usr/lib64/python3.12/xml/__init__.py000064400000001055152343631740013044 0ustar00"""Core XML support for Python. This package contains four sub-packages: dom -- The W3C Document Object Model. This supports DOM Level 1 + Namespaces. parsers -- Python wrappers for XML parsers (currently only supports Expat). sax -- The Simple API for XML, developed by XML-Dev, led by David Megginson and ported to Python by Lars Marius Garshol. This supports the SAX 2 API. etree -- The ElementTree XML library. This is a subset of the full ElementTree XML release. """ __all__ = ["dom", "parsers", "sax", "etree"] lib64/python3.12/pydoc_data/__init__.py000064400000000000152343632060013523 0ustar00usr/lib64/python3.6/xml/__init__.py000064400000001055152343730300012757 0ustar00"""Core XML support for Python. This package contains four sub-packages: dom -- The W3C Document Object Model. This supports DOM Level 1 + Namespaces. parsers -- Python wrappers for XML parsers (currently only supports Expat). sax -- The Simple API for XML, developed by XML-Dev, led by David Megginson and ported to Python by Lars Marius Garshol. This supports the SAX 2 API. etree -- The ElementTree XML library. This is a subset of the full ElementTree XML release. """ __all__ = ["dom", "parsers", "sax", "etree"] usr/lib64/python2.7/json/__init__.py000064400000034601152343731250013140 0ustar00r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is the externally maintained version of the :mod:`json` library contained in Python 2.6, but maintains compatibility with Python 2.4 and Python 2.5 and (currently) has significant performance advantages, even without using the optional C extension for speedups. Encoding basic Python object hierarchies:: >>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print json.dumps("\"foo\bar") "\"foo\bar" >>> print json.dumps(u'\u1234') "\u1234" >>> print json.dumps('\\') "\\" >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True) {"a": 0, "b": 0, "c": 0} >>> from StringIO import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]' Compact encoding:: >>> import json >>> json.dumps([1,2,3,{'4': 5, '6': 7}], sort_keys=True, separators=(',',':')) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: >>> import json >>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, ... indent=4, separators=(',', ': ')) { "4": 5, "6": 7 } Decoding JSON:: >>> import json >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}] >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj True >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar' True >>> from StringIO import StringIO >>> io = StringIO('["streaming API"]') >>> json.load(io)[0] == 'streaming API' True Specializing JSON object decoding:: >>> import json >>> def as_complex(dct): ... if '__complex__' in dct: ... return complex(dct['real'], dct['imag']) ... return dct ... >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', ... object_hook=as_complex) (1+2j) >>> from decimal import Decimal >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') True Specializing JSON object encoding:: >>> import json >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... raise TypeError(repr(obj) + " is not JSON serializable") ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) '[2.0, 1.0]' >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) '[2.0, 1.0]' Using json.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } $ echo '{ 1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONEncoder', ] __author__ = 'Bob Ippolito ' from .decoder import JSONDecoder from .encoder import JSONEncoder _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, encoding='utf-8', default=None, ) def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, sort_keys=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is true (the default), all non-ASCII characters in the output are escaped with ``\uXXXX`` sequences, and the result is a ``str`` instance consisting of ASCII characters only. If ``ensure_ascii`` is false, some chunks written to ``fp`` may be ``unicode`` instances. This usually happens because the input contains unicode strings or the ``encoding`` parameter is used. Unless ``fp.write()`` explicitly understands ``unicode`` (as in ``codecs.getwriter``) this is likely to cause an error. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. Since the default item separator is ``', '``, the output might include trailing whitespace when ``indent`` is specified. You can use ``separators=(',', ': ')`` to avoid this. If ``separators`` is an ``(item_separator, dict_separator)`` tuple then it will be used instead of the default ``(', ', ': ')`` separators. ``(',', ':')`` is the most compact JSON representation. ``encoding`` is the character encoding for str instances, default is UTF-8. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and not sort_keys and not kw): iterable = _default_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, encoding=encoding, default=default, sort_keys=sort_keys, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, sort_keys=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, all non-ASCII characters are not escaped, and the return value may be a ``unicode`` instance. See ``dump`` for details. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. Since the default item separator is ``', '``, the output might include trailing whitespace when ``indent`` is specified. You can use ``separators=(',', ': ')`` to avoid this. If ``separators`` is an ``(item_separator, dict_separator)`` tuple then it will be used instead of the default ``(', ', ': ')`` separators. ``(',', ':')`` is the most compact JSON representation. ``encoding`` is the character encoding for str instances, default is UTF-8. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and not sort_keys and not kw): return _default_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, encoding=encoding, default=default, sort_keys=sort_keys, **kw).encode(obj) _default_decoder = JSONDecoder(encoding=None, object_hook=None, object_pairs_hook=None) def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. If the contents of ``fp`` is encoded with an ASCII based encoding other than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed, and should be wrapped with ``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode`` object and passed to ``loads()`` ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict will remember the order of insertion). If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ return loads(fp.read(), encoding=encoding, cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON document) to a Python object. If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed and should be decoded to ``unicode`` first. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict will remember the order of insertion). If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. ``parse_float``, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal). ``parse_int``, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float). ``parse_constant``, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ if (cls is None and encoding is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(encoding=encoding, **kw).decode(s) lib64/python3.8/email/__init__.py000064400000003346152344010500012436 0ustar00# Copyright (C) 2001-2007 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org """A package for parsing, handling, and generating email messages.""" __all__ = [ 'base64mime', 'charset', 'encoders', 'errors', 'feedparser', 'generator', 'header', 'iterators', 'message', 'message_from_file', 'message_from_binary_file', 'message_from_string', 'message_from_bytes', 'mime', 'parser', 'quoprimime', 'utils', ] # Some convenience routines. Don't import Parser and Message as side-effects # of importing email since those cascadingly import most of the rest of the # email package. def message_from_string(s, *args, **kws): """Parse a string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parsestr(s) def message_from_bytes(s, *args, **kws): """Parse a bytes string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parsebytes(s) def message_from_file(fp, *args, **kws): """Read a file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parse(fp) def message_from_binary_file(fp, *args, **kws): """Read a binary file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parse(fp) lib64/python3.8/unittest/__init__.py000064400000006303152344013230013225 0ustar00""" Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's Smalltalk testing framework (used with permission). This module contains the core framework classes that form the basis of specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results (TextTestRunner). Simple usage: import unittest class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): # test method names begin with 'test' self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main() Further information is available in the bundled documentation, and from http://docs.python.org/library/unittest.html Copyright (c) 1999-2003 Steve Purcell Copyright (c) 2003-2010 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __all__ = ['TestResult', 'TestCase', 'IsolatedAsyncioTestCase', 'TestSuite', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', 'registerResult', 'removeResult', 'removeHandler', 'addModuleCleanup'] # Expose obsolete functions for backwards compatibility __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) __unittest = True from .result import TestResult from .async_case import IsolatedAsyncioTestCase from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip, skipIf, skipUnless, expectedFailure) from .suite import BaseTestSuite, TestSuite from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, findTestCases) from .main import TestProgram, main from .runner import TextTestRunner, TextTestResult from .signals import installHandler, registerResult, removeResult, removeHandler # deprecated _TextTestResult = TextTestResult # There are no tests here, so don't try to run anything discovered from # introspecting the symbols (e.g. FunctionTestCase). Instead, all our # tests come from within unittest.test. def load_tests(loader, tests, pattern): import os.path # top level directory cached on loader instance this_dir = os.path.dirname(__file__) return loader.discover(start_dir=this_dir, pattern=pattern) usr/lib64/python3.8/dbm/__init__.py000064400000013317152344053450012734 0ustar00"""Generic interface to all dbm clones. Use import dbm d = dbm.open(file, 'w', 0o666) The returned object is a dbm.gnu, dbm.ndbm or dbm.dumb object, dependent on the type of database being opened (determined by the whichdb function) in the case of an existing dbm. If the dbm does not exist and the create or new flag ('c' or 'n') was specified, the dbm type will be determined by the availability of the modules (tested in the above order). It has the following interface (key and data are strings): d[key] = data # store data at key (may override data at # existing key) data = d[key] # retrieve data at key (raise KeyError if no # such key) del d[key] # delete data stored at key (raises KeyError # if no such key) flag = key in d # true if the key exists list = d.keys() # return a list of all existing keys (slow!) Future versions may change the order in which implementations are tested for existence, and add interfaces to other dbm-like implementations. """ __all__ = ['open', 'whichdb', 'error'] import io import os import struct import sys class error(Exception): pass _names = ['dbm.gnu', 'dbm.ndbm', 'dbm.dumb'] _defaultmod = None _modules = {} error = (error, OSError) try: from dbm import ndbm except ImportError: ndbm = None def open(file, flag='r', mode=0o666): """Open or create database at path given by *file*. Optional argument *flag* can be 'r' (default) for read-only access, 'w' for read-write access of an existing database, 'c' for read-write access to a new or existing database, and 'n' for read-write access to a new database. Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it only if it doesn't exist; and 'n' always creates a new database. """ global _defaultmod if _defaultmod is None: for name in _names: try: mod = __import__(name, fromlist=['open']) except ImportError: continue if not _defaultmod: _defaultmod = mod _modules[name] = mod if not _defaultmod: raise ImportError("no dbm clone found; tried %s" % _names) # guess the type of an existing database, if not creating a new one result = whichdb(file) if 'n' not in flag else None if result is None: # db doesn't exist or 'n' flag was specified to create a new db if 'c' in flag or 'n' in flag: # file doesn't exist and the new flag was used so use default type mod = _defaultmod else: raise error[0]("db file doesn't exist; " "use 'c' or 'n' flag to create a new db") elif result == "": # db type cannot be determined raise error[0]("db type could not be determined") elif result not in _modules: raise error[0]("db type is {0}, but the module is not " "available".format(result)) else: mod = _modules[result] return mod.open(file, flag, mode) def whichdb(filename): """Guess which db package to use to open a db file. Return values: - None if the database file can't be read; - empty string if the file can be read but can't be recognized - the name of the dbm submodule (e.g. "ndbm" or "gnu") if recognized. Importing the given module may still fail, and opening the database using that module may still fail. """ # Check for ndbm first -- this has a .pag and a .dir file try: f = io.open(filename + ".pag", "rb") f.close() f = io.open(filename + ".dir", "rb") f.close() return "dbm.ndbm" except OSError: # some dbm emulations based on Berkeley DB generate a .db file # some do not, but they should be caught by the bsd checks try: f = io.open(filename + ".db", "rb") f.close() # guarantee we can actually open the file using dbm # kind of overkill, but since we are dealing with emulations # it seems like a prudent step if ndbm is not None: d = ndbm.open(filename) d.close() return "dbm.ndbm" except OSError: pass # Check for dumbdbm next -- this has a .dir and a .dat file try: # First check for presence of files os.stat(filename + ".dat") size = os.stat(filename + ".dir").st_size # dumbdbm files with no keys are empty if size == 0: return "dbm.dumb" f = io.open(filename + ".dir", "rb") try: if f.read(1) in (b"'", b'"'): return "dbm.dumb" finally: f.close() except OSError: pass # See if the file exists, return None if not try: f = io.open(filename, "rb") except OSError: return None with f: # Read the start of the file -- the magic number s16 = f.read(16) s = s16[0:4] # Return "" if not at least 4 bytes if len(s) != 4: return "" # Convert to 4-byte int in native byte order -- return "" if impossible try: (magic,) = struct.unpack("=l", s) except struct.error: return "" # Check for GNU dbm if magic in (0x13579ace, 0x13579acd, 0x13579acf): return "dbm.gnu" # Later versions of Berkeley db hash file have a 12-byte pad in # front of the file type try: (magic,) = struct.unpack("=l", s16[-4:]) except struct.error: return "" # Unknown return "" if __name__ == "__main__": for filename in sys.argv[1:]: print(whichdb(filename) or "UNKNOWN", filename) lib64/python3.12/unittest/__init__.py000064400000006637152344054010013313 0ustar00""" Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's Smalltalk testing framework (used with permission). This module contains the core framework classes that form the basis of specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results (TextTestRunner). Simple usage: import unittest class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): # test method names begin with 'test' self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main() Further information is available in the bundled documentation, and from http://docs.python.org/library/unittest.html Copyright (c) 1999-2003 Steve Purcell Copyright (c) 2003-2010 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __all__ = ['TestResult', 'TestCase', 'IsolatedAsyncioTestCase', 'TestSuite', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', 'registerResult', 'removeResult', 'removeHandler', 'addModuleCleanup', 'doModuleCleanups', 'enterModuleContext'] # Expose obsolete functions for backwards compatibility # bpo-5846: Deprecated in Python 3.11, scheduled for removal in Python 3.13. __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) __unittest = True from .result import TestResult from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip, skipIf, skipUnless, expectedFailure, doModuleCleanups, enterModuleContext) from .suite import BaseTestSuite, TestSuite from .loader import TestLoader, defaultTestLoader from .main import TestProgram, main from .runner import TextTestRunner, TextTestResult from .signals import installHandler, registerResult, removeResult, removeHandler # IsolatedAsyncioTestCase will be imported lazily. from .loader import makeSuite, getTestCaseNames, findTestCases # Lazy import of IsolatedAsyncioTestCase from .async_case # It imports asyncio, which is relatively heavy, but most tests # do not need it. def __dir__(): return globals().keys() | {'IsolatedAsyncioTestCase'} def __getattr__(name): if name == 'IsolatedAsyncioTestCase': global IsolatedAsyncioTestCase from .async_case import IsolatedAsyncioTestCase return IsolatedAsyncioTestCase raise AttributeError(f"module {__name__!r} has no attribute {name!r}") usr/lib64/python3.8/ctypes/__init__.py000064400000042763152344054360013511 0ustar00"""create and manipulate C data types in Python""" import os as _os, sys as _sys __version__ = "1.1.0" from _ctypes import Union, Structure, Array from _ctypes import _Pointer from _ctypes import CFuncPtr as _CFuncPtr from _ctypes import __version__ as _ctypes_version from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import ArgumentError from struct import calcsize as _calcsize if __version__ != _ctypes_version: raise Exception("Version number mismatch", __version__, _ctypes_version) if _os.name == "nt": from _ctypes import FormatError DEFAULT_MODE = RTLD_LOCAL if _os.name == "posix" and _sys.platform == "darwin": # On OS X 10.3, we use RTLD_GLOBAL as default mode # because RTLD_LOCAL does not work at least on some # libraries. OS X 10.3 is Darwin 7, so we check for # that. if int(_os.uname().release.split('.')[0]) < 8: DEFAULT_MODE = RTLD_GLOBAL from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \ FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \ FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR # WINOLEAPI -> HRESULT # WINOLEAPI_(type) # # STDMETHODCALLTYPE # # STDMETHOD(name) # STDMETHOD_(type, name) # # STDAPICALLTYPE def create_string_buffer(init, size=None): """create_string_buffer(aBytes) -> character array create_string_buffer(anInteger) -> character array create_string_buffer(aBytes, anInteger) -> character array """ if isinstance(init, bytes): if size is None: size = len(init)+1 _sys.audit("ctypes.create_string_buffer", init, size) buftype = c_char * size buf = buftype() buf.value = init return buf elif isinstance(init, int): _sys.audit("ctypes.create_string_buffer", None, init) buftype = c_char * init buf = buftype() return buf raise TypeError(init) def c_buffer(init, size=None): ## "deprecated, use create_string_buffer instead" ## import warnings ## warnings.warn("c_buffer is deprecated, use create_string_buffer instead", ## DeprecationWarning, stacklevel=2) return create_string_buffer(init, size) _c_functype_cache = {} def CFUNCTYPE(restype, *argtypes, **kw): """CFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) -> function prototype. restype: the result type argtypes: a sequence specifying the argument types The function prototype can be called in different ways to create a callable object: prototype(integer address) -> foreign function prototype(callable) -> create and return a C callable function from callable prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal prototype((function name, dll object)[, paramflags]) -> foreign function exported by name """ flags = _FUNCFLAG_CDECL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _c_functype_cache[(restype, argtypes, flags)] except KeyError: class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _c_functype_cache[(restype, argtypes, flags)] = CFunctionType return CFunctionType if _os.name == "nt": from _ctypes import LoadLibrary as _dlopen from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL _win_functype_cache = {} def WINFUNCTYPE(restype, *argtypes, **kw): # docstring set later (very similar to CFUNCTYPE.__doc__) flags = _FUNCFLAG_STDCALL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _win_functype_cache[(restype, argtypes, flags)] except KeyError: class WinFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType return WinFunctionType if WINFUNCTYPE.__doc__: WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE") elif _os.name == "posix": from _ctypes import dlopen as _dlopen from _ctypes import sizeof, byref, addressof, alignment, resize from _ctypes import get_errno, set_errno from _ctypes import _SimpleCData def _check_size(typ, typecode=None): # Check if sizeof(ctypes_type) against struct.calcsize. This # should protect somewhat against a misconfigured libffi. from struct import calcsize if typecode is None: # Most _type_ codes are the same as used in struct typecode = typ._type_ actual, required = sizeof(typ), calcsize(typecode) if actual != required: raise SystemError("sizeof(%s) wrong: %d instead of %d" % \ (typ, actual, required)) class py_object(_SimpleCData): _type_ = "O" def __repr__(self): try: return super().__repr__() except ValueError: return "%s()" % type(self).__name__ _check_size(py_object, "P") class c_short(_SimpleCData): _type_ = "h" _check_size(c_short) class c_ushort(_SimpleCData): _type_ = "H" _check_size(c_ushort) class c_long(_SimpleCData): _type_ = "l" _check_size(c_long) class c_ulong(_SimpleCData): _type_ = "L" _check_size(c_ulong) if _calcsize("i") == _calcsize("l"): # if int and long have the same size, make c_int an alias for c_long c_int = c_long c_uint = c_ulong else: class c_int(_SimpleCData): _type_ = "i" _check_size(c_int) class c_uint(_SimpleCData): _type_ = "I" _check_size(c_uint) class c_float(_SimpleCData): _type_ = "f" _check_size(c_float) class c_double(_SimpleCData): _type_ = "d" _check_size(c_double) class c_longdouble(_SimpleCData): _type_ = "g" if sizeof(c_longdouble) == sizeof(c_double): c_longdouble = c_double if _calcsize("l") == _calcsize("q"): # if long and long long have the same size, make c_longlong an alias for c_long c_longlong = c_long c_ulonglong = c_ulong else: class c_longlong(_SimpleCData): _type_ = "q" _check_size(c_longlong) class c_ulonglong(_SimpleCData): _type_ = "Q" ## def from_param(cls, val): ## return ('d', float(val), val) ## from_param = classmethod(from_param) _check_size(c_ulonglong) class c_ubyte(_SimpleCData): _type_ = "B" c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte # backward compatibility: ##c_uchar = c_ubyte _check_size(c_ubyte) class c_byte(_SimpleCData): _type_ = "b" c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte _check_size(c_byte) class c_char(_SimpleCData): _type_ = "c" c_char.__ctype_le__ = c_char.__ctype_be__ = c_char _check_size(c_char) class c_char_p(_SimpleCData): _type_ = "z" def __repr__(self): return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) _check_size(c_char_p, "P") class c_void_p(_SimpleCData): _type_ = "P" c_voidp = c_void_p # backwards compatibility (to a bug) _check_size(c_void_p) class c_bool(_SimpleCData): _type_ = "?" from _ctypes import POINTER, pointer, _pointer_type_cache class c_wchar_p(_SimpleCData): _type_ = "Z" def __repr__(self): return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) class c_wchar(_SimpleCData): _type_ = "u" def _reset_cache(): _pointer_type_cache.clear() _c_functype_cache.clear() if _os.name == "nt": _win_functype_cache.clear() # _SimpleCData.c_wchar_p_from_param POINTER(c_wchar).from_param = c_wchar_p.from_param # _SimpleCData.c_char_p_from_param POINTER(c_char).from_param = c_char_p.from_param _pointer_type_cache[None] = c_void_p def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array create_unicode_buffer(aString, anInteger) -> character array """ if isinstance(init, str): if size is None: if sizeof(c_wchar) == 2: # UTF-16 requires a surrogate pair (2 wchar_t) for non-BMP # characters (outside [U+0000; U+FFFF] range). +1 for trailing # NUL character. size = sum(2 if ord(c) > 0xFFFF else 1 for c in init) + 1 else: # 32-bit wchar_t (1 wchar_t per Unicode character). +1 for # trailing NUL character. size = len(init) + 1 _sys.audit("ctypes.create_unicode_buffer", init, size) buftype = c_wchar * size buf = buftype() buf.value = init return buf elif isinstance(init, int): _sys.audit("ctypes.create_unicode_buffer", None, init) buftype = c_wchar * init buf = buftype() return buf raise TypeError(init) # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: raise RuntimeError("This type already exists in the cache") if id(pointer) not in _pointer_type_cache: raise RuntimeError("What's this???") pointer.set_type(cls) _pointer_type_cache[cls] = pointer del _pointer_type_cache[id(pointer)] # XXX Deprecated def ARRAY(typ, len): return typ * len ################################################################ class CDLL(object): """An instance of this class represents a loaded dll/shared library, exporting functions using the standard C calling convention (named 'cdecl' on Windows). The exported functions can be accessed as attributes, or by indexing with the function name. Examples: .qsort -> callable object ['qsort'] -> callable object Calling the functions releases the Python GIL during the call and reacquires it afterwards. """ _func_flags_ = _FUNCFLAG_CDECL _func_restype_ = c_int # default values for repr _name = '' _handle = 0 _FuncPtr = None def __init__(self, name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None): self._name = name flags = self._func_flags_ if use_errno: flags |= _FUNCFLAG_USE_ERRNO if use_last_error: flags |= _FUNCFLAG_USE_LASTERROR if _sys.platform.startswith("aix"): """When the name contains ".a(" and ends with ")", e.g., "libFOO.a(libFOO.so)" - this is taken to be an archive(member) syntax for dlopen(), and the mode is adjusted. Otherwise, name is presented to dlopen() as a file argument. """ if name and name.endswith(")") and ".a(" in name: mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW ) if _os.name == "nt": if winmode is not None: mode = winmode else: import nt mode = nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS if '/' in name or '\\' in name: self._name = nt._getfullpathname(self._name) mode |= nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR class _FuncPtr(_CFuncPtr): _flags_ = flags _restype_ = self._func_restype_ self._FuncPtr = _FuncPtr if handle is None: self._handle = _dlopen(self._name, mode) else: self._handle = handle def __repr__(self): return "<%s '%s', handle %x at %#x>" % \ (self.__class__.__name__, self._name, (self._handle & (_sys.maxsize*2 + 1)), id(self) & (_sys.maxsize*2 + 1)) def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): raise AttributeError(name) func = self.__getitem__(name) setattr(self, name, func) return func def __getitem__(self, name_or_ordinal): func = self._FuncPtr((name_or_ordinal, self)) if not isinstance(name_or_ordinal, int): func.__name__ = name_or_ordinal return func class PyDLL(CDLL): """This class represents the Python library itself. It allows accessing Python API functions. The GIL is not released, and Python exceptions are handled correctly. """ _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI if _os.name == "nt": class WinDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention. """ _func_flags_ = _FUNCFLAG_STDCALL # XXX Hm, what about HRESULT as normal parameter? # Mustn't it derive from c_long then? from _ctypes import _check_HRESULT, _SimpleCData class HRESULT(_SimpleCData): _type_ = "l" # _check_retval_ is called with the function's result when it # is used as restype. It checks for the FAILED bit, and # raises an OSError if it is set. # # The _check_retval_ method is implemented in C, so that the # method definition itself is not included in the traceback # when it raises an error - that is what we want (and Python # doesn't have a way to raise an exception in the caller's # frame). _check_retval_ = _check_HRESULT class OleDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention, and returning HRESULT. HRESULT error values are automatically raised as OSError exceptions. """ _func_flags_ = _FUNCFLAG_STDCALL _func_restype_ = HRESULT class LibraryLoader(object): def __init__(self, dlltype): self._dlltype = dlltype def __getattr__(self, name): if name[0] == '_': raise AttributeError(name) dll = self._dlltype(name) setattr(self, name, dll) return dll def __getitem__(self, name): return getattr(self, name) def LoadLibrary(self, name): return self._dlltype(name) cdll = LibraryLoader(CDLL) pydll = LibraryLoader(PyDLL) if _os.name == "nt": pythonapi = PyDLL("python dll", None, _sys.dllhandle) elif _sys.platform == "cygwin": pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) else: pythonapi = PyDLL(None) if _os.name == "nt": windll = LibraryLoader(WinDLL) oledll = LibraryLoader(OleDLL) GetLastError = windll.kernel32.GetLastError from _ctypes import get_last_error, set_last_error def WinError(code=None, descr=None): if code is None: code = GetLastError() if descr is None: descr = FormatError(code).strip() return OSError(None, descr, None, code) if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int elif sizeof(c_ulong) == sizeof(c_void_p): c_size_t = c_ulong c_ssize_t = c_long elif sizeof(c_ulonglong) == sizeof(c_void_p): c_size_t = c_ulonglong c_ssize_t = c_longlong # functions from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr ## void *memmove(void *, const void *, size_t); memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) ## void *memset(void *, int, size_t) memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) def PYFUNCTYPE(restype, *argtypes): class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI return CFunctionType _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) def cast(obj, typ): return _cast(obj, obj, typ) _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) def string_at(ptr, size=-1): """string_at(addr[, size]) -> string Return the string at addr.""" return _string_at(ptr, size) try: from _ctypes import _wstring_at_addr except ImportError: pass else: _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) def wstring_at(ptr, size=-1): """wstring_at(addr[, size]) -> string Return the string at addr.""" return _wstring_at(ptr, size) if _os.name == "nt": # COM stuff def DllGetClassObject(rclsid, riid, ppv): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return -2147221231 # CLASS_E_CLASSNOTAVAILABLE else: return ccom.DllGetClassObject(rclsid, riid, ppv) def DllCanUnloadNow(): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return 0 # S_OK return ccom.DllCanUnloadNow() from ctypes._endian import BigEndianStructure, LittleEndianStructure # Fill in specifically-sized types c_int8 = c_byte c_uint8 = c_ubyte for kind in [c_short, c_int, c_long, c_longlong]: if sizeof(kind) == 2: c_int16 = kind elif sizeof(kind) == 4: c_int32 = kind elif sizeof(kind) == 8: c_int64 = kind for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]: if sizeof(kind) == 2: c_uint16 = kind elif sizeof(kind) == 4: c_uint32 = kind elif sizeof(kind) == 8: c_uint64 = kind del(kind) _reset_cache() lib64/python3.6/email/__init__.py000064400000003346152344143670012453 0ustar00# Copyright (C) 2001-2007 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org """A package for parsing, handling, and generating email messages.""" __all__ = [ 'base64mime', 'charset', 'encoders', 'errors', 'feedparser', 'generator', 'header', 'iterators', 'message', 'message_from_file', 'message_from_binary_file', 'message_from_string', 'message_from_bytes', 'mime', 'parser', 'quoprimime', 'utils', ] # Some convenience routines. Don't import Parser and Message as side-effects # of importing email since those cascadingly import most of the rest of the # email package. def message_from_string(s, *args, **kws): """Parse a string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parsestr(s) def message_from_bytes(s, *args, **kws): """Parse a bytes string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parsebytes(s) def message_from_file(fp, *args, **kws): """Read a file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parse(fp) def message_from_binary_file(fp, *args, **kws): """Read a binary file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parse(fp) lib64/python3.8/dbm/__init__.py000064400000013317152344256160012126 0ustar00"""Generic interface to all dbm clones. Use import dbm d = dbm.open(file, 'w', 0o666) The returned object is a dbm.gnu, dbm.ndbm or dbm.dumb object, dependent on the type of database being opened (determined by the whichdb function) in the case of an existing dbm. If the dbm does not exist and the create or new flag ('c' or 'n') was specified, the dbm type will be determined by the availability of the modules (tested in the above order). It has the following interface (key and data are strings): d[key] = data # store data at key (may override data at # existing key) data = d[key] # retrieve data at key (raise KeyError if no # such key) del d[key] # delete data stored at key (raises KeyError # if no such key) flag = key in d # true if the key exists list = d.keys() # return a list of all existing keys (slow!) Future versions may change the order in which implementations are tested for existence, and add interfaces to other dbm-like implementations. """ __all__ = ['open', 'whichdb', 'error'] import io import os import struct import sys class error(Exception): pass _names = ['dbm.gnu', 'dbm.ndbm', 'dbm.dumb'] _defaultmod = None _modules = {} error = (error, OSError) try: from dbm import ndbm except ImportError: ndbm = None def open(file, flag='r', mode=0o666): """Open or create database at path given by *file*. Optional argument *flag* can be 'r' (default) for read-only access, 'w' for read-write access of an existing database, 'c' for read-write access to a new or existing database, and 'n' for read-write access to a new database. Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it only if it doesn't exist; and 'n' always creates a new database. """ global _defaultmod if _defaultmod is None: for name in _names: try: mod = __import__(name, fromlist=['open']) except ImportError: continue if not _defaultmod: _defaultmod = mod _modules[name] = mod if not _defaultmod: raise ImportError("no dbm clone found; tried %s" % _names) # guess the type of an existing database, if not creating a new one result = whichdb(file) if 'n' not in flag else None if result is None: # db doesn't exist or 'n' flag was specified to create a new db if 'c' in flag or 'n' in flag: # file doesn't exist and the new flag was used so use default type mod = _defaultmod else: raise error[0]("db file doesn't exist; " "use 'c' or 'n' flag to create a new db") elif result == "": # db type cannot be determined raise error[0]("db type could not be determined") elif result not in _modules: raise error[0]("db type is {0}, but the module is not " "available".format(result)) else: mod = _modules[result] return mod.open(file, flag, mode) def whichdb(filename): """Guess which db package to use to open a db file. Return values: - None if the database file can't be read; - empty string if the file can be read but can't be recognized - the name of the dbm submodule (e.g. "ndbm" or "gnu") if recognized. Importing the given module may still fail, and opening the database using that module may still fail. """ # Check for ndbm first -- this has a .pag and a .dir file try: f = io.open(filename + ".pag", "rb") f.close() f = io.open(filename + ".dir", "rb") f.close() return "dbm.ndbm" except OSError: # some dbm emulations based on Berkeley DB generate a .db file # some do not, but they should be caught by the bsd checks try: f = io.open(filename + ".db", "rb") f.close() # guarantee we can actually open the file using dbm # kind of overkill, but since we are dealing with emulations # it seems like a prudent step if ndbm is not None: d = ndbm.open(filename) d.close() return "dbm.ndbm" except OSError: pass # Check for dumbdbm next -- this has a .dir and a .dat file try: # First check for presence of files os.stat(filename + ".dat") size = os.stat(filename + ".dir").st_size # dumbdbm files with no keys are empty if size == 0: return "dbm.dumb" f = io.open(filename + ".dir", "rb") try: if f.read(1) in (b"'", b'"'): return "dbm.dumb" finally: f.close() except OSError: pass # See if the file exists, return None if not try: f = io.open(filename, "rb") except OSError: return None with f: # Read the start of the file -- the magic number s16 = f.read(16) s = s16[0:4] # Return "" if not at least 4 bytes if len(s) != 4: return "" # Convert to 4-byte int in native byte order -- return "" if impossible try: (magic,) = struct.unpack("=l", s) except struct.error: return "" # Check for GNU dbm if magic in (0x13579ace, 0x13579acd, 0x13579acf): return "dbm.gnu" # Later versions of Berkeley db hash file have a 12-byte pad in # front of the file type try: (magic,) = struct.unpack("=l", s16[-4:]) except struct.error: return "" # Unknown return "" if __name__ == "__main__": for filename in sys.argv[1:]: print(whichdb(filename) or "UNKNOWN", filename) lib64/python2.7/pydoc_data/__init__.py000064400000000000152344307450013451 0ustar00usr/lib64/python3.8/lib2to3/__init__.py000064400000000007152344307510013437 0ustar00#empty lib64/python3.12/lib2to3/pgen2/__init__.py000064400000000217152344307750013725 0ustar00# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """The pgen2 package.""" usr/lib64/python3.6/html/__init__.py000064400000011224152344311150013121 0ustar00""" General functions for HTML manipulation. """ import re as _re from html.entities import html5 as _html5 __all__ = ['escape', 'unescape'] def escape(s, quote=True): """ Replace special characters "&", "<" and ">" to HTML-safe sequences. If the optional flag quote is true (the default), the quotation mark characters, both double quote (") and single quote (') characters are also translated. """ s = s.replace("&", "&") # Must be done first! s = s.replace("<", "<") s = s.replace(">", ">") if quote: s = s.replace('"', """) s = s.replace('\'', "'") return s # see http://www.w3.org/TR/html5/syntax.html#tokenizing-character-references _invalid_charrefs = { 0x00: '\ufffd', # REPLACEMENT CHARACTER 0x0d: '\r', # CARRIAGE RETURN 0x80: '\u20ac', # EURO SIGN 0x81: '\x81', # 0x82: '\u201a', # SINGLE LOW-9 QUOTATION MARK 0x83: '\u0192', # LATIN SMALL LETTER F WITH HOOK 0x84: '\u201e', # DOUBLE LOW-9 QUOTATION MARK 0x85: '\u2026', # HORIZONTAL ELLIPSIS 0x86: '\u2020', # DAGGER 0x87: '\u2021', # DOUBLE DAGGER 0x88: '\u02c6', # MODIFIER LETTER CIRCUMFLEX ACCENT 0x89: '\u2030', # PER MILLE SIGN 0x8a: '\u0160', # LATIN CAPITAL LETTER S WITH CARON 0x8b: '\u2039', # SINGLE LEFT-POINTING ANGLE QUOTATION MARK 0x8c: '\u0152', # LATIN CAPITAL LIGATURE OE 0x8d: '\x8d', # 0x8e: '\u017d', # LATIN CAPITAL LETTER Z WITH CARON 0x8f: '\x8f', # 0x90: '\x90', # 0x91: '\u2018', # LEFT SINGLE QUOTATION MARK 0x92: '\u2019', # RIGHT SINGLE QUOTATION MARK 0x93: '\u201c', # LEFT DOUBLE QUOTATION MARK 0x94: '\u201d', # RIGHT DOUBLE QUOTATION MARK 0x95: '\u2022', # BULLET 0x96: '\u2013', # EN DASH 0x97: '\u2014', # EM DASH 0x98: '\u02dc', # SMALL TILDE 0x99: '\u2122', # TRADE MARK SIGN 0x9a: '\u0161', # LATIN SMALL LETTER S WITH CARON 0x9b: '\u203a', # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 0x9c: '\u0153', # LATIN SMALL LIGATURE OE 0x9d: '\x9d', # 0x9e: '\u017e', # LATIN SMALL LETTER Z WITH CARON 0x9f: '\u0178', # LATIN CAPITAL LETTER Y WITH DIAERESIS } _invalid_codepoints = { # 0x0001 to 0x0008 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, # 0x000E to 0x001F 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, # 0x007F to 0x009F 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, # 0xFDD0 to 0xFDEF 0xfdd0, 0xfdd1, 0xfdd2, 0xfdd3, 0xfdd4, 0xfdd5, 0xfdd6, 0xfdd7, 0xfdd8, 0xfdd9, 0xfdda, 0xfddb, 0xfddc, 0xfddd, 0xfdde, 0xfddf, 0xfde0, 0xfde1, 0xfde2, 0xfde3, 0xfde4, 0xfde5, 0xfde6, 0xfde7, 0xfde8, 0xfde9, 0xfdea, 0xfdeb, 0xfdec, 0xfded, 0xfdee, 0xfdef, # others 0xb, 0xfffe, 0xffff, 0x1fffe, 0x1ffff, 0x2fffe, 0x2ffff, 0x3fffe, 0x3ffff, 0x4fffe, 0x4ffff, 0x5fffe, 0x5ffff, 0x6fffe, 0x6ffff, 0x7fffe, 0x7ffff, 0x8fffe, 0x8ffff, 0x9fffe, 0x9ffff, 0xafffe, 0xaffff, 0xbfffe, 0xbffff, 0xcfffe, 0xcffff, 0xdfffe, 0xdffff, 0xefffe, 0xeffff, 0xffffe, 0xfffff, 0x10fffe, 0x10ffff } def _replace_charref(s): s = s.group(1) if s[0] == '#': # numeric charref if s[1] in 'xX': num = int(s[2:].rstrip(';'), 16) else: num = int(s[1:].rstrip(';')) if num in _invalid_charrefs: return _invalid_charrefs[num] if 0xD800 <= num <= 0xDFFF or num > 0x10FFFF: return '\uFFFD' if num in _invalid_codepoints: return '' return chr(num) else: # named charref if s in _html5: return _html5[s] # find the longest matching name (as defined by the standard) for x in range(len(s)-1, 1, -1): if s[:x] in _html5: return _html5[s[:x]] + s[x:] else: return '&' + s _charref = _re.compile(r'&(#[0-9]+;?' r'|#[xX][0-9a-fA-F]+;?' r'|[^\t\n\f <&#;]{1,32};?)') def unescape(s): """ Convert all named and numeric character references (e.g. >, >, &x3e;) in the string s to the corresponding unicode characters. This function uses the rules defined by the HTML 5 standard for both valid and invalid character references, and the list of HTML 5 named character references defined in html.entities.html5. """ if '&' not in s: return s return _charref.sub(_replace_charref, s) usr/lib64/python3.12/ctypes/__init__.py000064400000043442152344436010013553 0ustar00"""create and manipulate C data types in Python""" import os as _os, sys as _sys import types as _types __version__ = "1.1.0" from _ctypes import Union, Structure, Array from _ctypes import _Pointer from _ctypes import CFuncPtr as _CFuncPtr from _ctypes import __version__ as _ctypes_version from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import ArgumentError from _ctypes import SIZEOF_TIME_T from struct import calcsize as _calcsize if __version__ != _ctypes_version: raise Exception("Version number mismatch", __version__, _ctypes_version) if _os.name == "nt": from _ctypes import FormatError DEFAULT_MODE = RTLD_LOCAL if _os.name == "posix" and _sys.platform == "darwin": # On OS X 10.3, we use RTLD_GLOBAL as default mode # because RTLD_LOCAL does not work at least on some # libraries. OS X 10.3 is Darwin 7, so we check for # that. if int(_os.uname().release.split('.')[0]) < 8: DEFAULT_MODE = RTLD_GLOBAL from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \ FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \ FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR # WINOLEAPI -> HRESULT # WINOLEAPI_(type) # # STDMETHODCALLTYPE # # STDMETHOD(name) # STDMETHOD_(type, name) # # STDAPICALLTYPE def create_string_buffer(init, size=None): """create_string_buffer(aBytes) -> character array create_string_buffer(anInteger) -> character array create_string_buffer(aBytes, anInteger) -> character array """ if isinstance(init, bytes): if size is None: size = len(init)+1 _sys.audit("ctypes.create_string_buffer", init, size) buftype = c_char * size buf = buftype() buf.value = init return buf elif isinstance(init, int): _sys.audit("ctypes.create_string_buffer", None, init) buftype = c_char * init buf = buftype() return buf raise TypeError(init) # Alias to create_string_buffer() for backward compatibility c_buffer = create_string_buffer _c_functype_cache = {} def CFUNCTYPE(restype, *argtypes, **kw): """CFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) -> function prototype. restype: the result type argtypes: a sequence specifying the argument types The function prototype can be called in different ways to create a callable object: prototype(integer address) -> foreign function prototype(callable) -> create and return a C callable function from callable prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal prototype((function name, dll object)[, paramflags]) -> foreign function exported by name """ flags = _FUNCFLAG_CDECL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _c_functype_cache[(restype, argtypes, flags)] except KeyError: pass class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _c_functype_cache[(restype, argtypes, flags)] = CFunctionType return CFunctionType if _os.name == "nt": from _ctypes import LoadLibrary as _dlopen from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL _win_functype_cache = {} def WINFUNCTYPE(restype, *argtypes, **kw): # docstring set later (very similar to CFUNCTYPE.__doc__) flags = _FUNCFLAG_STDCALL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _win_functype_cache[(restype, argtypes, flags)] except KeyError: pass class WinFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType return WinFunctionType if WINFUNCTYPE.__doc__: WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE") elif _os.name == "posix": from _ctypes import dlopen as _dlopen from _ctypes import sizeof, byref, addressof, alignment, resize from _ctypes import get_errno, set_errno from _ctypes import _SimpleCData def _check_size(typ, typecode=None): # Check if sizeof(ctypes_type) against struct.calcsize. This # should protect somewhat against a misconfigured libffi. from struct import calcsize if typecode is None: # Most _type_ codes are the same as used in struct typecode = typ._type_ actual, required = sizeof(typ), calcsize(typecode) if actual != required: raise SystemError("sizeof(%s) wrong: %d instead of %d" % \ (typ, actual, required)) class py_object(_SimpleCData): _type_ = "O" def __repr__(self): try: return super().__repr__() except ValueError: return "%s()" % type(self).__name__ _check_size(py_object, "P") class c_short(_SimpleCData): _type_ = "h" _check_size(c_short) class c_ushort(_SimpleCData): _type_ = "H" _check_size(c_ushort) class c_long(_SimpleCData): _type_ = "l" _check_size(c_long) class c_ulong(_SimpleCData): _type_ = "L" _check_size(c_ulong) if _calcsize("i") == _calcsize("l"): # if int and long have the same size, make c_int an alias for c_long c_int = c_long c_uint = c_ulong else: class c_int(_SimpleCData): _type_ = "i" _check_size(c_int) class c_uint(_SimpleCData): _type_ = "I" _check_size(c_uint) class c_float(_SimpleCData): _type_ = "f" _check_size(c_float) class c_double(_SimpleCData): _type_ = "d" _check_size(c_double) class c_longdouble(_SimpleCData): _type_ = "g" if sizeof(c_longdouble) == sizeof(c_double): c_longdouble = c_double if _calcsize("l") == _calcsize("q"): # if long and long long have the same size, make c_longlong an alias for c_long c_longlong = c_long c_ulonglong = c_ulong else: class c_longlong(_SimpleCData): _type_ = "q" _check_size(c_longlong) class c_ulonglong(_SimpleCData): _type_ = "Q" ## def from_param(cls, val): ## return ('d', float(val), val) ## from_param = classmethod(from_param) _check_size(c_ulonglong) class c_ubyte(_SimpleCData): _type_ = "B" c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte # backward compatibility: ##c_uchar = c_ubyte _check_size(c_ubyte) class c_byte(_SimpleCData): _type_ = "b" c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte _check_size(c_byte) class c_char(_SimpleCData): _type_ = "c" c_char.__ctype_le__ = c_char.__ctype_be__ = c_char _check_size(c_char) class c_char_p(_SimpleCData): _type_ = "z" def __repr__(self): return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) _check_size(c_char_p, "P") class c_void_p(_SimpleCData): _type_ = "P" c_voidp = c_void_p # backwards compatibility (to a bug) _check_size(c_void_p) class c_bool(_SimpleCData): _type_ = "?" from _ctypes import POINTER, pointer, _pointer_type_cache class c_wchar_p(_SimpleCData): _type_ = "Z" def __repr__(self): return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) class c_wchar(_SimpleCData): _type_ = "u" def _reset_cache(): _pointer_type_cache.clear() _c_functype_cache.clear() if _os.name == "nt": _win_functype_cache.clear() # _SimpleCData.c_wchar_p_from_param POINTER(c_wchar).from_param = c_wchar_p.from_param # _SimpleCData.c_char_p_from_param POINTER(c_char).from_param = c_char_p.from_param _pointer_type_cache[None] = c_void_p def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array create_unicode_buffer(aString, anInteger) -> character array """ if isinstance(init, str): if size is None: if sizeof(c_wchar) == 2: # UTF-16 requires a surrogate pair (2 wchar_t) for non-BMP # characters (outside [U+0000; U+FFFF] range). +1 for trailing # NUL character. size = sum(2 if ord(c) > 0xFFFF else 1 for c in init) + 1 else: # 32-bit wchar_t (1 wchar_t per Unicode character). +1 for # trailing NUL character. size = len(init) + 1 _sys.audit("ctypes.create_unicode_buffer", init, size) buftype = c_wchar * size buf = buftype() buf.value = init return buf elif isinstance(init, int): _sys.audit("ctypes.create_unicode_buffer", None, init) buftype = c_wchar * init buf = buftype() return buf raise TypeError(init) # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: raise RuntimeError("This type already exists in the cache") if id(pointer) not in _pointer_type_cache: raise RuntimeError("What's this???") pointer.set_type(cls) _pointer_type_cache[cls] = pointer del _pointer_type_cache[id(pointer)] # XXX Deprecated def ARRAY(typ, len): return typ * len ################################################################ class CDLL(object): """An instance of this class represents a loaded dll/shared library, exporting functions using the standard C calling convention (named 'cdecl' on Windows). The exported functions can be accessed as attributes, or by indexing with the function name. Examples: .qsort -> callable object ['qsort'] -> callable object Calling the functions releases the Python GIL during the call and reacquires it afterwards. """ _func_flags_ = _FUNCFLAG_CDECL _func_restype_ = c_int # default values for repr _name = '' _handle = 0 _FuncPtr = None def __init__(self, name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None): if name: name = _os.fspath(name) self._name = name flags = self._func_flags_ if use_errno: flags |= _FUNCFLAG_USE_ERRNO if use_last_error: flags |= _FUNCFLAG_USE_LASTERROR if _sys.platform.startswith("aix"): """When the name contains ".a(" and ends with ")", e.g., "libFOO.a(libFOO.so)" - this is taken to be an archive(member) syntax for dlopen(), and the mode is adjusted. Otherwise, name is presented to dlopen() as a file argument. """ if name and name.endswith(")") and ".a(" in name: mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW ) if _os.name == "nt": if winmode is not None: mode = winmode else: import nt mode = nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS if '/' in name or '\\' in name: self._name = nt._getfullpathname(self._name) mode |= nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR class _FuncPtr(_CFuncPtr): _flags_ = flags _restype_ = self._func_restype_ self._FuncPtr = _FuncPtr if handle is None: self._handle = _dlopen(self._name, mode) else: self._handle = handle def __repr__(self): return "<%s '%s', handle %x at %#x>" % \ (self.__class__.__name__, self._name, (self._handle & (_sys.maxsize*2 + 1)), id(self) & (_sys.maxsize*2 + 1)) def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): raise AttributeError(name) func = self.__getitem__(name) setattr(self, name, func) return func def __getitem__(self, name_or_ordinal): func = self._FuncPtr((name_or_ordinal, self)) if not isinstance(name_or_ordinal, int): func.__name__ = name_or_ordinal return func class PyDLL(CDLL): """This class represents the Python library itself. It allows accessing Python API functions. The GIL is not released, and Python exceptions are handled correctly. """ _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI if _os.name == "nt": class WinDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention. """ _func_flags_ = _FUNCFLAG_STDCALL # XXX Hm, what about HRESULT as normal parameter? # Mustn't it derive from c_long then? from _ctypes import _check_HRESULT, _SimpleCData class HRESULT(_SimpleCData): _type_ = "l" # _check_retval_ is called with the function's result when it # is used as restype. It checks for the FAILED bit, and # raises an OSError if it is set. # # The _check_retval_ method is implemented in C, so that the # method definition itself is not included in the traceback # when it raises an error - that is what we want (and Python # doesn't have a way to raise an exception in the caller's # frame). _check_retval_ = _check_HRESULT class OleDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention, and returning HRESULT. HRESULT error values are automatically raised as OSError exceptions. """ _func_flags_ = _FUNCFLAG_STDCALL _func_restype_ = HRESULT class LibraryLoader(object): def __init__(self, dlltype): self._dlltype = dlltype def __getattr__(self, name): if name[0] == '_': raise AttributeError(name) try: dll = self._dlltype(name) except OSError: raise AttributeError(name) setattr(self, name, dll) return dll def __getitem__(self, name): return getattr(self, name) def LoadLibrary(self, name): return self._dlltype(name) __class_getitem__ = classmethod(_types.GenericAlias) cdll = LibraryLoader(CDLL) pydll = LibraryLoader(PyDLL) if _os.name == "nt": pythonapi = PyDLL("python dll", None, _sys.dllhandle) elif _sys.platform == "cygwin": pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) else: pythonapi = PyDLL(None) if _os.name == "nt": windll = LibraryLoader(WinDLL) oledll = LibraryLoader(OleDLL) GetLastError = windll.kernel32.GetLastError from _ctypes import get_last_error, set_last_error def WinError(code=None, descr=None): if code is None: code = GetLastError() if descr is None: descr = FormatError(code).strip() return OSError(None, descr, None, code) if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int elif sizeof(c_ulong) == sizeof(c_void_p): c_size_t = c_ulong c_ssize_t = c_long elif sizeof(c_ulonglong) == sizeof(c_void_p): c_size_t = c_ulonglong c_ssize_t = c_longlong # functions from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr ## void *memmove(void *, const void *, size_t); memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) ## void *memset(void *, int, size_t) memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) def PYFUNCTYPE(restype, *argtypes): class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI return CFunctionType _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) def cast(obj, typ): return _cast(obj, obj, typ) _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) def string_at(ptr, size=-1): """string_at(ptr[, size]) -> string Return the byte string at void *ptr.""" return _string_at(ptr, size) try: from _ctypes import _wstring_at_addr except ImportError: pass else: _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) def wstring_at(ptr, size=-1): """wstring_at(ptr[, size]) -> string Return the wide-character string at void *ptr.""" return _wstring_at(ptr, size) if _os.name == "nt": # COM stuff def DllGetClassObject(rclsid, riid, ppv): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return -2147221231 # CLASS_E_CLASSNOTAVAILABLE else: return ccom.DllGetClassObject(rclsid, riid, ppv) def DllCanUnloadNow(): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return 0 # S_OK return ccom.DllCanUnloadNow() from ctypes._endian import BigEndianStructure, LittleEndianStructure from ctypes._endian import BigEndianUnion, LittleEndianUnion # Fill in specifically-sized types c_int8 = c_byte c_uint8 = c_ubyte for kind in [c_short, c_int, c_long, c_longlong]: if sizeof(kind) == 2: c_int16 = kind elif sizeof(kind) == 4: c_int32 = kind elif sizeof(kind) == 8: c_int64 = kind for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]: if sizeof(kind) == 2: c_uint16 = kind elif sizeof(kind) == 4: c_uint32 = kind elif sizeof(kind) == 8: c_uint64 = kind del(kind) if SIZEOF_TIME_T == 8: c_time_t = c_int64 elif SIZEOF_TIME_T == 4: c_time_t = c_int32 else: raise SystemError(f"Unexpected sizeof(time_t): {SIZEOF_TIME_T=}") _reset_cache() lib64/python3.12/dbm/__init__.py000064400000013372152344452730012203 0ustar00"""Generic interface to all dbm clones. Use import dbm d = dbm.open(file, 'w', 0o666) The returned object is a dbm.gnu, dbm.ndbm or dbm.dumb object, dependent on the type of database being opened (determined by the whichdb function) in the case of an existing dbm. If the dbm does not exist and the create or new flag ('c' or 'n') was specified, the dbm type will be determined by the availability of the modules (tested in the above order). It has the following interface (key and data are strings): d[key] = data # store data at key (may override data at # existing key) data = d[key] # retrieve data at key (raise KeyError if no # such key) del d[key] # delete data stored at key (raises KeyError # if no such key) flag = key in d # true if the key exists list = d.keys() # return a list of all existing keys (slow!) Future versions may change the order in which implementations are tested for existence, and add interfaces to other dbm-like implementations. """ __all__ = ['open', 'whichdb', 'error'] import io import os import struct import sys class error(Exception): pass _names = ['dbm.gnu', 'dbm.ndbm', 'dbm.dumb'] _defaultmod = None _modules = {} error = (error, OSError) try: from dbm import ndbm except ImportError: ndbm = None def open(file, flag='r', mode=0o666): """Open or create database at path given by *file*. Optional argument *flag* can be 'r' (default) for read-only access, 'w' for read-write access of an existing database, 'c' for read-write access to a new or existing database, and 'n' for read-write access to a new database. Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it only if it doesn't exist; and 'n' always creates a new database. """ global _defaultmod if _defaultmod is None: for name in _names: try: mod = __import__(name, fromlist=['open']) except ImportError: continue if not _defaultmod: _defaultmod = mod _modules[name] = mod if not _defaultmod: raise ImportError("no dbm clone found; tried %s" % _names) # guess the type of an existing database, if not creating a new one result = whichdb(file) if 'n' not in flag else None if result is None: # db doesn't exist or 'n' flag was specified to create a new db if 'c' in flag or 'n' in flag: # file doesn't exist and the new flag was used so use default type mod = _defaultmod else: raise error[0]("db file doesn't exist; " "use 'c' or 'n' flag to create a new db") elif result == "": # db type cannot be determined raise error[0]("db type could not be determined") elif result not in _modules: raise error[0]("db type is {0}, but the module is not " "available".format(result)) else: mod = _modules[result] return mod.open(file, flag, mode) def whichdb(filename): """Guess which db package to use to open a db file. Return values: - None if the database file can't be read; - empty string if the file can be read but can't be recognized - the name of the dbm submodule (e.g. "ndbm" or "gnu") if recognized. Importing the given module may still fail, and opening the database using that module may still fail. """ # Check for ndbm first -- this has a .pag and a .dir file filename = os.fsencode(filename) try: f = io.open(filename + b".pag", "rb") f.close() f = io.open(filename + b".dir", "rb") f.close() return "dbm.ndbm" except OSError: # some dbm emulations based on Berkeley DB generate a .db file # some do not, but they should be caught by the bsd checks try: f = io.open(filename + b".db", "rb") f.close() # guarantee we can actually open the file using dbm # kind of overkill, but since we are dealing with emulations # it seems like a prudent step if ndbm is not None: d = ndbm.open(filename) d.close() return "dbm.ndbm" except OSError: pass # Check for dumbdbm next -- this has a .dir and a .dat file try: # First check for presence of files os.stat(filename + b".dat") size = os.stat(filename + b".dir").st_size # dumbdbm files with no keys are empty if size == 0: return "dbm.dumb" f = io.open(filename + b".dir", "rb") try: if f.read(1) in (b"'", b'"'): return "dbm.dumb" finally: f.close() except OSError: pass # See if the file exists, return None if not try: f = io.open(filename, "rb") except OSError: return None with f: # Read the start of the file -- the magic number s16 = f.read(16) s = s16[0:4] # Return "" if not at least 4 bytes if len(s) != 4: return "" # Convert to 4-byte int in native byte order -- return "" if impossible try: (magic,) = struct.unpack("=l", s) except struct.error: return "" # Check for GNU dbm if magic in (0x13579ace, 0x13579acd, 0x13579acf): return "dbm.gnu" # Later versions of Berkeley db hash file have a 12-byte pad in # front of the file type try: (magic,) = struct.unpack("=l", s16[-4:]) except struct.error: return "" # Unknown return "" if __name__ == "__main__": for filename in sys.argv[1:]: print(whichdb(filename) or "UNKNOWN", filename) lib64/python3.6/venv/__init__.py000064400000046561152344454410012345 0ustar00""" Virtual environment (venv) package for Python. Based on PEP 405. Copyright (C) 2011-2014 Vinay Sajip. Licensed to the PSF under a contributor agreement. """ import logging import os import shutil import subprocess import sys import types import shlex logger = logging.getLogger(__name__) class EnvBuilder: """ This class exists to allow virtual environment creation to be customized. The constructor parameters determine the builder's behaviour when called upon to create a virtual environment. By default, the builder makes the system (global) site-packages dir *un*available to the created environment. If invoked using the Python -m option, the default is to use copying on Windows platforms but symlinks elsewhere. If instantiated some other way, the default is to *not* use symlinks. :param system_site_packages: If True, the system (global) site-packages dir is available to created environments. :param clear: If True, delete the contents of the environment directory if it already exists, before environment creation. :param symlinks: If True, attempt to symlink rather than copy files into virtual environment. :param upgrade: If True, upgrade an existing virtual environment. :param with_pip: If True, ensure pip is installed in the virtual environment :param prompt: Alternative terminal prefix for the environment. """ def __init__(self, system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None): self.system_site_packages = system_site_packages self.clear = clear self.symlinks = symlinks self.upgrade = upgrade self.with_pip = with_pip self.prompt = prompt def create(self, env_dir): """ Create a virtual environment in a directory. :param env_dir: The target directory to create an environment in. """ env_dir = os.path.abspath(env_dir) context = self.ensure_directories(env_dir) # See issue 24875. We need system_site_packages to be False # until after pip is installed. true_system_site_packages = self.system_site_packages self.system_site_packages = False self.create_configuration(context) self.setup_python(context) if self.with_pip: self._setup_pip(context) if not self.upgrade: self.setup_scripts(context) self.post_setup(context) if true_system_site_packages: # We had set it to False before, now # restore it and rewrite the configuration self.system_site_packages = True self.create_configuration(context) def clear_directory(self, path): for fn in os.listdir(path): fn = os.path.join(path, fn) if os.path.islink(fn) or os.path.isfile(fn): os.remove(fn) elif os.path.isdir(fn): shutil.rmtree(fn) def ensure_directories(self, env_dir): """ Create the directories for the environment. Returns a context object which holds paths in the environment, for use by subsequent logic. """ def create_if_needed(d): if not os.path.exists(d): os.makedirs(d) elif os.path.islink(d) or os.path.isfile(d): raise ValueError('Unable to create directory %r' % d) if os.path.exists(env_dir) and self.clear: self.clear_directory(env_dir) context = types.SimpleNamespace() context.env_dir = env_dir context.env_name = os.path.split(env_dir)[1] prompt = self.prompt if self.prompt is not None else context.env_name context.prompt = '(%s) ' % prompt create_if_needed(env_dir) env = os.environ if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env: executable = os.environ['__PYVENV_LAUNCHER__'] else: executable = sys.executable dirname, exename = os.path.split(os.path.abspath(executable)) context.executable = executable context.python_dir = dirname context.python_exe = exename if sys.platform == 'win32': binname = 'Scripts' incpath = 'Include' libpath = os.path.join(env_dir, 'Lib', 'site-packages') else: binname = 'bin' incpath = 'include' libpath = os.path.join(env_dir, 'lib', 'python%d.%d' % sys.version_info[:2], 'site-packages') context.inc_path = path = os.path.join(env_dir, incpath) create_if_needed(path) create_if_needed(libpath) # Issue 21197: create lib64 as a symlink to lib on 64-bit non-OS X POSIX if ((sys.maxsize > 2**32) and (os.name == 'posix') and (sys.platform != 'darwin')): link_path = os.path.join(env_dir, 'lib64') if not os.path.exists(link_path): # Issue #21643 os.symlink('lib', link_path) context.bin_path = binpath = os.path.join(env_dir, binname) context.bin_name = binname context.env_exe = os.path.join(binpath, exename) create_if_needed(binpath) return context def create_configuration(self, context): """ Create a configuration file indicating where the environment's Python was copied from, and whether the system site-packages should be made available in the environment. :param context: The information for the environment creation request being processed. """ context.cfg_path = path = os.path.join(context.env_dir, 'pyvenv.cfg') with open(path, 'w', encoding='utf-8') as f: f.write('home = %s\n' % context.python_dir) if self.system_site_packages: incl = 'true' else: incl = 'false' f.write('include-system-site-packages = %s\n' % incl) f.write('version = %d.%d.%d\n' % sys.version_info[:3]) if os.name == 'nt': def include_binary(self, f): if f.endswith(('.pyd', '.dll')): result = True else: result = f.startswith('python') and f.endswith('.exe') return result def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): """ Try symlinking a file, and if that fails, fall back to copying. """ force_copy = not self.symlinks if not force_copy: try: if not os.path.islink(dst): # can't link to itself! if relative_symlinks_ok: assert os.path.dirname(src) == os.path.dirname(dst) os.symlink(os.path.basename(src), dst) else: os.symlink(src, dst) except Exception: # may need to use a more specific exception logger.warning('Unable to symlink %r to %r', src, dst) force_copy = True if force_copy: shutil.copyfile(src, dst) def setup_python(self, context): """ Set up a Python executable in the environment. :param context: The information for the environment creation request being processed. """ binpath = context.bin_path path = context.env_exe copier = self.symlink_or_copy copier(context.executable, path) dirname = context.python_dir if os.name != 'nt': if not os.path.islink(path): os.chmod(path, 0o755) for suffix in ('python', 'python3'): path = os.path.join(binpath, suffix) if not os.path.exists(path): # Issue 18807: make copies if # symlinks are not wanted copier(context.env_exe, path, relative_symlinks_ok=True) if not os.path.islink(path): os.chmod(path, 0o755) else: subdir = 'DLLs' include = self.include_binary files = [f for f in os.listdir(dirname) if include(f)] for f in files: src = os.path.join(dirname, f) dst = os.path.join(binpath, f) if dst != context.env_exe: # already done, above copier(src, dst) dirname = os.path.join(dirname, subdir) if os.path.isdir(dirname): files = [f for f in os.listdir(dirname) if include(f)] for f in files: src = os.path.join(dirname, f) dst = os.path.join(binpath, f) copier(src, dst) # copy init.tcl over for root, dirs, files in os.walk(context.python_dir): if 'init.tcl' in files: tcldir = os.path.basename(root) tcldir = os.path.join(context.env_dir, 'Lib', tcldir) if not os.path.exists(tcldir): os.makedirs(tcldir) src = os.path.join(root, 'init.tcl') dst = os.path.join(tcldir, 'init.tcl') shutil.copyfile(src, dst) break def _setup_pip(self, context): """Installs or upgrades pip in a virtual environment""" # We run ensurepip in isolated mode to avoid side effects from # environment vars, the current directory and anything else # intended for the global Python environment cmd = [context.env_exe, '-Im', 'ensurepip', '--upgrade', '--default-pip'] subprocess.check_output(cmd, stderr=subprocess.STDOUT) def setup_scripts(self, context): """ Set up scripts into the created environment from a directory. This method installs the default scripts into the environment being created. You can prevent the default installation by overriding this method if you really need to, or if you need to specify a different location for the scripts to install. By default, the 'scripts' directory in the venv package is used as the source of scripts to install. """ path = os.path.abspath(os.path.dirname(__file__)) path = os.path.join(path, 'scripts') self.install_scripts(context, path) def post_setup(self, context): """ Hook for post-setup modification of the venv. Subclasses may install additional packages or scripts here, add activation shell scripts, etc. :param context: The information for the environment creation request being processed. """ pass def replace_variables(self, text, context): """ Replace variable placeholders in script text with context-specific variables. Return the text passed in , but with variables replaced. :param text: The text in which to replace placeholder variables. :param context: The information for the environment creation request being processed. """ replacements = { '__VENV_DIR__': context.env_dir, '__VENV_NAME__': context.env_name, '__VENV_PROMPT__': context.prompt, '__VENV_BIN_NAME__': context.bin_name, '__VENV_PYTHON__': context.env_exe, } def quote_ps1(s): """ This should satisfy PowerShell quoting rules [1], unless the quoted string is passed directly to Windows native commands [2]. [1]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules [2]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing#passing-arguments-that-contain-quote-characters """ s = s.replace("'", "''") return f"'{s}'" def quote_bat(s): return s # gh-124651: need to quote the template strings properly quote = shlex.quote script_path = context.script_path if script_path.endswith('.ps1'): quote = quote_ps1 elif script_path.endswith('.bat'): quote = quote_bat else: # fallbacks to POSIX shell compliant quote quote = shlex.quote replacements = {key: quote(s) for key, s in replacements.items()} for key, quoted in replacements.items(): text = text.replace(key, quoted) return text def install_scripts(self, context, path): """ Install scripts into the created environment from a directory. :param context: The information for the environment creation request being processed. :param path: Absolute pathname of a directory containing script. Scripts in the 'common' subdirectory of this directory, and those in the directory named for the platform being run on, are installed in the created environment. Placeholder variables are replaced with environment- specific values. """ binpath = context.bin_path plen = len(path) for root, dirs, files in os.walk(path): if root == path: # at top-level, remove irrelevant dirs for d in dirs[:]: if d not in ('common', os.name): dirs.remove(d) continue # ignore files in top level for f in files: srcfile = os.path.join(root, f) suffix = root[plen:].split(os.sep)[2:] if not suffix: dstdir = binpath else: dstdir = os.path.join(binpath, *suffix) if not os.path.exists(dstdir): os.makedirs(dstdir) dstfile = os.path.join(dstdir, f) with open(srcfile, 'rb') as f: data = f.read() if not srcfile.endswith('.exe'): context.script_path = srcfile try: data = data.decode('utf-8') data = self.replace_variables(data, context) data = data.encode('utf-8') except UnicodeError as e: data = None logger.warning('unable to copy script %r, ' 'may be binary: %s', srcfile, e) if data is not None: with open(dstfile, 'wb') as f: f.write(data) shutil.copymode(srcfile, dstfile) def create(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None): """Create a virtual environment in a directory.""" builder = EnvBuilder(system_site_packages=system_site_packages, clear=clear, symlinks=symlinks, with_pip=with_pip, prompt=prompt) builder.create(env_dir) def main(args=None): compatible = True if sys.version_info < (3, 3): compatible = False elif not hasattr(sys, 'base_prefix'): compatible = False if not compatible: raise ValueError('This script is only for use with Python >= 3.3') else: import argparse parser = argparse.ArgumentParser(prog=__name__, description='Creates virtual Python ' 'environments in one or ' 'more target ' 'directories.', epilog='Once an environment has been ' 'created, you may wish to ' 'activate it, e.g. by ' 'sourcing an activate script ' 'in its bin directory.') parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', help='A directory to create the environment in.') parser.add_argument('--system-site-packages', default=False, action='store_true', dest='system_site', help='Give the virtual environment access to the ' 'system site-packages dir.') if os.name == 'nt': use_symlinks = False else: use_symlinks = True group = parser.add_mutually_exclusive_group() group.add_argument('--symlinks', default=use_symlinks, action='store_true', dest='symlinks', help='Try to use symlinks rather than copies, ' 'when symlinks are not the default for ' 'the platform.') group.add_argument('--copies', default=not use_symlinks, action='store_false', dest='symlinks', help='Try to use copies rather than symlinks, ' 'even when symlinks are the default for ' 'the platform.') parser.add_argument('--clear', default=False, action='store_true', dest='clear', help='Delete the contents of the ' 'environment directory if it ' 'already exists, before ' 'environment creation.') parser.add_argument('--upgrade', default=False, action='store_true', dest='upgrade', help='Upgrade the environment ' 'directory to use this version ' 'of Python, assuming Python ' 'has been upgraded in-place.') parser.add_argument('--without-pip', dest='with_pip', default=True, action='store_false', help='Skips installing or upgrading pip in the ' 'virtual environment (pip is bootstrapped ' 'by default)') parser.add_argument('--prompt', help='Provides an alternative prompt prefix for ' 'this environment.') options = parser.parse_args(args) if options.upgrade and options.clear: raise ValueError('you cannot supply --upgrade and --clear together.') builder = EnvBuilder(system_site_packages=options.system_site, clear=options.clear, symlinks=options.symlinks, upgrade=options.upgrade, with_pip=options.with_pip, prompt=options.prompt) for d in options.dirs: builder.create(d) if __name__ == '__main__': rc = 1 try: main() rc = 0 except Exception as e: print('Error: %s' % e, file=sys.stderr) sys.exit(rc) usr/lib64/python3.12/tomllib/__init__.py000064400000000464152344456200013706 0ustar00# SPDX-License-Identifier: MIT # SPDX-FileCopyrightText: 2021 Taneli Hukkinen # Licensed to PSF under a Contributor Agreement. __all__ = ("loads", "load", "TOMLDecodeError") from ._parser import TOMLDecodeError, load, loads # Pretend this exception was created here. TOMLDecodeError.__module__ = __name__ usr/lib64/python3.8/xml/__init__.py000064400000001055152344514660012773 0ustar00"""Core XML support for Python. This package contains four sub-packages: dom -- The W3C Document Object Model. This supports DOM Level 1 + Namespaces. parsers -- Python wrappers for XML parsers (currently only supports Expat). sax -- The Simple API for XML, developed by XML-Dev, led by David Megginson and ported to Python by Lars Marius Garshol. This supports the SAX 2 API. etree -- The ElementTree XML library. This is a subset of the full ElementTree XML release. """ __all__ = ["dom", "parsers", "sax", "etree"] lib64/python2.7/unittest/__init__.py000064400000005336152344515230013237 0ustar00""" Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's Smalltalk testing framework. This module contains the core framework classes that form the basis of specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results (TextTestRunner). Simple usage: import unittest class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): ## test method names begin 'test*' self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main() Further information is available in the bundled documentation, and from http://docs.python.org/library/unittest.html Copyright (c) 1999-2003 Steve Purcell Copyright (c) 2003-2010 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', 'registerResult', 'removeResult', 'removeHandler'] # Expose obsolete functions for backwards compatibility __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) __unittest = True from .result import TestResult from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf, skipUnless, expectedFailure, _skipInRpmBuild, _expectedFailureInRpmBuild) from .suite import BaseTestSuite, TestSuite from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, findTestCases) from .main import TestProgram, main from .runner import TextTestRunner, TextTestResult from .signals import installHandler, registerResult, removeResult, removeHandler # deprecated _TextTestResult = TextTestResult lib64/python3.6/email/mime/__init__.py000064400000000000152344515560013363 0ustar00usr/lib64/python3.6/json/__init__.py000064400000034074152344520770013150 0ustar00r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is derived from a version of the externally maintained simplejson library. Encoding basic Python object hierarchies:: >>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print(json.dumps("\"foo\bar")) "\"foo\bar" >>> print(json.dumps('\u1234')) "\u1234" >>> print(json.dumps('\\')) "\\" >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) {"a": 0, "b": 0, "c": 0} >>> from io import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]' Compact encoding:: >>> import json >>> from collections import OrderedDict >>> mydict = OrderedDict([('4', 5), ('6', 7)]) >>> json.dumps([1,2,3,mydict], separators=(',', ':')) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: >>> import json >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)) { "4": 5, "6": 7 } Decoding JSON:: >>> import json >>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}] >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj True >>> json.loads('"\\"foo\\bar"') == '"foo\x08ar' True >>> from io import StringIO >>> io = StringIO('["streaming API"]') >>> json.load(io)[0] == 'streaming API' True Specializing JSON object decoding:: >>> import json >>> def as_complex(dct): ... if '__complex__' in dct: ... return complex(dct['real'], dct['imag']) ... return dct ... >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', ... object_hook=as_complex) (1+2j) >>> from decimal import Decimal >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') True Specializing JSON object encoding:: >>> import json >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... raise TypeError(repr(obj) + " is not JSON serializable") ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) '[2.0, 1.0]' >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) '[2.0, 1.0]' Using json.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } $ echo '{ 1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] __author__ = 'Bob Ippolito ' from .decoder import JSONDecoder, JSONDecodeError from .encoder import JSONEncoder import codecs _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, default=None, ) def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the strings written to ``fp`` can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): iterable = _default_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the return value can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): return _default_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).encode(obj) _default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None) def detect_encoding(b): bstartswith = b.startswith if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)): return 'utf-32' if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)): return 'utf-16' if bstartswith(codecs.BOM_UTF8): return 'utf-8-sig' if len(b) >= 4: if not b[0]: # 00 00 -- -- - utf-32-be # 00 XX -- -- - utf-16-be return 'utf-16-be' if b[1] else 'utf-32-be' if not b[1]: # XX 00 00 00 - utf-32-le # XX 00 00 XX - utf-16-le # XX 00 XX -- - utf-16-le return 'utf-16-le' if b[2] or b[3] else 'utf-32-le' elif len(b) == 2: if not b[0]: # 00 XX - utf-16-be return 'utf-16-be' if not b[1]: # XX 00 - utf-16-le return 'utf-16-le' # default return 'utf-8' def load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict will remember the order of insertion). If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ return loads(fp.read(), cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict will remember the order of insertion). If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. ``parse_float``, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal). ``parse_int``, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float). ``parse_constant``, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. The ``encoding`` argument is ignored and deprecated. """ if isinstance(s, str): if s.startswith('\ufeff'): raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0) else: if not isinstance(s, (bytes, bytearray)): raise TypeError('the JSON object must be str, bytes or bytearray, ' 'not {!r}'.format(s.__class__.__name__)) s = s.decode(detect_encoding(s), 'surrogatepass') if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s) lib64/python3.6/curses/__init__.py000064400000006446152344523160012670 0ustar00"""curses The main package for curses support for Python. Normally used by importing the package, and perhaps a particular module inside it. import curses from curses import textpad curses.initscr() ... """ from _curses import * import os as _os import sys as _sys # Some constants, most notably the ACS_* ones, are only added to the C # _curses module's dictionary after initscr() is called. (Some # versions of SGI's curses don't define values for those constants # until initscr() has been called.) This wrapper function calls the # underlying C initscr(), and then copies the constants from the # _curses module to the curses package's dictionary. Don't do 'from # curses import *' if you'll be needing the ACS_* constants. def initscr(): import _curses, curses # we call setupterm() here because it raises an error # instead of calling exit() in error cases. setupterm(term=_os.environ.get("TERM", "unknown"), fd=_sys.__stdout__.fileno()) stdscr = _curses.initscr() for key, value in _curses.__dict__.items(): if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): setattr(curses, key, value) return stdscr # This is a similar wrapper for start_color(), which adds the COLORS and # COLOR_PAIRS variables which are only available after start_color() is # called. def start_color(): import _curses, curses retval = _curses.start_color() if hasattr(_curses, 'COLORS'): curses.COLORS = _curses.COLORS if hasattr(_curses, 'COLOR_PAIRS'): curses.COLOR_PAIRS = _curses.COLOR_PAIRS return retval # Import Python has_key() implementation if _curses doesn't contain has_key() try: has_key except NameError: from .has_key import has_key # Wrapper for the entire curses-based application. Runs a function which # should be the rest of your curses-based application. If the application # raises an exception, wrapper() will restore the terminal to a sane state so # you can read the resulting traceback. def wrapper(func, *args, **kwds): """Wrapper function that initializes curses and calls another function, restoring normal keyboard/screen behavior on error. The callable object 'func' is then passed the main window 'stdscr' as its first argument, followed by any other arguments passed to wrapper(). """ try: # Initialize curses stdscr = initscr() # Turn off echoing of keys, and enter cbreak mode, # where no buffering is performed on keyboard input noecho() cbreak() # In keypad mode, escape sequences for special keys # (like the cursor keys) will be interpreted and # a special value like curses.KEY_LEFT will be returned stdscr.keypad(1) # Start color, too. Harmless if the terminal doesn't have # color; user can test with has_color() later on. The try/catch # works around a minor bit of over-conscientiousness in the curses # module -- the error return from C start_color() is ignorable. try: start_color() except: pass return func(stdscr, *args, **kwds) finally: # Set everything back to normal if 'stdscr' in locals(): stdscr.keypad(0) echo() nocbreak() endwin() lib64/python3.8/distutils/__init__.py000064400000000354152344523160013402 0ustar00"""distutils The main package for the Python Module Distribution Utilities. Normally used from a setup script as from distutils.core import setup setup (...) """ import sys __version__ = sys.version[:sys.version.index(' ')] usr/lib64/python2.7/xml/sax/__init__.py000064400000007042152344523530013562 0ustar00"""Simple API for XML (SAX) implementation for Python. This module provides an implementation of the SAX 2 interface; information about the Java version of the interface can be found at http://www.megginson.com/SAX/. The Python version of the interface is documented at <...>. This package contains the following modules: handler -- Base classes and constants which define the SAX 2 API for the 'client-side' of SAX for Python. saxutils -- Implementation of the convenience classes commonly used to work with SAX. xmlreader -- Base classes and constants which define the SAX 2 API for the parsers used with SAX for Python. expatreader -- Driver that allows use of the Expat parser with SAX. """ from xmlreader import InputSource from handler import ContentHandler, ErrorHandler from _exceptions import SAXException, SAXNotRecognizedException, \ SAXParseException, SAXNotSupportedException, \ SAXReaderNotAvailable def parse(source, handler, errorHandler=ErrorHandler()): parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) parser.parse(source) def parseString(string, handler, errorHandler=ErrorHandler()): try: from cStringIO import StringIO except ImportError: from StringIO import StringIO if errorHandler is None: errorHandler = ErrorHandler() parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) inpsrc = InputSource() inpsrc.setByteStream(StringIO(string)) parser.parse(inpsrc) # this is the parser list used by the make_parser function if no # alternatives are given as parameters to the function default_parser_list = ["xml.sax.expatreader"] # tell modulefinder that importing sax potentially imports expatreader _false = 0 if _false: import xml.sax.expatreader import os, sys if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ: default_parser_list = os.environ["PY_SAX_PARSER"].split(",") del os _key = "python.xml.sax.parser" if sys.platform[:4] == "java" and sys.registry.containsKey(_key): default_parser_list = sys.registry.getProperty(_key).split(",") def make_parser(parser_list = []): """Creates and returns a SAX parser. Creates the first parser it is able to instantiate of the ones given in the list created by doing parser_list + default_parser_list. The lists must contain the names of Python modules containing both a SAX parser and a create_parser function.""" for parser_name in parser_list + default_parser_list: try: return _create_parser(parser_name) except ImportError,e: import sys if parser_name in sys.modules: # The parser module was found, but importing it # failed unexpectedly, pass this exception through raise except SAXReaderNotAvailable: # The parser module detected that it won't work properly, # so try the next one pass raise SAXReaderNotAvailable("No parsers found", None) # --- Internal utility methods used by make_parser if sys.platform[ : 4] == "java": def _create_parser(parser_name): from org.python.core import imp drv_module = imp.importName(parser_name, 0, globals()) return drv_module.create_parser() else: def _create_parser(parser_name): drv_module = __import__(parser_name,{},{},['create_parser']) return drv_module.create_parser() del sys usr/lib64/python3.6/lib2to3/__init__.py000064400000000007152344523670013444 0ustar00#empty lib64/python3.6/lib2to3/pgen2/__init__.py000064400000000217152344552170013646 0ustar00# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """The pgen2 package.""" lib64/python3.12/logging/__init__.py000064400000242755152344561400013073 0ustar00# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation, and that the name of Vinay Sajip # not be used in advertising or publicity pertaining to distribution # of the software without specific, written prior permission. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import sys, os, time, io, re, traceback, warnings, weakref, collections.abc from types import GenericAlias from string import Template from string import Formatter as StrFormatter __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', 'lastResort', 'raiseExceptions', 'getLevelNamesMapping', 'getHandlerByName', 'getHandlerNames'] import threading __author__ = "Vinay Sajip " __status__ = "production" # The following module attributes are no longer updated. __version__ = "0.5.1.2" __date__ = "07 February 2010" #--------------------------------------------------------------------------- # Miscellaneous module data #--------------------------------------------------------------------------- # #_startTime is used as the base when calculating the relative time of events # _startTime = time.time() # #raiseExceptions is used to see if exceptions during handling should be #propagated # raiseExceptions = True # # If you don't want threading information in the log, set this to False # logThreads = True # # If you don't want multiprocessing information in the log, set this to False # logMultiprocessing = True # # If you don't want process information in the log, set this to False # logProcesses = True # # If you don't want asyncio task information in the log, set this to False # logAsyncioTasks = True #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- # # Default levels and level names, these can be replaced with any positive set # of values having corresponding names. There is a pseudo-level, NOTSET, which # is only really there as a lower limit for user-defined levels. Handlers and # loggers are initialized with NOTSET so that they will log all messages, even # at user-defined levels. # CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 _levelToName = { CRITICAL: 'CRITICAL', ERROR: 'ERROR', WARNING: 'WARNING', INFO: 'INFO', DEBUG: 'DEBUG', NOTSET: 'NOTSET', } _nameToLevel = { 'CRITICAL': CRITICAL, 'FATAL': FATAL, 'ERROR': ERROR, 'WARN': WARNING, 'WARNING': WARNING, 'INFO': INFO, 'DEBUG': DEBUG, 'NOTSET': NOTSET, } def getLevelNamesMapping(): return _nameToLevel.copy() def getLevelName(level): """ Return the textual or numeric representation of logging level 'level'. If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, INFO, DEBUG) then you get the corresponding string. If you have associated levels with names using addLevelName then the name you have associated with 'level' is returned. If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned. If a string representation of the level is passed in, the corresponding numeric value is returned. If no matching numeric or string value is passed in, the string 'Level %s' % level is returned. """ # See Issues #22386, #27937 and #29220 for why it's this way result = _levelToName.get(level) if result is not None: return result result = _nameToLevel.get(level) if result is not None: return result return "Level %s" % level def addLevelName(level, levelName): """ Associate 'levelName' with 'level'. This is used when converting levels to text during message formatting. """ _acquireLock() try: #unlikely to cause an exception, but you never know... _levelToName[level] = levelName _nameToLevel[levelName] = level finally: _releaseLock() if hasattr(sys, "_getframe"): currentframe = lambda: sys._getframe(1) else: #pragma: no cover def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise Exception except Exception as exc: return exc.__traceback__.tb_frame.f_back # # _srcfile is used when walking the stack to check when we've got the first # caller stack frame, by skipping frames whose filename is that of this # module's source. It therefore should contain the filename of this module's # source file. # # Ordinarily we would use __file__ for this, but frozen modules don't always # have __file__ set, for some reason (see Issue #21736). Thus, we get the # filename from a handy code object from a function defined in this module. # (There's no particular reason for picking addLevelName.) # _srcfile = os.path.normcase(addLevelName.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). # Setting _srcfile to None will prevent findCaller() from being called. This # way, you can avoid the overhead of fetching caller information. # The following is based on warnings._is_internal_frame. It makes sure that # frames of the import mechanism are skipped when logging at module level and # using a stacklevel value greater than one. def _is_internal_frame(frame): """Signal whether the frame is a CPython or logging module internal.""" filename = os.path.normcase(frame.f_code.co_filename) return filename == _srcfile or ( "importlib" in filename and "_bootstrap" in filename ) def _checkLevel(level): if isinstance(level, int): rv = level elif str(level) == level: if level not in _nameToLevel: raise ValueError("Unknown level: %r" % level) rv = _nameToLevel[level] else: raise TypeError("Level not an integer or a valid string: %r" % (level,)) return rv #--------------------------------------------------------------------------- # Thread-related stuff #--------------------------------------------------------------------------- # #_lock is used to serialize access to shared data structures in this module. #This needs to be an RLock because fileConfig() creates and configures #Handlers, and so might arbitrary user threads. Since Handler code updates the #shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # _lock = threading.RLock() def _acquireLock(): """ Acquire the module-level lock for serializing access to shared data. This should be released with _releaseLock(). """ if _lock: _lock.acquire() def _releaseLock(): """ Release the module-level lock acquired by calling _acquireLock(). """ if _lock: _lock.release() # Prevent a held logging lock from blocking a child from logging. if not hasattr(os, 'register_at_fork'): # Windows and friends. def _register_at_fork_reinit_lock(instance): pass # no-op when os.register_at_fork does not exist. else: # A collection of instances with a _at_fork_reinit method (logging.Handler) # to be called in the child after forking. The weakref avoids us keeping # discarded Handler instances alive. _at_fork_reinit_lock_weakset = weakref.WeakSet() def _register_at_fork_reinit_lock(instance): _acquireLock() try: _at_fork_reinit_lock_weakset.add(instance) finally: _releaseLock() def _after_at_fork_child_reinit_locks(): for handler in _at_fork_reinit_lock_weakset: handler._at_fork_reinit() # _acquireLock() was called in the parent before forking. # The lock is reinitialized to unlocked state. _lock._at_fork_reinit() os.register_at_fork(before=_acquireLock, after_in_child=_after_at_fork_child_reinit_locks, after_in_parent=_releaseLock) #--------------------------------------------------------------------------- # The logging record #--------------------------------------------------------------------------- class LogRecord(object): """ A LogRecord instance represents an event being logged. LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is in msg and args, which are combined using str(msg) % args to create the message field of the record. The record also includes information such as when the record was created, the source line where the logging call was made, and any exception information to be logged. """ def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None, **kwargs): """ Initialize a logging record with interesting information. """ ct = time.time() self.name = name self.msg = msg # # The following statement allows passing of a dictionary as a sole # argument, so that you can do something like # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) # Suggested by Stefan Behnel. # Note that without the test for args[0], we get a problem because # during formatting, we test to see if the arg is present using # 'if self.args:'. If the event being logged is e.g. 'Value is %d' # and if the passed arg fails 'if self.args:' then no formatting # is done. For example, logger.warning('Value is %d', 0) would log # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. # Issue #21172: a request was made to relax the isinstance check # to hasattr(args[0], '__getitem__'). However, the docs on string # formatting still seem to suggest a mapping object is required. # Thus, while not removing the isinstance check, it does now look # for collections.abc.Mapping rather than, as before, dict. if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping) and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) self.levelno = level self.pathname = pathname try: self.filename = os.path.basename(pathname) self.module = os.path.splitext(self.filename)[0] except (TypeError, ValueError, AttributeError): self.filename = pathname self.module = "Unknown module" self.exc_info = exc_info self.exc_text = None # used to cache the traceback text self.stack_info = sinfo self.lineno = lineno self.funcName = func self.created = ct self.msecs = int((ct - int(ct)) * 1000) + 0.0 # see gh-89047 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads: self.thread = threading.get_ident() self.threadName = threading.current_thread().name else: # pragma: no cover self.thread = None self.threadName = None if not logMultiprocessing: # pragma: no cover self.processName = None else: self.processName = 'MainProcess' mp = sys.modules.get('multiprocessing') if mp is not None: # Errors may occur if multiprocessing has not finished loading # yet - e.g. if a custom import hook causes third-party code # to run when multiprocessing calls import. See issue 8200 # for an example try: self.processName = mp.current_process().name except Exception: #pragma: no cover pass if logProcesses and hasattr(os, 'getpid'): self.process = os.getpid() else: self.process = None self.taskName = None if logAsyncioTasks: asyncio = sys.modules.get('asyncio') if asyncio: try: self.taskName = asyncio.current_task().get_name() except Exception: pass def __repr__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) def getMessage(self): """ Return the message for this LogRecord. Return the message for this LogRecord after merging any user-supplied arguments with the message. """ msg = str(self.msg) if self.args: msg = msg % self.args return msg # # Determine which class to use when instantiating log records. # _logRecordFactory = LogRecord def setLogRecordFactory(factory): """ Set the factory to be used when instantiating a log record. :param factory: A callable which will be called to instantiate a log record. """ global _logRecordFactory _logRecordFactory = factory def getLogRecordFactory(): """ Return the factory to be used when instantiating a log record. """ return _logRecordFactory def makeLogRecord(dict): """ Make a LogRecord whose attributes are defined by the specified dictionary, This function is useful for converting a logging event received over a socket connection (which is sent as a dictionary) into a LogRecord instance. """ rv = _logRecordFactory(None, None, "", 0, "", (), None, None) rv.__dict__.update(dict) return rv #--------------------------------------------------------------------------- # Formatter classes and functions #--------------------------------------------------------------------------- _str_formatter = StrFormatter() del StrFormatter class PercentStyle(object): default_format = '%(message)s' asctime_format = '%(asctime)s' asctime_search = '%(asctime)' validation_pattern = re.compile(r'%\(\w+\)[#0+ -]*(\*|\d+)?(\.(\*|\d+))?[diouxefgcrsa%]', re.I) def __init__(self, fmt, *, defaults=None): self._fmt = fmt or self.default_format self._defaults = defaults def usesTime(self): return self._fmt.find(self.asctime_search) >= 0 def validate(self): """Validate the input format, ensure it matches the correct style""" if not self.validation_pattern.search(self._fmt): raise ValueError("Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0])) def _format(self, record): if defaults := self._defaults: values = defaults | record.__dict__ else: values = record.__dict__ return self._fmt % values def format(self, record): try: return self._format(record) except KeyError as e: raise ValueError('Formatting field not found in record: %s' % e) class StrFormatStyle(PercentStyle): default_format = '{message}' asctime_format = '{asctime}' asctime_search = '{asctime' fmt_spec = re.compile(r'^(.?[<>=^])?[+ -]?#?0?(\d+|{\w+})?[,_]?(\.(\d+|{\w+}))?[bcdefgnosx%]?$', re.I) field_spec = re.compile(r'^(\d+|\w+)(\.\w+|\[[^]]+\])*$') def _format(self, record): if defaults := self._defaults: values = defaults | record.__dict__ else: values = record.__dict__ return self._fmt.format(**values) def validate(self): """Validate the input format, ensure it is the correct string formatting style""" fields = set() try: for _, fieldname, spec, conversion in _str_formatter.parse(self._fmt): if fieldname: if not self.field_spec.match(fieldname): raise ValueError('invalid field name/expression: %r' % fieldname) fields.add(fieldname) if conversion and conversion not in 'rsa': raise ValueError('invalid conversion: %r' % conversion) if spec and not self.fmt_spec.match(spec): raise ValueError('bad specifier: %r' % spec) except ValueError as e: raise ValueError('invalid format: %s' % e) if not fields: raise ValueError('invalid format: no fields') class StringTemplateStyle(PercentStyle): default_format = '${message}' asctime_format = '${asctime}' asctime_search = '${asctime}' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._tpl = Template(self._fmt) def usesTime(self): fmt = self._fmt return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_search) >= 0 def validate(self): pattern = Template.pattern fields = set() for m in pattern.finditer(self._fmt): d = m.groupdict() if d['named']: fields.add(d['named']) elif d['braced']: fields.add(d['braced']) elif m.group(0) == '$': raise ValueError('invalid format: bare \'$\' not allowed') if not fields: raise ValueError('invalid format: no fields') def _format(self, record): if defaults := self._defaults: values = defaults | record.__dict__ else: values = record.__dict__ return self._tpl.substitute(**values) BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" _STYLES = { '%': (PercentStyle, BASIC_FORMAT), '{': (StrFormatStyle, '{levelname}:{name}:{message}'), '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), } class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. Formatters need to know how a LogRecord is constructed. They are responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the style-dependent default value, "%(message)s", "{message}", or "${message}", is used. The Formatter can be initialized with a format string which makes use of knowledge of the LogRecord attributes - e.g. the default value mentioned above makes use of the fact that the user's message and arguments are pre- formatted into a LogRecord's message attribute. Currently, the useful attributes in a LogRecord are described by: %(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(taskName)s Task name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted """ converter = time.localtime def __init__(self, fmt=None, datefmt=None, style='%', validate=True, *, defaults=None): """ Initialize the formatter with specified format strings. Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument. If datefmt is omitted, you get an ISO8601-like (or RFC 3339-like) format. Use a style parameter of '%', '{' or '$' to specify that you want to use one of %-formatting, :meth:`str.format` (``{}``) formatting or :class:`string.Template` formatting in your format string. .. versionchanged:: 3.2 Added the ``style`` parameter. """ if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) self._style = _STYLES[style][0](fmt, defaults=defaults) if validate: self._style.validate() self._fmt = self._style._fmt self.datefmt = datefmt default_time_format = '%Y-%m-%d %H:%M:%S' default_msec_format = '%s,%03d' def formatTime(self, record, datefmt=None): """ Return the creation time of the specified LogRecord as formatted text. This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) if datefmt: s = time.strftime(datefmt, ct) else: s = time.strftime(self.default_time_format, ct) if self.default_msec_format: s = self.default_msec_format % (s, record.msecs) return s def formatException(self, ei): """ Format and return the specified exception information as a string. This default implementation just uses traceback.print_exception() """ sio = io.StringIO() tb = ei[2] # See issues #9427, #1553375. Commented out for now. #if getattr(self, 'fullstack', False): # traceback.print_stack(tb.tb_frame.f_back, file=sio) traceback.print_exception(ei[0], ei[1], tb, None, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] return s def usesTime(self): """ Check if the format uses the creation time of the record. """ return self._style.usesTime() def formatMessage(self, record): return self._style.format(record) def formatStack(self, stack_info): """ This method is provided as an extension point for specialized formatting of stack information. The input data is a string as returned from a call to :func:`traceback.print_stack`, but with the last trailing newline removed. The base implementation just returns the value passed in. """ return stack_info def format(self, record): """ Format the specified record as text. The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message. """ record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) return s # # The default formatter to use when no other is specified # _defaultFormatter = Formatter() class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ def __init__(self, linefmt=None): """ Optionally specify a formatter which will be used to format each individual record. """ if linefmt: self.linefmt = linefmt else: self.linefmt = _defaultFormatter def formatHeader(self, records): """ Return the header string for the specified records. """ return "" def formatFooter(self, records): """ Return the footer string for the specified records. """ return "" def format(self, records): """ Format the specified records and return the result as a string. """ rv = "" if len(records) > 0: rv = rv + self.formatHeader(records) for record in records: rv = rv + self.linefmt.format(record) rv = rv + self.formatFooter(records) return rv #--------------------------------------------------------------------------- # Filter classes and functions #--------------------------------------------------------------------------- class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed. """ def __init__(self, name=''): """ Initialize a filter. Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event. """ self.name = name self.nlen = len(name) def filter(self, record): """ Determine if the specified record is to be logged. Returns True if the record should be logged, or False otherwise. If deemed appropriate, the record may be modified in-place. """ if self.nlen == 0: return True elif self.name == record.name: return True elif record.name.find(self.name, 0, self.nlen) != 0: return False return (record.name[self.nlen] == ".") class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. """ def __init__(self): """ Initialize the list of filters to be an empty list. """ self.filters = [] def addFilter(self, filter): """ Add the specified filter to this handler. """ if not (filter in self.filters): self.filters.append(filter) def removeFilter(self, filter): """ Remove the specified filter from this handler. """ if filter in self.filters: self.filters.remove(filter) def filter(self, record): """ Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto this by returning a false value. If a filter attached to a handler returns a log record instance, then that instance is used in place of the original log record in any further processing of the event by that handler. If a filter returns any other true value, the original log record is used in any further processing of the event by that handler. If none of the filters return false values, this method returns a log record. If any of the filters return a false value, this method returns a false value. .. versionchanged:: 3.2 Allow filters to be just callables. .. versionchanged:: 3.12 Allow filters to return a LogRecord instead of modifying it in place. """ for f in self.filters: if hasattr(f, 'filter'): result = f.filter(record) else: result = f(record) # assume callable - will raise if not if not result: return False if isinstance(result, LogRecord): record = result return record #--------------------------------------------------------------------------- # Handler classes and functions #--------------------------------------------------------------------------- _handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized def _removeHandlerRef(wr): """ Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are # set to None. It can also be called from another thread. So we need to # pre-emptively grab the necessary globals and check if they're None, # to prevent race conditions and failures during interpreter shutdown. acquire, release, handlers = _acquireLock, _releaseLock, _handlerList if acquire and release and handlers: acquire() try: handlers.remove(wr) except ValueError: pass finally: release() def _addHandlerRef(handler): """ Add a handler to the internal cleanup list using a weak reference. """ _acquireLock() try: _handlerList.append(weakref.ref(handler, _removeHandlerRef)) finally: _releaseLock() def getHandlerByName(name): """ Get a handler with the specified *name*, or None if there isn't one with that name. """ return _handlers.get(name) def getHandlerNames(): """ Return all known handler names as an immutable set. """ result = set(_handlers.keys()) return frozenset(result) class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. The base handler class. Acts as a placeholder which defines the Handler interface. Handlers can optionally use Formatter instances to format records as desired. By default, no formatter is specified; in this case, the 'raw' message as determined by record.message is logged. """ def __init__(self, level=NOTSET): """ Initializes the instance - basically setting the formatter to None and the filter list to empty. """ Filterer.__init__(self) self._name = None self.level = _checkLevel(level) self.formatter = None self._closed = False # Add the handler to the global _handlerList (for cleanup on shutdown) _addHandlerRef(self) self.createLock() def get_name(self): return self._name def set_name(self, name): _acquireLock() try: if self._name in _handlers: del _handlers[self._name] self._name = name if name: _handlers[name] = self finally: _releaseLock() name = property(get_name, set_name) def createLock(self): """ Acquire a thread lock for serializing access to the underlying I/O. """ self.lock = threading.RLock() _register_at_fork_reinit_lock(self) def _at_fork_reinit(self): self.lock._at_fork_reinit() def acquire(self): """ Acquire the I/O thread lock. """ if self.lock: self.lock.acquire() def release(self): """ Release the I/O thread lock. """ if self.lock: self.lock.release() def setLevel(self, level): """ Set the logging level of this handler. level must be an int or a str. """ self.level = _checkLevel(level) def format(self, record): """ Format the specified record. If a formatter is set, use it. Otherwise, use the default formatter for the module. """ if self.formatter: fmt = self.formatter else: fmt = _defaultFormatter return fmt.format(record) def emit(self, record): """ Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so raises a NotImplementedError. """ raise NotImplementedError('emit must be implemented ' 'by Handler subclasses') def handle(self, record): """ Conditionally emit the specified logging record. Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns an instance of the log record that was emitted if it passed all filters, otherwise a false value is returned. """ rv = self.filter(record) if isinstance(rv, LogRecord): record = rv if rv: self.acquire() try: self.emit(record) finally: self.release() return rv def setFormatter(self, fmt): """ Set the formatter for this handler. """ self.formatter = fmt def flush(self): """ Ensure all logging output has been flushed. This version does nothing and is intended to be implemented by subclasses. """ pass def close(self): """ Tidy up any resources used by the handler. This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... self._closed = True if self._name and self._name in _handlers: del _handlers[self._name] finally: _releaseLock() def handleError(self, record): """ Handle errors which occur during an emit() call. This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method. """ if raiseExceptions and sys.stderr: # see issue 13807 t, v, tb = sys.exc_info() try: sys.stderr.write('--- Logging error ---\n') traceback.print_exception(t, v, tb, None, sys.stderr) sys.stderr.write('Call stack:\n') # Walk the stack frame up until we're out of logging, # so as to print the calling context. frame = tb.tb_frame while (frame and os.path.dirname(frame.f_code.co_filename) == __path__[0]): frame = frame.f_back if frame: traceback.print_stack(frame, file=sys.stderr) else: # couldn't find the right stack frame, for some reason sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) # Issue 18671: output logging message and arguments try: sys.stderr.write('Message: %r\n' 'Arguments: %s\n' % (record.msg, record.args)) except RecursionError: # See issue 36272 raise except Exception: sys.stderr.write('Unable to print the message and arguments' ' - possible formatting error.\nUse the' ' traceback above to help find the error.\n' ) except OSError: #pragma: no cover pass # see issue 5971 finally: del t, v, tb def __repr__(self): level = getLevelName(self.level) return '<%s (%s)>' % (self.__class__.__name__, level) class StreamHandler(Handler): """ A handler class which writes logging records, appropriately formatted, to a stream. Note that this class does not close the stream, as sys.stdout or sys.stderr may be used. """ terminator = '\n' def __init__(self, stream=None): """ Initialize the handler. If stream is not specified, sys.stderr is used. """ Handler.__init__(self) if stream is None: stream = sys.stderr self.stream = stream def flush(self): """ Flushes the stream. """ self.acquire() try: if self.stream and hasattr(self.stream, "flush"): self.stream.flush() finally: self.release() def emit(self, record): """ Emit a record. If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an 'encoding' attribute, it is used to determine how to do the output to the stream. """ try: msg = self.format(record) stream = self.stream # issue 35046: merged two stream.writes into one. stream.write(msg + self.terminator) self.flush() except RecursionError: # See issue 36272 raise except Exception: self.handleError(record) def setStream(self, stream): """ Sets the StreamHandler's stream to the specified value, if it is different. Returns the old stream, if the stream was changed, or None if it wasn't. """ if stream is self.stream: result = None else: result = self.stream self.acquire() try: self.flush() self.stream = stream finally: self.release() return result def __repr__(self): level = getLevelName(self.level) name = getattr(self.stream, 'name', '') # bpo-36015: name can be an int name = str(name) if name: name += ' ' return '<%s %s(%s)>' % (self.__class__.__name__, name, level) __class_getitem__ = classmethod(GenericAlias) class FileHandler(StreamHandler): """ A handler class which writes formatted logging records to disk files. """ def __init__(self, filename, mode='a', encoding=None, delay=False, errors=None): """ Open the specified file and use it as the stream for logging. """ # Issue #27493: add support for Path objects to be passed in filename = os.fspath(filename) #keep the absolute path, otherwise derived classes which use this #may come a cropper when the current directory changes self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding if "b" not in mode: self.encoding = io.text_encoding(encoding) self.errors = errors self.delay = delay # bpo-26789: FileHandler keeps a reference to the builtin open() # function to be able to open or reopen the file during Python # finalization. self._builtin_open = open if delay: #We don't open the stream, but we still need to call the #Handler constructor to set level, formatter, lock etc. Handler.__init__(self) self.stream = None else: StreamHandler.__init__(self, self._open()) def close(self): """ Closes the stream. """ self.acquire() try: try: if self.stream: try: self.flush() finally: stream = self.stream self.stream = None if hasattr(stream, "close"): stream.close() finally: # Issue #19523: call unconditionally to # prevent a handler leak when delay is set # Also see Issue #42378: we also rely on # self._closed being set to True there StreamHandler.close(self) finally: self.release() def _open(self): """ Open the current base file with the (original) mode and encoding. Return the resulting stream. """ open_func = self._builtin_open return open_func(self.baseFilename, self.mode, encoding=self.encoding, errors=self.errors) def emit(self, record): """ Emit a record. If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit. If stream is not open, current mode is 'w' and `_closed=True`, record will not be emitted (see Issue #42378). """ if self.stream is None: if self.mode != 'w' or not self._closed: self.stream = self._open() if self.stream: StreamHandler.emit(self, record) def __repr__(self): level = getLevelName(self.level) return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level) class _StderrHandler(StreamHandler): """ This class is like a StreamHandler using sys.stderr, but always uses whatever sys.stderr is currently set to rather than the value of sys.stderr at handler construction time. """ def __init__(self, level=NOTSET): """ Initialize the handler. """ Handler.__init__(self, level) @property def stream(self): return sys.stderr _defaultLastResort = _StderrHandler(WARNING) lastResort = _defaultLastResort #--------------------------------------------------------------------------- # Manager classes and functions #--------------------------------------------------------------------------- class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is intended for internal use only and not as part of the public API. """ def __init__(self, alogger): """ Initialize with the specified logger being a child of this placeholder. """ self.loggerMap = { alogger : None } def append(self, alogger): """ Add the specified logger as a child of this placeholder. """ if alogger not in self.loggerMap: self.loggerMap[alogger] = None # # Determine which class to use when instantiating loggers. # def setLoggerClass(klass): """ Set the class to be used when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__() """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) global _loggerClass _loggerClass = klass def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ return _loggerClass class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. """ def __init__(self, rootnode): """ Initialize the manager with the root node of the logger hierarchy. """ self.root = rootnode self.disable = 0 self.emittedNoHandlerWarning = False self.loggerDict = {} self.loggerClass = None self.logRecordFactory = None @property def disable(self): return self._disable @disable.setter def disable(self, value): self._disable = _checkLevel(value) def getLogger(self, name): """ Get a logger with the specified name (channel name), creating it if it doesn't yet exist. This name is a dot-separated hierarchical name, such as "a", "a.b", "a.b.c" or similar. If a PlaceHolder existed for the specified name [i.e. the logger didn't exist but a child of it did], replace it with the created logger and fix up the parent/child references which pointed to the placeholder to now point to the logger. """ rv = None if not isinstance(name, str): raise TypeError('A logger name must be a string') _acquireLock() try: if name in self.loggerDict: rv = self.loggerDict[name] if isinstance(rv, PlaceHolder): ph = rv rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupChildren(ph, rv) self._fixupParents(rv) else: rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupParents(rv) finally: _releaseLock() return rv def setLoggerClass(self, klass): """ Set the class to be used when instantiating a logger with this Manager. """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) self.loggerClass = klass def setLogRecordFactory(self, factory): """ Set the factory to be used when instantiating a log record with this Manager. """ self.logRecordFactory = factory def _fixupParents(self, alogger): """ Ensure that there are either loggers or placeholders all the way from the specified logger to the root of the logger hierarchy. """ name = alogger.name i = name.rfind(".") rv = None while (i > 0) and not rv: substr = name[:i] if substr not in self.loggerDict: self.loggerDict[substr] = PlaceHolder(alogger) else: obj = self.loggerDict[substr] if isinstance(obj, Logger): rv = obj else: assert isinstance(obj, PlaceHolder) obj.append(alogger) i = name.rfind(".", 0, i - 1) if not rv: rv = self.root alogger.parent = rv def _fixupChildren(self, ph, alogger): """ Ensure that children of the placeholder ph are connected to the specified logger. """ name = alogger.name namelen = len(name) for c in ph.loggerMap.keys(): #The if means ... if not c.parent.name.startswith(nm) if c.parent.name[:namelen] != name: alogger.parent = c.parent c.parent = alogger def _clear_cache(self): """ Clear the cache for all loggers in loggerDict Called when level changes are made """ _acquireLock() for logger in self.loggerDict.values(): if isinstance(logger, Logger): logger._cache.clear() self.root._cache.clear() _releaseLock() #--------------------------------------------------------------------------- # Logger classes and functions #--------------------------------------------------------------------------- class Logger(Filterer): """ Instances of the Logger class represent a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting. """ def __init__(self, name, level=NOTSET): """ Initialize the logger with a name and an optional level. """ Filterer.__init__(self) self.name = name self.level = _checkLevel(level) self.parent = None self.propagate = True self.handlers = [] self.disabled = False self._cache = {} def setLevel(self, level): """ Set the logging level of this logger. level must be an int or a str. """ self.level = _checkLevel(level) self.manager._clear_cache() def debug(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'DEBUG'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.debug("Houston, we have a %s", "thorny problem", exc_info=True) """ if self.isEnabledFor(DEBUG): self._log(DEBUG, msg, args, **kwargs) def info(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'INFO'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.info("Houston, we have a %s", "notable problem", exc_info=True) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) def warning(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'WARNING'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.warning("Houston, we have a %s", "bit of a problem", exc_info=True) """ if self.isEnabledFor(WARNING): self._log(WARNING, msg, args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'ERROR'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.error("Houston, we have a %s", "major problem", exc_info=True) """ if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Convenience method for logging an ERROR with exception information. """ self.error(msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'CRITICAL'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.critical("Houston, we have a %s", "major disaster", exc_info=True) """ if self.isEnabledFor(CRITICAL): self._log(CRITICAL, msg, args, **kwargs) def fatal(self, msg, *args, **kwargs): """ Don't use this method, use critical() instead. """ self.critical(msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.log(level, "We have a %s", "mysterious problem", exc_info=True) """ if not isinstance(level, int): if raiseExceptions: raise TypeError("level must be an integer") else: return if self.isEnabledFor(level): self._log(level, msg, args, **kwargs) def findCaller(self, stack_info=False, stacklevel=1): """ Find the stack frame of the caller so that we can note the source file name, line number and function name. """ f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. if f is None: return "(unknown file)", 0, "(unknown function)", None while stacklevel > 0: next_f = f.f_back if next_f is None: ## We've got options here. ## If we want to use the last (deepest) frame: break ## If we want to mimic the warnings module: #return ("sys", 1, "(unknown function)", None) ## If we want to be pedantic: #raise ValueError("call stack is not deep enough") f = next_f if not _is_internal_frame(f): stacklevel -= 1 co = f.f_code sinfo = None if stack_info: with io.StringIO() as sio: sio.write("Stack (most recent call last):\n") traceback.print_stack(f, file=sio) sinfo = sio.getvalue() if sinfo[-1] == '\n': sinfo = sinfo[:-1] return co.co_filename, f.f_lineno, co.co_name, sinfo def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None): """ A factory method which can be overridden in subclasses to create specialized LogRecords. """ rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func, sinfo) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] return rv def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1): """ Low-level logging routine which creates a LogRecord and then calls all the handlers of this logger to handle the record. """ sinfo = None if _srcfile: #IronPython doesn't track Python frames, so findCaller raises an #exception on some versions of IronPython. We trap it here so that #IronPython can use logging. try: fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel) except ValueError: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" else: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: if isinstance(exc_info, BaseException): exc_info = (type(exc_info), exc_info, exc_info.__traceback__) elif not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra, sinfo) self.handle(record) def handle(self, record): """ Call the handlers for the specified record. This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ if self.disabled: return maybe_record = self.filter(record) if not maybe_record: return if isinstance(maybe_record, LogRecord): record = maybe_record self.callHandlers(record) def addHandler(self, hdlr): """ Add the specified handler to this logger. """ _acquireLock() try: if not (hdlr in self.handlers): self.handlers.append(hdlr) finally: _releaseLock() def removeHandler(self, hdlr): """ Remove the specified handler from this logger. """ _acquireLock() try: if hdlr in self.handlers: self.handlers.remove(hdlr) finally: _releaseLock() def hasHandlers(self): """ See if this logger has any handlers configured. Loop through all handlers for this logger and its parents in the logger hierarchy. Return True if a handler was found, else False. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger which is checked for the existence of handlers. """ c = self rv = False while c: if c.handlers: rv = True break if not c.propagate: break else: c = c.parent return rv def callHandlers(self, record): """ Pass a record to all relevant handlers. Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called. """ c = self found = 0 while c: for hdlr in c.handlers: found = found + 1 if record.levelno >= hdlr.level: hdlr.handle(record) if not c.propagate: c = None #break out else: c = c.parent if (found == 0): if lastResort: if record.levelno >= lastResort.level: lastResort.handle(record) elif raiseExceptions and not self.manager.emittedNoHandlerWarning: sys.stderr.write("No handlers could be found for logger" " \"%s\"\n" % self.name) self.manager.emittedNoHandlerWarning = True def getEffectiveLevel(self): """ Get the effective level for this logger. Loop through this logger and its parents in the logger hierarchy, looking for a non-zero logging level. Return the first one found. """ logger = self while logger: if logger.level: return logger.level logger = logger.parent return NOTSET def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.disabled: return False try: return self._cache[level] except KeyError: _acquireLock() try: if self.manager.disable >= level: is_enabled = self._cache[level] = False else: is_enabled = self._cache[level] = ( level >= self.getEffectiveLevel() ) finally: _releaseLock() return is_enabled def getChild(self, suffix): """ Get a logger which is a descendant to this one. This is a convenience method, such that logging.getLogger('abc').getChild('def.ghi') is the same as logging.getLogger('abc.def.ghi') It's useful, for example, when the parent logger is named using __name__ rather than a literal string. """ if self.root is not self: suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) def getChildren(self): def _hierlevel(logger): if logger is logger.manager.root: return 0 return 1 + logger.name.count('.') d = self.manager.loggerDict _acquireLock() try: # exclude PlaceHolders - the last check is to ensure that lower-level # descendants aren't returned - if there are placeholders, a logger's # parent field might point to a grandparent or ancestor thereof. return set(item for item in d.values() if isinstance(item, Logger) and item.parent is self and _hierlevel(item) == 1 + _hierlevel(item.parent)) finally: _releaseLock() def __repr__(self): level = getLevelName(self.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) def __reduce__(self): if getLogger(self.name) is not self: import pickle raise pickle.PicklingError('logger cannot be pickled') return getLogger, (self.name,) class RootLogger(Logger): """ A root logger is not that different to any other logger, except that it must have a logging level and there is only one instance of it in the hierarchy. """ def __init__(self, level): """ Initialize the logger with the name "root". """ Logger.__init__(self, "root", level) def __reduce__(self): return getLogger, () _loggerClass = Logger class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. """ def __init__(self, logger, extra=None): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows easy stacking of LoggerAdapters, if so desired. You can effectively pass keyword arguments as shown in the following example: adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) """ self.logger = logger self.extra = extra def process(self, msg, kwargs): """ Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs. Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs. """ kwargs["extra"] = self.extra return msg, kwargs # # Boilerplate convenience methods # def debug(self, msg, *args, **kwargs): """ Delegate a debug call to the underlying logger. """ self.log(DEBUG, msg, *args, **kwargs) def info(self, msg, *args, **kwargs): """ Delegate an info call to the underlying logger. """ self.log(INFO, msg, *args, **kwargs) def warning(self, msg, *args, **kwargs): """ Delegate a warning call to the underlying logger. """ self.log(WARNING, msg, *args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Delegate an error call to the underlying logger. """ self.log(ERROR, msg, *args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Delegate an exception call to the underlying logger. """ self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Delegate a critical call to the underlying logger. """ self.log(CRITICAL, msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Delegate a log call to the underlying logger, after adding contextual information from this adapter instance. """ if self.isEnabledFor(level): msg, kwargs = self.process(msg, kwargs) self.logger.log(level, msg, *args, **kwargs) def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ return self.logger.isEnabledFor(level) def setLevel(self, level): """ Set the specified level on the underlying logger. """ self.logger.setLevel(level) def getEffectiveLevel(self): """ Get the effective level for the underlying logger. """ return self.logger.getEffectiveLevel() def hasHandlers(self): """ See if the underlying logger has any handlers. """ return self.logger.hasHandlers() def _log(self, level, msg, args, **kwargs): """ Low-level log implementation, proxied to allow nested logger adapters. """ return self.logger._log(level, msg, args, **kwargs) @property def manager(self): return self.logger.manager @manager.setter def manager(self, value): self.logger.manager = value @property def name(self): return self.logger.name def __repr__(self): logger = self.logger level = getLevelName(logger.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level) __class_getitem__ = classmethod(GenericAlias) root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) #--------------------------------------------------------------------------- # Configuration classes and functions #--------------------------------------------------------------------------- def basicConfig(**kwargs): """ Do basic configuration for the logging system. This function does nothing if the root logger already has handlers configured, unless the keyword argument *force* is set to ``True``. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package. The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger. A number of optional keyword arguments may be specified, which can alter the default behaviour. filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler. filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format Use the specified format string for the handler. datefmt Use the specified date/time format. style If a format string is specified, use this to specify the type of format string (possible values '%', '{', '$', for %-formatting, :meth:`str.format` and :class:`string.Template` - defaults to '%'). level Set the root logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored. handlers If specified, this should be an iterable of already created handlers, which will be added to the root logger. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function. force If this keyword is specified as true, any existing handlers attached to the root logger are removed and closed, before carrying out the configuration as specified by the other arguments. encoding If specified together with a filename, this encoding is passed to the created FileHandler, causing it to be used when the file is opened. errors If specified together with a filename, this value is passed to the created FileHandler, causing it to be used when the file is opened in text mode. If not specified, the default value is `backslashreplace`. Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed. .. versionchanged:: 3.2 Added the ``style`` parameter. .. versionchanged:: 3.3 Added the ``handlers`` parameter. A ``ValueError`` is now thrown for incompatible arguments (e.g. ``handlers`` specified together with ``filename``/``filemode``, or ``filename``/``filemode`` specified together with ``stream``, or ``handlers`` specified together with ``stream``. .. versionchanged:: 3.8 Added the ``force`` parameter. .. versionchanged:: 3.9 Added the ``encoding`` and ``errors`` parameters. """ # Add thread safety in case someone mistakenly calls # basicConfig() from multiple threads _acquireLock() try: force = kwargs.pop('force', False) encoding = kwargs.pop('encoding', None) errors = kwargs.pop('errors', 'backslashreplace') if force: for h in root.handlers[:]: root.removeHandler(h) h.close() if len(root.handlers) == 0: handlers = kwargs.pop("handlers", None) if handlers is None: if "stream" in kwargs and "filename" in kwargs: raise ValueError("'stream' and 'filename' should not be " "specified together") else: if "stream" in kwargs or "filename" in kwargs: raise ValueError("'stream' or 'filename' should not be " "specified together with 'handlers'") if handlers is None: filename = kwargs.pop("filename", None) mode = kwargs.pop("filemode", 'a') if filename: if 'b' in mode: errors = None else: encoding = io.text_encoding(encoding) h = FileHandler(filename, mode, encoding=encoding, errors=errors) else: stream = kwargs.pop("stream", None) h = StreamHandler(stream) handlers = [h] dfs = kwargs.pop("datefmt", None) style = kwargs.pop("style", '%') if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) fs = kwargs.pop("format", _STYLES[style][1]) fmt = Formatter(fs, dfs, style) for h in handlers: if h.formatter is None: h.setFormatter(fmt) root.addHandler(h) level = kwargs.pop("level", None) if level is not None: root.setLevel(level) if kwargs: keys = ', '.join(kwargs.keys()) raise ValueError('Unrecognised argument(s): %s' % keys) finally: _releaseLock() #--------------------------------------------------------------------------- # Utility functions at module level. # Basically delegate everything to the root logger. #--------------------------------------------------------------------------- def getLogger(name=None): """ Return a logger with the specified name, creating it if necessary. If no name is specified, return the root logger. """ if not name or isinstance(name, str) and name == root.name: return root return Logger.manager.getLogger(name) def critical(msg, *args, **kwargs): """ Log a message with severity 'CRITICAL' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.critical(msg, *args, **kwargs) def fatal(msg, *args, **kwargs): """ Don't use this function, use critical() instead. """ critical(msg, *args, **kwargs) def error(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.error(msg, *args, **kwargs) def exception(msg, *args, exc_info=True, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. If the logger has no handlers, basicConfig() is called to add a console handler with a pre-defined format. """ error(msg, *args, exc_info=exc_info, **kwargs) def warning(msg, *args, **kwargs): """ Log a message with severity 'WARNING' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.warning(msg, *args, **kwargs) def warn(msg, *args, **kwargs): warnings.warn("The 'warn' function is deprecated, " "use 'warning' instead", DeprecationWarning, 2) warning(msg, *args, **kwargs) def info(msg, *args, **kwargs): """ Log a message with severity 'INFO' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.info(msg, *args, **kwargs) def debug(msg, *args, **kwargs): """ Log a message with severity 'DEBUG' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.debug(msg, *args, **kwargs) def log(level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.log(level, msg, *args, **kwargs) def disable(level=CRITICAL): """ Disable all logging calls of severity 'level' and below. """ root.manager.disable = level root.manager._clear_cache() def shutdown(handlerList=_handlerList): """ Perform any cleanup actions in the logging system (e.g. flushing buffers). Should be called at application exit. """ for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: h = wr() if h: try: h.acquire() # MemoryHandlers might not want to be flushed on close, # but circular imports prevent us scoping this to just # those handlers. hence the default to True. if getattr(h, 'flushOnClose', True): h.flush() h.close() except (OSError, ValueError): # Ignore errors which might be caused # because handlers have been closed but # references to them are still around at # application exit. pass finally: h.release() except: # ignore everything, as we're shutting down if raiseExceptions: raise #else, swallow #Let's try and shutdown automatically on application exit... import atexit atexit.register(shutdown) # Null handler class NullHandler(Handler): """ This handler does nothing. It's intended to be used to avoid the "No handlers could be found for logger XXX" one-off warning. This is important for library code, which may contain code to log events. If a user of the library does not configure logging, the one-off warning might be produced; to avoid this, the library developer simply needs to instantiate a NullHandler and add it to the top-level logger of the library module or package. """ def handle(self, record): """Stub.""" def emit(self, record): """Stub.""" def createLock(self): self.lock = None def _at_fork_reinit(self): pass # Warnings integration _warnings_showwarning = None def _showwarning(message, category, filename, lineno, file=None, line=None): """ Implementation of showwarnings which redirects to logging, which will first check to see if the file parameter is None. If a file is specified, it will delegate to the original warnings implementation of showwarning. Otherwise, it will call warnings.formatwarning and will log the resulting string to a warnings logger named "py.warnings" with level logging.WARNING. """ if file is not None: if _warnings_showwarning is not None: _warnings_showwarning(message, category, filename, lineno, file, line) else: s = warnings.formatwarning(message, category, filename, lineno, line) logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) # bpo-46557: Log str(s) as msg instead of logger.warning("%s", s) # since some log aggregation tools group logs by the msg arg logger.warning(str(s)) def captureWarnings(capture): """ If capture is true, redirect all warnings to the logging package. If capture is False, ensure that warnings are not redirected to logging but to their original destinations. """ global _warnings_showwarning if capture: if _warnings_showwarning is None: _warnings_showwarning = warnings.showwarning warnings.showwarning = _showwarning else: if _warnings_showwarning is not None: warnings.showwarning = _warnings_showwarning _warnings_showwarning = None lib64/python3.8/asyncio/__init__.py000064400000002313152344652170013024 0ustar00"""The asyncio package, tracking PEP 3156.""" # flake8: noqa import sys # This relies on each of the submodules having an __all__ variable. from .base_events import * from .coroutines import * from .events import * from .exceptions import * from .futures import * from .locks import * from .protocols import * from .runners import * from .queues import * from .streams import * from .subprocess import * from .tasks import * from .transports import * # Exposed for _asynciomodule.c to implement now deprecated # Task.all_tasks() method. This function will be removed in 3.9. from .tasks import _all_tasks_compat # NoQA __all__ = (base_events.__all__ + coroutines.__all__ + events.__all__ + exceptions.__all__ + futures.__all__ + locks.__all__ + protocols.__all__ + runners.__all__ + queues.__all__ + streams.__all__ + subprocess.__all__ + tasks.__all__ + transports.__all__) if sys.platform == 'win32': # pragma: no cover from .windows_events import * __all__ += windows_events.__all__ else: from .unix_events import * # pragma: no cover __all__ += unix_events.__all__ lib64/python3.8/pydoc_data/__init__.py000064400000000000152344652220013451 0ustar00lib64/python3.12/xmlrpc/__init__.py000064400000000046152344657740012750 0ustar00# This directory is a Python package. lib64/python2.7/wsgiref/__init__.py000064400000001112152344703460013016 0ustar00"""wsgiref -- a WSGI (PEP 333) Reference Library Current Contents: * util -- Miscellaneous useful functions and wrappers * headers -- Manage response headers * handlers -- base classes for server/gateway implementations * simple_server -- a simple BaseHTTPServer that supports WSGI * validate -- validation wrapper that sits between an app and a server to detect errors in either To-Do: * cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard) * cgi_wrapper -- Run CGI apps under WSGI * router -- a simple middleware component that handles URL traversal """ usr/lib64/python3.8/json/__init__.py000064400000034011152344747600013144 0ustar00r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is derived from a version of the externally maintained simplejson library. Encoding basic Python object hierarchies:: >>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print(json.dumps("\"foo\bar")) "\"foo\bar" >>> print(json.dumps('\u1234')) "\u1234" >>> print(json.dumps('\\')) "\\" >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) {"a": 0, "b": 0, "c": 0} >>> from io import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]' Compact encoding:: >>> import json >>> mydict = {'4': 5, '6': 7} >>> json.dumps([1,2,3,mydict], separators=(',', ':')) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: >>> import json >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)) { "4": 5, "6": 7 } Decoding JSON:: >>> import json >>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}] >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj True >>> json.loads('"\\"foo\\bar"') == '"foo\x08ar' True >>> from io import StringIO >>> io = StringIO('["streaming API"]') >>> json.load(io)[0] == 'streaming API' True Specializing JSON object decoding:: >>> import json >>> def as_complex(dct): ... if '__complex__' in dct: ... return complex(dct['real'], dct['imag']) ... return dct ... >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', ... object_hook=as_complex) (1+2j) >>> from decimal import Decimal >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') True Specializing JSON object encoding:: >>> import json >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... raise TypeError(f'Object of type {obj.__class__.__name__} ' ... f'is not JSON serializable') ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) '[2.0, 1.0]' >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) '[2.0, 1.0]' Using json.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } $ echo '{ 1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] __author__ = 'Bob Ippolito ' from .decoder import JSONDecoder, JSONDecodeError from .encoder import JSONEncoder import codecs _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, default=None, ) def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the strings written to ``fp`` can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): iterable = _default_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the return value can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): return _default_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).encode(obj) _default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None) def detect_encoding(b): bstartswith = b.startswith if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)): return 'utf-32' if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)): return 'utf-16' if bstartswith(codecs.BOM_UTF8): return 'utf-8-sig' if len(b) >= 4: if not b[0]: # 00 00 -- -- - utf-32-be # 00 XX -- -- - utf-16-be return 'utf-16-be' if b[1] else 'utf-32-be' if not b[1]: # XX 00 00 00 - utf-32-le # XX 00 00 XX - utf-16-le # XX 00 XX -- - utf-16-le return 'utf-16-le' if b[2] or b[3] else 'utf-32-le' elif len(b) == 2: if not b[0]: # 00 XX - utf-16-be return 'utf-16-be' if not b[1]: # XX 00 - utf-16-le return 'utf-16-le' # default return 'utf-8' def load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders. If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ return loads(fp.read(), cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) def loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders. If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. ``parse_float``, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal). ``parse_int``, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float). ``parse_constant``, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. The ``encoding`` argument is ignored and deprecated since Python 3.1. """ if isinstance(s, str): if s.startswith('\ufeff'): raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0) else: if not isinstance(s, (bytes, bytearray)): raise TypeError(f'the JSON object must be str, bytes or bytearray, ' f'not {s.__class__.__name__}') s = s.decode(detect_encoding(s), 'surrogatepass') if "encoding" in kw: import warnings warnings.warn( "'encoding' is ignored and deprecated. It will be removed in Python 3.9", DeprecationWarning, stacklevel=2 ) del kw['encoding'] if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s) lib64/python3.12/json/__init__.py000064400000033304152344753260012411 0ustar00r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is derived from a version of the externally maintained simplejson library. Encoding basic Python object hierarchies:: >>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print(json.dumps("\"foo\bar")) "\"foo\bar" >>> print(json.dumps('\u1234')) "\u1234" >>> print(json.dumps('\\')) "\\" >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) {"a": 0, "b": 0, "c": 0} >>> from io import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]' Compact encoding:: >>> import json >>> mydict = {'4': 5, '6': 7} >>> json.dumps([1,2,3,mydict], separators=(',', ':')) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: >>> import json >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)) { "4": 5, "6": 7 } Decoding JSON:: >>> import json >>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}] >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj True >>> json.loads('"\\"foo\\bar"') == '"foo\x08ar' True >>> from io import StringIO >>> io = StringIO('["streaming API"]') >>> json.load(io)[0] == 'streaming API' True Specializing JSON object decoding:: >>> import json >>> def as_complex(dct): ... if '__complex__' in dct: ... return complex(dct['real'], dct['imag']) ... return dct ... >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', ... object_hook=as_complex) (1+2j) >>> from decimal import Decimal >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') True Specializing JSON object encoding:: >>> import json >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... raise TypeError(f'Object of type {obj.__class__.__name__} ' ... f'is not JSON serializable') ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) '[2.0, 1.0]' >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) '[2.0, 1.0]' Using json.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } $ echo '{ 1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] __author__ = 'Bob Ippolito ' from .decoder import JSONDecoder, JSONDecodeError from .encoder import JSONEncoder import codecs _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, default=None, ) def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the strings written to ``fp`` can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``RecursionError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): iterable = _default_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the return value can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``RecursionError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): return _default_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).encode(obj) _default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None) def detect_encoding(b): bstartswith = b.startswith if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)): return 'utf-32' if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)): return 'utf-16' if bstartswith(codecs.BOM_UTF8): return 'utf-8-sig' if len(b) >= 4: if not b[0]: # 00 00 -- -- - utf-32-be # 00 XX -- -- - utf-16-be return 'utf-16-be' if b[1] else 'utf-32-be' if not b[1]: # XX 00 00 00 - utf-32-le # XX 00 00 XX - utf-16-le # XX 00 XX -- - utf-16-le return 'utf-16-le' if b[2] or b[3] else 'utf-32-le' elif len(b) == 2: if not b[0]: # 00 XX - utf-16-be return 'utf-16-be' if not b[1]: # XX 00 - utf-16-le return 'utf-16-le' # default return 'utf-8' def load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders. If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ return loads(fp.read(), cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) def loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders. If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. ``parse_float``, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal). ``parse_int``, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float). ``parse_constant``, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ if isinstance(s, str): if s.startswith('\ufeff'): raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0) else: if not isinstance(s, (bytes, bytearray)): raise TypeError(f'the JSON object must be str, bytes or bytearray, ' f'not {s.__class__.__name__}') s = s.decode(detect_encoding(s), 'surrogatepass') if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s) lib64/python3.6/json/__init__.py000064400000034074152344762750012345 0ustar00r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is derived from a version of the externally maintained simplejson library. Encoding basic Python object hierarchies:: >>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print(json.dumps("\"foo\bar")) "\"foo\bar" >>> print(json.dumps('\u1234')) "\u1234" >>> print(json.dumps('\\')) "\\" >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) {"a": 0, "b": 0, "c": 0} >>> from io import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]' Compact encoding:: >>> import json >>> from collections import OrderedDict >>> mydict = OrderedDict([('4', 5), ('6', 7)]) >>> json.dumps([1,2,3,mydict], separators=(',', ':')) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: >>> import json >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)) { "4": 5, "6": 7 } Decoding JSON:: >>> import json >>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}] >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj True >>> json.loads('"\\"foo\\bar"') == '"foo\x08ar' True >>> from io import StringIO >>> io = StringIO('["streaming API"]') >>> json.load(io)[0] == 'streaming API' True Specializing JSON object decoding:: >>> import json >>> def as_complex(dct): ... if '__complex__' in dct: ... return complex(dct['real'], dct['imag']) ... return dct ... >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', ... object_hook=as_complex) (1+2j) >>> from decimal import Decimal >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') True Specializing JSON object encoding:: >>> import json >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... raise TypeError(repr(obj) + " is not JSON serializable") ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) '[2.0, 1.0]' >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) '[2.0, 1.0]' Using json.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } $ echo '{ 1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] __author__ = 'Bob Ippolito ' from .decoder import JSONDecoder, JSONDecodeError from .encoder import JSONEncoder import codecs _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, default=None, ) def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the strings written to ``fp`` can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): iterable = _default_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the return value can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): return _default_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).encode(obj) _default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None) def detect_encoding(b): bstartswith = b.startswith if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)): return 'utf-32' if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)): return 'utf-16' if bstartswith(codecs.BOM_UTF8): return 'utf-8-sig' if len(b) >= 4: if not b[0]: # 00 00 -- -- - utf-32-be # 00 XX -- -- - utf-16-be return 'utf-16-be' if b[1] else 'utf-32-be' if not b[1]: # XX 00 00 00 - utf-32-le # XX 00 00 XX - utf-16-le # XX 00 XX -- - utf-16-le return 'utf-16-le' if b[2] or b[3] else 'utf-32-le' elif len(b) == 2: if not b[0]: # 00 XX - utf-16-be return 'utf-16-be' if not b[1]: # XX 00 - utf-16-le return 'utf-16-le' # default return 'utf-8' def load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict will remember the order of insertion). If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ return loads(fp.read(), cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) def loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict will remember the order of insertion). If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. ``parse_float``, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal). ``parse_int``, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float). ``parse_constant``, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. The ``encoding`` argument is ignored and deprecated. """ if isinstance(s, str): if s.startswith('\ufeff'): raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0) else: if not isinstance(s, (bytes, bytearray)): raise TypeError('the JSON object must be str, bytes or bytearray, ' 'not {!r}'.format(s.__class__.__name__)) s = s.decode(detect_encoding(s), 'surrogatepass') if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s) lib64/python3.6/asyncio/__init__.py000064400000002634152344764210013027 0ustar00"""The asyncio package, tracking PEP 3156.""" import sys # The selectors module is in the stdlib in Python 3.4 but not in 3.3. # Do this first, so the other submodules can use "from . import selectors". # Prefer asyncio/selectors.py over the stdlib one, as ours may be newer. try: from . import selectors except ImportError: import selectors # Will also be exported. if sys.platform == 'win32': # Similar thing for _overlapped. try: from . import _overlapped except ImportError: import _overlapped # Will also be exported. # This relies on each of the submodules having an __all__ variable. from .base_events import * from .coroutines import * from .events import * from .futures import * from .locks import * from .protocols import * from .queues import * from .streams import * from .subprocess import * from .tasks import * from .transports import * __all__ = (base_events.__all__ + coroutines.__all__ + events.__all__ + futures.__all__ + locks.__all__ + protocols.__all__ + queues.__all__ + streams.__all__ + subprocess.__all__ + tasks.__all__ + transports.__all__) if sys.platform == 'win32': # pragma: no cover from .windows_events import * __all__ += windows_events.__all__ else: from .unix_events import * # pragma: no cover __all__ += unix_events.__all__ lib64/python3.6/urllib/__init__.py000064400000000000152344767550012646 0ustar00usr/lib64/python2.7/xml/__init__.py000064400000001724152345031320012760 0ustar00"""Core XML support for Python. This package contains four sub-packages: dom -- The W3C Document Object Model. This supports DOM Level 1 + Namespaces. parsers -- Python wrappers for XML parsers (currently only supports Expat). sax -- The Simple API for XML, developed by XML-Dev, led by David Megginson and ported to Python by Lars Marius Garshol. This supports the SAX 2 API. etree -- The ElementTree XML library. This is a subset of the full ElementTree XML release. """ __all__ = ["dom", "parsers", "sax", "etree"] _MINIMUM_XMLPLUS_VERSION = (0, 8, 4) try: import _xmlplus except ImportError: pass else: try: v = _xmlplus.version_info except AttributeError: # _xmlplus is too old; ignore it pass else: if v >= _MINIMUM_XMLPLUS_VERSION: import sys _xmlplus.__path__.extend(__path__) sys.modules[__name__] = _xmlplus else: del v lib64/python3.8/collections/__init__.py000064400000135503152345046050013700 0ustar00'''This module implements specialized container datatypes providing alternatives to Python's general purpose built-in containers, dict, list, set, and tuple. * namedtuple factory function for creating tuple subclasses with named fields * deque list-like container with fast appends and pops on either end * ChainMap dict-like class for creating a single view of multiple mappings * Counter dict subclass for counting hashable objects * OrderedDict dict subclass that remembers the order entries were added * defaultdict dict subclass that calls a factory function to supply missing values * UserDict wrapper around dictionary objects for easier dict subclassing * UserList wrapper around list objects for easier list subclassing * UserString wrapper around string objects for easier string subclassing ''' __all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 'UserString', 'Counter', 'OrderedDict', 'ChainMap'] import _collections_abc from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from _weakref import proxy as _proxy from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from reprlib import recursive_repr as _recursive_repr try: from _collections import deque except ImportError: pass else: _collections_abc.MutableSequence.register(deque) try: from _collections import defaultdict except ImportError: pass def __getattr__(name): # For backwards compatibility, continue to make the collections ABCs # through Python 3.6 available through the collections module. # Note, no new collections ABCs were added in Python 3.7 if name in _collections_abc.__all__: obj = getattr(_collections_abc, name) import warnings warnings.warn("Using or importing the ABCs from 'collections' instead " "of from 'collections.abc' is deprecated since Python 3.3, " "and in 3.10 it will stop working", DeprecationWarning, stacklevel=2) globals()[name] = obj return obj raise AttributeError(f'module {__name__!r} has no attribute {name!r}') ################################################################################ ### OrderedDict ################################################################################ class _OrderedDictKeysView(_collections_abc.KeysView): def __reversed__(self): yield from reversed(self._mapping) class _OrderedDictItemsView(_collections_abc.ItemsView): def __reversed__(self): for key in reversed(self._mapping): yield (key, self._mapping[key]) class _OrderedDictValuesView(_collections_abc.ValuesView): def __reversed__(self): for key in reversed(self._mapping): yield self._mapping[key] class _Link(object): __slots__ = 'prev', 'next', 'key', '__weakref__' class OrderedDict(dict): 'Dictionary that remembers insertion order' # An inherited dict maps keys to values. # The inherited dict provides __getitem__, __len__, __contains__, and get. # The remaining methods are order-aware. # Big-O running times for all methods are the same as regular dictionaries. # The internal self.__map dict maps keys to links in a doubly linked list. # The circular doubly linked list starts and ends with a sentinel element. # The sentinel element never gets deleted (this simplifies the algorithm). # The sentinel is in self.__hardroot with a weakref proxy in self.__root. # The prev links are weakref proxies (to prevent circular references). # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. def __init__(self, other=(), /, **kwds): '''Initialize an ordered dictionary. The signature is the same as regular dictionaries. Keyword argument order is preserved. ''' try: self.__root except AttributeError: self.__hardroot = _Link() self.__root = root = _proxy(self.__hardroot) root.prev = root.next = root self.__map = {} self.__update(other, **kwds) def __setitem__(self, key, value, dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: self.__map[key] = link = Link() root = self.__root last = root.prev link.prev, link.next, link.key = last, root, key last.next = link root.prev = proxy(link) dict_setitem(self, key, value) def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link = self.__map.pop(key) link_prev = link.prev link_next = link.next link_prev.next = link_next link_next.prev = link_prev link.prev = None link.next = None def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. root = self.__root curr = root.next while curr is not root: yield curr.key curr = curr.next def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. root = self.__root curr = root.prev while curr is not root: yield curr.key curr = curr.prev def clear(self): 'od.clear() -> None. Remove all items from od.' root = self.__root root.prev = root.next = root self.__map.clear() dict.clear(self) def popitem(self, last=True): '''Remove and return a (key, value) pair from the dictionary. Pairs are returned in LIFO order if last is true or FIFO order if false. ''' if not self: raise KeyError('dictionary is empty') root = self.__root if last: link = root.prev link_prev = link.prev link_prev.next = root root.prev = link_prev else: link = root.next link_next = link.next root.next = link_next link_next.prev = root key = link.key del self.__map[key] value = dict.pop(self, key) return key, value def move_to_end(self, key, last=True): '''Move an existing element to the end (or beginning if last is false). Raise KeyError if the element does not exist. ''' link = self.__map[key] link_prev = link.prev link_next = link.next soft_link = link_next.prev link_prev.next = link_next link_next.prev = link_prev root = self.__root if last: last = root.prev link.prev = last link.next = root root.prev = soft_link last.next = link else: first = root.next link.prev = root link.next = first first.prev = soft_link root.next = link def __sizeof__(self): sizeof = _sys.getsizeof n = len(self) + 1 # number of links including root size = sizeof(self.__dict__) # instance dictionary size += sizeof(self.__map) * 2 # internal dict and inherited dict size += sizeof(self.__hardroot) * n # link objects size += sizeof(self.__root) * n # proxy objects return size update = __update = _collections_abc.MutableMapping.update def keys(self): "D.keys() -> a set-like object providing a view on D's keys" return _OrderedDictKeysView(self) def items(self): "D.items() -> a set-like object providing a view on D's items" return _OrderedDictItemsView(self) def values(self): "D.values() -> an object providing a view on D's values" return _OrderedDictValuesView(self) __ne__ = _collections_abc.MutableMapping.__ne__ __marker = object() def pop(self, key, default=__marker): '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised. ''' if key in self: result = self[key] del self[key] return result if default is self.__marker: raise KeyError(key) return default def setdefault(self, key, default=None): '''Insert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default. ''' if key in self: return self[key] self[key] = default return default @_recursive_repr() def __repr__(self): 'od.__repr__() <==> repr(od)' if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, list(self.items())) def __reduce__(self): 'Return state information for pickling' inst_dict = vars(self).copy() for k in vars(OrderedDict()): inst_dict.pop(k, None) return self.__class__, (), inst_dict or None, None, iter(self.items()) def copy(self): 'od.copy() -> a shallow copy of od' return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): '''Create a new ordered dictionary with keys from iterable and values set to value. ''' self = cls() for key in iterable: self[key] = value return self def __eq__(self, other): '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive while comparison to a regular mapping is order-insensitive. ''' if isinstance(other, OrderedDict): return dict.__eq__(self, other) and all(map(_eq, self, other)) return dict.__eq__(self, other) try: from _collections import OrderedDict except ImportError: # Leave the pure Python version in place. pass ################################################################################ ### namedtuple ################################################################################ try: from _collections import _tuplegetter except ImportError: _tuplegetter = lambda index, doc: property(_itemgetter(index), doc=doc) def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None): """Returns a new subclass of tuple with named fields. >>> Point = namedtuple('Point', ['x', 'y']) >>> Point.__doc__ # docstring for the new class 'Point(x, y)' >>> p = Point(11, y=22) # instantiate with positional args or keywords >>> p[0] + p[1] # indexable like a plain tuple 33 >>> x, y = p # unpack like a regular tuple >>> x, y (11, 22) >>> p.x + p.y # fields also accessible by name 33 >>> d = p._asdict() # convert to a dictionary >>> d['x'] 11 >>> Point(**d) # convert from a dictionary Point(x=11, y=22) >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields Point(x=100, y=22) """ # Validate the field names. At the user's option, either generate an error # message or automatically replace the field name with a valid name. if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() field_names = list(map(str, field_names)) typename = _sys.intern(str(typename)) if rename: seen = set() for index, name in enumerate(field_names): if (not name.isidentifier() or _iskeyword(name) or name.startswith('_') or name in seen): field_names[index] = f'_{index}' seen.add(name) for name in [typename] + field_names: if type(name) is not str: raise TypeError('Type names and field names must be strings') if not name.isidentifier(): raise ValueError('Type names and field names must be valid ' f'identifiers: {name!r}') if _iskeyword(name): raise ValueError('Type names and field names cannot be a ' f'keyword: {name!r}') seen = set() for name in field_names: if name.startswith('_') and not rename: raise ValueError('Field names cannot start with an underscore: ' f'{name!r}') if name in seen: raise ValueError(f'Encountered duplicate field name: {name!r}') seen.add(name) field_defaults = {} if defaults is not None: defaults = tuple(defaults) if len(defaults) > len(field_names): raise TypeError('Got more default values than field names') field_defaults = dict(reversed(list(zip(reversed(field_names), reversed(defaults))))) # Variables used in the methods and docstrings field_names = tuple(map(_sys.intern, field_names)) num_fields = len(field_names) arg_list = repr(field_names).replace("'", "")[1:-1] repr_fmt = '(' + ', '.join(f'{name}=%r' for name in field_names) + ')' tuple_new = tuple.__new__ _dict, _tuple, _len, _map, _zip = dict, tuple, len, map, zip # Create all the named tuple methods to be added to the class namespace s = f'def __new__(_cls, {arg_list}): return _tuple_new(_cls, ({arg_list}))' namespace = {'_tuple_new': tuple_new, '__name__': f'namedtuple_{typename}'} # Note: exec() has the side-effect of interning the field names exec(s, namespace) __new__ = namespace['__new__'] __new__.__doc__ = f'Create new instance of {typename}({arg_list})' if defaults is not None: __new__.__defaults__ = defaults @classmethod def _make(cls, iterable): result = tuple_new(cls, iterable) if _len(result) != num_fields: raise TypeError(f'Expected {num_fields} arguments, got {len(result)}') return result _make.__func__.__doc__ = (f'Make a new {typename} object from a sequence ' 'or iterable') def _replace(self, /, **kwds): result = self._make(_map(kwds.pop, field_names, self)) if kwds: raise ValueError(f'Got unexpected field names: {list(kwds)!r}') return result _replace.__doc__ = (f'Return a new {typename} object replacing specified ' 'fields with new values') def __repr__(self): 'Return a nicely formatted representation string' return self.__class__.__name__ + repr_fmt % self def _asdict(self): 'Return a new dict which maps field names to their values.' return _dict(_zip(self._fields, self)) def __getnewargs__(self): 'Return self as a plain tuple. Used by copy and pickle.' return _tuple(self) # Modify function metadata to help with introspection and debugging for method in (__new__, _make.__func__, _replace, __repr__, _asdict, __getnewargs__): method.__qualname__ = f'{typename}.{method.__name__}' # Build-up the class namespace dictionary # and use type() to build the result class class_namespace = { '__doc__': f'{typename}({arg_list})', '__slots__': (), '_fields': field_names, '_field_defaults': field_defaults, # alternate spelling for backward compatibility '_fields_defaults': field_defaults, '__new__': __new__, '_make': _make, '_replace': _replace, '__repr__': __repr__, '_asdict': _asdict, '__getnewargs__': __getnewargs__, } for index, name in enumerate(field_names): doc = _sys.intern(f'Alias for field number {index}') class_namespace[name] = _tuplegetter(index, doc) result = type(typename, (tuple,), class_namespace) # For pickling to work, the __module__ variable needs to be set to the frame # where the named tuple is created. Bypass this step in environments where # sys._getframe is not defined (Jython for example) or sys._getframe is not # defined for arguments greater than 0 (IronPython), or where the user has # specified a particular module. if module is None: try: module = _sys._getframe(1).f_globals.get('__name__', '__main__') except (AttributeError, ValueError): pass if module is not None: result.__module__ = module return result ######################################################################## ### Counter ######################################################################## def _count_elements(mapping, iterable): 'Tally elements from the iterable.' mapping_get = mapping.get for elem in iterable: mapping[elem] = mapping_get(elem, 0) + 1 try: # Load C helper function if available from _collections import _count_elements except ImportError: pass class Counter(dict): '''Dict subclass for counting hashable items. Sometimes called a bag or multiset. Elements are stored as dictionary keys and their counts are stored as dictionary values. >>> c = Counter('abcdeabcdabcaba') # count elements from a string >>> c.most_common(3) # three most common elements [('a', 5), ('b', 4), ('c', 3)] >>> sorted(c) # list all unique elements ['a', 'b', 'c', 'd', 'e'] >>> ''.join(sorted(c.elements())) # list elements with repetitions 'aaaaabbbbcccdde' >>> sum(c.values()) # total of all counts 15 >>> c['a'] # count of letter 'a' 5 >>> for elem in 'shazam': # update counts from an iterable ... c[elem] += 1 # by adding 1 to each element's count >>> c['a'] # now there are seven 'a' 7 >>> del c['b'] # remove all 'b' >>> c['b'] # now there are zero 'b' 0 >>> d = Counter('simsalabim') # make another counter >>> c.update(d) # add in the second counter >>> c['a'] # now there are nine 'a' 9 >>> c.clear() # empty the counter >>> c Counter() Note: If a count is set to zero or reduced to zero, it will remain in the counter until the entry is deleted or the counter is cleared: >>> c = Counter('aaabbc') >>> c['b'] -= 2 # reduce the count of 'b' by two >>> c.most_common() # 'b' is still in, but its count is zero [('a', 3), ('c', 1), ('b', 0)] ''' # References: # http://en.wikipedia.org/wiki/Multiset # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm # http://code.activestate.com/recipes/259174/ # Knuth, TAOCP Vol. II section 4.6.3 def __init__(self, iterable=None, /, **kwds): '''Create a new, empty Counter object. And if given, count elements from an input iterable. Or, initialize the count from another mapping of elements to their counts. >>> c = Counter() # a new, empty counter >>> c = Counter('gallahad') # a new counter from an iterable >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping >>> c = Counter(a=4, b=2) # a new counter from keyword args ''' super(Counter, self).__init__() self.update(iterable, **kwds) def __missing__(self, key): 'The count of elements not in the Counter is zero.' # Needed so that self[missing_item] does not raise KeyError return 0 def most_common(self, n=None): '''List the n most common elements and their counts from the most common to the least. If n is None, then list all element counts. >>> Counter('abracadabra').most_common(3) [('a', 5), ('b', 2), ('r', 2)] ''' # Emulate Bag.sortedByCount from Smalltalk if n is None: return sorted(self.items(), key=_itemgetter(1), reverse=True) return _heapq.nlargest(n, self.items(), key=_itemgetter(1)) def elements(self): '''Iterator over elements repeating each as many times as its count. >>> c = Counter('ABCABC') >>> sorted(c.elements()) ['A', 'A', 'B', 'B', 'C', 'C'] # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) >>> product = 1 >>> for factor in prime_factors.elements(): # loop over factors ... product *= factor # and multiply them >>> product 1836 Note, if an element's count has been set to zero or is a negative number, elements() will ignore it. ''' # Emulate Bag.do from Smalltalk and Multiset.begin from C++. return _chain.from_iterable(_starmap(_repeat, self.items())) # Override dict methods where necessary @classmethod def fromkeys(cls, iterable, v=None): # There is no equivalent method for counters because the semantics # would be ambiguous in cases such as Counter.fromkeys('aaabbc', v=2). # Initializing counters to zero values isn't necessary because zero # is already the default value for counter lookups. Initializing # to one is easily accomplished with Counter(set(iterable)). For # more exotic cases, create a dictionary first using a dictionary # comprehension or dict.fromkeys(). raise NotImplementedError( 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') def update(self, iterable=None, /, **kwds): '''Like dict.update() but add counts instead of replacing them. Source can be an iterable, a dictionary, or another Counter instance. >>> c = Counter('which') >>> c.update('witch') # add elements from another iterable >>> d = Counter('watch') >>> c.update(d) # add elements from another counter >>> c['h'] # four 'h' in which, witch, and watch 4 ''' # The regular dict.update() operation makes no sense here because the # replace behavior results in the some of original untouched counts # being mixed-in with all of the other counts for a mismash that # doesn't have a straight-forward interpretation in most counting # contexts. Instead, we implement straight-addition. Both the inputs # and outputs are allowed to contain zero and negative counts. if iterable is not None: if isinstance(iterable, _collections_abc.Mapping): if self: self_get = self.get for elem, count in iterable.items(): self[elem] = count + self_get(elem, 0) else: super(Counter, self).update(iterable) # fast path when counter is empty else: _count_elements(self, iterable) if kwds: self.update(kwds) def subtract(self, iterable=None, /, **kwds): '''Like dict.update() but subtracts counts instead of replacing them. Counts can be reduced below zero. Both the inputs and outputs are allowed to contain zero and negative counts. Source can be an iterable, a dictionary, or another Counter instance. >>> c = Counter('which') >>> c.subtract('witch') # subtract elements from another iterable >>> c.subtract(Counter('watch')) # subtract elements from another counter >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch 0 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch -1 ''' if iterable is not None: self_get = self.get if isinstance(iterable, _collections_abc.Mapping): for elem, count in iterable.items(): self[elem] = self_get(elem, 0) - count else: for elem in iterable: self[elem] = self_get(elem, 0) - 1 if kwds: self.subtract(kwds) def copy(self): 'Return a shallow copy.' return self.__class__(self) def __reduce__(self): return self.__class__, (dict(self),) def __delitem__(self, elem): 'Like dict.__delitem__() but does not raise KeyError for missing values.' if elem in self: super().__delitem__(elem) def __repr__(self): if not self: return '%s()' % self.__class__.__name__ try: items = ', '.join(map('%r: %r'.__mod__, self.most_common())) return '%s({%s})' % (self.__class__.__name__, items) except TypeError: # handle case where values are not orderable return '{0}({1!r})'.format(self.__class__.__name__, dict(self)) # Multiset-style mathematical operations discussed in: # Knuth TAOCP Volume II section 4.6.3 exercise 19 # and at http://en.wikipedia.org/wiki/Multiset # # Outputs guaranteed to only include positive counts. # # To strip negative and zero counts, add-in an empty counter: # c += Counter() # # Rich comparison operators for multiset subset and superset tests # are deliberately omitted due to semantic conflicts with the # existing inherited dict equality method. Subset and superset # semantics ignore zero counts and require that p≤q ∧ p≥q → p=q; # however, that would not be the case for p=Counter(a=1, b=0) # and q=Counter(a=1) where the dictionaries are not equal. def __add__(self, other): '''Add counts from two counters. >>> Counter('abbb') + Counter('bcc') Counter({'b': 4, 'c': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): newcount = count + other[elem] if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count > 0: result[elem] = count return result def __sub__(self, other): ''' Subtract count, but keep only results with positive counts. >>> Counter('abbbc') - Counter('bccd') Counter({'b': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): newcount = count - other[elem] if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count < 0: result[elem] = 0 - count return result def __or__(self, other): '''Union is the maximum of value in either of the input counters. >>> Counter('abbb') | Counter('bcc') Counter({'b': 3, 'c': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): other_count = other[elem] newcount = other_count if count < other_count else count if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count > 0: result[elem] = count return result def __and__(self, other): ''' Intersection is the minimum of corresponding counts. >>> Counter('abbb') & Counter('bcc') Counter({'b': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): other_count = other[elem] newcount = count if count < other_count else other_count if newcount > 0: result[elem] = newcount return result def __pos__(self): 'Adds an empty counter, effectively stripping negative and zero counts' result = Counter() for elem, count in self.items(): if count > 0: result[elem] = count return result def __neg__(self): '''Subtracts from an empty counter. Strips positive and zero counts, and flips the sign on negative counts. ''' result = Counter() for elem, count in self.items(): if count < 0: result[elem] = 0 - count return result def _keep_positive(self): '''Internal method to strip elements with a negative or zero count''' nonpositive = [elem for elem, count in self.items() if not count > 0] for elem in nonpositive: del self[elem] return self def __iadd__(self, other): '''Inplace add from another counter, keeping only positive counts. >>> c = Counter('abbb') >>> c += Counter('bcc') >>> c Counter({'b': 4, 'c': 2, 'a': 1}) ''' for elem, count in other.items(): self[elem] += count return self._keep_positive() def __isub__(self, other): '''Inplace subtract counter, but keep only results with positive counts. >>> c = Counter('abbbc') >>> c -= Counter('bccd') >>> c Counter({'b': 2, 'a': 1}) ''' for elem, count in other.items(): self[elem] -= count return self._keep_positive() def __ior__(self, other): '''Inplace union is the maximum of value from either counter. >>> c = Counter('abbb') >>> c |= Counter('bcc') >>> c Counter({'b': 3, 'c': 2, 'a': 1}) ''' for elem, other_count in other.items(): count = self[elem] if other_count > count: self[elem] = other_count return self._keep_positive() def __iand__(self, other): '''Inplace intersection is the minimum of corresponding counts. >>> c = Counter('abbb') >>> c &= Counter('bcc') >>> c Counter({'b': 1}) ''' for elem, count in self.items(): other_count = other[elem] if other_count < count: self[elem] = other_count return self._keep_positive() ######################################################################## ### ChainMap ######################################################################## class ChainMap(_collections_abc.MutableMapping): ''' A ChainMap groups multiple dicts (or other mappings) together to create a single, updateable view. The underlying mappings are stored in a list. That list is public and can be accessed or updated using the *maps* attribute. There is no other state. Lookups search the underlying mappings successively until a key is found. In contrast, writes, updates, and deletions only operate on the first mapping. ''' def __init__(self, *maps): '''Initialize a ChainMap by setting *maps* to the given mappings. If no mappings are provided, a single empty dictionary is used. ''' self.maps = list(maps) or [{}] # always at least one map def __missing__(self, key): raise KeyError(key) def __getitem__(self, key): for mapping in self.maps: try: return mapping[key] # can't use 'key in mapping' with defaultdict except KeyError: pass return self.__missing__(key) # support subclasses that define __missing__ def get(self, key, default=None): return self[key] if key in self else default def __len__(self): return len(set().union(*self.maps)) # reuses stored hash values if possible def __iter__(self): d = {} for mapping in reversed(self.maps): d.update(mapping) # reuses stored hash values if possible return iter(d) def __contains__(self, key): return any(key in m for m in self.maps) def __bool__(self): return any(self.maps) @_recursive_repr() def __repr__(self): return f'{self.__class__.__name__}({", ".join(map(repr, self.maps))})' @classmethod def fromkeys(cls, iterable, *args): 'Create a ChainMap with a single dict created from the iterable.' return cls(dict.fromkeys(iterable, *args)) def copy(self): 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' return self.__class__(self.maps[0].copy(), *self.maps[1:]) __copy__ = copy def new_child(self, m=None): # like Django's Context.push() '''New ChainMap with a new map followed by all previous maps. If no map is provided, an empty dict is used. ''' if m is None: m = {} return self.__class__(m, *self.maps) @property def parents(self): # like Django's Context.pop() 'New ChainMap from maps[1:].' return self.__class__(*self.maps[1:]) def __setitem__(self, key, value): self.maps[0][key] = value def __delitem__(self, key): try: del self.maps[0][key] except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def popitem(self): 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' try: return self.maps[0].popitem() except KeyError: raise KeyError('No keys found in the first mapping.') def pop(self, key, *args): 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' try: return self.maps[0].pop(key, *args) except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def clear(self): 'Clear maps[0], leaving maps[1:] intact.' self.maps[0].clear() ################################################################################ ### UserDict ################################################################################ class UserDict(_collections_abc.MutableMapping): # Start by filling-out the abstract methods def __init__(*args, **kwargs): if not args: raise TypeError("descriptor '__init__' of 'UserDict' object " "needs an argument") self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) if args: dict = args[0] elif 'dict' in kwargs: dict = kwargs.pop('dict') import warnings warnings.warn("Passing 'dict' as keyword argument is deprecated", DeprecationWarning, stacklevel=2) else: dict = None self.data = {} if dict is not None: self.update(dict) if kwargs: self.update(kwargs) __init__.__text_signature__ = '($self, dict=None, /, **kwargs)' def __len__(self): return len(self.data) def __getitem__(self, key): if key in self.data: return self.data[key] if hasattr(self.__class__, "__missing__"): return self.__class__.__missing__(self, key) raise KeyError(key) def __setitem__(self, key, item): self.data[key] = item def __delitem__(self, key): del self.data[key] def __iter__(self): return iter(self.data) # Modify __contains__ to work correctly when __missing__ is present def __contains__(self, key): return key in self.data # Now, add the methods in dicts but not in MutableMapping def __repr__(self): return repr(self.data) def __copy__(self): inst = self.__class__.__new__(self.__class__) inst.__dict__.update(self.__dict__) # Create a copy and avoid triggering descriptors inst.__dict__["data"] = self.__dict__["data"].copy() return inst def copy(self): if self.__class__ is UserDict: return UserDict(self.data.copy()) import copy data = self.data try: self.data = {} c = copy.copy(self) finally: self.data = data c.update(self) return c @classmethod def fromkeys(cls, iterable, value=None): d = cls() for key in iterable: d[key] = value return d ################################################################################ ### UserList ################################################################################ class UserList(_collections_abc.MutableSequence): """A more or less complete user-defined wrapper around list objects.""" def __init__(self, initlist=None): self.data = [] if initlist is not None: # XXX should this accept an arbitrary sequence? if type(initlist) == type(self.data): self.data[:] = initlist elif isinstance(initlist, UserList): self.data[:] = initlist.data[:] else: self.data = list(initlist) def __repr__(self): return repr(self.data) def __lt__(self, other): return self.data < self.__cast(other) def __le__(self, other): return self.data <= self.__cast(other) def __eq__(self, other): return self.data == self.__cast(other) def __gt__(self, other): return self.data > self.__cast(other) def __ge__(self, other): return self.data >= self.__cast(other) def __cast(self, other): return other.data if isinstance(other, UserList) else other def __contains__(self, item): return item in self.data def __len__(self): return len(self.data) def __getitem__(self, i): if isinstance(i, slice): return self.__class__(self.data[i]) else: return self.data[i] def __setitem__(self, i, item): self.data[i] = item def __delitem__(self, i): del self.data[i] def __add__(self, other): if isinstance(other, UserList): return self.__class__(self.data + other.data) elif isinstance(other, type(self.data)): return self.__class__(self.data + other) return self.__class__(self.data + list(other)) def __radd__(self, other): if isinstance(other, UserList): return self.__class__(other.data + self.data) elif isinstance(other, type(self.data)): return self.__class__(other + self.data) return self.__class__(list(other) + self.data) def __iadd__(self, other): if isinstance(other, UserList): self.data += other.data elif isinstance(other, type(self.data)): self.data += other else: self.data += list(other) return self def __mul__(self, n): return self.__class__(self.data*n) __rmul__ = __mul__ def __imul__(self, n): self.data *= n return self def __copy__(self): inst = self.__class__.__new__(self.__class__) inst.__dict__.update(self.__dict__) # Create a copy and avoid triggering descriptors inst.__dict__["data"] = self.__dict__["data"][:] return inst def append(self, item): self.data.append(item) def insert(self, i, item): self.data.insert(i, item) def pop(self, i=-1): return self.data.pop(i) def remove(self, item): self.data.remove(item) def clear(self): self.data.clear() def copy(self): return self.__class__(self) def count(self, item): return self.data.count(item) def index(self, item, *args): return self.data.index(item, *args) def reverse(self): self.data.reverse() def sort(self, /, *args, **kwds): self.data.sort(*args, **kwds) def extend(self, other): if isinstance(other, UserList): self.data.extend(other.data) else: self.data.extend(other) ################################################################################ ### UserString ################################################################################ class UserString(_collections_abc.Sequence): def __init__(self, seq): if isinstance(seq, str): self.data = seq elif isinstance(seq, UserString): self.data = seq.data[:] else: self.data = str(seq) def __str__(self): return str(self.data) def __repr__(self): return repr(self.data) def __int__(self): return int(self.data) def __float__(self): return float(self.data) def __complex__(self): return complex(self.data) def __hash__(self): return hash(self.data) def __getnewargs__(self): return (self.data[:],) def __eq__(self, string): if isinstance(string, UserString): return self.data == string.data return self.data == string def __lt__(self, string): if isinstance(string, UserString): return self.data < string.data return self.data < string def __le__(self, string): if isinstance(string, UserString): return self.data <= string.data return self.data <= string def __gt__(self, string): if isinstance(string, UserString): return self.data > string.data return self.data > string def __ge__(self, string): if isinstance(string, UserString): return self.data >= string.data return self.data >= string def __contains__(self, char): if isinstance(char, UserString): char = char.data return char in self.data def __len__(self): return len(self.data) def __getitem__(self, index): return self.__class__(self.data[index]) def __add__(self, other): if isinstance(other, UserString): return self.__class__(self.data + other.data) elif isinstance(other, str): return self.__class__(self.data + other) return self.__class__(self.data + str(other)) def __radd__(self, other): if isinstance(other, str): return self.__class__(other + self.data) return self.__class__(str(other) + self.data) def __mul__(self, n): return self.__class__(self.data*n) __rmul__ = __mul__ def __mod__(self, args): return self.__class__(self.data % args) def __rmod__(self, template): return self.__class__(str(template) % self) # the following methods are defined in alphabetical order: def capitalize(self): return self.__class__(self.data.capitalize()) def casefold(self): return self.__class__(self.data.casefold()) def center(self, width, *args): return self.__class__(self.data.center(width, *args)) def count(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.count(sub, start, end) def encode(self, encoding='utf-8', errors='strict'): encoding = 'utf-8' if encoding is None else encoding errors = 'strict' if errors is None else errors return self.data.encode(encoding, errors) def endswith(self, suffix, start=0, end=_sys.maxsize): return self.data.endswith(suffix, start, end) def expandtabs(self, tabsize=8): return self.__class__(self.data.expandtabs(tabsize)) def find(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.find(sub, start, end) def format(self, /, *args, **kwds): return self.data.format(*args, **kwds) def format_map(self, mapping): return self.data.format_map(mapping) def index(self, sub, start=0, end=_sys.maxsize): return self.data.index(sub, start, end) def isalpha(self): return self.data.isalpha() def isalnum(self): return self.data.isalnum() def isascii(self): return self.data.isascii() def isdecimal(self): return self.data.isdecimal() def isdigit(self): return self.data.isdigit() def isidentifier(self): return self.data.isidentifier() def islower(self): return self.data.islower() def isnumeric(self): return self.data.isnumeric() def isprintable(self): return self.data.isprintable() def isspace(self): return self.data.isspace() def istitle(self): return self.data.istitle() def isupper(self): return self.data.isupper() def join(self, seq): return self.data.join(seq) def ljust(self, width, *args): return self.__class__(self.data.ljust(width, *args)) def lower(self): return self.__class__(self.data.lower()) def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars)) maketrans = str.maketrans def partition(self, sep): return self.data.partition(sep) def replace(self, old, new, maxsplit=-1): if isinstance(old, UserString): old = old.data if isinstance(new, UserString): new = new.data return self.__class__(self.data.replace(old, new, maxsplit)) def rfind(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.rfind(sub, start, end) def rindex(self, sub, start=0, end=_sys.maxsize): return self.data.rindex(sub, start, end) def rjust(self, width, *args): return self.__class__(self.data.rjust(width, *args)) def rpartition(self, sep): return self.data.rpartition(sep) def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars)) def split(self, sep=None, maxsplit=-1): return self.data.split(sep, maxsplit) def rsplit(self, sep=None, maxsplit=-1): return self.data.rsplit(sep, maxsplit) def splitlines(self, keepends=False): return self.data.splitlines(keepends) def startswith(self, prefix, start=0, end=_sys.maxsize): return self.data.startswith(prefix, start, end) def strip(self, chars=None): return self.__class__(self.data.strip(chars)) def swapcase(self): return self.__class__(self.data.swapcase()) def title(self): return self.__class__(self.data.title()) def translate(self, *args): return self.__class__(self.data.translate(*args)) def upper(self): return self.__class__(self.data.upper()) def zfill(self, width): return self.__class__(self.data.zfill(width)) usr/lib64/python3.8/logging/__init__.py000064400000230204152345046750013622 0ustar00# Copyright 2001-2017 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation, and that the name of Vinay Sajip # not be used in advertising or publicity pertaining to distribution # of the software without specific, written prior permission. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. Copyright (C) 2001-2017 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import sys, os, time, io, re, traceback, warnings, weakref, collections.abc from string import Template from string import Formatter as StrFormatter __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', 'lastResort', 'raiseExceptions'] import threading __author__ = "Vinay Sajip " __status__ = "production" # The following module attributes are no longer updated. __version__ = "0.5.1.2" __date__ = "07 February 2010" #--------------------------------------------------------------------------- # Miscellaneous module data #--------------------------------------------------------------------------- # #_startTime is used as the base when calculating the relative time of events # _startTime = time.time() # #raiseExceptions is used to see if exceptions during handling should be #propagated # raiseExceptions = True # # If you don't want threading information in the log, set this to zero # logThreads = True # # If you don't want multiprocessing information in the log, set this to zero # logMultiprocessing = True # # If you don't want process information in the log, set this to zero # logProcesses = True #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- # # Default levels and level names, these can be replaced with any positive set # of values having corresponding names. There is a pseudo-level, NOTSET, which # is only really there as a lower limit for user-defined levels. Handlers and # loggers are initialized with NOTSET so that they will log all messages, even # at user-defined levels. # CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 _levelToName = { CRITICAL: 'CRITICAL', ERROR: 'ERROR', WARNING: 'WARNING', INFO: 'INFO', DEBUG: 'DEBUG', NOTSET: 'NOTSET', } _nameToLevel = { 'CRITICAL': CRITICAL, 'FATAL': FATAL, 'ERROR': ERROR, 'WARN': WARNING, 'WARNING': WARNING, 'INFO': INFO, 'DEBUG': DEBUG, 'NOTSET': NOTSET, } def getLevelName(level): """ Return the textual or numeric representation of logging level 'level'. If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, INFO, DEBUG) then you get the corresponding string. If you have associated levels with names using addLevelName then the name you have associated with 'level' is returned. If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned. If a string representation of the level is passed in, the corresponding numeric value is returned. If no matching numeric or string value is passed in, the string 'Level %s' % level is returned. """ # See Issues #22386, #27937 and #29220 for why it's this way result = _levelToName.get(level) if result is not None: return result result = _nameToLevel.get(level) if result is not None: return result return "Level %s" % level def addLevelName(level, levelName): """ Associate 'levelName' with 'level'. This is used when converting levels to text during message formatting. """ _acquireLock() try: #unlikely to cause an exception, but you never know... _levelToName[level] = levelName _nameToLevel[levelName] = level finally: _releaseLock() if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) else: #pragma: no cover def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise Exception except Exception: return sys.exc_info()[2].tb_frame.f_back # # _srcfile is used when walking the stack to check when we've got the first # caller stack frame, by skipping frames whose filename is that of this # module's source. It therefore should contain the filename of this module's # source file. # # Ordinarily we would use __file__ for this, but frozen modules don't always # have __file__ set, for some reason (see Issue #21736). Thus, we get the # filename from a handy code object from a function defined in this module. # (There's no particular reason for picking addLevelName.) # _srcfile = os.path.normcase(addLevelName.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). # To provide compatibility with older versions of Python, set _srcfile # to None if _getframe() is not available; this value will prevent # findCaller() from being called. You can also do this if you want to avoid # the overhead of fetching caller information, even when _getframe() is # available. #if not hasattr(sys, '_getframe'): # _srcfile = None def _checkLevel(level): if isinstance(level, int): rv = level elif str(level) == level: if level not in _nameToLevel: raise ValueError("Unknown level: %r" % level) rv = _nameToLevel[level] else: raise TypeError("Level not an integer or a valid string: %r" % level) return rv #--------------------------------------------------------------------------- # Thread-related stuff #--------------------------------------------------------------------------- # #_lock is used to serialize access to shared data structures in this module. #This needs to be an RLock because fileConfig() creates and configures #Handlers, and so might arbitrary user threads. Since Handler code updates the #shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # _lock = threading.RLock() def _acquireLock(): """ Acquire the module-level lock for serializing access to shared data. This should be released with _releaseLock(). """ if _lock: _lock.acquire() def _releaseLock(): """ Release the module-level lock acquired by calling _acquireLock(). """ if _lock: _lock.release() # Prevent a held logging lock from blocking a child from logging. if not hasattr(os, 'register_at_fork'): # Windows and friends. def _register_at_fork_reinit_lock(instance): pass # no-op when os.register_at_fork does not exist. else: # A collection of instances with a createLock method (logging.Handler) # to be called in the child after forking. The weakref avoids us keeping # discarded Handler instances alive. A set is used to avoid accumulating # duplicate registrations as createLock() is responsible for registering # a new Handler instance with this set in the first place. _at_fork_reinit_lock_weakset = weakref.WeakSet() def _register_at_fork_reinit_lock(instance): _acquireLock() try: _at_fork_reinit_lock_weakset.add(instance) finally: _releaseLock() def _after_at_fork_child_reinit_locks(): # _acquireLock() was called in the parent before forking. for handler in _at_fork_reinit_lock_weakset: try: handler.createLock() except Exception as err: # Similar to what PyErr_WriteUnraisable does. print("Ignoring exception from logging atfork", instance, "._reinit_lock() method:", err, file=sys.stderr) _releaseLock() # Acquired by os.register_at_fork(before=. os.register_at_fork(before=_acquireLock, after_in_child=_after_at_fork_child_reinit_locks, after_in_parent=_releaseLock) #--------------------------------------------------------------------------- # The logging record #--------------------------------------------------------------------------- class LogRecord(object): """ A LogRecord instance represents an event being logged. LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is in msg and args, which are combined using str(msg) % args to create the message field of the record. The record also includes information such as when the record was created, the source line where the logging call was made, and any exception information to be logged. """ def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None, **kwargs): """ Initialize a logging record with interesting information. """ ct = time.time() self.name = name self.msg = msg # # The following statement allows passing of a dictionary as a sole # argument, so that you can do something like # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) # Suggested by Stefan Behnel. # Note that without the test for args[0], we get a problem because # during formatting, we test to see if the arg is present using # 'if self.args:'. If the event being logged is e.g. 'Value is %d' # and if the passed arg fails 'if self.args:' then no formatting # is done. For example, logger.warning('Value is %d', 0) would log # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. # Issue #21172: a request was made to relax the isinstance check # to hasattr(args[0], '__getitem__'). However, the docs on string # formatting still seem to suggest a mapping object is required. # Thus, while not removing the isinstance check, it does now look # for collections.abc.Mapping rather than, as before, dict. if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping) and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) self.levelno = level self.pathname = pathname try: self.filename = os.path.basename(pathname) self.module = os.path.splitext(self.filename)[0] except (TypeError, ValueError, AttributeError): self.filename = pathname self.module = "Unknown module" self.exc_info = exc_info self.exc_text = None # used to cache the traceback text self.stack_info = sinfo self.lineno = lineno self.funcName = func self.created = ct self.msecs = (ct - int(ct)) * 1000 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads: self.thread = threading.get_ident() self.threadName = threading.current_thread().name else: # pragma: no cover self.thread = None self.threadName = None if not logMultiprocessing: # pragma: no cover self.processName = None else: self.processName = 'MainProcess' mp = sys.modules.get('multiprocessing') if mp is not None: # Errors may occur if multiprocessing has not finished loading # yet - e.g. if a custom import hook causes third-party code # to run when multiprocessing calls import. See issue 8200 # for an example try: self.processName = mp.current_process().name except Exception: #pragma: no cover pass if logProcesses and hasattr(os, 'getpid'): self.process = os.getpid() else: self.process = None def __repr__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) def getMessage(self): """ Return the message for this LogRecord. Return the message for this LogRecord after merging any user-supplied arguments with the message. """ msg = str(self.msg) if self.args: msg = msg % self.args return msg # # Determine which class to use when instantiating log records. # _logRecordFactory = LogRecord def setLogRecordFactory(factory): """ Set the factory to be used when instantiating a log record. :param factory: A callable which will be called to instantiate a log record. """ global _logRecordFactory _logRecordFactory = factory def getLogRecordFactory(): """ Return the factory to be used when instantiating a log record. """ return _logRecordFactory def makeLogRecord(dict): """ Make a LogRecord whose attributes are defined by the specified dictionary, This function is useful for converting a logging event received over a socket connection (which is sent as a dictionary) into a LogRecord instance. """ rv = _logRecordFactory(None, None, "", 0, "", (), None, None) rv.__dict__.update(dict) return rv #--------------------------------------------------------------------------- # Formatter classes and functions #--------------------------------------------------------------------------- _str_formatter = StrFormatter() del StrFormatter class PercentStyle(object): default_format = '%(message)s' asctime_format = '%(asctime)s' asctime_search = '%(asctime)' validation_pattern = re.compile(r'%\(\w+\)[#0+ -]*(\*|\d+)?(\.(\*|\d+))?[diouxefgcrsa%]', re.I) def __init__(self, fmt): self._fmt = fmt or self.default_format def usesTime(self): return self._fmt.find(self.asctime_search) >= 0 def validate(self): """Validate the input format, ensure it matches the correct style""" if not self.validation_pattern.search(self._fmt): raise ValueError("Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0])) def _format(self, record): return self._fmt % record.__dict__ def format(self, record): try: return self._format(record) except KeyError as e: raise ValueError('Formatting field not found in record: %s' % e) class StrFormatStyle(PercentStyle): default_format = '{message}' asctime_format = '{asctime}' asctime_search = '{asctime' fmt_spec = re.compile(r'^(.?[<>=^])?[+ -]?#?0?(\d+|{\w+})?[,_]?(\.(\d+|{\w+}))?[bcdefgnosx%]?$', re.I) field_spec = re.compile(r'^(\d+|\w+)(\.\w+|\[[^]]+\])*$') def _format(self, record): return self._fmt.format(**record.__dict__) def validate(self): """Validate the input format, ensure it is the correct string formatting style""" fields = set() try: for _, fieldname, spec, conversion in _str_formatter.parse(self._fmt): if fieldname: if not self.field_spec.match(fieldname): raise ValueError('invalid field name/expression: %r' % fieldname) fields.add(fieldname) if conversion and conversion not in 'rsa': raise ValueError('invalid conversion: %r' % conversion) if spec and not self.fmt_spec.match(spec): raise ValueError('bad specifier: %r' % spec) except ValueError as e: raise ValueError('invalid format: %s' % e) if not fields: raise ValueError('invalid format: no fields') class StringTemplateStyle(PercentStyle): default_format = '${message}' asctime_format = '${asctime}' asctime_search = '${asctime}' def __init__(self, fmt): self._fmt = fmt or self.default_format self._tpl = Template(self._fmt) def usesTime(self): fmt = self._fmt return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0 def validate(self): pattern = Template.pattern fields = set() for m in pattern.finditer(self._fmt): d = m.groupdict() if d['named']: fields.add(d['named']) elif d['braced']: fields.add(d['braced']) elif m.group(0) == '$': raise ValueError('invalid format: bare \'$\' not allowed') if not fields: raise ValueError('invalid format: no fields') def _format(self, record): return self._tpl.substitute(**record.__dict__) BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" _STYLES = { '%': (PercentStyle, BASIC_FORMAT), '{': (StrFormatStyle, '{levelname}:{name}:{message}'), '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), } class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. Formatters need to know how a LogRecord is constructed. They are responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the style-dependent default value, "%(message)s", "{message}", or "${message}", is used. The Formatter can be initialized with a format string which makes use of knowledge of the LogRecord attributes - e.g. the default value mentioned above makes use of the fact that the user's message and arguments are pre- formatted into a LogRecord's message attribute. Currently, the useful attributes in a LogRecord are described by: %(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted """ converter = time.localtime def __init__(self, fmt=None, datefmt=None, style='%', validate=True): """ Initialize the formatter with specified format strings. Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument. If datefmt is omitted, you get an ISO8601-like (or RFC 3339-like) format. Use a style parameter of '%', '{' or '$' to specify that you want to use one of %-formatting, :meth:`str.format` (``{}``) formatting or :class:`string.Template` formatting in your format string. .. versionchanged:: 3.2 Added the ``style`` parameter. """ if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) self._style = _STYLES[style][0](fmt) if validate: self._style.validate() self._fmt = self._style._fmt self.datefmt = datefmt default_time_format = '%Y-%m-%d %H:%M:%S' default_msec_format = '%s,%03d' def formatTime(self, record, datefmt=None): """ Return the creation time of the specified LogRecord as formatted text. This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) if datefmt: s = time.strftime(datefmt, ct) else: t = time.strftime(self.default_time_format, ct) s = self.default_msec_format % (t, record.msecs) return s def formatException(self, ei): """ Format and return the specified exception information as a string. This default implementation just uses traceback.print_exception() """ sio = io.StringIO() tb = ei[2] # See issues #9427, #1553375. Commented out for now. #if getattr(self, 'fullstack', False): # traceback.print_stack(tb.tb_frame.f_back, file=sio) traceback.print_exception(ei[0], ei[1], tb, None, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] return s def usesTime(self): """ Check if the format uses the creation time of the record. """ return self._style.usesTime() def formatMessage(self, record): return self._style.format(record) def formatStack(self, stack_info): """ This method is provided as an extension point for specialized formatting of stack information. The input data is a string as returned from a call to :func:`traceback.print_stack`, but with the last trailing newline removed. The base implementation just returns the value passed in. """ return stack_info def format(self, record): """ Format the specified record as text. The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message. """ record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) return s # # The default formatter to use when no other is specified # _defaultFormatter = Formatter() class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ def __init__(self, linefmt=None): """ Optionally specify a formatter which will be used to format each individual record. """ if linefmt: self.linefmt = linefmt else: self.linefmt = _defaultFormatter def formatHeader(self, records): """ Return the header string for the specified records. """ return "" def formatFooter(self, records): """ Return the footer string for the specified records. """ return "" def format(self, records): """ Format the specified records and return the result as a string. """ rv = "" if len(records) > 0: rv = rv + self.formatHeader(records) for record in records: rv = rv + self.linefmt.format(record) rv = rv + self.formatFooter(records) return rv #--------------------------------------------------------------------------- # Filter classes and functions #--------------------------------------------------------------------------- class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed. """ def __init__(self, name=''): """ Initialize a filter. Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event. """ self.name = name self.nlen = len(name) def filter(self, record): """ Determine if the specified record is to be logged. Returns True if the record should be logged, or False otherwise. If deemed appropriate, the record may be modified in-place. """ if self.nlen == 0: return True elif self.name == record.name: return True elif record.name.find(self.name, 0, self.nlen) != 0: return False return (record.name[self.nlen] == ".") class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. """ def __init__(self): """ Initialize the list of filters to be an empty list. """ self.filters = [] def addFilter(self, filter): """ Add the specified filter to this handler. """ if not (filter in self.filters): self.filters.append(filter) def removeFilter(self, filter): """ Remove the specified filter from this handler. """ if filter in self.filters: self.filters.remove(filter) def filter(self, record): """ Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto this and the record is then dropped. Returns a zero value if a record is to be dropped, else non-zero. .. versionchanged:: 3.2 Allow filters to be just callables. """ rv = True for f in self.filters: if hasattr(f, 'filter'): result = f.filter(record) else: result = f(record) # assume callable - will raise if not if not result: rv = False break return rv #--------------------------------------------------------------------------- # Handler classes and functions #--------------------------------------------------------------------------- _handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized def _removeHandlerRef(wr): """ Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are # set to None. It can also be called from another thread. So we need to # pre-emptively grab the necessary globals and check if they're None, # to prevent race conditions and failures during interpreter shutdown. acquire, release, handlers = _acquireLock, _releaseLock, _handlerList if acquire and release and handlers: acquire() try: if wr in handlers: handlers.remove(wr) finally: release() def _addHandlerRef(handler): """ Add a handler to the internal cleanup list using a weak reference. """ _acquireLock() try: _handlerList.append(weakref.ref(handler, _removeHandlerRef)) finally: _releaseLock() class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. The base handler class. Acts as a placeholder which defines the Handler interface. Handlers can optionally use Formatter instances to format records as desired. By default, no formatter is specified; in this case, the 'raw' message as determined by record.message is logged. """ def __init__(self, level=NOTSET): """ Initializes the instance - basically setting the formatter to None and the filter list to empty. """ Filterer.__init__(self) self._name = None self.level = _checkLevel(level) self.formatter = None # Add the handler to the global _handlerList (for cleanup on shutdown) _addHandlerRef(self) self.createLock() def get_name(self): return self._name def set_name(self, name): _acquireLock() try: if self._name in _handlers: del _handlers[self._name] self._name = name if name: _handlers[name] = self finally: _releaseLock() name = property(get_name, set_name) def createLock(self): """ Acquire a thread lock for serializing access to the underlying I/O. """ self.lock = threading.RLock() _register_at_fork_reinit_lock(self) def acquire(self): """ Acquire the I/O thread lock. """ if self.lock: self.lock.acquire() def release(self): """ Release the I/O thread lock. """ if self.lock: self.lock.release() def setLevel(self, level): """ Set the logging level of this handler. level must be an int or a str. """ self.level = _checkLevel(level) def format(self, record): """ Format the specified record. If a formatter is set, use it. Otherwise, use the default formatter for the module. """ if self.formatter: fmt = self.formatter else: fmt = _defaultFormatter return fmt.format(record) def emit(self, record): """ Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so raises a NotImplementedError. """ raise NotImplementedError('emit must be implemented ' 'by Handler subclasses') def handle(self, record): """ Conditionally emit the specified logging record. Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns whether the filter passed the record for emission. """ rv = self.filter(record) if rv: self.acquire() try: self.emit(record) finally: self.release() return rv def setFormatter(self, fmt): """ Set the formatter for this handler. """ self.formatter = fmt def flush(self): """ Ensure all logging output has been flushed. This version does nothing and is intended to be implemented by subclasses. """ pass def close(self): """ Tidy up any resources used by the handler. This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... if self._name and self._name in _handlers: del _handlers[self._name] finally: _releaseLock() def handleError(self, record): """ Handle errors which occur during an emit() call. This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method. """ if raiseExceptions and sys.stderr: # see issue 13807 t, v, tb = sys.exc_info() try: sys.stderr.write('--- Logging error ---\n') traceback.print_exception(t, v, tb, None, sys.stderr) sys.stderr.write('Call stack:\n') # Walk the stack frame up until we're out of logging, # so as to print the calling context. frame = tb.tb_frame while (frame and os.path.dirname(frame.f_code.co_filename) == __path__[0]): frame = frame.f_back if frame: traceback.print_stack(frame, file=sys.stderr) else: # couldn't find the right stack frame, for some reason sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) # Issue 18671: output logging message and arguments try: sys.stderr.write('Message: %r\n' 'Arguments: %s\n' % (record.msg, record.args)) except RecursionError: # See issue 36272 raise except Exception: sys.stderr.write('Unable to print the message and arguments' ' - possible formatting error.\nUse the' ' traceback above to help find the error.\n' ) except OSError: #pragma: no cover pass # see issue 5971 finally: del t, v, tb def __repr__(self): level = getLevelName(self.level) return '<%s (%s)>' % (self.__class__.__name__, level) class StreamHandler(Handler): """ A handler class which writes logging records, appropriately formatted, to a stream. Note that this class does not close the stream, as sys.stdout or sys.stderr may be used. """ terminator = '\n' def __init__(self, stream=None): """ Initialize the handler. If stream is not specified, sys.stderr is used. """ Handler.__init__(self) if stream is None: stream = sys.stderr self.stream = stream def flush(self): """ Flushes the stream. """ self.acquire() try: if self.stream and hasattr(self.stream, "flush"): self.stream.flush() finally: self.release() def emit(self, record): """ Emit a record. If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an 'encoding' attribute, it is used to determine how to do the output to the stream. """ try: msg = self.format(record) stream = self.stream # issue 35046: merged two stream.writes into one. stream.write(msg + self.terminator) self.flush() except RecursionError: # See issue 36272 raise except Exception: self.handleError(record) def setStream(self, stream): """ Sets the StreamHandler's stream to the specified value, if it is different. Returns the old stream, if the stream was changed, or None if it wasn't. """ if stream is self.stream: result = None else: result = self.stream self.acquire() try: self.flush() self.stream = stream finally: self.release() return result def __repr__(self): level = getLevelName(self.level) name = getattr(self.stream, 'name', '') # bpo-36015: name can be an int name = str(name) if name: name += ' ' return '<%s %s(%s)>' % (self.__class__.__name__, name, level) class FileHandler(StreamHandler): """ A handler class which writes formatted logging records to disk files. """ def __init__(self, filename, mode='a', encoding=None, delay=False): """ Open the specified file and use it as the stream for logging. """ # Issue #27493: add support for Path objects to be passed in filename = os.fspath(filename) #keep the absolute path, otherwise derived classes which use this #may come a cropper when the current directory changes self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding self.delay = delay if delay: #We don't open the stream, but we still need to call the #Handler constructor to set level, formatter, lock etc. Handler.__init__(self) self.stream = None else: StreamHandler.__init__(self, self._open()) def close(self): """ Closes the stream. """ self.acquire() try: try: if self.stream: try: self.flush() finally: stream = self.stream self.stream = None if hasattr(stream, "close"): stream.close() finally: # Issue #19523: call unconditionally to # prevent a handler leak when delay is set StreamHandler.close(self) finally: self.release() def _open(self): """ Open the current base file with the (original) mode and encoding. Return the resulting stream. """ return open(self.baseFilename, self.mode, encoding=self.encoding) def emit(self, record): """ Emit a record. If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit. """ if self.stream is None: self.stream = self._open() StreamHandler.emit(self, record) def __repr__(self): level = getLevelName(self.level) return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level) class _StderrHandler(StreamHandler): """ This class is like a StreamHandler using sys.stderr, but always uses whatever sys.stderr is currently set to rather than the value of sys.stderr at handler construction time. """ def __init__(self, level=NOTSET): """ Initialize the handler. """ Handler.__init__(self, level) @property def stream(self): return sys.stderr _defaultLastResort = _StderrHandler(WARNING) lastResort = _defaultLastResort #--------------------------------------------------------------------------- # Manager classes and functions #--------------------------------------------------------------------------- class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is intended for internal use only and not as part of the public API. """ def __init__(self, alogger): """ Initialize with the specified logger being a child of this placeholder. """ self.loggerMap = { alogger : None } def append(self, alogger): """ Add the specified logger as a child of this placeholder. """ if alogger not in self.loggerMap: self.loggerMap[alogger] = None # # Determine which class to use when instantiating loggers. # def setLoggerClass(klass): """ Set the class to be used when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__() """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) global _loggerClass _loggerClass = klass def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ return _loggerClass class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. """ def __init__(self, rootnode): """ Initialize the manager with the root node of the logger hierarchy. """ self.root = rootnode self.disable = 0 self.emittedNoHandlerWarning = False self.loggerDict = {} self.loggerClass = None self.logRecordFactory = None @property def disable(self): return self._disable @disable.setter def disable(self, value): self._disable = _checkLevel(value) def getLogger(self, name): """ Get a logger with the specified name (channel name), creating it if it doesn't yet exist. This name is a dot-separated hierarchical name, such as "a", "a.b", "a.b.c" or similar. If a PlaceHolder existed for the specified name [i.e. the logger didn't exist but a child of it did], replace it with the created logger and fix up the parent/child references which pointed to the placeholder to now point to the logger. """ rv = None if not isinstance(name, str): raise TypeError('A logger name must be a string') _acquireLock() try: if name in self.loggerDict: rv = self.loggerDict[name] if isinstance(rv, PlaceHolder): ph = rv rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupChildren(ph, rv) self._fixupParents(rv) else: rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupParents(rv) finally: _releaseLock() return rv def setLoggerClass(self, klass): """ Set the class to be used when instantiating a logger with this Manager. """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) self.loggerClass = klass def setLogRecordFactory(self, factory): """ Set the factory to be used when instantiating a log record with this Manager. """ self.logRecordFactory = factory def _fixupParents(self, alogger): """ Ensure that there are either loggers or placeholders all the way from the specified logger to the root of the logger hierarchy. """ name = alogger.name i = name.rfind(".") rv = None while (i > 0) and not rv: substr = name[:i] if substr not in self.loggerDict: self.loggerDict[substr] = PlaceHolder(alogger) else: obj = self.loggerDict[substr] if isinstance(obj, Logger): rv = obj else: assert isinstance(obj, PlaceHolder) obj.append(alogger) i = name.rfind(".", 0, i - 1) if not rv: rv = self.root alogger.parent = rv def _fixupChildren(self, ph, alogger): """ Ensure that children of the placeholder ph are connected to the specified logger. """ name = alogger.name namelen = len(name) for c in ph.loggerMap.keys(): #The if means ... if not c.parent.name.startswith(nm) if c.parent.name[:namelen] != name: alogger.parent = c.parent c.parent = alogger def _clear_cache(self): """ Clear the cache for all loggers in loggerDict Called when level changes are made """ _acquireLock() for logger in self.loggerDict.values(): if isinstance(logger, Logger): logger._cache.clear() self.root._cache.clear() _releaseLock() #--------------------------------------------------------------------------- # Logger classes and functions #--------------------------------------------------------------------------- class Logger(Filterer): """ Instances of the Logger class represent a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting. """ def __init__(self, name, level=NOTSET): """ Initialize the logger with a name and an optional level. """ Filterer.__init__(self) self.name = name self.level = _checkLevel(level) self.parent = None self.propagate = True self.handlers = [] self.disabled = False self._cache = {} def setLevel(self, level): """ Set the logging level of this logger. level must be an int or a str. """ self.level = _checkLevel(level) self.manager._clear_cache() def debug(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'DEBUG'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.debug("Houston, we have a %s", "thorny problem", exc_info=1) """ if self.isEnabledFor(DEBUG): self._log(DEBUG, msg, args, **kwargs) def info(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'INFO'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.info("Houston, we have a %s", "interesting problem", exc_info=1) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) def warning(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'WARNING'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1) """ if self.isEnabledFor(WARNING): self._log(WARNING, msg, args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'ERROR'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.error("Houston, we have a %s", "major problem", exc_info=1) """ if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Convenience method for logging an ERROR with exception information. """ self.error(msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'CRITICAL'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.critical("Houston, we have a %s", "major disaster", exc_info=1) """ if self.isEnabledFor(CRITICAL): self._log(CRITICAL, msg, args, **kwargs) fatal = critical def log(self, level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.log(level, "We have a %s", "mysterious problem", exc_info=1) """ if not isinstance(level, int): if raiseExceptions: raise TypeError("level must be an integer") else: return if self.isEnabledFor(level): self._log(level, msg, args, **kwargs) def findCaller(self, stack_info=False, stacklevel=1): """ Find the stack frame of the caller so that we can note the source file name, line number and function name. """ f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. if f is not None: f = f.f_back orig_f = f while f and stacklevel > 1: f = f.f_back stacklevel -= 1 if not f: f = orig_f rv = "(unknown file)", 0, "(unknown function)", None while hasattr(f, "f_code"): co = f.f_code filename = os.path.normcase(co.co_filename) if filename == _srcfile: f = f.f_back continue sinfo = None if stack_info: sio = io.StringIO() sio.write('Stack (most recent call last):\n') traceback.print_stack(f, file=sio) sinfo = sio.getvalue() if sinfo[-1] == '\n': sinfo = sinfo[:-1] sio.close() rv = (co.co_filename, f.f_lineno, co.co_name, sinfo) break return rv def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None): """ A factory method which can be overridden in subclasses to create specialized LogRecords. """ rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func, sinfo) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] return rv def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1): """ Low-level logging routine which creates a LogRecord and then calls all the handlers of this logger to handle the record. """ sinfo = None if _srcfile: #IronPython doesn't track Python frames, so findCaller raises an #exception on some versions of IronPython. We trap it here so that #IronPython can use logging. try: fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel) except ValueError: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" else: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: if isinstance(exc_info, BaseException): exc_info = (type(exc_info), exc_info, exc_info.__traceback__) elif not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra, sinfo) self.handle(record) def handle(self, record): """ Call the handlers for the specified record. This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ if (not self.disabled) and self.filter(record): self.callHandlers(record) def addHandler(self, hdlr): """ Add the specified handler to this logger. """ _acquireLock() try: if not (hdlr in self.handlers): self.handlers.append(hdlr) finally: _releaseLock() def removeHandler(self, hdlr): """ Remove the specified handler from this logger. """ _acquireLock() try: if hdlr in self.handlers: self.handlers.remove(hdlr) finally: _releaseLock() def hasHandlers(self): """ See if this logger has any handlers configured. Loop through all handlers for this logger and its parents in the logger hierarchy. Return True if a handler was found, else False. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger which is checked for the existence of handlers. """ c = self rv = False while c: if c.handlers: rv = True break if not c.propagate: break else: c = c.parent return rv def callHandlers(self, record): """ Pass a record to all relevant handlers. Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called. """ c = self found = 0 while c: for hdlr in c.handlers: found = found + 1 if record.levelno >= hdlr.level: hdlr.handle(record) if not c.propagate: c = None #break out else: c = c.parent if (found == 0): if lastResort: if record.levelno >= lastResort.level: lastResort.handle(record) elif raiseExceptions and not self.manager.emittedNoHandlerWarning: sys.stderr.write("No handlers could be found for logger" " \"%s\"\n" % self.name) self.manager.emittedNoHandlerWarning = True def getEffectiveLevel(self): """ Get the effective level for this logger. Loop through this logger and its parents in the logger hierarchy, looking for a non-zero logging level. Return the first one found. """ logger = self while logger: if logger.level: return logger.level logger = logger.parent return NOTSET def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.disabled: return False try: return self._cache[level] except KeyError: _acquireLock() try: if self.manager.disable >= level: is_enabled = self._cache[level] = False else: is_enabled = self._cache[level] = ( level >= self.getEffectiveLevel() ) finally: _releaseLock() return is_enabled def getChild(self, suffix): """ Get a logger which is a descendant to this one. This is a convenience method, such that logging.getLogger('abc').getChild('def.ghi') is the same as logging.getLogger('abc.def.ghi') It's useful, for example, when the parent logger is named using __name__ rather than a literal string. """ if self.root is not self: suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) def __repr__(self): level = getLevelName(self.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) def __reduce__(self): # In general, only the root logger will not be accessible via its name. # However, the root logger's class has its own __reduce__ method. if getLogger(self.name) is not self: import pickle raise pickle.PicklingError('logger cannot be pickled') return getLogger, (self.name,) class RootLogger(Logger): """ A root logger is not that different to any other logger, except that it must have a logging level and there is only one instance of it in the hierarchy. """ def __init__(self, level): """ Initialize the logger with the name "root". """ Logger.__init__(self, "root", level) def __reduce__(self): return getLogger, () _loggerClass = Logger class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. """ def __init__(self, logger, extra): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows easy stacking of LoggerAdapters, if so desired. You can effectively pass keyword arguments as shown in the following example: adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) """ self.logger = logger self.extra = extra def process(self, msg, kwargs): """ Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs. Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs. """ kwargs["extra"] = self.extra return msg, kwargs # # Boilerplate convenience methods # def debug(self, msg, *args, **kwargs): """ Delegate a debug call to the underlying logger. """ self.log(DEBUG, msg, *args, **kwargs) def info(self, msg, *args, **kwargs): """ Delegate an info call to the underlying logger. """ self.log(INFO, msg, *args, **kwargs) def warning(self, msg, *args, **kwargs): """ Delegate a warning call to the underlying logger. """ self.log(WARNING, msg, *args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Delegate an error call to the underlying logger. """ self.log(ERROR, msg, *args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Delegate an exception call to the underlying logger. """ self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Delegate a critical call to the underlying logger. """ self.log(CRITICAL, msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Delegate a log call to the underlying logger, after adding contextual information from this adapter instance. """ if self.isEnabledFor(level): msg, kwargs = self.process(msg, kwargs) self.logger.log(level, msg, *args, **kwargs) def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ return self.logger.isEnabledFor(level) def setLevel(self, level): """ Set the specified level on the underlying logger. """ self.logger.setLevel(level) def getEffectiveLevel(self): """ Get the effective level for the underlying logger. """ return self.logger.getEffectiveLevel() def hasHandlers(self): """ See if the underlying logger has any handlers. """ return self.logger.hasHandlers() def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): """ Low-level log implementation, proxied to allow nested logger adapters. """ return self.logger._log( level, msg, args, exc_info=exc_info, extra=extra, stack_info=stack_info, ) @property def manager(self): return self.logger.manager @manager.setter def manager(self, value): self.logger.manager = value @property def name(self): return self.logger.name def __repr__(self): logger = self.logger level = getLevelName(logger.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level) root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) #--------------------------------------------------------------------------- # Configuration classes and functions #--------------------------------------------------------------------------- def basicConfig(**kwargs): """ Do basic configuration for the logging system. This function does nothing if the root logger already has handlers configured, unless the keyword argument *force* is set to ``True``. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package. The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger. A number of optional keyword arguments may be specified, which can alter the default behaviour. filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler. filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format Use the specified format string for the handler. datefmt Use the specified date/time format. style If a format string is specified, use this to specify the type of format string (possible values '%', '{', '$', for %-formatting, :meth:`str.format` and :class:`string.Template` - defaults to '%'). level Set the root logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored. handlers If specified, this should be an iterable of already created handlers, which will be added to the root handler. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function. force If this keyword is specified as true, any existing handlers attached to the root logger are removed and closed, before carrying out the configuration as specified by the other arguments. Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed. .. versionchanged:: 3.8 Added the ``force`` parameter. .. versionchanged:: 3.2 Added the ``style`` parameter. .. versionchanged:: 3.3 Added the ``handlers`` parameter. A ``ValueError`` is now thrown for incompatible arguments (e.g. ``handlers`` specified together with ``filename``/``filemode``, or ``filename``/``filemode`` specified together with ``stream``, or ``handlers`` specified together with ``stream``. """ # Add thread safety in case someone mistakenly calls # basicConfig() from multiple threads _acquireLock() try: force = kwargs.pop('force', False) if force: for h in root.handlers[:]: root.removeHandler(h) h.close() if len(root.handlers) == 0: handlers = kwargs.pop("handlers", None) if handlers is None: if "stream" in kwargs and "filename" in kwargs: raise ValueError("'stream' and 'filename' should not be " "specified together") else: if "stream" in kwargs or "filename" in kwargs: raise ValueError("'stream' or 'filename' should not be " "specified together with 'handlers'") if handlers is None: filename = kwargs.pop("filename", None) mode = kwargs.pop("filemode", 'a') if filename: h = FileHandler(filename, mode) else: stream = kwargs.pop("stream", None) h = StreamHandler(stream) handlers = [h] dfs = kwargs.pop("datefmt", None) style = kwargs.pop("style", '%') if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) fs = kwargs.pop("format", _STYLES[style][1]) fmt = Formatter(fs, dfs, style) for h in handlers: if h.formatter is None: h.setFormatter(fmt) root.addHandler(h) level = kwargs.pop("level", None) if level is not None: root.setLevel(level) if kwargs: keys = ', '.join(kwargs.keys()) raise ValueError('Unrecognised argument(s): %s' % keys) finally: _releaseLock() #--------------------------------------------------------------------------- # Utility functions at module level. # Basically delegate everything to the root logger. #--------------------------------------------------------------------------- def getLogger(name=None): """ Return a logger with the specified name, creating it if necessary. If no name is specified, return the root logger. """ if name: return Logger.manager.getLogger(name) else: return root def critical(msg, *args, **kwargs): """ Log a message with severity 'CRITICAL' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.critical(msg, *args, **kwargs) fatal = critical def error(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.error(msg, *args, **kwargs) def exception(msg, *args, exc_info=True, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. If the logger has no handlers, basicConfig() is called to add a console handler with a pre-defined format. """ error(msg, *args, exc_info=exc_info, **kwargs) def warning(msg, *args, **kwargs): """ Log a message with severity 'WARNING' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.warning(msg, *args, **kwargs) def warn(msg, *args, **kwargs): warnings.warn("The 'warn' function is deprecated, " "use 'warning' instead", DeprecationWarning, 2) warning(msg, *args, **kwargs) def info(msg, *args, **kwargs): """ Log a message with severity 'INFO' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.info(msg, *args, **kwargs) def debug(msg, *args, **kwargs): """ Log a message with severity 'DEBUG' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.debug(msg, *args, **kwargs) def log(level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.log(level, msg, *args, **kwargs) def disable(level=CRITICAL): """ Disable all logging calls of severity 'level' and below. """ root.manager.disable = level root.manager._clear_cache() def shutdown(handlerList=_handlerList): """ Perform any cleanup actions in the logging system (e.g. flushing buffers). Should be called at application exit. """ for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: h = wr() if h: try: h.acquire() h.flush() h.close() except (OSError, ValueError): # Ignore errors which might be caused # because handlers have been closed but # references to them are still around at # application exit. pass finally: h.release() except: # ignore everything, as we're shutting down if raiseExceptions: raise #else, swallow #Let's try and shutdown automatically on application exit... import atexit atexit.register(shutdown) # Null handler class NullHandler(Handler): """ This handler does nothing. It's intended to be used to avoid the "No handlers could be found for logger XXX" one-off warning. This is important for library code, which may contain code to log events. If a user of the library does not configure logging, the one-off warning might be produced; to avoid this, the library developer simply needs to instantiate a NullHandler and add it to the top-level logger of the library module or package. """ def handle(self, record): """Stub.""" def emit(self, record): """Stub.""" def createLock(self): self.lock = None # Warnings integration _warnings_showwarning = None def _showwarning(message, category, filename, lineno, file=None, line=None): """ Implementation of showwarnings which redirects to logging, which will first check to see if the file parameter is None. If a file is specified, it will delegate to the original warnings implementation of showwarning. Otherwise, it will call warnings.formatwarning and will log the resulting string to a warnings logger named "py.warnings" with level logging.WARNING. """ if file is not None: if _warnings_showwarning is not None: _warnings_showwarning(message, category, filename, lineno, file, line) else: s = warnings.formatwarning(message, category, filename, lineno, line) logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) logger.warning("%s", s) def captureWarnings(capture): """ If capture is true, redirect all warnings to the logging package. If capture is False, ensure that warnings are not redirected to logging but to their original destinations. """ global _warnings_showwarning if capture: if _warnings_showwarning is None: _warnings_showwarning = warnings.showwarning warnings.showwarning = _showwarning else: if _warnings_showwarning is not None: warnings.showwarning = _warnings_showwarning _warnings_showwarning = None usr/lib64/python3.8/http/__init__.py000064400000014352152345047500013151 0ustar00from enum import IntEnum __all__ = ['HTTPStatus'] class HTTPStatus(IntEnum): """HTTP status codes and reason phrases Status codes from the following RFCs are all observed: * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 * RFC 6585: Additional HTTP Status Codes * RFC 3229: Delta encoding in HTTP * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 * RFC 5842: Binding Extensions to WebDAV * RFC 7238: Permanent Redirect * RFC 2295: Transparent Content Negotiation in HTTP * RFC 2774: An HTTP Extension Framework * RFC 7725: An HTTP Status Code to Report Legal Obstacles * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2) """ def __new__(cls, value, phrase, description=''): obj = int.__new__(cls, value) obj._value_ = value obj.phrase = phrase obj.description = description return obj # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', 'Switching to new protocol; obey Upgrade header') PROCESSING = 102, 'Processing' # success OK = 200, 'OK', 'Request fulfilled, document follows' CREATED = 201, 'Created', 'Document created, URL follows' ACCEPTED = (202, 'Accepted', 'Request accepted, processing continues off-line') NON_AUTHORITATIVE_INFORMATION = (203, 'Non-Authoritative Information', 'Request fulfilled from cache') NO_CONTENT = 204, 'No Content', 'Request fulfilled, nothing follows' RESET_CONTENT = 205, 'Reset Content', 'Clear input form for further input' PARTIAL_CONTENT = 206, 'Partial Content', 'Partial content follows' MULTI_STATUS = 207, 'Multi-Status' ALREADY_REPORTED = 208, 'Already Reported' IM_USED = 226, 'IM Used' # redirection MULTIPLE_CHOICES = (300, 'Multiple Choices', 'Object has several resources -- see URI list') MOVED_PERMANENTLY = (301, 'Moved Permanently', 'Object moved permanently -- see URI list') FOUND = 302, 'Found', 'Object moved temporarily -- see URI list' SEE_OTHER = 303, 'See Other', 'Object moved -- see Method and URL list' NOT_MODIFIED = (304, 'Not Modified', 'Document has not changed since given time') USE_PROXY = (305, 'Use Proxy', 'You must use proxy specified in Location to access this resource') TEMPORARY_REDIRECT = (307, 'Temporary Redirect', 'Object moved temporarily -- see URI list') PERMANENT_REDIRECT = (308, 'Permanent Redirect', 'Object moved permanently -- see URI list') # client error BAD_REQUEST = (400, 'Bad Request', 'Bad request syntax or unsupported method') UNAUTHORIZED = (401, 'Unauthorized', 'No permission -- see authorization schemes') PAYMENT_REQUIRED = (402, 'Payment Required', 'No payment -- see charging schemes') FORBIDDEN = (403, 'Forbidden', 'Request forbidden -- authorization will not help') NOT_FOUND = (404, 'Not Found', 'Nothing matches the given URI') METHOD_NOT_ALLOWED = (405, 'Method Not Allowed', 'Specified method is invalid for this resource') NOT_ACCEPTABLE = (406, 'Not Acceptable', 'URI not available in preferred format') PROXY_AUTHENTICATION_REQUIRED = (407, 'Proxy Authentication Required', 'You must authenticate with this proxy before proceeding') REQUEST_TIMEOUT = (408, 'Request Timeout', 'Request timed out; try again later') CONFLICT = 409, 'Conflict', 'Request conflict' GONE = (410, 'Gone', 'URI no longer exists and has been permanently removed') LENGTH_REQUIRED = (411, 'Length Required', 'Client must specify Content-Length') PRECONDITION_FAILED = (412, 'Precondition Failed', 'Precondition in headers is false') REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large', 'Entity is too large') REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long', 'URI is too long') UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type', 'Entity body in unsupported format') REQUESTED_RANGE_NOT_SATISFIABLE = (416, 'Requested Range Not Satisfiable', 'Cannot satisfy request range') EXPECTATION_FAILED = (417, 'Expectation Failed', 'Expect condition could not be satisfied') MISDIRECTED_REQUEST = (421, 'Misdirected Request', 'Server is not able to produce a response') UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity' LOCKED = 423, 'Locked' FAILED_DEPENDENCY = 424, 'Failed Dependency' UPGRADE_REQUIRED = 426, 'Upgrade Required' PRECONDITION_REQUIRED = (428, 'Precondition Required', 'The origin server requires the request to be conditional') TOO_MANY_REQUESTS = (429, 'Too Many Requests', 'The user has sent too many requests in ' 'a given amount of time ("rate limiting")') REQUEST_HEADER_FIELDS_TOO_LARGE = (431, 'Request Header Fields Too Large', 'The server is unwilling to process the request because its header ' 'fields are too large') UNAVAILABLE_FOR_LEGAL_REASONS = (451, 'Unavailable For Legal Reasons', 'The server is denying access to the ' 'resource as a consequence of a legal demand') # server errors INTERNAL_SERVER_ERROR = (500, 'Internal Server Error', 'Server got itself in trouble') NOT_IMPLEMENTED = (501, 'Not Implemented', 'Server does not support this operation') BAD_GATEWAY = (502, 'Bad Gateway', 'Invalid responses from another server/proxy') SERVICE_UNAVAILABLE = (503, 'Service Unavailable', 'The server cannot process the request due to a high load') GATEWAY_TIMEOUT = (504, 'Gateway Timeout', 'The gateway server did not receive a timely response') HTTP_VERSION_NOT_SUPPORTED = (505, 'HTTP Version Not Supported', 'Cannot fulfill request') VARIANT_ALSO_NEGOTIATES = 506, 'Variant Also Negotiates' INSUFFICIENT_STORAGE = 507, 'Insufficient Storage' LOOP_DETECTED = 508, 'Loop Detected' NOT_EXTENDED = 510, 'Not Extended' NETWORK_AUTHENTICATION_REQUIRED = (511, 'Network Authentication Required', 'The client needs to authenticate to gain network access') usr/lib64/python3.12/dbm/__init__.py000064400000013372152345047750013017 0ustar00"""Generic interface to all dbm clones. Use import dbm d = dbm.open(file, 'w', 0o666) The returned object is a dbm.gnu, dbm.ndbm or dbm.dumb object, dependent on the type of database being opened (determined by the whichdb function) in the case of an existing dbm. If the dbm does not exist and the create or new flag ('c' or 'n') was specified, the dbm type will be determined by the availability of the modules (tested in the above order). It has the following interface (key and data are strings): d[key] = data # store data at key (may override data at # existing key) data = d[key] # retrieve data at key (raise KeyError if no # such key) del d[key] # delete data stored at key (raises KeyError # if no such key) flag = key in d # true if the key exists list = d.keys() # return a list of all existing keys (slow!) Future versions may change the order in which implementations are tested for existence, and add interfaces to other dbm-like implementations. """ __all__ = ['open', 'whichdb', 'error'] import io import os import struct import sys class error(Exception): pass _names = ['dbm.gnu', 'dbm.ndbm', 'dbm.dumb'] _defaultmod = None _modules = {} error = (error, OSError) try: from dbm import ndbm except ImportError: ndbm = None def open(file, flag='r', mode=0o666): """Open or create database at path given by *file*. Optional argument *flag* can be 'r' (default) for read-only access, 'w' for read-write access of an existing database, 'c' for read-write access to a new or existing database, and 'n' for read-write access to a new database. Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it only if it doesn't exist; and 'n' always creates a new database. """ global _defaultmod if _defaultmod is None: for name in _names: try: mod = __import__(name, fromlist=['open']) except ImportError: continue if not _defaultmod: _defaultmod = mod _modules[name] = mod if not _defaultmod: raise ImportError("no dbm clone found; tried %s" % _names) # guess the type of an existing database, if not creating a new one result = whichdb(file) if 'n' not in flag else None if result is None: # db doesn't exist or 'n' flag was specified to create a new db if 'c' in flag or 'n' in flag: # file doesn't exist and the new flag was used so use default type mod = _defaultmod else: raise error[0]("db file doesn't exist; " "use 'c' or 'n' flag to create a new db") elif result == "": # db type cannot be determined raise error[0]("db type could not be determined") elif result not in _modules: raise error[0]("db type is {0}, but the module is not " "available".format(result)) else: mod = _modules[result] return mod.open(file, flag, mode) def whichdb(filename): """Guess which db package to use to open a db file. Return values: - None if the database file can't be read; - empty string if the file can be read but can't be recognized - the name of the dbm submodule (e.g. "ndbm" or "gnu") if recognized. Importing the given module may still fail, and opening the database using that module may still fail. """ # Check for ndbm first -- this has a .pag and a .dir file filename = os.fsencode(filename) try: f = io.open(filename + b".pag", "rb") f.close() f = io.open(filename + b".dir", "rb") f.close() return "dbm.ndbm" except OSError: # some dbm emulations based on Berkeley DB generate a .db file # some do not, but they should be caught by the bsd checks try: f = io.open(filename + b".db", "rb") f.close() # guarantee we can actually open the file using dbm # kind of overkill, but since we are dealing with emulations # it seems like a prudent step if ndbm is not None: d = ndbm.open(filename) d.close() return "dbm.ndbm" except OSError: pass # Check for dumbdbm next -- this has a .dir and a .dat file try: # First check for presence of files os.stat(filename + b".dat") size = os.stat(filename + b".dir").st_size # dumbdbm files with no keys are empty if size == 0: return "dbm.dumb" f = io.open(filename + b".dir", "rb") try: if f.read(1) in (b"'", b'"'): return "dbm.dumb" finally: f.close() except OSError: pass # See if the file exists, return None if not try: f = io.open(filename, "rb") except OSError: return None with f: # Read the start of the file -- the magic number s16 = f.read(16) s = s16[0:4] # Return "" if not at least 4 bytes if len(s) != 4: return "" # Convert to 4-byte int in native byte order -- return "" if impossible try: (magic,) = struct.unpack("=l", s) except struct.error: return "" # Check for GNU dbm if magic in (0x13579ace, 0x13579acd, 0x13579acf): return "dbm.gnu" # Later versions of Berkeley db hash file have a 12-byte pad in # front of the file type try: (magic,) = struct.unpack("=l", s16[-4:]) except struct.error: return "" # Unknown return "" if __name__ == "__main__": for filename in sys.argv[1:]: print(whichdb(filename) or "UNKNOWN", filename) lib64/python3.12/concurrent/__init__.py000064400000000046152345066320013612 0ustar00# This directory is a Python package. lib64/python3.12/ensurepip/__init__.py000064400000022345152345226120013444 0ustar00import collections import os import os.path import subprocess import sys import sysconfig import tempfile from importlib import resources __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('pip',) _PIP_VERSION = "25.0.1" _PROJECTS = [ ("pip", _PIP_VERSION, "py3"), ] # Packages bundled in ensurepip._bundled have wheel_name set. # Packages from WHEEL_PKG_DIR have wheel_path set. _Package = collections.namedtuple('Package', ('version', 'wheel_name', 'wheel_path')) # Directory of system wheel packages. Some Linux distribution packaging # policies recommend against bundling dependencies. For example, Fedora # installs wheel packages in the /usr/share/python-wheels/ directory and don't # install the ensurepip._bundled package. _WHEEL_PKG_DIR = sysconfig.get_config_var('WHEEL_PKG_DIR') def _find_packages(path): packages = {} try: filenames = os.listdir(path) except OSError: # Ignore: path doesn't exist or permission error filenames = () # Make the code deterministic if a directory contains multiple wheel files # of the same package, but don't attempt to implement correct version # comparison since this case should not happen. filenames = sorted(filenames) for filename in filenames: # filename is like 'pip-21.2.4-py3-none-any.whl' if not filename.endswith(".whl"): continue for name in _PACKAGE_NAMES: prefix = name + '-' if filename.startswith(prefix): break else: continue # Extract '21.2.4' from 'pip-21.2.4-py3-none-any.whl' version = filename.removeprefix(prefix).partition('-')[0] wheel_path = os.path.join(path, filename) packages[name] = _Package(version, None, wheel_path) return packages def _get_packages(): global _PACKAGES, _WHEEL_PKG_DIR if _PACKAGES is not None: return _PACKAGES packages = {} for name, version, py_tag in _PROJECTS: wheel_name = f"{name}-{version}-{py_tag}-none-any.whl" packages[name] = _Package(version, wheel_name, None) if _WHEEL_PKG_DIR: dir_packages = _find_packages(_WHEEL_PKG_DIR) # only used the wheel package directory if all packages are found there if all(name in dir_packages for name in _PACKAGE_NAMES): packages = dir_packages _PACKAGES = packages return packages _PACKAGES = None def _run_pip(args, additional_paths=None): # Run the bootstrapping in a subprocess to avoid leaking any state that happens # after pip has executed. Particularly, this avoids the case when pip holds onto # the files in *additional_paths*, preventing us to remove them at the end of the # invocation. code = f""" import runpy import sys sys.path = {additional_paths or []} + sys.path sys.argv[1:] = {args} runpy.run_module("pip", run_name="__main__", alter_sys=True) """ cmd = [ sys.executable, '-W', 'ignore::DeprecationWarning', '-c', code, ] if sys.flags.isolated: # run code in isolated mode if currently running isolated cmd.insert(1, '-I') return subprocess.run(cmd, check=True).returncode def version(): """ Returns a string specifying the bundled version of pip. """ return _get_packages()['pip'].version def _disable_pip_configuration_settings(): # We deliberately ignore all pip environment variables # when invoking pip # See http://bugs.python.org/issue19734 for details keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] for k in keys_to_remove: del os.environ[k] # We also ignore the settings in the default pip configuration file # See http://bugs.python.org/issue20053 for details os.environ['PIP_CONFIG_FILE'] = os.devnull def bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Note that calling this function will alter both sys.path and os.environ. """ # Discard the return value _bootstrap(root=root, upgrade=upgrade, user=user, altinstall=altinstall, default_pip=default_pip, verbosity=verbosity) def _bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Returns pip command status code. Note that calling this function will alter both sys.path and os.environ. """ if altinstall and default_pip: raise ValueError("Cannot use altinstall and default_pip together") sys.audit("ensurepip.bootstrap", root) _disable_pip_configuration_settings() # By default, installing pip installs all of the # following scripts (X.Y == running Python version): # # pip, pipX, pipX.Y # # pip 1.5+ allows ensurepip to request that some of those be left out if altinstall: # omit pip, pipX os.environ["ENSUREPIP_OPTIONS"] = "altinstall" elif not default_pip: # omit pip os.environ["ENSUREPIP_OPTIONS"] = "install" with tempfile.TemporaryDirectory() as tmpdir: # Put our bundled wheels into a temporary directory and construct the # additional paths that need added to sys.path additional_paths = [] for name, package in _get_packages().items(): if package.wheel_name: # Use bundled wheel package wheel_name = package.wheel_name wheel_path = resources.files("ensurepip") / "_bundled" / wheel_name whl = wheel_path.read_bytes() else: # Use the wheel package directory with open(package.wheel_path, "rb") as fp: whl = fp.read() wheel_name = os.path.basename(package.wheel_path) filename = os.path.join(tmpdir, wheel_name) with open(filename, "wb") as fp: fp.write(whl) additional_paths.append(filename) # Construct the arguments to be passed to the pip command args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir] if root: args += ["--root", root] if upgrade: args += ["--upgrade"] if user: args += ["--user"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip([*args, *_PACKAGE_NAMES], additional_paths) def _uninstall_helper(*, verbosity=0): """Helper to support a clean default uninstall process on Windows Note that calling this function may alter os.environ. """ # Nothing to do if pip was never installed, or has been removed try: import pip except ImportError: return # If the installed pip version doesn't match the available one, # leave it alone available_version = version() if pip.__version__ != available_version: print(f"ensurepip will only uninstall a matching version " f"({pip.__version__!r} installed, " f"{available_version!r} available)", file=sys.stderr) return _disable_pip_configuration_settings() # Construct the arguments to be passed to the pip command args = ["uninstall", "-y", "--disable-pip-version-check"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip([*args, *reversed(_PACKAGE_NAMES)]) def _main(argv=None): import argparse parser = argparse.ArgumentParser(prog="python -m ensurepip") parser.add_argument( "--version", action="version", version="pip {}".format(version()), help="Show the version of pip that is bundled with this Python.", ) parser.add_argument( "-v", "--verbose", action="count", default=0, dest="verbosity", help=("Give more output. Option is additive, and can be used up to 3 " "times."), ) parser.add_argument( "-U", "--upgrade", action="store_true", default=False, help="Upgrade pip and dependencies, even if already installed.", ) parser.add_argument( "--user", action="store_true", default=False, help="Install using the user scheme.", ) parser.add_argument( "--root", default=None, help="Install everything relative to this alternate root directory.", ) parser.add_argument( "--altinstall", action="store_true", default=False, help=("Make an alternate install, installing only the X.Y versioned " "scripts (Default: pipX, pipX.Y)."), ) parser.add_argument( "--default-pip", action="store_true", default=False, help=("Make a default pip install, installing the unqualified pip " "in addition to the versioned scripts."), ) args = parser.parse_args(argv) return _bootstrap( root=args.root, upgrade=args.upgrade, user=args.user, verbosity=args.verbosity, altinstall=args.altinstall, default_pip=args.default_pip, ) lib64/python3.6/dbm/__init__.py000064400000013227152345305140012116 0ustar00"""Generic interface to all dbm clones. Use import dbm d = dbm.open(file, 'w', 0o666) The returned object is a dbm.gnu, dbm.ndbm or dbm.dumb object, dependent on the type of database being opened (determined by the whichdb function) in the case of an existing dbm. If the dbm does not exist and the create or new flag ('c' or 'n') was specified, the dbm type will be determined by the availability of the modules (tested in the above order). It has the following interface (key and data are strings): d[key] = data # store data at key (may override data at # existing key) data = d[key] # retrieve data at key (raise KeyError if no # such key) del d[key] # delete data stored at key (raises KeyError # if no such key) flag = key in d # true if the key exists list = d.keys() # return a list of all existing keys (slow!) Future versions may change the order in which implementations are tested for existence, and add interfaces to other dbm-like implementations. """ __all__ = ['open', 'whichdb', 'error'] import io import os import struct import sys class error(Exception): pass _names = ['dbm.gnu', 'dbm.ndbm', 'dbm.dumb'] _defaultmod = None _modules = {} error = (error, OSError) try: from dbm import ndbm except ImportError: ndbm = None def open(file, flag='r', mode=0o666): """Open or create database at path given by *file*. Optional argument *flag* can be 'r' (default) for read-only access, 'w' for read-write access of an existing database, 'c' for read-write access to a new or existing database, and 'n' for read-write access to a new database. Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it only if it doesn't exist; and 'n' always creates a new database. """ global _defaultmod if _defaultmod is None: for name in _names: try: mod = __import__(name, fromlist=['open']) except ImportError: continue if not _defaultmod: _defaultmod = mod _modules[name] = mod if not _defaultmod: raise ImportError("no dbm clone found; tried %s" % _names) # guess the type of an existing database, if not creating a new one result = whichdb(file) if 'n' not in flag else None if result is None: # db doesn't exist or 'n' flag was specified to create a new db if 'c' in flag or 'n' in flag: # file doesn't exist and the new flag was used so use default type mod = _defaultmod else: raise error[0]("need 'c' or 'n' flag to open new db") elif result == "": # db type cannot be determined raise error[0]("db type could not be determined") elif result not in _modules: raise error[0]("db type is {0}, but the module is not " "available".format(result)) else: mod = _modules[result] return mod.open(file, flag, mode) def whichdb(filename): """Guess which db package to use to open a db file. Return values: - None if the database file can't be read; - empty string if the file can be read but can't be recognized - the name of the dbm submodule (e.g. "ndbm" or "gnu") if recognized. Importing the given module may still fail, and opening the database using that module may still fail. """ # Check for ndbm first -- this has a .pag and a .dir file try: f = io.open(filename + ".pag", "rb") f.close() f = io.open(filename + ".dir", "rb") f.close() return "dbm.ndbm" except OSError: # some dbm emulations based on Berkeley DB generate a .db file # some do not, but they should be caught by the bsd checks try: f = io.open(filename + ".db", "rb") f.close() # guarantee we can actually open the file using dbm # kind of overkill, but since we are dealing with emulations # it seems like a prudent step if ndbm is not None: d = ndbm.open(filename) d.close() return "dbm.ndbm" except OSError: pass # Check for dumbdbm next -- this has a .dir and a .dat file try: # First check for presence of files os.stat(filename + ".dat") size = os.stat(filename + ".dir").st_size # dumbdbm files with no keys are empty if size == 0: return "dbm.dumb" f = io.open(filename + ".dir", "rb") try: if f.read(1) in (b"'", b'"'): return "dbm.dumb" finally: f.close() except OSError: pass # See if the file exists, return None if not try: f = io.open(filename, "rb") except OSError: return None with f: # Read the start of the file -- the magic number s16 = f.read(16) s = s16[0:4] # Return "" if not at least 4 bytes if len(s) != 4: return "" # Convert to 4-byte int in native byte order -- return "" if impossible try: (magic,) = struct.unpack("=l", s) except struct.error: return "" # Check for GNU dbm if magic in (0x13579ace, 0x13579acd, 0x13579acf): return "dbm.gnu" # Later versions of Berkeley db hash file have a 12-byte pad in # front of the file type try: (magic,) = struct.unpack("=l", s16[-4:]) except struct.error: return "" # Unknown return "" if __name__ == "__main__": for filename in sys.argv[1:]: print(whichdb(filename) or "UNKNOWN", filename) lib64/python3.12/asyncio/__init__.py000064400000002304152345307160013074 0ustar00"""The asyncio package, tracking PEP 3156.""" # flake8: noqa import sys # This relies on each of the submodules having an __all__ variable. from .base_events import * from .coroutines import * from .events import * from .exceptions import * from .futures import * from .locks import * from .protocols import * from .runners import * from .queues import * from .streams import * from .subprocess import * from .tasks import * from .taskgroups import * from .timeouts import * from .threads import * from .transports import * __all__ = (base_events.__all__ + coroutines.__all__ + events.__all__ + exceptions.__all__ + futures.__all__ + locks.__all__ + protocols.__all__ + runners.__all__ + queues.__all__ + streams.__all__ + subprocess.__all__ + tasks.__all__ + taskgroups.__all__ + threads.__all__ + timeouts.__all__ + transports.__all__) if sys.platform == 'win32': # pragma: no cover from .windows_events import * __all__ += windows_events.__all__ else: from .unix_events import * # pragma: no cover __all__ += unix_events.__all__ usr/lib64/python3.6/logging/__init__.py000064400000213145152345416460013624 0ustar00# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation, and that the name of Vinay Sajip # not be used in advertising or publicity pertaining to distribution # of the software without specific, written prior permission. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import sys, os, time, io, traceback, warnings, weakref, collections from string import Template __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', 'lastResort', 'raiseExceptions'] try: import threading except ImportError: #pragma: no cover threading = None __author__ = "Vinay Sajip " __status__ = "production" # The following module attributes are no longer updated. __version__ = "0.5.1.2" __date__ = "07 February 2010" #--------------------------------------------------------------------------- # Miscellaneous module data #--------------------------------------------------------------------------- # #_startTime is used as the base when calculating the relative time of events # _startTime = time.time() # #raiseExceptions is used to see if exceptions during handling should be #propagated # raiseExceptions = True # # If you don't want threading information in the log, set this to zero # logThreads = True # # If you don't want multiprocessing information in the log, set this to zero # logMultiprocessing = True # # If you don't want process information in the log, set this to zero # logProcesses = True #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- # # Default levels and level names, these can be replaced with any positive set # of values having corresponding names. There is a pseudo-level, NOTSET, which # is only really there as a lower limit for user-defined levels. Handlers and # loggers are initialized with NOTSET so that they will log all messages, even # at user-defined levels. # CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 _levelToName = { CRITICAL: 'CRITICAL', ERROR: 'ERROR', WARNING: 'WARNING', INFO: 'INFO', DEBUG: 'DEBUG', NOTSET: 'NOTSET', } _nameToLevel = { 'CRITICAL': CRITICAL, 'FATAL': FATAL, 'ERROR': ERROR, 'WARN': WARNING, 'WARNING': WARNING, 'INFO': INFO, 'DEBUG': DEBUG, 'NOTSET': NOTSET, } def getLevelName(level): """ Return the textual representation of logging level 'level'. If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, INFO, DEBUG) then you get the corresponding string. If you have associated levels with names using addLevelName then the name you have associated with 'level' is returned. If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned. Otherwise, the string "Level %s" % level is returned. """ # See Issues #22386, #27937 and #29220 for why it's this way result = _levelToName.get(level) if result is not None: return result result = _nameToLevel.get(level) if result is not None: return result return "Level %s" % level def addLevelName(level, levelName): """ Associate 'levelName' with 'level'. This is used when converting levels to text during message formatting. """ _acquireLock() try: #unlikely to cause an exception, but you never know... _levelToName[level] = levelName _nameToLevel[levelName] = level finally: _releaseLock() if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) else: #pragma: no cover def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise Exception except Exception: return sys.exc_info()[2].tb_frame.f_back # # _srcfile is used when walking the stack to check when we've got the first # caller stack frame, by skipping frames whose filename is that of this # module's source. It therefore should contain the filename of this module's # source file. # # Ordinarily we would use __file__ for this, but frozen modules don't always # have __file__ set, for some reason (see Issue #21736). Thus, we get the # filename from a handy code object from a function defined in this module. # (There's no particular reason for picking addLevelName.) # _srcfile = os.path.normcase(addLevelName.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). # To provide compatibility with older versions of Python, set _srcfile # to None if _getframe() is not available; this value will prevent # findCaller() from being called. You can also do this if you want to avoid # the overhead of fetching caller information, even when _getframe() is # available. #if not hasattr(sys, '_getframe'): # _srcfile = None def _checkLevel(level): if isinstance(level, int): rv = level elif str(level) == level: if level not in _nameToLevel: raise ValueError("Unknown level: %r" % level) rv = _nameToLevel[level] else: raise TypeError("Level not an integer or a valid string: %r" % level) return rv #--------------------------------------------------------------------------- # Thread-related stuff #--------------------------------------------------------------------------- # #_lock is used to serialize access to shared data structures in this module. #This needs to be an RLock because fileConfig() creates and configures #Handlers, and so might arbitrary user threads. Since Handler code updates the #shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # if threading: _lock = threading.RLock() else: #pragma: no cover _lock = None def _acquireLock(): """ Acquire the module-level lock for serializing access to shared data. This should be released with _releaseLock(). """ if _lock: _lock.acquire() def _releaseLock(): """ Release the module-level lock acquired by calling _acquireLock(). """ if _lock: _lock.release() #--------------------------------------------------------------------------- # The logging record #--------------------------------------------------------------------------- class LogRecord(object): """ A LogRecord instance represents an event being logged. LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is in msg and args, which are combined using str(msg) % args to create the message field of the record. The record also includes information such as when the record was created, the source line where the logging call was made, and any exception information to be logged. """ def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None, **kwargs): """ Initialize a logging record with interesting information. """ ct = time.time() self.name = name self.msg = msg # # The following statement allows passing of a dictionary as a sole # argument, so that you can do something like # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) # Suggested by Stefan Behnel. # Note that without the test for args[0], we get a problem because # during formatting, we test to see if the arg is present using # 'if self.args:'. If the event being logged is e.g. 'Value is %d' # and if the passed arg fails 'if self.args:' then no formatting # is done. For example, logger.warning('Value is %d', 0) would log # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. # Issue #21172: a request was made to relax the isinstance check # to hasattr(args[0], '__getitem__'). However, the docs on string # formatting still seem to suggest a mapping object is required. # Thus, while not removing the isinstance check, it does now look # for collections.Mapping rather than, as before, dict. if (args and len(args) == 1 and isinstance(args[0], collections.Mapping) and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) self.levelno = level self.pathname = pathname try: self.filename = os.path.basename(pathname) self.module = os.path.splitext(self.filename)[0] except (TypeError, ValueError, AttributeError): self.filename = pathname self.module = "Unknown module" self.exc_info = exc_info self.exc_text = None # used to cache the traceback text self.stack_info = sinfo self.lineno = lineno self.funcName = func self.created = ct self.msecs = (ct - int(ct)) * 1000 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads and threading: self.thread = threading.get_ident() self.threadName = threading.current_thread().name else: # pragma: no cover self.thread = None self.threadName = None if not logMultiprocessing: # pragma: no cover self.processName = None else: self.processName = 'MainProcess' mp = sys.modules.get('multiprocessing') if mp is not None: # Errors may occur if multiprocessing has not finished loading # yet - e.g. if a custom import hook causes third-party code # to run when multiprocessing calls import. See issue 8200 # for an example try: self.processName = mp.current_process().name except Exception: #pragma: no cover pass if logProcesses and hasattr(os, 'getpid'): self.process = os.getpid() else: self.process = None def __str__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) __repr__ = __str__ def getMessage(self): """ Return the message for this LogRecord. Return the message for this LogRecord after merging any user-supplied arguments with the message. """ msg = str(self.msg) if self.args: msg = msg % self.args return msg # # Determine which class to use when instantiating log records. # _logRecordFactory = LogRecord def setLogRecordFactory(factory): """ Set the factory to be used when instantiating a log record. :param factory: A callable which will be called to instantiate a log record. """ global _logRecordFactory _logRecordFactory = factory def getLogRecordFactory(): """ Return the factory to be used when instantiating a log record. """ return _logRecordFactory def makeLogRecord(dict): """ Make a LogRecord whose attributes are defined by the specified dictionary, This function is useful for converting a logging event received over a socket connection (which is sent as a dictionary) into a LogRecord instance. """ rv = _logRecordFactory(None, None, "", 0, "", (), None, None) rv.__dict__.update(dict) return rv #--------------------------------------------------------------------------- # Formatter classes and functions #--------------------------------------------------------------------------- class PercentStyle(object): default_format = '%(message)s' asctime_format = '%(asctime)s' asctime_search = '%(asctime)' def __init__(self, fmt): self._fmt = fmt or self.default_format def usesTime(self): return self._fmt.find(self.asctime_search) >= 0 def format(self, record): return self._fmt % record.__dict__ class StrFormatStyle(PercentStyle): default_format = '{message}' asctime_format = '{asctime}' asctime_search = '{asctime' def format(self, record): return self._fmt.format(**record.__dict__) class StringTemplateStyle(PercentStyle): default_format = '${message}' asctime_format = '${asctime}' asctime_search = '${asctime}' def __init__(self, fmt): self._fmt = fmt or self.default_format self._tpl = Template(self._fmt) def usesTime(self): fmt = self._fmt return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0 def format(self, record): return self._tpl.substitute(**record.__dict__) BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" _STYLES = { '%': (PercentStyle, BASIC_FORMAT), '{': (StrFormatStyle, '{levelname}:{name}:{message}'), '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), } class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. Formatters need to know how a LogRecord is constructed. They are responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the the style-dependent default value, "%(message)s", "{message}", or "${message}", is used. The Formatter can be initialized with a format string which makes use of knowledge of the LogRecord attributes - e.g. the default value mentioned above makes use of the fact that the user's message and arguments are pre- formatted into a LogRecord's message attribute. Currently, the useful attributes in a LogRecord are described by: %(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted """ converter = time.localtime def __init__(self, fmt=None, datefmt=None, style='%'): """ Initialize the formatter with specified format strings. Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument. If datefmt is omitted, you get an ISO8601-like (or RFC 3339-like) format. Use a style parameter of '%', '{' or '$' to specify that you want to use one of %-formatting, :meth:`str.format` (``{}``) formatting or :class:`string.Template` formatting in your format string. .. versionchanged:: 3.2 Added the ``style`` parameter. """ if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) self._style = _STYLES[style][0](fmt) self._fmt = self._style._fmt self.datefmt = datefmt default_time_format = '%Y-%m-%d %H:%M:%S' default_msec_format = '%s,%03d' def formatTime(self, record, datefmt=None): """ Return the creation time of the specified LogRecord as formatted text. This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) if datefmt: s = time.strftime(datefmt, ct) else: t = time.strftime(self.default_time_format, ct) s = self.default_msec_format % (t, record.msecs) return s def formatException(self, ei): """ Format and return the specified exception information as a string. This default implementation just uses traceback.print_exception() """ sio = io.StringIO() tb = ei[2] # See issues #9427, #1553375. Commented out for now. #if getattr(self, 'fullstack', False): # traceback.print_stack(tb.tb_frame.f_back, file=sio) traceback.print_exception(ei[0], ei[1], tb, None, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] return s def usesTime(self): """ Check if the format uses the creation time of the record. """ return self._style.usesTime() def formatMessage(self, record): return self._style.format(record) def formatStack(self, stack_info): """ This method is provided as an extension point for specialized formatting of stack information. The input data is a string as returned from a call to :func:`traceback.print_stack`, but with the last trailing newline removed. The base implementation just returns the value passed in. """ return stack_info def format(self, record): """ Format the specified record as text. The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message. """ record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) return s # # The default formatter to use when no other is specified # _defaultFormatter = Formatter() class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ def __init__(self, linefmt=None): """ Optionally specify a formatter which will be used to format each individual record. """ if linefmt: self.linefmt = linefmt else: self.linefmt = _defaultFormatter def formatHeader(self, records): """ Return the header string for the specified records. """ return "" def formatFooter(self, records): """ Return the footer string for the specified records. """ return "" def format(self, records): """ Format the specified records and return the result as a string. """ rv = "" if len(records) > 0: rv = rv + self.formatHeader(records) for record in records: rv = rv + self.linefmt.format(record) rv = rv + self.formatFooter(records) return rv #--------------------------------------------------------------------------- # Filter classes and functions #--------------------------------------------------------------------------- class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed. """ def __init__(self, name=''): """ Initialize a filter. Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event. """ self.name = name self.nlen = len(name) def filter(self, record): """ Determine if the specified record is to be logged. Is the specified record to be logged? Returns 0 for no, nonzero for yes. If deemed appropriate, the record may be modified in-place. """ if self.nlen == 0: return True elif self.name == record.name: return True elif record.name.find(self.name, 0, self.nlen) != 0: return False return (record.name[self.nlen] == ".") class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. """ def __init__(self): """ Initialize the list of filters to be an empty list. """ self.filters = [] def addFilter(self, filter): """ Add the specified filter to this handler. """ if not (filter in self.filters): self.filters.append(filter) def removeFilter(self, filter): """ Remove the specified filter from this handler. """ if filter in self.filters: self.filters.remove(filter) def filter(self, record): """ Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto this and the record is then dropped. Returns a zero value if a record is to be dropped, else non-zero. .. versionchanged:: 3.2 Allow filters to be just callables. """ rv = True for f in self.filters: if hasattr(f, 'filter'): result = f.filter(record) else: result = f(record) # assume callable - will raise if not if not result: rv = False break return rv #--------------------------------------------------------------------------- # Handler classes and functions #--------------------------------------------------------------------------- _handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized def _removeHandlerRef(wr): """ Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are # set to None. It can also be called from another thread. So we need to # pre-emptively grab the necessary globals and check if they're None, # to prevent race conditions and failures during interpreter shutdown. acquire, release, handlers = _acquireLock, _releaseLock, _handlerList if acquire and release and handlers: acquire() try: if wr in handlers: handlers.remove(wr) finally: release() def _addHandlerRef(handler): """ Add a handler to the internal cleanup list using a weak reference. """ _acquireLock() try: _handlerList.append(weakref.ref(handler, _removeHandlerRef)) finally: _releaseLock() class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. The base handler class. Acts as a placeholder which defines the Handler interface. Handlers can optionally use Formatter instances to format records as desired. By default, no formatter is specified; in this case, the 'raw' message as determined by record.message is logged. """ def __init__(self, level=NOTSET): """ Initializes the instance - basically setting the formatter to None and the filter list to empty. """ Filterer.__init__(self) self._name = None self.level = _checkLevel(level) self.formatter = None # Add the handler to the global _handlerList (for cleanup on shutdown) _addHandlerRef(self) self.createLock() def get_name(self): return self._name def set_name(self, name): _acquireLock() try: if self._name in _handlers: del _handlers[self._name] self._name = name if name: _handlers[name] = self finally: _releaseLock() name = property(get_name, set_name) def createLock(self): """ Acquire a thread lock for serializing access to the underlying I/O. """ if threading: self.lock = threading.RLock() else: #pragma: no cover self.lock = None def acquire(self): """ Acquire the I/O thread lock. """ if self.lock: self.lock.acquire() def release(self): """ Release the I/O thread lock. """ if self.lock: self.lock.release() def setLevel(self, level): """ Set the logging level of this handler. level must be an int or a str. """ self.level = _checkLevel(level) def format(self, record): """ Format the specified record. If a formatter is set, use it. Otherwise, use the default formatter for the module. """ if self.formatter: fmt = self.formatter else: fmt = _defaultFormatter return fmt.format(record) def emit(self, record): """ Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so raises a NotImplementedError. """ raise NotImplementedError('emit must be implemented ' 'by Handler subclasses') def handle(self, record): """ Conditionally emit the specified logging record. Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns whether the filter passed the record for emission. """ rv = self.filter(record) if rv: self.acquire() try: self.emit(record) finally: self.release() return rv def setFormatter(self, fmt): """ Set the formatter for this handler. """ self.formatter = fmt def flush(self): """ Ensure all logging output has been flushed. This version does nothing and is intended to be implemented by subclasses. """ pass def close(self): """ Tidy up any resources used by the handler. This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... if self._name and self._name in _handlers: del _handlers[self._name] finally: _releaseLock() def handleError(self, record): """ Handle errors which occur during an emit() call. This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method. """ if raiseExceptions and sys.stderr: # see issue 13807 t, v, tb = sys.exc_info() try: sys.stderr.write('--- Logging error ---\n') traceback.print_exception(t, v, tb, None, sys.stderr) sys.stderr.write('Call stack:\n') # Walk the stack frame up until we're out of logging, # so as to print the calling context. frame = tb.tb_frame while (frame and os.path.dirname(frame.f_code.co_filename) == __path__[0]): frame = frame.f_back if frame: traceback.print_stack(frame, file=sys.stderr) else: # couldn't find the right stack frame, for some reason sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) # Issue 18671: output logging message and arguments try: sys.stderr.write('Message: %r\n' 'Arguments: %s\n' % (record.msg, record.args)) except Exception: sys.stderr.write('Unable to print the message and arguments' ' - possible formatting error.\nUse the' ' traceback above to help find the error.\n' ) except OSError: #pragma: no cover pass # see issue 5971 finally: del t, v, tb def __repr__(self): level = getLevelName(self.level) return '<%s (%s)>' % (self.__class__.__name__, level) class StreamHandler(Handler): """ A handler class which writes logging records, appropriately formatted, to a stream. Note that this class does not close the stream, as sys.stdout or sys.stderr may be used. """ terminator = '\n' def __init__(self, stream=None): """ Initialize the handler. If stream is not specified, sys.stderr is used. """ Handler.__init__(self) if stream is None: stream = sys.stderr self.stream = stream def flush(self): """ Flushes the stream. """ self.acquire() try: if self.stream and hasattr(self.stream, "flush"): self.stream.flush() finally: self.release() def emit(self, record): """ Emit a record. If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an 'encoding' attribute, it is used to determine how to do the output to the stream. """ try: msg = self.format(record) stream = self.stream stream.write(msg) stream.write(self.terminator) self.flush() except Exception: self.handleError(record) def __repr__(self): level = getLevelName(self.level) name = getattr(self.stream, 'name', '') if name: name += ' ' return '<%s %s(%s)>' % (self.__class__.__name__, name, level) class FileHandler(StreamHandler): """ A handler class which writes formatted logging records to disk files. """ def __init__(self, filename, mode='a', encoding=None, delay=False): """ Open the specified file and use it as the stream for logging. """ # Issue #27493: add support for Path objects to be passed in filename = os.fspath(filename) #keep the absolute path, otherwise derived classes which use this #may come a cropper when the current directory changes self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding self.delay = delay if delay: #We don't open the stream, but we still need to call the #Handler constructor to set level, formatter, lock etc. Handler.__init__(self) self.stream = None else: StreamHandler.__init__(self, self._open()) def close(self): """ Closes the stream. """ self.acquire() try: try: if self.stream: try: self.flush() finally: stream = self.stream self.stream = None if hasattr(stream, "close"): stream.close() finally: # Issue #19523: call unconditionally to # prevent a handler leak when delay is set StreamHandler.close(self) finally: self.release() def _open(self): """ Open the current base file with the (original) mode and encoding. Return the resulting stream. """ return open(self.baseFilename, self.mode, encoding=self.encoding) def emit(self, record): """ Emit a record. If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit. """ if self.stream is None: self.stream = self._open() StreamHandler.emit(self, record) def __repr__(self): level = getLevelName(self.level) return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level) class _StderrHandler(StreamHandler): """ This class is like a StreamHandler using sys.stderr, but always uses whatever sys.stderr is currently set to rather than the value of sys.stderr at handler construction time. """ def __init__(self, level=NOTSET): """ Initialize the handler. """ Handler.__init__(self, level) @property def stream(self): return sys.stderr _defaultLastResort = _StderrHandler(WARNING) lastResort = _defaultLastResort #--------------------------------------------------------------------------- # Manager classes and functions #--------------------------------------------------------------------------- class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is intended for internal use only and not as part of the public API. """ def __init__(self, alogger): """ Initialize with the specified logger being a child of this placeholder. """ self.loggerMap = { alogger : None } def append(self, alogger): """ Add the specified logger as a child of this placeholder. """ if alogger not in self.loggerMap: self.loggerMap[alogger] = None # # Determine which class to use when instantiating loggers. # def setLoggerClass(klass): """ Set the class to be used when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__() """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) global _loggerClass _loggerClass = klass def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ return _loggerClass class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. """ def __init__(self, rootnode): """ Initialize the manager with the root node of the logger hierarchy. """ self.root = rootnode self.disable = 0 self.emittedNoHandlerWarning = False self.loggerDict = {} self.loggerClass = None self.logRecordFactory = None def getLogger(self, name): """ Get a logger with the specified name (channel name), creating it if it doesn't yet exist. This name is a dot-separated hierarchical name, such as "a", "a.b", "a.b.c" or similar. If a PlaceHolder existed for the specified name [i.e. the logger didn't exist but a child of it did], replace it with the created logger and fix up the parent/child references which pointed to the placeholder to now point to the logger. """ rv = None if not isinstance(name, str): raise TypeError('A logger name must be a string') _acquireLock() try: if name in self.loggerDict: rv = self.loggerDict[name] if isinstance(rv, PlaceHolder): ph = rv rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupChildren(ph, rv) self._fixupParents(rv) else: rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupParents(rv) finally: _releaseLock() return rv def setLoggerClass(self, klass): """ Set the class to be used when instantiating a logger with this Manager. """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) self.loggerClass = klass def setLogRecordFactory(self, factory): """ Set the factory to be used when instantiating a log record with this Manager. """ self.logRecordFactory = factory def _fixupParents(self, alogger): """ Ensure that there are either loggers or placeholders all the way from the specified logger to the root of the logger hierarchy. """ name = alogger.name i = name.rfind(".") rv = None while (i > 0) and not rv: substr = name[:i] if substr not in self.loggerDict: self.loggerDict[substr] = PlaceHolder(alogger) else: obj = self.loggerDict[substr] if isinstance(obj, Logger): rv = obj else: assert isinstance(obj, PlaceHolder) obj.append(alogger) i = name.rfind(".", 0, i - 1) if not rv: rv = self.root alogger.parent = rv def _fixupChildren(self, ph, alogger): """ Ensure that children of the placeholder ph are connected to the specified logger. """ name = alogger.name namelen = len(name) for c in ph.loggerMap.keys(): #The if means ... if not c.parent.name.startswith(nm) if c.parent.name[:namelen] != name: alogger.parent = c.parent c.parent = alogger #--------------------------------------------------------------------------- # Logger classes and functions #--------------------------------------------------------------------------- class Logger(Filterer): """ Instances of the Logger class represent a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting. """ def __init__(self, name, level=NOTSET): """ Initialize the logger with a name and an optional level. """ Filterer.__init__(self) self.name = name self.level = _checkLevel(level) self.parent = None self.propagate = True self.handlers = [] self.disabled = False def setLevel(self, level): """ Set the logging level of this logger. level must be an int or a str. """ self.level = _checkLevel(level) def debug(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'DEBUG'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.debug("Houston, we have a %s", "thorny problem", exc_info=1) """ if self.isEnabledFor(DEBUG): self._log(DEBUG, msg, args, **kwargs) def info(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'INFO'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.info("Houston, we have a %s", "interesting problem", exc_info=1) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) def warning(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'WARNING'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1) """ if self.isEnabledFor(WARNING): self._log(WARNING, msg, args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'ERROR'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.error("Houston, we have a %s", "major problem", exc_info=1) """ if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Convenience method for logging an ERROR with exception information. """ self.error(msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'CRITICAL'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.critical("Houston, we have a %s", "major disaster", exc_info=1) """ if self.isEnabledFor(CRITICAL): self._log(CRITICAL, msg, args, **kwargs) fatal = critical def log(self, level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.log(level, "We have a %s", "mysterious problem", exc_info=1) """ if not isinstance(level, int): if raiseExceptions: raise TypeError("level must be an integer") else: return if self.isEnabledFor(level): self._log(level, msg, args, **kwargs) def findCaller(self, stack_info=False): """ Find the stack frame of the caller so that we can note the source file name, line number and function name. """ f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. if f is not None: f = f.f_back rv = "(unknown file)", 0, "(unknown function)", None while hasattr(f, "f_code"): co = f.f_code filename = os.path.normcase(co.co_filename) if filename == _srcfile: f = f.f_back continue sinfo = None if stack_info: sio = io.StringIO() sio.write('Stack (most recent call last):\n') traceback.print_stack(f, file=sio) sinfo = sio.getvalue() if sinfo[-1] == '\n': sinfo = sinfo[:-1] sio.close() rv = (co.co_filename, f.f_lineno, co.co_name, sinfo) break return rv def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None): """ A factory method which can be overridden in subclasses to create specialized LogRecords. """ rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func, sinfo) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] return rv def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): """ Low-level logging routine which creates a LogRecord and then calls all the handlers of this logger to handle the record. """ sinfo = None if _srcfile: #IronPython doesn't track Python frames, so findCaller raises an #exception on some versions of IronPython. We trap it here so that #IronPython can use logging. try: fn, lno, func, sinfo = self.findCaller(stack_info) except ValueError: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" else: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: if isinstance(exc_info, BaseException): exc_info = (type(exc_info), exc_info, exc_info.__traceback__) elif not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra, sinfo) self.handle(record) def handle(self, record): """ Call the handlers for the specified record. This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ if (not self.disabled) and self.filter(record): self.callHandlers(record) def addHandler(self, hdlr): """ Add the specified handler to this logger. """ _acquireLock() try: if not (hdlr in self.handlers): self.handlers.append(hdlr) finally: _releaseLock() def removeHandler(self, hdlr): """ Remove the specified handler from this logger. """ _acquireLock() try: if hdlr in self.handlers: self.handlers.remove(hdlr) finally: _releaseLock() def hasHandlers(self): """ See if this logger has any handlers configured. Loop through all handlers for this logger and its parents in the logger hierarchy. Return True if a handler was found, else False. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger which is checked for the existence of handlers. """ c = self rv = False while c: if c.handlers: rv = True break if not c.propagate: break else: c = c.parent return rv def callHandlers(self, record): """ Pass a record to all relevant handlers. Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called. """ c = self found = 0 while c: for hdlr in c.handlers: found = found + 1 if record.levelno >= hdlr.level: hdlr.handle(record) if not c.propagate: c = None #break out else: c = c.parent if (found == 0): if lastResort: if record.levelno >= lastResort.level: lastResort.handle(record) elif raiseExceptions and not self.manager.emittedNoHandlerWarning: sys.stderr.write("No handlers could be found for logger" " \"%s\"\n" % self.name) self.manager.emittedNoHandlerWarning = True def getEffectiveLevel(self): """ Get the effective level for this logger. Loop through this logger and its parents in the logger hierarchy, looking for a non-zero logging level. Return the first one found. """ logger = self while logger: if logger.level: return logger.level logger = logger.parent return NOTSET def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.manager.disable >= level: return False return level >= self.getEffectiveLevel() def getChild(self, suffix): """ Get a logger which is a descendant to this one. This is a convenience method, such that logging.getLogger('abc').getChild('def.ghi') is the same as logging.getLogger('abc.def.ghi') It's useful, for example, when the parent logger is named using __name__ rather than a literal string. """ if self.root is not self: suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) def __repr__(self): level = getLevelName(self.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) class RootLogger(Logger): """ A root logger is not that different to any other logger, except that it must have a logging level and there is only one instance of it in the hierarchy. """ def __init__(self, level): """ Initialize the logger with the name "root". """ Logger.__init__(self, "root", level) _loggerClass = Logger class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. """ def __init__(self, logger, extra): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows easy stacking of LoggerAdapters, if so desired. You can effectively pass keyword arguments as shown in the following example: adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) """ self.logger = logger self.extra = extra def process(self, msg, kwargs): """ Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs. Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs. """ kwargs["extra"] = self.extra return msg, kwargs # # Boilerplate convenience methods # def debug(self, msg, *args, **kwargs): """ Delegate a debug call to the underlying logger. """ self.log(DEBUG, msg, *args, **kwargs) def info(self, msg, *args, **kwargs): """ Delegate an info call to the underlying logger. """ self.log(INFO, msg, *args, **kwargs) def warning(self, msg, *args, **kwargs): """ Delegate a warning call to the underlying logger. """ self.log(WARNING, msg, *args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Delegate an error call to the underlying logger. """ self.log(ERROR, msg, *args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Delegate an exception call to the underlying logger. """ self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Delegate a critical call to the underlying logger. """ self.log(CRITICAL, msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Delegate a log call to the underlying logger, after adding contextual information from this adapter instance. """ if self.isEnabledFor(level): msg, kwargs = self.process(msg, kwargs) self.logger.log(level, msg, *args, **kwargs) def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.logger.manager.disable >= level: return False return level >= self.getEffectiveLevel() def setLevel(self, level): """ Set the specified level on the underlying logger. """ self.logger.setLevel(level) def getEffectiveLevel(self): """ Get the effective level for the underlying logger. """ return self.logger.getEffectiveLevel() def hasHandlers(self): """ See if the underlying logger has any handlers. """ return self.logger.hasHandlers() def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): """ Low-level log implementation, proxied to allow nested logger adapters. """ return self.logger._log( level, msg, args, exc_info=exc_info, extra=extra, stack_info=stack_info, ) @property def manager(self): return self.logger.manager @manager.setter def manager(self, value): self.logger.manager = value @property def name(self): return self.logger.name def __repr__(self): logger = self.logger level = getLevelName(logger.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level) root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) #--------------------------------------------------------------------------- # Configuration classes and functions #--------------------------------------------------------------------------- def basicConfig(**kwargs): """ Do basic configuration for the logging system. This function does nothing if the root logger already has handlers configured. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package. The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger. A number of optional keyword arguments may be specified, which can alter the default behaviour. filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler. filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format Use the specified format string for the handler. datefmt Use the specified date/time format. style If a format string is specified, use this to specify the type of format string (possible values '%', '{', '$', for %-formatting, :meth:`str.format` and :class:`string.Template` - defaults to '%'). level Set the root logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored. handlers If specified, this should be an iterable of already created handlers, which will be added to the root handler. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function. Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed. .. versionchanged:: 3.2 Added the ``style`` parameter. .. versionchanged:: 3.3 Added the ``handlers`` parameter. A ``ValueError`` is now thrown for incompatible arguments (e.g. ``handlers`` specified together with ``filename``/``filemode``, or ``filename``/``filemode`` specified together with ``stream``, or ``handlers`` specified together with ``stream``. """ # Add thread safety in case someone mistakenly calls # basicConfig() from multiple threads _acquireLock() try: if len(root.handlers) == 0: handlers = kwargs.pop("handlers", None) if handlers is None: if "stream" in kwargs and "filename" in kwargs: raise ValueError("'stream' and 'filename' should not be " "specified together") else: if "stream" in kwargs or "filename" in kwargs: raise ValueError("'stream' or 'filename' should not be " "specified together with 'handlers'") if handlers is None: filename = kwargs.pop("filename", None) mode = kwargs.pop("filemode", 'a') if filename: h = FileHandler(filename, mode) else: stream = kwargs.pop("stream", None) h = StreamHandler(stream) handlers = [h] dfs = kwargs.pop("datefmt", None) style = kwargs.pop("style", '%') if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) fs = kwargs.pop("format", _STYLES[style][1]) fmt = Formatter(fs, dfs, style) for h in handlers: if h.formatter is None: h.setFormatter(fmt) root.addHandler(h) level = kwargs.pop("level", None) if level is not None: root.setLevel(level) if kwargs: keys = ', '.join(kwargs.keys()) raise ValueError('Unrecognised argument(s): %s' % keys) finally: _releaseLock() #--------------------------------------------------------------------------- # Utility functions at module level. # Basically delegate everything to the root logger. #--------------------------------------------------------------------------- def getLogger(name=None): """ Return a logger with the specified name, creating it if necessary. If no name is specified, return the root logger. """ if name: return Logger.manager.getLogger(name) else: return root def critical(msg, *args, **kwargs): """ Log a message with severity 'CRITICAL' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.critical(msg, *args, **kwargs) fatal = critical def error(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.error(msg, *args, **kwargs) def exception(msg, *args, exc_info=True, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. If the logger has no handlers, basicConfig() is called to add a console handler with a pre-defined format. """ error(msg, *args, exc_info=exc_info, **kwargs) def warning(msg, *args, **kwargs): """ Log a message with severity 'WARNING' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.warning(msg, *args, **kwargs) def warn(msg, *args, **kwargs): warnings.warn("The 'warn' function is deprecated, " "use 'warning' instead", DeprecationWarning, 2) warning(msg, *args, **kwargs) def info(msg, *args, **kwargs): """ Log a message with severity 'INFO' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.info(msg, *args, **kwargs) def debug(msg, *args, **kwargs): """ Log a message with severity 'DEBUG' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.debug(msg, *args, **kwargs) def log(level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.log(level, msg, *args, **kwargs) def disable(level): """ Disable all logging calls of severity 'level' and below. """ root.manager.disable = level def shutdown(handlerList=_handlerList): """ Perform any cleanup actions in the logging system (e.g. flushing buffers). Should be called at application exit. """ for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: h = wr() if h: try: h.acquire() h.flush() h.close() except (OSError, ValueError): # Ignore errors which might be caused # because handlers have been closed but # references to them are still around at # application exit. pass finally: h.release() except: # ignore everything, as we're shutting down if raiseExceptions: raise #else, swallow #Let's try and shutdown automatically on application exit... import atexit atexit.register(shutdown) # Null handler class NullHandler(Handler): """ This handler does nothing. It's intended to be used to avoid the "No handlers could be found for logger XXX" one-off warning. This is important for library code, which may contain code to log events. If a user of the library does not configure logging, the one-off warning might be produced; to avoid this, the library developer simply needs to instantiate a NullHandler and add it to the top-level logger of the library module or package. """ def handle(self, record): """Stub.""" def emit(self, record): """Stub.""" def createLock(self): self.lock = None # Warnings integration _warnings_showwarning = None def _showwarning(message, category, filename, lineno, file=None, line=None): """ Implementation of showwarnings which redirects to logging, which will first check to see if the file parameter is None. If a file is specified, it will delegate to the original warnings implementation of showwarning. Otherwise, it will call warnings.formatwarning and will log the resulting string to a warnings logger named "py.warnings" with level logging.WARNING. """ if file is not None: if _warnings_showwarning is not None: _warnings_showwarning(message, category, filename, lineno, file, line) else: s = warnings.formatwarning(message, category, filename, lineno, line) logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) logger.warning("%s", s) def captureWarnings(capture): """ If capture is true, redirect all warnings to the logging package. If capture is False, ensure that warnings are not redirected to logging but to their original destinations. """ global _warnings_showwarning if capture: if _warnings_showwarning is None: _warnings_showwarning = warnings.showwarning warnings.showwarning = _showwarning else: if _warnings_showwarning is not None: warnings.showwarning = _warnings_showwarning _warnings_showwarning = None usr/lib/python3.6/site-packages/dnf/__init__.py000064400000002555152345420760015312 0ustar00# __init__.py # The toplevel DNF package. # # Copyright (C) 2012-2016 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU General Public License v.2, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY expressed or implied, including the implied warranties of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. You should have received a copy of the # GNU General Public License along with this program; if not, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # from __future__ import unicode_literals import warnings import dnf.pycomp warnings.filterwarnings('once', category=DeprecationWarning, module=r'^dnf\..*$') from dnf.const import VERSION __version__ = VERSION # :api import dnf.base Base = dnf.base.Base # :api import dnf.plugin Plugin = dnf.plugin.Plugin # :api # setup libraries dnf.pycomp.urlparse.uses_fragment.append("media") usr/lib64/python3.6/dbm/__init__.py000064400000013227152345534420012734 0ustar00"""Generic interface to all dbm clones. Use import dbm d = dbm.open(file, 'w', 0o666) The returned object is a dbm.gnu, dbm.ndbm or dbm.dumb object, dependent on the type of database being opened (determined by the whichdb function) in the case of an existing dbm. If the dbm does not exist and the create or new flag ('c' or 'n') was specified, the dbm type will be determined by the availability of the modules (tested in the above order). It has the following interface (key and data are strings): d[key] = data # store data at key (may override data at # existing key) data = d[key] # retrieve data at key (raise KeyError if no # such key) del d[key] # delete data stored at key (raises KeyError # if no such key) flag = key in d # true if the key exists list = d.keys() # return a list of all existing keys (slow!) Future versions may change the order in which implementations are tested for existence, and add interfaces to other dbm-like implementations. """ __all__ = ['open', 'whichdb', 'error'] import io import os import struct import sys class error(Exception): pass _names = ['dbm.gnu', 'dbm.ndbm', 'dbm.dumb'] _defaultmod = None _modules = {} error = (error, OSError) try: from dbm import ndbm except ImportError: ndbm = None def open(file, flag='r', mode=0o666): """Open or create database at path given by *file*. Optional argument *flag* can be 'r' (default) for read-only access, 'w' for read-write access of an existing database, 'c' for read-write access to a new or existing database, and 'n' for read-write access to a new database. Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it only if it doesn't exist; and 'n' always creates a new database. """ global _defaultmod if _defaultmod is None: for name in _names: try: mod = __import__(name, fromlist=['open']) except ImportError: continue if not _defaultmod: _defaultmod = mod _modules[name] = mod if not _defaultmod: raise ImportError("no dbm clone found; tried %s" % _names) # guess the type of an existing database, if not creating a new one result = whichdb(file) if 'n' not in flag else None if result is None: # db doesn't exist or 'n' flag was specified to create a new db if 'c' in flag or 'n' in flag: # file doesn't exist and the new flag was used so use default type mod = _defaultmod else: raise error[0]("need 'c' or 'n' flag to open new db") elif result == "": # db type cannot be determined raise error[0]("db type could not be determined") elif result not in _modules: raise error[0]("db type is {0}, but the module is not " "available".format(result)) else: mod = _modules[result] return mod.open(file, flag, mode) def whichdb(filename): """Guess which db package to use to open a db file. Return values: - None if the database file can't be read; - empty string if the file can be read but can't be recognized - the name of the dbm submodule (e.g. "ndbm" or "gnu") if recognized. Importing the given module may still fail, and opening the database using that module may still fail. """ # Check for ndbm first -- this has a .pag and a .dir file try: f = io.open(filename + ".pag", "rb") f.close() f = io.open(filename + ".dir", "rb") f.close() return "dbm.ndbm" except OSError: # some dbm emulations based on Berkeley DB generate a .db file # some do not, but they should be caught by the bsd checks try: f = io.open(filename + ".db", "rb") f.close() # guarantee we can actually open the file using dbm # kind of overkill, but since we are dealing with emulations # it seems like a prudent step if ndbm is not None: d = ndbm.open(filename) d.close() return "dbm.ndbm" except OSError: pass # Check for dumbdbm next -- this has a .dir and a .dat file try: # First check for presence of files os.stat(filename + ".dat") size = os.stat(filename + ".dir").st_size # dumbdbm files with no keys are empty if size == 0: return "dbm.dumb" f = io.open(filename + ".dir", "rb") try: if f.read(1) in (b"'", b'"'): return "dbm.dumb" finally: f.close() except OSError: pass # See if the file exists, return None if not try: f = io.open(filename, "rb") except OSError: return None with f: # Read the start of the file -- the magic number s16 = f.read(16) s = s16[0:4] # Return "" if not at least 4 bytes if len(s) != 4: return "" # Convert to 4-byte int in native byte order -- return "" if impossible try: (magic,) = struct.unpack("=l", s) except struct.error: return "" # Check for GNU dbm if magic in (0x13579ace, 0x13579acd, 0x13579acf): return "dbm.gnu" # Later versions of Berkeley db hash file have a 12-byte pad in # front of the file type try: (magic,) = struct.unpack("=l", s16[-4:]) except struct.error: return "" # Unknown return "" if __name__ == "__main__": for filename in sys.argv[1:]: print(whichdb(filename) or "UNKNOWN", filename) lib64/python3.12/ctypes/macholib/__init__.py000064400000000232152345534750014521 0ustar00""" Enough Mach-O to make your head spin. See the relevant header files in /usr/include/mach-o And also Apple's documentation. """ __version__ = '1.0' usr/lib64/python2.7/encodings/__init__.py000064400000013102152345535270014137 0ustar00""" Standard "encodings" Package Standard Python encoding modules are stored in this package directory. Codec modules must have names corresponding to normalized encoding names as defined in the normalize_encoding() function below, e.g. 'utf-8' must be implemented by the module 'utf_8.py'. Each codec module must export the following interface: * getregentry() -> codecs.CodecInfo object The getregentry() API must a CodecInfo object with encoder, decoder, incrementalencoder, incrementaldecoder, streamwriter and streamreader atttributes which adhere to the Python Codec Interface Standard. In addition, a module may optionally also define the following APIs which are then used by the package's codec search function: * getaliases() -> sequence of encoding name strings to use as aliases Alias names returned by getaliases() must be normalized encoding names as defined by normalize_encoding(). Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" import codecs from encodings import aliases import __builtin__ _cache = {} _unknown = '--unknown--' _import_tail = ['*'] _norm_encoding_map = (' . ' '0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ ' ' abcdefghijklmnopqrstuvwxyz ' ' ' ' ' ' ') _aliases = aliases.aliases class CodecRegistryError(LookupError, SystemError): pass def normalize_encoding(encoding): """ Normalize an encoding name. Normalization works as follows: all non-alphanumeric characters except the dot used for Python package names are collapsed and replaced with a single underscore, e.g. ' -;#' becomes '_'. Leading and trailing underscores are removed. Note that encoding names should be ASCII only; if they do use non-ASCII characters, these must be Latin-1 compatible. """ # Make sure we have an 8-bit string, because .translate() works # differently for Unicode strings. if hasattr(__builtin__, "unicode") and isinstance(encoding, unicode): # Note that .encode('latin-1') does *not* use the codec # registry, so this call doesn't recurse. (See unicodeobject.c # PyUnicode_AsEncodedString() for details) encoding = encoding.encode('latin-1') return '_'.join(encoding.translate(_norm_encoding_map).split()) def search_function(encoding): # Cache lookup entry = _cache.get(encoding, _unknown) if entry is not _unknown: return entry # Import the module: # # First try to find an alias for the normalized encoding # name and lookup the module using the aliased name, then try to # lookup the module using the standard import scheme, i.e. first # try in the encodings package, then at top-level. # norm_encoding = normalize_encoding(encoding) aliased_encoding = _aliases.get(norm_encoding) or \ _aliases.get(norm_encoding.replace('.', '_')) if aliased_encoding is not None: modnames = [aliased_encoding, norm_encoding] else: modnames = [norm_encoding] for modname in modnames: if not modname or '.' in modname: continue try: # Import is absolute to prevent the possibly malicious import of a # module with side-effects that is not in the 'encodings' package. mod = __import__('encodings.' + modname, fromlist=_import_tail, level=0) except ImportError: pass else: break else: mod = None try: getregentry = mod.getregentry except AttributeError: # Not a codec module mod = None if mod is None: # Cache misses _cache[encoding] = None return None # Now ask the module for the registry entry entry = getregentry() if not isinstance(entry, codecs.CodecInfo): if not 4 <= len(entry) <= 7: raise CodecRegistryError,\ 'module "%s" (%s) failed to register' % \ (mod.__name__, mod.__file__) if not hasattr(entry[0], '__call__') or \ not hasattr(entry[1], '__call__') or \ (entry[2] is not None and not hasattr(entry[2], '__call__')) or \ (entry[3] is not None and not hasattr(entry[3], '__call__')) or \ (len(entry) > 4 and entry[4] is not None and not hasattr(entry[4], '__call__')) or \ (len(entry) > 5 and entry[5] is not None and not hasattr(entry[5], '__call__')): raise CodecRegistryError,\ 'incompatible codecs in module "%s" (%s)' % \ (mod.__name__, mod.__file__) if len(entry)<7 or entry[6] is None: entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],) entry = codecs.CodecInfo(*entry) # Cache the codec registry entry _cache[encoding] = entry # Register its aliases (without overwriting previously registered # aliases) try: codecaliases = mod.getaliases() except AttributeError: pass else: for alias in codecaliases: if alias not in _aliases: _aliases[alias] = modname # Return the registry entry return entry # Register the search_function in the Python codec registry codecs.register(search_function) usr/lib/python3.8/site-packages/pip/__init__.py000064400000000027152345554460015332 0ustar00__version__ = "19.3.1" usr/lib/python3.6/site-packages/pyudev/__init__.py000064400000004676152345560130016061 0ustar00# -*- coding: utf-8 -*- # Copyright (C) 2010, 2011, 2012 Sebastian Wiesner # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation; either version 2.1 of the License, or (at your # option) any later version. # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License # for more details. # You should have received a copy of the GNU Lesser General Public License # along with this library; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ pyudev ====== A binding to libudev. The :class:`Context` provides the connection to the udev device database and enumerates devices. Individual devices are represented by the :class:`Device` class. Device monitoring is provided by :class:`Monitor` and :class:`MonitorObserver`. With :mod:`pyudev.pyqt4`, :mod:`pyudev.pyside`, :mod:`pyudev.glib` and :mod:`pyudev.wx` device monitoring can be integrated into the event loop of various GUI toolkits. .. moduleauthor:: Sebastian Wiesner """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals from pyudev.device import Attributes from pyudev.device import Device from pyudev.device import Devices from pyudev.device import DeviceNotFoundAtPathError from pyudev.device import DeviceNotFoundByFileError from pyudev.device import DeviceNotFoundByNameError from pyudev.device import DeviceNotFoundByNumberError from pyudev.device import DeviceNotFoundError from pyudev.device import DeviceNotFoundInEnvironmentError from pyudev.device import Tags from pyudev.discover import DeviceFileHypothesis from pyudev.discover import DeviceNameHypothesis from pyudev.discover import DeviceNumberHypothesis from pyudev.discover import DevicePathHypothesis from pyudev.discover import Discovery from pyudev.core import Context from pyudev.core import Enumerator from pyudev.monitor import Monitor from pyudev.monitor import MonitorObserver from pyudev.version import __version__ from pyudev.version import __version_info__ from pyudev._util import udev_version usr/lib64/python3.12/multiprocessing/__init__.py000064400000001624152345566450015504 0ustar00# # Package analogous to 'threading.py' but using processes # # multiprocessing/__init__.py # # This package is intended to duplicate the functionality (and much of # the API) of threading.py but uses processes instead of threads. A # subpackage 'multiprocessing.dummy' has the same API but is a simple # wrapper for 'threading'. # # Copyright (c) 2006-2008, R Oudkerk # Licensed to PSF under a Contributor Agreement. # import sys from . import context # # Copy stuff from default context # __all__ = [x for x in dir(context._default_context) if not x.startswith('_')] globals().update((name, getattr(context._default_context, name)) for name in __all__) # # XXX These should not really be documented or public. # SUBDEBUG = 5 SUBWARNING = 25 # # Alias for main module -- will be reset by bootstrapping child processes # if '__main__' in sys.modules: sys.modules['__mp_main__'] = sys.modules['__main__'] lib64/python3.12/email/__init__.py000064400000003344152345600430012517 0ustar00# Copyright (C) 2001-2007 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org """A package for parsing, handling, and generating email messages.""" __all__ = [ 'base64mime', 'charset', 'encoders', 'errors', 'feedparser', 'generator', 'header', 'iterators', 'message', 'message_from_file', 'message_from_binary_file', 'message_from_string', 'message_from_bytes', 'mime', 'parser', 'quoprimime', 'utils', ] # Some convenience routines. Don't import Parser and Message as side-effects # of importing email since those cascadingly import most of the rest of the # email package. def message_from_string(s, *args, **kws): """Parse a string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parsestr(s) def message_from_bytes(s, *args, **kws): """Parse a bytes string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parsebytes(s) def message_from_file(fp, *args, **kws): """Read a file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parse(fp) def message_from_binary_file(fp, *args, **kws): """Read a binary file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parse(fp) usr/lib/python3.6/site-packages/iotop/__init__.py000064400000000000152345601670015655 0ustar00usr/lib64/python3.6/site-packages/librepo/__init__.py000064400000154654152345674730016371 0ustar00# librepo - A library providing (libcURL like) API to downloading repository # Copyright (C) 2012-2014 Tomas Mlcoch # # Licensed under the GNU Lesser General Public License Version 2.1 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # """ Version contants ---------------- .. data:: VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION Constants with version numbers and whole version string. .. _handle-options-label: :class:`~.Handle` options ------------------------- **LRO_** (aka LibRepo Option) prefixed constants are used to set :class:`.Handle` options via :meth:`~.Handle.setopt` method. This options could be also set by :class:`.Handle` attributes with the same names but in lowercase and without ``LRO_`` prefix. Example:: # The command: h.setopt(librepo.LRO_URLS, ["http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/17/Everything/i386/os/"]) # is equivalent to: h.urls = ["http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/17/Everything/i386/os/"] .. note:: For detailed description of this options consult :class:`.Handle` page. .. data:: LRO_UPDATE *Boolean*. Set to ``True`` if only want update localised or downloaded repository represented by :class:`.Result` object. Update mode is meant to download previously omitted repository file(s). .. data:: LRO_URLS *List or None*. Set repository urls (repository url and baseurl are interchangeable terms in this context). .. data:: LRO_MIRRORLIST *String or None*. **DEPRECATED** Set mirrorlist url (url could point to a metalink mirrorlist or to a simple mirrorlist where each line without ``'#'`` is considered as mirror url). .. data:: LRO_MIRRORLISTURL *String or None*. Mirrorlist URL. .. data:: LRO_METALINKURL *String or None*. Metalink URL. .. data:: LRO_LOCAL *Boolean*. If set to True, no local copy of repository is created and repository is just localized in its current location. When True, url of repository MUST be a local address (e.g. '/home/user/repo' or 'file:///home/user/repo'). .. data:: LRO_HTTPAUTH *Boolean*. If True, all supported methods of HTTP authentication are enabled. .. data:: LRO_USERPWD *String or None*. Set username and password for HTTP authentication. Param must be in format 'username:password'. .. data:: LRO_PROXY *String or None*. Set proxy server address. Port could be specified by different option or by the :[port] suffix of this address. Any protocol prefix (``http://``, ...) will be ignored. .. data:: LRO_PROXYPORT *Integer or None*. Set proxy port number to connect unless it is specified in the proxy address string. None sets default value 1080. .. data:: LRO_PROXYTYPE *Long*. Set type of proxy - could be one of :ref:`proxy-type-label` .. data:: LRO_PROXYAUTH *Boolean*. If True, all supported proxy authentication methods are enabled. If False, only basic authentication method is enabled. .. data:: LRO_PROXYUSERPWD *String or None*. Set username and password for proxy authentication in format 'username:password'. .. data:: LRO_PROGRESSCB *Function or None*. (See: :ref:`callback-progresscb-label`) Set progress callback. Callback must be in format: ``callback(userdata, total_to_download, downloaded)``. If total_to_download is 0, then total size is not known. Total size (total_to_download) could change (grow) among two callback calls (if some download failed and another mirror is tried). .. data:: LRO_PROGRESSDATA *Any object*. Set user data for the progress callback. .. data:: LRO_MAXSPEED *Long or None*. Set maximal allowed speed per download in bytes per second. 0 = unlimited speed - the default value. .. data:: LRO_DESTDIR *String or None*. Set destination directory for downloaded data (metadata or packages). .. data:: LRO_REPOTYPE *Integer*. One of :ref:`repotype-constants-label`. See more :meth:`~.Handle.repotype` Set type of repository. .. data:: LRO_CONNECTTIMEOUT *Integer or None. Set maximal timeout in sec for connection phase. Default value is 30. None as *val* sets the default value. .. data:: LRO_IGNOREMISSING *Boolean*. If you want to localize (LRO_LOCAL is True) a incomplete local repository (eg. only primary and filelists are present but repomd.xml contains more files), you could use LRO_YUMDLIST and specify only file that are present, or use LRO_YUMBLIST and specify files that are not present or use this option. .. data:: LRO_INTERRUPTIBLE *Boolean*. Librepo sets up its own SIGTERM handler. If the SIGTERM signal is catched, the current download is interrupted. .. data:: LRO_USERAGENT *String*. String for User-Agent: header in the http request sent to the remote server. .. data:: LRO_FETCHMIRRORS *Boolean*. With this option enabled, only mirrorlist download and parsing will be performed during :meth:`librepo.Handle.perform`. .. data:: LRO_MAXMIRRORTRIES *Integer or None*. If download fails, try at most the specified number of mirrors. 0 (None) means try all available mirrors. .. data:: LRO_MAXPARALLELDOWNLOADS *Integer or None*. Maximum number of parallel downloads. ``None`` sets default value. .. data:: LRO_MAXDOWNLOADSPERMIRROR *Integer or None*. Maximum number of parallel downloads per mirror. ``None`` sets default value. .. data:: LRO_VARSUB *[(String, String), ...] or None*. Set list of substitutions for variables in ulrs (e.g.: "http://foo/$version/"). ``[("releasever", "f18"), ("basearch", "i386")]`` .. data:: LRO_FASTESTMIRROR *Boolean*. If True, internal mirrorlist is sorted by the determined connection speed, after it is constructed. .. data:: LRO_FASTESTMIRRORCACHE *String or None*. Path to the cache file. If cache file it doesn't exists it will be created. .. data:: LRO_FASTESTMIRRORMAXAGE *Integer or None*. Max age of cache record. Older records will not be used. .. data:: LRO_FASTESTMIRRORCB *Function or None*. (See: :ref:`callback-fastestmirrorcb-label`) Fastest mirror status callback. Its prototype looks like ``callback(userdata, stage, data)`` Where *userdata* are data passed by user via LRO_FASTESTMIRRORDATA. *stage* is value from :ref:`fastestmirror-stages-constants-label`. *data* value depends on *stage* value. See the list of available stages. .. data:: LRO_FASTESTMIRRORDATA *Any object*. User data for fastest mirror status callback. .. data:: LRO_LOWSPEEDTIME *Integer or None*. The time in seconds that the transfer should be below the LRO_LOWSPEEDLIMIT for the library to consider it too slow and abort. Default: 30 (sec) .. data:: LRO_LOWSPEEDLIMIT *Integer or None*. The transfer speed in bytes per second that the transfer should be below during LRO_LOWSPEEDTIME seconds for the library to consider it too slow and abort. Default: 1000 (byte/s) .. data:: LRO_GPGCHECK *Boolean*. Set True to enable gpg check (if available) of downloaded repo. .. data:: LRO_CHECKSUM *Boolean*. Set False/True to disable/enable checksum check. .. note:: Checksum check is enabled by default. .. note:: If checksum check is disabled, then even explicitly specified checksum related params e.g. in :meth:`~librepo.Handle.download` method are ignored and checksum is not checked! .. data:: LRO_YUMDLIST *List of strings*. Some predefined list :ref:`predefined-yumdlists-label`. Set list of yum metadata files to download. e.g. ``["primary", "filelists", "other", "primary_db", "prestodelta"]`` If *val* is None, all metadata files will be downloaded. If *val* is ``[]`` or ``[None]`` only ``repomd.xml`` will be downloaded. .. data:: LRO_YUMSLIST *[(String, String), ...] or None*. Set list of substitutions for repomd records. ``[("group_gz", "group")]` .. data:: LRO_RPMMDDLIST See LRO_YUMDLIST .. data:: LRO_YUMBLIST *List of strings*. Set skiplist of yum metadata files. This files will not be downloaded. .. data:: LRO_RPMMDBLIST See LRO_YUMBLIST .. data:: LRO_HMFCB *Function or None* (See: :ref:`callback-handlemirrorfailurecb-label`) The Handle Mirror Failure Callback is called when a metadata download fails. It provides a detailed information about what exactly failed. Call of this callback doesn't mean that whole downloading failed. If there are other mirrors on the list, these mirrors will be tried. .. data:: LRO_SSLVERIFYPEER *Boolean*. This option determines whether librepo verifies the authenticity of the peer's certificate. This trust is based on a chain of digital signatures, rooted in certification authority (CA) certificates. .. data:: LRO_SSLVERIFYSTATUS *Boolean*. This option determines whether librepo verifies the status of the server cert using the 'Certificate Status Request' TLS extension (aka. OCSP stapling). Note that if this option is enabled but the server does not support the TLS extension, the verification will fail. */ .. data:: LRO_SSLVERIFYHOST *Boolean*. This option determines whether librepo verifies that the server cert is for the server it is known as. .. data:: LRO_SSLCLIENTCERT *String or None*. Path to the PEM format SSL client certificate to use when talking to the server. .. data:: LRO_SSLCLIENTKEY *String or None*. Path to the PEM format SSL client key to use when talking to the server. .. data:: LRO_SSLCACERT *String or None*. Path to a file containing the list of PEM format trusted CA certificates. .. data:: LRO_PROXY_SSLVERIFYPEER *Boolean*. This option determines whether librepo verifies the authenticity of the proxy certificate. This trust is based on a chain of digital signatures, rooted in certification authority (CA) certificates. .. data:: LRO_PROXY_SSLVERIFYHOST *Boolean*. This option determines whether librepo verifies the name of the proxy certificate against the host. .. data:: LRO_PROXY_SSLCLIENTCERT *String or None*. Path to the PEM format SSL client certificate to use when talking to the proxy. .. data:: LRO_PROXY_SSLCLIENTKEY *String or None*. Path to the PEM format SSL client key to use when talking to the proxy. .. data:: LRO_PROXY_SSLCACERT *String or None*. Path to a file containing the list of PEM format trusted CA certificates. Used for proxy. .. data:: LRO_IPRESOLVE *Integer or None* Sets kind of IP addresses to use when resolving host names. Could be one of: :ref:`ipresolve-type-label` .. data:: LRO_ALLOWEDMIRRORFAILURES *Integer or None* If all transfers from a mirror failed (no successful transfer from the mirror exists) and the number of failed downloads is higher or equal to this value the mirror will be skipped (ignored) for all next downloads. **Note:** Number of failed transfers for a single mirror can outreach this number! For example, if you set this value to 1 but you allow 3 parallel downloads it is possible that all three downloads start from the mirror, before any of them can fail. Then, if all three transfers fail, the number of failures for the mirror will be 3, even if this option was set to 1. .. data:: LRO_ADAPTIVEMIRRORSORTING *Integer or None* If enabled, internal list of mirrors for each handle is re-sorted after each finished transfer. The the sorting is based on mirror error rate etc. .. data:: LRO_GNUPGHOMEDIR *String or None* set own GNUPG configuration directory (a dir with keyring). .. data:: LRO_FASTESTMIRRORTIMEOUT *Float of None* Max length of fastest mirror measurement in seconds. Default value is 2.0sec. .. data:: LRO_HTTPHEADER *List of strings or None* List of strings that represent http headers. Each header has format "header_name: content". If you add a header with no content as in 'Accept:' (no data on the right side of the colon), the internally used header will get disabled. With this option you can add new headers, replace internal headers and remove internal headers. To add a header with no content (nothing to the right side of the colon), use the form 'MyHeader;' (note the ending semicolon). Note: Headers must not be CRLF-terminated! .. data:: LRO_OFFLINE *Boolean* Make the handle work only locally, all remote URLs are ignored. Remote mirrorlists/metalinks (if they are specified) are ignored. Fastest mirror check (if enabled) is skiped. .. data:: LRO_HTTPAUTHMETHODS *Long (bitmask)* Bitmask which tell Librepo which auth metods to use. See: :ref:`auth-methods-label` .. data:: LRO_PROXYAUTHMETHODS *Long (bitmask)* Bitmask which tell Librepo which auth metods to use for proxy authentication. See: :ref:`auth-methods-label` .. data:: LRO_FTPUSEEPSV *Boolean* Enable/Disable EPSV (Extended Passive mode) for FTP. .. data:: LRO_PRESERVETIME *Boolean* If enabled, librepo will try to keep timestamps of the downloaded files in sync with that on the remote side. .. _handle-info-options-label: :class:`~.Handle` info options ------------------------------ LRI (aka LibRepo Information) constants are used to get information from :class:`.Handle` via :meth:`~.Handle.getinfo` method. .. data:: LRI_UPDATE .. data:: LRI_URLS .. data:: LRI_MIRRORLIST .. data:: LRI_MIRRORLISTURL .. data:: LRI_METALINKURL .. data:: LRI_LOCAL .. data:: LRI_PROGRESSCB .. data:: LRI_PROGRESSDATA .. data:: LRI_DESTDIR .. data:: LRI_REPOTYPE .. data:: LRI_USERAGENT .. data:: LRI_YUMDLIST .. data:: LRI_YUMSLIST .. data:: LRI_RPMMDDLIST .. data:: LRI_YUMBLIST .. data:: LRI_RPMMDBLIST .. data:: LRI_FETCHMIRRORS .. data:: LRI_MAXMIRRORTRIES .. data:: LRI_VARSUB .. data:: LRI_MIRRORS .. data:: LRI_METALINK .. data:: LRI_FASTESTMIRROR .. data:: LRI_FASTESTMIRRORCACHE .. data:: LRI_FASTESTMIRRORMAXAGE .. data:: LRI_HMFCB .. data:: LRI_SSLVERIFYPEER .. data:: LRI_SSLVERIFYSTATUS .. data:: LRI_SSLVERIFYHOST .. data:: LRI_SSLCLIENTCERT .. data:: LRI_SSLCLIENTKEY .. data:: LRI_SSLCACERT .. data:: LRI_PROXY_SSLVERIFYPEER .. data:: LRI_PROXY_SSLVERIFYHOST .. data:: LRI_PROXY_SSLCLIENTCERT .. data:: LRI_PROXY_SSLCLIENTKEY .. data:: LRI_PROXY_SSLCACERT .. data:: LRI_IPRESOLVE .. data:: LRI_ALLOWEDMIRRORFAILURES .. data:: LRI_ADAPTIVEMIRRORSORTING .. data:: LRI_GNUPGHOMEDIR .. data:: LRI_FASTESTMIRRORTIMEOUT .. data:: LRI_HTTPHEADER .. data:: LRI_OFFLINE .. data:: LRI_HTTPAUTHMETHODS .. data:: LRI_PROXYAUTHMETHODS .. data:: LRI_FTPUSEEPSV .. _proxy-type-label: Proxy type constants -------------------- .. data:: PROXY_HTTP (LR_PROXY_HTTP) .. data:: PROXY_HTTP_1_0 (LR_PROXY_HTTP_1_0) .. data:: PROXY_SOCKS4 (LR_PROXY_SOCKS4) .. data:: PROXY_SOCKS5 (LR_PROXY_SOCKS5) .. data:: PROXY_SOCKS4A (LR_PROXY_SOCKS4A) .. data:: PROXY_SOCKS5_HOSTNAME (LR_PROXY_SOCKS5_HOSTNAME) .. _ipresolve-type-label: Supported IP resolving ---------------------- .. data:: IPRESOLVE_WHATEVER Default value, resolves addresses to all IP versions that your system allows. .. data:: IPRESOLVE_V4 Resolve to IPv4 addresses. .. data:: IPRESOLVE_V6 Resolve to IPv6 addresses. .. _repotype-constants-label: Repo type constants ------------------- .. data:: RPMMDREPO (LR_RPMMDREPO) Classical repository in repo-md format with ``repodata/`` directory. .. data:: YUMREPO (LR_YUMREPO) See RPMMDREPO .. data:: SUSEREPO (LR_SUSEREPO) YaST2 repository (http://en.opensuse.org/openSUSE:Standards_YaST2_Repository_Metadata_content). .. note:: This option is not supported yet! .. data:: DEBREPO (LR_DEBREPO) Debian repository .. note:: This option is not supported yet! .. _predefined-yumdlists-label: Predefined yumdlist lists ------------------------- .. data:: RPMMD_FULL (YUM_FULL, LR_YUM_FULL) Download all repodata files .. data:: RPMMD_REPOMDONLY (YUM_REPOMDONLY, LR_YUM_REPOMDONLY) Download only repomd.xml file .. data:: RPMMD_BASEXML (YUM_BASEXML, LR_YUM_BASEXML) Download only primary.xml, filelists.xml and other.xml .. data:: RPMMD_BASEDB (YUM_BASEDB, LR_YUM_BASEDB) Download only primary, filelists and other databases. .. data:: RPMMD_HAWKEY (YUM_HAWKEY, LR_YUM_HAWKEY) Download only files used by Hawkey (https://github.com/akozumpl/hawkey/). (primary, filelists, prestodelta) .. _auth-methods-label: Auth methods ------------ Supported auth methods for :data:`~.LRO_HTTPAUTHMETHODS` and :data:`~.LRO_PROXYAUTHMETHODS` options. .. data:: LR_AUTH_NONE No auth method enabled. .. data:: LR_AUTH_BASIC HTTP Basic authentication (Default). .. data:: LR_AUTH_DIGEST HTTP Digest authentication. .. data:: LR_AUTH_NEGOTIATE HTTP Negotiate (SPNEGO) authentication. .. data:: LR_AUTH_NTLM HTTP NTLM authentication. .. data:: LR_AUTH_DIGEST_IE HTTP Digest authentication with an IE flavor. .. data:: LR_AUTH_NTLM_WB NTLM delegating to winbind helper. .. data:: LR_AUTH_ONLY This is a meta symbol. OR this value together with a single specific auth value to force libcurl to probe for un-restricted auth and if not, only that single auth algorithm is acceptable. .. data:: LR_AUTH_ANY All suitable methods. .. _fastestmirror-stages-constants-label: Fastest mirror stages --------------------- Values used by fastest mirror callback (:data:`~.LRO_FASTESTMIRRORCB`): .. data:: FMSTAGE_INIT (0) Fastest mirror detection just started. *data* is None. .. data:: FMSTAGE_CACHELOADING (1) Cache file is specified. *data* is path to the cache file. .. data:: FMSTAGE_CACHELOADINGSTATUS (2) Cache loading finished. If successful, *data* is None, otherwise *data* is string with error message. .. data:: FMSTAGE_DETECTION (3) Detection in progress. *data* is number of mirrors that will be pinged. If all times were loaded from cache, this stage is skiped. .. data:: FMSTAGE_FINISHING (4) Detection is done, sorting mirrors, updating cache, etc. *data* is None. .. data:: FMSTAGE_STATUS (5) The very last invocation of fastest mirror callback. If fastest mirror detection was successful *data*, otherwise *data* contain string with error message. .. _error-codes-label: Error codes ----------- LibRepo Error codes. .. data:: LRE_OK (0) Everything is ok. .. data:: LRE_BADFUNCARG (1) Bad function argument(s). .. data:: LRE_BADOPTARG (2) Bad argument for the option in :meth:`~.Handle.setopt`. .. data:: LRE_UNKNOWNOPT (3) Unknown option. .. data:: LRE_CURLSETOPT (4) cURL doesn't know an option used by librepo. Probably too old cURL version is used. .. data:: LRE_ALREADYUSEDRESULT (5) :class:`.Result` object is not "clean" (it has been already used). .. data:: LRE_INCOMPLETERESULT (6) :class:`.Result` object doesn't contain all what is needed. .. data:: LRE_CURLDUP (7) Cannot duplicate cURL handle. No free memory? .. data:: LRE_CURL (8) A cURL error. .. data:: LRE_CURLM (9) A multi cURL handle error. .. data:: LRE_BADSTATUS (10) Error HTTP or FTP status code. .. data:: LRE_TEMPORARYERR (11) An error that should be temporary (e.g. HTTP status codes 500, 502-504, ..) .. data:: LRE_NOTLOCAL (12) URL is not a local address. E.g. in case when :data:`~.LRO_UPDATE` option is ``True`` and URL is a remote address. .. data:: LRE_CANNOTCREATEDIR (13) Cannot create directory for downloaded data. Bad permission? .. data:: LRE_IO (14) Input/Output error. .. data:: LRE_MLBAD (15) Bad mirrorlist or metalink file. E.g. metalink doesn't contain reference to target file (repomd.xml), mirrorlist is empty, .. .. data:: LRE_MLXML (16) Cannot parse metalink xml. Non-valid metalink file? E.g. (metalink doesn't contain needed file, mirrorlist doesn't contain urls, ..) .. data:: LRE_BADCHECKSUM (17) Bad checksum. .. data:: LRE_REPOMDXML (18) Cannot parse repomd.xml file. Non-valid repomd.xml file? .. data:: LRE_NOURL (19) No usable URL found. E.g. bad links or no links in metalink. .. data:: LRE_CANNOTCREATETMP (20) Cannot create temporary directory. .. data:: LRE_UNKNOWNCHECKSUM (21) Unknown type of checksum is needed for verification of one or more files. .. data:: LRE_BADURL (22) Bad URL specified. .. data:: LRE_GPGNOTSUPPORTED (23) OpenPGP protocol is not supported. .. data:: LRE_GPGERROR (24) GPG error. .. data:: LRE_BADGPG (25) Bad GPG signature. .. data:: LRE_INCOMPLETEREPO (26) Repository metadata are not complete. .. data:: LRE_INTERRUPTED (27) Download was interrupted by SIGTERM signal. .. data:: LRE_SIGACTION (28) Sigaction system call failed. .. data:: LRE_ALREADYDOWNLOADED (29) The file is already downloaded and its checksum matches. .. data:: LRE_UNFINISHED (30) Download wasn't (or cannot be) finished. .. data:: LRE_SELECT (31) select() call failed. .. data:: LRE_OPENSSL (32) OpenSSL library related error. .. data:: LRE_MEMORY (33) Cannot allocate more memory. .. data:: LRE_XMLPARSER (34) XML parser error. .. data:: LRE_CBINTERRUPTED (35) Interrupted by user cb. .. data:: LRE_UNKNOWNERROR An unknown error. .. _result-options-label: :class:`~.Result` options ------------------------- LibRepo Result options for use in :meth:`~.Result.getinfo` method. .. data:: LRR_YUM_REPO (deprecated - use LRR_RPMMD_REPO instead) Returns a flat dictionary with local paths to downloaded/localised rpmmd repository and basic repository's information.:: {'repomd': u'/tmp/librepotest-jPMmX5/repodata/repomd.xml', 'url': u'http://127.0.0.1:5000/yum/static/01/' 'destdir': u'/tmp/librepotest-jPMmX5', 'metalink': None, 'mirrorlist': None, 'signature': None, 'primary': u'/tmp/librepotest-jPMmX5/repodata/4543ad62e4d86337cd1949346f9aec976b847b58-primary.xml.gz', 'primary_db': u'/tmp/librepotest-jPMmX5/repodata/735cd6294df08bdf28e2ba113915ca05a151118e-primary.sqlite.bz2', 'filelists': u'/tmp/librepotest-jPMmX5/repodata/aeca08fccd3c1ab831e1df1a62711a44ba1922c9-filelists.xml.gz', 'filelists_db': u'/tmp/librepotest-jPMmX5/repodata/4034dcea76c94d3f7a9616779539a4ea8cac288f-filelists.sqlite.bz2', 'other': u'/tmp/librepotest-jPMmX5/repodata/a8977cdaa0b14321d9acfab81ce8a85e869eee32-other.xml.gz', 'other_db': u'/tmp/librepotest-jPMmX5/repodata/fd96942c919628895187778633001cff61e872b8-other.sqlite.bz2', } .. data:: LRR_RPMMD_REPO Returns a dict with local paths to downloaded/localised rpmmd repository and basic repository's information.:: {'repomd': u'/tmp/librepotest-jPMmX5/repodata/repomd.xml', 'url': u'http://127.0.0.1:5000/yum/static/01/' 'destdir': u'/tmp/librepotest-jPMmX5', 'metalink': None, 'mirrorlist': None, 'signature': None, 'paths': {'primary': u'/tmp/librepotest-jPMmX5/repodata/4543ad62e4d86337cd1949346f9aec976b847b58-primary.xml.gz', 'primary_db': u'/tmp/librepotest-jPMmX5/repodata/735cd6294df08bdf28e2ba113915ca05a151118e-primary.sqlite.bz2', 'filelists': u'/tmp/librepotest-jPMmX5/repodata/aeca08fccd3c1ab831e1df1a62711a44ba1922c9-filelists.xml.gz', 'filelists_db': u'/tmp/librepotest-jPMmX5/repodata/4034dcea76c94d3f7a9616779539a4ea8cac288f-filelists.sqlite.bz2', 'other': u'/tmp/librepotest-jPMmX5/repodata/a8977cdaa0b14321d9acfab81ce8a85e869eee32-other.xml.gz', 'other_db': u'/tmp/librepotest-jPMmX5/repodata/fd96942c919628895187778633001cff61e872b8-other.sqlite.bz2'} } .. data:: LRR_YUM_REPOMD (deprecated - use LRR_RPMMD_REPOMD instead) Returns a flat dict representing a repomd.xml file of downloaded rpmmd repository.:: {'revision': u'1347459931', 'repo_tags': [], 'content_tags': [], 'distro_tags': [], 'primary': {'checksum': u'4543ad62e4d86337cd1949346f9aec976b847b58', 'checksum_open': u'68457ceb8e20bda004d46e0a4dfa4a69ce71db48', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 0L, 'location_href': u'repodata/4543ad62e4d86337cd1949346f9aec976b847b58-primary.xml.gz', 'size': 936L, 'size_open': 3385L, 'timestamp': 1347459930L}, 'primary_db': {'checksum': u'735cd6294df08bdf28e2ba113915ca05a151118e', 'checksum_open': u'ba636386312e1b597fc4feb182d04c059b2a77d5', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 10L, 'location_href': u'repodata/735cd6294df08bdf28e2ba113915ca05a151118e-primary.sqlite.bz2', 'size': 2603L, 'size_open': 23552L, 'timestamp': 1347459931L}, 'filelists': {'checksum': u'aeca08fccd3c1ab831e1df1a62711a44ba1922c9', 'checksum_open': u'52d30ae3162ca863c63c345ffdb7f0e10c1414a5', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 0L, 'location_href': u'repodata/aeca08fccd3c1ab831e1df1a62711a44ba1922c9-filelists.xml.gz', 'size': 43310L, 'size_open': 735088L, 'timestamp': 1347459930L}, 'filelists_db': {'checksum': u'4034dcea76c94d3f7a9616779539a4ea8cac288f', 'checksum_open': u'949c6b7b605b2bc66852630c841a5003603ca5b2', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 10L, 'location_href': u'repodata/4034dcea76c94d3f7a9616779539a4ea8cac288f-filelists.sqlite.bz2', 'size': 22575L, 'size_open': 201728L, 'timestamp': 1347459931L}, 'other': {'checksum': u'a8977cdaa0b14321d9acfab81ce8a85e869eee32', 'checksum_open': u'4b5b8874fb233a626b03b3260a1aa08dce90e81a', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 0L, 'location_href': u'repodata/a8977cdaa0b14321d9acfab81ce8a85e869eee32-other.xml.gz', 'size': 807L, 'size_open': 1910L, 'timestamp': 1347459930L}, 'other_db': {'checksum': u'fd96942c919628895187778633001cff61e872b8', 'checksum_open': u'c5262f62b6b3360722b9b2fb5d0a9335d0a51112', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 10L, 'location_href': u'repodata/fd96942c919628895187778633001cff61e872b8-other.sqlite.bz2', 'size': 1407L, 'size_open': 8192L, 'timestamp': 1347459931L}, } .. data:: LRR_RPMMD_REPOMD Returns a dict representing a repomd.xml file of downloaded rpmmd repository.:: {'revision': u'1347459931', 'repo_tags': [], 'content_tags': [], 'distro_tags': [], 'records': {'primary': {'checksum': u'4543ad62e4d86337cd1949346f9aec976b847b58', 'checksum_open': u'68457ceb8e20bda004d46e0a4dfa4a69ce71db48', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 0L, 'location_href': u'repodata/4543ad62e4d86337cd1949346f9aec976b847b58-primary.xml.gz', 'size': 936L, 'size_open': 3385L, 'timestamp': 1347459930L}, 'primary_db': {'checksum': u'735cd6294df08bdf28e2ba113915ca05a151118e', 'checksum_open': u'ba636386312e1b597fc4feb182d04c059b2a77d5', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 10L, 'location_href': u'repodata/735cd6294df08bdf28e2ba113915ca05a151118e-primary.sqlite.bz2', 'size': 2603L, 'size_open': 23552L, 'timestamp': 1347459931L}}, 'filelists': {'checksum': u'aeca08fccd3c1ab831e1df1a62711a44ba1922c9', 'checksum_open': u'52d30ae3162ca863c63c345ffdb7f0e10c1414a5', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 0L, 'location_href': u'repodata/aeca08fccd3c1ab831e1df1a62711a44ba1922c9-filelists.xml.gz', 'size': 43310L, 'size_open': 735088L, 'timestamp': 1347459930L}, 'filelists_db': {'checksum': u'4034dcea76c94d3f7a9616779539a4ea8cac288f', 'checksum_open': u'949c6b7b605b2bc66852630c841a5003603ca5b2', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 10L, 'location_href': u'repodata/4034dcea76c94d3f7a9616779539a4ea8cac288f-filelists.sqlite.bz2', 'size': 22575L, 'size_open': 201728L, 'timestamp': 1347459931L}, 'other': {'checksum': u'a8977cdaa0b14321d9acfab81ce8a85e869eee32', 'checksum_open': u'4b5b8874fb233a626b03b3260a1aa08dce90e81a', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 0L, 'location_href': u'repodata/a8977cdaa0b14321d9acfab81ce8a85e869eee32-other.xml.gz', 'size': 807L, 'size_open': 1910L, 'timestamp': 1347459930L}, 'other_db': {'checksum': u'fd96942c919628895187778633001cff61e872b8', 'checksum_open': u'c5262f62b6b3360722b9b2fb5d0a9335d0a51112', 'checksum_open_type': u'sha1', 'checksum_type': u'sha1', 'db_version': 10L, 'location_href': u'repodata/fd96942c919628895187778633001cff61e872b8-other.sqlite.bz2', 'size': 1407L, 'size_open': 8192L, 'timestamp': 1347459931L}, } .. data:: LRR_RPMMD_TIMESTAMP (LRR_YUM_TIMESTAMP) Returns the highest timestamp from all records in the repomd. See: http://yum.baseurl.org/gitweb?p=yum.git;a=commitdiff;h=59d3d67f .. _endcb-statuses-label: Transfer statuses for endcb of :class:`~.PackageTarget` ------------------------------------------------------- .. data:: TRANSFER_SUCCESSFUL .. data:: TRANSFER_ALREADYEXISTS .. data:: TRANSFER_ERROR Callbacks prototypes -------------------- Some librepo's functions and classes can take a callbacks in their arguments. This section contain the callbacks prototypes and explanation of their arguments. By default all callbacks should return *None* (this is default behaviour of python function if it doesn't have a specified return statement - it returns None). But there are some callbacks that can return a specific values defined in :ref:`callbacks-return-values`. .. _callback-progresscb-label: Progress callback - progresscb ------------------------------ ``progresscb(userdata, totalsize, downloaded)`` Callback frequently called during a download. :userdata: User specified data or *None* :totalsize: Total size (in bytes) of the target (float). :downloaded: Currently downloaded size (in bytes). :returns: This callback can return values from :ref:`callbacks-return-values` .. _callback-endcb-label: End callback - endcb -------------------- ``endcb(userdata, status, msg)`` Callback called when a transfer is done either successfully or unsuccessfully. :userdata: User specified data or *None* :status: :ref:`endcb-statuses-label` :msg: String with error message or *None* :returns: This callback can return values from :ref:`callbacks-return-values` .. _callback-mirrorfailurecb-label: Mirror Failure Callback - mirrorfailurecb ----------------------------------------- ``mirrorfailurecb(userdata, msg, url)`` Callback called when a transfer failed. :userdata: User specified data or *None* :msg: String with error message :url: String with mirror URL :returns: This callback can return values from :ref:`callbacks-return-values` .. _callback-fastestmirrorcb-label: Fastestmirror callback - fastestmirrorcb ---------------------------------------- ``fastestmirrorcb(userdata, stage, data)`` :userdata: User specified data or *None* :stage: :ref:`fastestmirror-stages-constants-label` :data: Content of *data* is different for different stages. See :ref:`fastestmirror-stages-constants-label` :returns: This callback must return *None* each other value will be ignored. .. _callback-handlemirrorfailurecb-label: Handle Mirror Failure Callback - hmfcb -------------------------------------- ``hmfcb(userdata, msg, url, metadata)`` Callback called when a download of a metadata during :meth:`~.Handle.perform()` fails. :userdata: User specified data or *None* :msg: String with error message :url: String with mirror URL :metadata: String with metadata name ("primary", "filelists", ...) :returns: This callback can return values from :ref:`callbacks-return-values` .. _callbacks-return-values: Callbacks return values ----------------------- Each callback can safely return ``None`` (this is implicit return value when no return statement is defined). ``return None`` is equivalent for ``return librepo.CB_OK``. .. data:: CB_OK Everything is OK .. data:: CB_ABORT Abort just the current transfer. Note: If failfast option for the downloading is enabled, the whole downloading will be aborted. .. data:: CB_ERROR Abort the whole downloading (all transfers). (Note: This code is automatically internally returned when an exception is raised in the callback.) .. _checksum-constants-label: Checksum (hash) type constants ------------------------------ .. data:: MD5 (CHECKSUM_MD5) .. data:: SHA1 (CHECKSUM_SHA1) .. data:: SHA224 (CHECKSUM_SHA224) .. data:: SHA256 (CHECKSUM_SHA256) .. data:: SHA384 (CHECKSUM_SHA384) .. data:: SHA512 (CHECKSUM_SHA512) """ import sys import librepo._librepo current_module = sys.modules[__name__] LibrepoException = _librepo.LibrepoException ATTR_TO_LRO = {} ATTR_TO_LRI = {} ATTR_TO_LRR = {} _CHECKSUM_STR_TO_VAL_MAP = {} # Create local aliases for contants from _librepo C module for attr in dir(_librepo): if not attr.isupper(): # Only constants should be imported automatically continue # Create local alias val = getattr(_librepo, attr) setattr(current_module, attr, val) if attr.endswith("_SENTINEL"): # Ignore sentinel values continue if attr.startswith("LR_"): setattr(current_module, attr[3:], val) if attr.startswith("LRO_"): ATTR_TO_LRO[attr.lower()[4:]] = val if attr.startswith("LRI_"): ATTR_TO_LRI[attr.lower()[4:]] = val if attr.startswith("LRR_"): ATTR_TO_LRR[attr.lower()[4:]] = val if attr.startswith("LR_CHECKSUM_"): setattr(current_module, attr[12:], val) _CHECKSUM_STR_TO_VAL_MAP[attr[12:].lower()] = val RPMMD_FULL = YUM_FULL = LR_YUM_FULL = None RPMMD_REPOMDONLY= YUM_REPOMDONLY = LR_YUM_REPOMDONLY = [None] RPMMD_BASEXML = YUM_BASEXML = LR_YUM_BASEXML = ["primary", "filelists", "other", None] RPMMD_BASEDB = YUM_BASEDB = LR_YUM_BASEDB = ["primary_db", "filelists_db", "other_db", None] RPMMD_HAWKEY = YUM_HAWKEY = LR_YUM_HAWKEY = ["primary", "filelists", "prestodelta", None] def checksum_str_to_type(name): """ Convert string with name of hash function to numeric value that represents the hash in createrepo_c. :param name: Checksum name (e.g. "sha256", "sha512", ...) :returns: Integer value (from :ref:`checksum-constants-label`) """ name = name.lower() return _CHECKSUM_STR_TO_VAL_MAP.get(name, CHECKSUM_UNKNOWN) class MetadataTarget(_librepo.MetadataTarget): def __init__(self, handle=None, cbdata=None, progresscb=None, mirrorfailurecb=None, endcb=None, gnupghomedir=None): _librepo.MetadataTarget.__init__(self, handle, cbdata, progresscb, mirrorfailurecb, endcb, gnupghomedir) class PackageTarget(_librepo.PackageTarget): """ Represent a single package that will be downloaded by :func:`~librepo.download_packages`. """ def __init__(self, relative_url, dest=None, checksum_type=CHECKSUM_UNKNOWN, checksum=None, expectedsize=0, base_url=None, resume=False, progresscb=None, cbdata=None, handle=None, endcb=None, mirrorfailurecb=None, byterangestart=0, byterangeend=0): """ :param relative_url: Target URL. If *handle* or *base_url* specified, the *url* can be (and logically should be) only a relative part of path. :param dest: Destination filename or directory (file basename will be derived from the relative_url). If *None* current working directory will be used. :param checksum_type: :ref:`checksum-constants-label` :param checksum: Expected checksum value. :param expectedsize: Expected size of the target. If server reports different size, then download won't be performed. :param base_url: Base part of URL :param resume: If True then downloader will try to resume download if the destination file already exists. If the file doesn't exist yet, it will be downloaded. :param progresscb: :ref:`callback-progresscb-label` :param cbdata: User data for the callback. :param handle: :class:`~librepo.Handle` :param endcb: :ref:`callback-endcb-label` :param mirrorfailurecb: See :ref:`callback-mirrorfailurecb-label` :param byterangestart: Start downloading from the specified byte. :param byterangeend: Stop downloading at the specified byte. *Note: If the byterangeend is less or equal to byterangestart, then it is ignored!* """ _librepo.PackageTarget.__init__(self, handle, relative_url, dest, checksum_type, checksum, expectedsize, base_url, resume, progresscb, cbdata, endcb, mirrorfailurecb, byterangestart, byterangeend) class Handle(_librepo.Handle): """Librepo handle class. Handle hold information about a repository and configuration for downloading from the repository. **Attributes:** .. attribute:: update: See: :data:`.LRO_UPDATE` .. attribute:: urls: See: :data:`.LRO_URLS` .. attribute:: mirrorlist: See: :data:`.LRO_MIRRORLIST` .. attribute:: mirrorlisturl: See: :data:`.LRO_MIRRORLISTURL` .. attribute:: metalinkurl: See: :data:`.LRO_METALINKURL` .. attribute:: local: See: :data:`.LRO_LOCAL` .. attribute:: httpauth: See: :data:`.LRO_HTTPAUTH` .. attribute:: userpwd: See: :data:`.LRO_USERPWD` .. attribute:: proxy: See: :data:`.LRO_PROXY` .. attribute:: proxyport: See: :data:`.LRO_PROXYPORT` .. attribute:: proxytype: See: :data:`.LRO_PROXYTYPE` .. attribute:: proxyauth: See: :data:`.LRO_PROXYAUTH` .. attribute:: proxyuserpwd: See: :data:`.LRO_PROXYUSERPWD` .. attribute:: progresscb: See: :data:`.LRO_PROGRESSCB` .. attribute:: progressdata: See: :data:`.LRO_PROGRESSDATA` .. attribute:: maxspeed: See: :data:`.LRO_MAXSPEED` .. attribute:: destdir: See: :data:`.LRO_DESTDIR` .. attribute:: repotype: See: :data:`.LRO_REPOTYPE` .. attribute:: connecttimeout: See: :data:`.LRO_CONNECTTIMEOUT` .. attribute:: ignoremissing: See: :data:`.LRO_IGNOREMISSING` .. attribute:: interruptible: See: :data:`.LRO_INTERRUPTIBLE` .. attribute:: useragent: See: :data:`.LRO_USERAGENT` .. attribute:: fetchmirrors: See: :data:`.LRO_FETCHMIRRORS` .. attribute:: maxmirrortries: See: :data:`.LRO_MAXMIRRORTRIES` .. attribute:: maxparalleldownloads: See: :data:`.LRO_MAXPARALLELDOWNLOADS` .. attribute:: maxdownloadspermirror: See: :data:`.LRO_MAXDOWNLOADSPERMIRROR` .. attribute:: varsub: See: :data:`.LRO_VARSUB` .. attribute:: fastestmirror: See: :data:`.LRO_FASTESTMIRROR` .. attribute:: fastestmirrorcache: See: :data:`.LRO_FASTESTMIRRORCACHE` .. attribute:: fastestmirrormaxage: See: :data:`.LRO_FASTESTMIRRORMAXAGE` .. attribute:: fastestmirrorcb: See: :data:`.LRO_FASTESTMIRRORCB` .. attribute:: fastestmirrordata: See: :data:`.LRO_FASTESTMIRRORDATA` .. attribute:: lowspeedtime: See: :data:`.LRO_LOWSPEEDTIME` .. attribute:: lowspeedlimit: See: :data:`.LRO_LOWSPEEDLIMIT` .. attribute:: gpgcheck: See: :data:`.LRO_GPGCHECK` .. attribute:: checksum: See: :data:`.LRO_CHECKSUM` .. attribute:: rpmmddlist: See: :data:`.LRO_RPMMDDLIST` .. attribute:: yumdlist: See: :data:`.LRO_YUMDLIST` .. attribute:: yumslist: See: :data:`.LRO_YUMSLIST` .. attribute:: rpmmdblist: See: :data:`.LRO_RPMMDBLIST` .. attribute:: yumblist: See: :data:`.LRO_YUMBLIST` .. attribute:: hmfcb: See: :data:`.LRO_HMFCB` .. attribute:: sslverifypeer: See :data:`.LRO_SSLVERIFYPEER` .. attribute:: sslverifystatus: See :data:`.LRO_SSLVERIFYSTATUS` .. attribute:: sslverifyhost: See :data:`.LRO_SSLVERIFYHOST` .. attribute:: sslclientcert: See :data:`.LRO_SSLCLIENTCERT` .. attribute:: sslclientkey: See :data:`.LRO_SSLCLIENTKEY` .. attribute:: sslcacert: See :data:`.LRO_SSLCACERT` .. attribute:: proxy_sslverifypeer: See :data:`.LRO_PROXY_SSLVERIFYPEER` .. attribute:: proxy_sslverifyhost: See :data:`.LRO_PROXY_SSLVERIFYHOST` .. attribute:: proxy_sslclientcert: See :data:`.LRO_PROXY_SSLCLIENTCERT` .. attribute:: proxy_sslclientkey: See :data:`.LRO_PROXY_SSLCLIENTKEY` .. attribute:: proxy_sslcacert: See :data:`.LRO_PROXY_SSLCACERT` .. attribute:: ipresolve: See :data:`.LRO_IPRESOLVE` .. attribute:: allowedmirrorfailures: See :data:`.LRO_ALLOWEDMIRRORFAILURES` .. attribute:: adaptivemirrorsorting: See :data:`.LRO_ADAPTIVEMIRRORSORTING` .. attribute:: gnupghomedir: See :data:`.LRO_GNUPGHOMEDIR` .. attribute:: fastestmirrortimeout: See :data:`.LRO_FASTESTMIRRORTIMEOUT` .. attribute:: httpheader: See :data:`.LRO_HTTPHEADER` .. attribute:: offline: See :data:`.LRO_OFFLINE` .. attribute:: httpauthmethods See :data:`.LRO_HTTPAUTHMETHODS` .. attribute:: proxyauthmethods See :data:`.LRO_PROXYAUTHMETHODS` .. attribute:: ftpuseepsv See :data:`.LRO_FTPUSEEPSV` .. attribute:: preservetime See :data:`.LRO_PRESERVETIME` """ def setopt(self, option, val): """Set option to :class:`.Handle` directly. :param option: One of: :ref:`handle-options-label` :returns: *None* Example:: # The command: h.setopt(librepo.LRO_URLS, ["http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/17/Everything/i386/os/"]) # is equivalent to: h.urls(["http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/17/Everything/i386/os/"]) """ if (option == LRO_URLS and (not isinstance(val, list) and val is not None)): import warnings warnings.warn("Using string value for LRO_URLS is deprecated, " \ "use list of strings instead", DeprecationWarning) val = [val] _librepo.Handle.setopt(self, option, val) def __setattr__(self, attr, val): if attr not in ATTR_TO_LRO and attr in ATTR_TO_LRI: raise AttributeError("Set of attribute '%s' is not supported" % attr) elif attr not in ATTR_TO_LRO: raise AttributeError("'%s' object has no attribute '%s'" % \ (self.__class__.__name__, attr)) self.setopt(ATTR_TO_LRO[attr], val) def __getattr__(self, attr): if attr not in ATTR_TO_LRI and attr in ATTR_TO_LRO: raise AttributeError("Read of attribute '%s' is not supported" % attr) elif attr not in ATTR_TO_LRI: raise AttributeError("'%s' object has no attribute '%s'" % \ (self.__class__.__name__, attr)) return _librepo.Handle.getinfo(self, ATTR_TO_LRI[attr]) def getinfo(self, option): """Get information from :class:`.Handle`. :param option: One of :ref:`handle-info-options-label` :returns: Value for the specified option or *None* if the option is not set. """ return _librepo.Handle.getinfo(self, option) def download(self, url, dest=None, checksum_type=CHECKSUM_UNKNOWN, checksum=None, expectedsize=0, base_url=None, resume=0): """ **This method is deprecated** - Use :func:`~librepo.download_packages` instead. Download package from the repository specified in the :Class:`~librepo.Handle`. If *base_url* is specified, urls and mirrors specified in the Handle are ignored. Note: If resume is True and checksum_type and checksum are specified and downloaded package already exists, then checksum of the existing package is checked. If checksum matches, then no downloading is done and exception with LRE_ALREADYDOWNLOADED return code is raised. :param url: Relative path to the package in the repository. :param dest: Destination for package. Could be absolute/relative path to directory or filename. :param checksum_type: :ref:`checksum-constants-label`. :param checksum: Checksum value. :param expectedsize: Expected size of the file. If server reports different size, then no download is preformed. :param base_url: Instead of repositories specified in ``Handle`` use repository on this url. :param resume: ``True`` enables resume. Resume means that if local destination file exists, just try to resume download, if not or resume download failed than download whole file again. Example:: h = librepo.Handle() h.setopt(librepo.LRO_URLS, ["http://ftp.linux.ncsu.edu/pub/fedora/linux/releases/17/Everything/i386/os/"]) h.setopt(librepo.LRO_REPOTYPE, librepo.LR_YUMREPO) h.download("Packages/s/sl-3.03-12.fc17.i686.rpm", checksum="0ec8535d0fc00b497d8aef491c3f8b3955f2d84846325ee44851d9de8a36d12c", checksum_type=librepo.CHECKSUM_SHA256) .. note:: If checksum check is disabled in the current ``Handle``, then checksum is NOT checked even if *checksum* and *checksum_type* params are specified! """ if isinstance(checksum_type, str): checksum_type = checksum_str_to_type(checksum_type) self.download_package(url, dest, checksum_type, checksum, expectedsize, base_url, resume) def perform(self, result=None): """ Perform the specified action - download/locate a repository. :param result: :Class:`~librepo.Result` object or *None* :returns: :Class:`~librepo.Result` object that was passed by *result* parameter or the new one if the parameter was not specified or was *None*. """ if result is None: result = Result() _librepo.Handle.perform(self, result) return result def new_packagetarget(self, relative_url, **kwargs): """ Shortcut for creating a new :Class:`~librepo.PackageTarget` objects. Targets created by this way have automatically setted handle to the current :Class:`~librepo.Handle` object. :param relative_url: Relative par of target (package) URL :returns: New :Class:`~librepo.PackageTarget` """ return PackageTarget(relative_url, handle=self, **kwargs) class Result(_librepo.Result): """Librepo result class This class holds information about a downloaded/localised repository. **Attributes:** .. attribute:: rpmmd_repo See: :data:`.LRR_RPMMD_REPO` .. attribute:: yum_repo See: :data:`.LRR_YUM_REPO` .. attribute:: rpmmd_repomd See: :data:`.LRR_RPMMD_REPOMD` .. attribute:: yum_repomd See: :data:`.LRR_YUM_REPOMD` .. attribute:: rpmmd_timestamp See: :data:`.LRR_RPMMD_TIMESTAMP` .. attribute:: yum_timestamp See: :data:`.LRR_YUM_TIMESTAMP` """ def getinfo(self, option): """Returns information about a downloaded/localised repository. *option* could be one of: :ref:`result-options-label` """ return _librepo.Result.getinfo(self, option) def __getattr__(self, attr): if attr not in ATTR_TO_LRR: raise AttributeError("'%s' object has no attribute '%s'" % \ (self.__class__.__name__, attr)) return self.getinfo(ATTR_TO_LRR[attr]) # Functions def download_metadata(list): """ Download metadata. *list* is a list of :class:`~librepo.MetadataTarget` objects. Exception is raised only if a nonrecoverable error related to the function itself is meet (Errors related to individual downloads are reported via corresponding MetadataTarget objects) :param list: List of :class:`~.librepo.MetadataTarget` objects. :returns: *None* """ return _librepo.download_metadata(list) def download_packages(list, failfast=False): """ Download list of packages. *list* is a list of :class:`~librepo.PackageTarget` objects. If the *failfast* is True, then whole downloading is stopped immediately when any of download fails (and exception is raised). If the failfast is False, then this function returns after all downloads finish (no matter if successfully or unsuccessfully) and exception is raised only if a nonrecoverable error related to the function itself is meet (Errors related to individual downloads are reported via corresponding PackageTarget objects) :param list: List of :class:`~.librepo.PackageTarget` objects. :param failfast: If *True*, stop whole downloading immediately when any of downloads fails. If *False*, ignore failed download(s) and continue with other downloads. :returns: *None* """ return _librepo.download_packages(list, failfast) def download_url(url, fd, handle=None): """ Download specified URL and write it content to opened file descriptor. :param url: Target URL :param fd: Opened file descriptor (To get a file descriptor use for example **os.open()**. :param handle: :Class:`~librepo.Handle` object or *None* :returns: *None* """ return _librepo.download_url(handle, url, fd) def yum_repomd_get_age(result_object): """ Get the highest timestamp of the repo's repomd.xml. :param result_object: Used (filled) :Class:`~librepo.Result` :returns: The highest timestamp from repomd (Float) or *0.0* on error. """ return _librepo.yum_repomd_get_age(result_object) def set_debug_log_handler(log_function, user_data=None): """ ONLY FOR DEVELOPMENT (DEBUGGING) PURPOSES! (Deprecated, use :func:`~log_set_file` instead) When python debug log handler is used, the librepo is **THREAD-UNSAFE**! If used, it overrides logging set by :func:`~log_set_file` and vice versa. :param log_function: Function that will handle the debug messages. :param user_data: An data you want to be passed to the log_function during call. :returns: *None* Example:: def debug_function(msg, _): print(msg) librepo.set_debug_log_handler(debug_function) """ return _librepo.set_debug_log_handler(log_function, user_data) def log_set_file(filename): """Set a filename of a file where logs are going to be written. Note: Only one file could be set at a time. Note: If the LIBREPO_DEBUG environ variable is set and this function is used then the LIBREPO_DEBUG effect will be suppressed. (All debug output will be redirected to the specified file) :param filename: Filename :returns: Id of the handler """ return _librepo.log_set_file(filename) def log_remove_handler(handler_id): """Remove handler. :param handler_id: id """ return _librepo.log_remove_handler(handler_id) usr/lib64/python2.7/xml/etree/__init__.py000064400000003104152345705450014072 0ustar00# $Id: __init__.py 3375 2008-02-13 08:05:08Z fredrik $ # elementtree package # -------------------------------------------------------------------- # The ElementTree toolkit is # # Copyright (c) 1999-2008 by Fredrik Lundh # # By obtaining, using, and/or copying this software and/or its # associated documentation, you agree that you have read, understood, # and will comply with the following terms and conditions: # # Permission to use, copy, modify, and distribute this software and # its associated documentation for any purpose and without fee is # hereby granted, provided that the above copyright notice appears in # all copies, and that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of # Secret Labs AB or the author not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # OF THIS SOFTWARE. # -------------------------------------------------------------------- # Licensed to PSF under a Contributor Agreement. # See http://www.python.org/psf/license for licensing details. lib64/python3.6/distutils/__init__.py000064400000000354152345722230013400 0ustar00"""distutils The main package for the Python Module Distribution Utilities. Normally used from a setup script as from distutils.core import setup setup (...) """ import sys __version__ = sys.version[:sys.version.index(' ')] lib64/python3.12/zoneinfo/__init__.py000064400000001277152345724350013272 0ustar00__all__ = [ "ZoneInfo", "reset_tzpath", "available_timezones", "TZPATH", "ZoneInfoNotFoundError", "InvalidTZPathWarning", ] from . import _tzpath from ._common import ZoneInfoNotFoundError try: from _zoneinfo import ZoneInfo except ImportError: # pragma: nocover from ._zoneinfo import ZoneInfo reset_tzpath = _tzpath.reset_tzpath available_timezones = _tzpath.available_timezones InvalidTZPathWarning = _tzpath.InvalidTZPathWarning def __getattr__(name): if name == "TZPATH": return _tzpath.TZPATH else: raise AttributeError(f"module {__name__!r} has no attribute {name!r}") def __dir__(): return sorted(list(globals()) + ["TZPATH"]) usr/lib64/python3.6/urllib/__init__.py000064400000000000152345727310013446 0ustar00lib64/python3.12/collections/__init__.py000064400000146232152345731560013763 0ustar00'''This module implements specialized container datatypes providing alternatives to Python's general purpose built-in containers, dict, list, set, and tuple. * namedtuple factory function for creating tuple subclasses with named fields * deque list-like container with fast appends and pops on either end * ChainMap dict-like class for creating a single view of multiple mappings * Counter dict subclass for counting hashable objects * OrderedDict dict subclass that remembers the order entries were added * defaultdict dict subclass that calls a factory function to supply missing values * UserDict wrapper around dictionary objects for easier dict subclassing * UserList wrapper around list objects for easier list subclassing * UserString wrapper around string objects for easier string subclassing ''' __all__ = [ 'ChainMap', 'Counter', 'OrderedDict', 'UserDict', 'UserList', 'UserString', 'defaultdict', 'deque', 'namedtuple', ] import _collections_abc import sys as _sys from itertools import chain as _chain from itertools import repeat as _repeat from itertools import starmap as _starmap from keyword import iskeyword as _iskeyword from operator import eq as _eq from operator import itemgetter as _itemgetter from reprlib import recursive_repr as _recursive_repr from _weakref import proxy as _proxy try: from _collections import deque except ImportError: pass else: _collections_abc.MutableSequence.register(deque) try: from _collections import _deque_iterator except ImportError: pass try: from _collections import defaultdict except ImportError: pass ################################################################################ ### OrderedDict ################################################################################ class _OrderedDictKeysView(_collections_abc.KeysView): def __reversed__(self): yield from reversed(self._mapping) class _OrderedDictItemsView(_collections_abc.ItemsView): def __reversed__(self): for key in reversed(self._mapping): yield (key, self._mapping[key]) class _OrderedDictValuesView(_collections_abc.ValuesView): def __reversed__(self): for key in reversed(self._mapping): yield self._mapping[key] class _Link(object): __slots__ = 'prev', 'next', 'key', '__weakref__' class OrderedDict(dict): 'Dictionary that remembers insertion order' # An inherited dict maps keys to values. # The inherited dict provides __getitem__, __len__, __contains__, and get. # The remaining methods are order-aware. # Big-O running times for all methods are the same as regular dictionaries. # The internal self.__map dict maps keys to links in a doubly linked list. # The circular doubly linked list starts and ends with a sentinel element. # The sentinel element never gets deleted (this simplifies the algorithm). # The sentinel is in self.__hardroot with a weakref proxy in self.__root. # The prev links are weakref proxies (to prevent circular references). # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. def __new__(cls, /, *args, **kwds): "Create the ordered dict object and set up the underlying structures." self = dict.__new__(cls) self.__hardroot = _Link() self.__root = root = _proxy(self.__hardroot) root.prev = root.next = root self.__map = {} return self def __init__(self, other=(), /, **kwds): '''Initialize an ordered dictionary. The signature is the same as regular dictionaries. Keyword argument order is preserved. ''' self.__update(other, **kwds) def __setitem__(self, key, value, dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: self.__map[key] = link = Link() root = self.__root last = root.prev link.prev, link.next, link.key = last, root, key last.next = link root.prev = proxy(link) dict_setitem(self, key, value) def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link = self.__map.pop(key) link_prev = link.prev link_next = link.next link_prev.next = link_next link_next.prev = link_prev link.prev = None link.next = None def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. root = self.__root curr = root.next while curr is not root: yield curr.key curr = curr.next def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. root = self.__root curr = root.prev while curr is not root: yield curr.key curr = curr.prev def clear(self): 'od.clear() -> None. Remove all items from od.' root = self.__root root.prev = root.next = root self.__map.clear() dict.clear(self) def popitem(self, last=True): '''Remove and return a (key, value) pair from the dictionary. Pairs are returned in LIFO order if last is true or FIFO order if false. ''' if not self: raise KeyError('dictionary is empty') root = self.__root if last: link = root.prev link_prev = link.prev link_prev.next = root root.prev = link_prev else: link = root.next link_next = link.next root.next = link_next link_next.prev = root key = link.key del self.__map[key] value = dict.pop(self, key) return key, value def move_to_end(self, key, last=True): '''Move an existing element to the end (or beginning if last is false). Raise KeyError if the element does not exist. ''' link = self.__map[key] link_prev = link.prev link_next = link.next soft_link = link_next.prev link_prev.next = link_next link_next.prev = link_prev root = self.__root if last: last = root.prev link.prev = last link.next = root root.prev = soft_link last.next = link else: first = root.next link.prev = root link.next = first first.prev = soft_link root.next = link def __sizeof__(self): sizeof = _sys.getsizeof n = len(self) + 1 # number of links including root size = sizeof(self.__dict__) # instance dictionary size += sizeof(self.__map) * 2 # internal dict and inherited dict size += sizeof(self.__hardroot) * n # link objects size += sizeof(self.__root) * n # proxy objects return size update = __update = _collections_abc.MutableMapping.update def keys(self): "D.keys() -> a set-like object providing a view on D's keys" return _OrderedDictKeysView(self) def items(self): "D.items() -> a set-like object providing a view on D's items" return _OrderedDictItemsView(self) def values(self): "D.values() -> an object providing a view on D's values" return _OrderedDictValuesView(self) __ne__ = _collections_abc.MutableMapping.__ne__ __marker = object() def pop(self, key, default=__marker): '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised. ''' marker = self.__marker result = dict.pop(self, key, marker) if result is not marker: # The same as in __delitem__(). link = self.__map.pop(key) link_prev = link.prev link_next = link.next link_prev.next = link_next link_next.prev = link_prev link.prev = None link.next = None return result if default is marker: raise KeyError(key) return default def setdefault(self, key, default=None): '''Insert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default. ''' if key in self: return self[key] self[key] = default return default @_recursive_repr() def __repr__(self): 'od.__repr__() <==> repr(od)' if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, dict(self.items())) def __reduce__(self): 'Return state information for pickling' state = self.__getstate__() if state: if isinstance(state, tuple): state, slots = state else: slots = {} state = state.copy() slots = slots.copy() for k in vars(OrderedDict()): state.pop(k, None) slots.pop(k, None) if slots: state = state, slots else: state = state or None return self.__class__, (), state, None, iter(self.items()) def copy(self): 'od.copy() -> a shallow copy of od' return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): '''Create a new ordered dictionary with keys from iterable and values set to value. ''' self = cls() for key in iterable: self[key] = value return self def __eq__(self, other): '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive while comparison to a regular mapping is order-insensitive. ''' if isinstance(other, OrderedDict): return dict.__eq__(self, other) and all(map(_eq, self, other)) return dict.__eq__(self, other) def __ior__(self, other): self.update(other) return self def __or__(self, other): if not isinstance(other, dict): return NotImplemented new = self.__class__(self) new.update(other) return new def __ror__(self, other): if not isinstance(other, dict): return NotImplemented new = self.__class__(other) new.update(self) return new try: from _collections import OrderedDict except ImportError: # Leave the pure Python version in place. pass ################################################################################ ### namedtuple ################################################################################ try: from _collections import _tuplegetter except ImportError: _tuplegetter = lambda index, doc: property(_itemgetter(index), doc=doc) def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None): """Returns a new subclass of tuple with named fields. >>> Point = namedtuple('Point', ['x', 'y']) >>> Point.__doc__ # docstring for the new class 'Point(x, y)' >>> p = Point(11, y=22) # instantiate with positional args or keywords >>> p[0] + p[1] # indexable like a plain tuple 33 >>> x, y = p # unpack like a regular tuple >>> x, y (11, 22) >>> p.x + p.y # fields also accessible by name 33 >>> d = p._asdict() # convert to a dictionary >>> d['x'] 11 >>> Point(**d) # convert from a dictionary Point(x=11, y=22) >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields Point(x=100, y=22) """ # Validate the field names. At the user's option, either generate an error # message or automatically replace the field name with a valid name. if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() field_names = list(map(str, field_names)) typename = _sys.intern(str(typename)) if rename: seen = set() for index, name in enumerate(field_names): if (not name.isidentifier() or _iskeyword(name) or name.startswith('_') or name in seen): field_names[index] = f'_{index}' seen.add(name) for name in [typename] + field_names: if type(name) is not str: raise TypeError('Type names and field names must be strings') if not name.isidentifier(): raise ValueError('Type names and field names must be valid ' f'identifiers: {name!r}') if _iskeyword(name): raise ValueError('Type names and field names cannot be a ' f'keyword: {name!r}') seen = set() for name in field_names: if name.startswith('_') and not rename: raise ValueError('Field names cannot start with an underscore: ' f'{name!r}') if name in seen: raise ValueError(f'Encountered duplicate field name: {name!r}') seen.add(name) field_defaults = {} if defaults is not None: defaults = tuple(defaults) if len(defaults) > len(field_names): raise TypeError('Got more default values than field names') field_defaults = dict(reversed(list(zip(reversed(field_names), reversed(defaults))))) # Variables used in the methods and docstrings field_names = tuple(map(_sys.intern, field_names)) num_fields = len(field_names) arg_list = ', '.join(field_names) if num_fields == 1: arg_list += ',' repr_fmt = '(' + ', '.join(f'{name}=%r' for name in field_names) + ')' tuple_new = tuple.__new__ _dict, _tuple, _len, _map, _zip = dict, tuple, len, map, zip # Create all the named tuple methods to be added to the class namespace namespace = { '_tuple_new': tuple_new, '__builtins__': {}, '__name__': f'namedtuple_{typename}', } code = f'lambda _cls, {arg_list}: _tuple_new(_cls, ({arg_list}))' __new__ = eval(code, namespace) __new__.__name__ = '__new__' __new__.__doc__ = f'Create new instance of {typename}({arg_list})' if defaults is not None: __new__.__defaults__ = defaults @classmethod def _make(cls, iterable): result = tuple_new(cls, iterable) if _len(result) != num_fields: raise TypeError(f'Expected {num_fields} arguments, got {len(result)}') return result _make.__func__.__doc__ = (f'Make a new {typename} object from a sequence ' 'or iterable') def _replace(self, /, **kwds): result = self._make(_map(kwds.pop, field_names, self)) if kwds: raise ValueError(f'Got unexpected field names: {list(kwds)!r}') return result _replace.__doc__ = (f'Return a new {typename} object replacing specified ' 'fields with new values') def __repr__(self): 'Return a nicely formatted representation string' return self.__class__.__name__ + repr_fmt % self def _asdict(self): 'Return a new dict which maps field names to their values.' return _dict(_zip(self._fields, self)) def __getnewargs__(self): 'Return self as a plain tuple. Used by copy and pickle.' return _tuple(self) # Modify function metadata to help with introspection and debugging for method in ( __new__, _make.__func__, _replace, __repr__, _asdict, __getnewargs__, ): method.__qualname__ = f'{typename}.{method.__name__}' # Build-up the class namespace dictionary # and use type() to build the result class class_namespace = { '__doc__': f'{typename}({arg_list})', '__slots__': (), '_fields': field_names, '_field_defaults': field_defaults, '__new__': __new__, '_make': _make, '_replace': _replace, '__repr__': __repr__, '_asdict': _asdict, '__getnewargs__': __getnewargs__, '__match_args__': field_names, } for index, name in enumerate(field_names): doc = _sys.intern(f'Alias for field number {index}') class_namespace[name] = _tuplegetter(index, doc) result = type(typename, (tuple,), class_namespace) # For pickling to work, the __module__ variable needs to be set to the frame # where the named tuple is created. Bypass this step in environments where # sys._getframe is not defined (Jython for example) or sys._getframe is not # defined for arguments greater than 0 (IronPython), or where the user has # specified a particular module. if module is None: try: module = _sys._getframemodulename(1) or '__main__' except AttributeError: try: module = _sys._getframe(1).f_globals.get('__name__', '__main__') except (AttributeError, ValueError): pass if module is not None: result.__module__ = module return result ######################################################################## ### Counter ######################################################################## def _count_elements(mapping, iterable): 'Tally elements from the iterable.' mapping_get = mapping.get for elem in iterable: mapping[elem] = mapping_get(elem, 0) + 1 try: # Load C helper function if available from _collections import _count_elements except ImportError: pass class Counter(dict): '''Dict subclass for counting hashable items. Sometimes called a bag or multiset. Elements are stored as dictionary keys and their counts are stored as dictionary values. >>> c = Counter('abcdeabcdabcaba') # count elements from a string >>> c.most_common(3) # three most common elements [('a', 5), ('b', 4), ('c', 3)] >>> sorted(c) # list all unique elements ['a', 'b', 'c', 'd', 'e'] >>> ''.join(sorted(c.elements())) # list elements with repetitions 'aaaaabbbbcccdde' >>> sum(c.values()) # total of all counts 15 >>> c['a'] # count of letter 'a' 5 >>> for elem in 'shazam': # update counts from an iterable ... c[elem] += 1 # by adding 1 to each element's count >>> c['a'] # now there are seven 'a' 7 >>> del c['b'] # remove all 'b' >>> c['b'] # now there are zero 'b' 0 >>> d = Counter('simsalabim') # make another counter >>> c.update(d) # add in the second counter >>> c['a'] # now there are nine 'a' 9 >>> c.clear() # empty the counter >>> c Counter() Note: If a count is set to zero or reduced to zero, it will remain in the counter until the entry is deleted or the counter is cleared: >>> c = Counter('aaabbc') >>> c['b'] -= 2 # reduce the count of 'b' by two >>> c.most_common() # 'b' is still in, but its count is zero [('a', 3), ('c', 1), ('b', 0)] ''' # References: # http://en.wikipedia.org/wiki/Multiset # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html # http://www.java2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm # http://code.activestate.com/recipes/259174/ # Knuth, TAOCP Vol. II section 4.6.3 def __init__(self, iterable=None, /, **kwds): '''Create a new, empty Counter object. And if given, count elements from an input iterable. Or, initialize the count from another mapping of elements to their counts. >>> c = Counter() # a new, empty counter >>> c = Counter('gallahad') # a new counter from an iterable >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping >>> c = Counter(a=4, b=2) # a new counter from keyword args ''' super().__init__() self.update(iterable, **kwds) def __missing__(self, key): 'The count of elements not in the Counter is zero.' # Needed so that self[missing_item] does not raise KeyError return 0 def total(self): 'Sum of the counts' return sum(self.values()) def most_common(self, n=None): '''List the n most common elements and their counts from the most common to the least. If n is None, then list all element counts. >>> Counter('abracadabra').most_common(3) [('a', 5), ('b', 2), ('r', 2)] ''' # Emulate Bag.sortedByCount from Smalltalk if n is None: return sorted(self.items(), key=_itemgetter(1), reverse=True) # Lazy import to speedup Python startup time import heapq return heapq.nlargest(n, self.items(), key=_itemgetter(1)) def elements(self): '''Iterator over elements repeating each as many times as its count. >>> c = Counter('ABCABC') >>> sorted(c.elements()) ['A', 'A', 'B', 'B', 'C', 'C'] Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1 >>> import math >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) >>> math.prod(prime_factors.elements()) 1836 Note, if an element's count has been set to zero or is a negative number, elements() will ignore it. ''' # Emulate Bag.do from Smalltalk and Multiset.begin from C++. return _chain.from_iterable(_starmap(_repeat, self.items())) # Override dict methods where necessary @classmethod def fromkeys(cls, iterable, v=None): # There is no equivalent method for counters because the semantics # would be ambiguous in cases such as Counter.fromkeys('aaabbc', v=2). # Initializing counters to zero values isn't necessary because zero # is already the default value for counter lookups. Initializing # to one is easily accomplished with Counter(set(iterable)). For # more exotic cases, create a dictionary first using a dictionary # comprehension or dict.fromkeys(). raise NotImplementedError( 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') def update(self, iterable=None, /, **kwds): '''Like dict.update() but add counts instead of replacing them. Source can be an iterable, a dictionary, or another Counter instance. >>> c = Counter('which') >>> c.update('witch') # add elements from another iterable >>> d = Counter('watch') >>> c.update(d) # add elements from another counter >>> c['h'] # four 'h' in which, witch, and watch 4 ''' # The regular dict.update() operation makes no sense here because the # replace behavior results in some of the original untouched counts # being mixed-in with all of the other counts for a mismash that # doesn't have a straight-forward interpretation in most counting # contexts. Instead, we implement straight-addition. Both the inputs # and outputs are allowed to contain zero and negative counts. if iterable is not None: if isinstance(iterable, _collections_abc.Mapping): if self: self_get = self.get for elem, count in iterable.items(): self[elem] = count + self_get(elem, 0) else: # fast path when counter is empty super().update(iterable) else: _count_elements(self, iterable) if kwds: self.update(kwds) def subtract(self, iterable=None, /, **kwds): '''Like dict.update() but subtracts counts instead of replacing them. Counts can be reduced below zero. Both the inputs and outputs are allowed to contain zero and negative counts. Source can be an iterable, a dictionary, or another Counter instance. >>> c = Counter('which') >>> c.subtract('witch') # subtract elements from another iterable >>> c.subtract(Counter('watch')) # subtract elements from another counter >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch 0 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch -1 ''' if iterable is not None: self_get = self.get if isinstance(iterable, _collections_abc.Mapping): for elem, count in iterable.items(): self[elem] = self_get(elem, 0) - count else: for elem in iterable: self[elem] = self_get(elem, 0) - 1 if kwds: self.subtract(kwds) def copy(self): 'Return a shallow copy.' return self.__class__(self) def __reduce__(self): return self.__class__, (dict(self),) def __delitem__(self, elem): 'Like dict.__delitem__() but does not raise KeyError for missing values.' if elem in self: super().__delitem__(elem) def __repr__(self): if not self: return f'{self.__class__.__name__}()' try: # dict() preserves the ordering returned by most_common() d = dict(self.most_common()) except TypeError: # handle case where values are not orderable d = dict(self) return f'{self.__class__.__name__}({d!r})' # Multiset-style mathematical operations discussed in: # Knuth TAOCP Volume II section 4.6.3 exercise 19 # and at http://en.wikipedia.org/wiki/Multiset # # Outputs guaranteed to only include positive counts. # # To strip negative and zero counts, add-in an empty counter: # c += Counter() # # Results are ordered according to when an element is first # encountered in the left operand and then by the order # encountered in the right operand. # # When the multiplicities are all zero or one, multiset operations # are guaranteed to be equivalent to the corresponding operations # for regular sets. # Given counter multisets such as: # cp = Counter(a=1, b=0, c=1) # cq = Counter(c=1, d=0, e=1) # The corresponding regular sets would be: # sp = {'a', 'c'} # sq = {'c', 'e'} # All of the following relations would hold: # set(cp + cq) == sp | sq # set(cp - cq) == sp - sq # set(cp | cq) == sp | sq # set(cp & cq) == sp & sq # (cp == cq) == (sp == sq) # (cp != cq) == (sp != sq) # (cp <= cq) == (sp <= sq) # (cp < cq) == (sp < sq) # (cp >= cq) == (sp >= sq) # (cp > cq) == (sp > sq) def __eq__(self, other): 'True if all counts agree. Missing counts are treated as zero.' if not isinstance(other, Counter): return NotImplemented return all(self[e] == other[e] for c in (self, other) for e in c) def __ne__(self, other): 'True if any counts disagree. Missing counts are treated as zero.' if not isinstance(other, Counter): return NotImplemented return not self == other def __le__(self, other): 'True if all counts in self are a subset of those in other.' if not isinstance(other, Counter): return NotImplemented return all(self[e] <= other[e] for c in (self, other) for e in c) def __lt__(self, other): 'True if all counts in self are a proper subset of those in other.' if not isinstance(other, Counter): return NotImplemented return self <= other and self != other def __ge__(self, other): 'True if all counts in self are a superset of those in other.' if not isinstance(other, Counter): return NotImplemented return all(self[e] >= other[e] for c in (self, other) for e in c) def __gt__(self, other): 'True if all counts in self are a proper superset of those in other.' if not isinstance(other, Counter): return NotImplemented return self >= other and self != other def __add__(self, other): '''Add counts from two counters. >>> Counter('abbb') + Counter('bcc') Counter({'b': 4, 'c': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): newcount = count + other[elem] if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count > 0: result[elem] = count return result def __sub__(self, other): ''' Subtract count, but keep only results with positive counts. >>> Counter('abbbc') - Counter('bccd') Counter({'b': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): newcount = count - other[elem] if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count < 0: result[elem] = 0 - count return result def __or__(self, other): '''Union is the maximum of value in either of the input counters. >>> Counter('abbb') | Counter('bcc') Counter({'b': 3, 'c': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): other_count = other[elem] newcount = other_count if count < other_count else count if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count > 0: result[elem] = count return result def __and__(self, other): ''' Intersection is the minimum of corresponding counts. >>> Counter('abbb') & Counter('bcc') Counter({'b': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): other_count = other[elem] newcount = count if count < other_count else other_count if newcount > 0: result[elem] = newcount return result def __pos__(self): 'Adds an empty counter, effectively stripping negative and zero counts' result = Counter() for elem, count in self.items(): if count > 0: result[elem] = count return result def __neg__(self): '''Subtracts from an empty counter. Strips positive and zero counts, and flips the sign on negative counts. ''' result = Counter() for elem, count in self.items(): if count < 0: result[elem] = 0 - count return result def _keep_positive(self): '''Internal method to strip elements with a negative or zero count''' nonpositive = [elem for elem, count in self.items() if not count > 0] for elem in nonpositive: del self[elem] return self def __iadd__(self, other): '''Inplace add from another counter, keeping only positive counts. >>> c = Counter('abbb') >>> c += Counter('bcc') >>> c Counter({'b': 4, 'c': 2, 'a': 1}) ''' for elem, count in other.items(): self[elem] += count return self._keep_positive() def __isub__(self, other): '''Inplace subtract counter, but keep only results with positive counts. >>> c = Counter('abbbc') >>> c -= Counter('bccd') >>> c Counter({'b': 2, 'a': 1}) ''' for elem, count in other.items(): self[elem] -= count return self._keep_positive() def __ior__(self, other): '''Inplace union is the maximum of value from either counter. >>> c = Counter('abbb') >>> c |= Counter('bcc') >>> c Counter({'b': 3, 'c': 2, 'a': 1}) ''' for elem, other_count in other.items(): count = self[elem] if other_count > count: self[elem] = other_count return self._keep_positive() def __iand__(self, other): '''Inplace intersection is the minimum of corresponding counts. >>> c = Counter('abbb') >>> c &= Counter('bcc') >>> c Counter({'b': 1}) ''' for elem, count in self.items(): other_count = other[elem] if other_count < count: self[elem] = other_count return self._keep_positive() ######################################################################## ### ChainMap ######################################################################## class ChainMap(_collections_abc.MutableMapping): ''' A ChainMap groups multiple dicts (or other mappings) together to create a single, updateable view. The underlying mappings are stored in a list. That list is public and can be accessed or updated using the *maps* attribute. There is no other state. Lookups search the underlying mappings successively until a key is found. In contrast, writes, updates, and deletions only operate on the first mapping. ''' def __init__(self, *maps): '''Initialize a ChainMap by setting *maps* to the given mappings. If no mappings are provided, a single empty dictionary is used. ''' self.maps = list(maps) or [{}] # always at least one map def __missing__(self, key): raise KeyError(key) def __getitem__(self, key): for mapping in self.maps: try: return mapping[key] # can't use 'key in mapping' with defaultdict except KeyError: pass return self.__missing__(key) # support subclasses that define __missing__ def get(self, key, default=None): return self[key] if key in self else default def __len__(self): return len(set().union(*self.maps)) # reuses stored hash values if possible def __iter__(self): d = {} for mapping in map(dict.fromkeys, reversed(self.maps)): d |= mapping # reuses stored hash values if possible return iter(d) def __contains__(self, key): return any(key in m for m in self.maps) def __bool__(self): return any(self.maps) @_recursive_repr() def __repr__(self): return f'{self.__class__.__name__}({", ".join(map(repr, self.maps))})' @classmethod def fromkeys(cls, iterable, *args): 'Create a ChainMap with a single dict created from the iterable.' return cls(dict.fromkeys(iterable, *args)) def copy(self): 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' return self.__class__(self.maps[0].copy(), *self.maps[1:]) __copy__ = copy def new_child(self, m=None, **kwargs): # like Django's Context.push() '''New ChainMap with a new map followed by all previous maps. If no map is provided, an empty dict is used. Keyword arguments update the map or new empty dict. ''' if m is None: m = kwargs elif kwargs: m.update(kwargs) return self.__class__(m, *self.maps) @property def parents(self): # like Django's Context.pop() 'New ChainMap from maps[1:].' return self.__class__(*self.maps[1:]) def __setitem__(self, key, value): self.maps[0][key] = value def __delitem__(self, key): try: del self.maps[0][key] except KeyError: raise KeyError(f'Key not found in the first mapping: {key!r}') def popitem(self): 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' try: return self.maps[0].popitem() except KeyError: raise KeyError('No keys found in the first mapping.') def pop(self, key, *args): 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' try: return self.maps[0].pop(key, *args) except KeyError: raise KeyError(f'Key not found in the first mapping: {key!r}') def clear(self): 'Clear maps[0], leaving maps[1:] intact.' self.maps[0].clear() def __ior__(self, other): self.maps[0].update(other) return self def __or__(self, other): if not isinstance(other, _collections_abc.Mapping): return NotImplemented m = self.copy() m.maps[0].update(other) return m def __ror__(self, other): if not isinstance(other, _collections_abc.Mapping): return NotImplemented m = dict(other) for child in reversed(self.maps): m.update(child) return self.__class__(m) ################################################################################ ### UserDict ################################################################################ class UserDict(_collections_abc.MutableMapping): # Start by filling-out the abstract methods def __init__(self, dict=None, /, **kwargs): self.data = {} if dict is not None: self.update(dict) if kwargs: self.update(kwargs) def __len__(self): return len(self.data) def __getitem__(self, key): if key in self.data: return self.data[key] if hasattr(self.__class__, "__missing__"): return self.__class__.__missing__(self, key) raise KeyError(key) def __setitem__(self, key, item): self.data[key] = item def __delitem__(self, key): del self.data[key] def __iter__(self): return iter(self.data) # Modify __contains__ and get() to work like dict # does when __missing__ is present. def __contains__(self, key): return key in self.data def get(self, key, default=None): if key in self: return self[key] return default # Now, add the methods in dicts but not in MutableMapping def __repr__(self): return repr(self.data) def __or__(self, other): if isinstance(other, UserDict): return self.__class__(self.data | other.data) if isinstance(other, dict): return self.__class__(self.data | other) return NotImplemented def __ror__(self, other): if isinstance(other, UserDict): return self.__class__(other.data | self.data) if isinstance(other, dict): return self.__class__(other | self.data) return NotImplemented def __ior__(self, other): if isinstance(other, UserDict): self.data |= other.data else: self.data |= other return self def __copy__(self): inst = self.__class__.__new__(self.__class__) inst.__dict__.update(self.__dict__) # Create a copy and avoid triggering descriptors inst.__dict__["data"] = self.__dict__["data"].copy() return inst def copy(self): if self.__class__ is UserDict: return UserDict(self.data.copy()) import copy data = self.data try: self.data = {} c = copy.copy(self) finally: self.data = data c.update(self) return c @classmethod def fromkeys(cls, iterable, value=None): d = cls() for key in iterable: d[key] = value return d ################################################################################ ### UserList ################################################################################ class UserList(_collections_abc.MutableSequence): """A more or less complete user-defined wrapper around list objects.""" def __init__(self, initlist=None): self.data = [] if initlist is not None: # XXX should this accept an arbitrary sequence? if type(initlist) == type(self.data): self.data[:] = initlist elif isinstance(initlist, UserList): self.data[:] = initlist.data[:] else: self.data = list(initlist) def __repr__(self): return repr(self.data) def __lt__(self, other): return self.data < self.__cast(other) def __le__(self, other): return self.data <= self.__cast(other) def __eq__(self, other): return self.data == self.__cast(other) def __gt__(self, other): return self.data > self.__cast(other) def __ge__(self, other): return self.data >= self.__cast(other) def __cast(self, other): return other.data if isinstance(other, UserList) else other def __contains__(self, item): return item in self.data def __len__(self): return len(self.data) def __getitem__(self, i): if isinstance(i, slice): return self.__class__(self.data[i]) else: return self.data[i] def __setitem__(self, i, item): self.data[i] = item def __delitem__(self, i): del self.data[i] def __add__(self, other): if isinstance(other, UserList): return self.__class__(self.data + other.data) elif isinstance(other, type(self.data)): return self.__class__(self.data + other) return self.__class__(self.data + list(other)) def __radd__(self, other): if isinstance(other, UserList): return self.__class__(other.data + self.data) elif isinstance(other, type(self.data)): return self.__class__(other + self.data) return self.__class__(list(other) + self.data) def __iadd__(self, other): if isinstance(other, UserList): self.data += other.data elif isinstance(other, type(self.data)): self.data += other else: self.data += list(other) return self def __mul__(self, n): return self.__class__(self.data * n) __rmul__ = __mul__ def __imul__(self, n): self.data *= n return self def __copy__(self): inst = self.__class__.__new__(self.__class__) inst.__dict__.update(self.__dict__) # Create a copy and avoid triggering descriptors inst.__dict__["data"] = self.__dict__["data"][:] return inst def append(self, item): self.data.append(item) def insert(self, i, item): self.data.insert(i, item) def pop(self, i=-1): return self.data.pop(i) def remove(self, item): self.data.remove(item) def clear(self): self.data.clear() def copy(self): return self.__class__(self) def count(self, item): return self.data.count(item) def index(self, item, *args): return self.data.index(item, *args) def reverse(self): self.data.reverse() def sort(self, /, *args, **kwds): self.data.sort(*args, **kwds) def extend(self, other): if isinstance(other, UserList): self.data.extend(other.data) else: self.data.extend(other) ################################################################################ ### UserString ################################################################################ class UserString(_collections_abc.Sequence): def __init__(self, seq): if isinstance(seq, str): self.data = seq elif isinstance(seq, UserString): self.data = seq.data[:] else: self.data = str(seq) def __str__(self): return str(self.data) def __repr__(self): return repr(self.data) def __int__(self): return int(self.data) def __float__(self): return float(self.data) def __complex__(self): return complex(self.data) def __hash__(self): return hash(self.data) def __getnewargs__(self): return (self.data[:],) def __eq__(self, string): if isinstance(string, UserString): return self.data == string.data return self.data == string def __lt__(self, string): if isinstance(string, UserString): return self.data < string.data return self.data < string def __le__(self, string): if isinstance(string, UserString): return self.data <= string.data return self.data <= string def __gt__(self, string): if isinstance(string, UserString): return self.data > string.data return self.data > string def __ge__(self, string): if isinstance(string, UserString): return self.data >= string.data return self.data >= string def __contains__(self, char): if isinstance(char, UserString): char = char.data return char in self.data def __len__(self): return len(self.data) def __getitem__(self, index): return self.__class__(self.data[index]) def __add__(self, other): if isinstance(other, UserString): return self.__class__(self.data + other.data) elif isinstance(other, str): return self.__class__(self.data + other) return self.__class__(self.data + str(other)) def __radd__(self, other): if isinstance(other, str): return self.__class__(other + self.data) return self.__class__(str(other) + self.data) def __mul__(self, n): return self.__class__(self.data * n) __rmul__ = __mul__ def __mod__(self, args): return self.__class__(self.data % args) def __rmod__(self, template): return self.__class__(str(template) % self) # the following methods are defined in alphabetical order: def capitalize(self): return self.__class__(self.data.capitalize()) def casefold(self): return self.__class__(self.data.casefold()) def center(self, width, *args): return self.__class__(self.data.center(width, *args)) def count(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.count(sub, start, end) def removeprefix(self, prefix, /): if isinstance(prefix, UserString): prefix = prefix.data return self.__class__(self.data.removeprefix(prefix)) def removesuffix(self, suffix, /): if isinstance(suffix, UserString): suffix = suffix.data return self.__class__(self.data.removesuffix(suffix)) def encode(self, encoding='utf-8', errors='strict'): encoding = 'utf-8' if encoding is None else encoding errors = 'strict' if errors is None else errors return self.data.encode(encoding, errors) def endswith(self, suffix, start=0, end=_sys.maxsize): return self.data.endswith(suffix, start, end) def expandtabs(self, tabsize=8): return self.__class__(self.data.expandtabs(tabsize)) def find(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.find(sub, start, end) def format(self, /, *args, **kwds): return self.data.format(*args, **kwds) def format_map(self, mapping): return self.data.format_map(mapping) def index(self, sub, start=0, end=_sys.maxsize): return self.data.index(sub, start, end) def isalpha(self): return self.data.isalpha() def isalnum(self): return self.data.isalnum() def isascii(self): return self.data.isascii() def isdecimal(self): return self.data.isdecimal() def isdigit(self): return self.data.isdigit() def isidentifier(self): return self.data.isidentifier() def islower(self): return self.data.islower() def isnumeric(self): return self.data.isnumeric() def isprintable(self): return self.data.isprintable() def isspace(self): return self.data.isspace() def istitle(self): return self.data.istitle() def isupper(self): return self.data.isupper() def join(self, seq): return self.data.join(seq) def ljust(self, width, *args): return self.__class__(self.data.ljust(width, *args)) def lower(self): return self.__class__(self.data.lower()) def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars)) maketrans = str.maketrans def partition(self, sep): return self.data.partition(sep) def replace(self, old, new, maxsplit=-1): if isinstance(old, UserString): old = old.data if isinstance(new, UserString): new = new.data return self.__class__(self.data.replace(old, new, maxsplit)) def rfind(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.rfind(sub, start, end) def rindex(self, sub, start=0, end=_sys.maxsize): return self.data.rindex(sub, start, end) def rjust(self, width, *args): return self.__class__(self.data.rjust(width, *args)) def rpartition(self, sep): return self.data.rpartition(sep) def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars)) def split(self, sep=None, maxsplit=-1): return self.data.split(sep, maxsplit) def rsplit(self, sep=None, maxsplit=-1): return self.data.rsplit(sep, maxsplit) def splitlines(self, keepends=False): return self.data.splitlines(keepends) def startswith(self, prefix, start=0, end=_sys.maxsize): return self.data.startswith(prefix, start, end) def strip(self, chars=None): return self.__class__(self.data.strip(chars)) def swapcase(self): return self.__class__(self.data.swapcase()) def title(self): return self.__class__(self.data.title()) def translate(self, *args): return self.__class__(self.data.translate(*args)) def upper(self): return self.__class__(self.data.upper()) def zfill(self, width): return self.__class__(self.data.zfill(width)) lib64/python3.12/wsgiref/__init__.py000064400000001221152345744330013076 0ustar00"""wsgiref -- a WSGI (PEP 3333) Reference Library Current Contents: * util -- Miscellaneous useful functions and wrappers * headers -- Manage response headers * handlers -- base classes for server/gateway implementations * simple_server -- a simple BaseHTTPServer that supports WSGI * validate -- validation wrapper that sits between an app and a server to detect errors in either * types -- collection of WSGI-related types for static type checking To-Do: * cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard) * cgi_wrapper -- Run CGI apps under WSGI * router -- a simple middleware component that handles URL traversal """ lib64/python3.6/ensurepip/__init__.py000064400000015520152345747420013377 0ustar00import distutils.version import glob import os import os.path import sys import tempfile __all__ = ["version", "bootstrap"] _WHEEL_DIR = "/usr/share/python{}-wheels/".format(sys.version_info[0]) def _get_most_recent_wheel_version(pkg): prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) suffix = "-py2.py3-none-any.whl" pattern = "{}*{}".format(prefix, suffix) versions = (p[len(prefix):-len(suffix)] for p in glob.glob(pattern)) return str(max(versions, key=distutils.version.LooseVersion)) _SETUPTOOLS_VERSION = _get_most_recent_wheel_version("setuptools") _PIP_VERSION = _get_most_recent_wheel_version("pip") _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION), ("pip", _PIP_VERSION), ] def _run_pip(args, additional_paths=None): # Add our bundled software to the sys.path so we can import it if additional_paths is not None: sys.path = additional_paths + sys.path try: # pip 10 from pip._internal import main except ImportError: # pip 9 from pip import main if args[0] in ["install", "list", "wheel"]: args.append('--pre') return main(args) def version(): """ Returns a string specifying the bundled version of pip. """ return _PIP_VERSION def _disable_pip_configuration_settings(): # We deliberately ignore all pip environment variables # when invoking pip # See http://bugs.python.org/issue19734 for details keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] for k in keys_to_remove: del os.environ[k] # We also ignore the settings in the default pip configuration file # See http://bugs.python.org/issue20053 for details os.environ['PIP_CONFIG_FILE'] = os.devnull def bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Note that calling this function will alter both sys.path and os.environ. """ # Discard the return value _bootstrap(root=root, upgrade=upgrade, user=user, altinstall=altinstall, default_pip=default_pip, verbosity=verbosity) def _bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Returns pip command status code. Note that calling this function will alter both sys.path and os.environ. """ if altinstall and default_pip: raise ValueError("Cannot use altinstall and default_pip together") _disable_pip_configuration_settings() # By default, installing pip and setuptools installs all of the # following scripts (X.Y == running Python version): # # pip, pipX, pipX.Y, easy_install, easy_install-X.Y # # pip 1.5+ allows ensurepip to request that some of those be left out if altinstall: # omit pip, pipX and easy_install os.environ["ENSUREPIP_OPTIONS"] = "altinstall" elif not default_pip: # omit pip and easy_install os.environ["ENSUREPIP_OPTIONS"] = "install" with tempfile.TemporaryDirectory() as tmpdir: # Put our bundled wheels into a temporary directory and construct the # additional paths that need added to sys.path additional_paths = [] for project, version in _PROJECTS: wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version) with open(os.path.join(_WHEEL_DIR, wheel_name), "rb") as sfp: with open(os.path.join(tmpdir, wheel_name), "wb") as fp: fp.write(sfp.read()) additional_paths.append(os.path.join(tmpdir, wheel_name)) # Construct the arguments to be passed to the pip command args = ["install", "--no-index", "--find-links", tmpdir] if root: args += ["--root", root] if upgrade: args += ["--upgrade"] if user: args += ["--user"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) def _uninstall_helper(*, verbosity=0): """Helper to support a clean default uninstall process on Windows Note that calling this function may alter os.environ. """ # Nothing to do if pip was never installed, or has been removed try: import pip except ImportError: return # If the pip version doesn't match the bundled one, leave it alone if pip.__version__ != _PIP_VERSION: msg = ("ensurepip will only uninstall a matching version " "({!r} installed, {!r} bundled)") print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) return _disable_pip_configuration_settings() # Construct the arguments to be passed to the pip command args = ["uninstall", "-y", "--disable-pip-version-check"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) def _main(argv=None): import argparse parser = argparse.ArgumentParser(prog="python -m ensurepip") parser.add_argument( "--version", action="version", version="pip {}".format(version()), help="Show the version of pip that is bundled with this Python.", ) parser.add_argument( "-v", "--verbose", action="count", default=0, dest="verbosity", help=("Give more output. Option is additive, and can be used up to 3 " "times."), ) parser.add_argument( "-U", "--upgrade", action="store_true", default=False, help="Upgrade pip and dependencies, even if already installed.", ) parser.add_argument( "--user", action="store_true", default=False, help="Install using the user scheme.", ) parser.add_argument( "--root", default=None, help="Install everything relative to this alternate root directory.", ) parser.add_argument( "--altinstall", action="store_true", default=False, help=("Make an alternate install, installing only the X.Y versioned " "scripts (Default: pipX, pipX.Y, easy_install-X.Y)."), ) parser.add_argument( "--default-pip", action="store_true", default=False, help=("Make a default pip install, installing the unqualified pip " "and easy_install in addition to the versioned scripts."), ) args = parser.parse_args(argv) return _bootstrap( root=args.root, upgrade=args.upgrade, user=args.user, verbosity=args.verbosity, altinstall=args.altinstall, default_pip=args.default_pip, ) usr/lib64/python3.8/unittest/__init__.py000064400000006303152345754740014061 0ustar00""" Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's Smalltalk testing framework (used with permission). This module contains the core framework classes that form the basis of specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results (TextTestRunner). Simple usage: import unittest class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): # test method names begin with 'test' self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main() Further information is available in the bundled documentation, and from http://docs.python.org/library/unittest.html Copyright (c) 1999-2003 Steve Purcell Copyright (c) 2003-2010 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __all__ = ['TestResult', 'TestCase', 'IsolatedAsyncioTestCase', 'TestSuite', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', 'registerResult', 'removeResult', 'removeHandler', 'addModuleCleanup'] # Expose obsolete functions for backwards compatibility __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) __unittest = True from .result import TestResult from .async_case import IsolatedAsyncioTestCase from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip, skipIf, skipUnless, expectedFailure) from .suite import BaseTestSuite, TestSuite from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, findTestCases) from .main import TestProgram, main from .runner import TextTestRunner, TextTestResult from .signals import installHandler, registerResult, removeResult, removeHandler # deprecated _TextTestResult = TextTestResult # There are no tests here, so don't try to run anything discovered from # introspecting the symbols (e.g. FunctionTestCase). Instead, all our # tests come from within unittest.test. def load_tests(loader, tests, pattern): import os.path # top level directory cached on loader instance this_dir = os.path.dirname(__file__) return loader.discover(start_dir=this_dir, pattern=pattern) usr/lib64/python3.6/email/__init__.py000064400000003346152345756660013276 0ustar00# Copyright (C) 2001-2007 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org """A package for parsing, handling, and generating email messages.""" __all__ = [ 'base64mime', 'charset', 'encoders', 'errors', 'feedparser', 'generator', 'header', 'iterators', 'message', 'message_from_file', 'message_from_binary_file', 'message_from_string', 'message_from_bytes', 'mime', 'parser', 'quoprimime', 'utils', ] # Some convenience routines. Don't import Parser and Message as side-effects # of importing email since those cascadingly import most of the rest of the # email package. def message_from_string(s, *args, **kws): """Parse a string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parsestr(s) def message_from_bytes(s, *args, **kws): """Parse a bytes string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parsebytes(s) def message_from_file(fp, *args, **kws): """Read a file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parse(fp) def message_from_binary_file(fp, *args, **kws): """Read a binary file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parse(fp) lib64/python2.7/logging/__init__.py000064400000170342152345757470013025 0ustar00# Copyright 2001-2014 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation, and that the name of Vinay Sajip # not be used in advertising or publicity pertaining to distribution # of the software without specific, written prior permission. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import sys, os, time, cStringIO, traceback, warnings, weakref, collections __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning'] try: import codecs except ImportError: codecs = None try: import thread import threading except ImportError: thread = None __author__ = "Vinay Sajip " __status__ = "production" # Note: the attributes below are no longer maintained. __version__ = "0.5.1.2" __date__ = "07 February 2010" #--------------------------------------------------------------------------- # Miscellaneous module data #--------------------------------------------------------------------------- try: unicode _unicode = True except NameError: _unicode = False # next bit filched from 1.5.2's inspect.py def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise Exception except: return sys.exc_info()[2].tb_frame.f_back if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) # done filching # # _srcfile is used when walking the stack to check when we've got the first # caller stack frame. # _srcfile = os.path.normcase(currentframe.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). # To provide compatibility with older versions of Python, set _srcfile # to None if _getframe() is not available; this value will prevent # findCaller() from being called. #if not hasattr(sys, "_getframe"): # _srcfile = None # #_startTime is used as the base when calculating the relative time of events # _startTime = time.time() # #raiseExceptions is used to see if exceptions during handling should be #propagated # raiseExceptions = 1 # # If you don't want threading information in the log, set this to zero # logThreads = 1 # # If you don't want multiprocessing information in the log, set this to zero # logMultiprocessing = 1 # # If you don't want process information in the log, set this to zero # logProcesses = 1 #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- # # Default levels and level names, these can be replaced with any positive set # of values having corresponding names. There is a pseudo-level, NOTSET, which # is only really there as a lower limit for user-defined levels. Handlers and # loggers are initialized with NOTSET so that they will log all messages, even # at user-defined levels. # CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 _levelNames = { CRITICAL : 'CRITICAL', ERROR : 'ERROR', WARNING : 'WARNING', INFO : 'INFO', DEBUG : 'DEBUG', NOTSET : 'NOTSET', 'CRITICAL' : CRITICAL, 'ERROR' : ERROR, 'WARN' : WARNING, 'WARNING' : WARNING, 'INFO' : INFO, 'DEBUG' : DEBUG, 'NOTSET' : NOTSET, } def getLevelName(level): """ Return the textual representation of logging level 'level'. If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, INFO, DEBUG) then you get the corresponding string. If you have associated levels with names using addLevelName then the name you have associated with 'level' is returned. If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned. Otherwise, the string "Level %s" % level is returned. """ return _levelNames.get(level, ("Level %s" % level)) def addLevelName(level, levelName): """ Associate 'levelName' with 'level'. This is used when converting levels to text during message formatting. """ _acquireLock() try: #unlikely to cause an exception, but you never know... _levelNames[level] = levelName _levelNames[levelName] = level finally: _releaseLock() def _checkLevel(level): if isinstance(level, (int, long)): rv = level elif str(level) == level: if level not in _levelNames: raise ValueError("Unknown level: %r" % level) rv = _levelNames[level] else: raise TypeError("Level not an integer or a valid string: %r" % level) return rv #--------------------------------------------------------------------------- # Thread-related stuff #--------------------------------------------------------------------------- # #_lock is used to serialize access to shared data structures in this module. #This needs to be an RLock because fileConfig() creates and configures #Handlers, and so might arbitrary user threads. Since Handler code updates the #shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # if thread: _lock = threading.RLock() else: _lock = None def _acquireLock(): """ Acquire the module-level lock for serializing access to shared data. This should be released with _releaseLock(). """ if _lock: _lock.acquire() def _releaseLock(): """ Release the module-level lock acquired by calling _acquireLock(). """ if _lock: _lock.release() #--------------------------------------------------------------------------- # The logging record #--------------------------------------------------------------------------- class LogRecord(object): """ A LogRecord instance represents an event being logged. LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is in msg and args, which are combined using str(msg) % args to create the message field of the record. The record also includes information such as when the record was created, the source line where the logging call was made, and any exception information to be logged. """ def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None): """ Initialize a logging record with interesting information. """ ct = time.time() self.name = name self.msg = msg # # The following statement allows passing of a dictionary as a sole # argument, so that you can do something like # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) # Suggested by Stefan Behnel. # Note that without the test for args[0], we get a problem because # during formatting, we test to see if the arg is present using # 'if self.args:'. If the event being logged is e.g. 'Value is %d' # and if the passed arg fails 'if self.args:' then no formatting # is done. For example, logger.warn('Value is %d', 0) would log # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. # Issue #21172: a request was made to relax the isinstance check # to hasattr(args[0], '__getitem__'). However, the docs on string # formatting still seem to suggest a mapping object is required. # Thus, while not removing the isinstance check, it does now look # for collections.Mapping rather than, as before, dict. if (args and len(args) == 1 and isinstance(args[0], collections.Mapping) and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) self.levelno = level self.pathname = pathname try: self.filename = os.path.basename(pathname) self.module = os.path.splitext(self.filename)[0] except (TypeError, ValueError, AttributeError): self.filename = pathname self.module = "Unknown module" self.exc_info = exc_info self.exc_text = None # used to cache the traceback text self.lineno = lineno self.funcName = func self.created = ct self.msecs = (ct - long(ct)) * 1000 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads and thread: self.thread = thread.get_ident() self.threadName = threading.current_thread().name else: self.thread = None self.threadName = None if not logMultiprocessing: self.processName = None else: self.processName = 'MainProcess' mp = sys.modules.get('multiprocessing') if mp is not None: # Errors may occur if multiprocessing has not finished loading # yet - e.g. if a custom import hook causes third-party code # to run when multiprocessing calls import. See issue 8200 # for an example try: self.processName = mp.current_process().name except StandardError: pass if logProcesses and hasattr(os, 'getpid'): self.process = os.getpid() else: self.process = None def __str__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) def getMessage(self): """ Return the message for this LogRecord. Return the message for this LogRecord after merging any user-supplied arguments with the message. """ if not _unicode: #if no unicode support... msg = str(self.msg) else: msg = self.msg if not isinstance(msg, basestring): try: msg = str(self.msg) except UnicodeError: msg = self.msg #Defer encoding till later if self.args: msg = msg % self.args return msg def makeLogRecord(dict): """ Make a LogRecord whose attributes are defined by the specified dictionary, This function is useful for converting a logging event received over a socket connection (which is sent as a dictionary) into a LogRecord instance. """ rv = LogRecord(None, None, "", 0, "", (), None, None) rv.__dict__.update(dict) return rv #--------------------------------------------------------------------------- # Formatter classes and functions #--------------------------------------------------------------------------- class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. Formatters need to know how a LogRecord is constructed. They are responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the default value of "%s(message)\\n" is used. The Formatter can be initialized with a format string which makes use of knowledge of the LogRecord attributes - e.g. the default value mentioned above makes use of the fact that the user's message and arguments are pre- formatted into a LogRecord's message attribute. Currently, the useful attributes in a LogRecord are described by: %(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted """ converter = time.localtime def __init__(self, fmt=None, datefmt=None): """ Initialize the formatter with specified format strings. Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument (if omitted, you get the ISO8601 format). """ if fmt: self._fmt = fmt else: self._fmt = "%(message)s" self.datefmt = datefmt def formatTime(self, record, datefmt=None): """ Return the creation time of the specified LogRecord as formatted text. This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, the ISO8601 format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) if datefmt: s = time.strftime(datefmt, ct) else: t = time.strftime("%Y-%m-%d %H:%M:%S", ct) s = "%s,%03d" % (t, record.msecs) return s def formatException(self, ei): """ Format and return the specified exception information as a string. This default implementation just uses traceback.print_exception() """ sio = cStringIO.StringIO() traceback.print_exception(ei[0], ei[1], ei[2], None, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] return s def usesTime(self): """ Check if the format uses the creation time of the record. """ return self._fmt.find("%(asctime)") >= 0 def format(self, record): """ Format the specified record as text. The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message. """ record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) try: s = self._fmt % record.__dict__ except UnicodeDecodeError as e: # Issue 25664. The logger name may be Unicode. Try again ... try: record.name = record.name.decode('utf-8') s = self._fmt % record.__dict__ except UnicodeDecodeError: raise e if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" try: s = s + record.exc_text except UnicodeError: # Sometimes filenames have non-ASCII chars, which can lead # to errors when s is Unicode and record.exc_text is str # See issue 8924. # We also use replace for when there are multiple # encodings, e.g. UTF-8 for the filesystem and latin-1 # for a script. See issue 13232. s = s + record.exc_text.decode(sys.getfilesystemencoding(), 'replace') return s # # The default formatter to use when no other is specified # _defaultFormatter = Formatter() class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ def __init__(self, linefmt=None): """ Optionally specify a formatter which will be used to format each individual record. """ if linefmt: self.linefmt = linefmt else: self.linefmt = _defaultFormatter def formatHeader(self, records): """ Return the header string for the specified records. """ return "" def formatFooter(self, records): """ Return the footer string for the specified records. """ return "" def format(self, records): """ Format the specified records and return the result as a string. """ rv = "" if len(records) > 0: rv = rv + self.formatHeader(records) for record in records: rv = rv + self.linefmt.format(record) rv = rv + self.formatFooter(records) return rv #--------------------------------------------------------------------------- # Filter classes and functions #--------------------------------------------------------------------------- class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed. """ def __init__(self, name=''): """ Initialize a filter. Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event. """ self.name = name self.nlen = len(name) def filter(self, record): """ Determine if the specified record is to be logged. Is the specified record to be logged? Returns 0 for no, nonzero for yes. If deemed appropriate, the record may be modified in-place. """ if self.nlen == 0: return 1 elif self.name == record.name: return 1 elif record.name.find(self.name, 0, self.nlen) != 0: return 0 return (record.name[self.nlen] == ".") class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. """ def __init__(self): """ Initialize the list of filters to be an empty list. """ self.filters = [] def addFilter(self, filter): """ Add the specified filter to this handler. """ if not (filter in self.filters): self.filters.append(filter) def removeFilter(self, filter): """ Remove the specified filter from this handler. """ if filter in self.filters: self.filters.remove(filter) def filter(self, record): """ Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto this and the record is then dropped. Returns a zero value if a record is to be dropped, else non-zero. """ rv = 1 for f in self.filters: if not f.filter(record): rv = 0 break return rv #--------------------------------------------------------------------------- # Handler classes and functions #--------------------------------------------------------------------------- _handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized def _removeHandlerRef(wr): """ Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are # set to None. It can also be called from another thread. So we need to # pre-emptively grab the necessary globals and check if they're None, # to prevent race conditions and failures during interpreter shutdown. acquire, release, handlers = _acquireLock, _releaseLock, _handlerList if acquire and release and handlers: try: acquire() try: if wr in handlers: handlers.remove(wr) finally: release() except TypeError: # https://bugs.python.org/issue21149 - If the RLock object behind # acquire() and release() has been partially finalized you may see # an error about NoneType not being callable. Absolutely nothing # we can do in this GC during process shutdown situation. Eat it. pass def _addHandlerRef(handler): """ Add a handler to the internal cleanup list using a weak reference. """ _acquireLock() try: _handlerList.append(weakref.ref(handler, _removeHandlerRef)) finally: _releaseLock() class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. The base handler class. Acts as a placeholder which defines the Handler interface. Handlers can optionally use Formatter instances to format records as desired. By default, no formatter is specified; in this case, the 'raw' message as determined by record.message is logged. """ def __init__(self, level=NOTSET): """ Initializes the instance - basically setting the formatter to None and the filter list to empty. """ Filterer.__init__(self) self._name = None self.level = _checkLevel(level) self.formatter = None # Add the handler to the global _handlerList (for cleanup on shutdown) _addHandlerRef(self) self.createLock() def get_name(self): return self._name def set_name(self, name): _acquireLock() try: if self._name in _handlers: del _handlers[self._name] self._name = name if name: _handlers[name] = self finally: _releaseLock() name = property(get_name, set_name) def createLock(self): """ Acquire a thread lock for serializing access to the underlying I/O. """ if thread: self.lock = threading.RLock() else: self.lock = None def acquire(self): """ Acquire the I/O thread lock. """ if self.lock: self.lock.acquire() def release(self): """ Release the I/O thread lock. """ if self.lock: self.lock.release() def setLevel(self, level): """ Set the logging level of this handler. """ self.level = _checkLevel(level) def format(self, record): """ Format the specified record. If a formatter is set, use it. Otherwise, use the default formatter for the module. """ if self.formatter: fmt = self.formatter else: fmt = _defaultFormatter return fmt.format(record) def emit(self, record): """ Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so raises a NotImplementedError. """ raise NotImplementedError('emit must be implemented ' 'by Handler subclasses') def handle(self, record): """ Conditionally emit the specified logging record. Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns whether the filter passed the record for emission. """ rv = self.filter(record) if rv: self.acquire() try: self.emit(record) finally: self.release() return rv def setFormatter(self, fmt): """ Set the formatter for this handler. """ self.formatter = fmt def flush(self): """ Ensure all logging output has been flushed. This version does nothing and is intended to be implemented by subclasses. """ pass def close(self): """ Tidy up any resources used by the handler. This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... if self._name and self._name in _handlers: del _handlers[self._name] finally: _releaseLock() def handleError(self, record): """ Handle errors which occur during an emit() call. This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method. """ if raiseExceptions and sys.stderr: # see issue 13807 ei = sys.exc_info() try: traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr) sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) except IOError: pass # see issue 5971 finally: del ei class StreamHandler(Handler): """ A handler class which writes logging records, appropriately formatted, to a stream. Note that this class does not close the stream, as sys.stdout or sys.stderr may be used. """ def __init__(self, stream=None): """ Initialize the handler. If stream is not specified, sys.stderr is used. """ Handler.__init__(self) if stream is None: stream = sys.stderr self.stream = stream def flush(self): """ Flushes the stream. """ self.acquire() try: if self.stream and hasattr(self.stream, "flush"): self.stream.flush() finally: self.release() def emit(self, record): """ Emit a record. If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an 'encoding' attribute, it is used to determine how to do the output to the stream. """ try: msg = self.format(record) stream = self.stream fs = "%s\n" if not _unicode: #if no unicode support... stream.write(fs % msg) else: try: if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): ufs = u'%s\n' try: stream.write(ufs % msg) except UnicodeEncodeError: #Printing to terminals sometimes fails. For example, #with an encoding of 'cp1251', the above write will #work if written to a stream opened or wrapped by #the codecs module, but fail when writing to a #terminal even when the codepage is set to cp1251. #An extra encoding step seems to be needed. stream.write((ufs % msg).encode(stream.encoding)) else: stream.write(fs % msg) except UnicodeError: stream.write(fs % msg.encode("UTF-8")) self.flush() except (KeyboardInterrupt, SystemExit): raise except: self.handleError(record) class FileHandler(StreamHandler): """ A handler class which writes formatted logging records to disk files. """ def __init__(self, filename, mode='a', encoding=None, delay=0): """ Open the specified file and use it as the stream for logging. """ #keep the absolute path, otherwise derived classes which use this #may come a cropper when the current directory changes if codecs is None: encoding = None self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding self.delay = delay if delay: #We don't open the stream, but we still need to call the #Handler constructor to set level, formatter, lock etc. Handler.__init__(self) self.stream = None else: StreamHandler.__init__(self, self._open()) def close(self): """ Closes the stream. """ self.acquire() try: try: if self.stream: try: self.flush() finally: stream = self.stream self.stream = None if hasattr(stream, "close"): stream.close() finally: # Issue #19523: call unconditionally to # prevent a handler leak when delay is set StreamHandler.close(self) finally: self.release() def _open(self): """ Open the current base file with the (original) mode and encoding. Return the resulting stream. """ if self.encoding is None: stream = open(self.baseFilename, self.mode) else: stream = codecs.open(self.baseFilename, self.mode, self.encoding) return stream def emit(self, record): """ Emit a record. If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit. """ if self.stream is None: self.stream = self._open() StreamHandler.emit(self, record) #--------------------------------------------------------------------------- # Manager classes and functions #--------------------------------------------------------------------------- class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is intended for internal use only and not as part of the public API. """ def __init__(self, alogger): """ Initialize with the specified logger being a child of this placeholder. """ #self.loggers = [alogger] self.loggerMap = { alogger : None } def append(self, alogger): """ Add the specified logger as a child of this placeholder. """ #if alogger not in self.loggers: if alogger not in self.loggerMap: #self.loggers.append(alogger) self.loggerMap[alogger] = None # # Determine which class to use when instantiating loggers. # _loggerClass = None def setLoggerClass(klass): """ Set the class to be used when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__() """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) global _loggerClass _loggerClass = klass def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ return _loggerClass class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. """ def __init__(self, rootnode): """ Initialize the manager with the root node of the logger hierarchy. """ self.root = rootnode self.disable = 0 self.emittedNoHandlerWarning = 0 self.loggerDict = {} self.loggerClass = None def getLogger(self, name): """ Get a logger with the specified name (channel name), creating it if it doesn't yet exist. This name is a dot-separated hierarchical name, such as "a", "a.b", "a.b.c" or similar. If a PlaceHolder existed for the specified name [i.e. the logger didn't exist but a child of it did], replace it with the created logger and fix up the parent/child references which pointed to the placeholder to now point to the logger. """ rv = None if not isinstance(name, basestring): raise TypeError('A logger name must be string or Unicode') if isinstance(name, unicode): name = name.encode('utf-8') _acquireLock() try: if name in self.loggerDict: rv = self.loggerDict[name] if isinstance(rv, PlaceHolder): ph = rv rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupChildren(ph, rv) self._fixupParents(rv) else: rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupParents(rv) finally: _releaseLock() return rv def setLoggerClass(self, klass): """ Set the class to be used when instantiating a logger with this Manager. """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) self.loggerClass = klass def _fixupParents(self, alogger): """ Ensure that there are either loggers or placeholders all the way from the specified logger to the root of the logger hierarchy. """ name = alogger.name i = name.rfind(".") rv = None while (i > 0) and not rv: substr = name[:i] if substr not in self.loggerDict: self.loggerDict[substr] = PlaceHolder(alogger) else: obj = self.loggerDict[substr] if isinstance(obj, Logger): rv = obj else: assert isinstance(obj, PlaceHolder) obj.append(alogger) i = name.rfind(".", 0, i - 1) if not rv: rv = self.root alogger.parent = rv def _fixupChildren(self, ph, alogger): """ Ensure that children of the placeholder ph are connected to the specified logger. """ name = alogger.name namelen = len(name) for c in ph.loggerMap.keys(): #The if means ... if not c.parent.name.startswith(nm) if c.parent.name[:namelen] != name: alogger.parent = c.parent c.parent = alogger #--------------------------------------------------------------------------- # Logger classes and functions #--------------------------------------------------------------------------- class Logger(Filterer): """ Instances of the Logger class represent a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting. """ def __init__(self, name, level=NOTSET): """ Initialize the logger with a name and an optional level. """ Filterer.__init__(self) self.name = name self.level = _checkLevel(level) self.parent = None self.propagate = 1 self.handlers = [] self.disabled = 0 def setLevel(self, level): """ Set the logging level of this logger. """ self.level = _checkLevel(level) def debug(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'DEBUG'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.debug("Houston, we have a %s", "thorny problem", exc_info=1) """ if self.isEnabledFor(DEBUG): self._log(DEBUG, msg, args, **kwargs) def info(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'INFO'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.info("Houston, we have a %s", "interesting problem", exc_info=1) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) def warning(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'WARNING'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1) """ if self.isEnabledFor(WARNING): self._log(WARNING, msg, args, **kwargs) warn = warning def error(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'ERROR'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.error("Houston, we have a %s", "major problem", exc_info=1) """ if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) def exception(self, msg, *args, **kwargs): """ Convenience method for logging an ERROR with exception information. """ kwargs['exc_info'] = 1 self.error(msg, *args, **kwargs) def critical(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'CRITICAL'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.critical("Houston, we have a %s", "major disaster", exc_info=1) """ if self.isEnabledFor(CRITICAL): self._log(CRITICAL, msg, args, **kwargs) fatal = critical def log(self, level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.log(level, "We have a %s", "mysterious problem", exc_info=1) """ if not isinstance(level, (int, long)): if raiseExceptions: raise TypeError("level must be an integer") else: return if self.isEnabledFor(level): self._log(level, msg, args, **kwargs) def findCaller(self): """ Find the stack frame of the caller so that we can note the source file name, line number and function name. """ f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. if f is not None: f = f.f_back rv = "(unknown file)", 0, "(unknown function)" while hasattr(f, "f_code"): co = f.f_code filename = os.path.normcase(co.co_filename) if filename == _srcfile: f = f.f_back continue rv = (co.co_filename, f.f_lineno, co.co_name) break return rv def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None): """ A factory method which can be overridden in subclasses to create specialized LogRecords. """ rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] return rv def _log(self, level, msg, args, exc_info=None, extra=None): """ Low-level logging routine which creates a LogRecord and then calls all the handlers of this logger to handle the record. """ if _srcfile: #IronPython doesn't track Python frames, so findCaller raises an #exception on some versions of IronPython. We trap it here so that #IronPython can use logging. try: fn, lno, func = self.findCaller() except ValueError: fn, lno, func = "(unknown file)", 0, "(unknown function)" else: fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: if not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra) self.handle(record) def handle(self, record): """ Call the handlers for the specified record. This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ if (not self.disabled) and self.filter(record): self.callHandlers(record) def addHandler(self, hdlr): """ Add the specified handler to this logger. """ _acquireLock() try: if not (hdlr in self.handlers): self.handlers.append(hdlr) finally: _releaseLock() def removeHandler(self, hdlr): """ Remove the specified handler from this logger. """ _acquireLock() try: if hdlr in self.handlers: self.handlers.remove(hdlr) finally: _releaseLock() def callHandlers(self, record): """ Pass a record to all relevant handlers. Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called. """ c = self found = 0 while c: for hdlr in c.handlers: found = found + 1 if record.levelno >= hdlr.level: hdlr.handle(record) if not c.propagate: c = None #break out else: c = c.parent if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning: sys.stderr.write("No handlers could be found for logger" " \"%s\"\n" % self.name) self.manager.emittedNoHandlerWarning = 1 def getEffectiveLevel(self): """ Get the effective level for this logger. Loop through this logger and its parents in the logger hierarchy, looking for a non-zero logging level. Return the first one found. """ logger = self while logger: if logger.level: return logger.level logger = logger.parent return NOTSET def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.manager.disable >= level: return 0 return level >= self.getEffectiveLevel() def getChild(self, suffix): """ Get a logger which is a descendant to this one. This is a convenience method, such that logging.getLogger('abc').getChild('def.ghi') is the same as logging.getLogger('abc.def.ghi') It's useful, for example, when the parent logger is named using __name__ rather than a literal string. """ if self.root is not self: suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) class RootLogger(Logger): """ A root logger is not that different to any other logger, except that it must have a logging level and there is only one instance of it in the hierarchy. """ def __init__(self, level): """ Initialize the logger with the name "root". """ Logger.__init__(self, "root", level) _loggerClass = Logger class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. """ def __init__(self, logger, extra): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows easy stacking of LoggerAdapters, if so desired. You can effectively pass keyword arguments as shown in the following example: adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) """ self.logger = logger self.extra = extra def process(self, msg, kwargs): """ Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs. Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs. """ kwargs["extra"] = self.extra return msg, kwargs def debug(self, msg, *args, **kwargs): """ Delegate a debug call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.debug(msg, *args, **kwargs) def info(self, msg, *args, **kwargs): """ Delegate an info call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.info(msg, *args, **kwargs) def warning(self, msg, *args, **kwargs): """ Delegate a warning call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Delegate an error call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.error(msg, *args, **kwargs) def exception(self, msg, *args, **kwargs): """ Delegate an exception call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) kwargs["exc_info"] = 1 self.logger.error(msg, *args, **kwargs) def critical(self, msg, *args, **kwargs): """ Delegate a critical call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.critical(msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Delegate a log call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.log(level, msg, *args, **kwargs) def isEnabledFor(self, level): """ See if the underlying logger is enabled for the specified level. """ return self.logger.isEnabledFor(level) root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) #--------------------------------------------------------------------------- # Configuration classes and functions #--------------------------------------------------------------------------- BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" def basicConfig(**kwargs): """ Do basic configuration for the logging system. This function does nothing if the root logger already has handlers configured. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package. The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger. A number of optional keyword arguments may be specified, which can alter the default behaviour. filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler. filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format Use the specified format string for the handler. datefmt Use the specified date/time format. level Set the root logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored. Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed. """ # Add thread safety in case someone mistakenly calls # basicConfig() from multiple threads _acquireLock() try: if len(root.handlers) == 0: filename = kwargs.get("filename") if filename: mode = kwargs.get("filemode", 'a') hdlr = FileHandler(filename, mode) else: stream = kwargs.get("stream") hdlr = StreamHandler(stream) fs = kwargs.get("format", BASIC_FORMAT) dfs = kwargs.get("datefmt", None) fmt = Formatter(fs, dfs) hdlr.setFormatter(fmt) root.addHandler(hdlr) level = kwargs.get("level") if level is not None: root.setLevel(level) finally: _releaseLock() #--------------------------------------------------------------------------- # Utility functions at module level. # Basically delegate everything to the root logger. #--------------------------------------------------------------------------- def getLogger(name=None): """ Return a logger with the specified name, creating it if necessary. If no name is specified, return the root logger. """ if name: return Logger.manager.getLogger(name) else: return root #def getRootLogger(): # """ # Return the root logger. # # Note that getLogger('') now does the same thing, so this function is # deprecated and may disappear in the future. # """ # return root def critical(msg, *args, **kwargs): """ Log a message with severity 'CRITICAL' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.critical(msg, *args, **kwargs) fatal = critical def error(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.error(msg, *args, **kwargs) def exception(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. """ kwargs['exc_info'] = 1 error(msg, *args, **kwargs) def warning(msg, *args, **kwargs): """ Log a message with severity 'WARNING' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.warning(msg, *args, **kwargs) warn = warning def info(msg, *args, **kwargs): """ Log a message with severity 'INFO' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.info(msg, *args, **kwargs) def debug(msg, *args, **kwargs): """ Log a message with severity 'DEBUG' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.debug(msg, *args, **kwargs) def log(level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.log(level, msg, *args, **kwargs) def disable(level): """ Disable all logging calls of severity 'level' and below. """ root.manager.disable = level def shutdown(handlerList=_handlerList): """ Perform any cleanup actions in the logging system (e.g. flushing buffers). Should be called at application exit. """ for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: h = wr() if h: try: h.acquire() h.flush() h.close() except (IOError, ValueError): # Ignore errors which might be caused # because handlers have been closed but # references to them are still around at # application exit. pass finally: h.release() except: if raiseExceptions: raise #else, swallow #Let's try and shutdown automatically on application exit... import atexit atexit.register(shutdown) # Null handler class NullHandler(Handler): """ This handler does nothing. It's intended to be used to avoid the "No handlers could be found for logger XXX" one-off warning. This is important for library code, which may contain code to log events. If a user of the library does not configure logging, the one-off warning might be produced; to avoid this, the library developer simply needs to instantiate a NullHandler and add it to the top-level logger of the library module or package. """ def handle(self, record): pass def emit(self, record): pass def createLock(self): self.lock = None # Warnings integration _warnings_showwarning = None def _showwarning(message, category, filename, lineno, file=None, line=None): """ Implementation of showwarnings which redirects to logging, which will first check to see if the file parameter is None. If a file is specified, it will delegate to the original warnings implementation of showwarning. Otherwise, it will call warnings.formatwarning and will log the resulting string to a warnings logger named "py.warnings" with level logging.WARNING. """ if file is not None: if _warnings_showwarning is not None: _warnings_showwarning(message, category, filename, lineno, file, line) else: s = warnings.formatwarning(message, category, filename, lineno, line) logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) logger.warning("%s", s) def captureWarnings(capture): """ If capture is true, redirect all warnings to the logging package. If capture is False, ensure that warnings are not redirected to logging but to their original destinations. """ global _warnings_showwarning if capture: if _warnings_showwarning is None: _warnings_showwarning = warnings.showwarning warnings.showwarning = _showwarning else: if _warnings_showwarning is not None: warnings.showwarning = _warnings_showwarning _warnings_showwarning = None usr/lib64/python3.6/multiprocessing/__init__.py000064400000001633152345760030015415 0ustar00# # Package analogous to 'threading.py' but using processes # # multiprocessing/__init__.py # # This package is intended to duplicate the functionality (and much of # the API) of threading.py but uses processes instead of threads. A # subpackage 'multiprocessing.dummy' has the same API but is a simple # wrapper for 'threading'. # # Copyright (c) 2006-2008, R Oudkerk # Licensed to PSF under a Contributor Agreement. # import sys from . import context # # Copy stuff from default context # globals().update((name, getattr(context._default_context, name)) for name in context._default_context.__all__) __all__ = context._default_context.__all__ # # XXX These should not really be documented or public. # SUBDEBUG = 5 SUBWARNING = 25 # # Alias for main module -- will be reset by bootstrapping child processes # if '__main__' in sys.modules: sys.modules['__mp_main__'] = sys.modules['__main__'] usr/lib64/python3.8/collections/__init__.py000064400000135503152346012100014477 0ustar00'''This module implements specialized container datatypes providing alternatives to Python's general purpose built-in containers, dict, list, set, and tuple. * namedtuple factory function for creating tuple subclasses with named fields * deque list-like container with fast appends and pops on either end * ChainMap dict-like class for creating a single view of multiple mappings * Counter dict subclass for counting hashable objects * OrderedDict dict subclass that remembers the order entries were added * defaultdict dict subclass that calls a factory function to supply missing values * UserDict wrapper around dictionary objects for easier dict subclassing * UserList wrapper around list objects for easier list subclassing * UserString wrapper around string objects for easier string subclassing ''' __all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 'UserString', 'Counter', 'OrderedDict', 'ChainMap'] import _collections_abc from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from _weakref import proxy as _proxy from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from reprlib import recursive_repr as _recursive_repr try: from _collections import deque except ImportError: pass else: _collections_abc.MutableSequence.register(deque) try: from _collections import defaultdict except ImportError: pass def __getattr__(name): # For backwards compatibility, continue to make the collections ABCs # through Python 3.6 available through the collections module. # Note, no new collections ABCs were added in Python 3.7 if name in _collections_abc.__all__: obj = getattr(_collections_abc, name) import warnings warnings.warn("Using or importing the ABCs from 'collections' instead " "of from 'collections.abc' is deprecated since Python 3.3, " "and in 3.10 it will stop working", DeprecationWarning, stacklevel=2) globals()[name] = obj return obj raise AttributeError(f'module {__name__!r} has no attribute {name!r}') ################################################################################ ### OrderedDict ################################################################################ class _OrderedDictKeysView(_collections_abc.KeysView): def __reversed__(self): yield from reversed(self._mapping) class _OrderedDictItemsView(_collections_abc.ItemsView): def __reversed__(self): for key in reversed(self._mapping): yield (key, self._mapping[key]) class _OrderedDictValuesView(_collections_abc.ValuesView): def __reversed__(self): for key in reversed(self._mapping): yield self._mapping[key] class _Link(object): __slots__ = 'prev', 'next', 'key', '__weakref__' class OrderedDict(dict): 'Dictionary that remembers insertion order' # An inherited dict maps keys to values. # The inherited dict provides __getitem__, __len__, __contains__, and get. # The remaining methods are order-aware. # Big-O running times for all methods are the same as regular dictionaries. # The internal self.__map dict maps keys to links in a doubly linked list. # The circular doubly linked list starts and ends with a sentinel element. # The sentinel element never gets deleted (this simplifies the algorithm). # The sentinel is in self.__hardroot with a weakref proxy in self.__root. # The prev links are weakref proxies (to prevent circular references). # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. def __init__(self, other=(), /, **kwds): '''Initialize an ordered dictionary. The signature is the same as regular dictionaries. Keyword argument order is preserved. ''' try: self.__root except AttributeError: self.__hardroot = _Link() self.__root = root = _proxy(self.__hardroot) root.prev = root.next = root self.__map = {} self.__update(other, **kwds) def __setitem__(self, key, value, dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: self.__map[key] = link = Link() root = self.__root last = root.prev link.prev, link.next, link.key = last, root, key last.next = link root.prev = proxy(link) dict_setitem(self, key, value) def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link = self.__map.pop(key) link_prev = link.prev link_next = link.next link_prev.next = link_next link_next.prev = link_prev link.prev = None link.next = None def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. root = self.__root curr = root.next while curr is not root: yield curr.key curr = curr.next def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. root = self.__root curr = root.prev while curr is not root: yield curr.key curr = curr.prev def clear(self): 'od.clear() -> None. Remove all items from od.' root = self.__root root.prev = root.next = root self.__map.clear() dict.clear(self) def popitem(self, last=True): '''Remove and return a (key, value) pair from the dictionary. Pairs are returned in LIFO order if last is true or FIFO order if false. ''' if not self: raise KeyError('dictionary is empty') root = self.__root if last: link = root.prev link_prev = link.prev link_prev.next = root root.prev = link_prev else: link = root.next link_next = link.next root.next = link_next link_next.prev = root key = link.key del self.__map[key] value = dict.pop(self, key) return key, value def move_to_end(self, key, last=True): '''Move an existing element to the end (or beginning if last is false). Raise KeyError if the element does not exist. ''' link = self.__map[key] link_prev = link.prev link_next = link.next soft_link = link_next.prev link_prev.next = link_next link_next.prev = link_prev root = self.__root if last: last = root.prev link.prev = last link.next = root root.prev = soft_link last.next = link else: first = root.next link.prev = root link.next = first first.prev = soft_link root.next = link def __sizeof__(self): sizeof = _sys.getsizeof n = len(self) + 1 # number of links including root size = sizeof(self.__dict__) # instance dictionary size += sizeof(self.__map) * 2 # internal dict and inherited dict size += sizeof(self.__hardroot) * n # link objects size += sizeof(self.__root) * n # proxy objects return size update = __update = _collections_abc.MutableMapping.update def keys(self): "D.keys() -> a set-like object providing a view on D's keys" return _OrderedDictKeysView(self) def items(self): "D.items() -> a set-like object providing a view on D's items" return _OrderedDictItemsView(self) def values(self): "D.values() -> an object providing a view on D's values" return _OrderedDictValuesView(self) __ne__ = _collections_abc.MutableMapping.__ne__ __marker = object() def pop(self, key, default=__marker): '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised. ''' if key in self: result = self[key] del self[key] return result if default is self.__marker: raise KeyError(key) return default def setdefault(self, key, default=None): '''Insert key with a value of default if key is not in the dictionary. Return the value for key if key is in the dictionary, else default. ''' if key in self: return self[key] self[key] = default return default @_recursive_repr() def __repr__(self): 'od.__repr__() <==> repr(od)' if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, list(self.items())) def __reduce__(self): 'Return state information for pickling' inst_dict = vars(self).copy() for k in vars(OrderedDict()): inst_dict.pop(k, None) return self.__class__, (), inst_dict or None, None, iter(self.items()) def copy(self): 'od.copy() -> a shallow copy of od' return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): '''Create a new ordered dictionary with keys from iterable and values set to value. ''' self = cls() for key in iterable: self[key] = value return self def __eq__(self, other): '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive while comparison to a regular mapping is order-insensitive. ''' if isinstance(other, OrderedDict): return dict.__eq__(self, other) and all(map(_eq, self, other)) return dict.__eq__(self, other) try: from _collections import OrderedDict except ImportError: # Leave the pure Python version in place. pass ################################################################################ ### namedtuple ################################################################################ try: from _collections import _tuplegetter except ImportError: _tuplegetter = lambda index, doc: property(_itemgetter(index), doc=doc) def namedtuple(typename, field_names, *, rename=False, defaults=None, module=None): """Returns a new subclass of tuple with named fields. >>> Point = namedtuple('Point', ['x', 'y']) >>> Point.__doc__ # docstring for the new class 'Point(x, y)' >>> p = Point(11, y=22) # instantiate with positional args or keywords >>> p[0] + p[1] # indexable like a plain tuple 33 >>> x, y = p # unpack like a regular tuple >>> x, y (11, 22) >>> p.x + p.y # fields also accessible by name 33 >>> d = p._asdict() # convert to a dictionary >>> d['x'] 11 >>> Point(**d) # convert from a dictionary Point(x=11, y=22) >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields Point(x=100, y=22) """ # Validate the field names. At the user's option, either generate an error # message or automatically replace the field name with a valid name. if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() field_names = list(map(str, field_names)) typename = _sys.intern(str(typename)) if rename: seen = set() for index, name in enumerate(field_names): if (not name.isidentifier() or _iskeyword(name) or name.startswith('_') or name in seen): field_names[index] = f'_{index}' seen.add(name) for name in [typename] + field_names: if type(name) is not str: raise TypeError('Type names and field names must be strings') if not name.isidentifier(): raise ValueError('Type names and field names must be valid ' f'identifiers: {name!r}') if _iskeyword(name): raise ValueError('Type names and field names cannot be a ' f'keyword: {name!r}') seen = set() for name in field_names: if name.startswith('_') and not rename: raise ValueError('Field names cannot start with an underscore: ' f'{name!r}') if name in seen: raise ValueError(f'Encountered duplicate field name: {name!r}') seen.add(name) field_defaults = {} if defaults is not None: defaults = tuple(defaults) if len(defaults) > len(field_names): raise TypeError('Got more default values than field names') field_defaults = dict(reversed(list(zip(reversed(field_names), reversed(defaults))))) # Variables used in the methods and docstrings field_names = tuple(map(_sys.intern, field_names)) num_fields = len(field_names) arg_list = repr(field_names).replace("'", "")[1:-1] repr_fmt = '(' + ', '.join(f'{name}=%r' for name in field_names) + ')' tuple_new = tuple.__new__ _dict, _tuple, _len, _map, _zip = dict, tuple, len, map, zip # Create all the named tuple methods to be added to the class namespace s = f'def __new__(_cls, {arg_list}): return _tuple_new(_cls, ({arg_list}))' namespace = {'_tuple_new': tuple_new, '__name__': f'namedtuple_{typename}'} # Note: exec() has the side-effect of interning the field names exec(s, namespace) __new__ = namespace['__new__'] __new__.__doc__ = f'Create new instance of {typename}({arg_list})' if defaults is not None: __new__.__defaults__ = defaults @classmethod def _make(cls, iterable): result = tuple_new(cls, iterable) if _len(result) != num_fields: raise TypeError(f'Expected {num_fields} arguments, got {len(result)}') return result _make.__func__.__doc__ = (f'Make a new {typename} object from a sequence ' 'or iterable') def _replace(self, /, **kwds): result = self._make(_map(kwds.pop, field_names, self)) if kwds: raise ValueError(f'Got unexpected field names: {list(kwds)!r}') return result _replace.__doc__ = (f'Return a new {typename} object replacing specified ' 'fields with new values') def __repr__(self): 'Return a nicely formatted representation string' return self.__class__.__name__ + repr_fmt % self def _asdict(self): 'Return a new dict which maps field names to their values.' return _dict(_zip(self._fields, self)) def __getnewargs__(self): 'Return self as a plain tuple. Used by copy and pickle.' return _tuple(self) # Modify function metadata to help with introspection and debugging for method in (__new__, _make.__func__, _replace, __repr__, _asdict, __getnewargs__): method.__qualname__ = f'{typename}.{method.__name__}' # Build-up the class namespace dictionary # and use type() to build the result class class_namespace = { '__doc__': f'{typename}({arg_list})', '__slots__': (), '_fields': field_names, '_field_defaults': field_defaults, # alternate spelling for backward compatibility '_fields_defaults': field_defaults, '__new__': __new__, '_make': _make, '_replace': _replace, '__repr__': __repr__, '_asdict': _asdict, '__getnewargs__': __getnewargs__, } for index, name in enumerate(field_names): doc = _sys.intern(f'Alias for field number {index}') class_namespace[name] = _tuplegetter(index, doc) result = type(typename, (tuple,), class_namespace) # For pickling to work, the __module__ variable needs to be set to the frame # where the named tuple is created. Bypass this step in environments where # sys._getframe is not defined (Jython for example) or sys._getframe is not # defined for arguments greater than 0 (IronPython), or where the user has # specified a particular module. if module is None: try: module = _sys._getframe(1).f_globals.get('__name__', '__main__') except (AttributeError, ValueError): pass if module is not None: result.__module__ = module return result ######################################################################## ### Counter ######################################################################## def _count_elements(mapping, iterable): 'Tally elements from the iterable.' mapping_get = mapping.get for elem in iterable: mapping[elem] = mapping_get(elem, 0) + 1 try: # Load C helper function if available from _collections import _count_elements except ImportError: pass class Counter(dict): '''Dict subclass for counting hashable items. Sometimes called a bag or multiset. Elements are stored as dictionary keys and their counts are stored as dictionary values. >>> c = Counter('abcdeabcdabcaba') # count elements from a string >>> c.most_common(3) # three most common elements [('a', 5), ('b', 4), ('c', 3)] >>> sorted(c) # list all unique elements ['a', 'b', 'c', 'd', 'e'] >>> ''.join(sorted(c.elements())) # list elements with repetitions 'aaaaabbbbcccdde' >>> sum(c.values()) # total of all counts 15 >>> c['a'] # count of letter 'a' 5 >>> for elem in 'shazam': # update counts from an iterable ... c[elem] += 1 # by adding 1 to each element's count >>> c['a'] # now there are seven 'a' 7 >>> del c['b'] # remove all 'b' >>> c['b'] # now there are zero 'b' 0 >>> d = Counter('simsalabim') # make another counter >>> c.update(d) # add in the second counter >>> c['a'] # now there are nine 'a' 9 >>> c.clear() # empty the counter >>> c Counter() Note: If a count is set to zero or reduced to zero, it will remain in the counter until the entry is deleted or the counter is cleared: >>> c = Counter('aaabbc') >>> c['b'] -= 2 # reduce the count of 'b' by two >>> c.most_common() # 'b' is still in, but its count is zero [('a', 3), ('c', 1), ('b', 0)] ''' # References: # http://en.wikipedia.org/wiki/Multiset # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm # http://code.activestate.com/recipes/259174/ # Knuth, TAOCP Vol. II section 4.6.3 def __init__(self, iterable=None, /, **kwds): '''Create a new, empty Counter object. And if given, count elements from an input iterable. Or, initialize the count from another mapping of elements to their counts. >>> c = Counter() # a new, empty counter >>> c = Counter('gallahad') # a new counter from an iterable >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping >>> c = Counter(a=4, b=2) # a new counter from keyword args ''' super(Counter, self).__init__() self.update(iterable, **kwds) def __missing__(self, key): 'The count of elements not in the Counter is zero.' # Needed so that self[missing_item] does not raise KeyError return 0 def most_common(self, n=None): '''List the n most common elements and their counts from the most common to the least. If n is None, then list all element counts. >>> Counter('abracadabra').most_common(3) [('a', 5), ('b', 2), ('r', 2)] ''' # Emulate Bag.sortedByCount from Smalltalk if n is None: return sorted(self.items(), key=_itemgetter(1), reverse=True) return _heapq.nlargest(n, self.items(), key=_itemgetter(1)) def elements(self): '''Iterator over elements repeating each as many times as its count. >>> c = Counter('ABCABC') >>> sorted(c.elements()) ['A', 'A', 'B', 'B', 'C', 'C'] # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) >>> product = 1 >>> for factor in prime_factors.elements(): # loop over factors ... product *= factor # and multiply them >>> product 1836 Note, if an element's count has been set to zero or is a negative number, elements() will ignore it. ''' # Emulate Bag.do from Smalltalk and Multiset.begin from C++. return _chain.from_iterable(_starmap(_repeat, self.items())) # Override dict methods where necessary @classmethod def fromkeys(cls, iterable, v=None): # There is no equivalent method for counters because the semantics # would be ambiguous in cases such as Counter.fromkeys('aaabbc', v=2). # Initializing counters to zero values isn't necessary because zero # is already the default value for counter lookups. Initializing # to one is easily accomplished with Counter(set(iterable)). For # more exotic cases, create a dictionary first using a dictionary # comprehension or dict.fromkeys(). raise NotImplementedError( 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') def update(self, iterable=None, /, **kwds): '''Like dict.update() but add counts instead of replacing them. Source can be an iterable, a dictionary, or another Counter instance. >>> c = Counter('which') >>> c.update('witch') # add elements from another iterable >>> d = Counter('watch') >>> c.update(d) # add elements from another counter >>> c['h'] # four 'h' in which, witch, and watch 4 ''' # The regular dict.update() operation makes no sense here because the # replace behavior results in the some of original untouched counts # being mixed-in with all of the other counts for a mismash that # doesn't have a straight-forward interpretation in most counting # contexts. Instead, we implement straight-addition. Both the inputs # and outputs are allowed to contain zero and negative counts. if iterable is not None: if isinstance(iterable, _collections_abc.Mapping): if self: self_get = self.get for elem, count in iterable.items(): self[elem] = count + self_get(elem, 0) else: super(Counter, self).update(iterable) # fast path when counter is empty else: _count_elements(self, iterable) if kwds: self.update(kwds) def subtract(self, iterable=None, /, **kwds): '''Like dict.update() but subtracts counts instead of replacing them. Counts can be reduced below zero. Both the inputs and outputs are allowed to contain zero and negative counts. Source can be an iterable, a dictionary, or another Counter instance. >>> c = Counter('which') >>> c.subtract('witch') # subtract elements from another iterable >>> c.subtract(Counter('watch')) # subtract elements from another counter >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch 0 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch -1 ''' if iterable is not None: self_get = self.get if isinstance(iterable, _collections_abc.Mapping): for elem, count in iterable.items(): self[elem] = self_get(elem, 0) - count else: for elem in iterable: self[elem] = self_get(elem, 0) - 1 if kwds: self.subtract(kwds) def copy(self): 'Return a shallow copy.' return self.__class__(self) def __reduce__(self): return self.__class__, (dict(self),) def __delitem__(self, elem): 'Like dict.__delitem__() but does not raise KeyError for missing values.' if elem in self: super().__delitem__(elem) def __repr__(self): if not self: return '%s()' % self.__class__.__name__ try: items = ', '.join(map('%r: %r'.__mod__, self.most_common())) return '%s({%s})' % (self.__class__.__name__, items) except TypeError: # handle case where values are not orderable return '{0}({1!r})'.format(self.__class__.__name__, dict(self)) # Multiset-style mathematical operations discussed in: # Knuth TAOCP Volume II section 4.6.3 exercise 19 # and at http://en.wikipedia.org/wiki/Multiset # # Outputs guaranteed to only include positive counts. # # To strip negative and zero counts, add-in an empty counter: # c += Counter() # # Rich comparison operators for multiset subset and superset tests # are deliberately omitted due to semantic conflicts with the # existing inherited dict equality method. Subset and superset # semantics ignore zero counts and require that p≤q ∧ p≥q → p=q; # however, that would not be the case for p=Counter(a=1, b=0) # and q=Counter(a=1) where the dictionaries are not equal. def __add__(self, other): '''Add counts from two counters. >>> Counter('abbb') + Counter('bcc') Counter({'b': 4, 'c': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): newcount = count + other[elem] if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count > 0: result[elem] = count return result def __sub__(self, other): ''' Subtract count, but keep only results with positive counts. >>> Counter('abbbc') - Counter('bccd') Counter({'b': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): newcount = count - other[elem] if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count < 0: result[elem] = 0 - count return result def __or__(self, other): '''Union is the maximum of value in either of the input counters. >>> Counter('abbb') | Counter('bcc') Counter({'b': 3, 'c': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): other_count = other[elem] newcount = other_count if count < other_count else count if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count > 0: result[elem] = count return result def __and__(self, other): ''' Intersection is the minimum of corresponding counts. >>> Counter('abbb') & Counter('bcc') Counter({'b': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): other_count = other[elem] newcount = count if count < other_count else other_count if newcount > 0: result[elem] = newcount return result def __pos__(self): 'Adds an empty counter, effectively stripping negative and zero counts' result = Counter() for elem, count in self.items(): if count > 0: result[elem] = count return result def __neg__(self): '''Subtracts from an empty counter. Strips positive and zero counts, and flips the sign on negative counts. ''' result = Counter() for elem, count in self.items(): if count < 0: result[elem] = 0 - count return result def _keep_positive(self): '''Internal method to strip elements with a negative or zero count''' nonpositive = [elem for elem, count in self.items() if not count > 0] for elem in nonpositive: del self[elem] return self def __iadd__(self, other): '''Inplace add from another counter, keeping only positive counts. >>> c = Counter('abbb') >>> c += Counter('bcc') >>> c Counter({'b': 4, 'c': 2, 'a': 1}) ''' for elem, count in other.items(): self[elem] += count return self._keep_positive() def __isub__(self, other): '''Inplace subtract counter, but keep only results with positive counts. >>> c = Counter('abbbc') >>> c -= Counter('bccd') >>> c Counter({'b': 2, 'a': 1}) ''' for elem, count in other.items(): self[elem] -= count return self._keep_positive() def __ior__(self, other): '''Inplace union is the maximum of value from either counter. >>> c = Counter('abbb') >>> c |= Counter('bcc') >>> c Counter({'b': 3, 'c': 2, 'a': 1}) ''' for elem, other_count in other.items(): count = self[elem] if other_count > count: self[elem] = other_count return self._keep_positive() def __iand__(self, other): '''Inplace intersection is the minimum of corresponding counts. >>> c = Counter('abbb') >>> c &= Counter('bcc') >>> c Counter({'b': 1}) ''' for elem, count in self.items(): other_count = other[elem] if other_count < count: self[elem] = other_count return self._keep_positive() ######################################################################## ### ChainMap ######################################################################## class ChainMap(_collections_abc.MutableMapping): ''' A ChainMap groups multiple dicts (or other mappings) together to create a single, updateable view. The underlying mappings are stored in a list. That list is public and can be accessed or updated using the *maps* attribute. There is no other state. Lookups search the underlying mappings successively until a key is found. In contrast, writes, updates, and deletions only operate on the first mapping. ''' def __init__(self, *maps): '''Initialize a ChainMap by setting *maps* to the given mappings. If no mappings are provided, a single empty dictionary is used. ''' self.maps = list(maps) or [{}] # always at least one map def __missing__(self, key): raise KeyError(key) def __getitem__(self, key): for mapping in self.maps: try: return mapping[key] # can't use 'key in mapping' with defaultdict except KeyError: pass return self.__missing__(key) # support subclasses that define __missing__ def get(self, key, default=None): return self[key] if key in self else default def __len__(self): return len(set().union(*self.maps)) # reuses stored hash values if possible def __iter__(self): d = {} for mapping in reversed(self.maps): d.update(mapping) # reuses stored hash values if possible return iter(d) def __contains__(self, key): return any(key in m for m in self.maps) def __bool__(self): return any(self.maps) @_recursive_repr() def __repr__(self): return f'{self.__class__.__name__}({", ".join(map(repr, self.maps))})' @classmethod def fromkeys(cls, iterable, *args): 'Create a ChainMap with a single dict created from the iterable.' return cls(dict.fromkeys(iterable, *args)) def copy(self): 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' return self.__class__(self.maps[0].copy(), *self.maps[1:]) __copy__ = copy def new_child(self, m=None): # like Django's Context.push() '''New ChainMap with a new map followed by all previous maps. If no map is provided, an empty dict is used. ''' if m is None: m = {} return self.__class__(m, *self.maps) @property def parents(self): # like Django's Context.pop() 'New ChainMap from maps[1:].' return self.__class__(*self.maps[1:]) def __setitem__(self, key, value): self.maps[0][key] = value def __delitem__(self, key): try: del self.maps[0][key] except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def popitem(self): 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' try: return self.maps[0].popitem() except KeyError: raise KeyError('No keys found in the first mapping.') def pop(self, key, *args): 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' try: return self.maps[0].pop(key, *args) except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def clear(self): 'Clear maps[0], leaving maps[1:] intact.' self.maps[0].clear() ################################################################################ ### UserDict ################################################################################ class UserDict(_collections_abc.MutableMapping): # Start by filling-out the abstract methods def __init__(*args, **kwargs): if not args: raise TypeError("descriptor '__init__' of 'UserDict' object " "needs an argument") self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) if args: dict = args[0] elif 'dict' in kwargs: dict = kwargs.pop('dict') import warnings warnings.warn("Passing 'dict' as keyword argument is deprecated", DeprecationWarning, stacklevel=2) else: dict = None self.data = {} if dict is not None: self.update(dict) if kwargs: self.update(kwargs) __init__.__text_signature__ = '($self, dict=None, /, **kwargs)' def __len__(self): return len(self.data) def __getitem__(self, key): if key in self.data: return self.data[key] if hasattr(self.__class__, "__missing__"): return self.__class__.__missing__(self, key) raise KeyError(key) def __setitem__(self, key, item): self.data[key] = item def __delitem__(self, key): del self.data[key] def __iter__(self): return iter(self.data) # Modify __contains__ to work correctly when __missing__ is present def __contains__(self, key): return key in self.data # Now, add the methods in dicts but not in MutableMapping def __repr__(self): return repr(self.data) def __copy__(self): inst = self.__class__.__new__(self.__class__) inst.__dict__.update(self.__dict__) # Create a copy and avoid triggering descriptors inst.__dict__["data"] = self.__dict__["data"].copy() return inst def copy(self): if self.__class__ is UserDict: return UserDict(self.data.copy()) import copy data = self.data try: self.data = {} c = copy.copy(self) finally: self.data = data c.update(self) return c @classmethod def fromkeys(cls, iterable, value=None): d = cls() for key in iterable: d[key] = value return d ################################################################################ ### UserList ################################################################################ class UserList(_collections_abc.MutableSequence): """A more or less complete user-defined wrapper around list objects.""" def __init__(self, initlist=None): self.data = [] if initlist is not None: # XXX should this accept an arbitrary sequence? if type(initlist) == type(self.data): self.data[:] = initlist elif isinstance(initlist, UserList): self.data[:] = initlist.data[:] else: self.data = list(initlist) def __repr__(self): return repr(self.data) def __lt__(self, other): return self.data < self.__cast(other) def __le__(self, other): return self.data <= self.__cast(other) def __eq__(self, other): return self.data == self.__cast(other) def __gt__(self, other): return self.data > self.__cast(other) def __ge__(self, other): return self.data >= self.__cast(other) def __cast(self, other): return other.data if isinstance(other, UserList) else other def __contains__(self, item): return item in self.data def __len__(self): return len(self.data) def __getitem__(self, i): if isinstance(i, slice): return self.__class__(self.data[i]) else: return self.data[i] def __setitem__(self, i, item): self.data[i] = item def __delitem__(self, i): del self.data[i] def __add__(self, other): if isinstance(other, UserList): return self.__class__(self.data + other.data) elif isinstance(other, type(self.data)): return self.__class__(self.data + other) return self.__class__(self.data + list(other)) def __radd__(self, other): if isinstance(other, UserList): return self.__class__(other.data + self.data) elif isinstance(other, type(self.data)): return self.__class__(other + self.data) return self.__class__(list(other) + self.data) def __iadd__(self, other): if isinstance(other, UserList): self.data += other.data elif isinstance(other, type(self.data)): self.data += other else: self.data += list(other) return self def __mul__(self, n): return self.__class__(self.data*n) __rmul__ = __mul__ def __imul__(self, n): self.data *= n return self def __copy__(self): inst = self.__class__.__new__(self.__class__) inst.__dict__.update(self.__dict__) # Create a copy and avoid triggering descriptors inst.__dict__["data"] = self.__dict__["data"][:] return inst def append(self, item): self.data.append(item) def insert(self, i, item): self.data.insert(i, item) def pop(self, i=-1): return self.data.pop(i) def remove(self, item): self.data.remove(item) def clear(self): self.data.clear() def copy(self): return self.__class__(self) def count(self, item): return self.data.count(item) def index(self, item, *args): return self.data.index(item, *args) def reverse(self): self.data.reverse() def sort(self, /, *args, **kwds): self.data.sort(*args, **kwds) def extend(self, other): if isinstance(other, UserList): self.data.extend(other.data) else: self.data.extend(other) ################################################################################ ### UserString ################################################################################ class UserString(_collections_abc.Sequence): def __init__(self, seq): if isinstance(seq, str): self.data = seq elif isinstance(seq, UserString): self.data = seq.data[:] else: self.data = str(seq) def __str__(self): return str(self.data) def __repr__(self): return repr(self.data) def __int__(self): return int(self.data) def __float__(self): return float(self.data) def __complex__(self): return complex(self.data) def __hash__(self): return hash(self.data) def __getnewargs__(self): return (self.data[:],) def __eq__(self, string): if isinstance(string, UserString): return self.data == string.data return self.data == string def __lt__(self, string): if isinstance(string, UserString): return self.data < string.data return self.data < string def __le__(self, string): if isinstance(string, UserString): return self.data <= string.data return self.data <= string def __gt__(self, string): if isinstance(string, UserString): return self.data > string.data return self.data > string def __ge__(self, string): if isinstance(string, UserString): return self.data >= string.data return self.data >= string def __contains__(self, char): if isinstance(char, UserString): char = char.data return char in self.data def __len__(self): return len(self.data) def __getitem__(self, index): return self.__class__(self.data[index]) def __add__(self, other): if isinstance(other, UserString): return self.__class__(self.data + other.data) elif isinstance(other, str): return self.__class__(self.data + other) return self.__class__(self.data + str(other)) def __radd__(self, other): if isinstance(other, str): return self.__class__(other + self.data) return self.__class__(str(other) + self.data) def __mul__(self, n): return self.__class__(self.data*n) __rmul__ = __mul__ def __mod__(self, args): return self.__class__(self.data % args) def __rmod__(self, template): return self.__class__(str(template) % self) # the following methods are defined in alphabetical order: def capitalize(self): return self.__class__(self.data.capitalize()) def casefold(self): return self.__class__(self.data.casefold()) def center(self, width, *args): return self.__class__(self.data.center(width, *args)) def count(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.count(sub, start, end) def encode(self, encoding='utf-8', errors='strict'): encoding = 'utf-8' if encoding is None else encoding errors = 'strict' if errors is None else errors return self.data.encode(encoding, errors) def endswith(self, suffix, start=0, end=_sys.maxsize): return self.data.endswith(suffix, start, end) def expandtabs(self, tabsize=8): return self.__class__(self.data.expandtabs(tabsize)) def find(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.find(sub, start, end) def format(self, /, *args, **kwds): return self.data.format(*args, **kwds) def format_map(self, mapping): return self.data.format_map(mapping) def index(self, sub, start=0, end=_sys.maxsize): return self.data.index(sub, start, end) def isalpha(self): return self.data.isalpha() def isalnum(self): return self.data.isalnum() def isascii(self): return self.data.isascii() def isdecimal(self): return self.data.isdecimal() def isdigit(self): return self.data.isdigit() def isidentifier(self): return self.data.isidentifier() def islower(self): return self.data.islower() def isnumeric(self): return self.data.isnumeric() def isprintable(self): return self.data.isprintable() def isspace(self): return self.data.isspace() def istitle(self): return self.data.istitle() def isupper(self): return self.data.isupper() def join(self, seq): return self.data.join(seq) def ljust(self, width, *args): return self.__class__(self.data.ljust(width, *args)) def lower(self): return self.__class__(self.data.lower()) def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars)) maketrans = str.maketrans def partition(self, sep): return self.data.partition(sep) def replace(self, old, new, maxsplit=-1): if isinstance(old, UserString): old = old.data if isinstance(new, UserString): new = new.data return self.__class__(self.data.replace(old, new, maxsplit)) def rfind(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.rfind(sub, start, end) def rindex(self, sub, start=0, end=_sys.maxsize): return self.data.rindex(sub, start, end) def rjust(self, width, *args): return self.__class__(self.data.rjust(width, *args)) def rpartition(self, sep): return self.data.rpartition(sep) def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars)) def split(self, sep=None, maxsplit=-1): return self.data.split(sep, maxsplit) def rsplit(self, sep=None, maxsplit=-1): return self.data.rsplit(sep, maxsplit) def splitlines(self, keepends=False): return self.data.splitlines(keepends) def startswith(self, prefix, start=0, end=_sys.maxsize): return self.data.startswith(prefix, start, end) def strip(self, chars=None): return self.__class__(self.data.strip(chars)) def swapcase(self): return self.__class__(self.data.swapcase()) def title(self): return self.__class__(self.data.title()) def translate(self, *args): return self.__class__(self.data.translate(*args)) def upper(self): return self.__class__(self.data.upper()) def zfill(self, width): return self.__class__(self.data.zfill(width)) lib64/python2.7/idlelib/__init__.py000064400000000440152346020420012745 0ustar00"""The idlelib package implements the Idle application. Idle includes an interactive shell and editor. Use the files named idle.* to start Idle. The other files are private implementations. Their details are subject to change. See PEP 434 for more. Import them at your own risk. """ usr/lib64/python3.8/tkinter/__init__.py000064400000512715152346026070013660 0ustar00"""Wrapper functions for Tcl/Tk. Tkinter provides classes which allow the display, positioning and control of widgets. Toplevel widgets are Tk and Toplevel. Other widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox LabelFrame and PanedWindow. Properties of the widgets are specified with keyword arguments. Keyword arguments have the same name as the corresponding resource under Tk. Widgets are positioned with one of the geometry managers Place, Pack or Grid. These managers can be called with methods place, pack, grid available in every Widget. Actions are bound to events by resources (e.g. keyword argument command) or with the method bind. Example (Hello, World): import tkinter from tkinter.constants import * tk = tkinter.Tk() frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2) frame.pack(fill=BOTH,expand=1) label = tkinter.Label(frame, text="Hello, World") label.pack(fill=X, expand=1) button = tkinter.Button(frame,text="Exit",command=tk.destroy) button.pack(side=BOTTOM) tk.mainloop() """ import enum import sys import _tkinter # If this fails your Python may not be configured for Tk TclError = _tkinter.TclError from tkinter.constants import * import re wantobjects = 1 TkVersion = float(_tkinter.TK_VERSION) TclVersion = float(_tkinter.TCL_VERSION) READABLE = _tkinter.READABLE WRITABLE = _tkinter.WRITABLE EXCEPTION = _tkinter.EXCEPTION _magic_re = re.compile(r'([\\{}])') _space_re = re.compile(r'([\s])', re.ASCII) def _join(value): """Internal function.""" return ' '.join(map(_stringify, value)) def _stringify(value): """Internal function.""" if isinstance(value, (list, tuple)): if len(value) == 1: value = _stringify(value[0]) if _magic_re.search(value): value = '{%s}' % value else: value = '{%s}' % _join(value) else: value = str(value) if not value: value = '{}' elif _magic_re.search(value): # add '\' before special characters and spaces value = _magic_re.sub(r'\\\1', value) value = value.replace('\n', r'\n') value = _space_re.sub(r'\\\1', value) if value[0] == '"': value = '\\' + value elif value[0] == '"' or _space_re.search(value): value = '{%s}' % value return value def _flatten(seq): """Internal function.""" res = () for item in seq: if isinstance(item, (tuple, list)): res = res + _flatten(item) elif item is not None: res = res + (item,) return res try: _flatten = _tkinter._flatten except AttributeError: pass def _cnfmerge(cnfs): """Internal function.""" if isinstance(cnfs, dict): return cnfs elif isinstance(cnfs, (type(None), str)): return cnfs else: cnf = {} for c in _flatten(cnfs): try: cnf.update(c) except (AttributeError, TypeError) as msg: print("_cnfmerge: fallback due to:", msg) for k, v in c.items(): cnf[k] = v return cnf try: _cnfmerge = _tkinter._cnfmerge except AttributeError: pass def _splitdict(tk, v, cut_minus=True, conv=None): """Return a properly formatted dict built from Tcl list pairs. If cut_minus is True, the supposed '-' prefix will be removed from keys. If conv is specified, it is used to convert values. Tcl list is expected to contain an even number of elements. """ t = tk.splitlist(v) if len(t) % 2: raise RuntimeError('Tcl list representing a dict is expected ' 'to contain an even number of elements') it = iter(t) dict = {} for key, value in zip(it, it): key = str(key) if cut_minus and key[0] == '-': key = key[1:] if conv: value = conv(value) dict[key] = value return dict class EventType(str, enum.Enum): KeyPress = '2' Key = KeyPress KeyRelease = '3' ButtonPress = '4' Button = ButtonPress ButtonRelease = '5' Motion = '6' Enter = '7' Leave = '8' FocusIn = '9' FocusOut = '10' Keymap = '11' # undocumented Expose = '12' GraphicsExpose = '13' # undocumented NoExpose = '14' # undocumented Visibility = '15' Create = '16' Destroy = '17' Unmap = '18' Map = '19' MapRequest = '20' Reparent = '21' Configure = '22' ConfigureRequest = '23' Gravity = '24' ResizeRequest = '25' Circulate = '26' CirculateRequest = '27' Property = '28' SelectionClear = '29' # undocumented SelectionRequest = '30' # undocumented Selection = '31' # undocumented Colormap = '32' ClientMessage = '33' # undocumented Mapping = '34' # undocumented VirtualEvent = '35' # undocumented Activate = '36' Deactivate = '37' MouseWheel = '38' __str__ = str.__str__ class Event: """Container for the properties of an event. Instances of this type are generated if one of the following events occurs: KeyPress, KeyRelease - for keyboard events ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, Colormap, Gravity, Reparent, Property, Destroy, Activate, Deactivate - for window events. If a callback function for one of these events is registered using bind, bind_all, bind_class, or tag_bind, the callback is called with an Event as first argument. It will have the following attributes (in braces are the event types for which the attribute is valid): serial - serial number of event num - mouse button pressed (ButtonPress, ButtonRelease) focus - whether the window has the focus (Enter, Leave) height - height of the exposed window (Configure, Expose) width - width of the exposed window (Configure, Expose) keycode - keycode of the pressed key (KeyPress, KeyRelease) state - state of the event as a number (ButtonPress, ButtonRelease, Enter, KeyPress, KeyRelease, Leave, Motion) state - state as a string (Visibility) time - when the event occurred x - x-position of the mouse y - y-position of the mouse x_root - x-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) y_root - y-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) char - pressed character (KeyPress, KeyRelease) send_event - see X/Windows documentation keysym - keysym of the event as a string (KeyPress, KeyRelease) keysym_num - keysym of the event as a number (KeyPress, KeyRelease) type - type of the event as a number widget - widget in which the event occurred delta - delta of wheel movement (MouseWheel) """ def __repr__(self): attrs = {k: v for k, v in self.__dict__.items() if v != '??'} if not self.char: del attrs['char'] elif self.char != '??': attrs['char'] = repr(self.char) if not getattr(self, 'send_event', True): del attrs['send_event'] if self.state == 0: del attrs['state'] elif isinstance(self.state, int): state = self.state mods = ('Shift', 'Lock', 'Control', 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Button1', 'Button2', 'Button3', 'Button4', 'Button5') s = [] for i, n in enumerate(mods): if state & (1 << i): s.append(n) state = state & ~((1<< len(mods)) - 1) if state or not s: s.append(hex(state)) attrs['state'] = '|'.join(s) if self.delta == 0: del attrs['delta'] # widget usually is known # serial and time are not very interesting # keysym_num duplicates keysym # x_root and y_root mostly duplicate x and y keys = ('send_event', 'state', 'keysym', 'keycode', 'char', 'num', 'delta', 'focus', 'x', 'y', 'width', 'height') return '<%s event%s>' % ( getattr(self.type, 'name', self.type), ''.join(' %s=%s' % (k, attrs[k]) for k in keys if k in attrs) ) _support_default_root = True _default_root = None def NoDefaultRoot(): """Inhibit setting of default root window. Call this function to inhibit that the first instance of Tk is used for windows without an explicit parent window. """ global _support_default_root, _default_root _support_default_root = False # Delete, so any use of _default_root will immediately raise an exception. # Rebind before deletion, so repeated calls will not fail. _default_root = None del _default_root def _get_default_root(what=None): if not _support_default_root: raise RuntimeError("No master specified and tkinter is " "configured to not support default root") if not _default_root: if what: raise RuntimeError(f"Too early to {what}: no default root window") root = Tk() assert _default_root is root return _default_root def _tkerror(err): """Internal function.""" pass def _exit(code=0): """Internal function. Calling it will raise the exception SystemExit.""" try: code = int(code) except ValueError: pass raise SystemExit(code) _varnum = 0 class Variable: """Class to define value holders for e.g. buttons. Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations that constrain the type of the value returned from get().""" _default = "" _tk = None _tclCommands = None def __init__(self, master=None, value=None, name=None): """Construct a variable MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ # check for type of NAME parameter to override weird error message # raised from Modules/_tkinter.c:SetVar like: # TypeError: setvar() takes exactly 3 arguments (2 given) if name is not None and not isinstance(name, str): raise TypeError("name must be a string") global _varnum if not master: master = _get_default_root('create variable') self._root = master._root() self._tk = master.tk if name: self._name = name else: self._name = 'PY_VAR' + repr(_varnum) _varnum += 1 if value is not None: self.initialize(value) elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)): self.initialize(self._default) def __del__(self): """Unset the variable in Tcl.""" if self._tk is None: return if self._tk.getboolean(self._tk.call("info", "exists", self._name)): self._tk.globalunsetvar(self._name) if self._tclCommands is not None: for name in self._tclCommands: #print '- Tkinter: deleted command', name self._tk.deletecommand(name) self._tclCommands = None def __str__(self): """Return the name of the variable in Tcl.""" return self._name def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, value) initialize = set def get(self): """Return value of variable.""" return self._tk.globalgetvar(self._name) def _register(self, callback): f = CallWrapper(callback, None, self._root).__call__ cbname = repr(id(f)) try: callback = callback.__func__ except AttributeError: pass try: cbname = cbname + callback.__name__ except AttributeError: pass self._tk.createcommand(cbname, f) if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(cbname) return cbname def trace_add(self, mode, callback): """Define a trace callback for the variable. Mode is one of "read", "write", "unset", or a list or tuple of such strings. Callback must be a function which is called when the variable is read, written or unset. Return the name of the callback. """ cbname = self._register(callback) self._tk.call('trace', 'add', 'variable', self._name, mode, (cbname,)) return cbname def trace_remove(self, mode, cbname): """Delete the trace callback for a variable. Mode is one of "read", "write", "unset" or a list or tuple of such strings. Must be same as were specified in trace_add(). cbname is the name of the callback returned from trace_add(). """ self._tk.call('trace', 'remove', 'variable', self._name, mode, cbname) for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_info(self): """Return all trace callback information.""" splitlist = self._tk.splitlist return [(splitlist(k), v) for k, v in map(splitlist, splitlist(self._tk.call('trace', 'info', 'variable', self._name)))] def trace_variable(self, mode, callback): """Define a trace callback for the variable. MODE is one of "r", "w", "u" for read, write, undefine. CALLBACK must be a function which is called when the variable is read, written or undefined. Return the name of the callback. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_add() instead. """ # TODO: Add deprecation warning cbname = self._register(callback) self._tk.call("trace", "variable", self._name, mode, cbname) return cbname trace = trace_variable def trace_vdelete(self, mode, cbname): """Delete the trace callback for a variable. MODE is one of "r", "w", "u" for read, write, undefine. CBNAME is the name of the callback returned from trace_variable or trace. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_remove() instead. """ # TODO: Add deprecation warning self._tk.call("trace", "vdelete", self._name, mode, cbname) cbname = self._tk.splitlist(cbname)[0] for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_vinfo(self): """Return all trace callback information. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_info() instead. """ # TODO: Add deprecation warning return [self._tk.splitlist(x) for x in self._tk.splitlist( self._tk.call("trace", "vinfo", self._name))] def __eq__(self, other): if not isinstance(other, Variable): return NotImplemented return (self._name == other._name and self.__class__.__name__ == other.__class__.__name__ and self._tk == other._tk) class StringVar(Variable): """Value holder for strings variables.""" _default = "" def __init__(self, master=None, value=None, name=None): """Construct a string variable. MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return value of variable as string.""" value = self._tk.globalgetvar(self._name) if isinstance(value, str): return value return str(value) class IntVar(Variable): """Value holder for integer variables.""" _default = 0 def __init__(self, master=None, value=None, name=None): """Construct an integer variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as an integer.""" value = self._tk.globalgetvar(self._name) try: return self._tk.getint(value) except (TypeError, TclError): return int(self._tk.getdouble(value)) class DoubleVar(Variable): """Value holder for float variables.""" _default = 0.0 def __init__(self, master=None, value=None, name=None): """Construct a float variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0.0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as a float.""" return self._tk.getdouble(self._tk.globalgetvar(self._name)) class BooleanVar(Variable): """Value holder for boolean variables.""" _default = False def __init__(self, master=None, value=None, name=None): """Construct a boolean variable. MASTER can be given as master widget. VALUE is an optional value (defaults to False) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, self._tk.getboolean(value)) initialize = set def get(self): """Return the value of the variable as a bool.""" try: return self._tk.getboolean(self._tk.globalgetvar(self._name)) except TclError: raise ValueError("invalid literal for getboolean()") def mainloop(n=0): """Run the main loop of Tcl.""" _get_default_root('run the main loop').tk.mainloop(n) getint = int getdouble = float def getboolean(s): """Convert Tcl object to True or False.""" try: return _get_default_root('use getboolean()').tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") # Methods defined on both toplevel and interior widgets class Misc: """Internal class. Base class which defines methods common for interior widgets.""" # used for generating child widget names _last_child_ids = None # XXX font command? _tclCommands = None def destroy(self): """Internal function. Delete all Tcl commands created for this widget in the Tcl interpreter.""" if self._tclCommands is not None: for name in self._tclCommands: #print '- Tkinter: deleted command', name self.tk.deletecommand(name) self._tclCommands = None def deletecommand(self, name): """Internal function. Delete the Tcl command provided in NAME.""" #print '- Tkinter: deleted command', name self.tk.deletecommand(name) try: self._tclCommands.remove(name) except ValueError: pass def tk_strictMotif(self, boolean=None): """Set Tcl internal variable, whether the look and feel should adhere to Motif. A parameter of 1 means adhere to Motif (e.g. no color change if mouse passes over slider). Returns the set value.""" return self.tk.getboolean(self.tk.call( 'set', 'tk_strictMotif', boolean)) def tk_bisque(self): """Change the color scheme to light brown as used in Tk 3.6 and before.""" self.tk.call('tk_bisque') def tk_setPalette(self, *args, **kw): """Set a new color scheme for all widget elements. A single color as argument will cause that all colors of Tk widget elements are derived from this. Alternatively several keyword parameters and its associated colors can be given. The following keywords are valid: activeBackground, foreground, selectColor, activeForeground, highlightBackground, selectBackground, background, highlightColor, selectForeground, disabledForeground, insertBackground, troughColor.""" self.tk.call(('tk_setPalette',) + _flatten(args) + _flatten(list(kw.items()))) def wait_variable(self, name='PY_VAR'): """Wait until the variable is modified. A parameter of type IntVar, StringVar, DoubleVar or BooleanVar must be given.""" self.tk.call('tkwait', 'variable', name) waitvar = wait_variable # XXX b/w compat def wait_window(self, window=None): """Wait until a WIDGET is destroyed. If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'window', window._w) def wait_visibility(self, window=None): """Wait until the visibility of a WIDGET changes (e.g. it appears). If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'visibility', window._w) def setvar(self, name='PY_VAR', value='1'): """Set Tcl variable NAME to VALUE.""" self.tk.setvar(name, value) def getvar(self, name='PY_VAR'): """Return value of Tcl variable NAME.""" return self.tk.getvar(name) def getint(self, s): try: return self.tk.getint(s) except TclError as exc: raise ValueError(str(exc)) def getdouble(self, s): try: return self.tk.getdouble(s) except TclError as exc: raise ValueError(str(exc)) def getboolean(self, s): """Return a boolean value for Tcl boolean values true and false given as parameter.""" try: return self.tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") def focus_set(self): """Direct input focus to this widget. If the application currently does not have the focus this widget will get the focus if the application gets the focus through the window manager.""" self.tk.call('focus', self._w) focus = focus_set # XXX b/w compat? def focus_force(self): """Direct input focus to this widget even if the application does not have the focus. Use with caution!""" self.tk.call('focus', '-force', self._w) def focus_get(self): """Return the widget which has currently the focus in the application. Use focus_displayof to allow working with several displays. Return None if application does not have the focus.""" name = self.tk.call('focus') if name == 'none' or not name: return None return self._nametowidget(name) def focus_displayof(self): """Return the widget which has currently the focus on the display where this widget is located. Return None if the application does not have the focus.""" name = self.tk.call('focus', '-displayof', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def focus_lastfor(self): """Return the widget which would have the focus if top level for this widget gets the focus from the window manager.""" name = self.tk.call('focus', '-lastfor', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def tk_focusFollowsMouse(self): """The widget under mouse will get automatically focus. Can not be disabled easily.""" self.tk.call('tk_focusFollowsMouse') def tk_focusNext(self): """Return the next widget in the focus order which follows widget which has currently the focus. The focus order first goes to the next child, then to the children of the child recursively and then to the next sibling which is higher in the stacking order. A widget is omitted if it has the takefocus resource set to 0.""" name = self.tk.call('tk_focusNext', self._w) if not name: return None return self._nametowidget(name) def tk_focusPrev(self): """Return previous widget in the focus order. See tk_focusNext for details.""" name = self.tk.call('tk_focusPrev', self._w) if not name: return None return self._nametowidget(name) def after(self, ms, func=None, *args): """Call function once after given time. MS specifies the time in milliseconds. FUNC gives the function which shall be called. Additional parameters are given as parameters to the function call. Return identifier to cancel scheduling with after_cancel.""" if not func: # I'd rather use time.sleep(ms*0.001) self.tk.call('after', ms) return None else: def callit(): try: func(*args) finally: try: self.deletecommand(name) except TclError: pass callit.__name__ = func.__name__ name = self._register(callit) return self.tk.call('after', ms, name) def after_idle(self, func, *args): """Call FUNC once if the Tcl main loop has no event to process. Return an identifier to cancel the scheduling with after_cancel.""" return self.after('idle', func, *args) def after_cancel(self, id): """Cancel scheduling of function identified with ID. Identifier returned by after or after_idle must be given as first parameter. """ if not id: raise ValueError('id must be a valid identifier returned from ' 'after or after_idle') try: data = self.tk.call('after', 'info', id) script = self.tk.splitlist(data)[0] self.deletecommand(script) except TclError: pass self.tk.call('after', 'cancel', id) def bell(self, displayof=0): """Ring a display's bell.""" self.tk.call(('bell',) + self._displayof(displayof)) # Clipboard handling: def clipboard_get(self, **kw): """Retrieve data from the clipboard on window's display. The window keyword defaults to the root window of the Tkinter application. The type keyword specifies the form in which the data is to be returned and should be an atom name such as STRING or FILE_NAME. Type defaults to STRING, except on X11, where the default is to try UTF8_STRING and fall back to STRING. This command is equivalent to: selection_get(CLIPBOARD) """ if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('clipboard', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('clipboard', 'get') + self._options(kw)) def clipboard_clear(self, **kw): """Clear the data in the Tk clipboard. A widget specified for the optional displayof keyword argument specifies the target display.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'clear') + self._options(kw)) def clipboard_append(self, string, **kw): """Append STRING to the Tk clipboard. A widget specified at the optional displayof keyword argument specifies the target display. The clipboard can be retrieved with selection_get.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'append') + self._options(kw) + ('--', string)) # XXX grab current w/o window argument def grab_current(self): """Return widget which has currently the grab in this application or None.""" name = self.tk.call('grab', 'current', self._w) if not name: return None return self._nametowidget(name) def grab_release(self): """Release grab for this widget if currently set.""" self.tk.call('grab', 'release', self._w) def grab_set(self): """Set grab for this widget. A grab directs all events to this and descendant widgets in the application.""" self.tk.call('grab', 'set', self._w) def grab_set_global(self): """Set global grab for this widget. A global grab directs all events to this and descendant widgets on the display. Use with caution - other applications do not get events anymore.""" self.tk.call('grab', 'set', '-global', self._w) def grab_status(self): """Return None, "local" or "global" if this widget has no, a local or a global grab.""" status = self.tk.call('grab', 'status', self._w) if status == 'none': status = None return status def option_add(self, pattern, value, priority = None): """Set a VALUE (second parameter) for an option PATTERN (first parameter). An optional third parameter gives the numeric priority (defaults to 80).""" self.tk.call('option', 'add', pattern, value, priority) def option_clear(self): """Clear the option database. It will be reloaded if option_add is called.""" self.tk.call('option', 'clear') def option_get(self, name, className): """Return the value for an option NAME for this widget with CLASSNAME. Values with higher priority override lower values.""" return self.tk.call('option', 'get', self._w, name, className) def option_readfile(self, fileName, priority = None): """Read file FILENAME into the option database. An optional second parameter gives the numeric priority.""" self.tk.call('option', 'readfile', fileName, priority) def selection_clear(self, **kw): """Clear the current X selection.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('selection', 'clear') + self._options(kw)) def selection_get(self, **kw): """Return the contents of the current X selection. A keyword parameter selection specifies the name of the selection and defaults to PRIMARY. A keyword parameter displayof specifies a widget on the display to use. A keyword parameter type specifies the form of data to be fetched, defaulting to STRING except on X11, where UTF8_STRING is tried before STRING.""" if 'displayof' not in kw: kw['displayof'] = self._w if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('selection', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('selection', 'get') + self._options(kw)) def selection_handle(self, command, **kw): """Specify a function COMMAND to call if the X selection owned by this widget is queried by another application. This function must return the contents of the selection. The function will be called with the arguments OFFSET and LENGTH which allows the chunking of very long selections. The following keyword parameters can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" name = self._register(command) self.tk.call(('selection', 'handle') + self._options(kw) + (self._w, name)) def selection_own(self, **kw): """Become owner of X selection. A keyword parameter selection specifies the name of the selection (default PRIMARY).""" self.tk.call(('selection', 'own') + self._options(kw) + (self._w,)) def selection_own_get(self, **kw): """Return owner of X selection. The following keyword parameter can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" if 'displayof' not in kw: kw['displayof'] = self._w name = self.tk.call(('selection', 'own') + self._options(kw)) if not name: return None return self._nametowidget(name) def send(self, interp, cmd, *args): """Send Tcl command CMD to different interpreter INTERP to be executed.""" return self.tk.call(('send', interp, cmd) + args) def lower(self, belowThis=None): """Lower this widget in the stacking order.""" self.tk.call('lower', self._w, belowThis) def tkraise(self, aboveThis=None): """Raise this widget in the stacking order.""" self.tk.call('raise', self._w, aboveThis) lift = tkraise def winfo_atom(self, name, displayof=0): """Return integer which represents atom NAME.""" args = ('winfo', 'atom') + self._displayof(displayof) + (name,) return self.tk.getint(self.tk.call(args)) def winfo_atomname(self, id, displayof=0): """Return name of atom with identifier ID.""" args = ('winfo', 'atomname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_cells(self): """Return number of cells in the colormap for this widget.""" return self.tk.getint( self.tk.call('winfo', 'cells', self._w)) def winfo_children(self): """Return a list of all widgets which are children of this widget.""" result = [] for child in self.tk.splitlist( self.tk.call('winfo', 'children', self._w)): try: # Tcl sometimes returns extra windows, e.g. for # menus; those need to be skipped result.append(self._nametowidget(child)) except KeyError: pass return result def winfo_class(self): """Return window class name of this widget.""" return self.tk.call('winfo', 'class', self._w) def winfo_colormapfull(self): """Return True if at the last color request the colormap was full.""" return self.tk.getboolean( self.tk.call('winfo', 'colormapfull', self._w)) def winfo_containing(self, rootX, rootY, displayof=0): """Return the widget which is at the root coordinates ROOTX, ROOTY.""" args = ('winfo', 'containing') \ + self._displayof(displayof) + (rootX, rootY) name = self.tk.call(args) if not name: return None return self._nametowidget(name) def winfo_depth(self): """Return the number of bits per pixel.""" return self.tk.getint(self.tk.call('winfo', 'depth', self._w)) def winfo_exists(self): """Return true if this widget exists.""" return self.tk.getint( self.tk.call('winfo', 'exists', self._w)) def winfo_fpixels(self, number): """Return the number of pixels for the given distance NUMBER (e.g. "3c") as float.""" return self.tk.getdouble(self.tk.call( 'winfo', 'fpixels', self._w, number)) def winfo_geometry(self): """Return geometry string for this widget in the form "widthxheight+X+Y".""" return self.tk.call('winfo', 'geometry', self._w) def winfo_height(self): """Return height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'height', self._w)) def winfo_id(self): """Return identifier ID for this widget.""" return int(self.tk.call('winfo', 'id', self._w), 0) def winfo_interps(self, displayof=0): """Return the name of all Tcl interpreters for this display.""" args = ('winfo', 'interps') + self._displayof(displayof) return self.tk.splitlist(self.tk.call(args)) def winfo_ismapped(self): """Return true if this widget is mapped.""" return self.tk.getint( self.tk.call('winfo', 'ismapped', self._w)) def winfo_manager(self): """Return the window manager name for this widget.""" return self.tk.call('winfo', 'manager', self._w) def winfo_name(self): """Return the name of this widget.""" return self.tk.call('winfo', 'name', self._w) def winfo_parent(self): """Return the name of the parent of this widget.""" return self.tk.call('winfo', 'parent', self._w) def winfo_pathname(self, id, displayof=0): """Return the pathname of the widget given by ID.""" args = ('winfo', 'pathname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_pixels(self, number): """Rounded integer value of winfo_fpixels.""" return self.tk.getint( self.tk.call('winfo', 'pixels', self._w, number)) def winfo_pointerx(self): """Return the x coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointerx', self._w)) def winfo_pointerxy(self): """Return a tuple of x and y coordinates of the pointer on the root window.""" return self._getints( self.tk.call('winfo', 'pointerxy', self._w)) def winfo_pointery(self): """Return the y coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointery', self._w)) def winfo_reqheight(self): """Return requested height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqheight', self._w)) def winfo_reqwidth(self): """Return requested width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqwidth', self._w)) def winfo_rgb(self, color): """Return a tuple of integer RGB values in range(65536) for color in this widget.""" return self._getints( self.tk.call('winfo', 'rgb', self._w, color)) def winfo_rootx(self): """Return x coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rootx', self._w)) def winfo_rooty(self): """Return y coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rooty', self._w)) def winfo_screen(self): """Return the screen name of this widget.""" return self.tk.call('winfo', 'screen', self._w) def winfo_screencells(self): """Return the number of the cells in the colormap of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screencells', self._w)) def winfo_screendepth(self): """Return the number of bits per pixel of the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screendepth', self._w)) def winfo_screenheight(self): """Return the number of pixels of the height of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenheight', self._w)) def winfo_screenmmheight(self): """Return the number of pixels of the height of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmheight', self._w)) def winfo_screenmmwidth(self): """Return the number of pixels of the width of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmwidth', self._w)) def winfo_screenvisual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the default colormodel of this screen.""" return self.tk.call('winfo', 'screenvisual', self._w) def winfo_screenwidth(self): """Return the number of pixels of the width of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenwidth', self._w)) def winfo_server(self): """Return information of the X-Server of the screen of this widget in the form "XmajorRminor vendor vendorVersion".""" return self.tk.call('winfo', 'server', self._w) def winfo_toplevel(self): """Return the toplevel widget of this widget.""" return self._nametowidget(self.tk.call( 'winfo', 'toplevel', self._w)) def winfo_viewable(self): """Return true if the widget and all its higher ancestors are mapped.""" return self.tk.getint( self.tk.call('winfo', 'viewable', self._w)) def winfo_visual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the colormodel of this widget.""" return self.tk.call('winfo', 'visual', self._w) def winfo_visualid(self): """Return the X identifier for the visual for this widget.""" return self.tk.call('winfo', 'visualid', self._w) def winfo_visualsavailable(self, includeids=False): """Return a list of all visuals available for the screen of this widget. Each item in the list consists of a visual name (see winfo_visual), a depth and if includeids is true is given also the X identifier.""" data = self.tk.call('winfo', 'visualsavailable', self._w, 'includeids' if includeids else None) data = [self.tk.splitlist(x) for x in self.tk.splitlist(data)] return [self.__winfo_parseitem(x) for x in data] def __winfo_parseitem(self, t): """Internal function.""" return t[:1] + tuple(map(self.__winfo_getint, t[1:])) def __winfo_getint(self, x): """Internal function.""" return int(x, 0) def winfo_vrootheight(self): """Return the height of the virtual root window associated with this widget in pixels. If there is no virtual root window return the height of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootheight', self._w)) def winfo_vrootwidth(self): """Return the width of the virtual root window associated with this widget in pixel. If there is no virtual root window return the width of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootwidth', self._w)) def winfo_vrootx(self): """Return the x offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrootx', self._w)) def winfo_vrooty(self): """Return the y offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrooty', self._w)) def winfo_width(self): """Return the width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'width', self._w)) def winfo_x(self): """Return the x coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'x', self._w)) def winfo_y(self): """Return the y coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'y', self._w)) def update(self): """Enter event loop until all pending events have been processed by Tcl.""" self.tk.call('update') def update_idletasks(self): """Enter event loop until all idle callbacks have been called. This will update the display of windows but not process events caused by the user.""" self.tk.call('update', 'idletasks') def bindtags(self, tagList=None): """Set or get the list of bindtags for this widget. With no argument return the list of all bindtags associated with this widget. With a list of strings as argument the bindtags are set to this list. The bindtags determine in which order events are processed (see bind).""" if tagList is None: return self.tk.splitlist( self.tk.call('bindtags', self._w)) else: self.tk.call('bindtags', self._w, tagList) def _bind(self, what, sequence, func, add, needcleanup=1): """Internal function.""" if isinstance(func, str): self.tk.call(what + (sequence, func)) elif func: funcid = self._register(func, self._substitute, needcleanup) cmd = ('%sif {"[%s %s]" == "break"} break\n' % (add and '+' or '', funcid, self._subst_format_str)) self.tk.call(what + (sequence, cmd)) return funcid elif sequence: return self.tk.call(what + (sequence,)) else: return self.tk.splitlist(self.tk.call(what)) def bind(self, sequence=None, func=None, add=None): """Bind to this widget at event SEQUENCE a call to function FUNC. SEQUENCE is a string of concatenated event patterns. An event pattern is of the form where MODIFIER is one of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, B3, Alt, Button4, B4, Double, Button5, B5 Triple, Mod1, M1. TYPE is one of Activate, Enter, Map, ButtonPress, Button, Expose, Motion, ButtonRelease FocusIn, MouseWheel, Circulate, FocusOut, Property, Colormap, Gravity Reparent, Configure, KeyPress, Key, Unmap, Deactivate, KeyRelease Visibility, Destroy, Leave and DETAIL is the button number for ButtonPress, ButtonRelease and DETAIL is the Keysym for KeyPress and KeyRelease. Examples are for pressing Control and mouse button 1 or for pressing A and the Alt key (KeyPress can be omitted). An event pattern can also be a virtual event of the form <> where AString can be arbitrary. This event can be generated by event_generate. If events are concatenated they must appear shortly after each other. FUNC will be called if the event sequence occurs with an instance of Event as argument. If the return value of FUNC is "break" no further bound function is invoked. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. Bind will return an identifier to allow deletion of the bound function with unbind without memory leak. If FUNC or SEQUENCE is omitted the bound function or list of bound events are returned.""" return self._bind(('bind', self._w), sequence, func, add) def unbind(self, sequence, funcid=None): """Unbind for this widget for event SEQUENCE the function identified with FUNCID.""" self.tk.call('bind', self._w, sequence, '') if funcid: self.deletecommand(funcid) def bind_all(self, sequence=None, func=None, add=None): """Bind to all widgets at an event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind(('bind', 'all'), sequence, func, add, 0) def unbind_all(self, sequence): """Unbind for all widgets for event SEQUENCE all functions.""" self.tk.call('bind', 'all' , sequence, '') def bind_class(self, className, sequence=None, func=None, add=None): """Bind to widgets with bindtag CLASSNAME at event SEQUENCE a call of function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind(('bind', className), sequence, func, add, 0) def unbind_class(self, className, sequence): """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self.tk.call('bind', className , sequence, '') def mainloop(self, n=0): """Call the mainloop of Tk.""" self.tk.mainloop(n) def quit(self): """Quit the Tcl interpreter. All widgets will be destroyed.""" self.tk.quit() def _getints(self, string): """Internal function.""" if string: return tuple(map(self.tk.getint, self.tk.splitlist(string))) def _getdoubles(self, string): """Internal function.""" if string: return tuple(map(self.tk.getdouble, self.tk.splitlist(string))) def _getboolean(self, string): """Internal function.""" if string: return self.tk.getboolean(string) def _displayof(self, displayof): """Internal function.""" if displayof: return ('-displayof', displayof) if displayof is None: return ('-displayof', self._w) return () @property def _windowingsystem(self): """Internal function.""" try: return self._root()._windowingsystem_cached except AttributeError: ws = self._root()._windowingsystem_cached = \ self.tk.call('tk', 'windowingsystem') return ws def _options(self, cnf, kw = None): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) else: cnf = _cnfmerge(cnf) res = () for k, v in cnf.items(): if v is not None: if k[-1] == '_': k = k[:-1] if callable(v): v = self._register(v) elif isinstance(v, (tuple, list)): nv = [] for item in v: if isinstance(item, int): nv.append(str(item)) elif isinstance(item, str): nv.append(_stringify(item)) else: break else: v = ' '.join(nv) res = res + ('-'+k, v) return res def nametowidget(self, name): """Return the Tkinter instance of a widget identified by its Tcl name NAME.""" name = str(name).split('.') w = self if not name[0]: w = w._root() name = name[1:] for n in name: if not n: break w = w.children[n] return w _nametowidget = nametowidget def _register(self, func, subst=None, needcleanup=1): """Return a newly created Tcl function. If this function is called, the Python function FUNC will be executed. An optional function SUBST can be given which will be executed before FUNC.""" f = CallWrapper(func, subst, self).__call__ name = repr(id(f)) try: func = func.__func__ except AttributeError: pass try: name = name + func.__name__ except AttributeError: pass self.tk.createcommand(name, f) if needcleanup: if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(name) return name register = _register def _root(self): """Internal function.""" w = self while w.master: w = w.master return w _subst_format = ('%#', '%b', '%f', '%h', '%k', '%s', '%t', '%w', '%x', '%y', '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') _subst_format_str = " ".join(_subst_format) def _substitute(self, *args): """Internal function.""" if len(args) != len(self._subst_format): return args getboolean = self.tk.getboolean getint = self.tk.getint def getint_event(s): """Tk changed behavior in 8.4.2, returning "??" rather more often.""" try: return getint(s) except (ValueError, TclError): return s nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args # Missing: (a, c, d, m, o, v, B, R) e = Event() # serial field: valid for all events # number of button: ButtonPress and ButtonRelease events only # height field: Configure, ConfigureRequest, Create, # ResizeRequest, and Expose events only # keycode field: KeyPress and KeyRelease events only # time field: "valid for events that contain a time field" # width field: Configure, ConfigureRequest, Create, ResizeRequest, # and Expose events only # x field: "valid for events that contain an x field" # y field: "valid for events that contain a y field" # keysym as decimal: KeyPress and KeyRelease events only # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, # KeyRelease, and Motion events e.serial = getint(nsign) e.num = getint_event(b) try: e.focus = getboolean(f) except TclError: pass e.height = getint_event(h) e.keycode = getint_event(k) e.state = getint_event(s) e.time = getint_event(t) e.width = getint_event(w) e.x = getint_event(x) e.y = getint_event(y) e.char = A try: e.send_event = getboolean(E) except TclError: pass e.keysym = K e.keysym_num = getint_event(N) try: e.type = EventType(T) except ValueError: e.type = T try: e.widget = self._nametowidget(W) except KeyError: e.widget = W e.x_root = getint_event(X) e.y_root = getint_event(Y) try: e.delta = getint(D) except (ValueError, TclError): e.delta = 0 return (e,) def _report_exception(self): """Internal function.""" exc, val, tb = sys.exc_info() root = self._root() root.report_callback_exception(exc, val, tb) def _getconfigure(self, *args): """Call Tcl configure command and return the result as a dict.""" cnf = {} for x in self.tk.splitlist(self.tk.call(*args)): x = self.tk.splitlist(x) cnf[x[0][1:]] = (x[0][1:],) + x[1:] return cnf def _getconfigure1(self, *args): x = self.tk.splitlist(self.tk.call(*args)) return (x[0][1:],) + x[1:] def _configure(self, cmd, cnf, kw): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) elif cnf: cnf = _cnfmerge(cnf) if cnf is None: return self._getconfigure(_flatten((self._w, cmd))) if isinstance(cnf, str): return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) # These used to be defined in Widget: def configure(self, cnf=None, **kw): """Configure resources of a widget. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method keys. """ return self._configure('configure', cnf, kw) config = configure def cget(self, key): """Return the resource value for a KEY given as string.""" return self.tk.call(self._w, 'cget', '-' + key) __getitem__ = cget def __setitem__(self, key, value): self.configure({key: value}) def keys(self): """Return a list of all resource names of this widget.""" splitlist = self.tk.splitlist return [splitlist(x)[0][1:] for x in splitlist(self.tk.call(self._w, 'configure'))] def __str__(self): """Return the window path name of this widget.""" return self._w def __repr__(self): return '<%s.%s object %s>' % ( self.__class__.__module__, self.__class__.__qualname__, self._w) # Pack methods that apply to the master _noarg_ = ['_noarg_'] def pack_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'pack', 'propagate', self._w)) else: self.tk.call('pack', 'propagate', self._w, flag) propagate = pack_propagate def pack_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call('pack', 'slaves', self._w))] slaves = pack_slaves # Place method that applies to the master def place_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call( 'place', 'slaves', self._w))] # Grid methods that apply to the master def grid_anchor(self, anchor=None): # new in Tk 8.5 """The anchor value controls how to place the grid within the master when no row/column has any weight. The default anchor is nw.""" self.tk.call('grid', 'anchor', self._w, anchor) anchor = grid_anchor def grid_bbox(self, column=None, row=None, col2=None, row2=None): """Return a tuple of integer coordinates for the bounding box of this widget controlled by the geometry manager grid. If COLUMN, ROW is given the bounding box applies from the cell with row and column 0 to the specified cell. If COL2 and ROW2 are given the bounding box starts at that cell. The returned integers specify the offset of the upper left corner in the master widget and the width and height. """ args = ('grid', 'bbox', self._w) if column is not None and row is not None: args = args + (column, row) if col2 is not None and row2 is not None: args = args + (col2, row2) return self._getints(self.tk.call(*args)) or None bbox = grid_bbox def _gridconvvalue(self, value): if isinstance(value, (str, _tkinter.Tcl_Obj)): try: svalue = str(value) if not svalue: return None elif '.' in svalue: return self.tk.getdouble(svalue) else: return self.tk.getint(svalue) except (ValueError, TclError): pass return value def _grid_configure(self, command, index, cnf, kw): """Internal function.""" if isinstance(cnf, str) and not kw: if cnf[-1:] == '_': cnf = cnf[:-1] if cnf[:1] != '-': cnf = '-'+cnf options = (cnf,) else: options = self._options(cnf, kw) if not options: return _splitdict( self.tk, self.tk.call('grid', command, self._w, index), conv=self._gridconvvalue) res = self.tk.call( ('grid', command, self._w, index) + options) if len(options) == 1: return self._gridconvvalue(res) def grid_columnconfigure(self, index, cnf={}, **kw): """Configure column INDEX of a grid. Valid resources are minsize (minimum size of the column), weight (how much does additional space propagate to this column) and pad (how much space to let additionally).""" return self._grid_configure('columnconfigure', index, cnf, kw) columnconfigure = grid_columnconfigure def grid_location(self, x, y): """Return a tuple of column and row which identify the cell at which the pixel at position X and Y inside the master widget is located.""" return self._getints( self.tk.call( 'grid', 'location', self._w, x, y)) or None def grid_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given, the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'grid', 'propagate', self._w)) else: self.tk.call('grid', 'propagate', self._w, flag) def grid_rowconfigure(self, index, cnf={}, **kw): """Configure row INDEX of a grid. Valid resources are minsize (minimum size of the row), weight (how much does additional space propagate to this row) and pad (how much space to let additionally).""" return self._grid_configure('rowconfigure', index, cnf, kw) rowconfigure = grid_rowconfigure def grid_size(self): """Return a tuple of the number of column and rows in the grid.""" return self._getints( self.tk.call('grid', 'size', self._w)) or None size = grid_size def grid_slaves(self, row=None, column=None): """Return a list of all slaves of this widget in its packing order.""" args = () if row is not None: args = args + ('-row', row) if column is not None: args = args + ('-column', column) return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call( ('grid', 'slaves', self._w) + args))] # Support for the "event" command, new in Tk 4.2. # By Case Roole. def event_add(self, virtual, *sequences): """Bind a virtual event VIRTUAL (of the form <>) to an event SEQUENCE such that the virtual event is triggered whenever SEQUENCE occurs.""" args = ('event', 'add', virtual) + sequences self.tk.call(args) def event_delete(self, virtual, *sequences): """Unbind a virtual event VIRTUAL from SEQUENCE.""" args = ('event', 'delete', virtual) + sequences self.tk.call(args) def event_generate(self, sequence, **kw): """Generate an event SEQUENCE. Additional keyword arguments specify parameter of the event (e.g. x, y, rootx, rooty).""" args = ('event', 'generate', self._w, sequence) for k, v in kw.items(): args = args + ('-%s' % k, str(v)) self.tk.call(args) def event_info(self, virtual=None): """Return a list of all virtual events or the information about the SEQUENCE bound to the virtual event VIRTUAL.""" return self.tk.splitlist( self.tk.call('event', 'info', virtual)) # Image related commands def image_names(self): """Return a list of all existing image names.""" return self.tk.splitlist(self.tk.call('image', 'names')) def image_types(self): """Return a list of all available image types (e.g. photo bitmap).""" return self.tk.splitlist(self.tk.call('image', 'types')) class CallWrapper: """Internal class. Stores function to call when some user defined Tcl function is called e.g. after an event occurred.""" def __init__(self, func, subst, widget): """Store FUNC, SUBST and WIDGET as members.""" self.func = func self.subst = subst self.widget = widget def __call__(self, *args): """Apply first function SUBST to arguments, than FUNC.""" try: if self.subst: args = self.subst(*args) return self.func(*args) except SystemExit: raise except: self.widget._report_exception() class XView: """Mix-in class for querying and changing the horizontal position of a widget's window.""" def xview(self, *args): """Query and change the horizontal position of the view.""" res = self.tk.call(self._w, 'xview', *args) if not args: return self._getdoubles(res) def xview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total width of the canvas is off-screen to the left.""" self.tk.call(self._w, 'xview', 'moveto', fraction) def xview_scroll(self, number, what): """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'xview', 'scroll', number, what) class YView: """Mix-in class for querying and changing the vertical position of a widget's window.""" def yview(self, *args): """Query and change the vertical position of the view.""" res = self.tk.call(self._w, 'yview', *args) if not args: return self._getdoubles(res) def yview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total height of the canvas is off-screen to the top.""" self.tk.call(self._w, 'yview', 'moveto', fraction) def yview_scroll(self, number, what): """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'yview', 'scroll', number, what) class Wm: """Provides functions for the communication with the window manager.""" def wm_aspect(self, minNumer=None, minDenom=None, maxNumer=None, maxDenom=None): """Instruct the window manager to set the aspect ratio (width/height) of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple of the actual values if no argument is given.""" return self._getints( self.tk.call('wm', 'aspect', self._w, minNumer, minDenom, maxNumer, maxDenom)) aspect = wm_aspect def wm_attributes(self, *args): """This subcommand returns or sets platform specific attributes The first form returns a list of the platform specific flags and their values. The second form returns the value for the specific option. The third form sets one or more of the values. The values are as follows: On Windows, -disabled gets or sets whether the window is in a disabled state. -toolwindow gets or sets the style of the window to toolwindow (as defined in the MSDN). -topmost gets or sets whether this is a topmost window (displays above all other windows). On Macintosh, XXXXX On Unix, there are currently no special attribute values. """ args = ('wm', 'attributes', self._w) + args return self.tk.call(args) attributes = wm_attributes def wm_client(self, name=None): """Store NAME in WM_CLIENT_MACHINE property of this widget. Return current value.""" return self.tk.call('wm', 'client', self._w, name) client = wm_client def wm_colormapwindows(self, *wlist): """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property of this widget. This list contains windows whose colormaps differ from their parents. Return current list of widgets if WLIST is empty.""" if len(wlist) > 1: wlist = (wlist,) # Tk needs a list of windows here args = ('wm', 'colormapwindows', self._w) + wlist if wlist: self.tk.call(args) else: return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call(args))] colormapwindows = wm_colormapwindows def wm_command(self, value=None): """Store VALUE in WM_COMMAND property. It is the command which shall be used to invoke the application. Return current command if VALUE is None.""" return self.tk.call('wm', 'command', self._w, value) command = wm_command def wm_deiconify(self): """Deiconify this widget. If it was never mapped it will not be mapped. On Windows it will raise this widget and give it the focus.""" return self.tk.call('wm', 'deiconify', self._w) deiconify = wm_deiconify def wm_focusmodel(self, model=None): """Set focus model to MODEL. "active" means that this widget will claim the focus itself, "passive" means that the window manager shall give the focus. Return current focus model if MODEL is None.""" return self.tk.call('wm', 'focusmodel', self._w, model) focusmodel = wm_focusmodel def wm_forget(self, window): # new in Tk 8.5 """The window will be unmapped from the screen and will no longer be managed by wm. toplevel windows will be treated like frame windows once they are no longer managed by wm, however, the menu option configuration will be remembered and the menus will return once the widget is managed again.""" self.tk.call('wm', 'forget', window) forget = wm_forget def wm_frame(self): """Return identifier for decorative frame of this widget if present.""" return self.tk.call('wm', 'frame', self._w) frame = wm_frame def wm_geometry(self, newGeometry=None): """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return current value if None is given.""" return self.tk.call('wm', 'geometry', self._w, newGeometry) geometry = wm_geometry def wm_grid(self, baseWidth=None, baseHeight=None, widthInc=None, heightInc=None): """Instruct the window manager that this widget shall only be resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the number of grid units requested in Tk_GeometryRequest.""" return self._getints(self.tk.call( 'wm', 'grid', self._w, baseWidth, baseHeight, widthInc, heightInc)) grid = wm_grid def wm_group(self, pathName=None): """Set the group leader widgets for related widgets to PATHNAME. Return the group leader of this widget if None is given.""" return self.tk.call('wm', 'group', self._w, pathName) group = wm_group def wm_iconbitmap(self, bitmap=None, default=None): """Set bitmap for the iconified widget to BITMAP. Return the bitmap if None is given. Under Windows, the DEFAULT parameter can be used to set the icon for the widget and any descendents that don't have an icon set explicitly. DEFAULT can be the relative path to a .ico file (example: root.iconbitmap(default='myicon.ico') ). See Tk documentation for more information.""" if default: return self.tk.call('wm', 'iconbitmap', self._w, '-default', default) else: return self.tk.call('wm', 'iconbitmap', self._w, bitmap) iconbitmap = wm_iconbitmap def wm_iconify(self): """Display widget as icon.""" return self.tk.call('wm', 'iconify', self._w) iconify = wm_iconify def wm_iconmask(self, bitmap=None): """Set mask for the icon bitmap of this widget. Return the mask if None is given.""" return self.tk.call('wm', 'iconmask', self._w, bitmap) iconmask = wm_iconmask def wm_iconname(self, newName=None): """Set the name of the icon for this widget. Return the name if None is given.""" return self.tk.call('wm', 'iconname', self._w, newName) iconname = wm_iconname def wm_iconphoto(self, default=False, *args): # new in Tk 8.5 """Sets the titlebar icon for this window based on the named photo images passed through args. If default is True, this is applied to all future created toplevels as well. The data in the images is taken as a snapshot at the time of invocation. If the images are later changed, this is not reflected to the titlebar icons. Multiple images are accepted to allow different images sizes to be provided. The window manager may scale provided icons to an appropriate size. On Windows, the images are packed into a Windows icon structure. This will override an icon specified to wm_iconbitmap, and vice versa. On X, the images are arranged into the _NET_WM_ICON X property, which most modern window managers support. An icon specified by wm_iconbitmap may exist simultaneously. On Macintosh, this currently does nothing.""" if default: self.tk.call('wm', 'iconphoto', self._w, "-default", *args) else: self.tk.call('wm', 'iconphoto', self._w, *args) iconphoto = wm_iconphoto def wm_iconposition(self, x=None, y=None): """Set the position of the icon of this widget to X and Y. Return a tuple of the current values of X and X if None is given.""" return self._getints(self.tk.call( 'wm', 'iconposition', self._w, x, y)) iconposition = wm_iconposition def wm_iconwindow(self, pathName=None): """Set widget PATHNAME to be displayed instead of icon. Return the current value if None is given.""" return self.tk.call('wm', 'iconwindow', self._w, pathName) iconwindow = wm_iconwindow def wm_manage(self, widget): # new in Tk 8.5 """The widget specified will become a stand alone top-level window. The window will be decorated with the window managers title bar, etc.""" self.tk.call('wm', 'manage', widget) manage = wm_manage def wm_maxsize(self, width=None, height=None): """Set max WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'maxsize', self._w, width, height)) maxsize = wm_maxsize def wm_minsize(self, width=None, height=None): """Set min WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'minsize', self._w, width, height)) minsize = wm_minsize def wm_overrideredirect(self, boolean=None): """Instruct the window manager to ignore this widget if BOOLEAN is given with 1. Return the current value if None is given.""" return self._getboolean(self.tk.call( 'wm', 'overrideredirect', self._w, boolean)) overrideredirect = wm_overrideredirect def wm_positionfrom(self, who=None): """Instruct the window manager that the position of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'positionfrom', self._w, who) positionfrom = wm_positionfrom def wm_protocol(self, name=None, func=None): """Bind function FUNC to command NAME for this widget. Return the function bound to NAME if None is given. NAME could be e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" if callable(func): command = self._register(func) else: command = func return self.tk.call( 'wm', 'protocol', self._w, name, command) protocol = wm_protocol def wm_resizable(self, width=None, height=None): """Instruct the window manager whether this width can be resized in WIDTH or HEIGHT. Both values are boolean values.""" return self.tk.call('wm', 'resizable', self._w, width, height) resizable = wm_resizable def wm_sizefrom(self, who=None): """Instruct the window manager that the size of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'sizefrom', self._w, who) sizefrom = wm_sizefrom def wm_state(self, newstate=None): """Query or set the state of this widget as one of normal, icon, iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" return self.tk.call('wm', 'state', self._w, newstate) state = wm_state def wm_title(self, string=None): """Set the title of this widget.""" return self.tk.call('wm', 'title', self._w, string) title = wm_title def wm_transient(self, master=None): """Instruct the window manager that this widget is transient with regard to widget MASTER.""" return self.tk.call('wm', 'transient', self._w, master) transient = wm_transient def wm_withdraw(self): """Withdraw this widget from the screen such that it is unmapped and forgotten by the window manager. Re-draw it with wm_deiconify.""" return self.tk.call('wm', 'withdraw', self._w) withdraw = wm_withdraw class Tk(Misc, Wm): """Toplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.""" _w = '.' def __init__(self, screenName=None, baseName=None, className='Tk', useTk=1, sync=0, use=None): """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will be created. BASENAME will be used for the identification of the profile file (see readprofile). It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME is the name of the widget class.""" self.master = None self.children = {} self._tkloaded = False # to avoid recursions in the getattr code in case of failure, we # ensure that self.tk is always _something_. self.tk = None if baseName is None: import os baseName = os.path.basename(sys.argv[0]) baseName, ext = os.path.splitext(baseName) if ext not in ('.py', '.pyc'): baseName = baseName + ext interactive = 0 self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) if useTk: self._loadtk() if not sys.flags.ignore_environment: # Issue #16248: Honor the -E flag to avoid code injection. self.readprofile(baseName, className) def loadtk(self): if not self._tkloaded: self.tk.loadtk() self._loadtk() def _loadtk(self): self._tkloaded = True global _default_root # Version sanity checks tk_version = self.tk.getvar('tk_version') if tk_version != _tkinter.TK_VERSION: raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)" % (_tkinter.TK_VERSION, tk_version)) # Under unknown circumstances, tcl_version gets coerced to float tcl_version = str(self.tk.getvar('tcl_version')) if tcl_version != _tkinter.TCL_VERSION: raise RuntimeError("tcl.h version (%s) doesn't match libtcl.a version (%s)" \ % (_tkinter.TCL_VERSION, tcl_version)) # Create and register the tkerror and exit commands # We need to inline parts of _register here, _ register # would register differently-named commands. if self._tclCommands is None: self._tclCommands = [] self.tk.createcommand('tkerror', _tkerror) self.tk.createcommand('exit', _exit) self._tclCommands.append('tkerror') self._tclCommands.append('exit') if _support_default_root and not _default_root: _default_root = self self.protocol("WM_DELETE_WINDOW", self.destroy) def destroy(self): """Destroy this and all descendants widgets. This will end the application of this Tcl interpreter.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) Misc.destroy(self) global _default_root if _support_default_root and _default_root is self: _default_root = None def readprofile(self, baseName, className): """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into the Tcl Interpreter and calls exec on the contents of BASENAME.py and CLASSNAME.py if such a file exists in the home directory.""" import os if 'HOME' in os.environ: home = os.environ['HOME'] else: home = os.curdir class_tcl = os.path.join(home, '.%s.tcl' % className) class_py = os.path.join(home, '.%s.py' % className) base_tcl = os.path.join(home, '.%s.tcl' % baseName) base_py = os.path.join(home, '.%s.py' % baseName) dir = {'self': self} exec('from tkinter import *', dir) if os.path.isfile(class_tcl): self.tk.call('source', class_tcl) if os.path.isfile(class_py): exec(open(class_py).read(), dir) if os.path.isfile(base_tcl): self.tk.call('source', base_tcl) if os.path.isfile(base_py): exec(open(base_py).read(), dir) def report_callback_exception(self, exc, val, tb): """Report callback exception on sys.stderr. Applications may want to override this internal function, and should when sys.stderr is None.""" import traceback print("Exception in Tkinter callback", file=sys.stderr) sys.last_type = exc sys.last_value = val sys.last_traceback = tb traceback.print_exception(exc, val, tb) def __getattr__(self, attr): "Delegate attribute access to the interpreter object" return getattr(self.tk, attr) # Ideally, the classes Pack, Place and Grid disappear, the # pack/place/grid methods are defined on the Widget class, and # everybody uses w.pack_whatever(...) instead of Pack.whatever(w, # ...), with pack(), place() and grid() being short for # pack_configure(), place_configure() and grid_columnconfigure(), and # forget() being short for pack_forget(). As a practical matter, I'm # afraid that there is too much code out there that may be using the # Pack, Place or Grid class, so I leave them intact -- but only as # backwards compatibility features. Also note that those methods that # take a master as argument (e.g. pack_propagate) have been moved to # the Misc class (which now incorporates all methods common between # toplevel and interior widgets). Again, for compatibility, these are # copied into the Pack, Place or Grid class. def Tcl(screenName=None, baseName=None, className='Tk', useTk=0): return Tk(screenName, baseName, className, useTk) class Pack: """Geometry manager Pack. Base class to use the methods pack_* in every widget.""" def pack_configure(self, cnf={}, **kw): """Pack a widget in the parent widget. Use as options: after=widget - pack it after you have packed widget anchor=NSEW (or subset) - position widget according to given direction before=widget - pack it before you will pack widget expand=bool - expand widget if parent size grows fill=NONE or X or Y or BOTH - fill widget if widget grows in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. """ self.tk.call( ('pack', 'configure', self._w) + self._options(cnf, kw)) pack = configure = config = pack_configure def pack_forget(self): """Unmap this widget and do not use it for the packing order.""" self.tk.call('pack', 'forget', self._w) forget = pack_forget def pack_info(self): """Return information about the packing options for this widget.""" d = _splitdict(self.tk, self.tk.call('pack', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = pack_info propagate = pack_propagate = Misc.pack_propagate slaves = pack_slaves = Misc.pack_slaves class Place: """Geometry manager Place. Base class to use the methods place_* in every widget.""" def place_configure(self, cnf={}, **kw): """Place a widget in the parent widget. Use as options: in=master - master relative to which the widget is placed in_=master - see 'in' option description x=amount - locate anchor of this widget at position x of master y=amount - locate anchor of this widget at position y of master relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge) rely=amount - locate anchor of this widget between 0.0 and 1.0 relative to height of master (1.0 is bottom edge) anchor=NSEW (or subset) - position anchor according to given direction width=amount - width of this widget in pixel height=amount - height of this widget in pixel relwidth=amount - width of this widget between 0.0 and 1.0 relative to width of master (1.0 is the same width as the master) relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master) bordermode="inside" or "outside" - whether to take border width of master widget into account """ self.tk.call( ('place', 'configure', self._w) + self._options(cnf, kw)) place = configure = config = place_configure def place_forget(self): """Unmap this widget.""" self.tk.call('place', 'forget', self._w) forget = place_forget def place_info(self): """Return information about the placing options for this widget.""" d = _splitdict(self.tk, self.tk.call('place', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = place_info slaves = place_slaves = Misc.place_slaves class Grid: """Geometry manager Grid. Base class to use the methods grid_* in every widget.""" # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) def grid_configure(self, cnf={}, **kw): """Position a widget in the parent widget in a grid. Use as options: column=number - use cell identified with given column (starting with 0) columnspan=number - this widget will span several columns in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction row=number - use cell identified with given row (starting with 0) rowspan=number - this widget will span several rows sticky=NSEW - if cell is larger on which sides will this widget stick to the cell boundary """ self.tk.call( ('grid', 'configure', self._w) + self._options(cnf, kw)) grid = configure = config = grid_configure bbox = grid_bbox = Misc.grid_bbox columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure def grid_forget(self): """Unmap this widget.""" self.tk.call('grid', 'forget', self._w) forget = grid_forget def grid_remove(self): """Unmap this widget but remember the grid options.""" self.tk.call('grid', 'remove', self._w) def grid_info(self): """Return information about the options for positioning this widget in a grid.""" d = _splitdict(self.tk, self.tk.call('grid', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = grid_info location = grid_location = Misc.grid_location propagate = grid_propagate = Misc.grid_propagate rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure size = grid_size = Misc.grid_size slaves = grid_slaves = Misc.grid_slaves class BaseWidget(Misc): """Internal class.""" def _setup(self, master, cnf): """Internal function. Sets up information about children.""" if not master: master = _get_default_root() self.master = master self.tk = master.tk name = None if 'name' in cnf: name = cnf['name'] del cnf['name'] if not name: name = self.__class__.__name__.lower() if master._last_child_ids is None: master._last_child_ids = {} count = master._last_child_ids.get(name, 0) + 1 master._last_child_ids[name] = count if count == 1: name = '!%s' % (name,) else: name = '!%s%d' % (name, count) self._name = name if master._w=='.': self._w = '.' + name else: self._w = master._w + '.' + name self.children = {} if self._name in self.master.children: self.master.children[self._name].destroy() self.master.children[self._name] = self def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): """Construct a widget with the parent widget MASTER, a name WIDGETNAME and appropriate options.""" if kw: cnf = _cnfmerge((cnf, kw)) self.widgetName = widgetName BaseWidget._setup(self, master, cnf) if self._tclCommands is None: self._tclCommands = [] classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)] for k, v in classes: del cnf[k] self.tk.call( (widgetName, self._w) + extra + self._options(cnf)) for k, v in classes: k.configure(self, v) def destroy(self): """Destroy this and all descendants widgets.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) if self._name in self.master.children: del self.master.children[self._name] Misc.destroy(self) def _do(self, name, args=()): # XXX Obsolete -- better use self.tk.call directly! return self.tk.call((self._w, name) + args) class Widget(BaseWidget, Pack, Place, Grid): """Internal class. Base class for a widget which can be positioned with the geometry managers Pack, Place or Grid.""" pass class Toplevel(BaseWidget, Wm): """Toplevel widget, e.g. for dialogs.""" def __init__(self, master=None, cnf={}, **kw): """Construct a toplevel widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, menu, relief, screen, takefocus, use, visual, width.""" if kw: cnf = _cnfmerge((cnf, kw)) extra = () for wmkey in ['screen', 'class_', 'class', 'visual', 'colormap']: if wmkey in cnf: val = cnf[wmkey] # TBD: a hack needed because some keys # are not valid as keyword arguments if wmkey[-1] == '_': opt = '-'+wmkey[:-1] else: opt = '-'+wmkey extra = extra + (opt, val) del cnf[wmkey] BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) root = self._root() self.iconname(root.iconname()) self.title(root.title()) self.protocol("WM_DELETE_WINDOW", self.destroy) class Button(Widget): """Button widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a button widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, repeatdelay, repeatinterval, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS command, compound, default, height, overrelief, state, width """ Widget.__init__(self, master, 'button', cnf, kw) def flash(self): """Flash the button. This is accomplished by redisplaying the button several times, alternating between active and normal colors. At the end of the flash the button is left in the same normal/active state as when the command was invoked. This command is ignored if the button's state is disabled. """ self.tk.call(self._w, 'flash') def invoke(self): """Invoke the command associated with the button. The return value is the return value from the command, or an empty string if there is no command associated with the button. This command is ignored if the button's state is disabled. """ return self.tk.call(self._w, 'invoke') class Canvas(Widget, XView, YView): """Canvas widget to display graphical elements like lines or text.""" def __init__(self, master=None, cnf={}, **kw): """Construct a canvas widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, closeenough, confine, cursor, height, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, offset, relief, scrollregion, selectbackground, selectborderwidth, selectforeground, state, takefocus, width, xscrollcommand, xscrollincrement, yscrollcommand, yscrollincrement.""" Widget.__init__(self, master, 'canvas', cnf, kw) def addtag(self, *args): """Internal function.""" self.tk.call((self._w, 'addtag') + args) def addtag_above(self, newtag, tagOrId): """Add tag NEWTAG to all items above TAGORID.""" self.addtag(newtag, 'above', tagOrId) def addtag_all(self, newtag): """Add tag NEWTAG to all items.""" self.addtag(newtag, 'all') def addtag_below(self, newtag, tagOrId): """Add tag NEWTAG to all items below TAGORID.""" self.addtag(newtag, 'below', tagOrId) def addtag_closest(self, newtag, x, y, halo=None, start=None): """Add tag NEWTAG to item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closests). If START is specified the next below this tag is taken.""" self.addtag(newtag, 'closest', x, y, halo, start) def addtag_enclosed(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items in the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'enclosed', x1, y1, x2, y2) def addtag_overlapping(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'overlapping', x1, y1, x2, y2) def addtag_withtag(self, newtag, tagOrId): """Add tag NEWTAG to all items with TAGORID.""" self.addtag(newtag, 'withtag', tagOrId) def bbox(self, *args): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses all items with tags specified as arguments.""" return self._getints( self.tk.call((self._w, 'bbox') + args)) or None def tag_unbind(self, tagOrId, sequence, funcid=None): """Unbind for all items with TAGORID for event SEQUENCE the function identified with FUNCID.""" self.tk.call(self._w, 'bind', tagOrId, sequence, '') if funcid: self.deletecommand(funcid) def tag_bind(self, tagOrId, sequence=None, func=None, add=None): """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'bind', tagOrId), sequence, func, add) def canvasx(self, screenx, gridspacing=None): """Return the canvas x coordinate of pixel position SCREENX rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasx', screenx, gridspacing)) def canvasy(self, screeny, gridspacing=None): """Return the canvas y coordinate of pixel position SCREENY rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasy', screeny, gridspacing)) def coords(self, *args): """Return a list of coordinates for the item given in ARGS.""" # XXX Should use _flatten on args return [self.tk.getdouble(x) for x in self.tk.splitlist( self.tk.call((self._w, 'coords') + args))] def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) """Internal function.""" args = _flatten(args) cnf = args[-1] if isinstance(cnf, (dict, tuple)): args = args[:-1] else: cnf = {} return self.tk.getint(self.tk.call( self._w, 'create', itemType, *(args + self._options(cnf, kw)))) def create_arc(self, *args, **kw): """Create arc shaped region with coordinates x1,y1,x2,y2.""" return self._create('arc', args, kw) def create_bitmap(self, *args, **kw): """Create bitmap with coordinates x1,y1.""" return self._create('bitmap', args, kw) def create_image(self, *args, **kw): """Create image item with coordinates x1,y1.""" return self._create('image', args, kw) def create_line(self, *args, **kw): """Create line with coordinates x1,y1,...,xn,yn.""" return self._create('line', args, kw) def create_oval(self, *args, **kw): """Create oval with coordinates x1,y1,x2,y2.""" return self._create('oval', args, kw) def create_polygon(self, *args, **kw): """Create polygon with coordinates x1,y1,...,xn,yn.""" return self._create('polygon', args, kw) def create_rectangle(self, *args, **kw): """Create rectangle with coordinates x1,y1,x2,y2.""" return self._create('rectangle', args, kw) def create_text(self, *args, **kw): """Create text with coordinates x1,y1.""" return self._create('text', args, kw) def create_window(self, *args, **kw): """Create window with coordinates x1,y1,x2,y2.""" return self._create('window', args, kw) def dchars(self, *args): """Delete characters of text items identified by tag or id in ARGS (possibly several times) from FIRST to LAST character (including).""" self.tk.call((self._w, 'dchars') + args) def delete(self, *args): """Delete items identified by all tag or ids contained in ARGS.""" self.tk.call((self._w, 'delete') + args) def dtag(self, *args): """Delete tag or id given as last arguments in ARGS from items identified by first argument in ARGS.""" self.tk.call((self._w, 'dtag') + args) def find(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'find') + args)) or () def find_above(self, tagOrId): """Return items above TAGORID.""" return self.find('above', tagOrId) def find_all(self): """Return all items.""" return self.find('all') def find_below(self, tagOrId): """Return all items below TAGORID.""" return self.find('below', tagOrId) def find_closest(self, x, y, halo=None, start=None): """Return item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.""" return self.find('closest', x, y, halo, start) def find_enclosed(self, x1, y1, x2, y2): """Return all items in rectangle defined by X1,Y1,X2,Y2.""" return self.find('enclosed', x1, y1, x2, y2) def find_overlapping(self, x1, y1, x2, y2): """Return all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" return self.find('overlapping', x1, y1, x2, y2) def find_withtag(self, tagOrId): """Return all items with TAGORID.""" return self.find('withtag', tagOrId) def focus(self, *args): """Set focus to the first item specified in ARGS.""" return self.tk.call((self._w, 'focus') + args) def gettags(self, *args): """Return tags associated with the first item specified in ARGS.""" return self.tk.splitlist( self.tk.call((self._w, 'gettags') + args)) def icursor(self, *args): """Set cursor at position POS in the item identified by TAGORID. In ARGS TAGORID must be first.""" self.tk.call((self._w, 'icursor') + args) def index(self, *args): """Return position of cursor as integer in item specified in ARGS.""" return self.tk.getint(self.tk.call((self._w, 'index') + args)) def insert(self, *args): """Insert TEXT in item TAGORID at position POS. ARGS must be TAGORID POS TEXT.""" self.tk.call((self._w, 'insert') + args) def itemcget(self, tagOrId, option): """Return the resource value for an OPTION for item TAGORID.""" return self.tk.call( (self._w, 'itemcget') + (tagOrId, '-'+option)) def itemconfigure(self, tagOrId, cnf=None, **kw): """Configure resources of an item TAGORID. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. """ return self._configure(('itemconfigure', tagOrId), cnf, kw) itemconfig = itemconfigure # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, # so the preferred name for them is tag_lower, tag_raise # (similar to tag_bind, and similar to the Text widget); # unfortunately can't delete the old ones yet (maybe in 1.6) def tag_lower(self, *args): """Lower an item TAGORID given in ARGS (optional below another item).""" self.tk.call((self._w, 'lower') + args) lower = tag_lower def move(self, *args): """Move an item TAGORID given in ARGS.""" self.tk.call((self._w, 'move') + args) def moveto(self, tagOrId, x='', y=''): """Move the items given by TAGORID in the canvas coordinate space so that the first coordinate pair of the bottommost item with tag TAGORID is located at position (X,Y). X and Y may be the empty string, in which case the corresponding coordinate will be unchanged. All items matching TAGORID remain in the same positions relative to each other.""" self.tk.call(self._w, 'moveto', tagOrId, x, y) def postscript(self, cnf={}, **kw): """Print the contents of the canvas to a postscript file. Valid options: colormap, colormode, file, fontmap, height, pageanchor, pageheight, pagewidth, pagex, pagey, rotate, width, x, y.""" return self.tk.call((self._w, 'postscript') + self._options(cnf, kw)) def tag_raise(self, *args): """Raise an item TAGORID given in ARGS (optional above another item).""" self.tk.call((self._w, 'raise') + args) lift = tkraise = tag_raise def scale(self, *args): """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" self.tk.call((self._w, 'scale') + args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y, gain=10): """Adjust the view of the canvas to GAIN times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y, gain) def select_adjust(self, tagOrId, index): """Adjust the end of the selection near the cursor of an item TAGORID to index.""" self.tk.call(self._w, 'select', 'adjust', tagOrId, index) def select_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'select', 'clear') def select_from(self, tagOrId, index): """Set the fixed end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'from', tagOrId, index) def select_item(self): """Return the item which has the selection.""" return self.tk.call(self._w, 'select', 'item') or None def select_to(self, tagOrId, index): """Set the variable end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'to', tagOrId, index) def type(self, tagOrId): """Return the type of the item TAGORID.""" return self.tk.call(self._w, 'type', tagOrId) or None class Checkbutton(Widget): """Checkbutton widget which is either in on- or off-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a checkbutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, offvalue, onvalue, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, variable, width, wraplength.""" Widget.__init__(self, master, 'checkbutton', cnf, kw) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') def toggle(self): """Toggle the button.""" self.tk.call(self._w, 'toggle') class Entry(Widget, XView): """Entry widget which allows displaying simple text.""" def __init__(self, master=None, cnf={}, **kw): """Construct an entry widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, invalidcommand, invcmd, justify, relief, selectbackground, selectborderwidth, selectforeground, show, state, takefocus, textvariable, validate, validatecommand, vcmd, width, xscrollcommand.""" Widget.__init__(self, master, 'entry', cnf, kw) def delete(self, first, last=None): """Delete text from FIRST to LAST (not included).""" self.tk.call(self._w, 'delete', first, last) def get(self): """Return the text.""" return self.tk.call(self._w, 'get') def icursor(self, index): """Insert cursor at INDEX.""" self.tk.call(self._w, 'icursor', index) def index(self, index): """Return position of cursor.""" return self.tk.getint(self.tk.call( self._w, 'index', index)) def insert(self, index, string): """Insert STRING at INDEX.""" self.tk.call(self._w, 'insert', index, string) def scan_mark(self, x): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x) def scan_dragto(self, x): """Adjust the view of the canvas to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x) def selection_adjust(self, index): """Adjust the end of the selection near the cursor to INDEX.""" self.tk.call(self._w, 'selection', 'adjust', index) select_adjust = selection_adjust def selection_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'selection', 'clear') select_clear = selection_clear def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'from', index) select_from = selection_from def selection_present(self): """Return True if there are characters selected in the entry, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) select_present = selection_present def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.tk.call(self._w, 'selection', 'range', start, end) select_range = selection_range def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'to', index) select_to = selection_to class Frame(Widget): """Frame widget which may contain other widgets and can have a 3D border.""" def __init__(self, master=None, cnf={}, **kw): """Construct a frame widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.""" cnf = _cnfmerge((cnf, kw)) extra = () if 'class_' in cnf: extra = ('-class', cnf['class_']) del cnf['class_'] elif 'class' in cnf: extra = ('-class', cnf['class']) del cnf['class'] Widget.__init__(self, master, 'frame', cnf, {}, extra) class Label(Widget): """Label widget which can display text and bitmaps.""" def __init__(self, master=None, cnf={}, **kw): """Construct a label widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground, highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS height, state, width """ Widget.__init__(self, master, 'label', cnf, kw) class Listbox(Widget, XView, YView): """Listbox widget which can display a list of strings.""" def __init__(self, master=None, cnf={}, **kw): """Construct a listbox widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, relief, selectbackground, selectborderwidth, selectforeground, selectmode, setgrid, takefocus, width, xscrollcommand, yscrollcommand, listvariable.""" Widget.__init__(self, master, 'listbox', cnf, kw) def activate(self, index): """Activate item identified by INDEX.""" self.tk.call(self._w, 'activate', index) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the item identified by the given index.""" return self._getints(self.tk.call(self._w, 'bbox', index)) or None def curselection(self): """Return the indices of currently selected item.""" return self._getints(self.tk.call(self._w, 'curselection')) or () def delete(self, first, last=None): """Delete items from FIRST to LAST (included).""" self.tk.call(self._w, 'delete', first, last) def get(self, first, last=None): """Get list of items from FIRST to LAST (included).""" if last is not None: return self.tk.splitlist(self.tk.call( self._w, 'get', first, last)) else: return self.tk.call(self._w, 'get', first) def index(self, index): """Return index of item identified with INDEX.""" i = self.tk.call(self._w, 'index', index) if i == 'none': return None return self.tk.getint(i) def insert(self, index, *elements): """Insert ELEMENTS at INDEX.""" self.tk.call((self._w, 'insert', index) + elements) def nearest(self, y): """Get index of item which is nearest to y coordinate Y.""" return self.tk.getint(self.tk.call( self._w, 'nearest', y)) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the listbox to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def see(self, index): """Scroll such that INDEX is visible.""" self.tk.call(self._w, 'see', index) def selection_anchor(self, index): """Set the fixed end oft the selection to INDEX.""" self.tk.call(self._w, 'selection', 'anchor', index) select_anchor = selection_anchor def selection_clear(self, first, last=None): """Clear the selection from FIRST to LAST (included).""" self.tk.call(self._w, 'selection', 'clear', first, last) select_clear = selection_clear def selection_includes(self, index): """Return True if INDEX is part of the selection.""" return self.tk.getboolean(self.tk.call( self._w, 'selection', 'includes', index)) select_includes = selection_includes def selection_set(self, first, last=None): """Set the selection from FIRST to LAST (included) without changing the currently selected elements.""" self.tk.call(self._w, 'selection', 'set', first, last) select_set = selection_set def size(self): """Return the number of elements in the listbox.""" return self.tk.getint(self.tk.call(self._w, 'size')) def itemcget(self, index, option): """Return the resource value for an ITEM and an OPTION.""" return self.tk.call( (self._w, 'itemcget') + (index, '-'+option)) def itemconfigure(self, index, cnf=None, **kw): """Configure resources of an ITEM. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. Valid resource names: background, bg, foreground, fg, selectbackground, selectforeground.""" return self._configure(('itemconfigure', index), cnf, kw) itemconfig = itemconfigure class Menu(Widget): """Menu widget which allows displaying menu bars, pull-down menus and pop-up menus.""" def __init__(self, master=None, cnf={}, **kw): """Construct menu widget with the parent MASTER. Valid resource names: activebackground, activeborderwidth, activeforeground, background, bd, bg, borderwidth, cursor, disabledforeground, fg, font, foreground, postcommand, relief, selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" Widget.__init__(self, master, 'menu', cnf, kw) def tk_popup(self, x, y, entry=""): """Post the menu at position X,Y with entry ENTRY.""" self.tk.call('tk_popup', self._w, x, y, entry) def activate(self, index): """Activate entry at INDEX.""" self.tk.call(self._w, 'activate', index) def add(self, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'add', itemType) + self._options(cnf, kw)) def add_cascade(self, cnf={}, **kw): """Add hierarchical menu item.""" self.add('cascade', cnf or kw) def add_checkbutton(self, cnf={}, **kw): """Add checkbutton menu item.""" self.add('checkbutton', cnf or kw) def add_command(self, cnf={}, **kw): """Add command menu item.""" self.add('command', cnf or kw) def add_radiobutton(self, cnf={}, **kw): """Addd radio menu item.""" self.add('radiobutton', cnf or kw) def add_separator(self, cnf={}, **kw): """Add separator.""" self.add('separator', cnf or kw) def insert(self, index, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'insert', index, itemType) + self._options(cnf, kw)) def insert_cascade(self, index, cnf={}, **kw): """Add hierarchical menu item at INDEX.""" self.insert(index, 'cascade', cnf or kw) def insert_checkbutton(self, index, cnf={}, **kw): """Add checkbutton menu item at INDEX.""" self.insert(index, 'checkbutton', cnf or kw) def insert_command(self, index, cnf={}, **kw): """Add command menu item at INDEX.""" self.insert(index, 'command', cnf or kw) def insert_radiobutton(self, index, cnf={}, **kw): """Addd radio menu item at INDEX.""" self.insert(index, 'radiobutton', cnf or kw) def insert_separator(self, index, cnf={}, **kw): """Add separator at INDEX.""" self.insert(index, 'separator', cnf or kw) def delete(self, index1, index2=None): """Delete menu items between INDEX1 and INDEX2 (included).""" if index2 is None: index2 = index1 num_index1, num_index2 = self.index(index1), self.index(index2) if (num_index1 is None) or (num_index2 is None): num_index1, num_index2 = 0, -1 for i in range(num_index1, num_index2 + 1): if 'command' in self.entryconfig(i): c = str(self.entrycget(i, 'command')) if c: self.deletecommand(c) self.tk.call(self._w, 'delete', index1, index2) def entrycget(self, index, option): """Return the resource value of a menu item for OPTION at INDEX.""" return self.tk.call(self._w, 'entrycget', index, '-' + option) def entryconfigure(self, index, cnf=None, **kw): """Configure a menu item at INDEX.""" return self._configure(('entryconfigure', index), cnf, kw) entryconfig = entryconfigure def index(self, index): """Return the index of a menu item identified by INDEX.""" i = self.tk.call(self._w, 'index', index) if i == 'none': return None return self.tk.getint(i) def invoke(self, index): """Invoke a menu item identified by INDEX and execute the associated command.""" return self.tk.call(self._w, 'invoke', index) def post(self, x, y): """Display a menu at position X,Y.""" self.tk.call(self._w, 'post', x, y) def type(self, index): """Return the type of the menu item at INDEX.""" return self.tk.call(self._w, 'type', index) def unpost(self): """Unmap a menu.""" self.tk.call(self._w, 'unpost') def xposition(self, index): # new in Tk 8.5 """Return the x-position of the leftmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call(self._w, 'xposition', index)) def yposition(self, index): """Return the y-position of the topmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call( self._w, 'yposition', index)) class Menubutton(Widget): """Menubutton widget, obsolete since Tk8.0.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'menubutton', cnf, kw) class Message(Widget): """Message widget to display multiline text. Obsolete since Label does it too.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'message', cnf, kw) class Radiobutton(Widget): """Radiobutton widget which shows only one of several buttons in on-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a radiobutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, value, variable, width, wraplength.""" Widget.__init__(self, master, 'radiobutton', cnf, kw) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') class Scale(Widget): """Scale widget which can display a numerical scale.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scale widget with the parent MASTER. Valid resource names: activebackground, background, bigincrement, bd, bg, borderwidth, command, cursor, digits, fg, font, foreground, from, highlightbackground, highlightcolor, highlightthickness, label, length, orient, relief, repeatdelay, repeatinterval, resolution, showvalue, sliderlength, sliderrelief, state, takefocus, tickinterval, to, troughcolor, variable, width.""" Widget.__init__(self, master, 'scale', cnf, kw) def get(self): """Get the current value as integer or float.""" value = self.tk.call(self._w, 'get') try: return self.tk.getint(value) except (ValueError, TypeError, TclError): return self.tk.getdouble(value) def set(self, value): """Set the value to VALUE.""" self.tk.call(self._w, 'set', value) def coords(self, value=None): """Return a tuple (X,Y) of the point along the centerline of the trough that corresponds to VALUE or the current value if None is given.""" return self._getints(self.tk.call(self._w, 'coords', value)) def identify(self, x, y): """Return where the point X,Y lies. Valid return values are "slider", "though1" and "though2".""" return self.tk.call(self._w, 'identify', x, y) class Scrollbar(Widget): """Scrollbar widget which displays a slider at a certain position.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scrollbar widget with the parent MASTER. Valid resource names: activebackground, activerelief, background, bd, bg, borderwidth, command, cursor, elementborderwidth, highlightbackground, highlightcolor, highlightthickness, jump, orient, relief, repeatdelay, repeatinterval, takefocus, troughcolor, width.""" Widget.__init__(self, master, 'scrollbar', cnf, kw) def activate(self, index=None): """Marks the element indicated by index as active. The only index values understood by this method are "arrow1", "slider", or "arrow2". If any other value is specified then no element of the scrollbar will be active. If index is not specified, the method returns the name of the element that is currently active, or None if no element is active.""" return self.tk.call(self._w, 'activate', index) or None def delta(self, deltax, deltay): """Return the fractional change of the scrollbar setting if it would be moved by DELTAX or DELTAY pixels.""" return self.tk.getdouble( self.tk.call(self._w, 'delta', deltax, deltay)) def fraction(self, x, y): """Return the fractional value which corresponds to a slider position of X,Y.""" return self.tk.getdouble(self.tk.call(self._w, 'fraction', x, y)) def identify(self, x, y): """Return the element under position X,Y as one of "arrow1","slider","arrow2" or "".""" return self.tk.call(self._w, 'identify', x, y) def get(self): """Return the current fractional values (upper and lower end) of the slider position.""" return self._getdoubles(self.tk.call(self._w, 'get')) def set(self, first, last): """Set the fractional values of the slider position (upper and lower ends as value between 0 and 1).""" self.tk.call(self._w, 'set', first, last) class Text(Widget, XView, YView): """Text widget which can display text in various forms.""" def __init__(self, master=None, cnf={}, **kw): """Construct a text widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, padx, pady, relief, selectbackground, selectborderwidth, selectforeground, setgrid, takefocus, xscrollcommand, yscrollcommand, WIDGET-SPECIFIC OPTIONS autoseparators, height, maxundo, spacing1, spacing2, spacing3, state, tabs, undo, width, wrap, """ Widget.__init__(self, master, 'text', cnf, kw) def bbox(self, index): """Return a tuple of (x,y,width,height) which gives the bounding box of the visible part of the character at the given index.""" return self._getints( self.tk.call(self._w, 'bbox', index)) or None def compare(self, index1, op, index2): """Return whether between index INDEX1 and index INDEX2 the relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" return self.tk.getboolean(self.tk.call( self._w, 'compare', index1, op, index2)) def count(self, index1, index2, *args): # new in Tk 8.5 """Counts the number of relevant things between the two indices. If index1 is after index2, the result will be a negative number (and this holds for each of the possible options). The actual items which are counted depends on the options given by args. The result is a list of integers, one for the result of each counting option given. Valid counting options are "chars", "displaychars", "displayindices", "displaylines", "indices", "lines", "xpixels" and "ypixels". There is an additional possible option "update", which if given then all subsequent options ensure that any possible out of date information is recalculated.""" args = ['-%s' % arg for arg in args if not arg.startswith('-')] args += [index1, index2] res = self.tk.call(self._w, 'count', *args) or None if res is not None and len(args) <= 3: return (res, ) else: return res def debug(self, boolean=None): """Turn on the internal consistency checks of the B-Tree inside the text widget according to BOOLEAN.""" if boolean is None: return self.tk.getboolean(self.tk.call(self._w, 'debug')) self.tk.call(self._w, 'debug', boolean) def delete(self, index1, index2=None): """Delete the characters between INDEX1 and INDEX2 (not included).""" self.tk.call(self._w, 'delete', index1, index2) def dlineinfo(self, index): """Return tuple (x,y,width,height,baseline) giving the bounding box and baseline position of the visible part of the line containing the character at INDEX.""" return self._getints(self.tk.call(self._w, 'dlineinfo', index)) def dump(self, index1, index2=None, command=None, **kw): """Return the contents of the widget between index1 and index2. The type of contents returned in filtered based on the keyword parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are given and true, then the corresponding items are returned. The result is a list of triples of the form (key, value, index). If none of the keywords are true then 'all' is used by default. If the 'command' argument is given, it is called once for each element of the list of triples, with the values of each triple serving as the arguments to the function. In this case the list is not returned.""" args = [] func_name = None result = None if not command: # Never call the dump command without the -command flag, since the # output could involve Tcl quoting and would be a pain to parse # right. Instead just set the command to build a list of triples # as if we had done the parsing. result = [] def append_triple(key, value, index, result=result): result.append((key, value, index)) command = append_triple try: if not isinstance(command, str): func_name = command = self._register(command) args += ["-command", command] for key in kw: if kw[key]: args.append("-" + key) args.append(index1) if index2: args.append(index2) self.tk.call(self._w, "dump", *args) return result finally: if func_name: self.deletecommand(func_name) ## new in tk8.4 def edit(self, *args): """Internal method This method controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the command are currently supported: edit_modified, edit_redo, edit_reset, edit_separator and edit_undo """ return self.tk.call(self._w, 'edit', *args) def edit_modified(self, arg=None): """Get or Set the modified flag If arg is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to arg. """ return self.edit("modified", arg) def edit_redo(self): """Redo the last undone edit When the undo option is true, reapplies the last undone edits provided no other edits were done since then. Generates an error when the redo stack is empty. Does nothing when the undo option is false. """ return self.edit("redo") def edit_reset(self): """Clears the undo and redo stacks """ return self.edit("reset") def edit_separator(self): """Inserts a separator (boundary) on the undo stack. Does nothing when the undo option is false """ return self.edit("separator") def edit_undo(self): """Undoes the last edit action If the undo option is true. An edit action is defined as all the insert and delete commands that are recorded on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the undo option is false """ return self.edit("undo") def get(self, index1, index2=None): """Return the text from INDEX1 to INDEX2 (not included).""" return self.tk.call(self._w, 'get', index1, index2) # (Image commands are new in 8.0) def image_cget(self, index, option): """Return the value of OPTION of an embedded image at INDEX.""" if option[:1] != "-": option = "-" + option if option[-1:] == "_": option = option[:-1] return self.tk.call(self._w, "image", "cget", index, option) def image_configure(self, index, cnf=None, **kw): """Configure an embedded image at INDEX.""" return self._configure(('image', 'configure', index), cnf, kw) def image_create(self, index, cnf={}, **kw): """Create an embedded image at INDEX.""" return self.tk.call( self._w, "image", "create", index, *self._options(cnf, kw)) def image_names(self): """Return all names of embedded images in this widget.""" return self.tk.call(self._w, "image", "names") def index(self, index): """Return the index in the form line.char for INDEX.""" return str(self.tk.call(self._w, 'index', index)) def insert(self, index, chars, *args): """Insert CHARS before the characters at INDEX. An additional tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" self.tk.call((self._w, 'insert', index, chars) + args) def mark_gravity(self, markName, direction=None): """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). Return the current value if None is given for DIRECTION.""" return self.tk.call( (self._w, 'mark', 'gravity', markName, direction)) def mark_names(self): """Return all mark names.""" return self.tk.splitlist(self.tk.call( self._w, 'mark', 'names')) def mark_set(self, markName, index): """Set mark MARKNAME before the character at INDEX.""" self.tk.call(self._w, 'mark', 'set', markName, index) def mark_unset(self, *markNames): """Delete all marks in MARKNAMES.""" self.tk.call((self._w, 'mark', 'unset') + markNames) def mark_next(self, index): """Return the name of the next mark after INDEX.""" return self.tk.call(self._w, 'mark', 'next', index) or None def mark_previous(self, index): """Return the name of the previous mark before INDEX.""" return self.tk.call(self._w, 'mark', 'previous', index) or None def peer_create(self, newPathName, cnf={}, **kw): # new in Tk 8.5 """Creates a peer text widget with the given newPathName, and any optional standard configuration options. By default the peer will have the same start and end line as the parent widget, but these can be overridden with the standard configuration options.""" self.tk.call(self._w, 'peer', 'create', newPathName, *self._options(cnf, kw)) def peer_names(self): # new in Tk 8.5 """Returns a list of peers of this widget (this does not include the widget itself).""" return self.tk.splitlist(self.tk.call(self._w, 'peer', 'names')) def replace(self, index1, index2, chars, *args): # new in Tk 8.5 """Replaces the range of characters between index1 and index2 with the given characters and tags specified by args. See the method insert for some more information about args, and the method delete for information about the indices.""" self.tk.call(self._w, 'replace', index1, index2, chars, *args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the text to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def search(self, pattern, index, stopindex=None, forwards=None, backwards=None, exact=None, regexp=None, nocase=None, count=None, elide=None): """Search PATTERN beginning from INDEX until STOPINDEX. Return the index of the first character of a match or an empty string.""" args = [self._w, 'search'] if forwards: args.append('-forwards') if backwards: args.append('-backwards') if exact: args.append('-exact') if regexp: args.append('-regexp') if nocase: args.append('-nocase') if elide: args.append('-elide') if count: args.append('-count'); args.append(count) if pattern and pattern[0] == '-': args.append('--') args.append(pattern) args.append(index) if stopindex: args.append(stopindex) return str(self.tk.call(tuple(args))) def see(self, index): """Scroll such that the character at INDEX is visible.""" self.tk.call(self._w, 'see', index) def tag_add(self, tagName, index1, *args): """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. Additional pairs of indices may follow in ARGS.""" self.tk.call( (self._w, 'tag', 'add', tagName, index1) + args) def tag_unbind(self, tagName, sequence, funcid=None): """Unbind for all characters with TAGNAME for event SEQUENCE the function identified with FUNCID.""" self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '') if funcid: self.deletecommand(funcid) def tag_bind(self, tagName, sequence, func, add=None): """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'tag', 'bind', tagName), sequence, func, add) def tag_cget(self, tagName, option): """Return the value of OPTION for tag TAGNAME.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'tag', 'cget', tagName, option) def tag_configure(self, tagName, cnf=None, **kw): """Configure a tag TAGNAME.""" return self._configure(('tag', 'configure', tagName), cnf, kw) tag_config = tag_configure def tag_delete(self, *tagNames): """Delete all tags in TAGNAMES.""" self.tk.call((self._w, 'tag', 'delete') + tagNames) def tag_lower(self, tagName, belowThis=None): """Change the priority of tag TAGNAME such that it is lower than the priority of BELOWTHIS.""" self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) def tag_names(self, index=None): """Return a list of all tag names.""" return self.tk.splitlist( self.tk.call(self._w, 'tag', 'names', index)) def tag_nextrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched forward from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'nextrange', tagName, index1, index2)) def tag_prevrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched backwards from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'prevrange', tagName, index1, index2)) def tag_raise(self, tagName, aboveThis=None): """Change the priority of tag TAGNAME such that it is higher than the priority of ABOVETHIS.""" self.tk.call( self._w, 'tag', 'raise', tagName, aboveThis) def tag_ranges(self, tagName): """Return a list of ranges of text which have tag TAGNAME.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'ranges', tagName)) def tag_remove(self, tagName, index1, index2=None): """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" self.tk.call( self._w, 'tag', 'remove', tagName, index1, index2) def window_cget(self, index, option): """Return the value of OPTION of an embedded window at INDEX.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'window', 'cget', index, option) def window_configure(self, index, cnf=None, **kw): """Configure an embedded window at INDEX.""" return self._configure(('window', 'configure', index), cnf, kw) window_config = window_configure def window_create(self, index, cnf={}, **kw): """Create a window at INDEX.""" self.tk.call( (self._w, 'window', 'create', index) + self._options(cnf, kw)) def window_names(self): """Return all names of embedded windows in this widget.""" return self.tk.splitlist( self.tk.call(self._w, 'window', 'names')) def yview_pickplace(self, *what): """Obsolete function, use see.""" self.tk.call((self._w, 'yview', '-pickplace') + what) class _setit: """Internal class. It wraps the command in the widget OptionMenu.""" def __init__(self, var, value, callback=None): self.__value = value self.__var = var self.__callback = callback def __call__(self, *args): self.__var.set(self.__value) if self.__callback: self.__callback(self.__value, *args) class OptionMenu(Menubutton): """OptionMenu which allows the user to select a value from a menu.""" def __init__(self, master, variable, value, *values, **kwargs): """Construct an optionmenu widget with the parent MASTER, with the resource textvariable set to VARIABLE, the initially selected value VALUE, the other menu values VALUES and an additional keyword argument command.""" kw = {"borderwidth": 2, "textvariable": variable, "indicatoron": 1, "relief": RAISED, "anchor": "c", "highlightthickness": 2} Widget.__init__(self, master, "menubutton", kw) self.widgetName = 'tk_optionMenu' menu = self.__menu = Menu(self, name="menu", tearoff=0) self.menuname = menu._w # 'command' is the only supported keyword callback = kwargs.get('command') if 'command' in kwargs: del kwargs['command'] if kwargs: raise TclError('unknown option -'+next(iter(kwargs))) menu.add_command(label=value, command=_setit(variable, value, callback)) for v in values: menu.add_command(label=v, command=_setit(variable, v, callback)) self["menu"] = menu def __getitem__(self, name): if name == 'menu': return self.__menu return Widget.__getitem__(self, name) def destroy(self): """Destroy this widget and the associated menu.""" Menubutton.destroy(self) self.__menu = None class Image: """Base class for images.""" _last_id = 0 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): self.name = None if not master: master = _get_default_root('create image') self.tk = getattr(master, 'tk', master) if not name: Image._last_id += 1 name = "pyimage%r" % (Image._last_id,) # tk itself would use image if kw and cnf: cnf = _cnfmerge((cnf, kw)) elif kw: cnf = kw options = () for k, v in cnf.items(): if callable(v): v = self._register(v) options = options + ('-'+k, v) self.tk.call(('image', 'create', imgtype, name,) + options) self.name = name def __str__(self): return self.name def __del__(self): if self.name: try: self.tk.call('image', 'delete', self.name) except TclError: # May happen if the root was destroyed pass def __setitem__(self, key, value): self.tk.call(self.name, 'configure', '-'+key, value) def __getitem__(self, key): return self.tk.call(self.name, 'configure', '-'+key) def configure(self, **kw): """Configure the image.""" res = () for k, v in _cnfmerge(kw).items(): if v is not None: if k[-1] == '_': k = k[:-1] if callable(v): v = self._register(v) res = res + ('-'+k, v) self.tk.call((self.name, 'config') + res) config = configure def height(self): """Return the height of the image.""" return self.tk.getint( self.tk.call('image', 'height', self.name)) def type(self): """Return the type of the image, e.g. "photo" or "bitmap".""" return self.tk.call('image', 'type', self.name) def width(self): """Return the width of the image.""" return self.tk.getint( self.tk.call('image', 'width', self.name)) class PhotoImage(Image): """Widget which can display images in PGM, PPM, GIF, PNG format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create an image with NAME. Valid resource names: data, format, file, gamma, height, palette, width.""" Image.__init__(self, 'photo', name, cnf, master, **kw) def blank(self): """Display a transparent image.""" self.tk.call(self.name, 'blank') def cget(self, option): """Return the value of OPTION.""" return self.tk.call(self.name, 'cget', '-' + option) # XXX config def __getitem__(self, key): return self.tk.call(self.name, 'cget', '-' + key) # XXX copy -from, -to, ...? def copy(self): """Return a new PhotoImage with the same image as this widget.""" destImage = PhotoImage(master=self.tk) self.tk.call(destImage, 'copy', self.name) return destImage def zoom(self, x, y=''): """Return a new PhotoImage with the same image as this widget but zoom it with a factor of x in the X direction and y in the Y direction. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) return destImage def subsample(self, x, y=''): """Return a new PhotoImage based on the same image as this widget but use only every Xth or Yth pixel. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) return destImage def get(self, x, y): """Return the color (red, green, blue) of the pixel at X,Y.""" return self.tk.call(self.name, 'get', x, y) def put(self, data, to=None): """Put row formatted colors to image starting from position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" args = (self.name, 'put', data) if to: if to[0] == '-to': to = to[1:] args = args + ('-to',) + tuple(to) self.tk.call(args) # XXX read def write(self, filename, format=None, from_coords=None): """Write image to file FILENAME in FORMAT starting from position FROM_COORDS.""" args = (self.name, 'write', filename) if format: args = args + ('-format', format) if from_coords: args = args + ('-from',) + tuple(from_coords) self.tk.call(args) def transparency_get(self, x, y): """Return True if the pixel at x,y is transparent.""" return self.tk.getboolean(self.tk.call( self.name, 'transparency', 'get', x, y)) def transparency_set(self, x, y, boolean): """Set the transparency of the pixel at x,y.""" self.tk.call(self.name, 'transparency', 'set', x, y, boolean) class BitmapImage(Image): """Widget which can display images in XBM format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create a bitmap with NAME. Valid resource names: background, data, file, foreground, maskdata, maskfile.""" Image.__init__(self, 'bitmap', name, cnf, master, **kw) def image_names(): tk = _get_default_root('use image_names()').tk return tk.splitlist(tk.call('image', 'names')) def image_types(): tk = _get_default_root('use image_types()').tk return tk.splitlist(tk.call('image', 'types')) class Spinbox(Widget, XView): """spinbox widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a spinbox widget with the parent MASTER. STANDARD OPTIONS activebackground, background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, justify, relief, repeatdelay, repeatinterval, selectbackground, selectborderwidth selectforeground, takefocus, textvariable xscrollcommand. WIDGET-SPECIFIC OPTIONS buttonbackground, buttoncursor, buttondownrelief, buttonuprelief, command, disabledbackground, disabledforeground, format, from, invalidcommand, increment, readonlybackground, state, to, validate, validatecommand values, width, wrap, """ Widget.__init__(self, master, 'spinbox', cnf, kw) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the character given by index. The first two elements of the list give the x and y coordinates of the upper-left corner of the screen area covered by the character (in pixels relative to the widget) and the last two elements give the width and height of the character, in pixels. The bounding box may refer to a region outside the visible area of the window. """ return self._getints(self.tk.call(self._w, 'bbox', index)) or None def delete(self, first, last=None): """Delete one or more elements of the spinbox. First is the index of the first character to delete, and last is the index of the character just after the last one to delete. If last isn't specified it defaults to first+1, i.e. a single character is deleted. This command returns an empty string. """ return self.tk.call(self._w, 'delete', first, last) def get(self): """Returns the spinbox's string""" return self.tk.call(self._w, 'get') def icursor(self, index): """Alter the position of the insertion cursor. The insertion cursor will be displayed just before the character given by index. Returns an empty string """ return self.tk.call(self._w, 'icursor', index) def identify(self, x, y): """Returns the name of the widget at position x, y Return value is one of: none, buttondown, buttonup, entry """ return self.tk.call(self._w, 'identify', x, y) def index(self, index): """Returns the numerical index corresponding to index """ return self.tk.call(self._w, 'index', index) def insert(self, index, s): """Insert string s at index Returns an empty string. """ return self.tk.call(self._w, 'insert', index, s) def invoke(self, element): """Causes the specified element to be invoked The element could be buttondown or buttonup triggering the action associated with it. """ return self.tk.call(self._w, 'invoke', element) def scan(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'scan') + args)) or () def scan_mark(self, x): """Records x and the current view in the spinbox window; used in conjunction with later scan dragto commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. """ return self.scan("mark", x) def scan_dragto(self, x): """Compute the difference between the given x argument and the x argument to the last scan mark command It then adjusts the view left or right by 10 times the difference in x-coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the spinbox at high speed through the window. The return value is an empty string. """ return self.scan("dragto", x) def selection(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'selection') + args)) or () def selection_adjust(self, index): """Locate the end of the selection nearest to the character given by index, Then adjust that end of the selection to be at index (i.e including but not going beyond index). The other end of the selection is made the anchor point for future select to commands. If the selection isn't currently in the spinbox, then a new selection is created to include the characters between index and the most recent selection anchor point, inclusive. """ return self.selection("adjust", index) def selection_clear(self): """Clear the selection If the selection isn't in this widget then the command has no effect. """ return self.selection("clear") def selection_element(self, element=None): """Sets or gets the currently selected element. If a spinbutton element is specified, it will be displayed depressed. """ return self.tk.call(self._w, 'selection', 'element', element) def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.selection('from', index) def selection_present(self): """Return True if there are characters selected in the spinbox, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.selection('range', start, end) def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.selection('to', index) ########################################################################### class LabelFrame(Widget): """labelframe widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a labelframe widget with the parent MASTER. STANDARD OPTIONS borderwidth, cursor, font, foreground, highlightbackground, highlightcolor, highlightthickness, padx, pady, relief, takefocus, text WIDGET-SPECIFIC OPTIONS background, class, colormap, container, height, labelanchor, labelwidget, visual, width """ Widget.__init__(self, master, 'labelframe', cnf, kw) ######################################################################## class PanedWindow(Widget): """panedwindow widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a panedwindow widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, height, orient, relief, width WIDGET-SPECIFIC OPTIONS handlepad, handlesize, opaqueresize, sashcursor, sashpad, sashrelief, sashwidth, showhandle, """ Widget.__init__(self, master, 'panedwindow', cnf, kw) def add(self, child, **kw): """Add a child widget to the panedwindow in a new pane. The child argument is the name of the child widget followed by pairs of arguments that specify how to manage the windows. The possible options and values are the ones accepted by the paneconfigure method. """ self.tk.call((self._w, 'add', child) + self._options(kw)) def remove(self, child): """Remove the pane containing child from the panedwindow All geometry management options for child will be forgotten. """ self.tk.call(self._w, 'forget', child) forget = remove def identify(self, x, y): """Identify the panedwindow component at point x, y If the point is over a sash or a sash handle, the result is a two element list containing the index of the sash or handle, and a word indicating whether it is over a sash or a handle, such as {0 sash} or {2 handle}. If the point is over any other part of the panedwindow, the result is an empty list. """ return self.tk.call(self._w, 'identify', x, y) def proxy(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'proxy') + args)) or () def proxy_coord(self): """Return the x and y pair of the most recent proxy location """ return self.proxy("coord") def proxy_forget(self): """Remove the proxy from the display. """ return self.proxy("forget") def proxy_place(self, x, y): """Place the proxy at the given x and y coordinates. """ return self.proxy("place", x, y) def sash(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'sash') + args)) or () def sash_coord(self, index): """Return the current x and y pair for the sash given by index. Index must be an integer between 0 and 1 less than the number of panes in the panedwindow. The coordinates given are those of the top left corner of the region containing the sash. pathName sash dragto index x y This command computes the difference between the given coordinates and the coordinates given to the last sash coord command for the given sash. It then moves that sash the computed difference. The return value is the empty string. """ return self.sash("coord", index) def sash_mark(self, index): """Records x and y for the sash given by index; Used in conjunction with later dragto commands to move the sash. """ return self.sash("mark", index) def sash_place(self, index, x, y): """Place the sash given by index at the given coordinates """ return self.sash("place", index, x, y) def panecget(self, child, option): """Query a management option for window. Option may be any value allowed by the paneconfigure subcommand """ return self.tk.call( (self._w, 'panecget') + (child, '-'+option)) def paneconfigure(self, tagOrId, cnf=None, **kw): """Query or modify the management options for window. If no option is specified, returns a list describing all of the available options for pathName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. The following options are supported: after window Insert the window after the window specified. window should be the name of a window already managed by pathName. before window Insert the window before the window specified. window should be the name of a window already managed by pathName. height size Specify a height for the window. The height will be the outer dimension of the window including its border, if any. If size is an empty string, or if -height is not specified, then the height requested internally by the window will be used initially; the height may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. minsize n Specifies that the size of the window cannot be made less than n. This constraint only affects the size of the widget in the paned dimension -- the x dimension for horizontal panedwindows, the y dimension for vertical panedwindows. May be any value accepted by Tk_GetPixels. padx n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the X-direction. The value may have any of the forms accepted by Tk_GetPixels. pady n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the Y-direction. The value may have any of the forms accepted by Tk_GetPixels. sticky style If a window's pane is larger than the requested dimensions of the window, this option may be used to position (or stretch) the window within its pane. Style is a string that contains zero or more of the characters n, s, e or w. The string can optionally contains spaces or commas, but they are ignored. Each letter refers to a side (north, south, east, or west) that the window will "stick" to. If both n and s (or e and w) are specified, the window will be stretched to fill the entire height (or width) of its cavity. width size Specify a width for the window. The width will be the outer dimension of the window including its border, if any. If size is an empty string, or if -width is not specified, then the width requested internally by the window will be used initially; the width may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. """ if cnf is None and not kw: return self._getconfigure(self._w, 'paneconfigure', tagOrId) if isinstance(cnf, str) and not kw: return self._getconfigure1( self._w, 'paneconfigure', tagOrId, '-'+cnf) self.tk.call((self._w, 'paneconfigure', tagOrId) + self._options(cnf, kw)) paneconfig = paneconfigure def panes(self): """Returns an ordered list of the child panes.""" return self.tk.splitlist(self.tk.call(self._w, 'panes')) # Test: def _test(): root = Tk() text = "This is Tcl/Tk version %s" % TclVersion text += "\nThis should be a cedilla: \xe7" label = Label(root, text=text) label.pack() test = Button(root, text="Click me!", command=lambda root=root: root.test.configure( text="[%s]" % root.test['text'])) test.pack() root.test = test quit = Button(root, text="QUIT", command=root.destroy) quit.pack() # The following three commands are needed so the window pops # up on top on Windows... root.iconify() root.update() root.deiconify() root.mainloop() if __name__ == '__main__': _test() lib64/python3.6/site-packages/hawkey/test/__init__.py000064400000003411152346031300016330 0ustar00# # Copyright (C) 2012-2013 Red Hat, Inc. # # Licensed under the GNU Lesser General Public License Version 2.1 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # from __future__ import absolute_import from . import _hawkey_test import hawkey import os EXPECT_SYSTEM_NSOLVABLES = _hawkey_test.EXPECT_SYSTEM_NSOLVABLES EXPECT_MAIN_NSOLVABLES = _hawkey_test.EXPECT_MAIN_NSOLVABLES EXPECT_UPDATES_NSOLVABLES = _hawkey_test.EXPECT_UPDATES_NSOLVABLES EXPECT_YUM_NSOLVABLES = _hawkey_test.EXPECT_YUM_NSOLVABLES FIXED_ARCH = _hawkey_test.FIXED_ARCH UNITTEST_DIR = _hawkey_test.UNITTEST_DIR YUM_DIR_SUFFIX = _hawkey_test.YUM_DIR_SUFFIX glob_for_repofiles = _hawkey_test.glob_for_repofiles class TestSackMixin(object): def __init__(self, repo_dir): self.repo_dir = repo_dir def load_test_repo(self, name, fn, system=False): path = os.path.join(self.repo_dir, fn) _hawkey_test.load_repo(self, name, path, system) def load_system_repo(self, *args, **kwargs): path = os.path.join(self.repo_dir, "@System.repo") _hawkey_test.load_repo(self, hawkey.SYSTEM_REPO_NAME, path, True) lib64/python3.8/xmlrpc/__init__.py000064400000000046152346070750012665 0ustar00# This directory is a Python package. usr/lib64/python3.6/xmlrpc/__init__.py000064400000000046152346073260013473 0ustar00# This directory is a Python package. lib64/python3.12/lib2to3/fixes/__init__.py000064400000000057152346073510014026 0ustar00# Dummy file to make this directory a package. usr/lib64/python3.6/email/mime/__init__.py000064400000000000152346105570014172 0ustar00usr/lib/python3.6/site-packages/isc/__init__.py000064400000001651152346127450015316 0ustar00############################################################################ # Copyright (C) Internet Systems Consortium, Inc. ("ISC") # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, you can obtain one at https://mozilla.org/MPL/2.0/. # # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. ############################################################################ __all__ = ['checkds', 'coverage', 'keymgr', 'dnskey', 'eventlist', 'keydict', 'keyevent', 'keyseries', 'keyzone', 'policy', 'parsetab', 'rndc', 'utils'] from isc.dnskey import * from isc.eventlist import * from isc.keydict import * from isc.keyevent import * from isc.keyseries import * from isc.keyzone import * from isc.policy import * from isc.rndc import * from isc.utils import * usr/lib64/python3.8/wsgiref/__init__.py000064400000001113152346130330013622 0ustar00"""wsgiref -- a WSGI (PEP 3333) Reference Library Current Contents: * util -- Miscellaneous useful functions and wrappers * headers -- Manage response headers * handlers -- base classes for server/gateway implementations * simple_server -- a simple BaseHTTPServer that supports WSGI * validate -- validation wrapper that sits between an app and a server to detect errors in either To-Do: * cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard) * cgi_wrapper -- Run CGI apps under WSGI * router -- a simple middleware component that handles URL traversal """ usr/lib64/python3.12/zipfile/__init__.py000064400000255646152346132520013722 0ustar00""" Read and write ZIP files. XXX references to utf-8 need further investigation. """ import binascii import importlib.util import io import os import shutil import stat import struct import sys import threading import time try: import zlib # We may need its compression method crc32 = zlib.crc32 except ImportError: zlib = None crc32 = binascii.crc32 try: import bz2 # We may need its compression method except ImportError: bz2 = None try: import lzma # We may need its compression method except ImportError: lzma = None __all__ = ["BadZipFile", "BadZipfile", "error", "ZIP_STORED", "ZIP_DEFLATED", "ZIP_BZIP2", "ZIP_LZMA", "is_zipfile", "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile", "Path"] class BadZipFile(Exception): pass class LargeZipFile(Exception): """ Raised when writing a zipfile, the zipfile requires ZIP64 extensions and those extensions are disabled. """ error = BadZipfile = BadZipFile # Pre-3.2 compatibility names ZIP64_LIMIT = (1 << 31) - 1 ZIP_FILECOUNT_LIMIT = (1 << 16) - 1 ZIP_MAX_COMMENT = (1 << 16) - 1 # constants for Zip file compression methods ZIP_STORED = 0 ZIP_DEFLATED = 8 ZIP_BZIP2 = 12 ZIP_LZMA = 14 # Other ZIP compression methods not supported DEFAULT_VERSION = 20 ZIP64_VERSION = 45 BZIP2_VERSION = 46 LZMA_VERSION = 63 # we recognize (but not necessarily support) all features up to that version MAX_EXTRACT_VERSION = 63 # Below are some formats and associated data for reading/writing headers using # the struct module. The names and structures of headers/records are those used # in the PKWARE description of the ZIP file format: # http://www.pkware.com/documents/casestudies/APPNOTE.TXT # (URL valid as of January 2008) # The "end of central directory" structure, magic number, size, and indices # (section V.I in the format document) structEndArchive = b"<4s4H2LH" stringEndArchive = b"PK\005\006" sizeEndCentDir = struct.calcsize(structEndArchive) _ECD_SIGNATURE = 0 _ECD_DISK_NUMBER = 1 _ECD_DISK_START = 2 _ECD_ENTRIES_THIS_DISK = 3 _ECD_ENTRIES_TOTAL = 4 _ECD_SIZE = 5 _ECD_OFFSET = 6 _ECD_COMMENT_SIZE = 7 # These last two indices are not part of the structure as defined in the # spec, but they are used internally by this module as a convenience _ECD_COMMENT = 8 _ECD_LOCATION = 9 # The "central directory" structure, magic number, size, and indices # of entries in the structure (section V.F in the format document) structCentralDir = "<4s4B4HL2L5H2L" stringCentralDir = b"PK\001\002" sizeCentralDir = struct.calcsize(structCentralDir) # indexes of entries in the central directory structure _CD_SIGNATURE = 0 _CD_CREATE_VERSION = 1 _CD_CREATE_SYSTEM = 2 _CD_EXTRACT_VERSION = 3 _CD_EXTRACT_SYSTEM = 4 _CD_FLAG_BITS = 5 _CD_COMPRESS_TYPE = 6 _CD_TIME = 7 _CD_DATE = 8 _CD_CRC = 9 _CD_COMPRESSED_SIZE = 10 _CD_UNCOMPRESSED_SIZE = 11 _CD_FILENAME_LENGTH = 12 _CD_EXTRA_FIELD_LENGTH = 13 _CD_COMMENT_LENGTH = 14 _CD_DISK_NUMBER_START = 15 _CD_INTERNAL_FILE_ATTRIBUTES = 16 _CD_EXTERNAL_FILE_ATTRIBUTES = 17 _CD_LOCAL_HEADER_OFFSET = 18 # General purpose bit flags # Zip Appnote: 4.4.4 general purpose bit flag: (2 bytes) _MASK_ENCRYPTED = 1 << 0 # Bits 1 and 2 have different meanings depending on the compression used. _MASK_COMPRESS_OPTION_1 = 1 << 1 # _MASK_COMPRESS_OPTION_2 = 1 << 2 # _MASK_USE_DATA_DESCRIPTOR: If set, crc-32, compressed size and uncompressed # size are zero in the local header and the real values are written in the data # descriptor immediately following the compressed data. _MASK_USE_DATA_DESCRIPTOR = 1 << 3 # Bit 4: Reserved for use with compression method 8, for enhanced deflating. # _MASK_RESERVED_BIT_4 = 1 << 4 _MASK_COMPRESSED_PATCH = 1 << 5 _MASK_STRONG_ENCRYPTION = 1 << 6 # _MASK_UNUSED_BIT_7 = 1 << 7 # _MASK_UNUSED_BIT_8 = 1 << 8 # _MASK_UNUSED_BIT_9 = 1 << 9 # _MASK_UNUSED_BIT_10 = 1 << 10 _MASK_UTF_FILENAME = 1 << 11 # Bit 12: Reserved by PKWARE for enhanced compression. # _MASK_RESERVED_BIT_12 = 1 << 12 # _MASK_ENCRYPTED_CENTRAL_DIR = 1 << 13 # Bit 14, 15: Reserved by PKWARE # _MASK_RESERVED_BIT_14 = 1 << 14 # _MASK_RESERVED_BIT_15 = 1 << 15 # The "local file header" structure, magic number, size, and indices # (section V.A in the format document) structFileHeader = "<4s2B4HL2L2H" stringFileHeader = b"PK\003\004" sizeFileHeader = struct.calcsize(structFileHeader) _FH_SIGNATURE = 0 _FH_EXTRACT_VERSION = 1 _FH_EXTRACT_SYSTEM = 2 _FH_GENERAL_PURPOSE_FLAG_BITS = 3 _FH_COMPRESSION_METHOD = 4 _FH_LAST_MOD_TIME = 5 _FH_LAST_MOD_DATE = 6 _FH_CRC = 7 _FH_COMPRESSED_SIZE = 8 _FH_UNCOMPRESSED_SIZE = 9 _FH_FILENAME_LENGTH = 10 _FH_EXTRA_FIELD_LENGTH = 11 # The "Zip64 end of central directory locator" structure, magic number, and size structEndArchive64Locator = "<4sLQL" stringEndArchive64Locator = b"PK\x06\x07" sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator) # The "Zip64 end of central directory" record, magic number, size, and indices # (section V.G in the format document) structEndArchive64 = "<4sQ2H2L4Q" stringEndArchive64 = b"PK\x06\x06" sizeEndCentDir64 = struct.calcsize(structEndArchive64) _CD64_SIGNATURE = 0 _CD64_DIRECTORY_RECSIZE = 1 _CD64_CREATE_VERSION = 2 _CD64_EXTRACT_VERSION = 3 _CD64_DISK_NUMBER = 4 _CD64_DISK_NUMBER_START = 5 _CD64_NUMBER_ENTRIES_THIS_DISK = 6 _CD64_NUMBER_ENTRIES_TOTAL = 7 _CD64_DIRECTORY_SIZE = 8 _CD64_OFFSET_START_CENTDIR = 9 _DD_SIGNATURE = 0x08074b50 _EXTRA_FIELD_STRUCT = struct.Struct(' 1: raise BadZipFile("zipfiles that span multiple disks are not supported") offset -= sizeEndCentDir64 if reloff > offset: raise BadZipFile("Corrupt zip64 end of central directory locator") # First, check the assumption that there is no prepended data. fpin.seek(reloff) extrasz = offset - reloff data = fpin.read(sizeEndCentDir64) if len(data) != sizeEndCentDir64: raise OSError("Unknown I/O error") if not data.startswith(stringEndArchive64) and reloff != offset: # Since we already have seen the Zip64 EOCD Locator, it's # possible we got here because there is prepended data. # Assume no 'zip64 extensible data' fpin.seek(offset) extrasz = 0 data = fpin.read(sizeEndCentDir64) if len(data) != sizeEndCentDir64: raise OSError("Unknown I/O error") if not data.startswith(stringEndArchive64): raise BadZipFile("Zip64 end of central directory record not found") sig, sz, create_version, read_version, disk_num, disk_dir, \ dircount, dircount2, dirsize, diroffset = \ struct.unpack(structEndArchive64, data) if (diroffset + dirsize != reloff or sz + 12 != sizeEndCentDir64 + extrasz): raise BadZipFile("Corrupt zip64 end of central directory record") # Update the original endrec using data from the ZIP64 record endrec[_ECD_SIGNATURE] = sig endrec[_ECD_DISK_NUMBER] = disk_num endrec[_ECD_DISK_START] = disk_dir endrec[_ECD_ENTRIES_THIS_DISK] = dircount endrec[_ECD_ENTRIES_TOTAL] = dircount2 endrec[_ECD_SIZE] = dirsize endrec[_ECD_OFFSET] = diroffset endrec[_ECD_LOCATION] = offset - extrasz return endrec def _EndRecData(fpin): """Return data from the "End of Central Directory" record, or None. The data is a list of the nine items in the ZIP "End of central dir" record followed by a tenth item, the file seek offset of this record.""" # Determine file size fpin.seek(0, 2) filesize = fpin.tell() # Check to see if this is ZIP file with no archive comment (the # "end of central directory" structure should be the last item in the # file if this is the case). try: fpin.seek(-sizeEndCentDir, 2) except OSError: return None data = fpin.read(sizeEndCentDir) if (len(data) == sizeEndCentDir and data[0:4] == stringEndArchive and data[-2:] == b"\000\000"): # the signature is correct and there's no comment, unpack structure endrec = struct.unpack(structEndArchive, data) endrec=list(endrec) # Append a blank comment and record start offset endrec.append(b"") endrec.append(filesize - sizeEndCentDir) # Try to read the "Zip64 end of central directory" structure return _EndRecData64(fpin, filesize - sizeEndCentDir, endrec) # Either this is not a ZIP file, or it is a ZIP file with an archive # comment. Search the end of the file for the "end of central directory" # record signature. The comment is the last item in the ZIP file and may be # up to 64K long. It is assumed that the "end of central directory" magic # number does not appear in the comment. maxCommentStart = max(filesize - ZIP_MAX_COMMENT - sizeEndCentDir, 0) fpin.seek(maxCommentStart, 0) data = fpin.read(ZIP_MAX_COMMENT + sizeEndCentDir) start = data.rfind(stringEndArchive) if start >= 0: # found the magic number; attempt to unpack and interpret recData = data[start:start+sizeEndCentDir] if len(recData) != sizeEndCentDir: # Zip file is corrupted. return None endrec = list(struct.unpack(structEndArchive, recData)) commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] endrec.append(comment) endrec.append(maxCommentStart + start) # Try to read the "Zip64 end of central directory" structure return _EndRecData64(fpin, maxCommentStart + start, endrec) # Unable to find a valid end of central directory structure return None def _sanitize_filename(filename): """Terminate the file name at the first null byte and ensure paths always use forward slashes as the directory separator.""" # Terminate the file name at the first null byte. Null bytes in file # names are used as tricks by viruses in archives. null_byte = filename.find(chr(0)) if null_byte >= 0: filename = filename[0:null_byte] # This is used to ensure paths in generated ZIP files always use # forward slashes as the directory separator, as required by the # ZIP format specification. if os.sep != "/" and os.sep in filename: filename = filename.replace(os.sep, "/") if os.altsep and os.altsep != "/" and os.altsep in filename: filename = filename.replace(os.altsep, "/") return filename class ZipInfo (object): """Class with attributes describing each file in the ZIP archive.""" __slots__ = ( 'orig_filename', 'filename', 'date_time', 'compress_type', '_compresslevel', 'comment', 'extra', 'create_system', 'create_version', 'extract_version', 'reserved', 'flag_bits', 'volume', 'internal_attr', 'external_attr', 'header_offset', 'CRC', 'compress_size', 'file_size', '_raw_time', '_end_offset', ) def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): self.orig_filename = filename # Original file name in archive # Terminate the file name at the first null byte and # ensure paths always use forward slashes as the directory separator. filename = _sanitize_filename(filename) self.filename = filename # Normalized file name self.date_time = date_time # year, month, day, hour, min, sec if date_time[0] < 1980: raise ValueError('ZIP does not support timestamps before 1980') # Standard values: self.compress_type = ZIP_STORED # Type of compression for the file self._compresslevel = None # Level for the compressor self.comment = b"" # Comment for each file self.extra = b"" # ZIP extra data if sys.platform == 'win32': self.create_system = 0 # System which created ZIP archive else: # Assume everything else is unix-y self.create_system = 3 # System which created ZIP archive self.create_version = DEFAULT_VERSION # Version which created ZIP archive self.extract_version = DEFAULT_VERSION # Version needed to extract archive self.reserved = 0 # Must be zero self.flag_bits = 0 # ZIP flag bits self.volume = 0 # Volume number of file header self.internal_attr = 0 # Internal attributes self.external_attr = 0 # External file attributes self.compress_size = 0 # Size of the compressed file self.file_size = 0 # Size of the uncompressed file self._end_offset = None # Start of the next local header or central directory # Other attributes are set by class ZipFile: # header_offset Byte offset to the file header # CRC CRC-32 of the uncompressed file def __repr__(self): result = ['<%s filename=%r' % (self.__class__.__name__, self.filename)] if self.compress_type != ZIP_STORED: result.append(' compress_type=%s' % compressor_names.get(self.compress_type, self.compress_type)) hi = self.external_attr >> 16 lo = self.external_attr & 0xFFFF if hi: result.append(' filemode=%r' % stat.filemode(hi)) if lo: result.append(' external_attr=%#x' % lo) isdir = self.is_dir() if not isdir or self.file_size: result.append(' file_size=%r' % self.file_size) if ((not isdir or self.compress_size) and (self.compress_type != ZIP_STORED or self.file_size != self.compress_size)): result.append(' compress_size=%r' % self.compress_size) result.append('>') return ''.join(result) def FileHeader(self, zip64=None): """Return the per-file header as a bytes object. When the optional zip64 arg is None rather than a bool, we will decide based upon the file_size and compress_size, if known, False otherwise. """ dt = self.date_time dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) if self.flag_bits & _MASK_USE_DATA_DESCRIPTOR: # Set these to zero because we write them after the file data CRC = compress_size = file_size = 0 else: CRC = self.CRC compress_size = self.compress_size file_size = self.file_size extra = self.extra min_version = 0 if zip64 is None: # We always explicitly pass zip64 within this module.... This # remains for anyone using ZipInfo.FileHeader as a public API. zip64 = file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT if zip64: fmt = '= 4: tp, ln = unpack(' len(extra): raise BadZipFile("Corrupt extra field %04x (size=%d)" % (tp, ln)) if tp == 0x0001: data = extra[4:ln+4] # ZIP64 extension (large files and/or large archives) try: if self.file_size in (0xFFFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF): field = "File size" self.file_size, = unpack(' 2107: date_time = (2107, 12, 31, 23, 59, 59) # Create ZipInfo instance to store file information if arcname is None: arcname = filename arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) while arcname[0] in (os.sep, os.altsep): arcname = arcname[1:] if isdir: arcname += '/' zinfo = cls(arcname, date_time) zinfo.external_attr = (st.st_mode & 0xFFFF) << 16 # Unix attributes if isdir: zinfo.file_size = 0 zinfo.external_attr |= 0x10 # MS-DOS directory flag else: zinfo.file_size = st.st_size return zinfo def is_dir(self): """Return True if this archive member is a directory.""" if self.filename.endswith('/'): return True # The ZIP format specification requires to use forward slashes # as the directory separator, but in practice some ZIP files # created on Windows can use backward slashes. For compatibility # with the extraction code which already handles this: if os.path.altsep: return self.filename.endswith((os.path.sep, os.path.altsep)) return False # ZIP encryption uses the CRC32 one-byte primitive for scrambling some # internal keys. We noticed that a direct implementation is faster than # relying on binascii.crc32(). _crctable = None def _gen_crc(crc): for j in range(8): if crc & 1: crc = (crc >> 1) ^ 0xEDB88320 else: crc >>= 1 return crc # ZIP supports a password-based form of encryption. Even though known # plaintext attacks have been found against it, it is still useful # to be able to get data out of such a file. # # Usage: # zd = _ZipDecrypter(mypwd) # plain_bytes = zd(cypher_bytes) def _ZipDecrypter(pwd): key0 = 305419896 key1 = 591751049 key2 = 878082192 global _crctable if _crctable is None: _crctable = list(map(_gen_crc, range(256))) crctable = _crctable def crc32(ch, crc): """Compute the CRC32 primitive on one byte.""" return (crc >> 8) ^ crctable[(crc ^ ch) & 0xFF] def update_keys(c): nonlocal key0, key1, key2 key0 = crc32(c, key0) key1 = (key1 + (key0 & 0xFF)) & 0xFFFFFFFF key1 = (key1 * 134775813 + 1) & 0xFFFFFFFF key2 = crc32(key1 >> 24, key2) for p in pwd: update_keys(p) def decrypter(data): """Decrypt a bytes object.""" result = bytearray() append = result.append for c in data: k = key2 | 2 c ^= ((k * (k^1)) >> 8) & 0xFF update_keys(c) append(c) return bytes(result) return decrypter class LZMACompressor: def __init__(self): self._comp = None def _init(self): props = lzma._encode_filter_properties({'id': lzma.FILTER_LZMA1}) self._comp = lzma.LZMACompressor(lzma.FORMAT_RAW, filters=[ lzma._decode_filter_properties(lzma.FILTER_LZMA1, props) ]) return struct.pack('> 8) & 0xff else: # compare against the CRC otherwise check_byte = (zipinfo.CRC >> 24) & 0xff h = self._init_decrypter() if h != check_byte: raise RuntimeError("Bad password for file %r" % zipinfo.orig_filename) def _init_decrypter(self): self._decrypter = _ZipDecrypter(self._pwd) # The first 12 bytes in the cypher stream is an encryption header # used to strengthen the algorithm. The first 11 bytes are # completely random, while the 12th contains the MSB of the CRC, # or the MSB of the file time depending on the header type # and is used to check the correctness of the password. header = self._fileobj.read(12) self._compress_left -= 12 return self._decrypter(header)[11] def __repr__(self): result = ['<%s.%s' % (self.__class__.__module__, self.__class__.__qualname__)] if not self.closed: result.append(' name=%r mode=%r' % (self.name, self.mode)) if self._compress_type != ZIP_STORED: result.append(' compress_type=%s' % compressor_names.get(self._compress_type, self._compress_type)) else: result.append(' [closed]') result.append('>') return ''.join(result) def readline(self, limit=-1): """Read and return a line from the stream. If limit is specified, at most limit bytes will be read. """ if limit < 0: # Shortcut common case - newline found in buffer. i = self._readbuffer.find(b'\n', self._offset) + 1 if i > 0: line = self._readbuffer[self._offset: i] self._offset = i return line return io.BufferedIOBase.readline(self, limit) def peek(self, n=1): """Returns buffered bytes without advancing the position.""" if n > len(self._readbuffer) - self._offset: chunk = self.read(n) if len(chunk) > self._offset: self._readbuffer = chunk + self._readbuffer[self._offset:] self._offset = 0 else: self._offset -= len(chunk) # Return up to 512 bytes to reduce allocation overhead for tight loops. return self._readbuffer[self._offset: self._offset + 512] def readable(self): if self.closed: raise ValueError("I/O operation on closed file.") return True def read(self, n=-1): """Read and return up to n bytes. If the argument is omitted, None, or negative, data is read and returned until EOF is reached. """ if self.closed: raise ValueError("read from closed file.") if n is None or n < 0: buf = self._readbuffer[self._offset:] self._readbuffer = b'' self._offset = 0 while not self._eof: buf += self._read1(self.MAX_N) return buf end = n + self._offset if end < len(self._readbuffer): buf = self._readbuffer[self._offset:end] self._offset = end return buf n = end - len(self._readbuffer) buf = self._readbuffer[self._offset:] self._readbuffer = b'' self._offset = 0 while n > 0 and not self._eof: data = self._read1(n) if n < len(data): self._readbuffer = data self._offset = n buf += data[:n] break buf += data n -= len(data) return buf def _update_crc(self, newdata): # Update the CRC using the given data. if self._expected_crc is None: # No need to compute the CRC if we don't have a reference value return self._running_crc = crc32(newdata, self._running_crc) # Check the CRC if we're at the end of the file if self._eof and self._running_crc != self._expected_crc: raise BadZipFile("Bad CRC-32 for file %r" % self.name) def read1(self, n): """Read up to n bytes with at most one read() system call.""" if n is None or n < 0: buf = self._readbuffer[self._offset:] self._readbuffer = b'' self._offset = 0 while not self._eof: data = self._read1(self.MAX_N) if data: buf += data break return buf end = n + self._offset if end < len(self._readbuffer): buf = self._readbuffer[self._offset:end] self._offset = end return buf n = end - len(self._readbuffer) buf = self._readbuffer[self._offset:] self._readbuffer = b'' self._offset = 0 if n > 0: while not self._eof: data = self._read1(n) if n < len(data): self._readbuffer = data self._offset = n buf += data[:n] break if data: buf += data break return buf def _read1(self, n): # Read up to n compressed bytes with at most one read() system call, # decrypt and decompress them. if self._eof or n <= 0: return b'' # Read from file. if self._compress_type == ZIP_DEFLATED: ## Handle unconsumed data. data = self._decompressor.unconsumed_tail if n > len(data): data += self._read2(n - len(data)) else: data = self._read2(n) if self._compress_type == ZIP_STORED: self._eof = self._compress_left <= 0 elif self._compress_type == ZIP_DEFLATED: n = max(n, self.MIN_READ_SIZE) data = self._decompressor.decompress(data, n) self._eof = (self._decompressor.eof or self._compress_left <= 0 and not self._decompressor.unconsumed_tail) if self._eof: data += self._decompressor.flush() else: data = self._decompressor.decompress(data) self._eof = self._decompressor.eof or self._compress_left <= 0 data = data[:self._left] self._left -= len(data) if self._left <= 0: self._eof = True self._update_crc(data) return data def _read2(self, n): if self._compress_left <= 0: return b'' n = max(n, self.MIN_READ_SIZE) n = min(n, self._compress_left) data = self._fileobj.read(n) self._compress_left -= len(data) if not data: raise EOFError if self._decrypter is not None: data = self._decrypter(data) return data def close(self): try: if self._close_fileobj: self._fileobj.close() finally: super().close() def seekable(self): if self.closed: raise ValueError("I/O operation on closed file.") return self._seekable def seek(self, offset, whence=os.SEEK_SET): if self.closed: raise ValueError("seek on closed file.") if not self._seekable: raise io.UnsupportedOperation("underlying stream is not seekable") curr_pos = self.tell() if whence == os.SEEK_SET: new_pos = offset elif whence == os.SEEK_CUR: new_pos = curr_pos + offset elif whence == os.SEEK_END: new_pos = self._orig_file_size + offset else: raise ValueError("whence must be os.SEEK_SET (0), " "os.SEEK_CUR (1), or os.SEEK_END (2)") if new_pos > self._orig_file_size: new_pos = self._orig_file_size if new_pos < 0: new_pos = 0 read_offset = new_pos - curr_pos buff_offset = read_offset + self._offset if buff_offset >= 0 and buff_offset < len(self._readbuffer): # Just move the _offset index if the new position is in the _readbuffer self._offset = buff_offset read_offset = 0 # Fast seek uncompressed unencrypted file elif self._compress_type == ZIP_STORED and self._decrypter is None and read_offset != 0: # disable CRC checking after first seeking - it would be invalid self._expected_crc = None # seek actual file taking already buffered data into account read_offset -= len(self._readbuffer) - self._offset self._fileobj.seek(read_offset, os.SEEK_CUR) self._left -= read_offset self._compress_left -= read_offset self._eof = self._left <= 0 read_offset = 0 # flush read buffer self._readbuffer = b'' self._offset = 0 elif read_offset < 0: # Position is before the current position. Reset the ZipExtFile self._fileobj.seek(self._orig_compress_start) self._running_crc = self._orig_start_crc self._expected_crc = self._orig_crc self._compress_left = self._orig_compress_size self._left = self._orig_file_size self._readbuffer = b'' self._offset = 0 self._decompressor = _get_decompressor(self._compress_type) self._eof = False read_offset = new_pos if self._decrypter is not None: self._init_decrypter() while read_offset > 0: read_len = min(self.MAX_SEEK_READ, read_offset) self.read(read_len) read_offset -= read_len return self.tell() def tell(self): if self.closed: raise ValueError("tell on closed file.") if not self._seekable: raise io.UnsupportedOperation("underlying stream is not seekable") filepos = self._orig_file_size - self._left - len(self._readbuffer) + self._offset return filepos class _ZipWriteFile(io.BufferedIOBase): def __init__(self, zf, zinfo, zip64): self._zinfo = zinfo self._zip64 = zip64 self._zipfile = zf self._compressor = _get_compressor(zinfo.compress_type, zinfo._compresslevel) self._file_size = 0 self._compress_size = 0 self._crc = 0 @property def _fileobj(self): return self._zipfile.fp def writable(self): return True def write(self, data): if self.closed: raise ValueError('I/O operation on closed file.') # Accept any data that supports the buffer protocol if isinstance(data, (bytes, bytearray)): nbytes = len(data) else: data = memoryview(data) nbytes = data.nbytes self._file_size += nbytes self._crc = crc32(data, self._crc) if self._compressor: data = self._compressor.compress(data) self._compress_size += len(data) self._fileobj.write(data) return nbytes def close(self): if self.closed: return try: super().close() # Flush any data from the compressor, and update header info if self._compressor: buf = self._compressor.flush() self._compress_size += len(buf) self._fileobj.write(buf) self._zinfo.compress_size = self._compress_size else: self._zinfo.compress_size = self._file_size self._zinfo.CRC = self._crc self._zinfo.file_size = self._file_size if not self._zip64: if self._file_size > ZIP64_LIMIT: raise RuntimeError("File size too large, try using force_zip64") if self._compress_size > ZIP64_LIMIT: raise RuntimeError("Compressed size too large, try using force_zip64") # Write updated header info if self._zinfo.flag_bits & _MASK_USE_DATA_DESCRIPTOR: # Write CRC and file sizes after the file data fmt = '') return ''.join(result) def _RealGetContents(self): """Read in the table of contents for the ZIP file.""" fp = self.fp try: endrec = _EndRecData(fp) except OSError: raise BadZipFile("File is not a zip file") if not endrec: raise BadZipFile("File is not a zip file") if self.debug > 1: print(endrec) size_cd = endrec[_ECD_SIZE] # bytes in central directory offset_cd = endrec[_ECD_OFFSET] # offset of central directory self._comment = endrec[_ECD_COMMENT] # archive comment # "concat" is zero, unless zip was concatenated to another file concat = endrec[_ECD_LOCATION] - size_cd - offset_cd if self.debug > 2: inferred = concat + offset_cd print("given, inferred, offset", offset_cd, inferred, concat) # self.start_dir: Position of start of central directory self.start_dir = offset_cd + concat if self.start_dir < 0: raise BadZipFile("Bad offset for central directory") fp.seek(self.start_dir, 0) data = fp.read(size_cd) fp = io.BytesIO(data) total = 0 while total < size_cd: centdir = fp.read(sizeCentralDir) if len(centdir) != sizeCentralDir: raise BadZipFile("Truncated central directory") centdir = struct.unpack(structCentralDir, centdir) if centdir[_CD_SIGNATURE] != stringCentralDir: raise BadZipFile("Bad magic number for central directory") if self.debug > 2: print(centdir) filename = fp.read(centdir[_CD_FILENAME_LENGTH]) orig_filename_crc = crc32(filename) flags = centdir[_CD_FLAG_BITS] if flags & _MASK_UTF_FILENAME: # UTF-8 file names extension filename = filename.decode('utf-8') else: # Historical ZIP filename encoding filename = filename.decode(self.metadata_encoding or 'cp437') # Create ZipInfo instance to store file information x = ZipInfo(filename) x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH]) x.comment = fp.read(centdir[_CD_COMMENT_LENGTH]) x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET] (x.create_version, x.create_system, x.extract_version, x.reserved, x.flag_bits, x.compress_type, t, d, x.CRC, x.compress_size, x.file_size) = centdir[1:12] if x.extract_version > MAX_EXTRACT_VERSION: raise NotImplementedError("zip file version %.1f" % (x.extract_version / 10)) x.volume, x.internal_attr, x.external_attr = centdir[15:18] # Convert date/time code to (year, month, day, hour, min, sec) x._raw_time = t x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F, t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) x._decodeExtra(orig_filename_crc) x.header_offset = x.header_offset + concat self.filelist.append(x) self.NameToInfo[x.filename] = x # update total bytes read from central directory total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH] + centdir[_CD_EXTRA_FIELD_LENGTH] + centdir[_CD_COMMENT_LENGTH]) if self.debug > 2: print("total", total) end_offset = self.start_dir for zinfo in reversed(sorted(self.filelist, key=lambda zinfo: zinfo.header_offset)): zinfo._end_offset = end_offset end_offset = zinfo.header_offset def namelist(self): """Return a list of file names in the archive.""" return [data.filename for data in self.filelist] def infolist(self): """Return a list of class ZipInfo instances for files in the archive.""" return self.filelist def printdir(self, file=None): """Print a table of contents for the zip file.""" print("%-46s %19s %12s" % ("File Name", "Modified ", "Size"), file=file) for zinfo in self.filelist: date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6] print("%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size), file=file) def testzip(self): """Read all the files and check the CRC. Return None if all files could be read successfully, or the name of the offending file otherwise.""" chunk_size = 2 ** 20 for zinfo in self.filelist: try: # Read by chunks, to avoid an OverflowError or a # MemoryError with very large embedded files. with self.open(zinfo.filename, "r") as f: while f.read(chunk_size): # Check CRC-32 pass except BadZipFile: return zinfo.filename def getinfo(self, name): """Return the instance of ZipInfo given 'name'.""" info = self.NameToInfo.get(name) if info is None: raise KeyError( 'There is no item named %r in the archive' % name) return info def setpassword(self, pwd): """Set default password for encrypted files.""" if pwd and not isinstance(pwd, bytes): raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__) if pwd: self.pwd = pwd else: self.pwd = None @property def comment(self): """The comment text associated with the ZIP file.""" return self._comment @comment.setter def comment(self, comment): if not isinstance(comment, bytes): raise TypeError("comment: expected bytes, got %s" % type(comment).__name__) # check for valid comment length if len(comment) > ZIP_MAX_COMMENT: import warnings warnings.warn('Archive comment is too long; truncating to %d bytes' % ZIP_MAX_COMMENT, stacklevel=2) comment = comment[:ZIP_MAX_COMMENT] self._comment = comment self._didModify = True def read(self, name, pwd=None): """Return file bytes for name. 'pwd' is the password to decrypt encrypted files.""" with self.open(name, "r", pwd) as fp: return fp.read() def open(self, name, mode="r", pwd=None, *, force_zip64=False): """Return file-like object for 'name'. name is a string for the file name within the ZIP file, or a ZipInfo object. mode should be 'r' to read a file already in the ZIP file, or 'w' to write to a file newly added to the archive. pwd is the password to decrypt files (only used for reading). When writing, if the file size is not known in advance but may exceed 2 GiB, pass force_zip64 to use the ZIP64 format, which can handle large files. If the size is known in advance, it is best to pass a ZipInfo instance for name, with zinfo.file_size set. """ if mode not in {"r", "w"}: raise ValueError('open() requires mode "r" or "w"') if pwd and (mode == "w"): raise ValueError("pwd is only supported for reading files") if not self.fp: raise ValueError( "Attempt to use ZIP archive that was already closed") # Make sure we have an info object if isinstance(name, ZipInfo): # 'name' is already an info object zinfo = name elif mode == 'w': zinfo = ZipInfo(name) zinfo.compress_type = self.compression zinfo._compresslevel = self.compresslevel else: # Get info object for name zinfo = self.getinfo(name) if mode == 'w': return self._open_to_write(zinfo, force_zip64=force_zip64) if self._writing: raise ValueError("Can't read from the ZIP file while there " "is an open writing handle on it. " "Close the writing handle before trying to read.") # Open for reading: self._fileRefCnt += 1 zef_file = _SharedFile(self.fp, zinfo.header_offset, self._fpclose, self._lock, lambda: self._writing) try: # Skip the file header: fheader = zef_file.read(sizeFileHeader) if len(fheader) != sizeFileHeader: raise BadZipFile("Truncated file header") fheader = struct.unpack(structFileHeader, fheader) if fheader[_FH_SIGNATURE] != stringFileHeader: raise BadZipFile("Bad magic number for file header") fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) if fheader[_FH_EXTRA_FIELD_LENGTH]: zef_file.seek(fheader[_FH_EXTRA_FIELD_LENGTH], whence=1) if zinfo.flag_bits & _MASK_COMPRESSED_PATCH: # Zip 2.7: compressed patched data raise NotImplementedError("compressed patched data (flag bit 5)") if zinfo.flag_bits & _MASK_STRONG_ENCRYPTION: # strong encryption raise NotImplementedError("strong encryption (flag bit 6)") if fheader[_FH_GENERAL_PURPOSE_FLAG_BITS] & _MASK_UTF_FILENAME: # UTF-8 filename fname_str = fname.decode("utf-8") else: fname_str = fname.decode(self.metadata_encoding or "cp437") if fname_str != zinfo.orig_filename: raise BadZipFile( 'File name in directory %r and header %r differ.' % (zinfo.orig_filename, fname)) if (zinfo._end_offset is not None and zef_file.tell() + zinfo.compress_size > zinfo._end_offset): if zinfo._end_offset == zinfo.header_offset: import warnings warnings.warn( f"Overlapped entries: {zinfo.orig_filename!r} " f"(possible zip bomb)", skip_file_prefixes=(os.path.dirname(__file__),)) else: raise BadZipFile( f"Overlapped entries: {zinfo.orig_filename!r} " f"(possible zip bomb)") # check for encrypted flag & handle password is_encrypted = zinfo.flag_bits & _MASK_ENCRYPTED if is_encrypted: if not pwd: pwd = self.pwd if pwd and not isinstance(pwd, bytes): raise TypeError("pwd: expected bytes, got %s" % type(pwd).__name__) if not pwd: raise RuntimeError("File %r is encrypted, password " "required for extraction" % name) else: pwd = None return ZipExtFile(zef_file, mode, zinfo, pwd, True) except: zef_file.close() raise def _open_to_write(self, zinfo, force_zip64=False): if force_zip64 and not self._allowZip64: raise ValueError( "force_zip64 is True, but allowZip64 was False when opening " "the ZIP file." ) if self._writing: raise ValueError("Can't write to the ZIP file while there is " "another write handle open on it. " "Close the first handle before opening another.") # Size and CRC are overwritten with correct data after processing the file zinfo.compress_size = 0 zinfo.CRC = 0 zinfo.flag_bits = 0x00 if zinfo.compress_type == ZIP_LZMA: # Compressed data includes an end-of-stream (EOS) marker zinfo.flag_bits |= _MASK_COMPRESS_OPTION_1 if not self._seekable: zinfo.flag_bits |= _MASK_USE_DATA_DESCRIPTOR if not zinfo.external_attr: zinfo.external_attr = 0o600 << 16 # permissions: ?rw------- # Compressed size can be larger than uncompressed size zip64 = force_zip64 or (zinfo.file_size * 1.05 > ZIP64_LIMIT) if not self._allowZip64 and zip64: raise LargeZipFile("Filesize would require ZIP64 extensions") if self._seekable: self.fp.seek(self.start_dir) zinfo.header_offset = self.fp.tell() self._writecheck(zinfo) self._didModify = True self.fp.write(zinfo.FileHeader(zip64)) self._writing = True return _ZipWriteFile(self, zinfo, zip64) def extract(self, member, path=None, pwd=None): """Extract a member from the archive to the current working directory, using its full name. Its file information is extracted as accurately as possible. `member' may be a filename or a ZipInfo object. You can specify a different directory using `path'. You can specify the password to decrypt the file using 'pwd'. """ if path is None: path = os.getcwd() else: path = os.fspath(path) return self._extract_member(member, path, pwd) def extractall(self, path=None, members=None, pwd=None): """Extract all members from the archive to the current working directory. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the list returned by namelist(). You can specify the password to decrypt all files using 'pwd'. """ if members is None: members = self.namelist() if path is None: path = os.getcwd() else: path = os.fspath(path) for zipinfo in members: self._extract_member(zipinfo, path, pwd) @classmethod def _sanitize_windows_name(cls, arcname, pathsep): """Replace bad characters and remove trailing dots from parts.""" table = cls._windows_illegal_name_trans_table if not table: illegal = ':<>|"?*' table = str.maketrans(illegal, '_' * len(illegal)) cls._windows_illegal_name_trans_table = table arcname = arcname.translate(table) # remove trailing dots and spaces arcname = (x.rstrip(' .') for x in arcname.split(pathsep)) # rejoin, removing empty parts. arcname = pathsep.join(x for x in arcname if x) return arcname def _extract_member(self, member, targetpath, pwd): """Extract the ZipInfo object 'member' to a physical file on the path targetpath. """ if not isinstance(member, ZipInfo): member = self.getinfo(member) # build the destination pathname, replacing # forward slashes to platform specific separators. arcname = member.filename.replace('/', os.path.sep) if os.path.altsep: arcname = arcname.replace(os.path.altsep, os.path.sep) # interpret absolute pathname as relative, remove drive letter or # UNC path, redundant separators, "." and ".." components. arcname = os.path.splitdrive(arcname)[1] invalid_path_parts = ('', os.path.curdir, os.path.pardir) arcname = os.path.sep.join(x for x in arcname.split(os.path.sep) if x not in invalid_path_parts) if os.path.sep == '\\': # filter illegal characters on Windows arcname = self._sanitize_windows_name(arcname, os.path.sep) if not arcname and not member.is_dir(): raise ValueError("Empty filename.") targetpath = os.path.join(targetpath, arcname) targetpath = os.path.normpath(targetpath) # Create all upper directories if necessary. upperdirs = os.path.dirname(targetpath) if upperdirs and not os.path.exists(upperdirs): os.makedirs(upperdirs) if member.is_dir(): if not os.path.isdir(targetpath): os.mkdir(targetpath) return targetpath with self.open(member, pwd=pwd) as source, \ open(targetpath, "wb") as target: shutil.copyfileobj(source, target) return targetpath def _writecheck(self, zinfo): """Check for errors before writing a file to the archive.""" if zinfo.filename in self.NameToInfo: import warnings warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3) if self.mode not in ('w', 'x', 'a'): raise ValueError("write() requires mode 'w', 'x', or 'a'") if not self.fp: raise ValueError( "Attempt to write ZIP archive that was already closed") _check_compression(zinfo.compress_type) if not self._allowZip64: requires_zip64 = None if len(self.filelist) >= ZIP_FILECOUNT_LIMIT: requires_zip64 = "Files count" elif zinfo.file_size > ZIP64_LIMIT: requires_zip64 = "Filesize" elif zinfo.header_offset > ZIP64_LIMIT: requires_zip64 = "Zipfile size" if requires_zip64: raise LargeZipFile(requires_zip64 + " would require ZIP64 extensions") def write(self, filename, arcname=None, compress_type=None, compresslevel=None): """Put the bytes from filename into the archive under the name arcname.""" if not self.fp: raise ValueError( "Attempt to write to ZIP archive that was already closed") if self._writing: raise ValueError( "Can't write to ZIP archive while an open writing handle exists" ) zinfo = ZipInfo.from_file(filename, arcname, strict_timestamps=self._strict_timestamps) if zinfo.is_dir(): zinfo.compress_size = 0 zinfo.CRC = 0 self.mkdir(zinfo) else: if compress_type is not None: zinfo.compress_type = compress_type else: zinfo.compress_type = self.compression if compresslevel is not None: zinfo._compresslevel = compresslevel else: zinfo._compresslevel = self.compresslevel with open(filename, "rb") as src, self.open(zinfo, 'w') as dest: shutil.copyfileobj(src, dest, 1024*8) def writestr(self, zinfo_or_arcname, data, compress_type=None, compresslevel=None): """Write a file into the archive. The contents is 'data', which may be either a 'str' or a 'bytes' instance; if it is a 'str', it is encoded as UTF-8 first. 'zinfo_or_arcname' is either a ZipInfo instance or the name of the file in the archive.""" if isinstance(data, str): data = data.encode("utf-8") if not isinstance(zinfo_or_arcname, ZipInfo): zinfo = ZipInfo(filename=zinfo_or_arcname, date_time=time.localtime(time.time())[:6]) zinfo.compress_type = self.compression zinfo._compresslevel = self.compresslevel if zinfo.filename.endswith('/'): zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x zinfo.external_attr |= 0x10 # MS-DOS directory flag else: zinfo.external_attr = 0o600 << 16 # ?rw------- else: zinfo = zinfo_or_arcname if not self.fp: raise ValueError( "Attempt to write to ZIP archive that was already closed") if self._writing: raise ValueError( "Can't write to ZIP archive while an open writing handle exists." ) if compress_type is not None: zinfo.compress_type = compress_type if compresslevel is not None: zinfo._compresslevel = compresslevel zinfo.file_size = len(data) # Uncompressed size with self._lock: with self.open(zinfo, mode='w') as dest: dest.write(data) def mkdir(self, zinfo_or_directory_name, mode=511): """Creates a directory inside the zip archive.""" if isinstance(zinfo_or_directory_name, ZipInfo): zinfo = zinfo_or_directory_name if not zinfo.is_dir(): raise ValueError("The given ZipInfo does not describe a directory") elif isinstance(zinfo_or_directory_name, str): directory_name = zinfo_or_directory_name if not directory_name.endswith("/"): directory_name += "/" zinfo = ZipInfo(directory_name) zinfo.compress_size = 0 zinfo.CRC = 0 zinfo.external_attr = ((0o40000 | mode) & 0xFFFF) << 16 zinfo.file_size = 0 zinfo.external_attr |= 0x10 else: raise TypeError("Expected type str or ZipInfo") with self._lock: if self._seekable: self.fp.seek(self.start_dir) zinfo.header_offset = self.fp.tell() # Start of header bytes if zinfo.compress_type == ZIP_LZMA: # Compressed data includes an end-of-stream (EOS) marker zinfo.flag_bits |= _MASK_COMPRESS_OPTION_1 self._writecheck(zinfo) self._didModify = True self.filelist.append(zinfo) self.NameToInfo[zinfo.filename] = zinfo self.fp.write(zinfo.FileHeader(False)) self.start_dir = self.fp.tell() def __del__(self): """Call the "close()" method in case the user forgot.""" self.close() def close(self): """Close the file, and for mode 'w', 'x' and 'a' write the ending records.""" if self.fp is None: return if self._writing: raise ValueError("Can't close the ZIP file while there is " "an open writing handle on it. " "Close the writing handle before closing the zip.") try: if self.mode in ('w', 'x', 'a') and self._didModify: # write ending records with self._lock: if self._seekable: self.fp.seek(self.start_dir) self._write_end_record() finally: fp = self.fp self.fp = None self._fpclose(fp) def _write_end_record(self): for zinfo in self.filelist: # write central directory dt = zinfo.date_time dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) extra = [] if zinfo.file_size > ZIP64_LIMIT \ or zinfo.compress_size > ZIP64_LIMIT: extra.append(zinfo.file_size) extra.append(zinfo.compress_size) file_size = 0xffffffff compress_size = 0xffffffff else: file_size = zinfo.file_size compress_size = zinfo.compress_size if zinfo.header_offset > ZIP64_LIMIT: extra.append(zinfo.header_offset) header_offset = 0xffffffff else: header_offset = zinfo.header_offset extra_data = zinfo.extra min_version = 0 if extra: # Append a ZIP64 field to the extra's extra_data = _strip_extra(extra_data, (1,)) extra_data = struct.pack( ' ZIP_FILECOUNT_LIMIT: requires_zip64 = "Files count" elif centDirOffset > ZIP64_LIMIT: requires_zip64 = "Central directory offset" elif centDirSize > ZIP64_LIMIT: requires_zip64 = "Central directory size" if requires_zip64: # Need to write the ZIP64 end-of-archive records if not self._allowZip64: raise LargeZipFile(requires_zip64 + " would require ZIP64 extensions") zip64endrec = struct.pack( structEndArchive64, stringEndArchive64, sizeEndCentDir64 - 12, 45, 45, 0, 0, centDirCount, centDirCount, centDirSize, centDirOffset) self.fp.write(zip64endrec) zip64locrec = struct.pack( structEndArchive64Locator, stringEndArchive64Locator, 0, pos2, 1) self.fp.write(zip64locrec) centDirCount = min(centDirCount, 0xFFFF) centDirSize = min(centDirSize, 0xFFFFFFFF) centDirOffset = min(centDirOffset, 0xFFFFFFFF) endrec = struct.pack(structEndArchive, stringEndArchive, 0, 0, centDirCount, centDirCount, centDirSize, centDirOffset, len(self._comment)) self.fp.write(endrec) self.fp.write(self._comment) if self.mode == "a": self.fp.truncate() self.fp.flush() def _fpclose(self, fp): assert self._fileRefCnt > 0 self._fileRefCnt -= 1 if not self._fileRefCnt and not self._filePassed: fp.close() class PyZipFile(ZipFile): """Class to create ZIP archives with Python library files and packages.""" def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True, optimize=-1): ZipFile.__init__(self, file, mode=mode, compression=compression, allowZip64=allowZip64) self._optimize = optimize def writepy(self, pathname, basename="", filterfunc=None): """Add all files from "pathname" to the ZIP archive. If pathname is a package directory, search the directory and all package subdirectories recursively for all *.py and enter the modules into the archive. If pathname is a plain directory, listdir *.py and enter all modules. Else, pathname must be a Python *.py file and the module will be put into the archive. Added modules are always module.pyc. This method will compile the module.py into module.pyc if necessary. If filterfunc(pathname) is given, it is called with every argument. When it is False, the file or directory is skipped. """ pathname = os.fspath(pathname) if filterfunc and not filterfunc(pathname): if self.debug: label = 'path' if os.path.isdir(pathname) else 'file' print('%s %r skipped by filterfunc' % (label, pathname)) return dir, name = os.path.split(pathname) if os.path.isdir(pathname): initname = os.path.join(pathname, "__init__.py") if os.path.isfile(initname): # This is a package directory, add it if basename: basename = "%s/%s" % (basename, name) else: basename = name if self.debug: print("Adding package in", pathname, "as", basename) fname, arcname = self._get_codename(initname[0:-3], basename) if self.debug: print("Adding", arcname) self.write(fname, arcname) dirlist = sorted(os.listdir(pathname)) dirlist.remove("__init__.py") # Add all *.py files and package subdirectories for filename in dirlist: path = os.path.join(pathname, filename) root, ext = os.path.splitext(filename) if os.path.isdir(path): if os.path.isfile(os.path.join(path, "__init__.py")): # This is a package directory, add it self.writepy(path, basename, filterfunc=filterfunc) # Recursive call elif ext == ".py": if filterfunc and not filterfunc(path): if self.debug: print('file %r skipped by filterfunc' % path) continue fname, arcname = self._get_codename(path[0:-3], basename) if self.debug: print("Adding", arcname) self.write(fname, arcname) else: # This is NOT a package directory, add its files at top level if self.debug: print("Adding files from directory", pathname) for filename in sorted(os.listdir(pathname)): path = os.path.join(pathname, filename) root, ext = os.path.splitext(filename) if ext == ".py": if filterfunc and not filterfunc(path): if self.debug: print('file %r skipped by filterfunc' % path) continue fname, arcname = self._get_codename(path[0:-3], basename) if self.debug: print("Adding", arcname) self.write(fname, arcname) else: if pathname[-3:] != ".py": raise RuntimeError( 'Files added with writepy() must end with ".py"') fname, arcname = self._get_codename(pathname[0:-3], basename) if self.debug: print("Adding file", arcname) self.write(fname, arcname) def _get_codename(self, pathname, basename): """Return (filename, archivename) for the path. Given a module name path, return the correct file path and archive name, compiling if necessary. For example, given /python/lib/string, return (/python/lib/string.pyc, string). """ def _compile(file, optimize=-1): import py_compile if self.debug: print("Compiling", file) try: py_compile.compile(file, doraise=True, optimize=optimize) except py_compile.PyCompileError as err: print(err.msg) return False return True file_py = pathname + ".py" file_pyc = pathname + ".pyc" pycache_opt0 = importlib.util.cache_from_source(file_py, optimization='') pycache_opt1 = importlib.util.cache_from_source(file_py, optimization=1) pycache_opt2 = importlib.util.cache_from_source(file_py, optimization=2) if self._optimize == -1: # legacy mode: use whatever file is present if (os.path.isfile(file_pyc) and os.stat(file_pyc).st_mtime >= os.stat(file_py).st_mtime): # Use .pyc file. arcname = fname = file_pyc elif (os.path.isfile(pycache_opt0) and os.stat(pycache_opt0).st_mtime >= os.stat(file_py).st_mtime): # Use the __pycache__/*.pyc file, but write it to the legacy pyc # file name in the archive. fname = pycache_opt0 arcname = file_pyc elif (os.path.isfile(pycache_opt1) and os.stat(pycache_opt1).st_mtime >= os.stat(file_py).st_mtime): # Use the __pycache__/*.pyc file, but write it to the legacy pyc # file name in the archive. fname = pycache_opt1 arcname = file_pyc elif (os.path.isfile(pycache_opt2) and os.stat(pycache_opt2).st_mtime >= os.stat(file_py).st_mtime): # Use the __pycache__/*.pyc file, but write it to the legacy pyc # file name in the archive. fname = pycache_opt2 arcname = file_pyc else: # Compile py into PEP 3147 pyc file. if _compile(file_py): if sys.flags.optimize == 0: fname = pycache_opt0 elif sys.flags.optimize == 1: fname = pycache_opt1 else: fname = pycache_opt2 arcname = file_pyc else: fname = arcname = file_py else: # new mode: use given optimization level if self._optimize == 0: fname = pycache_opt0 arcname = file_pyc else: arcname = file_pyc if self._optimize == 1: fname = pycache_opt1 elif self._optimize == 2: fname = pycache_opt2 else: msg = "invalid value for 'optimize': {!r}".format(self._optimize) raise ValueError(msg) if not (os.path.isfile(fname) and os.stat(fname).st_mtime >= os.stat(file_py).st_mtime): if not _compile(file_py, optimize=self._optimize): fname = arcname = file_py archivename = os.path.split(arcname)[1] if basename: archivename = "%s/%s" % (basename, archivename) return (fname, archivename) def main(args=None): import argparse description = 'A simple command-line interface for zipfile module.' parser = argparse.ArgumentParser(description=description) group = parser.add_mutually_exclusive_group(required=True) group.add_argument('-l', '--list', metavar='', help='Show listing of a zipfile') group.add_argument('-e', '--extract', nargs=2, metavar=('', ''), help='Extract zipfile into target dir') group.add_argument('-c', '--create', nargs='+', metavar=('', ''), help='Create zipfile from sources') group.add_argument('-t', '--test', metavar='', help='Test if a zipfile is valid') parser.add_argument('--metadata-encoding', metavar='', help='Specify encoding of member names for -l, -e and -t') args = parser.parse_args(args) encoding = args.metadata_encoding if args.test is not None: src = args.test with ZipFile(src, 'r', metadata_encoding=encoding) as zf: badfile = zf.testzip() if badfile: print("The following enclosed file is corrupted: {!r}".format(badfile)) print("Done testing") elif args.list is not None: src = args.list with ZipFile(src, 'r', metadata_encoding=encoding) as zf: zf.printdir() elif args.extract is not None: src, curdir = args.extract with ZipFile(src, 'r', metadata_encoding=encoding) as zf: zf.extractall(curdir) elif args.create is not None: if encoding: print("Non-conforming encodings not supported with -c.", file=sys.stderr) sys.exit(1) zip_name = args.create.pop(0) files = args.create def addToZip(zf, path, zippath): if os.path.isfile(path): zf.write(path, zippath, ZIP_DEFLATED) elif os.path.isdir(path): if zippath: zf.write(path, zippath) for nm in sorted(os.listdir(path)): addToZip(zf, os.path.join(path, nm), os.path.join(zippath, nm)) # else: ignore with ZipFile(zip_name, 'w') as zf: for path in files: zippath = os.path.basename(path) if not zippath: zippath = os.path.basename(os.path.dirname(path)) if zippath in ('', os.curdir, os.pardir): zippath = '' addToZip(zf, path, zippath) from ._path import ( # noqa: E402 Path, # used privately for tests CompleteDirs, # noqa: F401 ) usr/lib64/python3.6/asyncio/__init__.py000064400000002634152346133130013631 0ustar00"""The asyncio package, tracking PEP 3156.""" import sys # The selectors module is in the stdlib in Python 3.4 but not in 3.3. # Do this first, so the other submodules can use "from . import selectors". # Prefer asyncio/selectors.py over the stdlib one, as ours may be newer. try: from . import selectors except ImportError: import selectors # Will also be exported. if sys.platform == 'win32': # Similar thing for _overlapped. try: from . import _overlapped except ImportError: import _overlapped # Will also be exported. # This relies on each of the submodules having an __all__ variable. from .base_events import * from .coroutines import * from .events import * from .futures import * from .locks import * from .protocols import * from .queues import * from .streams import * from .subprocess import * from .tasks import * from .transports import * __all__ = (base_events.__all__ + coroutines.__all__ + events.__all__ + futures.__all__ + locks.__all__ + protocols.__all__ + queues.__all__ + streams.__all__ + subprocess.__all__ + tasks.__all__ + transports.__all__) if sys.platform == 'win32': # pragma: no cover from .windows_events import * __all__ += windows_events.__all__ else: from .unix_events import * # pragma: no cover __all__ += unix_events.__all__ usr/lib64/python3.12/curses/__init__.py000064400000006451152346134630013554 0ustar00"""curses The main package for curses support for Python. Normally used by importing the package, and perhaps a particular module inside it. import curses from curses import textpad curses.initscr() ... """ from _curses import * import os as _os import sys as _sys # Some constants, most notably the ACS_* ones, are only added to the C # _curses module's dictionary after initscr() is called. (Some # versions of SGI's curses don't define values for those constants # until initscr() has been called.) This wrapper function calls the # underlying C initscr(), and then copies the constants from the # _curses module to the curses package's dictionary. Don't do 'from # curses import *' if you'll be needing the ACS_* constants. def initscr(): import _curses, curses # we call setupterm() here because it raises an error # instead of calling exit() in error cases. setupterm(term=_os.environ.get("TERM", "unknown"), fd=_sys.__stdout__.fileno()) stdscr = _curses.initscr() for key, value in _curses.__dict__.items(): if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): setattr(curses, key, value) return stdscr # This is a similar wrapper for start_color(), which adds the COLORS and # COLOR_PAIRS variables which are only available after start_color() is # called. def start_color(): import _curses, curses retval = _curses.start_color() if hasattr(_curses, 'COLORS'): curses.COLORS = _curses.COLORS if hasattr(_curses, 'COLOR_PAIRS'): curses.COLOR_PAIRS = _curses.COLOR_PAIRS return retval # Import Python has_key() implementation if _curses doesn't contain has_key() try: has_key except NameError: from .has_key import has_key # Wrapper for the entire curses-based application. Runs a function which # should be the rest of your curses-based application. If the application # raises an exception, wrapper() will restore the terminal to a sane state so # you can read the resulting traceback. def wrapper(func, /, *args, **kwds): """Wrapper function that initializes curses and calls another function, restoring normal keyboard/screen behavior on error. The callable object 'func' is then passed the main window 'stdscr' as its first argument, followed by any other arguments passed to wrapper(). """ try: # Initialize curses stdscr = initscr() # Turn off echoing of keys, and enter cbreak mode, # where no buffering is performed on keyboard input noecho() cbreak() # In keypad mode, escape sequences for special keys # (like the cursor keys) will be interpreted and # a special value like curses.KEY_LEFT will be returned stdscr.keypad(1) # Start color, too. Harmless if the terminal doesn't have # color; user can test with has_color() later on. The try/catch # works around a minor bit of over-conscientiousness in the curses # module -- the error return from C start_color() is ignorable. try: start_color() except: pass return func(stdscr, *args, **kwds) finally: # Set everything back to normal if 'stdscr' in locals(): stdscr.keypad(0) echo() nocbreak() endwin() usr/lib/python3.6/site-packages/urllib3/__init__.py000064400000005242152346140640016110 0ustar00""" urllib3 - Thread-safe connection pooling and re-using. """ from __future__ import absolute_import import warnings from .connectionpool import ( HTTPConnectionPool, HTTPSConnectionPool, connection_from_url ) from . import exceptions from .filepost import encode_multipart_formdata from .poolmanager import PoolManager, ProxyManager, proxy_from_url from .response import HTTPResponse from .util.request import make_headers from .util.url import get_host from .util.timeout import Timeout from .util.retry import Retry # Set default logging handler to avoid "No handler found" warnings. import logging from logging import NullHandler __author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' __license__ = 'MIT' __version__ = '1.24.2' __all__ = ( 'HTTPConnectionPool', 'HTTPSConnectionPool', 'PoolManager', 'ProxyManager', 'HTTPResponse', 'Retry', 'Timeout', 'add_stderr_logger', 'connection_from_url', 'disable_warnings', 'encode_multipart_formdata', 'get_host', 'make_headers', 'proxy_from_url', ) logging.getLogger(__name__).addHandler(NullHandler()) def add_stderr_logger(level=logging.DEBUG): """ Helper for quickly adding a StreamHandler to the logger. Useful for debugging. Returns the handler after adding it. """ # This method needs to be in this __init__.py to get the __name__ correct # even if urllib3 is vendored within another package. logger = logging.getLogger(__name__) handler = logging.StreamHandler() handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) logger.addHandler(handler) logger.setLevel(level) logger.debug('Added a stderr logging handler to logger: %s', __name__) return handler # ... Clean up. del NullHandler # All warning filters *must* be appended unless you're really certain that they # shouldn't be: otherwise, it's very hard for users to use most Python # mechanisms to silence them. # SecurityWarning's always go off by default. warnings.simplefilter('always', exceptions.SecurityWarning, append=True) # SubjectAltNameWarning's should go off once per host warnings.simplefilter('default', exceptions.SubjectAltNameWarning, append=True) # InsecurePlatformWarning's don't vary between requests, so we keep it default. warnings.simplefilter('default', exceptions.InsecurePlatformWarning, append=True) # SNIMissingWarnings should go off only once. warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True) def disable_warnings(category=exceptions.HTTPWarning): """ Helper for quickly disabling all urllib3 warnings. """ warnings.simplefilter('ignore', category) lib64/python3.6/site-packages/dbus/__init__.py000064400000007364152346142330015037 0ustar00"""\ Implements the public API for a D-Bus client. See the dbus.service module to export objects or claim well-known names. .. for epydoc's benefit :NewField SupportedUsage: Supported usage :NewField Constructor: Constructor """ # Copyright (C) 2003, 2004, 2005, 2006 Red Hat Inc. # Copyright (C) 2003 David Zeuthen # Copyright (C) 2004 Rob Taylor # Copyright (C) 2005, 2006 Collabora Ltd. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. __all__ = [ # from _dbus 'Bus', 'SystemBus', 'SessionBus', 'StarterBus', # from proxies 'Interface', # from _dbus_bindings 'get_default_main_loop', 'set_default_main_loop', 'validate_interface_name', 'validate_member_name', 'validate_bus_name', 'validate_object_path', 'validate_error_name', 'BUS_DAEMON_NAME', 'BUS_DAEMON_PATH', 'BUS_DAEMON_IFACE', 'LOCAL_PATH', 'LOCAL_IFACE', 'PEER_IFACE', 'INTROSPECTABLE_IFACE', 'PROPERTIES_IFACE', 'ObjectPath', 'ByteArray', 'Signature', 'Byte', 'Boolean', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64', 'Double', 'String', 'Array', 'Struct', 'Dictionary', # from exceptions 'DBusException', 'MissingErrorHandlerException', 'MissingReplyHandlerException', 'ValidationException', 'IntrospectionParserException', 'UnknownMethodException', 'NameExistsException', # submodules 'service', 'mainloop', 'lowlevel' ] from dbus._compat import is_py2 if is_py2: __all__.append('UTF8String') __docformat__ = 'restructuredtext' # OLPC Sugar compatibility import dbus.exceptions as exceptions import dbus.types as types from _dbus_bindings import __version__ version = tuple(map(int, __version__.split('.'))) from _dbus_bindings import ( get_default_main_loop, set_default_main_loop, validate_bus_name, validate_error_name, validate_interface_name, validate_member_name, validate_object_path) from _dbus_bindings import ( BUS_DAEMON_IFACE, BUS_DAEMON_NAME, BUS_DAEMON_PATH, INTROSPECTABLE_IFACE, LOCAL_IFACE, LOCAL_PATH, PEER_IFACE, PROPERTIES_IFACE) from dbus.exceptions import ( DBusException, IntrospectionParserException, MissingErrorHandlerException, MissingReplyHandlerException, NameExistsException, UnknownMethodException, ValidationException) from _dbus_bindings import ( Array, Boolean, Byte, ByteArray, Dictionary, Double, Int16, Int32, Int64, ObjectPath, Signature, String, Struct, UInt16, UInt32, UInt64) if is_py2: from _dbus_bindings import UTF8String from dbus._dbus import Bus, SystemBus, SessionBus, StarterBus from dbus.proxies import Interface usr/lib64/python3.8/multiprocessing/__init__.py000064400000001624152346142420015415 0ustar00# # Package analogous to 'threading.py' but using processes # # multiprocessing/__init__.py # # This package is intended to duplicate the functionality (and much of # the API) of threading.py but uses processes instead of threads. A # subpackage 'multiprocessing.dummy' has the same API but is a simple # wrapper for 'threading'. # # Copyright (c) 2006-2008, R Oudkerk # Licensed to PSF under a Contributor Agreement. # import sys from . import context # # Copy stuff from default context # __all__ = [x for x in dir(context._default_context) if not x.startswith('_')] globals().update((name, getattr(context._default_context, name)) for name in __all__) # # XXX These should not really be documented or public. # SUBDEBUG = 5 SUBWARNING = 25 # # Alias for main module -- will be reset by bootstrapping child processes # if '__main__' in sys.modules: sys.modules['__mp_main__'] = sys.modules['__main__'] usr/lib64/python3.6/xml/sax/__init__.py000064400000007056152346152010013560 0ustar00"""Simple API for XML (SAX) implementation for Python. This module provides an implementation of the SAX 2 interface; information about the Java version of the interface can be found at http://www.megginson.com/SAX/. The Python version of the interface is documented at <...>. This package contains the following modules: handler -- Base classes and constants which define the SAX 2 API for the 'client-side' of SAX for Python. saxutils -- Implementation of the convenience classes commonly used to work with SAX. xmlreader -- Base classes and constants which define the SAX 2 API for the parsers used with SAX for Python. expatreader -- Driver that allows use of the Expat parser with SAX. """ from .xmlreader import InputSource from .handler import ContentHandler, ErrorHandler from ._exceptions import SAXException, SAXNotRecognizedException, \ SAXParseException, SAXNotSupportedException, \ SAXReaderNotAvailable def parse(source, handler, errorHandler=ErrorHandler()): parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) parser.parse(source) def parseString(string, handler, errorHandler=ErrorHandler()): import io if errorHandler is None: errorHandler = ErrorHandler() parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) inpsrc = InputSource() if isinstance(string, str): inpsrc.setCharacterStream(io.StringIO(string)) else: inpsrc.setByteStream(io.BytesIO(string)) parser.parse(inpsrc) # this is the parser list used by the make_parser function if no # alternatives are given as parameters to the function default_parser_list = ["xml.sax.expatreader"] # tell modulefinder that importing sax potentially imports expatreader _false = 0 if _false: import xml.sax.expatreader import os, sys if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ: default_parser_list = os.environ["PY_SAX_PARSER"].split(",") del os _key = "python.xml.sax.parser" if sys.platform[:4] == "java" and sys.registry.containsKey(_key): default_parser_list = sys.registry.getProperty(_key).split(",") def make_parser(parser_list = []): """Creates and returns a SAX parser. Creates the first parser it is able to instantiate of the ones given in the list created by doing parser_list + default_parser_list. The lists must contain the names of Python modules containing both a SAX parser and a create_parser function.""" for parser_name in parser_list + default_parser_list: try: return _create_parser(parser_name) except ImportError as e: import sys if parser_name in sys.modules: # The parser module was found, but importing it # failed unexpectedly, pass this exception through raise except SAXReaderNotAvailable: # The parser module detected that it won't work properly, # so try the next one pass raise SAXReaderNotAvailable("No parsers found", None) # --- Internal utility methods used by make_parser if sys.platform[ : 4] == "java": def _create_parser(parser_name): from org.python.core import imp drv_module = imp.importName(parser_name, 0, globals()) return drv_module.create_parser() else: def _create_parser(parser_name): drv_module = __import__(parser_name,{},{},['create_parser']) return drv_module.create_parser() del sys usr/lib64/python3.12/xml/etree/__init__.py000064400000003105152346166650014154 0ustar00# $Id: __init__.py 3375 2008-02-13 08:05:08Z fredrik $ # elementtree package # -------------------------------------------------------------------- # The ElementTree toolkit is # # Copyright (c) 1999-2008 by Fredrik Lundh # # By obtaining, using, and/or copying this software and/or its # associated documentation, you agree that you have read, understood, # and will comply with the following terms and conditions: # # Permission to use, copy, modify, and distribute this software and # its associated documentation for any purpose and without fee is # hereby granted, provided that the above copyright notice appears in # all copies, and that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of # Secret Labs AB or the author not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # OF THIS SOFTWARE. # -------------------------------------------------------------------- # Licensed to PSF under a Contributor Agreement. # See https://www.python.org/psf/license for licensing details. usr/lib64/python3.12/venv/__init__.py000064400000064176152346167600013241 0ustar00""" Virtual environment (venv) package for Python. Based on PEP 405. Copyright (C) 2011-2014 Vinay Sajip. Licensed to the PSF under a contributor agreement. """ import logging import os import shutil import subprocess import sys import sysconfig import types import shlex CORE_VENV_DEPS = ('pip',) logger = logging.getLogger(__name__) class EnvBuilder: """ This class exists to allow virtual environment creation to be customized. The constructor parameters determine the builder's behaviour when called upon to create a virtual environment. By default, the builder makes the system (global) site-packages dir *un*available to the created environment. If invoked using the Python -m option, the default is to use copying on Windows platforms but symlinks elsewhere. If instantiated some other way, the default is to *not* use symlinks. :param system_site_packages: If True, the system (global) site-packages dir is available to created environments. :param clear: If True, delete the contents of the environment directory if it already exists, before environment creation. :param symlinks: If True, attempt to symlink rather than copy files into virtual environment. :param upgrade: If True, upgrade an existing virtual environment. :param with_pip: If True, ensure pip is installed in the virtual environment :param prompt: Alternative terminal prefix for the environment. :param upgrade_deps: Update the base venv modules to the latest on PyPI """ def __init__(self, system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None, upgrade_deps=False): self.system_site_packages = system_site_packages self.clear = clear self.symlinks = symlinks self.upgrade = upgrade self.with_pip = with_pip self.orig_prompt = prompt if prompt == '.': # see bpo-38901 prompt = os.path.basename(os.getcwd()) self.prompt = prompt self.upgrade_deps = upgrade_deps def create(self, env_dir): """ Create a virtual environment in a directory. :param env_dir: The target directory to create an environment in. """ env_dir = os.path.abspath(env_dir) context = self.ensure_directories(env_dir) # See issue 24875. We need system_site_packages to be False # until after pip is installed. true_system_site_packages = self.system_site_packages self.system_site_packages = False self.create_configuration(context) self.setup_python(context) if self.with_pip: self._setup_pip(context) if not self.upgrade: self.setup_scripts(context) self.post_setup(context) if true_system_site_packages: # We had set it to False before, now # restore it and rewrite the configuration self.system_site_packages = True self.create_configuration(context) if self.upgrade_deps: self.upgrade_dependencies(context) def clear_directory(self, path): for fn in os.listdir(path): fn = os.path.join(path, fn) if os.path.islink(fn) or os.path.isfile(fn): os.remove(fn) elif os.path.isdir(fn): shutil.rmtree(fn) def _venv_path(self, env_dir, name): vars = { 'base': env_dir, 'platbase': env_dir, 'installed_base': env_dir, 'installed_platbase': env_dir, } return sysconfig.get_path(name, scheme='venv', vars=vars) @classmethod def _same_path(cls, path1, path2): """Check whether two paths appear the same. Whether they refer to the same file is irrelevant; we're testing for whether a human reader would look at the path string and easily tell that they're the same file. """ if sys.platform == 'win32': if os.path.normcase(path1) == os.path.normcase(path2): return True # gh-90329: Don't display a warning for short/long names import _winapi try: path1 = _winapi.GetLongPathName(os.fsdecode(path1)) except OSError: pass try: path2 = _winapi.GetLongPathName(os.fsdecode(path2)) except OSError: pass if os.path.normcase(path1) == os.path.normcase(path2): return True return False else: return path1 == path2 def ensure_directories(self, env_dir): """ Create the directories for the environment. Returns a context object which holds paths in the environment, for use by subsequent logic. """ def create_if_needed(d): if not os.path.exists(d): os.makedirs(d) elif os.path.islink(d) or os.path.isfile(d): raise ValueError('Unable to create directory %r' % d) if os.pathsep in os.fspath(env_dir): raise ValueError(f'Refusing to create a venv in {env_dir} because ' f'it contains the PATH separator {os.pathsep}.') if os.path.exists(env_dir) and self.clear: self.clear_directory(env_dir) context = types.SimpleNamespace() context.env_dir = env_dir context.env_name = os.path.split(env_dir)[1] prompt = self.prompt if self.prompt is not None else context.env_name context.prompt = '(%s) ' % prompt create_if_needed(env_dir) executable = sys._base_executable if not executable: # see gh-96861 raise ValueError('Unable to determine path to the running ' 'Python interpreter. Provide an explicit path or ' 'check that your PATH environment variable is ' 'correctly set.') dirname, exename = os.path.split(os.path.abspath(executable)) context.executable = executable context.python_dir = dirname context.python_exe = exename binpath = self._venv_path(env_dir, 'scripts') incpath = self._venv_path(env_dir, 'include') libpath = self._venv_path(env_dir, 'purelib') context.inc_path = incpath create_if_needed(incpath) context.lib_path = libpath create_if_needed(libpath) # Issue 21197: create lib64 as a symlink to lib on 64-bit non-OS X POSIX if ((sys.maxsize > 2**32) and (os.name == 'posix') and (sys.platform != 'darwin')): link_path = os.path.join(env_dir, 'lib64') if not os.path.exists(link_path): # Issue #21643 os.symlink('lib', link_path) context.bin_path = binpath context.bin_name = os.path.relpath(binpath, env_dir) context.env_exe = os.path.join(binpath, exename) create_if_needed(binpath) # Assign and update the command to use when launching the newly created # environment, in case it isn't simply the executable script (e.g. bpo-45337) context.env_exec_cmd = context.env_exe if sys.platform == 'win32': # bpo-45337: Fix up env_exec_cmd to account for file system redirections. # Some redirects only apply to CreateFile and not CreateProcess real_env_exe = os.path.realpath(context.env_exe) if not self._same_path(real_env_exe, context.env_exe): logger.warning('Actual environment location may have moved due to ' 'redirects, links or junctions.\n' ' Requested location: "%s"\n' ' Actual location: "%s"', context.env_exe, real_env_exe) context.env_exec_cmd = real_env_exe return context def create_configuration(self, context): """ Create a configuration file indicating where the environment's Python was copied from, and whether the system site-packages should be made available in the environment. :param context: The information for the environment creation request being processed. """ context.cfg_path = path = os.path.join(context.env_dir, 'pyvenv.cfg') with open(path, 'w', encoding='utf-8') as f: f.write('home = %s\n' % context.python_dir) if self.system_site_packages: incl = 'true' else: incl = 'false' f.write('include-system-site-packages = %s\n' % incl) f.write('version = %d.%d.%d\n' % sys.version_info[:3]) if self.prompt is not None: f.write(f'prompt = {self.prompt!r}\n') f.write('executable = %s\n' % os.path.realpath(sys.executable)) args = [] nt = os.name == 'nt' if nt and self.symlinks: args.append('--symlinks') if not nt and not self.symlinks: args.append('--copies') if not self.with_pip: args.append('--without-pip') if self.system_site_packages: args.append('--system-site-packages') if self.clear: args.append('--clear') if self.upgrade: args.append('--upgrade') if self.upgrade_deps: args.append('--upgrade-deps') if self.orig_prompt is not None: args.append(f'--prompt="{self.orig_prompt}"') args.append(context.env_dir) args = ' '.join(args) f.write(f'command = {sys.executable} -m venv {args}\n') if os.name != 'nt': def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): """ Try symlinking a file, and if that fails, fall back to copying. """ force_copy = not self.symlinks if not force_copy: try: if not os.path.islink(dst): # can't link to itself! if relative_symlinks_ok: assert os.path.dirname(src) == os.path.dirname(dst) os.symlink(os.path.basename(src), dst) else: os.symlink(src, dst) except Exception: # may need to use a more specific exception logger.warning('Unable to symlink %r to %r', src, dst) force_copy = True if force_copy: shutil.copyfile(src, dst) else: def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): """ Try symlinking a file, and if that fails, fall back to copying. """ bad_src = os.path.lexists(src) and not os.path.exists(src) if self.symlinks and not bad_src and not os.path.islink(dst): try: if relative_symlinks_ok: assert os.path.dirname(src) == os.path.dirname(dst) os.symlink(os.path.basename(src), dst) else: os.symlink(src, dst) return except Exception: # may need to use a more specific exception logger.warning('Unable to symlink %r to %r', src, dst) # On Windows, we rewrite symlinks to our base python.exe into # copies of venvlauncher.exe basename, ext = os.path.splitext(os.path.basename(src)) srcfn = os.path.join(os.path.dirname(__file__), "scripts", "nt", basename + ext) # Builds or venv's from builds need to remap source file # locations, as we do not put them into Lib/venv/scripts if sysconfig.is_python_build() or not os.path.isfile(srcfn): if basename.endswith('_d'): ext = '_d' + ext basename = basename[:-2] if basename == 'python': basename = 'venvlauncher' elif basename == 'pythonw': basename = 'venvwlauncher' src = os.path.join(os.path.dirname(src), basename + ext) else: src = srcfn if not os.path.exists(src): if not bad_src: logger.warning('Unable to copy %r', src) return shutil.copyfile(src, dst) def setup_python(self, context): """ Set up a Python executable in the environment. :param context: The information for the environment creation request being processed. """ binpath = context.bin_path path = context.env_exe copier = self.symlink_or_copy dirname = context.python_dir if os.name != 'nt': copier(context.executable, path) if not os.path.islink(path): os.chmod(path, 0o755) for suffix in ('python', 'python3', f'python3.{sys.version_info[1]}'): path = os.path.join(binpath, suffix) if not os.path.exists(path): # Issue 18807: make copies if # symlinks are not wanted copier(context.env_exe, path, relative_symlinks_ok=True) if not os.path.islink(path): os.chmod(path, 0o755) else: if self.symlinks: # For symlinking, we need a complete copy of the root directory # If symlinks fail, you'll get unnecessary copies of files, but # we assume that if you've opted into symlinks on Windows then # you know what you're doing. suffixes = [ f for f in os.listdir(dirname) if os.path.normcase(os.path.splitext(f)[1]) in ('.exe', '.dll') ] if sysconfig.is_python_build(): suffixes = [ f for f in suffixes if os.path.normcase(f).startswith(('python', 'vcruntime')) ] else: suffixes = {'python.exe', 'python_d.exe', 'pythonw.exe', 'pythonw_d.exe'} base_exe = os.path.basename(context.env_exe) suffixes.add(base_exe) for suffix in suffixes: src = os.path.join(dirname, suffix) if os.path.lexists(src): copier(src, os.path.join(binpath, suffix)) if sysconfig.is_python_build(): # copy init.tcl for root, dirs, files in os.walk(context.python_dir): if 'init.tcl' in files: tcldir = os.path.basename(root) tcldir = os.path.join(context.env_dir, 'Lib', tcldir) if not os.path.exists(tcldir): os.makedirs(tcldir) src = os.path.join(root, 'init.tcl') dst = os.path.join(tcldir, 'init.tcl') shutil.copyfile(src, dst) break def _call_new_python(self, context, *py_args, **kwargs): """Executes the newly created Python using safe-ish options""" # gh-98251: We do not want to just use '-I' because that masks # legitimate user preferences (such as not writing bytecode). All we # really need is to ensure that the path variables do not overrule # normal venv handling. args = [context.env_exec_cmd, *py_args] kwargs['env'] = env = os.environ.copy() env['VIRTUAL_ENV'] = context.env_dir env.pop('PYTHONHOME', None) env.pop('PYTHONPATH', None) kwargs['cwd'] = context.env_dir kwargs['executable'] = context.env_exec_cmd subprocess.check_output(args, **kwargs) def _setup_pip(self, context): """Installs or upgrades pip in a virtual environment""" self._call_new_python(context, '-m', 'ensurepip', '--upgrade', '--default-pip', stderr=subprocess.STDOUT) def setup_scripts(self, context): """ Set up scripts into the created environment from a directory. This method installs the default scripts into the environment being created. You can prevent the default installation by overriding this method if you really need to, or if you need to specify a different location for the scripts to install. By default, the 'scripts' directory in the venv package is used as the source of scripts to install. """ path = os.path.abspath(os.path.dirname(__file__)) path = os.path.join(path, 'scripts') self.install_scripts(context, path) def post_setup(self, context): """ Hook for post-setup modification of the venv. Subclasses may install additional packages or scripts here, add activation shell scripts, etc. :param context: The information for the environment creation request being processed. """ pass def replace_variables(self, text, context): """ Replace variable placeholders in script text with context-specific variables. Return the text passed in , but with variables replaced. :param text: The text in which to replace placeholder variables. :param context: The information for the environment creation request being processed. """ replacements = { '__VENV_DIR__': context.env_dir, '__VENV_NAME__': context.env_name, '__VENV_PROMPT__': context.prompt, '__VENV_BIN_NAME__': context.bin_name, '__VENV_PYTHON__': context.env_exe, } def quote_ps1(s): """ This should satisfy PowerShell quoting rules [1], unless the quoted string is passed directly to Windows native commands [2]. [1]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules [2]: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing#passing-arguments-that-contain-quote-characters """ s = s.replace("'", "''") return f"'{s}'" def quote_bat(s): return s # gh-124651: need to quote the template strings properly quote = shlex.quote script_path = context.script_path if script_path.endswith('.ps1'): quote = quote_ps1 elif script_path.endswith('.bat'): quote = quote_bat else: # fallbacks to POSIX shell compliant quote quote = shlex.quote replacements = {key: quote(s) for key, s in replacements.items()} for key, quoted in replacements.items(): text = text.replace(key, quoted) return text def install_scripts(self, context, path): """ Install scripts into the created environment from a directory. :param context: The information for the environment creation request being processed. :param path: Absolute pathname of a directory containing script. Scripts in the 'common' subdirectory of this directory, and those in the directory named for the platform being run on, are installed in the created environment. Placeholder variables are replaced with environment- specific values. """ binpath = context.bin_path plen = len(path) for root, dirs, files in os.walk(path): if root == path: # at top-level, remove irrelevant dirs for d in dirs[:]: if d not in ('common', os.name): dirs.remove(d) continue # ignore files in top level for f in files: if (os.name == 'nt' and f.startswith('python') and f.endswith(('.exe', '.pdb'))): continue srcfile = os.path.join(root, f) suffix = root[plen:].split(os.sep)[2:] if not suffix: dstdir = binpath else: dstdir = os.path.join(binpath, *suffix) if not os.path.exists(dstdir): os.makedirs(dstdir) dstfile = os.path.join(dstdir, f) with open(srcfile, 'rb') as f: data = f.read() if not srcfile.endswith(('.exe', '.pdb')): context.script_path = srcfile try: data = data.decode('utf-8') data = self.replace_variables(data, context) data = data.encode('utf-8') except UnicodeError as e: data = None logger.warning('unable to copy script %r, ' 'may be binary: %s', srcfile, e) if data is not None: with open(dstfile, 'wb') as f: f.write(data) shutil.copymode(srcfile, dstfile) def upgrade_dependencies(self, context): logger.debug( f'Upgrading {CORE_VENV_DEPS} packages in {context.bin_path}' ) self._call_new_python(context, '-m', 'pip', 'install', '--upgrade', *CORE_VENV_DEPS) def create(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None, upgrade_deps=False): """Create a virtual environment in a directory.""" builder = EnvBuilder(system_site_packages=system_site_packages, clear=clear, symlinks=symlinks, with_pip=with_pip, prompt=prompt, upgrade_deps=upgrade_deps) builder.create(env_dir) def main(args=None): import argparse parser = argparse.ArgumentParser(prog=__name__, description='Creates virtual Python ' 'environments in one or ' 'more target ' 'directories.', epilog='Once an environment has been ' 'created, you may wish to ' 'activate it, e.g. by ' 'sourcing an activate script ' 'in its bin directory.') parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', help='A directory to create the environment in.') parser.add_argument('--system-site-packages', default=False, action='store_true', dest='system_site', help='Give the virtual environment access to the ' 'system site-packages dir.') if os.name == 'nt': use_symlinks = False else: use_symlinks = True group = parser.add_mutually_exclusive_group() group.add_argument('--symlinks', default=use_symlinks, action='store_true', dest='symlinks', help='Try to use symlinks rather than copies, ' 'when symlinks are not the default for ' 'the platform.') group.add_argument('--copies', default=not use_symlinks, action='store_false', dest='symlinks', help='Try to use copies rather than symlinks, ' 'even when symlinks are the default for ' 'the platform.') parser.add_argument('--clear', default=False, action='store_true', dest='clear', help='Delete the contents of the ' 'environment directory if it ' 'already exists, before ' 'environment creation.') parser.add_argument('--upgrade', default=False, action='store_true', dest='upgrade', help='Upgrade the environment ' 'directory to use this version ' 'of Python, assuming Python ' 'has been upgraded in-place.') parser.add_argument('--without-pip', dest='with_pip', default=True, action='store_false', help='Skips installing or upgrading pip in the ' 'virtual environment (pip is bootstrapped ' 'by default)') parser.add_argument('--prompt', help='Provides an alternative prompt prefix for ' 'this environment.') parser.add_argument('--upgrade-deps', default=False, action='store_true', dest='upgrade_deps', help=f'Upgrade core dependencies ({", ".join(CORE_VENV_DEPS)}) ' 'to the latest version in PyPI') options = parser.parse_args(args) if options.upgrade and options.clear: raise ValueError('you cannot supply --upgrade and --clear together.') builder = EnvBuilder(system_site_packages=options.system_site, clear=options.clear, symlinks=options.symlinks, upgrade=options.upgrade, with_pip=options.with_pip, prompt=options.prompt, upgrade_deps=options.upgrade_deps) for d in options.dirs: builder.create(d) if __name__ == '__main__': rc = 1 try: main() rc = 0 except Exception as e: print('Error: %s' % e, file=sys.stderr) sys.exit(rc) usr/lib64/python3.12/urllib/__init__.py000064400000000000152346175160013524 0ustar00usr/lib64/python3.12/importlib/__init__.py000064400000011260152346177200014243 0ustar00"""A pure Python implementation of import.""" __all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload'] # Bootstrap help ##################################################### # Until bootstrapping is complete, DO NOT import any modules that attempt # to import importlib._bootstrap (directly or indirectly). Since this # partially initialised package would be present in sys.modules, those # modules would get an uninitialised copy of the source version, instead # of a fully initialised version (either the frozen one or the one # initialised below if the frozen one is not available). import _imp # Just the builtin component, NOT the full Python module import sys try: import _frozen_importlib as _bootstrap except ImportError: from . import _bootstrap _bootstrap._setup(sys, _imp) else: # importlib._bootstrap is the built-in import, ensure we don't create # a second copy of the module. _bootstrap.__name__ = 'importlib._bootstrap' _bootstrap.__package__ = 'importlib' try: _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap'] = _bootstrap try: import _frozen_importlib_external as _bootstrap_external except ImportError: from . import _bootstrap_external _bootstrap_external._set_bootstrap_module(_bootstrap) _bootstrap._bootstrap_external = _bootstrap_external else: _bootstrap_external.__name__ = 'importlib._bootstrap_external' _bootstrap_external.__package__ = 'importlib' try: _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap_external'] = _bootstrap_external # To simplify imports in test code _pack_uint32 = _bootstrap_external._pack_uint32 _unpack_uint32 = _bootstrap_external._unpack_uint32 # Fully bootstrapped at this point, import whatever you like, circular # dependencies and startup overhead minimisation permitting :) import warnings # Public API ######################################################### from ._bootstrap import __import__ def invalidate_caches(): """Call the invalidate_caches() method on all meta path finders stored in sys.meta_path (where implemented).""" for finder in sys.meta_path: if hasattr(finder, 'invalidate_caches'): finder.invalidate_caches() def import_module(name, package=None): """Import a module. The 'package' argument is required when performing a relative import. It specifies the package to use as the anchor point from which to resolve the relative import to an absolute import. """ level = 0 if name.startswith('.'): if not package: raise TypeError("the 'package' argument is required to perform a " f"relative import for {name!r}") for character in name: if character != '.': break level += 1 return _bootstrap._gcd_import(name[level:], package, level) _RELOADING = {} def reload(module): """Reload the module and return it. The module must have been successfully imported before. """ try: name = module.__spec__.name except AttributeError: try: name = module.__name__ except AttributeError: raise TypeError("reload() argument must be a module") from None if sys.modules.get(name) is not module: raise ImportError(f"module {name} not in sys.modules", name=name) if name in _RELOADING: return _RELOADING[name] _RELOADING[name] = module try: parent_name = name.rpartition('.')[0] if parent_name: try: parent = sys.modules[parent_name] except KeyError: raise ImportError(f"parent {parent_name!r} not in sys.modules", name=parent_name) from None else: pkgpath = parent.__path__ else: pkgpath = None target = module spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) if spec is None: raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name) _bootstrap._exec(spec, module) # The module may have replaced itself in sys.modules! return sys.modules[name] finally: try: del _RELOADING[name] except KeyError: pass usr/lib64/python2.7/curses/__init__.py000064400000003431152346177410013475 0ustar00"""curses The main package for curses support for Python. Normally used by importing the package, and perhaps a particular module inside it. import curses from curses import textpad curses.initscr() ... """ __revision__ = "$Id$" from _curses import * from curses.wrapper import wrapper import os as _os import sys as _sys # Some constants, most notably the ACS_* ones, are only added to the C # _curses module's dictionary after initscr() is called. (Some # versions of SGI's curses don't define values for those constants # until initscr() has been called.) This wrapper function calls the # underlying C initscr(), and then copies the constants from the # _curses module to the curses package's dictionary. Don't do 'from # curses import *' if you'll be needing the ACS_* constants. def initscr(): import _curses, curses # we call setupterm() here because it raises an error # instead of calling exit() in error cases. setupterm(term=_os.environ.get("TERM", "unknown"), fd=_sys.__stdout__.fileno()) stdscr = _curses.initscr() for key, value in _curses.__dict__.items(): if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): setattr(curses, key, value) return stdscr # This is a similar wrapper for start_color(), which adds the COLORS and # COLOR_PAIRS variables which are only available after start_color() is # called. def start_color(): import _curses, curses retval = _curses.start_color() if hasattr(_curses, 'COLORS'): curses.COLORS = _curses.COLORS if hasattr(_curses, 'COLOR_PAIRS'): curses.COLOR_PAIRS = _curses.COLOR_PAIRS return retval # Import Python has_key() implementation if _curses doesn't contain has_key() try: has_key except NameError: from has_key import has_key usr/lib64/python2.7/wsgiref/__init__.py000064400000001112152346207170013626 0ustar00"""wsgiref -- a WSGI (PEP 333) Reference Library Current Contents: * util -- Miscellaneous useful functions and wrappers * headers -- Manage response headers * handlers -- base classes for server/gateway implementations * simple_server -- a simple BaseHTTPServer that supports WSGI * validate -- validation wrapper that sits between an app and a server to detect errors in either To-Do: * cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard) * cgi_wrapper -- Run CGI apps under WSGI * router -- a simple middleware component that handles URL traversal """ usr/lib/python3.6/site-packages/ply/__init__.py000064400000000146152346207600015336 0ustar00# PLY package # Author: David Beazley (dave@dabeaz.com) __version__ = '3.9' __all__ = ['lex','yacc'] lib64/python3.6/xmlrpc/__init__.py000064400000000046152346210540012654 0ustar00# This directory is a Python package. lib64/python3.8/multiprocessing/__init__.py000064400000001624152346211630014604 0ustar00# # Package analogous to 'threading.py' but using processes # # multiprocessing/__init__.py # # This package is intended to duplicate the functionality (and much of # the API) of threading.py but uses processes instead of threads. A # subpackage 'multiprocessing.dummy' has the same API but is a simple # wrapper for 'threading'. # # Copyright (c) 2006-2008, R Oudkerk # Licensed to PSF under a Contributor Agreement. # import sys from . import context # # Copy stuff from default context # __all__ = [x for x in dir(context._default_context) if not x.startswith('_')] globals().update((name, getattr(context._default_context, name)) for name in __all__) # # XXX These should not really be documented or public. # SUBDEBUG = 5 SUBWARNING = 25 # # Alias for main module -- will be reset by bootstrapping child processes # if '__main__' in sys.modules: sys.modules['__mp_main__'] = sys.modules['__main__'] usr/lib64/python2.7/multiprocessing/__init__.py000064400000017175152346212660015427 0ustar00# # Package analogous to 'threading.py' but using processes # # multiprocessing/__init__.py # # This package is intended to duplicate the functionality (and much of # the API) of threading.py but uses processes instead of threads. A # subpackage 'multiprocessing.dummy' has the same API but is a simple # wrapper for 'threading'. # # Try calling `multiprocessing.doc.main()` to read the html # documentation in a webbrowser. # # # Copyright (c) 2006-2008, R Oudkerk # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of author nor the names of any contributors may be # used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # __version__ = '0.70a1' __all__ = [ 'Process', 'current_process', 'active_children', 'freeze_support', 'Manager', 'Pipe', 'cpu_count', 'log_to_stderr', 'get_logger', 'allow_connection_pickling', 'BufferTooShort', 'TimeoutError', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event', 'Queue', 'JoinableQueue', 'Pool', 'Value', 'Array', 'RawValue', 'RawArray', 'SUBDEBUG', 'SUBWARNING', ] __author__ = 'R. Oudkerk (r.m.oudkerk@gmail.com)' # # Imports # import os import sys from multiprocessing.process import Process, current_process, active_children from multiprocessing.util import SUBDEBUG, SUBWARNING # # Exceptions # class ProcessError(Exception): pass class BufferTooShort(ProcessError): pass class TimeoutError(ProcessError): pass class AuthenticationError(ProcessError): pass # This is down here because _multiprocessing uses BufferTooShort import _multiprocessing # # Definitions not depending on native semaphores # def Manager(): ''' Returns a manager associated with a running server process The managers methods such as `Lock()`, `Condition()` and `Queue()` can be used to create shared objects. ''' from multiprocessing.managers import SyncManager m = SyncManager() m.start() return m def Pipe(duplex=True): ''' Returns two connection object connected by a pipe ''' from multiprocessing.connection import Pipe return Pipe(duplex) def cpu_count(): ''' Returns the number of CPUs in the system ''' if sys.platform == 'win32': try: num = int(os.environ['NUMBER_OF_PROCESSORS']) except (ValueError, KeyError): num = 0 elif 'bsd' in sys.platform or sys.platform == 'darwin': comm = '/sbin/sysctl -n hw.ncpu' if sys.platform == 'darwin': comm = '/usr' + comm try: with os.popen(comm) as p: num = int(p.read()) except ValueError: num = 0 else: try: num = os.sysconf('SC_NPROCESSORS_ONLN') except (ValueError, OSError, AttributeError): num = 0 if num >= 1: return num else: raise NotImplementedError('cannot determine number of cpus') def freeze_support(): ''' Check whether this is a fake forked process in a frozen executable. If so then run code specified by commandline and exit. ''' if sys.platform == 'win32' and getattr(sys, 'frozen', False): from multiprocessing.forking import freeze_support freeze_support() def get_logger(): ''' Return package logger -- if it does not already exist then it is created ''' from multiprocessing.util import get_logger return get_logger() def log_to_stderr(level=None): ''' Turn on logging and add a handler which prints to stderr ''' from multiprocessing.util import log_to_stderr return log_to_stderr(level) def allow_connection_pickling(): ''' Install support for sending connections and sockets between processes ''' from multiprocessing import reduction # # Definitions depending on native semaphores # def Lock(): ''' Returns a non-recursive lock object ''' from multiprocessing.synchronize import Lock return Lock() def RLock(): ''' Returns a recursive lock object ''' from multiprocessing.synchronize import RLock return RLock() def Condition(lock=None): ''' Returns a condition object ''' from multiprocessing.synchronize import Condition return Condition(lock) def Semaphore(value=1): ''' Returns a semaphore object ''' from multiprocessing.synchronize import Semaphore return Semaphore(value) def BoundedSemaphore(value=1): ''' Returns a bounded semaphore object ''' from multiprocessing.synchronize import BoundedSemaphore return BoundedSemaphore(value) def Event(): ''' Returns an event object ''' from multiprocessing.synchronize import Event return Event() def Queue(maxsize=0): ''' Returns a queue object ''' from multiprocessing.queues import Queue return Queue(maxsize) def JoinableQueue(maxsize=0): ''' Returns a queue object ''' from multiprocessing.queues import JoinableQueue return JoinableQueue(maxsize) def Pool(processes=None, initializer=None, initargs=(), maxtasksperchild=None): ''' Returns a process pool object ''' from multiprocessing.pool import Pool return Pool(processes, initializer, initargs, maxtasksperchild) def RawValue(typecode_or_type, *args): ''' Returns a shared object ''' from multiprocessing.sharedctypes import RawValue return RawValue(typecode_or_type, *args) def RawArray(typecode_or_type, size_or_initializer): ''' Returns a shared array ''' from multiprocessing.sharedctypes import RawArray return RawArray(typecode_or_type, size_or_initializer) def Value(typecode_or_type, *args, **kwds): ''' Returns a synchronized shared object ''' from multiprocessing.sharedctypes import Value return Value(typecode_or_type, *args, **kwds) def Array(typecode_or_type, size_or_initializer, **kwds): ''' Returns a synchronized shared array ''' from multiprocessing.sharedctypes import Array return Array(typecode_or_type, size_or_initializer, **kwds) # # # if sys.platform == 'win32': def set_executable(executable): ''' Sets the path to a python.exe or pythonw.exe binary used to run child processes on Windows instead of sys.executable. Useful for people embedding Python. ''' from multiprocessing.forking import set_executable set_executable(executable) __all__ += ['set_executable'] lib64/python3.12/importlib/__init__.py000064400000011260152346220550013427 0ustar00"""A pure Python implementation of import.""" __all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload'] # Bootstrap help ##################################################### # Until bootstrapping is complete, DO NOT import any modules that attempt # to import importlib._bootstrap (directly or indirectly). Since this # partially initialised package would be present in sys.modules, those # modules would get an uninitialised copy of the source version, instead # of a fully initialised version (either the frozen one or the one # initialised below if the frozen one is not available). import _imp # Just the builtin component, NOT the full Python module import sys try: import _frozen_importlib as _bootstrap except ImportError: from . import _bootstrap _bootstrap._setup(sys, _imp) else: # importlib._bootstrap is the built-in import, ensure we don't create # a second copy of the module. _bootstrap.__name__ = 'importlib._bootstrap' _bootstrap.__package__ = 'importlib' try: _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap'] = _bootstrap try: import _frozen_importlib_external as _bootstrap_external except ImportError: from . import _bootstrap_external _bootstrap_external._set_bootstrap_module(_bootstrap) _bootstrap._bootstrap_external = _bootstrap_external else: _bootstrap_external.__name__ = 'importlib._bootstrap_external' _bootstrap_external.__package__ = 'importlib' try: _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap_external'] = _bootstrap_external # To simplify imports in test code _pack_uint32 = _bootstrap_external._pack_uint32 _unpack_uint32 = _bootstrap_external._unpack_uint32 # Fully bootstrapped at this point, import whatever you like, circular # dependencies and startup overhead minimisation permitting :) import warnings # Public API ######################################################### from ._bootstrap import __import__ def invalidate_caches(): """Call the invalidate_caches() method on all meta path finders stored in sys.meta_path (where implemented).""" for finder in sys.meta_path: if hasattr(finder, 'invalidate_caches'): finder.invalidate_caches() def import_module(name, package=None): """Import a module. The 'package' argument is required when performing a relative import. It specifies the package to use as the anchor point from which to resolve the relative import to an absolute import. """ level = 0 if name.startswith('.'): if not package: raise TypeError("the 'package' argument is required to perform a " f"relative import for {name!r}") for character in name: if character != '.': break level += 1 return _bootstrap._gcd_import(name[level:], package, level) _RELOADING = {} def reload(module): """Reload the module and return it. The module must have been successfully imported before. """ try: name = module.__spec__.name except AttributeError: try: name = module.__name__ except AttributeError: raise TypeError("reload() argument must be a module") from None if sys.modules.get(name) is not module: raise ImportError(f"module {name} not in sys.modules", name=name) if name in _RELOADING: return _RELOADING[name] _RELOADING[name] = module try: parent_name = name.rpartition('.')[0] if parent_name: try: parent = sys.modules[parent_name] except KeyError: raise ImportError(f"parent {parent_name!r} not in sys.modules", name=parent_name) from None else: pkgpath = parent.__path__ else: pkgpath = None target = module spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) if spec is None: raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name) _bootstrap._exec(spec, module) # The module may have replaced itself in sys.modules! return sys.modules[name] finally: try: del _RELOADING[name] except KeyError: pass lib64/python2.7/ctypes/__init__.py000064400000041366152346224030012667 0ustar00"""create and manipulate C data types in Python""" import os as _os, sys as _sys __version__ = "1.1.0" from _ctypes import Union, Structure, Array from _ctypes import _Pointer from _ctypes import CFuncPtr as _CFuncPtr from _ctypes import __version__ as _ctypes_version from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import ArgumentError from struct import calcsize as _calcsize if __version__ != _ctypes_version: raise Exception("Version number mismatch", __version__, _ctypes_version) if _os.name in ("nt", "ce"): from _ctypes import FormatError DEFAULT_MODE = RTLD_LOCAL if _os.name == "posix" and _sys.platform == "darwin": # On OS X 10.3, we use RTLD_GLOBAL as default mode # because RTLD_LOCAL does not work at least on some # libraries. OS X 10.3 is Darwin 7, so we check for # that. if int(_os.uname()[2].split('.')[0]) < 8: DEFAULT_MODE = RTLD_GLOBAL from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \ FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \ FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR """ WINOLEAPI -> HRESULT WINOLEAPI_(type) STDMETHODCALLTYPE STDMETHOD(name) STDMETHOD_(type, name) STDAPICALLTYPE """ def create_string_buffer(init, size=None): """create_string_buffer(aString) -> character array create_string_buffer(anInteger) -> character array create_string_buffer(aString, anInteger) -> character array """ if isinstance(init, (str, unicode)): if size is None: size = len(init)+1 buftype = c_char * size buf = buftype() buf.value = init return buf elif isinstance(init, (int, long)): buftype = c_char * init buf = buftype() return buf raise TypeError(init) def c_buffer(init, size=None): ## "deprecated, use create_string_buffer instead" ## import warnings ## warnings.warn("c_buffer is deprecated, use create_string_buffer instead", ## DeprecationWarning, stacklevel=2) return create_string_buffer(init, size) _c_functype_cache = {} def CFUNCTYPE(restype, *argtypes, **kw): """CFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) -> function prototype. restype: the result type argtypes: a sequence specifying the argument types The function prototype can be called in different ways to create a callable object: prototype(integer address) -> foreign function prototype(callable) -> create and return a C callable function from callable prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal prototype((function name, dll object)[, paramflags]) -> foreign function exported by name """ flags = _FUNCFLAG_CDECL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _c_functype_cache[(restype, argtypes, flags)] except KeyError: class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _c_functype_cache[(restype, argtypes, flags)] = CFunctionType return CFunctionType if _os.name in ("nt", "ce"): from _ctypes import LoadLibrary as _dlopen from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL if _os.name == "ce": # 'ce' doesn't have the stdcall calling convention _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL _win_functype_cache = {} def WINFUNCTYPE(restype, *argtypes, **kw): # docstring set later (very similar to CFUNCTYPE.__doc__) flags = _FUNCFLAG_STDCALL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _win_functype_cache[(restype, argtypes, flags)] except KeyError: class WinFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType return WinFunctionType if WINFUNCTYPE.__doc__: WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE") elif _os.name == "posix": from _ctypes import dlopen as _dlopen from _ctypes import sizeof, byref, addressof, alignment, resize from _ctypes import get_errno, set_errno from _ctypes import _SimpleCData def _check_size(typ, typecode=None): # Check if sizeof(ctypes_type) against struct.calcsize. This # should protect somewhat against a misconfigured libffi. from struct import calcsize if typecode is None: # Most _type_ codes are the same as used in struct typecode = typ._type_ actual, required = sizeof(typ), calcsize(typecode) if actual != required: raise SystemError("sizeof(%s) wrong: %d instead of %d" % \ (typ, actual, required)) class py_object(_SimpleCData): _type_ = "O" def __repr__(self): try: return super(py_object, self).__repr__() except ValueError: return "%s()" % type(self).__name__ _check_size(py_object, "P") class c_short(_SimpleCData): _type_ = "h" _check_size(c_short) class c_ushort(_SimpleCData): _type_ = "H" _check_size(c_ushort) class c_long(_SimpleCData): _type_ = "l" _check_size(c_long) class c_ulong(_SimpleCData): _type_ = "L" _check_size(c_ulong) if _calcsize("i") == _calcsize("l"): # if int and long have the same size, make c_int an alias for c_long c_int = c_long c_uint = c_ulong else: class c_int(_SimpleCData): _type_ = "i" _check_size(c_int) class c_uint(_SimpleCData): _type_ = "I" _check_size(c_uint) class c_float(_SimpleCData): _type_ = "f" _check_size(c_float) class c_double(_SimpleCData): _type_ = "d" _check_size(c_double) class c_longdouble(_SimpleCData): _type_ = "g" if sizeof(c_longdouble) == sizeof(c_double): c_longdouble = c_double if _calcsize("l") == _calcsize("q"): # if long and long long have the same size, make c_longlong an alias for c_long c_longlong = c_long c_ulonglong = c_ulong else: class c_longlong(_SimpleCData): _type_ = "q" _check_size(c_longlong) class c_ulonglong(_SimpleCData): _type_ = "Q" ## def from_param(cls, val): ## return ('d', float(val), val) ## from_param = classmethod(from_param) _check_size(c_ulonglong) class c_ubyte(_SimpleCData): _type_ = "B" c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte # backward compatibility: ##c_uchar = c_ubyte _check_size(c_ubyte) class c_byte(_SimpleCData): _type_ = "b" c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte _check_size(c_byte) class c_char(_SimpleCData): _type_ = "c" c_char.__ctype_le__ = c_char.__ctype_be__ = c_char _check_size(c_char) class c_char_p(_SimpleCData): _type_ = "z" if _os.name == "nt": def __repr__(self): if not windll.kernel32.IsBadStringPtrA(self, -1): return "%s(%r)" % (self.__class__.__name__, self.value) return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value) else: def __repr__(self): return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value) _check_size(c_char_p, "P") class c_void_p(_SimpleCData): _type_ = "P" c_voidp = c_void_p # backwards compatibility (to a bug) _check_size(c_void_p) class c_bool(_SimpleCData): _type_ = "?" from _ctypes import POINTER, pointer, _pointer_type_cache def _reset_cache(): _pointer_type_cache.clear() _c_functype_cache.clear() if _os.name in ("nt", "ce"): _win_functype_cache.clear() # _SimpleCData.c_wchar_p_from_param POINTER(c_wchar).from_param = c_wchar_p.from_param # _SimpleCData.c_char_p_from_param POINTER(c_char).from_param = c_char_p.from_param _pointer_type_cache[None] = c_void_p try: from _ctypes import set_conversion_mode except ImportError: pass else: if _os.name in ("nt", "ce"): set_conversion_mode("mbcs", "ignore") else: set_conversion_mode("ascii", "strict") class c_wchar_p(_SimpleCData): _type_ = "Z" class c_wchar(_SimpleCData): _type_ = "u" def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array create_unicode_buffer(aString, anInteger) -> character array """ if isinstance(init, (str, unicode)): if size is None: size = len(init)+1 buftype = c_wchar * size buf = buftype() buf.value = init return buf elif isinstance(init, (int, long)): buftype = c_wchar * init buf = buftype() return buf raise TypeError(init) # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: raise RuntimeError("This type already exists in the cache") if id(pointer) not in _pointer_type_cache: raise RuntimeError("What's this???") pointer.set_type(cls) _pointer_type_cache[cls] = pointer del _pointer_type_cache[id(pointer)] # XXX Deprecated def ARRAY(typ, len): return typ * len ################################################################ class CDLL(object): """An instance of this class represents a loaded dll/shared library, exporting functions using the standard C calling convention (named 'cdecl' on Windows). The exported functions can be accessed as attributes, or by indexing with the function name. Examples: .qsort -> callable object ['qsort'] -> callable object Calling the functions releases the Python GIL during the call and reacquires it afterwards. """ _func_flags_ = _FUNCFLAG_CDECL _func_restype_ = c_int # default values for repr _name = '' _handle = 0 _FuncPtr = None def __init__(self, name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False): self._name = name flags = self._func_flags_ if use_errno: flags |= _FUNCFLAG_USE_ERRNO if use_last_error: flags |= _FUNCFLAG_USE_LASTERROR class _FuncPtr(_CFuncPtr): _flags_ = flags _restype_ = self._func_restype_ self._FuncPtr = _FuncPtr if handle is None: self._handle = _dlopen(self._name, mode) else: self._handle = handle def __repr__(self): return "<%s '%s', handle %x at %x>" % \ (self.__class__.__name__, self._name, (self._handle & (_sys.maxint*2 + 1)), id(self) & (_sys.maxint*2 + 1)) def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): raise AttributeError(name) func = self.__getitem__(name) setattr(self, name, func) return func def __getitem__(self, name_or_ordinal): func = self._FuncPtr((name_or_ordinal, self)) if not isinstance(name_or_ordinal, (int, long)): func.__name__ = name_or_ordinal return func class PyDLL(CDLL): """This class represents the Python library itself. It allows accessing Python API functions. The GIL is not released, and Python exceptions are handled correctly. """ _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI if _os.name in ("nt", "ce"): class WinDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention. """ _func_flags_ = _FUNCFLAG_STDCALL # XXX Hm, what about HRESULT as normal parameter? # Mustn't it derive from c_long then? from _ctypes import _check_HRESULT, _SimpleCData class HRESULT(_SimpleCData): _type_ = "l" # _check_retval_ is called with the function's result when it # is used as restype. It checks for the FAILED bit, and # raises a WindowsError if it is set. # # The _check_retval_ method is implemented in C, so that the # method definition itself is not included in the traceback # when it raises an error - that is what we want (and Python # doesn't have a way to raise an exception in the caller's # frame). _check_retval_ = _check_HRESULT class OleDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention, and returning HRESULT. HRESULT error values are automatically raised as WindowsError exceptions. """ _func_flags_ = _FUNCFLAG_STDCALL _func_restype_ = HRESULT class LibraryLoader(object): def __init__(self, dlltype): self._dlltype = dlltype def __getattr__(self, name): if name[0] == '_': raise AttributeError(name) dll = self._dlltype(name) setattr(self, name, dll) return dll def __getitem__(self, name): return getattr(self, name) def LoadLibrary(self, name): return self._dlltype(name) cdll = LibraryLoader(CDLL) pydll = LibraryLoader(PyDLL) if _os.name in ("nt", "ce"): pythonapi = PyDLL("python dll", None, _sys.dllhandle) elif _sys.platform == "cygwin": pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) else: pythonapi = PyDLL(None) if _os.name in ("nt", "ce"): windll = LibraryLoader(WinDLL) oledll = LibraryLoader(OleDLL) if _os.name == "nt": GetLastError = windll.kernel32.GetLastError else: GetLastError = windll.coredll.GetLastError from _ctypes import get_last_error, set_last_error def WinError(code=None, descr=None): if code is None: code = GetLastError() if descr is None: descr = FormatError(code).strip() return WindowsError(code, descr) if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int elif sizeof(c_ulong) == sizeof(c_void_p): c_size_t = c_ulong c_ssize_t = c_long elif sizeof(c_ulonglong) == sizeof(c_void_p): c_size_t = c_ulonglong c_ssize_t = c_longlong # functions from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr ## void *memmove(void *, const void *, size_t); memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) ## void *memset(void *, int, size_t) memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) def PYFUNCTYPE(restype, *argtypes): class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI return CFunctionType _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) def cast(obj, typ): return _cast(obj, obj, typ) _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) def string_at(ptr, size=-1): """string_at(addr[, size]) -> string Return the string at addr.""" return _string_at(ptr, size) try: from _ctypes import _wstring_at_addr except ImportError: pass else: _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) def wstring_at(ptr, size=-1): """wstring_at(addr[, size]) -> string Return the string at addr.""" return _wstring_at(ptr, size) if _os.name in ("nt", "ce"): # COM stuff def DllGetClassObject(rclsid, riid, ppv): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return -2147221231 # CLASS_E_CLASSNOTAVAILABLE else: return ccom.DllGetClassObject(rclsid, riid, ppv) def DllCanUnloadNow(): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return 0 # S_OK return ccom.DllCanUnloadNow() from ctypes._endian import BigEndianStructure, LittleEndianStructure # Fill in specifically-sized types c_int8 = c_byte c_uint8 = c_ubyte for kind in [c_short, c_int, c_long, c_longlong]: if sizeof(kind) == 2: c_int16 = kind elif sizeof(kind) == 4: c_int32 = kind elif sizeof(kind) == 8: c_int64 = kind for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]: if sizeof(kind) == 2: c_uint16 = kind elif sizeof(kind) == 4: c_uint32 = kind elif sizeof(kind) == 8: c_uint64 = kind del(kind) _reset_cache() usr/lib/python3.6/site-packages/pip/__init__.py000064400000027236152346225260015335 0ustar00from __future__ import absolute_import import locale import logging import os import optparse import warnings import sys import re # 2016-06-17 barry@debian.org: urllib3 1.14 added optional support for socks, # but if invoked (i.e. imported), it will issue a warning to stderr if socks # isn't available. requests unconditionally imports urllib3's socks contrib # module, triggering this warning. The warning breaks DEP-8 tests (because of # the stderr output) and is just plain annoying in normal usage. I don't want # to add socks as yet another dependency for pip, nor do I want to allow-stder # in the DEP-8 tests, so just suppress the warning. pdb tells me this has to # be done before the import of pip.vcs. from pip._vendor.urllib3.exceptions import DependencyWarning warnings.filterwarnings("ignore", category=DependencyWarning) # noqa # We want to inject the use of SecureTransport as early as possible so that any # references or sessions or what have you are ensured to have it, however we # only want to do this in the case that we're running on macOS and the linked # OpenSSL is too old to handle TLSv1.2 try: import ssl except ImportError: pass else: if (sys.platform == "darwin" and getattr(ssl, "OPENSSL_VERSION_NUMBER", 0) < 0x1000100f): # OpenSSL 1.0.1 try: from pip._vendor.urllib3.contrib import securetransport except (ImportError, OSError): pass else: securetransport.inject_into_urllib3() from pip.exceptions import InstallationError, CommandError, PipError from pip.utils import get_installed_distributions, get_prog from pip.utils import deprecation, dist_is_editable from pip.vcs import git, mercurial, subversion, bazaar # noqa from pip.baseparser import ConfigOptionParser, UpdatingDefaultsHelpFormatter from pip.commands import get_summaries, get_similar_commands from pip.commands import commands_dict from pip._vendor.urllib3.exceptions import InsecureRequestWarning # assignment for flake8 to be happy # This fixes a peculiarity when importing via __import__ - as we are # initialising the pip module, "from pip import cmdoptions" is recursive # and appears not to work properly in that situation. import pip.cmdoptions cmdoptions = pip.cmdoptions # The version as used in the setup.py and the docs conf.py __version__ = "9.0.3" logger = logging.getLogger(__name__) # Hide the InsecureRequestWarning from urllib3 warnings.filterwarnings("ignore", category=InsecureRequestWarning) def autocomplete(): """Command and option completion for the main option parser (and options) and its subcommands (and options). Enable by sourcing one of the completion shell scripts (bash, zsh or fish). """ # Don't complete if user hasn't sourced bash_completion file. if 'PIP_AUTO_COMPLETE' not in os.environ: return cwords = os.environ['COMP_WORDS'].split()[1:] cword = int(os.environ['COMP_CWORD']) try: current = cwords[cword - 1] except IndexError: current = '' subcommands = [cmd for cmd, summary in get_summaries()] options = [] # subcommand try: subcommand_name = [w for w in cwords if w in subcommands][0] except IndexError: subcommand_name = None parser = create_main_parser() # subcommand options if subcommand_name: # special case: 'help' subcommand has no options if subcommand_name == 'help': sys.exit(1) # special case: list locally installed dists for uninstall command if subcommand_name == 'uninstall' and not current.startswith('-'): installed = [] lc = current.lower() for dist in get_installed_distributions(local_only=True): if dist.key.startswith(lc) and dist.key not in cwords[1:]: installed.append(dist.key) # if there are no dists installed, fall back to option completion if installed: for dist in installed: print(dist) sys.exit(1) subcommand = commands_dict[subcommand_name]() options += [(opt.get_opt_string(), opt.nargs) for opt in subcommand.parser.option_list_all if opt.help != optparse.SUPPRESS_HELP] # filter out previously specified options from available options prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] options = [(x, v) for (x, v) in options if x not in prev_opts] # filter options by current input options = [(k, v) for k, v in options if k.startswith(current)] for option in options: opt_label = option[0] # append '=' to options which require args if option[1]: opt_label += '=' print(opt_label) else: # show main parser options only when necessary if current.startswith('-') or current.startswith('--'): opts = [i.option_list for i in parser.option_groups] opts.append(parser.option_list) opts = (o for it in opts for o in it) subcommands += [i.get_opt_string() for i in opts if i.help != optparse.SUPPRESS_HELP] print(' '.join([x for x in subcommands if x.startswith(current)])) sys.exit(1) def create_main_parser(): parser_kw = { 'usage': '\n%prog [options]', 'add_help_option': False, 'formatter': UpdatingDefaultsHelpFormatter(), 'name': 'global', 'prog': get_prog(), } parser = ConfigOptionParser(**parser_kw) parser.disable_interspersed_args() pip_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) parser.version = 'pip %s from %s (python %s)' % ( __version__, pip_pkg_dir, sys.version[:3]) # add the general options gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) parser.add_option_group(gen_opts) parser.main = True # so the help formatter knows # create command listing for description command_summaries = get_summaries() description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] parser.description = '\n'.join(description) return parser def parseopts(args): parser = create_main_parser() # Note: parser calls disable_interspersed_args(), so the result of this # call is to split the initial args into the general options before the # subcommand and everything else. # For example: # args: ['--timeout=5', 'install', '--user', 'INITools'] # general_options: ['--timeout==5'] # args_else: ['install', '--user', 'INITools'] general_options, args_else = parser.parse_args(args) # --version if general_options.version: sys.stdout.write(parser.version) sys.stdout.write(os.linesep) sys.exit() # pip || pip help -> print_help() if not args_else or (args_else[0] == 'help' and len(args_else) == 1): parser.print_help() sys.exit() # the subcommand name cmd_name = args_else[0] if cmd_name not in commands_dict: guess = get_similar_commands(cmd_name) msg = ['unknown command "%s"' % cmd_name] if guess: msg.append('maybe you meant "%s"' % guess) raise CommandError(' - '.join(msg)) # all the args without the subcommand cmd_args = args[:] cmd_args.remove(cmd_name) return cmd_name, cmd_args def check_isolated(args): isolated = False if "--isolated" in args: isolated = True return isolated def main(args=None): if args is None: args = sys.argv[1:] # Configure our deprecation warnings to be sent through loggers deprecation.install_warning_logger() autocomplete() try: cmd_name, cmd_args = parseopts(args) except PipError as exc: sys.stderr.write("ERROR: %s" % exc) sys.stderr.write(os.linesep) sys.exit(1) # Needed for locale.getpreferredencoding(False) to work # in pip.utils.encoding.auto_decode try: locale.setlocale(locale.LC_ALL, '') except locale.Error as e: # setlocale can apparently crash if locale are uninitialized logger.debug("Ignoring error %s when setting locale", e) command = commands_dict[cmd_name](isolated=check_isolated(cmd_args)) return command.main(cmd_args) # ########################################################### # # Writing freeze files class FrozenRequirement(object): def __init__(self, name, req, editable, comments=()): self.name = name self.req = req self.editable = editable self.comments = comments _rev_re = re.compile(r'-r(\d+)$') _date_re = re.compile(r'-(20\d\d\d\d\d\d)$') @classmethod def from_dist(cls, dist, dependency_links): location = os.path.normcase(os.path.abspath(dist.location)) comments = [] from pip.vcs import vcs, get_src_requirement if dist_is_editable(dist) and vcs.get_backend_name(location): editable = True try: req = get_src_requirement(dist, location) except InstallationError as exc: logger.warning( "Error when trying to get requirement for VCS system %s, " "falling back to uneditable format", exc ) req = None if req is None: logger.warning( 'Could not determine repository location of %s', location ) comments.append( '## !! Could not determine repository location' ) req = dist.as_requirement() editable = False else: editable = False req = dist.as_requirement() specs = req.specs assert len(specs) == 1 and specs[0][0] in ["==", "==="], \ 'Expected 1 spec with == or ===; specs = %r; dist = %r' % \ (specs, dist) version = specs[0][1] ver_match = cls._rev_re.search(version) date_match = cls._date_re.search(version) if ver_match or date_match: svn_backend = vcs.get_backend('svn') if svn_backend: svn_location = svn_backend().get_location( dist, dependency_links, ) if not svn_location: logger.warning( 'Warning: cannot find svn location for %s', req) comments.append( '## FIXME: could not find svn URL in dependency_links ' 'for this package:' ) else: comments.append( '# Installing as editable to satisfy requirement %s:' % req ) if ver_match: rev = ver_match.group(1) else: rev = '{%s}' % date_match.group(1) editable = True req = '%s@%s#egg=%s' % ( svn_location, rev, cls.egg_name(dist) ) return cls(dist.project_name, req, editable, comments) @staticmethod def egg_name(dist): name = dist.egg_name() match = re.search(r'-py\d\.\d$', name) if match: name = name[:match.start()] return name def __str__(self): req = self.req if self.editable: req = '-e %s' % req return '\n'.join(list(self.comments) + [str(req)]) + '\n' if __name__ == '__main__': sys.exit(main()) usr/lib64/python3.6/importlib/__init__.py000064400000013356152346225420014174 0ustar00"""A pure Python implementation of import.""" __all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload'] # Bootstrap help ##################################################### # Until bootstrapping is complete, DO NOT import any modules that attempt # to import importlib._bootstrap (directly or indirectly). Since this # partially initialised package would be present in sys.modules, those # modules would get an uninitialised copy of the source version, instead # of a fully initialised version (either the frozen one or the one # initialised below if the frozen one is not available). import _imp # Just the builtin component, NOT the full Python module import sys try: import _frozen_importlib as _bootstrap except ImportError: from . import _bootstrap _bootstrap._setup(sys, _imp) else: # importlib._bootstrap is the built-in import, ensure we don't create # a second copy of the module. _bootstrap.__name__ = 'importlib._bootstrap' _bootstrap.__package__ = 'importlib' try: _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap'] = _bootstrap try: import _frozen_importlib_external as _bootstrap_external except ImportError: from . import _bootstrap_external _bootstrap_external._setup(_bootstrap) _bootstrap._bootstrap_external = _bootstrap_external else: _bootstrap_external.__name__ = 'importlib._bootstrap_external' _bootstrap_external.__package__ = 'importlib' try: _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap_external'] = _bootstrap_external # To simplify imports in test code _w_long = _bootstrap_external._w_long _r_long = _bootstrap_external._r_long # Fully bootstrapped at this point, import whatever you like, circular # dependencies and startup overhead minimisation permitting :) import types import warnings # Public API ######################################################### from ._bootstrap import __import__ def invalidate_caches(): """Call the invalidate_caches() method on all meta path finders stored in sys.meta_path (where implemented).""" for finder in sys.meta_path: if hasattr(finder, 'invalidate_caches'): finder.invalidate_caches() def find_loader(name, path=None): """Return the loader for the specified module. This is a backward-compatible wrapper around find_spec(). This function is deprecated in favor of importlib.util.find_spec(). """ warnings.warn('Use importlib.util.find_spec() instead.', DeprecationWarning, stacklevel=2) try: loader = sys.modules[name].__loader__ if loader is None: raise ValueError('{}.__loader__ is None'.format(name)) else: return loader except KeyError: pass except AttributeError: raise ValueError('{}.__loader__ is not set'.format(name)) from None spec = _bootstrap._find_spec(name, path) # We won't worry about malformed specs (missing attributes). if spec is None: return None if spec.loader is None: if spec.submodule_search_locations is None: raise ImportError('spec for {} missing loader'.format(name), name=name) raise ImportError('namespace packages do not have loaders', name=name) return spec.loader def import_module(name, package=None): """Import a module. The 'package' argument is required when performing a relative import. It specifies the package to use as the anchor point from which to resolve the relative import to an absolute import. """ level = 0 if name.startswith('.'): if not package: msg = ("the 'package' argument is required to perform a relative " "import for {!r}") raise TypeError(msg.format(name)) for character in name: if character != '.': break level += 1 return _bootstrap._gcd_import(name[level:], package, level) _RELOADING = {} def reload(module): """Reload the module and return it. The module must have been successfully imported before. """ if not module or not isinstance(module, types.ModuleType): raise TypeError("reload() argument must be a module") try: name = module.__spec__.name except AttributeError: name = module.__name__ if sys.modules.get(name) is not module: msg = "module {} not in sys.modules" raise ImportError(msg.format(name), name=name) if name in _RELOADING: return _RELOADING[name] _RELOADING[name] = module try: parent_name = name.rpartition('.')[0] if parent_name: try: parent = sys.modules[parent_name] except KeyError: msg = "parent {!r} not in sys.modules" raise ImportError(msg.format(parent_name), name=parent_name) from None else: pkgpath = parent.__path__ else: pkgpath = None target = module spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) _bootstrap._exec(spec, module) # The module may have replaced itself in sys.modules! return sys.modules[name] finally: try: del _RELOADING[name] except KeyError: pass usr/lib64/python3.12/logging/__init__.py000064400000242755152346226320013705 0ustar00# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation, and that the name of Vinay Sajip # not be used in advertising or publicity pertaining to distribution # of the software without specific, written prior permission. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import sys, os, time, io, re, traceback, warnings, weakref, collections.abc from types import GenericAlias from string import Template from string import Formatter as StrFormatter __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', 'lastResort', 'raiseExceptions', 'getLevelNamesMapping', 'getHandlerByName', 'getHandlerNames'] import threading __author__ = "Vinay Sajip " __status__ = "production" # The following module attributes are no longer updated. __version__ = "0.5.1.2" __date__ = "07 February 2010" #--------------------------------------------------------------------------- # Miscellaneous module data #--------------------------------------------------------------------------- # #_startTime is used as the base when calculating the relative time of events # _startTime = time.time() # #raiseExceptions is used to see if exceptions during handling should be #propagated # raiseExceptions = True # # If you don't want threading information in the log, set this to False # logThreads = True # # If you don't want multiprocessing information in the log, set this to False # logMultiprocessing = True # # If you don't want process information in the log, set this to False # logProcesses = True # # If you don't want asyncio task information in the log, set this to False # logAsyncioTasks = True #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- # # Default levels and level names, these can be replaced with any positive set # of values having corresponding names. There is a pseudo-level, NOTSET, which # is only really there as a lower limit for user-defined levels. Handlers and # loggers are initialized with NOTSET so that they will log all messages, even # at user-defined levels. # CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 _levelToName = { CRITICAL: 'CRITICAL', ERROR: 'ERROR', WARNING: 'WARNING', INFO: 'INFO', DEBUG: 'DEBUG', NOTSET: 'NOTSET', } _nameToLevel = { 'CRITICAL': CRITICAL, 'FATAL': FATAL, 'ERROR': ERROR, 'WARN': WARNING, 'WARNING': WARNING, 'INFO': INFO, 'DEBUG': DEBUG, 'NOTSET': NOTSET, } def getLevelNamesMapping(): return _nameToLevel.copy() def getLevelName(level): """ Return the textual or numeric representation of logging level 'level'. If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, INFO, DEBUG) then you get the corresponding string. If you have associated levels with names using addLevelName then the name you have associated with 'level' is returned. If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned. If a string representation of the level is passed in, the corresponding numeric value is returned. If no matching numeric or string value is passed in, the string 'Level %s' % level is returned. """ # See Issues #22386, #27937 and #29220 for why it's this way result = _levelToName.get(level) if result is not None: return result result = _nameToLevel.get(level) if result is not None: return result return "Level %s" % level def addLevelName(level, levelName): """ Associate 'levelName' with 'level'. This is used when converting levels to text during message formatting. """ _acquireLock() try: #unlikely to cause an exception, but you never know... _levelToName[level] = levelName _nameToLevel[levelName] = level finally: _releaseLock() if hasattr(sys, "_getframe"): currentframe = lambda: sys._getframe(1) else: #pragma: no cover def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise Exception except Exception as exc: return exc.__traceback__.tb_frame.f_back # # _srcfile is used when walking the stack to check when we've got the first # caller stack frame, by skipping frames whose filename is that of this # module's source. It therefore should contain the filename of this module's # source file. # # Ordinarily we would use __file__ for this, but frozen modules don't always # have __file__ set, for some reason (see Issue #21736). Thus, we get the # filename from a handy code object from a function defined in this module. # (There's no particular reason for picking addLevelName.) # _srcfile = os.path.normcase(addLevelName.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). # Setting _srcfile to None will prevent findCaller() from being called. This # way, you can avoid the overhead of fetching caller information. # The following is based on warnings._is_internal_frame. It makes sure that # frames of the import mechanism are skipped when logging at module level and # using a stacklevel value greater than one. def _is_internal_frame(frame): """Signal whether the frame is a CPython or logging module internal.""" filename = os.path.normcase(frame.f_code.co_filename) return filename == _srcfile or ( "importlib" in filename and "_bootstrap" in filename ) def _checkLevel(level): if isinstance(level, int): rv = level elif str(level) == level: if level not in _nameToLevel: raise ValueError("Unknown level: %r" % level) rv = _nameToLevel[level] else: raise TypeError("Level not an integer or a valid string: %r" % (level,)) return rv #--------------------------------------------------------------------------- # Thread-related stuff #--------------------------------------------------------------------------- # #_lock is used to serialize access to shared data structures in this module. #This needs to be an RLock because fileConfig() creates and configures #Handlers, and so might arbitrary user threads. Since Handler code updates the #shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # _lock = threading.RLock() def _acquireLock(): """ Acquire the module-level lock for serializing access to shared data. This should be released with _releaseLock(). """ if _lock: _lock.acquire() def _releaseLock(): """ Release the module-level lock acquired by calling _acquireLock(). """ if _lock: _lock.release() # Prevent a held logging lock from blocking a child from logging. if not hasattr(os, 'register_at_fork'): # Windows and friends. def _register_at_fork_reinit_lock(instance): pass # no-op when os.register_at_fork does not exist. else: # A collection of instances with a _at_fork_reinit method (logging.Handler) # to be called in the child after forking. The weakref avoids us keeping # discarded Handler instances alive. _at_fork_reinit_lock_weakset = weakref.WeakSet() def _register_at_fork_reinit_lock(instance): _acquireLock() try: _at_fork_reinit_lock_weakset.add(instance) finally: _releaseLock() def _after_at_fork_child_reinit_locks(): for handler in _at_fork_reinit_lock_weakset: handler._at_fork_reinit() # _acquireLock() was called in the parent before forking. # The lock is reinitialized to unlocked state. _lock._at_fork_reinit() os.register_at_fork(before=_acquireLock, after_in_child=_after_at_fork_child_reinit_locks, after_in_parent=_releaseLock) #--------------------------------------------------------------------------- # The logging record #--------------------------------------------------------------------------- class LogRecord(object): """ A LogRecord instance represents an event being logged. LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is in msg and args, which are combined using str(msg) % args to create the message field of the record. The record also includes information such as when the record was created, the source line where the logging call was made, and any exception information to be logged. """ def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None, **kwargs): """ Initialize a logging record with interesting information. """ ct = time.time() self.name = name self.msg = msg # # The following statement allows passing of a dictionary as a sole # argument, so that you can do something like # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) # Suggested by Stefan Behnel. # Note that without the test for args[0], we get a problem because # during formatting, we test to see if the arg is present using # 'if self.args:'. If the event being logged is e.g. 'Value is %d' # and if the passed arg fails 'if self.args:' then no formatting # is done. For example, logger.warning('Value is %d', 0) would log # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. # Issue #21172: a request was made to relax the isinstance check # to hasattr(args[0], '__getitem__'). However, the docs on string # formatting still seem to suggest a mapping object is required. # Thus, while not removing the isinstance check, it does now look # for collections.abc.Mapping rather than, as before, dict. if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping) and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) self.levelno = level self.pathname = pathname try: self.filename = os.path.basename(pathname) self.module = os.path.splitext(self.filename)[0] except (TypeError, ValueError, AttributeError): self.filename = pathname self.module = "Unknown module" self.exc_info = exc_info self.exc_text = None # used to cache the traceback text self.stack_info = sinfo self.lineno = lineno self.funcName = func self.created = ct self.msecs = int((ct - int(ct)) * 1000) + 0.0 # see gh-89047 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads: self.thread = threading.get_ident() self.threadName = threading.current_thread().name else: # pragma: no cover self.thread = None self.threadName = None if not logMultiprocessing: # pragma: no cover self.processName = None else: self.processName = 'MainProcess' mp = sys.modules.get('multiprocessing') if mp is not None: # Errors may occur if multiprocessing has not finished loading # yet - e.g. if a custom import hook causes third-party code # to run when multiprocessing calls import. See issue 8200 # for an example try: self.processName = mp.current_process().name except Exception: #pragma: no cover pass if logProcesses and hasattr(os, 'getpid'): self.process = os.getpid() else: self.process = None self.taskName = None if logAsyncioTasks: asyncio = sys.modules.get('asyncio') if asyncio: try: self.taskName = asyncio.current_task().get_name() except Exception: pass def __repr__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) def getMessage(self): """ Return the message for this LogRecord. Return the message for this LogRecord after merging any user-supplied arguments with the message. """ msg = str(self.msg) if self.args: msg = msg % self.args return msg # # Determine which class to use when instantiating log records. # _logRecordFactory = LogRecord def setLogRecordFactory(factory): """ Set the factory to be used when instantiating a log record. :param factory: A callable which will be called to instantiate a log record. """ global _logRecordFactory _logRecordFactory = factory def getLogRecordFactory(): """ Return the factory to be used when instantiating a log record. """ return _logRecordFactory def makeLogRecord(dict): """ Make a LogRecord whose attributes are defined by the specified dictionary, This function is useful for converting a logging event received over a socket connection (which is sent as a dictionary) into a LogRecord instance. """ rv = _logRecordFactory(None, None, "", 0, "", (), None, None) rv.__dict__.update(dict) return rv #--------------------------------------------------------------------------- # Formatter classes and functions #--------------------------------------------------------------------------- _str_formatter = StrFormatter() del StrFormatter class PercentStyle(object): default_format = '%(message)s' asctime_format = '%(asctime)s' asctime_search = '%(asctime)' validation_pattern = re.compile(r'%\(\w+\)[#0+ -]*(\*|\d+)?(\.(\*|\d+))?[diouxefgcrsa%]', re.I) def __init__(self, fmt, *, defaults=None): self._fmt = fmt or self.default_format self._defaults = defaults def usesTime(self): return self._fmt.find(self.asctime_search) >= 0 def validate(self): """Validate the input format, ensure it matches the correct style""" if not self.validation_pattern.search(self._fmt): raise ValueError("Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0])) def _format(self, record): if defaults := self._defaults: values = defaults | record.__dict__ else: values = record.__dict__ return self._fmt % values def format(self, record): try: return self._format(record) except KeyError as e: raise ValueError('Formatting field not found in record: %s' % e) class StrFormatStyle(PercentStyle): default_format = '{message}' asctime_format = '{asctime}' asctime_search = '{asctime' fmt_spec = re.compile(r'^(.?[<>=^])?[+ -]?#?0?(\d+|{\w+})?[,_]?(\.(\d+|{\w+}))?[bcdefgnosx%]?$', re.I) field_spec = re.compile(r'^(\d+|\w+)(\.\w+|\[[^]]+\])*$') def _format(self, record): if defaults := self._defaults: values = defaults | record.__dict__ else: values = record.__dict__ return self._fmt.format(**values) def validate(self): """Validate the input format, ensure it is the correct string formatting style""" fields = set() try: for _, fieldname, spec, conversion in _str_formatter.parse(self._fmt): if fieldname: if not self.field_spec.match(fieldname): raise ValueError('invalid field name/expression: %r' % fieldname) fields.add(fieldname) if conversion and conversion not in 'rsa': raise ValueError('invalid conversion: %r' % conversion) if spec and not self.fmt_spec.match(spec): raise ValueError('bad specifier: %r' % spec) except ValueError as e: raise ValueError('invalid format: %s' % e) if not fields: raise ValueError('invalid format: no fields') class StringTemplateStyle(PercentStyle): default_format = '${message}' asctime_format = '${asctime}' asctime_search = '${asctime}' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._tpl = Template(self._fmt) def usesTime(self): fmt = self._fmt return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_search) >= 0 def validate(self): pattern = Template.pattern fields = set() for m in pattern.finditer(self._fmt): d = m.groupdict() if d['named']: fields.add(d['named']) elif d['braced']: fields.add(d['braced']) elif m.group(0) == '$': raise ValueError('invalid format: bare \'$\' not allowed') if not fields: raise ValueError('invalid format: no fields') def _format(self, record): if defaults := self._defaults: values = defaults | record.__dict__ else: values = record.__dict__ return self._tpl.substitute(**values) BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" _STYLES = { '%': (PercentStyle, BASIC_FORMAT), '{': (StrFormatStyle, '{levelname}:{name}:{message}'), '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), } class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. Formatters need to know how a LogRecord is constructed. They are responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the style-dependent default value, "%(message)s", "{message}", or "${message}", is used. The Formatter can be initialized with a format string which makes use of knowledge of the LogRecord attributes - e.g. the default value mentioned above makes use of the fact that the user's message and arguments are pre- formatted into a LogRecord's message attribute. Currently, the useful attributes in a LogRecord are described by: %(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(taskName)s Task name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted """ converter = time.localtime def __init__(self, fmt=None, datefmt=None, style='%', validate=True, *, defaults=None): """ Initialize the formatter with specified format strings. Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument. If datefmt is omitted, you get an ISO8601-like (or RFC 3339-like) format. Use a style parameter of '%', '{' or '$' to specify that you want to use one of %-formatting, :meth:`str.format` (``{}``) formatting or :class:`string.Template` formatting in your format string. .. versionchanged:: 3.2 Added the ``style`` parameter. """ if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) self._style = _STYLES[style][0](fmt, defaults=defaults) if validate: self._style.validate() self._fmt = self._style._fmt self.datefmt = datefmt default_time_format = '%Y-%m-%d %H:%M:%S' default_msec_format = '%s,%03d' def formatTime(self, record, datefmt=None): """ Return the creation time of the specified LogRecord as formatted text. This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) if datefmt: s = time.strftime(datefmt, ct) else: s = time.strftime(self.default_time_format, ct) if self.default_msec_format: s = self.default_msec_format % (s, record.msecs) return s def formatException(self, ei): """ Format and return the specified exception information as a string. This default implementation just uses traceback.print_exception() """ sio = io.StringIO() tb = ei[2] # See issues #9427, #1553375. Commented out for now. #if getattr(self, 'fullstack', False): # traceback.print_stack(tb.tb_frame.f_back, file=sio) traceback.print_exception(ei[0], ei[1], tb, None, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] return s def usesTime(self): """ Check if the format uses the creation time of the record. """ return self._style.usesTime() def formatMessage(self, record): return self._style.format(record) def formatStack(self, stack_info): """ This method is provided as an extension point for specialized formatting of stack information. The input data is a string as returned from a call to :func:`traceback.print_stack`, but with the last trailing newline removed. The base implementation just returns the value passed in. """ return stack_info def format(self, record): """ Format the specified record as text. The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message. """ record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) return s # # The default formatter to use when no other is specified # _defaultFormatter = Formatter() class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ def __init__(self, linefmt=None): """ Optionally specify a formatter which will be used to format each individual record. """ if linefmt: self.linefmt = linefmt else: self.linefmt = _defaultFormatter def formatHeader(self, records): """ Return the header string for the specified records. """ return "" def formatFooter(self, records): """ Return the footer string for the specified records. """ return "" def format(self, records): """ Format the specified records and return the result as a string. """ rv = "" if len(records) > 0: rv = rv + self.formatHeader(records) for record in records: rv = rv + self.linefmt.format(record) rv = rv + self.formatFooter(records) return rv #--------------------------------------------------------------------------- # Filter classes and functions #--------------------------------------------------------------------------- class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed. """ def __init__(self, name=''): """ Initialize a filter. Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event. """ self.name = name self.nlen = len(name) def filter(self, record): """ Determine if the specified record is to be logged. Returns True if the record should be logged, or False otherwise. If deemed appropriate, the record may be modified in-place. """ if self.nlen == 0: return True elif self.name == record.name: return True elif record.name.find(self.name, 0, self.nlen) != 0: return False return (record.name[self.nlen] == ".") class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. """ def __init__(self): """ Initialize the list of filters to be an empty list. """ self.filters = [] def addFilter(self, filter): """ Add the specified filter to this handler. """ if not (filter in self.filters): self.filters.append(filter) def removeFilter(self, filter): """ Remove the specified filter from this handler. """ if filter in self.filters: self.filters.remove(filter) def filter(self, record): """ Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto this by returning a false value. If a filter attached to a handler returns a log record instance, then that instance is used in place of the original log record in any further processing of the event by that handler. If a filter returns any other true value, the original log record is used in any further processing of the event by that handler. If none of the filters return false values, this method returns a log record. If any of the filters return a false value, this method returns a false value. .. versionchanged:: 3.2 Allow filters to be just callables. .. versionchanged:: 3.12 Allow filters to return a LogRecord instead of modifying it in place. """ for f in self.filters: if hasattr(f, 'filter'): result = f.filter(record) else: result = f(record) # assume callable - will raise if not if not result: return False if isinstance(result, LogRecord): record = result return record #--------------------------------------------------------------------------- # Handler classes and functions #--------------------------------------------------------------------------- _handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized def _removeHandlerRef(wr): """ Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are # set to None. It can also be called from another thread. So we need to # pre-emptively grab the necessary globals and check if they're None, # to prevent race conditions and failures during interpreter shutdown. acquire, release, handlers = _acquireLock, _releaseLock, _handlerList if acquire and release and handlers: acquire() try: handlers.remove(wr) except ValueError: pass finally: release() def _addHandlerRef(handler): """ Add a handler to the internal cleanup list using a weak reference. """ _acquireLock() try: _handlerList.append(weakref.ref(handler, _removeHandlerRef)) finally: _releaseLock() def getHandlerByName(name): """ Get a handler with the specified *name*, or None if there isn't one with that name. """ return _handlers.get(name) def getHandlerNames(): """ Return all known handler names as an immutable set. """ result = set(_handlers.keys()) return frozenset(result) class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. The base handler class. Acts as a placeholder which defines the Handler interface. Handlers can optionally use Formatter instances to format records as desired. By default, no formatter is specified; in this case, the 'raw' message as determined by record.message is logged. """ def __init__(self, level=NOTSET): """ Initializes the instance - basically setting the formatter to None and the filter list to empty. """ Filterer.__init__(self) self._name = None self.level = _checkLevel(level) self.formatter = None self._closed = False # Add the handler to the global _handlerList (for cleanup on shutdown) _addHandlerRef(self) self.createLock() def get_name(self): return self._name def set_name(self, name): _acquireLock() try: if self._name in _handlers: del _handlers[self._name] self._name = name if name: _handlers[name] = self finally: _releaseLock() name = property(get_name, set_name) def createLock(self): """ Acquire a thread lock for serializing access to the underlying I/O. """ self.lock = threading.RLock() _register_at_fork_reinit_lock(self) def _at_fork_reinit(self): self.lock._at_fork_reinit() def acquire(self): """ Acquire the I/O thread lock. """ if self.lock: self.lock.acquire() def release(self): """ Release the I/O thread lock. """ if self.lock: self.lock.release() def setLevel(self, level): """ Set the logging level of this handler. level must be an int or a str. """ self.level = _checkLevel(level) def format(self, record): """ Format the specified record. If a formatter is set, use it. Otherwise, use the default formatter for the module. """ if self.formatter: fmt = self.formatter else: fmt = _defaultFormatter return fmt.format(record) def emit(self, record): """ Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so raises a NotImplementedError. """ raise NotImplementedError('emit must be implemented ' 'by Handler subclasses') def handle(self, record): """ Conditionally emit the specified logging record. Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns an instance of the log record that was emitted if it passed all filters, otherwise a false value is returned. """ rv = self.filter(record) if isinstance(rv, LogRecord): record = rv if rv: self.acquire() try: self.emit(record) finally: self.release() return rv def setFormatter(self, fmt): """ Set the formatter for this handler. """ self.formatter = fmt def flush(self): """ Ensure all logging output has been flushed. This version does nothing and is intended to be implemented by subclasses. """ pass def close(self): """ Tidy up any resources used by the handler. This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... self._closed = True if self._name and self._name in _handlers: del _handlers[self._name] finally: _releaseLock() def handleError(self, record): """ Handle errors which occur during an emit() call. This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method. """ if raiseExceptions and sys.stderr: # see issue 13807 t, v, tb = sys.exc_info() try: sys.stderr.write('--- Logging error ---\n') traceback.print_exception(t, v, tb, None, sys.stderr) sys.stderr.write('Call stack:\n') # Walk the stack frame up until we're out of logging, # so as to print the calling context. frame = tb.tb_frame while (frame and os.path.dirname(frame.f_code.co_filename) == __path__[0]): frame = frame.f_back if frame: traceback.print_stack(frame, file=sys.stderr) else: # couldn't find the right stack frame, for some reason sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) # Issue 18671: output logging message and arguments try: sys.stderr.write('Message: %r\n' 'Arguments: %s\n' % (record.msg, record.args)) except RecursionError: # See issue 36272 raise except Exception: sys.stderr.write('Unable to print the message and arguments' ' - possible formatting error.\nUse the' ' traceback above to help find the error.\n' ) except OSError: #pragma: no cover pass # see issue 5971 finally: del t, v, tb def __repr__(self): level = getLevelName(self.level) return '<%s (%s)>' % (self.__class__.__name__, level) class StreamHandler(Handler): """ A handler class which writes logging records, appropriately formatted, to a stream. Note that this class does not close the stream, as sys.stdout or sys.stderr may be used. """ terminator = '\n' def __init__(self, stream=None): """ Initialize the handler. If stream is not specified, sys.stderr is used. """ Handler.__init__(self) if stream is None: stream = sys.stderr self.stream = stream def flush(self): """ Flushes the stream. """ self.acquire() try: if self.stream and hasattr(self.stream, "flush"): self.stream.flush() finally: self.release() def emit(self, record): """ Emit a record. If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an 'encoding' attribute, it is used to determine how to do the output to the stream. """ try: msg = self.format(record) stream = self.stream # issue 35046: merged two stream.writes into one. stream.write(msg + self.terminator) self.flush() except RecursionError: # See issue 36272 raise except Exception: self.handleError(record) def setStream(self, stream): """ Sets the StreamHandler's stream to the specified value, if it is different. Returns the old stream, if the stream was changed, or None if it wasn't. """ if stream is self.stream: result = None else: result = self.stream self.acquire() try: self.flush() self.stream = stream finally: self.release() return result def __repr__(self): level = getLevelName(self.level) name = getattr(self.stream, 'name', '') # bpo-36015: name can be an int name = str(name) if name: name += ' ' return '<%s %s(%s)>' % (self.__class__.__name__, name, level) __class_getitem__ = classmethod(GenericAlias) class FileHandler(StreamHandler): """ A handler class which writes formatted logging records to disk files. """ def __init__(self, filename, mode='a', encoding=None, delay=False, errors=None): """ Open the specified file and use it as the stream for logging. """ # Issue #27493: add support for Path objects to be passed in filename = os.fspath(filename) #keep the absolute path, otherwise derived classes which use this #may come a cropper when the current directory changes self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding if "b" not in mode: self.encoding = io.text_encoding(encoding) self.errors = errors self.delay = delay # bpo-26789: FileHandler keeps a reference to the builtin open() # function to be able to open or reopen the file during Python # finalization. self._builtin_open = open if delay: #We don't open the stream, but we still need to call the #Handler constructor to set level, formatter, lock etc. Handler.__init__(self) self.stream = None else: StreamHandler.__init__(self, self._open()) def close(self): """ Closes the stream. """ self.acquire() try: try: if self.stream: try: self.flush() finally: stream = self.stream self.stream = None if hasattr(stream, "close"): stream.close() finally: # Issue #19523: call unconditionally to # prevent a handler leak when delay is set # Also see Issue #42378: we also rely on # self._closed being set to True there StreamHandler.close(self) finally: self.release() def _open(self): """ Open the current base file with the (original) mode and encoding. Return the resulting stream. """ open_func = self._builtin_open return open_func(self.baseFilename, self.mode, encoding=self.encoding, errors=self.errors) def emit(self, record): """ Emit a record. If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit. If stream is not open, current mode is 'w' and `_closed=True`, record will not be emitted (see Issue #42378). """ if self.stream is None: if self.mode != 'w' or not self._closed: self.stream = self._open() if self.stream: StreamHandler.emit(self, record) def __repr__(self): level = getLevelName(self.level) return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level) class _StderrHandler(StreamHandler): """ This class is like a StreamHandler using sys.stderr, but always uses whatever sys.stderr is currently set to rather than the value of sys.stderr at handler construction time. """ def __init__(self, level=NOTSET): """ Initialize the handler. """ Handler.__init__(self, level) @property def stream(self): return sys.stderr _defaultLastResort = _StderrHandler(WARNING) lastResort = _defaultLastResort #--------------------------------------------------------------------------- # Manager classes and functions #--------------------------------------------------------------------------- class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is intended for internal use only and not as part of the public API. """ def __init__(self, alogger): """ Initialize with the specified logger being a child of this placeholder. """ self.loggerMap = { alogger : None } def append(self, alogger): """ Add the specified logger as a child of this placeholder. """ if alogger not in self.loggerMap: self.loggerMap[alogger] = None # # Determine which class to use when instantiating loggers. # def setLoggerClass(klass): """ Set the class to be used when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__() """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) global _loggerClass _loggerClass = klass def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ return _loggerClass class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. """ def __init__(self, rootnode): """ Initialize the manager with the root node of the logger hierarchy. """ self.root = rootnode self.disable = 0 self.emittedNoHandlerWarning = False self.loggerDict = {} self.loggerClass = None self.logRecordFactory = None @property def disable(self): return self._disable @disable.setter def disable(self, value): self._disable = _checkLevel(value) def getLogger(self, name): """ Get a logger with the specified name (channel name), creating it if it doesn't yet exist. This name is a dot-separated hierarchical name, such as "a", "a.b", "a.b.c" or similar. If a PlaceHolder existed for the specified name [i.e. the logger didn't exist but a child of it did], replace it with the created logger and fix up the parent/child references which pointed to the placeholder to now point to the logger. """ rv = None if not isinstance(name, str): raise TypeError('A logger name must be a string') _acquireLock() try: if name in self.loggerDict: rv = self.loggerDict[name] if isinstance(rv, PlaceHolder): ph = rv rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupChildren(ph, rv) self._fixupParents(rv) else: rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupParents(rv) finally: _releaseLock() return rv def setLoggerClass(self, klass): """ Set the class to be used when instantiating a logger with this Manager. """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) self.loggerClass = klass def setLogRecordFactory(self, factory): """ Set the factory to be used when instantiating a log record with this Manager. """ self.logRecordFactory = factory def _fixupParents(self, alogger): """ Ensure that there are either loggers or placeholders all the way from the specified logger to the root of the logger hierarchy. """ name = alogger.name i = name.rfind(".") rv = None while (i > 0) and not rv: substr = name[:i] if substr not in self.loggerDict: self.loggerDict[substr] = PlaceHolder(alogger) else: obj = self.loggerDict[substr] if isinstance(obj, Logger): rv = obj else: assert isinstance(obj, PlaceHolder) obj.append(alogger) i = name.rfind(".", 0, i - 1) if not rv: rv = self.root alogger.parent = rv def _fixupChildren(self, ph, alogger): """ Ensure that children of the placeholder ph are connected to the specified logger. """ name = alogger.name namelen = len(name) for c in ph.loggerMap.keys(): #The if means ... if not c.parent.name.startswith(nm) if c.parent.name[:namelen] != name: alogger.parent = c.parent c.parent = alogger def _clear_cache(self): """ Clear the cache for all loggers in loggerDict Called when level changes are made """ _acquireLock() for logger in self.loggerDict.values(): if isinstance(logger, Logger): logger._cache.clear() self.root._cache.clear() _releaseLock() #--------------------------------------------------------------------------- # Logger classes and functions #--------------------------------------------------------------------------- class Logger(Filterer): """ Instances of the Logger class represent a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting. """ def __init__(self, name, level=NOTSET): """ Initialize the logger with a name and an optional level. """ Filterer.__init__(self) self.name = name self.level = _checkLevel(level) self.parent = None self.propagate = True self.handlers = [] self.disabled = False self._cache = {} def setLevel(self, level): """ Set the logging level of this logger. level must be an int or a str. """ self.level = _checkLevel(level) self.manager._clear_cache() def debug(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'DEBUG'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.debug("Houston, we have a %s", "thorny problem", exc_info=True) """ if self.isEnabledFor(DEBUG): self._log(DEBUG, msg, args, **kwargs) def info(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'INFO'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.info("Houston, we have a %s", "notable problem", exc_info=True) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) def warning(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'WARNING'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.warning("Houston, we have a %s", "bit of a problem", exc_info=True) """ if self.isEnabledFor(WARNING): self._log(WARNING, msg, args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'ERROR'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.error("Houston, we have a %s", "major problem", exc_info=True) """ if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Convenience method for logging an ERROR with exception information. """ self.error(msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'CRITICAL'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.critical("Houston, we have a %s", "major disaster", exc_info=True) """ if self.isEnabledFor(CRITICAL): self._log(CRITICAL, msg, args, **kwargs) def fatal(self, msg, *args, **kwargs): """ Don't use this method, use critical() instead. """ self.critical(msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.log(level, "We have a %s", "mysterious problem", exc_info=True) """ if not isinstance(level, int): if raiseExceptions: raise TypeError("level must be an integer") else: return if self.isEnabledFor(level): self._log(level, msg, args, **kwargs) def findCaller(self, stack_info=False, stacklevel=1): """ Find the stack frame of the caller so that we can note the source file name, line number and function name. """ f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. if f is None: return "(unknown file)", 0, "(unknown function)", None while stacklevel > 0: next_f = f.f_back if next_f is None: ## We've got options here. ## If we want to use the last (deepest) frame: break ## If we want to mimic the warnings module: #return ("sys", 1, "(unknown function)", None) ## If we want to be pedantic: #raise ValueError("call stack is not deep enough") f = next_f if not _is_internal_frame(f): stacklevel -= 1 co = f.f_code sinfo = None if stack_info: with io.StringIO() as sio: sio.write("Stack (most recent call last):\n") traceback.print_stack(f, file=sio) sinfo = sio.getvalue() if sinfo[-1] == '\n': sinfo = sinfo[:-1] return co.co_filename, f.f_lineno, co.co_name, sinfo def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None): """ A factory method which can be overridden in subclasses to create specialized LogRecords. """ rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func, sinfo) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] return rv def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1): """ Low-level logging routine which creates a LogRecord and then calls all the handlers of this logger to handle the record. """ sinfo = None if _srcfile: #IronPython doesn't track Python frames, so findCaller raises an #exception on some versions of IronPython. We trap it here so that #IronPython can use logging. try: fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel) except ValueError: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" else: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: if isinstance(exc_info, BaseException): exc_info = (type(exc_info), exc_info, exc_info.__traceback__) elif not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra, sinfo) self.handle(record) def handle(self, record): """ Call the handlers for the specified record. This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ if self.disabled: return maybe_record = self.filter(record) if not maybe_record: return if isinstance(maybe_record, LogRecord): record = maybe_record self.callHandlers(record) def addHandler(self, hdlr): """ Add the specified handler to this logger. """ _acquireLock() try: if not (hdlr in self.handlers): self.handlers.append(hdlr) finally: _releaseLock() def removeHandler(self, hdlr): """ Remove the specified handler from this logger. """ _acquireLock() try: if hdlr in self.handlers: self.handlers.remove(hdlr) finally: _releaseLock() def hasHandlers(self): """ See if this logger has any handlers configured. Loop through all handlers for this logger and its parents in the logger hierarchy. Return True if a handler was found, else False. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger which is checked for the existence of handlers. """ c = self rv = False while c: if c.handlers: rv = True break if not c.propagate: break else: c = c.parent return rv def callHandlers(self, record): """ Pass a record to all relevant handlers. Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called. """ c = self found = 0 while c: for hdlr in c.handlers: found = found + 1 if record.levelno >= hdlr.level: hdlr.handle(record) if not c.propagate: c = None #break out else: c = c.parent if (found == 0): if lastResort: if record.levelno >= lastResort.level: lastResort.handle(record) elif raiseExceptions and not self.manager.emittedNoHandlerWarning: sys.stderr.write("No handlers could be found for logger" " \"%s\"\n" % self.name) self.manager.emittedNoHandlerWarning = True def getEffectiveLevel(self): """ Get the effective level for this logger. Loop through this logger and its parents in the logger hierarchy, looking for a non-zero logging level. Return the first one found. """ logger = self while logger: if logger.level: return logger.level logger = logger.parent return NOTSET def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.disabled: return False try: return self._cache[level] except KeyError: _acquireLock() try: if self.manager.disable >= level: is_enabled = self._cache[level] = False else: is_enabled = self._cache[level] = ( level >= self.getEffectiveLevel() ) finally: _releaseLock() return is_enabled def getChild(self, suffix): """ Get a logger which is a descendant to this one. This is a convenience method, such that logging.getLogger('abc').getChild('def.ghi') is the same as logging.getLogger('abc.def.ghi') It's useful, for example, when the parent logger is named using __name__ rather than a literal string. """ if self.root is not self: suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) def getChildren(self): def _hierlevel(logger): if logger is logger.manager.root: return 0 return 1 + logger.name.count('.') d = self.manager.loggerDict _acquireLock() try: # exclude PlaceHolders - the last check is to ensure that lower-level # descendants aren't returned - if there are placeholders, a logger's # parent field might point to a grandparent or ancestor thereof. return set(item for item in d.values() if isinstance(item, Logger) and item.parent is self and _hierlevel(item) == 1 + _hierlevel(item.parent)) finally: _releaseLock() def __repr__(self): level = getLevelName(self.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) def __reduce__(self): if getLogger(self.name) is not self: import pickle raise pickle.PicklingError('logger cannot be pickled') return getLogger, (self.name,) class RootLogger(Logger): """ A root logger is not that different to any other logger, except that it must have a logging level and there is only one instance of it in the hierarchy. """ def __init__(self, level): """ Initialize the logger with the name "root". """ Logger.__init__(self, "root", level) def __reduce__(self): return getLogger, () _loggerClass = Logger class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. """ def __init__(self, logger, extra=None): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows easy stacking of LoggerAdapters, if so desired. You can effectively pass keyword arguments as shown in the following example: adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) """ self.logger = logger self.extra = extra def process(self, msg, kwargs): """ Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs. Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs. """ kwargs["extra"] = self.extra return msg, kwargs # # Boilerplate convenience methods # def debug(self, msg, *args, **kwargs): """ Delegate a debug call to the underlying logger. """ self.log(DEBUG, msg, *args, **kwargs) def info(self, msg, *args, **kwargs): """ Delegate an info call to the underlying logger. """ self.log(INFO, msg, *args, **kwargs) def warning(self, msg, *args, **kwargs): """ Delegate a warning call to the underlying logger. """ self.log(WARNING, msg, *args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Delegate an error call to the underlying logger. """ self.log(ERROR, msg, *args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Delegate an exception call to the underlying logger. """ self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Delegate a critical call to the underlying logger. """ self.log(CRITICAL, msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Delegate a log call to the underlying logger, after adding contextual information from this adapter instance. """ if self.isEnabledFor(level): msg, kwargs = self.process(msg, kwargs) self.logger.log(level, msg, *args, **kwargs) def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ return self.logger.isEnabledFor(level) def setLevel(self, level): """ Set the specified level on the underlying logger. """ self.logger.setLevel(level) def getEffectiveLevel(self): """ Get the effective level for the underlying logger. """ return self.logger.getEffectiveLevel() def hasHandlers(self): """ See if the underlying logger has any handlers. """ return self.logger.hasHandlers() def _log(self, level, msg, args, **kwargs): """ Low-level log implementation, proxied to allow nested logger adapters. """ return self.logger._log(level, msg, args, **kwargs) @property def manager(self): return self.logger.manager @manager.setter def manager(self, value): self.logger.manager = value @property def name(self): return self.logger.name def __repr__(self): logger = self.logger level = getLevelName(logger.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level) __class_getitem__ = classmethod(GenericAlias) root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) #--------------------------------------------------------------------------- # Configuration classes and functions #--------------------------------------------------------------------------- def basicConfig(**kwargs): """ Do basic configuration for the logging system. This function does nothing if the root logger already has handlers configured, unless the keyword argument *force* is set to ``True``. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package. The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger. A number of optional keyword arguments may be specified, which can alter the default behaviour. filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler. filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format Use the specified format string for the handler. datefmt Use the specified date/time format. style If a format string is specified, use this to specify the type of format string (possible values '%', '{', '$', for %-formatting, :meth:`str.format` and :class:`string.Template` - defaults to '%'). level Set the root logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored. handlers If specified, this should be an iterable of already created handlers, which will be added to the root logger. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function. force If this keyword is specified as true, any existing handlers attached to the root logger are removed and closed, before carrying out the configuration as specified by the other arguments. encoding If specified together with a filename, this encoding is passed to the created FileHandler, causing it to be used when the file is opened. errors If specified together with a filename, this value is passed to the created FileHandler, causing it to be used when the file is opened in text mode. If not specified, the default value is `backslashreplace`. Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed. .. versionchanged:: 3.2 Added the ``style`` parameter. .. versionchanged:: 3.3 Added the ``handlers`` parameter. A ``ValueError`` is now thrown for incompatible arguments (e.g. ``handlers`` specified together with ``filename``/``filemode``, or ``filename``/``filemode`` specified together with ``stream``, or ``handlers`` specified together with ``stream``. .. versionchanged:: 3.8 Added the ``force`` parameter. .. versionchanged:: 3.9 Added the ``encoding`` and ``errors`` parameters. """ # Add thread safety in case someone mistakenly calls # basicConfig() from multiple threads _acquireLock() try: force = kwargs.pop('force', False) encoding = kwargs.pop('encoding', None) errors = kwargs.pop('errors', 'backslashreplace') if force: for h in root.handlers[:]: root.removeHandler(h) h.close() if len(root.handlers) == 0: handlers = kwargs.pop("handlers", None) if handlers is None: if "stream" in kwargs and "filename" in kwargs: raise ValueError("'stream' and 'filename' should not be " "specified together") else: if "stream" in kwargs or "filename" in kwargs: raise ValueError("'stream' or 'filename' should not be " "specified together with 'handlers'") if handlers is None: filename = kwargs.pop("filename", None) mode = kwargs.pop("filemode", 'a') if filename: if 'b' in mode: errors = None else: encoding = io.text_encoding(encoding) h = FileHandler(filename, mode, encoding=encoding, errors=errors) else: stream = kwargs.pop("stream", None) h = StreamHandler(stream) handlers = [h] dfs = kwargs.pop("datefmt", None) style = kwargs.pop("style", '%') if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) fs = kwargs.pop("format", _STYLES[style][1]) fmt = Formatter(fs, dfs, style) for h in handlers: if h.formatter is None: h.setFormatter(fmt) root.addHandler(h) level = kwargs.pop("level", None) if level is not None: root.setLevel(level) if kwargs: keys = ', '.join(kwargs.keys()) raise ValueError('Unrecognised argument(s): %s' % keys) finally: _releaseLock() #--------------------------------------------------------------------------- # Utility functions at module level. # Basically delegate everything to the root logger. #--------------------------------------------------------------------------- def getLogger(name=None): """ Return a logger with the specified name, creating it if necessary. If no name is specified, return the root logger. """ if not name or isinstance(name, str) and name == root.name: return root return Logger.manager.getLogger(name) def critical(msg, *args, **kwargs): """ Log a message with severity 'CRITICAL' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.critical(msg, *args, **kwargs) def fatal(msg, *args, **kwargs): """ Don't use this function, use critical() instead. """ critical(msg, *args, **kwargs) def error(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.error(msg, *args, **kwargs) def exception(msg, *args, exc_info=True, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. If the logger has no handlers, basicConfig() is called to add a console handler with a pre-defined format. """ error(msg, *args, exc_info=exc_info, **kwargs) def warning(msg, *args, **kwargs): """ Log a message with severity 'WARNING' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.warning(msg, *args, **kwargs) def warn(msg, *args, **kwargs): warnings.warn("The 'warn' function is deprecated, " "use 'warning' instead", DeprecationWarning, 2) warning(msg, *args, **kwargs) def info(msg, *args, **kwargs): """ Log a message with severity 'INFO' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.info(msg, *args, **kwargs) def debug(msg, *args, **kwargs): """ Log a message with severity 'DEBUG' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.debug(msg, *args, **kwargs) def log(level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.log(level, msg, *args, **kwargs) def disable(level=CRITICAL): """ Disable all logging calls of severity 'level' and below. """ root.manager.disable = level root.manager._clear_cache() def shutdown(handlerList=_handlerList): """ Perform any cleanup actions in the logging system (e.g. flushing buffers). Should be called at application exit. """ for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: h = wr() if h: try: h.acquire() # MemoryHandlers might not want to be flushed on close, # but circular imports prevent us scoping this to just # those handlers. hence the default to True. if getattr(h, 'flushOnClose', True): h.flush() h.close() except (OSError, ValueError): # Ignore errors which might be caused # because handlers have been closed but # references to them are still around at # application exit. pass finally: h.release() except: # ignore everything, as we're shutting down if raiseExceptions: raise #else, swallow #Let's try and shutdown automatically on application exit... import atexit atexit.register(shutdown) # Null handler class NullHandler(Handler): """ This handler does nothing. It's intended to be used to avoid the "No handlers could be found for logger XXX" one-off warning. This is important for library code, which may contain code to log events. If a user of the library does not configure logging, the one-off warning might be produced; to avoid this, the library developer simply needs to instantiate a NullHandler and add it to the top-level logger of the library module or package. """ def handle(self, record): """Stub.""" def emit(self, record): """Stub.""" def createLock(self): self.lock = None def _at_fork_reinit(self): pass # Warnings integration _warnings_showwarning = None def _showwarning(message, category, filename, lineno, file=None, line=None): """ Implementation of showwarnings which redirects to logging, which will first check to see if the file parameter is None. If a file is specified, it will delegate to the original warnings implementation of showwarning. Otherwise, it will call warnings.formatwarning and will log the resulting string to a warnings logger named "py.warnings" with level logging.WARNING. """ if file is not None: if _warnings_showwarning is not None: _warnings_showwarning(message, category, filename, lineno, file, line) else: s = warnings.formatwarning(message, category, filename, lineno, line) logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) # bpo-46557: Log str(s) as msg instead of logger.warning("%s", s) # since some log aggregation tools group logs by the msg arg logger.warning(str(s)) def captureWarnings(capture): """ If capture is true, redirect all warnings to the logging package. If capture is False, ensure that warnings are not redirected to logging but to their original destinations. """ global _warnings_showwarning if capture: if _warnings_showwarning is None: _warnings_showwarning = warnings.showwarning warnings.showwarning = _showwarning else: if _warnings_showwarning is not None: warnings.showwarning = _warnings_showwarning _warnings_showwarning = None usr/lib64/python3.12/zipfile/_path/__init__.py000064400000025154152346237470015014 0ustar00""" A Path-like interface for zipfiles. This codebase is shared between zipfile.Path in the stdlib and zipp in PyPI. See https://github.com/python/importlib_metadata/wiki/Development-Methodology for more detail. """ import io import posixpath import zipfile import itertools import contextlib import pathlib import re from .glob import translate __all__ = ['Path'] def _parents(path): """ Given a path with elements separated by posixpath.sep, generate all parents of that path. >>> list(_parents('b/d')) ['b'] >>> list(_parents('/b/d/')) ['/b'] >>> list(_parents('b/d/f/')) ['b/d', 'b'] >>> list(_parents('b')) [] >>> list(_parents('')) [] """ return itertools.islice(_ancestry(path), 1, None) def _ancestry(path): """ Given a path with elements separated by posixpath.sep, generate all elements of that path. >>> list(_ancestry('b/d')) ['b/d', 'b'] >>> list(_ancestry('/b/d/')) ['/b/d', '/b'] >>> list(_ancestry('b/d/f/')) ['b/d/f', 'b/d', 'b'] >>> list(_ancestry('b')) ['b'] >>> list(_ancestry('')) [] Multiple separators are treated like a single. >>> list(_ancestry('//b//d///f//')) ['//b//d///f', '//b//d', '//b'] """ path = path.rstrip(posixpath.sep) while path.rstrip(posixpath.sep): yield path path, tail = posixpath.split(path) _dedupe = dict.fromkeys """Deduplicate an iterable in original order""" def _difference(minuend, subtrahend): """ Return items in minuend not in subtrahend, retaining order with O(1) lookup. """ return itertools.filterfalse(set(subtrahend).__contains__, minuend) class InitializedState: """ Mix-in to save the initialization state for pickling. """ def __init__(self, *args, **kwargs): self.__args = args self.__kwargs = kwargs super().__init__(*args, **kwargs) def __getstate__(self): return self.__args, self.__kwargs def __setstate__(self, state): args, kwargs = state super().__init__(*args, **kwargs) class CompleteDirs(InitializedState, zipfile.ZipFile): """ A ZipFile subclass that ensures that implied directories are always included in the namelist. >>> list(CompleteDirs._implied_dirs(['foo/bar.txt', 'foo/bar/baz.txt'])) ['foo/', 'foo/bar/'] >>> list(CompleteDirs._implied_dirs(['foo/bar.txt', 'foo/bar/baz.txt', 'foo/bar/'])) ['foo/'] """ @staticmethod def _implied_dirs(names): parents = itertools.chain.from_iterable(map(_parents, names)) as_dirs = (p + posixpath.sep for p in parents) return _dedupe(_difference(as_dirs, names)) def namelist(self): names = super().namelist() return names + list(self._implied_dirs(names)) def _name_set(self): return set(self.namelist()) def resolve_dir(self, name): """ If the name represents a directory, return that name as a directory (with the trailing slash). """ names = self._name_set() dirname = name + '/' dir_match = name not in names and dirname in names return dirname if dir_match else name def getinfo(self, name): """ Supplement getinfo for implied dirs. """ try: return super().getinfo(name) except KeyError: if not name.endswith('/') or name not in self._name_set(): raise return zipfile.ZipInfo(filename=name) @classmethod def make(cls, source): """ Given a source (filename or zipfile), return an appropriate CompleteDirs subclass. """ if isinstance(source, CompleteDirs): return source if not isinstance(source, zipfile.ZipFile): return cls(source) # Only allow for FastLookup when supplied zipfile is read-only if 'r' not in source.mode: cls = CompleteDirs source.__class__ = cls return source class FastLookup(CompleteDirs): """ ZipFile subclass to ensure implicit dirs exist and are resolved rapidly. """ def namelist(self): with contextlib.suppress(AttributeError): return self.__names self.__names = super().namelist() return self.__names def _name_set(self): with contextlib.suppress(AttributeError): return self.__lookup self.__lookup = super()._name_set() return self.__lookup def _extract_text_encoding(encoding=None, *args, **kwargs): # stacklevel=3 so that the caller of the caller see any warning. return io.text_encoding(encoding, 3), args, kwargs class Path: """ A :class:`importlib.resources.abc.Traversable` interface for zip files. Implements many of the features users enjoy from :class:`pathlib.Path`. Consider a zip file with this structure:: . ├── a.txt └── b ├── c.txt └── d └── e.txt >>> data = io.BytesIO() >>> zf = ZipFile(data, 'w') >>> zf.writestr('a.txt', 'content of a') >>> zf.writestr('b/c.txt', 'content of c') >>> zf.writestr('b/d/e.txt', 'content of e') >>> zf.filename = 'mem/abcde.zip' Path accepts the zipfile object itself or a filename >>> root = Path(zf) From there, several path operations are available. Directory iteration (including the zip file itself): >>> a, b = root.iterdir() >>> a Path('mem/abcde.zip', 'a.txt') >>> b Path('mem/abcde.zip', 'b/') name property: >>> b.name 'b' join with divide operator: >>> c = b / 'c.txt' >>> c Path('mem/abcde.zip', 'b/c.txt') >>> c.name 'c.txt' Read text: >>> c.read_text(encoding='utf-8') 'content of c' existence: >>> c.exists() True >>> (b / 'missing.txt').exists() False Coercion to string: >>> import os >>> str(c).replace(os.sep, posixpath.sep) 'mem/abcde.zip/b/c.txt' At the root, ``name``, ``filename``, and ``parent`` resolve to the zipfile. Note these attributes are not valid and will raise a ``ValueError`` if the zipfile has no filename. >>> root.name 'abcde.zip' >>> str(root.filename).replace(os.sep, posixpath.sep) 'mem/abcde.zip' >>> str(root.parent) 'mem' """ __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" def __init__(self, root, at=""): """ Construct a Path from a ZipFile or filename. Note: When the source is an existing ZipFile object, its type (__class__) will be mutated to a specialized type. If the caller wishes to retain the original type, the caller should either create a separate ZipFile object or pass a filename. """ self.root = FastLookup.make(root) self.at = at def __eq__(self, other): """ >>> Path(zipfile.ZipFile(io.BytesIO(), 'w')) == 'foo' False """ if self.__class__ is not other.__class__: return NotImplemented return (self.root, self.at) == (other.root, other.at) def __hash__(self): return hash((self.root, self.at)) def open(self, mode='r', *args, pwd=None, **kwargs): """ Open this entry as text or binary following the semantics of ``pathlib.Path.open()`` by passing arguments through to io.TextIOWrapper(). """ if self.is_dir(): raise IsADirectoryError(self) zip_mode = mode[0] if zip_mode == 'r' and not self.exists(): raise FileNotFoundError(self) stream = self.root.open(self.at, zip_mode, pwd=pwd) if 'b' in mode: if args or kwargs: raise ValueError("encoding args invalid for binary operation") return stream # Text mode: encoding, args, kwargs = _extract_text_encoding(*args, **kwargs) return io.TextIOWrapper(stream, encoding, *args, **kwargs) def _base(self): return pathlib.PurePosixPath(self.at or self.root.filename) @property def name(self): return self._base().name @property def suffix(self): return self._base().suffix @property def suffixes(self): return self._base().suffixes @property def stem(self): return self._base().stem @property def filename(self): return pathlib.Path(self.root.filename).joinpath(self.at) def read_text(self, *args, **kwargs): encoding, args, kwargs = _extract_text_encoding(*args, **kwargs) with self.open('r', encoding, *args, **kwargs) as strm: return strm.read() def read_bytes(self): with self.open('rb') as strm: return strm.read() def _is_child(self, path): return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") def _next(self, at): return self.__class__(self.root, at) def is_dir(self): return not self.at or self.at.endswith("/") def is_file(self): return self.exists() and not self.is_dir() def exists(self): return self.at in self.root._name_set() def iterdir(self): if not self.is_dir(): raise ValueError("Can't listdir a file") subs = map(self._next, self.root.namelist()) return filter(self._is_child, subs) def match(self, path_pattern): return pathlib.PurePosixPath(self.at).match(path_pattern) def is_symlink(self): """ Return whether this path is a symlink. Always false (python/cpython#82102). """ return False def glob(self, pattern): if not pattern: raise ValueError(f"Unacceptable pattern: {pattern!r}") prefix = re.escape(self.at) matches = re.compile(prefix + translate(pattern)).fullmatch return map(self._next, filter(matches, self.root.namelist())) def rglob(self, pattern): return self.glob(f'**/{pattern}') def relative_to(self, other, *extra): return posixpath.relpath(str(self), str(other.joinpath(*extra))) def __str__(self): return posixpath.join(self.root.filename, self.at) def __repr__(self): return self.__repr.format(self=self) def joinpath(self, *other): next = posixpath.join(self.at, *other) return self._next(self.root.resolve_dir(next)) __truediv__ = joinpath @property def parent(self): if not self.at: return self.filename.parent parent_at = posixpath.dirname(self.at.rstrip('/')) if parent_at: parent_at += '/' return self._next(parent_at) lib64/python2.7/distutils/__init__.py000064400000000354152346257420013405 0ustar00"""distutils The main package for the Python Module Distribution Utilities. Normally used from a setup script as from distutils.core import setup setup (...) """ import sys __version__ = sys.version[:sys.version.index(' ')] lib64/python3.6/multiprocessing/__init__.py000064400000001633152346265060014610 0ustar00# # Package analogous to 'threading.py' but using processes # # multiprocessing/__init__.py # # This package is intended to duplicate the functionality (and much of # the API) of threading.py but uses processes instead of threads. A # subpackage 'multiprocessing.dummy' has the same API but is a simple # wrapper for 'threading'. # # Copyright (c) 2006-2008, R Oudkerk # Licensed to PSF under a Contributor Agreement. # import sys from . import context # # Copy stuff from default context # globals().update((name, getattr(context._default_context, name)) for name in context._default_context.__all__) __all__ = context._default_context.__all__ # # XXX These should not really be documented or public. # SUBDEBUG = 5 SUBWARNING = 25 # # Alias for main module -- will be reset by bootstrapping child processes # if '__main__' in sys.modules: sys.modules['__mp_main__'] = sys.modules['__main__'] usr/lib64/python3.8/sqlite3/__init__.py000064400000001772152346360250013561 0ustar00# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. from sqlite3.dbapi2 import * usr/lib64/python3.6/sqlite3/__init__.py000064400000001772152346360350013560 0ustar00# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. from sqlite3.dbapi2 import * usr/lib64/python3.12/pydoc_data/__init__.py000064400000000000152346367410014343 0ustar00usr/lib64/python3.6/http/__init__.py000064400000013501152346377230013151 0ustar00from enum import IntEnum __all__ = ['HTTPStatus'] class HTTPStatus(IntEnum): """HTTP status codes and reason phrases Status codes from the following RFCs are all observed: * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 * RFC 6585: Additional HTTP Status Codes * RFC 3229: Delta encoding in HTTP * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 * RFC 5842: Binding Extensions to WebDAV * RFC 7238: Permanent Redirect * RFC 2295: Transparent Content Negotiation in HTTP * RFC 2774: An HTTP Extension Framework """ def __new__(cls, value, phrase, description=''): obj = int.__new__(cls, value) obj._value_ = value obj.phrase = phrase obj.description = description return obj # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', 'Switching to new protocol; obey Upgrade header') PROCESSING = 102, 'Processing' # success OK = 200, 'OK', 'Request fulfilled, document follows' CREATED = 201, 'Created', 'Document created, URL follows' ACCEPTED = (202, 'Accepted', 'Request accepted, processing continues off-line') NON_AUTHORITATIVE_INFORMATION = (203, 'Non-Authoritative Information', 'Request fulfilled from cache') NO_CONTENT = 204, 'No Content', 'Request fulfilled, nothing follows' RESET_CONTENT = 205, 'Reset Content', 'Clear input form for further input' PARTIAL_CONTENT = 206, 'Partial Content', 'Partial content follows' MULTI_STATUS = 207, 'Multi-Status' ALREADY_REPORTED = 208, 'Already Reported' IM_USED = 226, 'IM Used' # redirection MULTIPLE_CHOICES = (300, 'Multiple Choices', 'Object has several resources -- see URI list') MOVED_PERMANENTLY = (301, 'Moved Permanently', 'Object moved permanently -- see URI list') FOUND = 302, 'Found', 'Object moved temporarily -- see URI list' SEE_OTHER = 303, 'See Other', 'Object moved -- see Method and URL list' NOT_MODIFIED = (304, 'Not Modified', 'Document has not changed since given time') USE_PROXY = (305, 'Use Proxy', 'You must use proxy specified in Location to access this resource') TEMPORARY_REDIRECT = (307, 'Temporary Redirect', 'Object moved temporarily -- see URI list') PERMANENT_REDIRECT = (308, 'Permanent Redirect', 'Object moved temporarily -- see URI list') # client error BAD_REQUEST = (400, 'Bad Request', 'Bad request syntax or unsupported method') UNAUTHORIZED = (401, 'Unauthorized', 'No permission -- see authorization schemes') PAYMENT_REQUIRED = (402, 'Payment Required', 'No payment -- see charging schemes') FORBIDDEN = (403, 'Forbidden', 'Request forbidden -- authorization will not help') NOT_FOUND = (404, 'Not Found', 'Nothing matches the given URI') METHOD_NOT_ALLOWED = (405, 'Method Not Allowed', 'Specified method is invalid for this resource') NOT_ACCEPTABLE = (406, 'Not Acceptable', 'URI not available in preferred format') PROXY_AUTHENTICATION_REQUIRED = (407, 'Proxy Authentication Required', 'You must authenticate with this proxy before proceeding') REQUEST_TIMEOUT = (408, 'Request Timeout', 'Request timed out; try again later') CONFLICT = 409, 'Conflict', 'Request conflict' GONE = (410, 'Gone', 'URI no longer exists and has been permanently removed') LENGTH_REQUIRED = (411, 'Length Required', 'Client must specify Content-Length') PRECONDITION_FAILED = (412, 'Precondition Failed', 'Precondition in headers is false') REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large', 'Entity is too large') REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long', 'URI is too long') UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type', 'Entity body in unsupported format') REQUESTED_RANGE_NOT_SATISFIABLE = (416, 'Requested Range Not Satisfiable', 'Cannot satisfy request range') EXPECTATION_FAILED = (417, 'Expectation Failed', 'Expect condition could not be satisfied') UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity' LOCKED = 423, 'Locked' FAILED_DEPENDENCY = 424, 'Failed Dependency' UPGRADE_REQUIRED = 426, 'Upgrade Required' PRECONDITION_REQUIRED = (428, 'Precondition Required', 'The origin server requires the request to be conditional') TOO_MANY_REQUESTS = (429, 'Too Many Requests', 'The user has sent too many requests in ' 'a given amount of time ("rate limiting")') REQUEST_HEADER_FIELDS_TOO_LARGE = (431, 'Request Header Fields Too Large', 'The server is unwilling to process the request because its header ' 'fields are too large') # server errors INTERNAL_SERVER_ERROR = (500, 'Internal Server Error', 'Server got itself in trouble') NOT_IMPLEMENTED = (501, 'Not Implemented', 'Server does not support this operation') BAD_GATEWAY = (502, 'Bad Gateway', 'Invalid responses from another server/proxy') SERVICE_UNAVAILABLE = (503, 'Service Unavailable', 'The server cannot process the request due to a high load') GATEWAY_TIMEOUT = (504, 'Gateway Timeout', 'The gateway server did not receive a timely response') HTTP_VERSION_NOT_SUPPORTED = (505, 'HTTP Version Not Supported', 'Cannot fulfill request') VARIANT_ALSO_NEGOTIATES = 506, 'Variant Also Negotiates' INSUFFICIENT_STORAGE = 507, 'Insufficient Storage' LOOP_DETECTED = 508, 'Loop Detected' NOT_EXTENDED = 510, 'Not Extended' NETWORK_AUTHENTICATION_REQUIRED = (511, 'Network Authentication Required', 'The client needs to authenticate to gain network access') lib64/python3.6/encodings/__init__.py000064400000013012152346404200013313 0ustar00""" Standard "encodings" Package Standard Python encoding modules are stored in this package directory. Codec modules must have names corresponding to normalized encoding names as defined in the normalize_encoding() function below, e.g. 'utf-8' must be implemented by the module 'utf_8.py'. Each codec module must export the following interface: * getregentry() -> codecs.CodecInfo object The getregentry() API must return a CodecInfo object with encoder, decoder, incrementalencoder, incrementaldecoder, streamwriter and streamreader atttributes which adhere to the Python Codec Interface Standard. In addition, a module may optionally also define the following APIs which are then used by the package's codec search function: * getaliases() -> sequence of encoding name strings to use as aliases Alias names returned by getaliases() must be normalized encoding names as defined by normalize_encoding(). Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" import codecs import sys from . import aliases _cache = {} _unknown = '--unknown--' _import_tail = ['*'] _aliases = aliases.aliases class CodecRegistryError(LookupError, SystemError): pass def normalize_encoding(encoding): """ Normalize an encoding name. Normalization works as follows: all non-alphanumeric characters except the dot used for Python package names are collapsed and replaced with a single underscore, e.g. ' -;#' becomes '_'. Leading and trailing underscores are removed. Note that encoding names should be ASCII only; if they do use non-ASCII characters, these must be Latin-1 compatible. """ if isinstance(encoding, bytes): encoding = str(encoding, "ascii") chars = [] punct = False for c in encoding: if c.isalnum() or c == '.': if punct and chars: chars.append('_') chars.append(c) punct = False else: punct = True return ''.join(chars) def search_function(encoding): # Cache lookup entry = _cache.get(encoding, _unknown) if entry is not _unknown: return entry # Import the module: # # First try to find an alias for the normalized encoding # name and lookup the module using the aliased name, then try to # lookup the module using the standard import scheme, i.e. first # try in the encodings package, then at top-level. # norm_encoding = normalize_encoding(encoding) aliased_encoding = _aliases.get(norm_encoding) or \ _aliases.get(norm_encoding.replace('.', '_')) if aliased_encoding is not None: modnames = [aliased_encoding, norm_encoding] else: modnames = [norm_encoding] for modname in modnames: if not modname or '.' in modname: continue try: # Import is absolute to prevent the possibly malicious import of a # module with side-effects that is not in the 'encodings' package. mod = __import__('encodings.' + modname, fromlist=_import_tail, level=0) except ImportError: # ImportError may occur because 'encodings.(modname)' does not exist, # or because it imports a name that does not exist (see mbcs and oem) pass else: break else: mod = None try: getregentry = mod.getregentry except AttributeError: # Not a codec module mod = None if mod is None: # Cache misses _cache[encoding] = None return None # Now ask the module for the registry entry entry = getregentry() if not isinstance(entry, codecs.CodecInfo): if not 4 <= len(entry) <= 7: raise CodecRegistryError('module "%s" (%s) failed to register' % (mod.__name__, mod.__file__)) if not callable(entry[0]) or not callable(entry[1]) or \ (entry[2] is not None and not callable(entry[2])) or \ (entry[3] is not None and not callable(entry[3])) or \ (len(entry) > 4 and entry[4] is not None and not callable(entry[4])) or \ (len(entry) > 5 and entry[5] is not None and not callable(entry[5])): raise CodecRegistryError('incompatible codecs in module "%s" (%s)' % (mod.__name__, mod.__file__)) if len(entry)<7 or entry[6] is None: entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],) entry = codecs.CodecInfo(*entry) # Cache the codec registry entry _cache[encoding] = entry # Register its aliases (without overwriting previously registered # aliases) try: codecaliases = mod.getaliases() except AttributeError: pass else: for alias in codecaliases: if alias not in _aliases: _aliases[alias] = modname # Return the registry entry return entry # Register the search_function in the Python codec registry codecs.register(search_function) if sys.platform == 'win32': def _alias_mbcs(encoding): try: import _bootlocale if encoding == _bootlocale.getpreferredencoding(False): import encodings.mbcs return encodings.mbcs.getregentry() except ImportError: # Imports may fail while we are shutting down pass codecs.register(_alias_mbcs) usr/lib/python3.6/site-packages/rhn/__init__.py000064400000000204152346407520015317 0ustar00# # __init__.py # # Copyright (c) 2011--2013 Red Hat, Inc. # """ rhn - A collection of modules used by Red Hat Network Classic """ lib64/python3.6/site-packages/libdnf/__init__.py000064400000000727152346415000015331 0ustar00from __future__ import absolute_import # error needs to be imported first and with global visibility for its symbols, # as it defines a python exception, which is a global variable and the other # modules use the symbol. import sys, os sys.setdlopenflags(os.RTLD_NOW | os.RTLD_GLOBAL) from . import error sys.setdlopenflags(os.RTLD_NOW) from . import common_types from . import conf from . import module from . import repo from . import transaction from . import utils usr/lib64/python3.12/unittest/__init__.py000064400000006637152346415050014133 0ustar00""" Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's Smalltalk testing framework (used with permission). This module contains the core framework classes that form the basis of specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results (TextTestRunner). Simple usage: import unittest class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): # test method names begin with 'test' self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main() Further information is available in the bundled documentation, and from http://docs.python.org/library/unittest.html Copyright (c) 1999-2003 Steve Purcell Copyright (c) 2003-2010 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __all__ = ['TestResult', 'TestCase', 'IsolatedAsyncioTestCase', 'TestSuite', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', 'registerResult', 'removeResult', 'removeHandler', 'addModuleCleanup', 'doModuleCleanups', 'enterModuleContext'] # Expose obsolete functions for backwards compatibility # bpo-5846: Deprecated in Python 3.11, scheduled for removal in Python 3.13. __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) __unittest = True from .result import TestResult from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip, skipIf, skipUnless, expectedFailure, doModuleCleanups, enterModuleContext) from .suite import BaseTestSuite, TestSuite from .loader import TestLoader, defaultTestLoader from .main import TestProgram, main from .runner import TextTestRunner, TextTestResult from .signals import installHandler, registerResult, removeResult, removeHandler # IsolatedAsyncioTestCase will be imported lazily. from .loader import makeSuite, getTestCaseNames, findTestCases # Lazy import of IsolatedAsyncioTestCase from .async_case # It imports asyncio, which is relatively heavy, but most tests # do not need it. def __dir__(): return globals().keys() | {'IsolatedAsyncioTestCase'} def __getattr__(name): if name == 'IsolatedAsyncioTestCase': global IsolatedAsyncioTestCase from .async_case import IsolatedAsyncioTestCase return IsolatedAsyncioTestCase raise AttributeError(f"module {__name__!r} has no attribute {name!r}") lib64/python2.7/idlelib/idle_test/__init__.py000064400000001212152346433260014731 0ustar00'''idlelib.idle_test is a private implementation of test.test_idle, which tests the IDLE application as part of the stdlib test suite. Run IDLE tests alone with "python -m test.test_idle". This package and its contained modules are subject to change and any direct use is at your own risk. ''' from os.path import dirname def load_tests(loader, standard_tests, pattern): this_dir = dirname(__file__) top_dir = dirname(dirname(this_dir)) package_tests = loader.discover(start_dir=this_dir, pattern='test*.py', top_level_dir=top_dir) standard_tests.addTests(package_tests) return standard_tests usr/lib/python3.6/site-packages/pycparser/__init__.py000064400000005527152346435710016557 0ustar00#----------------------------------------------------------------- # pycparser: __init__.py # # This package file exports some convenience functions for # interacting with pycparser # # Copyright (C) 2008-2015, Eli Bendersky # License: BSD #----------------------------------------------------------------- __all__ = ['c_lexer', 'c_parser', 'c_ast'] __version__ = '2.14' from subprocess import Popen, PIPE from .c_parser import CParser def preprocess_file(filename, cpp_path='cpp', cpp_args=''): """ Preprocess a file using cpp. filename: Name of the file you want to preprocess. cpp_path: cpp_args: Refer to the documentation of parse_file for the meaning of these arguments. When successful, returns the preprocessed file's contents. Errors from cpp will be printed out. """ path_list = [cpp_path] if isinstance(cpp_args, list): path_list += cpp_args elif cpp_args != '': path_list += [cpp_args] path_list += [filename] try: # Note the use of universal_newlines to treat all newlines # as \n for Python's purpose # pipe = Popen( path_list, stdout=PIPE, universal_newlines=True) text = pipe.communicate()[0] except OSError as e: raise RuntimeError("Unable to invoke 'cpp'. " + 'Make sure its path was passed correctly\n' + ('Original error: %s' % e)) return text def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='', parser=None): """ Parse a C file using pycparser. filename: Name of the file you want to parse. use_cpp: Set to True if you want to execute the C pre-processor on the file prior to parsing it. cpp_path: If use_cpp is True, this is the path to 'cpp' on your system. If no path is provided, it attempts to just execute 'cpp', so it must be in your PATH. cpp_args: If use_cpp is True, set this to the command line arguments strings to cpp. Be careful with quotes - it's best to pass a raw string (r'') here. For example: r'-I../utils/fake_libc_include' If several arguments are required, pass a list of strings. parser: Optional parser object to be used instead of the default CParser When successful, an AST is returned. ParseError can be thrown if the file doesn't parse successfully. Errors from cpp will be printed out. """ if use_cpp: text = preprocess_file(filename, cpp_path, cpp_args) else: with open(filename, 'rU') as f: text = f.read() if parser is None: parser = CParser() return parser.parse(text, filename) lib64/python2.7/distutils/command/__init__.py000064400000001466152346503130015020 0ustar00"""distutils.command Package containing implementation of all the standard Distutils commands.""" __revision__ = "$Id$" __all__ = ['build', 'build_py', 'build_ext', 'build_clib', 'build_scripts', 'clean', 'install', 'install_lib', 'install_headers', 'install_scripts', 'install_data', 'sdist', 'register', 'bdist', 'bdist_dumb', 'bdist_rpm', 'bdist_wininst', 'upload', 'check', # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', # Note: # bdist_packager is not included because it only provides # an abstract base class ] usr/lib64/python3.6/wsgiref/__init__.py000064400000001113152346510630013625 0ustar00"""wsgiref -- a WSGI (PEP 3333) Reference Library Current Contents: * util -- Miscellaneous useful functions and wrappers * headers -- Manage response headers * handlers -- base classes for server/gateway implementations * simple_server -- a simple BaseHTTPServer that supports WSGI * validate -- validation wrapper that sits between an app and a server to detect errors in either To-Do: * cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard) * cgi_wrapper -- Run CGI apps under WSGI * router -- a simple middleware component that handles URL traversal """ lib64/python3.6/site-packages/gpg/__init__.py000064400000011623152346511240014650 0ustar00# Copyright (C) 2016 g10 Code GmbH # Copyright (C) 2004 Igor Belyi # Copyright (C) 2002 John Goerzen # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """gpg: GnuPG Interface for Python (GPGME bindings) Welcome to gpg, the GnuPG Interface for Python. The latest release of this package may be obtained from https://www.gnupg.org FEATURES -------- * Feature-rich, full implementation of the GPGME library. Supports all GPGME features. Callback functions may be written in pure Python. Exceptions raised in callbacks are properly propagated. * Ability to sign, encrypt, decrypt, and verify data. * Ability to list keys, export and import keys, and manage the keyring. * Fully object-oriented with convenient classes and modules. QUICK EXAMPLE ------------- >>> import gpg >>> with gpg.Context() as c: >>> with gpg.Context() as c: ... cipher, _, _ = c.encrypt("Hello world :)".encode(), ... passphrase="abc") ... c.decrypt(cipher, passphrase="abc") ... (b'Hello world :)', , ) GENERAL OVERVIEW ---------------- For those of you familiar with GPGME, you will be right at home here. The python gpg module is, for the most part, a direct interface to the C GPGME library. However, it is re-packaged in a more Pythonic way -- object-oriented with classes and modules. Take a look at the classes defined here -- they correspond directly to certain object types in GPGME for C. For instance, the following C code: gpgme_ctx_t context; gpgme_new(&context); ... gpgme_op_encrypt(context, recp, 1, plain, cipher); Translates into the following Python code: context = core.Context() ... context.op_encrypt(recp, 1, plain, cipher) The Python module automatically does error-checking and raises Python exception gpg.errors.GPGMEError when GPGME signals an error. getcode() and getsource() of this exception return code and source of the error. IMPORTANT NOTE -------------- This documentation only covers a small subset of available GPGME functions and methods. Please consult the documentation for the C library for comprehensive coverage. This library uses Python's reflection to automatically detect the methods that are available for each class, and as such, most of those methods do not appear explicitly anywhere. You can use dir() python built-in command on an object to see what methods and fields it has but their meaning can often only be found in the GPGME documentation. HIGHER LEVEL PYTHONIC LAYER --------------------------- A more pythonic or intuitive layer is being added above the automatically generated lower level bindings. This is the recommended way to access the module as if it is ever necessary to modify the underlying GPGME API, the higher level methods will remain the same. The quick example above is an example of this higher layer in action, whereas the second example demonstrating the mapping to GPGME itself is the lower layer. The second example in the higher layer would be more like the encrypt line in the quick example. FOR MORE INFORMATION -------------------- GnuPG homepage: https://www.gnupg.org/ GPGME documentation: https://www.gnupg.org/documentation/manuals/gpgme/ GPGME Python HOWTO: http://files.au.adversary.org/crypto/gpgme-python-howto-split/index.html To view this documentation, run help(gpg) in Python or one of the following commands outside of Python: pydoc gpg pydoc3 gpg python -m pydoc gpg python3 -m pydoc gpg """ from __future__ import absolute_import, print_function, unicode_literals from . import core from . import errors from . import constants from . import util from . import callbacks from . import version from .core import Context from .core import Data del absolute_import, print_function, unicode_literals # Interface hygiene. # Drop the low-level gpgme that creeps in for some reason. gpgme = None del gpgme # This is a white-list of symbols. Any other will alert pyflakes. _ = [Context, Data, core, errors, constants, util, callbacks, version] del _ __all__ = [ "Context", "Data", "core", "errors", "constants", "util", "callbacks", "version" ] usr/lib64/python2.7/ctypes/macholib/__init__.py000064400000000232152346514640015252 0ustar00""" Enough Mach-O to make your head spin. See the relevant header files in /usr/include/mach-o And also Apple's documentation. """ __version__ = '1.0' usr/lib/python3.6/site-packages/sepolicy/help/__init__.py000064400000000000152346516500017300 0ustar00lib64/python2.7/hotshot/__init__.py000064400000005156152346520560013054 0ustar00"""High-perfomance logging profiler, mostly written in C.""" import _hotshot from _hotshot import ProfilerError from warnings import warnpy3k as _warnpy3k _warnpy3k("The 'hotshot' module is not supported in 3.x, " "use the 'profile' module instead.", stacklevel=2) class Profile: def __init__(self, logfn, lineevents=0, linetimings=1): self.lineevents = lineevents and 1 or 0 self.linetimings = (linetimings and lineevents) and 1 or 0 self._prof = p = _hotshot.profiler( logfn, self.lineevents, self.linetimings) # Attempt to avoid confusing results caused by the presence of # Python wrappers around these functions, but only if we can # be sure the methods have not been overridden or extended. if self.__class__ is Profile: self.close = p.close self.start = p.start self.stop = p.stop self.addinfo = p.addinfo def close(self): """Close the logfile and terminate the profiler.""" self._prof.close() def fileno(self): """Return the file descriptor of the profiler's log file.""" return self._prof.fileno() def start(self): """Start the profiler.""" self._prof.start() def stop(self): """Stop the profiler.""" self._prof.stop() def addinfo(self, key, value): """Add an arbitrary labelled value to the profile log.""" self._prof.addinfo(key, value) # These methods offer the same interface as the profile.Profile class, # but delegate most of the work to the C implementation underneath. def run(self, cmd): """Profile an exec-compatible string in the script environment. The globals from the __main__ module are used as both the globals and locals for the script. """ import __main__ dict = __main__.__dict__ return self.runctx(cmd, dict, dict) def runctx(self, cmd, globals, locals): """Evaluate an exec-compatible string in a specific environment. The string is compiled before profiling begins. """ code = compile(cmd, "", "exec") self._prof.runcode(code, globals, locals) return self def runcall(self, func, *args, **kw): """Profile a single call of a callable. Additional positional and keyword arguments may be passed along; the result of the call is returned, and exceptions are allowed to propagate cleanly, while ensuring that profiling is disabled on the way out. """ return self._prof.runcall(func, args, kw) lib64/python3.8/distutils/command/__init__.py000064400000001437152346535530015031 0ustar00"""distutils.command Package containing implementation of all the standard Distutils commands.""" __all__ = ['build', 'build_py', 'build_ext', 'build_clib', 'build_scripts', 'clean', 'install', 'install_lib', 'install_headers', 'install_scripts', 'install_data', 'sdist', 'register', 'bdist', 'bdist_dumb', 'bdist_rpm', 'bdist_wininst', 'check', 'upload', # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', # Note: # bdist_packager is not included because it only provides # an abstract base class ] usr/lib64/python3.8/html/__init__.py000064400000011224152346550650013137 0ustar00""" General functions for HTML manipulation. """ import re as _re from html.entities import html5 as _html5 __all__ = ['escape', 'unescape'] def escape(s, quote=True): """ Replace special characters "&", "<" and ">" to HTML-safe sequences. If the optional flag quote is true (the default), the quotation mark characters, both double quote (") and single quote (') characters are also translated. """ s = s.replace("&", "&") # Must be done first! s = s.replace("<", "<") s = s.replace(">", ">") if quote: s = s.replace('"', """) s = s.replace('\'', "'") return s # see http://www.w3.org/TR/html5/syntax.html#tokenizing-character-references _invalid_charrefs = { 0x00: '\ufffd', # REPLACEMENT CHARACTER 0x0d: '\r', # CARRIAGE RETURN 0x80: '\u20ac', # EURO SIGN 0x81: '\x81', # 0x82: '\u201a', # SINGLE LOW-9 QUOTATION MARK 0x83: '\u0192', # LATIN SMALL LETTER F WITH HOOK 0x84: '\u201e', # DOUBLE LOW-9 QUOTATION MARK 0x85: '\u2026', # HORIZONTAL ELLIPSIS 0x86: '\u2020', # DAGGER 0x87: '\u2021', # DOUBLE DAGGER 0x88: '\u02c6', # MODIFIER LETTER CIRCUMFLEX ACCENT 0x89: '\u2030', # PER MILLE SIGN 0x8a: '\u0160', # LATIN CAPITAL LETTER S WITH CARON 0x8b: '\u2039', # SINGLE LEFT-POINTING ANGLE QUOTATION MARK 0x8c: '\u0152', # LATIN CAPITAL LIGATURE OE 0x8d: '\x8d', # 0x8e: '\u017d', # LATIN CAPITAL LETTER Z WITH CARON 0x8f: '\x8f', # 0x90: '\x90', # 0x91: '\u2018', # LEFT SINGLE QUOTATION MARK 0x92: '\u2019', # RIGHT SINGLE QUOTATION MARK 0x93: '\u201c', # LEFT DOUBLE QUOTATION MARK 0x94: '\u201d', # RIGHT DOUBLE QUOTATION MARK 0x95: '\u2022', # BULLET 0x96: '\u2013', # EN DASH 0x97: '\u2014', # EM DASH 0x98: '\u02dc', # SMALL TILDE 0x99: '\u2122', # TRADE MARK SIGN 0x9a: '\u0161', # LATIN SMALL LETTER S WITH CARON 0x9b: '\u203a', # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 0x9c: '\u0153', # LATIN SMALL LIGATURE OE 0x9d: '\x9d', # 0x9e: '\u017e', # LATIN SMALL LETTER Z WITH CARON 0x9f: '\u0178', # LATIN CAPITAL LETTER Y WITH DIAERESIS } _invalid_codepoints = { # 0x0001 to 0x0008 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, # 0x000E to 0x001F 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, # 0x007F to 0x009F 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, # 0xFDD0 to 0xFDEF 0xfdd0, 0xfdd1, 0xfdd2, 0xfdd3, 0xfdd4, 0xfdd5, 0xfdd6, 0xfdd7, 0xfdd8, 0xfdd9, 0xfdda, 0xfddb, 0xfddc, 0xfddd, 0xfdde, 0xfddf, 0xfde0, 0xfde1, 0xfde2, 0xfde3, 0xfde4, 0xfde5, 0xfde6, 0xfde7, 0xfde8, 0xfde9, 0xfdea, 0xfdeb, 0xfdec, 0xfded, 0xfdee, 0xfdef, # others 0xb, 0xfffe, 0xffff, 0x1fffe, 0x1ffff, 0x2fffe, 0x2ffff, 0x3fffe, 0x3ffff, 0x4fffe, 0x4ffff, 0x5fffe, 0x5ffff, 0x6fffe, 0x6ffff, 0x7fffe, 0x7ffff, 0x8fffe, 0x8ffff, 0x9fffe, 0x9ffff, 0xafffe, 0xaffff, 0xbfffe, 0xbffff, 0xcfffe, 0xcffff, 0xdfffe, 0xdffff, 0xefffe, 0xeffff, 0xffffe, 0xfffff, 0x10fffe, 0x10ffff } def _replace_charref(s): s = s.group(1) if s[0] == '#': # numeric charref if s[1] in 'xX': num = int(s[2:].rstrip(';'), 16) else: num = int(s[1:].rstrip(';')) if num in _invalid_charrefs: return _invalid_charrefs[num] if 0xD800 <= num <= 0xDFFF or num > 0x10FFFF: return '\uFFFD' if num in _invalid_codepoints: return '' return chr(num) else: # named charref if s in _html5: return _html5[s] # find the longest matching name (as defined by the standard) for x in range(len(s)-1, 1, -1): if s[:x] in _html5: return _html5[s[:x]] + s[x:] else: return '&' + s _charref = _re.compile(r'&(#[0-9]+;?' r'|#[xX][0-9a-fA-F]+;?' r'|[^\t\n\f <&#;]{1,32};?)') def unescape(s): """ Convert all named and numeric character references (e.g. >, >, &x3e;) in the string s to the corresponding unicode characters. This function uses the rules defined by the HTML 5 standard for both valid and invalid character references, and the list of HTML 5 named character references defined in html.entities.html5. """ if '&' not in s: return s return _charref.sub(_replace_charref, s) usr/lib64/python2.7/pydoc_data/__init__.py000064400000000000152346557720014273 0ustar00usr/lib64/python2.7/logging/__init__.py000064400000170342152346563060013625 0ustar00# Copyright 2001-2014 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation, and that the name of Vinay Sajip # not be used in advertising or publicity pertaining to distribution # of the software without specific, written prior permission. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import sys, os, time, cStringIO, traceback, warnings, weakref, collections __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning'] try: import codecs except ImportError: codecs = None try: import thread import threading except ImportError: thread = None __author__ = "Vinay Sajip " __status__ = "production" # Note: the attributes below are no longer maintained. __version__ = "0.5.1.2" __date__ = "07 February 2010" #--------------------------------------------------------------------------- # Miscellaneous module data #--------------------------------------------------------------------------- try: unicode _unicode = True except NameError: _unicode = False # next bit filched from 1.5.2's inspect.py def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise Exception except: return sys.exc_info()[2].tb_frame.f_back if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) # done filching # # _srcfile is used when walking the stack to check when we've got the first # caller stack frame. # _srcfile = os.path.normcase(currentframe.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). # To provide compatibility with older versions of Python, set _srcfile # to None if _getframe() is not available; this value will prevent # findCaller() from being called. #if not hasattr(sys, "_getframe"): # _srcfile = None # #_startTime is used as the base when calculating the relative time of events # _startTime = time.time() # #raiseExceptions is used to see if exceptions during handling should be #propagated # raiseExceptions = 1 # # If you don't want threading information in the log, set this to zero # logThreads = 1 # # If you don't want multiprocessing information in the log, set this to zero # logMultiprocessing = 1 # # If you don't want process information in the log, set this to zero # logProcesses = 1 #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- # # Default levels and level names, these can be replaced with any positive set # of values having corresponding names. There is a pseudo-level, NOTSET, which # is only really there as a lower limit for user-defined levels. Handlers and # loggers are initialized with NOTSET so that they will log all messages, even # at user-defined levels. # CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 _levelNames = { CRITICAL : 'CRITICAL', ERROR : 'ERROR', WARNING : 'WARNING', INFO : 'INFO', DEBUG : 'DEBUG', NOTSET : 'NOTSET', 'CRITICAL' : CRITICAL, 'ERROR' : ERROR, 'WARN' : WARNING, 'WARNING' : WARNING, 'INFO' : INFO, 'DEBUG' : DEBUG, 'NOTSET' : NOTSET, } def getLevelName(level): """ Return the textual representation of logging level 'level'. If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, INFO, DEBUG) then you get the corresponding string. If you have associated levels with names using addLevelName then the name you have associated with 'level' is returned. If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned. Otherwise, the string "Level %s" % level is returned. """ return _levelNames.get(level, ("Level %s" % level)) def addLevelName(level, levelName): """ Associate 'levelName' with 'level'. This is used when converting levels to text during message formatting. """ _acquireLock() try: #unlikely to cause an exception, but you never know... _levelNames[level] = levelName _levelNames[levelName] = level finally: _releaseLock() def _checkLevel(level): if isinstance(level, (int, long)): rv = level elif str(level) == level: if level not in _levelNames: raise ValueError("Unknown level: %r" % level) rv = _levelNames[level] else: raise TypeError("Level not an integer or a valid string: %r" % level) return rv #--------------------------------------------------------------------------- # Thread-related stuff #--------------------------------------------------------------------------- # #_lock is used to serialize access to shared data structures in this module. #This needs to be an RLock because fileConfig() creates and configures #Handlers, and so might arbitrary user threads. Since Handler code updates the #shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # if thread: _lock = threading.RLock() else: _lock = None def _acquireLock(): """ Acquire the module-level lock for serializing access to shared data. This should be released with _releaseLock(). """ if _lock: _lock.acquire() def _releaseLock(): """ Release the module-level lock acquired by calling _acquireLock(). """ if _lock: _lock.release() #--------------------------------------------------------------------------- # The logging record #--------------------------------------------------------------------------- class LogRecord(object): """ A LogRecord instance represents an event being logged. LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is in msg and args, which are combined using str(msg) % args to create the message field of the record. The record also includes information such as when the record was created, the source line where the logging call was made, and any exception information to be logged. """ def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None): """ Initialize a logging record with interesting information. """ ct = time.time() self.name = name self.msg = msg # # The following statement allows passing of a dictionary as a sole # argument, so that you can do something like # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) # Suggested by Stefan Behnel. # Note that without the test for args[0], we get a problem because # during formatting, we test to see if the arg is present using # 'if self.args:'. If the event being logged is e.g. 'Value is %d' # and if the passed arg fails 'if self.args:' then no formatting # is done. For example, logger.warn('Value is %d', 0) would log # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. # Issue #21172: a request was made to relax the isinstance check # to hasattr(args[0], '__getitem__'). However, the docs on string # formatting still seem to suggest a mapping object is required. # Thus, while not removing the isinstance check, it does now look # for collections.Mapping rather than, as before, dict. if (args and len(args) == 1 and isinstance(args[0], collections.Mapping) and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) self.levelno = level self.pathname = pathname try: self.filename = os.path.basename(pathname) self.module = os.path.splitext(self.filename)[0] except (TypeError, ValueError, AttributeError): self.filename = pathname self.module = "Unknown module" self.exc_info = exc_info self.exc_text = None # used to cache the traceback text self.lineno = lineno self.funcName = func self.created = ct self.msecs = (ct - long(ct)) * 1000 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads and thread: self.thread = thread.get_ident() self.threadName = threading.current_thread().name else: self.thread = None self.threadName = None if not logMultiprocessing: self.processName = None else: self.processName = 'MainProcess' mp = sys.modules.get('multiprocessing') if mp is not None: # Errors may occur if multiprocessing has not finished loading # yet - e.g. if a custom import hook causes third-party code # to run when multiprocessing calls import. See issue 8200 # for an example try: self.processName = mp.current_process().name except StandardError: pass if logProcesses and hasattr(os, 'getpid'): self.process = os.getpid() else: self.process = None def __str__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) def getMessage(self): """ Return the message for this LogRecord. Return the message for this LogRecord after merging any user-supplied arguments with the message. """ if not _unicode: #if no unicode support... msg = str(self.msg) else: msg = self.msg if not isinstance(msg, basestring): try: msg = str(self.msg) except UnicodeError: msg = self.msg #Defer encoding till later if self.args: msg = msg % self.args return msg def makeLogRecord(dict): """ Make a LogRecord whose attributes are defined by the specified dictionary, This function is useful for converting a logging event received over a socket connection (which is sent as a dictionary) into a LogRecord instance. """ rv = LogRecord(None, None, "", 0, "", (), None, None) rv.__dict__.update(dict) return rv #--------------------------------------------------------------------------- # Formatter classes and functions #--------------------------------------------------------------------------- class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. Formatters need to know how a LogRecord is constructed. They are responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the default value of "%s(message)\\n" is used. The Formatter can be initialized with a format string which makes use of knowledge of the LogRecord attributes - e.g. the default value mentioned above makes use of the fact that the user's message and arguments are pre- formatted into a LogRecord's message attribute. Currently, the useful attributes in a LogRecord are described by: %(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted """ converter = time.localtime def __init__(self, fmt=None, datefmt=None): """ Initialize the formatter with specified format strings. Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument (if omitted, you get the ISO8601 format). """ if fmt: self._fmt = fmt else: self._fmt = "%(message)s" self.datefmt = datefmt def formatTime(self, record, datefmt=None): """ Return the creation time of the specified LogRecord as formatted text. This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, the ISO8601 format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) if datefmt: s = time.strftime(datefmt, ct) else: t = time.strftime("%Y-%m-%d %H:%M:%S", ct) s = "%s,%03d" % (t, record.msecs) return s def formatException(self, ei): """ Format and return the specified exception information as a string. This default implementation just uses traceback.print_exception() """ sio = cStringIO.StringIO() traceback.print_exception(ei[0], ei[1], ei[2], None, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] return s def usesTime(self): """ Check if the format uses the creation time of the record. """ return self._fmt.find("%(asctime)") >= 0 def format(self, record): """ Format the specified record as text. The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message. """ record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) try: s = self._fmt % record.__dict__ except UnicodeDecodeError as e: # Issue 25664. The logger name may be Unicode. Try again ... try: record.name = record.name.decode('utf-8') s = self._fmt % record.__dict__ except UnicodeDecodeError: raise e if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" try: s = s + record.exc_text except UnicodeError: # Sometimes filenames have non-ASCII chars, which can lead # to errors when s is Unicode and record.exc_text is str # See issue 8924. # We also use replace for when there are multiple # encodings, e.g. UTF-8 for the filesystem and latin-1 # for a script. See issue 13232. s = s + record.exc_text.decode(sys.getfilesystemencoding(), 'replace') return s # # The default formatter to use when no other is specified # _defaultFormatter = Formatter() class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ def __init__(self, linefmt=None): """ Optionally specify a formatter which will be used to format each individual record. """ if linefmt: self.linefmt = linefmt else: self.linefmt = _defaultFormatter def formatHeader(self, records): """ Return the header string for the specified records. """ return "" def formatFooter(self, records): """ Return the footer string for the specified records. """ return "" def format(self, records): """ Format the specified records and return the result as a string. """ rv = "" if len(records) > 0: rv = rv + self.formatHeader(records) for record in records: rv = rv + self.linefmt.format(record) rv = rv + self.formatFooter(records) return rv #--------------------------------------------------------------------------- # Filter classes and functions #--------------------------------------------------------------------------- class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed. """ def __init__(self, name=''): """ Initialize a filter. Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event. """ self.name = name self.nlen = len(name) def filter(self, record): """ Determine if the specified record is to be logged. Is the specified record to be logged? Returns 0 for no, nonzero for yes. If deemed appropriate, the record may be modified in-place. """ if self.nlen == 0: return 1 elif self.name == record.name: return 1 elif record.name.find(self.name, 0, self.nlen) != 0: return 0 return (record.name[self.nlen] == ".") class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. """ def __init__(self): """ Initialize the list of filters to be an empty list. """ self.filters = [] def addFilter(self, filter): """ Add the specified filter to this handler. """ if not (filter in self.filters): self.filters.append(filter) def removeFilter(self, filter): """ Remove the specified filter from this handler. """ if filter in self.filters: self.filters.remove(filter) def filter(self, record): """ Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto this and the record is then dropped. Returns a zero value if a record is to be dropped, else non-zero. """ rv = 1 for f in self.filters: if not f.filter(record): rv = 0 break return rv #--------------------------------------------------------------------------- # Handler classes and functions #--------------------------------------------------------------------------- _handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized def _removeHandlerRef(wr): """ Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are # set to None. It can also be called from another thread. So we need to # pre-emptively grab the necessary globals and check if they're None, # to prevent race conditions and failures during interpreter shutdown. acquire, release, handlers = _acquireLock, _releaseLock, _handlerList if acquire and release and handlers: try: acquire() try: if wr in handlers: handlers.remove(wr) finally: release() except TypeError: # https://bugs.python.org/issue21149 - If the RLock object behind # acquire() and release() has been partially finalized you may see # an error about NoneType not being callable. Absolutely nothing # we can do in this GC during process shutdown situation. Eat it. pass def _addHandlerRef(handler): """ Add a handler to the internal cleanup list using a weak reference. """ _acquireLock() try: _handlerList.append(weakref.ref(handler, _removeHandlerRef)) finally: _releaseLock() class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. The base handler class. Acts as a placeholder which defines the Handler interface. Handlers can optionally use Formatter instances to format records as desired. By default, no formatter is specified; in this case, the 'raw' message as determined by record.message is logged. """ def __init__(self, level=NOTSET): """ Initializes the instance - basically setting the formatter to None and the filter list to empty. """ Filterer.__init__(self) self._name = None self.level = _checkLevel(level) self.formatter = None # Add the handler to the global _handlerList (for cleanup on shutdown) _addHandlerRef(self) self.createLock() def get_name(self): return self._name def set_name(self, name): _acquireLock() try: if self._name in _handlers: del _handlers[self._name] self._name = name if name: _handlers[name] = self finally: _releaseLock() name = property(get_name, set_name) def createLock(self): """ Acquire a thread lock for serializing access to the underlying I/O. """ if thread: self.lock = threading.RLock() else: self.lock = None def acquire(self): """ Acquire the I/O thread lock. """ if self.lock: self.lock.acquire() def release(self): """ Release the I/O thread lock. """ if self.lock: self.lock.release() def setLevel(self, level): """ Set the logging level of this handler. """ self.level = _checkLevel(level) def format(self, record): """ Format the specified record. If a formatter is set, use it. Otherwise, use the default formatter for the module. """ if self.formatter: fmt = self.formatter else: fmt = _defaultFormatter return fmt.format(record) def emit(self, record): """ Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so raises a NotImplementedError. """ raise NotImplementedError('emit must be implemented ' 'by Handler subclasses') def handle(self, record): """ Conditionally emit the specified logging record. Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns whether the filter passed the record for emission. """ rv = self.filter(record) if rv: self.acquire() try: self.emit(record) finally: self.release() return rv def setFormatter(self, fmt): """ Set the formatter for this handler. """ self.formatter = fmt def flush(self): """ Ensure all logging output has been flushed. This version does nothing and is intended to be implemented by subclasses. """ pass def close(self): """ Tidy up any resources used by the handler. This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... if self._name and self._name in _handlers: del _handlers[self._name] finally: _releaseLock() def handleError(self, record): """ Handle errors which occur during an emit() call. This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method. """ if raiseExceptions and sys.stderr: # see issue 13807 ei = sys.exc_info() try: traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr) sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) except IOError: pass # see issue 5971 finally: del ei class StreamHandler(Handler): """ A handler class which writes logging records, appropriately formatted, to a stream. Note that this class does not close the stream, as sys.stdout or sys.stderr may be used. """ def __init__(self, stream=None): """ Initialize the handler. If stream is not specified, sys.stderr is used. """ Handler.__init__(self) if stream is None: stream = sys.stderr self.stream = stream def flush(self): """ Flushes the stream. """ self.acquire() try: if self.stream and hasattr(self.stream, "flush"): self.stream.flush() finally: self.release() def emit(self, record): """ Emit a record. If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an 'encoding' attribute, it is used to determine how to do the output to the stream. """ try: msg = self.format(record) stream = self.stream fs = "%s\n" if not _unicode: #if no unicode support... stream.write(fs % msg) else: try: if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): ufs = u'%s\n' try: stream.write(ufs % msg) except UnicodeEncodeError: #Printing to terminals sometimes fails. For example, #with an encoding of 'cp1251', the above write will #work if written to a stream opened or wrapped by #the codecs module, but fail when writing to a #terminal even when the codepage is set to cp1251. #An extra encoding step seems to be needed. stream.write((ufs % msg).encode(stream.encoding)) else: stream.write(fs % msg) except UnicodeError: stream.write(fs % msg.encode("UTF-8")) self.flush() except (KeyboardInterrupt, SystemExit): raise except: self.handleError(record) class FileHandler(StreamHandler): """ A handler class which writes formatted logging records to disk files. """ def __init__(self, filename, mode='a', encoding=None, delay=0): """ Open the specified file and use it as the stream for logging. """ #keep the absolute path, otherwise derived classes which use this #may come a cropper when the current directory changes if codecs is None: encoding = None self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding self.delay = delay if delay: #We don't open the stream, but we still need to call the #Handler constructor to set level, formatter, lock etc. Handler.__init__(self) self.stream = None else: StreamHandler.__init__(self, self._open()) def close(self): """ Closes the stream. """ self.acquire() try: try: if self.stream: try: self.flush() finally: stream = self.stream self.stream = None if hasattr(stream, "close"): stream.close() finally: # Issue #19523: call unconditionally to # prevent a handler leak when delay is set StreamHandler.close(self) finally: self.release() def _open(self): """ Open the current base file with the (original) mode and encoding. Return the resulting stream. """ if self.encoding is None: stream = open(self.baseFilename, self.mode) else: stream = codecs.open(self.baseFilename, self.mode, self.encoding) return stream def emit(self, record): """ Emit a record. If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit. """ if self.stream is None: self.stream = self._open() StreamHandler.emit(self, record) #--------------------------------------------------------------------------- # Manager classes and functions #--------------------------------------------------------------------------- class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is intended for internal use only and not as part of the public API. """ def __init__(self, alogger): """ Initialize with the specified logger being a child of this placeholder. """ #self.loggers = [alogger] self.loggerMap = { alogger : None } def append(self, alogger): """ Add the specified logger as a child of this placeholder. """ #if alogger not in self.loggers: if alogger not in self.loggerMap: #self.loggers.append(alogger) self.loggerMap[alogger] = None # # Determine which class to use when instantiating loggers. # _loggerClass = None def setLoggerClass(klass): """ Set the class to be used when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__() """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) global _loggerClass _loggerClass = klass def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ return _loggerClass class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. """ def __init__(self, rootnode): """ Initialize the manager with the root node of the logger hierarchy. """ self.root = rootnode self.disable = 0 self.emittedNoHandlerWarning = 0 self.loggerDict = {} self.loggerClass = None def getLogger(self, name): """ Get a logger with the specified name (channel name), creating it if it doesn't yet exist. This name is a dot-separated hierarchical name, such as "a", "a.b", "a.b.c" or similar. If a PlaceHolder existed for the specified name [i.e. the logger didn't exist but a child of it did], replace it with the created logger and fix up the parent/child references which pointed to the placeholder to now point to the logger. """ rv = None if not isinstance(name, basestring): raise TypeError('A logger name must be string or Unicode') if isinstance(name, unicode): name = name.encode('utf-8') _acquireLock() try: if name in self.loggerDict: rv = self.loggerDict[name] if isinstance(rv, PlaceHolder): ph = rv rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupChildren(ph, rv) self._fixupParents(rv) else: rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupParents(rv) finally: _releaseLock() return rv def setLoggerClass(self, klass): """ Set the class to be used when instantiating a logger with this Manager. """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) self.loggerClass = klass def _fixupParents(self, alogger): """ Ensure that there are either loggers or placeholders all the way from the specified logger to the root of the logger hierarchy. """ name = alogger.name i = name.rfind(".") rv = None while (i > 0) and not rv: substr = name[:i] if substr not in self.loggerDict: self.loggerDict[substr] = PlaceHolder(alogger) else: obj = self.loggerDict[substr] if isinstance(obj, Logger): rv = obj else: assert isinstance(obj, PlaceHolder) obj.append(alogger) i = name.rfind(".", 0, i - 1) if not rv: rv = self.root alogger.parent = rv def _fixupChildren(self, ph, alogger): """ Ensure that children of the placeholder ph are connected to the specified logger. """ name = alogger.name namelen = len(name) for c in ph.loggerMap.keys(): #The if means ... if not c.parent.name.startswith(nm) if c.parent.name[:namelen] != name: alogger.parent = c.parent c.parent = alogger #--------------------------------------------------------------------------- # Logger classes and functions #--------------------------------------------------------------------------- class Logger(Filterer): """ Instances of the Logger class represent a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting. """ def __init__(self, name, level=NOTSET): """ Initialize the logger with a name and an optional level. """ Filterer.__init__(self) self.name = name self.level = _checkLevel(level) self.parent = None self.propagate = 1 self.handlers = [] self.disabled = 0 def setLevel(self, level): """ Set the logging level of this logger. """ self.level = _checkLevel(level) def debug(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'DEBUG'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.debug("Houston, we have a %s", "thorny problem", exc_info=1) """ if self.isEnabledFor(DEBUG): self._log(DEBUG, msg, args, **kwargs) def info(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'INFO'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.info("Houston, we have a %s", "interesting problem", exc_info=1) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) def warning(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'WARNING'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1) """ if self.isEnabledFor(WARNING): self._log(WARNING, msg, args, **kwargs) warn = warning def error(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'ERROR'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.error("Houston, we have a %s", "major problem", exc_info=1) """ if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) def exception(self, msg, *args, **kwargs): """ Convenience method for logging an ERROR with exception information. """ kwargs['exc_info'] = 1 self.error(msg, *args, **kwargs) def critical(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'CRITICAL'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.critical("Houston, we have a %s", "major disaster", exc_info=1) """ if self.isEnabledFor(CRITICAL): self._log(CRITICAL, msg, args, **kwargs) fatal = critical def log(self, level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.log(level, "We have a %s", "mysterious problem", exc_info=1) """ if not isinstance(level, (int, long)): if raiseExceptions: raise TypeError("level must be an integer") else: return if self.isEnabledFor(level): self._log(level, msg, args, **kwargs) def findCaller(self): """ Find the stack frame of the caller so that we can note the source file name, line number and function name. """ f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. if f is not None: f = f.f_back rv = "(unknown file)", 0, "(unknown function)" while hasattr(f, "f_code"): co = f.f_code filename = os.path.normcase(co.co_filename) if filename == _srcfile: f = f.f_back continue rv = (co.co_filename, f.f_lineno, co.co_name) break return rv def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None): """ A factory method which can be overridden in subclasses to create specialized LogRecords. """ rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] return rv def _log(self, level, msg, args, exc_info=None, extra=None): """ Low-level logging routine which creates a LogRecord and then calls all the handlers of this logger to handle the record. """ if _srcfile: #IronPython doesn't track Python frames, so findCaller raises an #exception on some versions of IronPython. We trap it here so that #IronPython can use logging. try: fn, lno, func = self.findCaller() except ValueError: fn, lno, func = "(unknown file)", 0, "(unknown function)" else: fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: if not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra) self.handle(record) def handle(self, record): """ Call the handlers for the specified record. This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ if (not self.disabled) and self.filter(record): self.callHandlers(record) def addHandler(self, hdlr): """ Add the specified handler to this logger. """ _acquireLock() try: if not (hdlr in self.handlers): self.handlers.append(hdlr) finally: _releaseLock() def removeHandler(self, hdlr): """ Remove the specified handler from this logger. """ _acquireLock() try: if hdlr in self.handlers: self.handlers.remove(hdlr) finally: _releaseLock() def callHandlers(self, record): """ Pass a record to all relevant handlers. Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called. """ c = self found = 0 while c: for hdlr in c.handlers: found = found + 1 if record.levelno >= hdlr.level: hdlr.handle(record) if not c.propagate: c = None #break out else: c = c.parent if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning: sys.stderr.write("No handlers could be found for logger" " \"%s\"\n" % self.name) self.manager.emittedNoHandlerWarning = 1 def getEffectiveLevel(self): """ Get the effective level for this logger. Loop through this logger and its parents in the logger hierarchy, looking for a non-zero logging level. Return the first one found. """ logger = self while logger: if logger.level: return logger.level logger = logger.parent return NOTSET def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.manager.disable >= level: return 0 return level >= self.getEffectiveLevel() def getChild(self, suffix): """ Get a logger which is a descendant to this one. This is a convenience method, such that logging.getLogger('abc').getChild('def.ghi') is the same as logging.getLogger('abc.def.ghi') It's useful, for example, when the parent logger is named using __name__ rather than a literal string. """ if self.root is not self: suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) class RootLogger(Logger): """ A root logger is not that different to any other logger, except that it must have a logging level and there is only one instance of it in the hierarchy. """ def __init__(self, level): """ Initialize the logger with the name "root". """ Logger.__init__(self, "root", level) _loggerClass = Logger class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. """ def __init__(self, logger, extra): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows easy stacking of LoggerAdapters, if so desired. You can effectively pass keyword arguments as shown in the following example: adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) """ self.logger = logger self.extra = extra def process(self, msg, kwargs): """ Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs. Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs. """ kwargs["extra"] = self.extra return msg, kwargs def debug(self, msg, *args, **kwargs): """ Delegate a debug call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.debug(msg, *args, **kwargs) def info(self, msg, *args, **kwargs): """ Delegate an info call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.info(msg, *args, **kwargs) def warning(self, msg, *args, **kwargs): """ Delegate a warning call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Delegate an error call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.error(msg, *args, **kwargs) def exception(self, msg, *args, **kwargs): """ Delegate an exception call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) kwargs["exc_info"] = 1 self.logger.error(msg, *args, **kwargs) def critical(self, msg, *args, **kwargs): """ Delegate a critical call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.critical(msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Delegate a log call to the underlying logger, after adding contextual information from this adapter instance. """ msg, kwargs = self.process(msg, kwargs) self.logger.log(level, msg, *args, **kwargs) def isEnabledFor(self, level): """ See if the underlying logger is enabled for the specified level. """ return self.logger.isEnabledFor(level) root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) #--------------------------------------------------------------------------- # Configuration classes and functions #--------------------------------------------------------------------------- BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" def basicConfig(**kwargs): """ Do basic configuration for the logging system. This function does nothing if the root logger already has handlers configured. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package. The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger. A number of optional keyword arguments may be specified, which can alter the default behaviour. filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler. filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format Use the specified format string for the handler. datefmt Use the specified date/time format. level Set the root logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored. Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed. """ # Add thread safety in case someone mistakenly calls # basicConfig() from multiple threads _acquireLock() try: if len(root.handlers) == 0: filename = kwargs.get("filename") if filename: mode = kwargs.get("filemode", 'a') hdlr = FileHandler(filename, mode) else: stream = kwargs.get("stream") hdlr = StreamHandler(stream) fs = kwargs.get("format", BASIC_FORMAT) dfs = kwargs.get("datefmt", None) fmt = Formatter(fs, dfs) hdlr.setFormatter(fmt) root.addHandler(hdlr) level = kwargs.get("level") if level is not None: root.setLevel(level) finally: _releaseLock() #--------------------------------------------------------------------------- # Utility functions at module level. # Basically delegate everything to the root logger. #--------------------------------------------------------------------------- def getLogger(name=None): """ Return a logger with the specified name, creating it if necessary. If no name is specified, return the root logger. """ if name: return Logger.manager.getLogger(name) else: return root #def getRootLogger(): # """ # Return the root logger. # # Note that getLogger('') now does the same thing, so this function is # deprecated and may disappear in the future. # """ # return root def critical(msg, *args, **kwargs): """ Log a message with severity 'CRITICAL' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.critical(msg, *args, **kwargs) fatal = critical def error(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.error(msg, *args, **kwargs) def exception(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. """ kwargs['exc_info'] = 1 error(msg, *args, **kwargs) def warning(msg, *args, **kwargs): """ Log a message with severity 'WARNING' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.warning(msg, *args, **kwargs) warn = warning def info(msg, *args, **kwargs): """ Log a message with severity 'INFO' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.info(msg, *args, **kwargs) def debug(msg, *args, **kwargs): """ Log a message with severity 'DEBUG' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.debug(msg, *args, **kwargs) def log(level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level' on the root logger. """ if len(root.handlers) == 0: basicConfig() root.log(level, msg, *args, **kwargs) def disable(level): """ Disable all logging calls of severity 'level' and below. """ root.manager.disable = level def shutdown(handlerList=_handlerList): """ Perform any cleanup actions in the logging system (e.g. flushing buffers). Should be called at application exit. """ for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: h = wr() if h: try: h.acquire() h.flush() h.close() except (IOError, ValueError): # Ignore errors which might be caused # because handlers have been closed but # references to them are still around at # application exit. pass finally: h.release() except: if raiseExceptions: raise #else, swallow #Let's try and shutdown automatically on application exit... import atexit atexit.register(shutdown) # Null handler class NullHandler(Handler): """ This handler does nothing. It's intended to be used to avoid the "No handlers could be found for logger XXX" one-off warning. This is important for library code, which may contain code to log events. If a user of the library does not configure logging, the one-off warning might be produced; to avoid this, the library developer simply needs to instantiate a NullHandler and add it to the top-level logger of the library module or package. """ def handle(self, record): pass def emit(self, record): pass def createLock(self): self.lock = None # Warnings integration _warnings_showwarning = None def _showwarning(message, category, filename, lineno, file=None, line=None): """ Implementation of showwarnings which redirects to logging, which will first check to see if the file parameter is None. If a file is specified, it will delegate to the original warnings implementation of showwarning. Otherwise, it will call warnings.formatwarning and will log the resulting string to a warnings logger named "py.warnings" with level logging.WARNING. """ if file is not None: if _warnings_showwarning is not None: _warnings_showwarning(message, category, filename, lineno, file, line) else: s = warnings.formatwarning(message, category, filename, lineno, line) logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) logger.warning("%s", s) def captureWarnings(capture): """ If capture is true, redirect all warnings to the logging package. If capture is False, ensure that warnings are not redirected to logging but to their original destinations. """ global _warnings_showwarning if capture: if _warnings_showwarning is None: _warnings_showwarning = warnings.showwarning warnings.showwarning = _showwarning else: if _warnings_showwarning is not None: warnings.showwarning = _warnings_showwarning _warnings_showwarning = None lib64/python3.8/logging/__init__.py000064400000230204152346563100013003 0ustar00# Copyright 2001-2017 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation, and that the name of Vinay Sajip # not be used in advertising or publicity pertaining to distribution # of the software without specific, written prior permission. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. Copyright (C) 2001-2017 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import sys, os, time, io, re, traceback, warnings, weakref, collections.abc from string import Template from string import Formatter as StrFormatter __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', 'lastResort', 'raiseExceptions'] import threading __author__ = "Vinay Sajip " __status__ = "production" # The following module attributes are no longer updated. __version__ = "0.5.1.2" __date__ = "07 February 2010" #--------------------------------------------------------------------------- # Miscellaneous module data #--------------------------------------------------------------------------- # #_startTime is used as the base when calculating the relative time of events # _startTime = time.time() # #raiseExceptions is used to see if exceptions during handling should be #propagated # raiseExceptions = True # # If you don't want threading information in the log, set this to zero # logThreads = True # # If you don't want multiprocessing information in the log, set this to zero # logMultiprocessing = True # # If you don't want process information in the log, set this to zero # logProcesses = True #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- # # Default levels and level names, these can be replaced with any positive set # of values having corresponding names. There is a pseudo-level, NOTSET, which # is only really there as a lower limit for user-defined levels. Handlers and # loggers are initialized with NOTSET so that they will log all messages, even # at user-defined levels. # CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 _levelToName = { CRITICAL: 'CRITICAL', ERROR: 'ERROR', WARNING: 'WARNING', INFO: 'INFO', DEBUG: 'DEBUG', NOTSET: 'NOTSET', } _nameToLevel = { 'CRITICAL': CRITICAL, 'FATAL': FATAL, 'ERROR': ERROR, 'WARN': WARNING, 'WARNING': WARNING, 'INFO': INFO, 'DEBUG': DEBUG, 'NOTSET': NOTSET, } def getLevelName(level): """ Return the textual or numeric representation of logging level 'level'. If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, INFO, DEBUG) then you get the corresponding string. If you have associated levels with names using addLevelName then the name you have associated with 'level' is returned. If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned. If a string representation of the level is passed in, the corresponding numeric value is returned. If no matching numeric or string value is passed in, the string 'Level %s' % level is returned. """ # See Issues #22386, #27937 and #29220 for why it's this way result = _levelToName.get(level) if result is not None: return result result = _nameToLevel.get(level) if result is not None: return result return "Level %s" % level def addLevelName(level, levelName): """ Associate 'levelName' with 'level'. This is used when converting levels to text during message formatting. """ _acquireLock() try: #unlikely to cause an exception, but you never know... _levelToName[level] = levelName _nameToLevel[levelName] = level finally: _releaseLock() if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) else: #pragma: no cover def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise Exception except Exception: return sys.exc_info()[2].tb_frame.f_back # # _srcfile is used when walking the stack to check when we've got the first # caller stack frame, by skipping frames whose filename is that of this # module's source. It therefore should contain the filename of this module's # source file. # # Ordinarily we would use __file__ for this, but frozen modules don't always # have __file__ set, for some reason (see Issue #21736). Thus, we get the # filename from a handy code object from a function defined in this module. # (There's no particular reason for picking addLevelName.) # _srcfile = os.path.normcase(addLevelName.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). # To provide compatibility with older versions of Python, set _srcfile # to None if _getframe() is not available; this value will prevent # findCaller() from being called. You can also do this if you want to avoid # the overhead of fetching caller information, even when _getframe() is # available. #if not hasattr(sys, '_getframe'): # _srcfile = None def _checkLevel(level): if isinstance(level, int): rv = level elif str(level) == level: if level not in _nameToLevel: raise ValueError("Unknown level: %r" % level) rv = _nameToLevel[level] else: raise TypeError("Level not an integer or a valid string: %r" % level) return rv #--------------------------------------------------------------------------- # Thread-related stuff #--------------------------------------------------------------------------- # #_lock is used to serialize access to shared data structures in this module. #This needs to be an RLock because fileConfig() creates and configures #Handlers, and so might arbitrary user threads. Since Handler code updates the #shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # _lock = threading.RLock() def _acquireLock(): """ Acquire the module-level lock for serializing access to shared data. This should be released with _releaseLock(). """ if _lock: _lock.acquire() def _releaseLock(): """ Release the module-level lock acquired by calling _acquireLock(). """ if _lock: _lock.release() # Prevent a held logging lock from blocking a child from logging. if not hasattr(os, 'register_at_fork'): # Windows and friends. def _register_at_fork_reinit_lock(instance): pass # no-op when os.register_at_fork does not exist. else: # A collection of instances with a createLock method (logging.Handler) # to be called in the child after forking. The weakref avoids us keeping # discarded Handler instances alive. A set is used to avoid accumulating # duplicate registrations as createLock() is responsible for registering # a new Handler instance with this set in the first place. _at_fork_reinit_lock_weakset = weakref.WeakSet() def _register_at_fork_reinit_lock(instance): _acquireLock() try: _at_fork_reinit_lock_weakset.add(instance) finally: _releaseLock() def _after_at_fork_child_reinit_locks(): # _acquireLock() was called in the parent before forking. for handler in _at_fork_reinit_lock_weakset: try: handler.createLock() except Exception as err: # Similar to what PyErr_WriteUnraisable does. print("Ignoring exception from logging atfork", instance, "._reinit_lock() method:", err, file=sys.stderr) _releaseLock() # Acquired by os.register_at_fork(before=. os.register_at_fork(before=_acquireLock, after_in_child=_after_at_fork_child_reinit_locks, after_in_parent=_releaseLock) #--------------------------------------------------------------------------- # The logging record #--------------------------------------------------------------------------- class LogRecord(object): """ A LogRecord instance represents an event being logged. LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is in msg and args, which are combined using str(msg) % args to create the message field of the record. The record also includes information such as when the record was created, the source line where the logging call was made, and any exception information to be logged. """ def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None, **kwargs): """ Initialize a logging record with interesting information. """ ct = time.time() self.name = name self.msg = msg # # The following statement allows passing of a dictionary as a sole # argument, so that you can do something like # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) # Suggested by Stefan Behnel. # Note that without the test for args[0], we get a problem because # during formatting, we test to see if the arg is present using # 'if self.args:'. If the event being logged is e.g. 'Value is %d' # and if the passed arg fails 'if self.args:' then no formatting # is done. For example, logger.warning('Value is %d', 0) would log # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. # Issue #21172: a request was made to relax the isinstance check # to hasattr(args[0], '__getitem__'). However, the docs on string # formatting still seem to suggest a mapping object is required. # Thus, while not removing the isinstance check, it does now look # for collections.abc.Mapping rather than, as before, dict. if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping) and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) self.levelno = level self.pathname = pathname try: self.filename = os.path.basename(pathname) self.module = os.path.splitext(self.filename)[0] except (TypeError, ValueError, AttributeError): self.filename = pathname self.module = "Unknown module" self.exc_info = exc_info self.exc_text = None # used to cache the traceback text self.stack_info = sinfo self.lineno = lineno self.funcName = func self.created = ct self.msecs = (ct - int(ct)) * 1000 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads: self.thread = threading.get_ident() self.threadName = threading.current_thread().name else: # pragma: no cover self.thread = None self.threadName = None if not logMultiprocessing: # pragma: no cover self.processName = None else: self.processName = 'MainProcess' mp = sys.modules.get('multiprocessing') if mp is not None: # Errors may occur if multiprocessing has not finished loading # yet - e.g. if a custom import hook causes third-party code # to run when multiprocessing calls import. See issue 8200 # for an example try: self.processName = mp.current_process().name except Exception: #pragma: no cover pass if logProcesses and hasattr(os, 'getpid'): self.process = os.getpid() else: self.process = None def __repr__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) def getMessage(self): """ Return the message for this LogRecord. Return the message for this LogRecord after merging any user-supplied arguments with the message. """ msg = str(self.msg) if self.args: msg = msg % self.args return msg # # Determine which class to use when instantiating log records. # _logRecordFactory = LogRecord def setLogRecordFactory(factory): """ Set the factory to be used when instantiating a log record. :param factory: A callable which will be called to instantiate a log record. """ global _logRecordFactory _logRecordFactory = factory def getLogRecordFactory(): """ Return the factory to be used when instantiating a log record. """ return _logRecordFactory def makeLogRecord(dict): """ Make a LogRecord whose attributes are defined by the specified dictionary, This function is useful for converting a logging event received over a socket connection (which is sent as a dictionary) into a LogRecord instance. """ rv = _logRecordFactory(None, None, "", 0, "", (), None, None) rv.__dict__.update(dict) return rv #--------------------------------------------------------------------------- # Formatter classes and functions #--------------------------------------------------------------------------- _str_formatter = StrFormatter() del StrFormatter class PercentStyle(object): default_format = '%(message)s' asctime_format = '%(asctime)s' asctime_search = '%(asctime)' validation_pattern = re.compile(r'%\(\w+\)[#0+ -]*(\*|\d+)?(\.(\*|\d+))?[diouxefgcrsa%]', re.I) def __init__(self, fmt): self._fmt = fmt or self.default_format def usesTime(self): return self._fmt.find(self.asctime_search) >= 0 def validate(self): """Validate the input format, ensure it matches the correct style""" if not self.validation_pattern.search(self._fmt): raise ValueError("Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0])) def _format(self, record): return self._fmt % record.__dict__ def format(self, record): try: return self._format(record) except KeyError as e: raise ValueError('Formatting field not found in record: %s' % e) class StrFormatStyle(PercentStyle): default_format = '{message}' asctime_format = '{asctime}' asctime_search = '{asctime' fmt_spec = re.compile(r'^(.?[<>=^])?[+ -]?#?0?(\d+|{\w+})?[,_]?(\.(\d+|{\w+}))?[bcdefgnosx%]?$', re.I) field_spec = re.compile(r'^(\d+|\w+)(\.\w+|\[[^]]+\])*$') def _format(self, record): return self._fmt.format(**record.__dict__) def validate(self): """Validate the input format, ensure it is the correct string formatting style""" fields = set() try: for _, fieldname, spec, conversion in _str_formatter.parse(self._fmt): if fieldname: if not self.field_spec.match(fieldname): raise ValueError('invalid field name/expression: %r' % fieldname) fields.add(fieldname) if conversion and conversion not in 'rsa': raise ValueError('invalid conversion: %r' % conversion) if spec and not self.fmt_spec.match(spec): raise ValueError('bad specifier: %r' % spec) except ValueError as e: raise ValueError('invalid format: %s' % e) if not fields: raise ValueError('invalid format: no fields') class StringTemplateStyle(PercentStyle): default_format = '${message}' asctime_format = '${asctime}' asctime_search = '${asctime}' def __init__(self, fmt): self._fmt = fmt or self.default_format self._tpl = Template(self._fmt) def usesTime(self): fmt = self._fmt return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0 def validate(self): pattern = Template.pattern fields = set() for m in pattern.finditer(self._fmt): d = m.groupdict() if d['named']: fields.add(d['named']) elif d['braced']: fields.add(d['braced']) elif m.group(0) == '$': raise ValueError('invalid format: bare \'$\' not allowed') if not fields: raise ValueError('invalid format: no fields') def _format(self, record): return self._tpl.substitute(**record.__dict__) BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" _STYLES = { '%': (PercentStyle, BASIC_FORMAT), '{': (StrFormatStyle, '{levelname}:{name}:{message}'), '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), } class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. Formatters need to know how a LogRecord is constructed. They are responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the style-dependent default value, "%(message)s", "{message}", or "${message}", is used. The Formatter can be initialized with a format string which makes use of knowledge of the LogRecord attributes - e.g. the default value mentioned above makes use of the fact that the user's message and arguments are pre- formatted into a LogRecord's message attribute. Currently, the useful attributes in a LogRecord are described by: %(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted """ converter = time.localtime def __init__(self, fmt=None, datefmt=None, style='%', validate=True): """ Initialize the formatter with specified format strings. Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument. If datefmt is omitted, you get an ISO8601-like (or RFC 3339-like) format. Use a style parameter of '%', '{' or '$' to specify that you want to use one of %-formatting, :meth:`str.format` (``{}``) formatting or :class:`string.Template` formatting in your format string. .. versionchanged:: 3.2 Added the ``style`` parameter. """ if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) self._style = _STYLES[style][0](fmt) if validate: self._style.validate() self._fmt = self._style._fmt self.datefmt = datefmt default_time_format = '%Y-%m-%d %H:%M:%S' default_msec_format = '%s,%03d' def formatTime(self, record, datefmt=None): """ Return the creation time of the specified LogRecord as formatted text. This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) if datefmt: s = time.strftime(datefmt, ct) else: t = time.strftime(self.default_time_format, ct) s = self.default_msec_format % (t, record.msecs) return s def formatException(self, ei): """ Format and return the specified exception information as a string. This default implementation just uses traceback.print_exception() """ sio = io.StringIO() tb = ei[2] # See issues #9427, #1553375. Commented out for now. #if getattr(self, 'fullstack', False): # traceback.print_stack(tb.tb_frame.f_back, file=sio) traceback.print_exception(ei[0], ei[1], tb, None, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] return s def usesTime(self): """ Check if the format uses the creation time of the record. """ return self._style.usesTime() def formatMessage(self, record): return self._style.format(record) def formatStack(self, stack_info): """ This method is provided as an extension point for specialized formatting of stack information. The input data is a string as returned from a call to :func:`traceback.print_stack`, but with the last trailing newline removed. The base implementation just returns the value passed in. """ return stack_info def format(self, record): """ Format the specified record as text. The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message. """ record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) return s # # The default formatter to use when no other is specified # _defaultFormatter = Formatter() class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ def __init__(self, linefmt=None): """ Optionally specify a formatter which will be used to format each individual record. """ if linefmt: self.linefmt = linefmt else: self.linefmt = _defaultFormatter def formatHeader(self, records): """ Return the header string for the specified records. """ return "" def formatFooter(self, records): """ Return the footer string for the specified records. """ return "" def format(self, records): """ Format the specified records and return the result as a string. """ rv = "" if len(records) > 0: rv = rv + self.formatHeader(records) for record in records: rv = rv + self.linefmt.format(record) rv = rv + self.formatFooter(records) return rv #--------------------------------------------------------------------------- # Filter classes and functions #--------------------------------------------------------------------------- class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed. """ def __init__(self, name=''): """ Initialize a filter. Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event. """ self.name = name self.nlen = len(name) def filter(self, record): """ Determine if the specified record is to be logged. Returns True if the record should be logged, or False otherwise. If deemed appropriate, the record may be modified in-place. """ if self.nlen == 0: return True elif self.name == record.name: return True elif record.name.find(self.name, 0, self.nlen) != 0: return False return (record.name[self.nlen] == ".") class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. """ def __init__(self): """ Initialize the list of filters to be an empty list. """ self.filters = [] def addFilter(self, filter): """ Add the specified filter to this handler. """ if not (filter in self.filters): self.filters.append(filter) def removeFilter(self, filter): """ Remove the specified filter from this handler. """ if filter in self.filters: self.filters.remove(filter) def filter(self, record): """ Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto this and the record is then dropped. Returns a zero value if a record is to be dropped, else non-zero. .. versionchanged:: 3.2 Allow filters to be just callables. """ rv = True for f in self.filters: if hasattr(f, 'filter'): result = f.filter(record) else: result = f(record) # assume callable - will raise if not if not result: rv = False break return rv #--------------------------------------------------------------------------- # Handler classes and functions #--------------------------------------------------------------------------- _handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized def _removeHandlerRef(wr): """ Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are # set to None. It can also be called from another thread. So we need to # pre-emptively grab the necessary globals and check if they're None, # to prevent race conditions and failures during interpreter shutdown. acquire, release, handlers = _acquireLock, _releaseLock, _handlerList if acquire and release and handlers: acquire() try: if wr in handlers: handlers.remove(wr) finally: release() def _addHandlerRef(handler): """ Add a handler to the internal cleanup list using a weak reference. """ _acquireLock() try: _handlerList.append(weakref.ref(handler, _removeHandlerRef)) finally: _releaseLock() class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. The base handler class. Acts as a placeholder which defines the Handler interface. Handlers can optionally use Formatter instances to format records as desired. By default, no formatter is specified; in this case, the 'raw' message as determined by record.message is logged. """ def __init__(self, level=NOTSET): """ Initializes the instance - basically setting the formatter to None and the filter list to empty. """ Filterer.__init__(self) self._name = None self.level = _checkLevel(level) self.formatter = None # Add the handler to the global _handlerList (for cleanup on shutdown) _addHandlerRef(self) self.createLock() def get_name(self): return self._name def set_name(self, name): _acquireLock() try: if self._name in _handlers: del _handlers[self._name] self._name = name if name: _handlers[name] = self finally: _releaseLock() name = property(get_name, set_name) def createLock(self): """ Acquire a thread lock for serializing access to the underlying I/O. """ self.lock = threading.RLock() _register_at_fork_reinit_lock(self) def acquire(self): """ Acquire the I/O thread lock. """ if self.lock: self.lock.acquire() def release(self): """ Release the I/O thread lock. """ if self.lock: self.lock.release() def setLevel(self, level): """ Set the logging level of this handler. level must be an int or a str. """ self.level = _checkLevel(level) def format(self, record): """ Format the specified record. If a formatter is set, use it. Otherwise, use the default formatter for the module. """ if self.formatter: fmt = self.formatter else: fmt = _defaultFormatter return fmt.format(record) def emit(self, record): """ Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so raises a NotImplementedError. """ raise NotImplementedError('emit must be implemented ' 'by Handler subclasses') def handle(self, record): """ Conditionally emit the specified logging record. Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns whether the filter passed the record for emission. """ rv = self.filter(record) if rv: self.acquire() try: self.emit(record) finally: self.release() return rv def setFormatter(self, fmt): """ Set the formatter for this handler. """ self.formatter = fmt def flush(self): """ Ensure all logging output has been flushed. This version does nothing and is intended to be implemented by subclasses. """ pass def close(self): """ Tidy up any resources used by the handler. This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... if self._name and self._name in _handlers: del _handlers[self._name] finally: _releaseLock() def handleError(self, record): """ Handle errors which occur during an emit() call. This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method. """ if raiseExceptions and sys.stderr: # see issue 13807 t, v, tb = sys.exc_info() try: sys.stderr.write('--- Logging error ---\n') traceback.print_exception(t, v, tb, None, sys.stderr) sys.stderr.write('Call stack:\n') # Walk the stack frame up until we're out of logging, # so as to print the calling context. frame = tb.tb_frame while (frame and os.path.dirname(frame.f_code.co_filename) == __path__[0]): frame = frame.f_back if frame: traceback.print_stack(frame, file=sys.stderr) else: # couldn't find the right stack frame, for some reason sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) # Issue 18671: output logging message and arguments try: sys.stderr.write('Message: %r\n' 'Arguments: %s\n' % (record.msg, record.args)) except RecursionError: # See issue 36272 raise except Exception: sys.stderr.write('Unable to print the message and arguments' ' - possible formatting error.\nUse the' ' traceback above to help find the error.\n' ) except OSError: #pragma: no cover pass # see issue 5971 finally: del t, v, tb def __repr__(self): level = getLevelName(self.level) return '<%s (%s)>' % (self.__class__.__name__, level) class StreamHandler(Handler): """ A handler class which writes logging records, appropriately formatted, to a stream. Note that this class does not close the stream, as sys.stdout or sys.stderr may be used. """ terminator = '\n' def __init__(self, stream=None): """ Initialize the handler. If stream is not specified, sys.stderr is used. """ Handler.__init__(self) if stream is None: stream = sys.stderr self.stream = stream def flush(self): """ Flushes the stream. """ self.acquire() try: if self.stream and hasattr(self.stream, "flush"): self.stream.flush() finally: self.release() def emit(self, record): """ Emit a record. If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an 'encoding' attribute, it is used to determine how to do the output to the stream. """ try: msg = self.format(record) stream = self.stream # issue 35046: merged two stream.writes into one. stream.write(msg + self.terminator) self.flush() except RecursionError: # See issue 36272 raise except Exception: self.handleError(record) def setStream(self, stream): """ Sets the StreamHandler's stream to the specified value, if it is different. Returns the old stream, if the stream was changed, or None if it wasn't. """ if stream is self.stream: result = None else: result = self.stream self.acquire() try: self.flush() self.stream = stream finally: self.release() return result def __repr__(self): level = getLevelName(self.level) name = getattr(self.stream, 'name', '') # bpo-36015: name can be an int name = str(name) if name: name += ' ' return '<%s %s(%s)>' % (self.__class__.__name__, name, level) class FileHandler(StreamHandler): """ A handler class which writes formatted logging records to disk files. """ def __init__(self, filename, mode='a', encoding=None, delay=False): """ Open the specified file and use it as the stream for logging. """ # Issue #27493: add support for Path objects to be passed in filename = os.fspath(filename) #keep the absolute path, otherwise derived classes which use this #may come a cropper when the current directory changes self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding self.delay = delay if delay: #We don't open the stream, but we still need to call the #Handler constructor to set level, formatter, lock etc. Handler.__init__(self) self.stream = None else: StreamHandler.__init__(self, self._open()) def close(self): """ Closes the stream. """ self.acquire() try: try: if self.stream: try: self.flush() finally: stream = self.stream self.stream = None if hasattr(stream, "close"): stream.close() finally: # Issue #19523: call unconditionally to # prevent a handler leak when delay is set StreamHandler.close(self) finally: self.release() def _open(self): """ Open the current base file with the (original) mode and encoding. Return the resulting stream. """ return open(self.baseFilename, self.mode, encoding=self.encoding) def emit(self, record): """ Emit a record. If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit. """ if self.stream is None: self.stream = self._open() StreamHandler.emit(self, record) def __repr__(self): level = getLevelName(self.level) return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level) class _StderrHandler(StreamHandler): """ This class is like a StreamHandler using sys.stderr, but always uses whatever sys.stderr is currently set to rather than the value of sys.stderr at handler construction time. """ def __init__(self, level=NOTSET): """ Initialize the handler. """ Handler.__init__(self, level) @property def stream(self): return sys.stderr _defaultLastResort = _StderrHandler(WARNING) lastResort = _defaultLastResort #--------------------------------------------------------------------------- # Manager classes and functions #--------------------------------------------------------------------------- class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is intended for internal use only and not as part of the public API. """ def __init__(self, alogger): """ Initialize with the specified logger being a child of this placeholder. """ self.loggerMap = { alogger : None } def append(self, alogger): """ Add the specified logger as a child of this placeholder. """ if alogger not in self.loggerMap: self.loggerMap[alogger] = None # # Determine which class to use when instantiating loggers. # def setLoggerClass(klass): """ Set the class to be used when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__() """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) global _loggerClass _loggerClass = klass def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ return _loggerClass class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. """ def __init__(self, rootnode): """ Initialize the manager with the root node of the logger hierarchy. """ self.root = rootnode self.disable = 0 self.emittedNoHandlerWarning = False self.loggerDict = {} self.loggerClass = None self.logRecordFactory = None @property def disable(self): return self._disable @disable.setter def disable(self, value): self._disable = _checkLevel(value) def getLogger(self, name): """ Get a logger with the specified name (channel name), creating it if it doesn't yet exist. This name is a dot-separated hierarchical name, such as "a", "a.b", "a.b.c" or similar. If a PlaceHolder existed for the specified name [i.e. the logger didn't exist but a child of it did], replace it with the created logger and fix up the parent/child references which pointed to the placeholder to now point to the logger. """ rv = None if not isinstance(name, str): raise TypeError('A logger name must be a string') _acquireLock() try: if name in self.loggerDict: rv = self.loggerDict[name] if isinstance(rv, PlaceHolder): ph = rv rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupChildren(ph, rv) self._fixupParents(rv) else: rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupParents(rv) finally: _releaseLock() return rv def setLoggerClass(self, klass): """ Set the class to be used when instantiating a logger with this Manager. """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) self.loggerClass = klass def setLogRecordFactory(self, factory): """ Set the factory to be used when instantiating a log record with this Manager. """ self.logRecordFactory = factory def _fixupParents(self, alogger): """ Ensure that there are either loggers or placeholders all the way from the specified logger to the root of the logger hierarchy. """ name = alogger.name i = name.rfind(".") rv = None while (i > 0) and not rv: substr = name[:i] if substr not in self.loggerDict: self.loggerDict[substr] = PlaceHolder(alogger) else: obj = self.loggerDict[substr] if isinstance(obj, Logger): rv = obj else: assert isinstance(obj, PlaceHolder) obj.append(alogger) i = name.rfind(".", 0, i - 1) if not rv: rv = self.root alogger.parent = rv def _fixupChildren(self, ph, alogger): """ Ensure that children of the placeholder ph are connected to the specified logger. """ name = alogger.name namelen = len(name) for c in ph.loggerMap.keys(): #The if means ... if not c.parent.name.startswith(nm) if c.parent.name[:namelen] != name: alogger.parent = c.parent c.parent = alogger def _clear_cache(self): """ Clear the cache for all loggers in loggerDict Called when level changes are made """ _acquireLock() for logger in self.loggerDict.values(): if isinstance(logger, Logger): logger._cache.clear() self.root._cache.clear() _releaseLock() #--------------------------------------------------------------------------- # Logger classes and functions #--------------------------------------------------------------------------- class Logger(Filterer): """ Instances of the Logger class represent a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting. """ def __init__(self, name, level=NOTSET): """ Initialize the logger with a name and an optional level. """ Filterer.__init__(self) self.name = name self.level = _checkLevel(level) self.parent = None self.propagate = True self.handlers = [] self.disabled = False self._cache = {} def setLevel(self, level): """ Set the logging level of this logger. level must be an int or a str. """ self.level = _checkLevel(level) self.manager._clear_cache() def debug(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'DEBUG'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.debug("Houston, we have a %s", "thorny problem", exc_info=1) """ if self.isEnabledFor(DEBUG): self._log(DEBUG, msg, args, **kwargs) def info(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'INFO'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.info("Houston, we have a %s", "interesting problem", exc_info=1) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) def warning(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'WARNING'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1) """ if self.isEnabledFor(WARNING): self._log(WARNING, msg, args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'ERROR'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.error("Houston, we have a %s", "major problem", exc_info=1) """ if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Convenience method for logging an ERROR with exception information. """ self.error(msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'CRITICAL'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.critical("Houston, we have a %s", "major disaster", exc_info=1) """ if self.isEnabledFor(CRITICAL): self._log(CRITICAL, msg, args, **kwargs) fatal = critical def log(self, level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.log(level, "We have a %s", "mysterious problem", exc_info=1) """ if not isinstance(level, int): if raiseExceptions: raise TypeError("level must be an integer") else: return if self.isEnabledFor(level): self._log(level, msg, args, **kwargs) def findCaller(self, stack_info=False, stacklevel=1): """ Find the stack frame of the caller so that we can note the source file name, line number and function name. """ f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. if f is not None: f = f.f_back orig_f = f while f and stacklevel > 1: f = f.f_back stacklevel -= 1 if not f: f = orig_f rv = "(unknown file)", 0, "(unknown function)", None while hasattr(f, "f_code"): co = f.f_code filename = os.path.normcase(co.co_filename) if filename == _srcfile: f = f.f_back continue sinfo = None if stack_info: sio = io.StringIO() sio.write('Stack (most recent call last):\n') traceback.print_stack(f, file=sio) sinfo = sio.getvalue() if sinfo[-1] == '\n': sinfo = sinfo[:-1] sio.close() rv = (co.co_filename, f.f_lineno, co.co_name, sinfo) break return rv def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None): """ A factory method which can be overridden in subclasses to create specialized LogRecords. """ rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func, sinfo) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] return rv def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False, stacklevel=1): """ Low-level logging routine which creates a LogRecord and then calls all the handlers of this logger to handle the record. """ sinfo = None if _srcfile: #IronPython doesn't track Python frames, so findCaller raises an #exception on some versions of IronPython. We trap it here so that #IronPython can use logging. try: fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel) except ValueError: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" else: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: if isinstance(exc_info, BaseException): exc_info = (type(exc_info), exc_info, exc_info.__traceback__) elif not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra, sinfo) self.handle(record) def handle(self, record): """ Call the handlers for the specified record. This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ if (not self.disabled) and self.filter(record): self.callHandlers(record) def addHandler(self, hdlr): """ Add the specified handler to this logger. """ _acquireLock() try: if not (hdlr in self.handlers): self.handlers.append(hdlr) finally: _releaseLock() def removeHandler(self, hdlr): """ Remove the specified handler from this logger. """ _acquireLock() try: if hdlr in self.handlers: self.handlers.remove(hdlr) finally: _releaseLock() def hasHandlers(self): """ See if this logger has any handlers configured. Loop through all handlers for this logger and its parents in the logger hierarchy. Return True if a handler was found, else False. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger which is checked for the existence of handlers. """ c = self rv = False while c: if c.handlers: rv = True break if not c.propagate: break else: c = c.parent return rv def callHandlers(self, record): """ Pass a record to all relevant handlers. Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called. """ c = self found = 0 while c: for hdlr in c.handlers: found = found + 1 if record.levelno >= hdlr.level: hdlr.handle(record) if not c.propagate: c = None #break out else: c = c.parent if (found == 0): if lastResort: if record.levelno >= lastResort.level: lastResort.handle(record) elif raiseExceptions and not self.manager.emittedNoHandlerWarning: sys.stderr.write("No handlers could be found for logger" " \"%s\"\n" % self.name) self.manager.emittedNoHandlerWarning = True def getEffectiveLevel(self): """ Get the effective level for this logger. Loop through this logger and its parents in the logger hierarchy, looking for a non-zero logging level. Return the first one found. """ logger = self while logger: if logger.level: return logger.level logger = logger.parent return NOTSET def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.disabled: return False try: return self._cache[level] except KeyError: _acquireLock() try: if self.manager.disable >= level: is_enabled = self._cache[level] = False else: is_enabled = self._cache[level] = ( level >= self.getEffectiveLevel() ) finally: _releaseLock() return is_enabled def getChild(self, suffix): """ Get a logger which is a descendant to this one. This is a convenience method, such that logging.getLogger('abc').getChild('def.ghi') is the same as logging.getLogger('abc.def.ghi') It's useful, for example, when the parent logger is named using __name__ rather than a literal string. """ if self.root is not self: suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) def __repr__(self): level = getLevelName(self.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) def __reduce__(self): # In general, only the root logger will not be accessible via its name. # However, the root logger's class has its own __reduce__ method. if getLogger(self.name) is not self: import pickle raise pickle.PicklingError('logger cannot be pickled') return getLogger, (self.name,) class RootLogger(Logger): """ A root logger is not that different to any other logger, except that it must have a logging level and there is only one instance of it in the hierarchy. """ def __init__(self, level): """ Initialize the logger with the name "root". """ Logger.__init__(self, "root", level) def __reduce__(self): return getLogger, () _loggerClass = Logger class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. """ def __init__(self, logger, extra): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows easy stacking of LoggerAdapters, if so desired. You can effectively pass keyword arguments as shown in the following example: adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) """ self.logger = logger self.extra = extra def process(self, msg, kwargs): """ Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs. Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs. """ kwargs["extra"] = self.extra return msg, kwargs # # Boilerplate convenience methods # def debug(self, msg, *args, **kwargs): """ Delegate a debug call to the underlying logger. """ self.log(DEBUG, msg, *args, **kwargs) def info(self, msg, *args, **kwargs): """ Delegate an info call to the underlying logger. """ self.log(INFO, msg, *args, **kwargs) def warning(self, msg, *args, **kwargs): """ Delegate a warning call to the underlying logger. """ self.log(WARNING, msg, *args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Delegate an error call to the underlying logger. """ self.log(ERROR, msg, *args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Delegate an exception call to the underlying logger. """ self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Delegate a critical call to the underlying logger. """ self.log(CRITICAL, msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Delegate a log call to the underlying logger, after adding contextual information from this adapter instance. """ if self.isEnabledFor(level): msg, kwargs = self.process(msg, kwargs) self.logger.log(level, msg, *args, **kwargs) def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ return self.logger.isEnabledFor(level) def setLevel(self, level): """ Set the specified level on the underlying logger. """ self.logger.setLevel(level) def getEffectiveLevel(self): """ Get the effective level for the underlying logger. """ return self.logger.getEffectiveLevel() def hasHandlers(self): """ See if the underlying logger has any handlers. """ return self.logger.hasHandlers() def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): """ Low-level log implementation, proxied to allow nested logger adapters. """ return self.logger._log( level, msg, args, exc_info=exc_info, extra=extra, stack_info=stack_info, ) @property def manager(self): return self.logger.manager @manager.setter def manager(self, value): self.logger.manager = value @property def name(self): return self.logger.name def __repr__(self): logger = self.logger level = getLevelName(logger.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level) root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) #--------------------------------------------------------------------------- # Configuration classes and functions #--------------------------------------------------------------------------- def basicConfig(**kwargs): """ Do basic configuration for the logging system. This function does nothing if the root logger already has handlers configured, unless the keyword argument *force* is set to ``True``. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package. The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger. A number of optional keyword arguments may be specified, which can alter the default behaviour. filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler. filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format Use the specified format string for the handler. datefmt Use the specified date/time format. style If a format string is specified, use this to specify the type of format string (possible values '%', '{', '$', for %-formatting, :meth:`str.format` and :class:`string.Template` - defaults to '%'). level Set the root logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored. handlers If specified, this should be an iterable of already created handlers, which will be added to the root handler. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function. force If this keyword is specified as true, any existing handlers attached to the root logger are removed and closed, before carrying out the configuration as specified by the other arguments. Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed. .. versionchanged:: 3.8 Added the ``force`` parameter. .. versionchanged:: 3.2 Added the ``style`` parameter. .. versionchanged:: 3.3 Added the ``handlers`` parameter. A ``ValueError`` is now thrown for incompatible arguments (e.g. ``handlers`` specified together with ``filename``/``filemode``, or ``filename``/``filemode`` specified together with ``stream``, or ``handlers`` specified together with ``stream``. """ # Add thread safety in case someone mistakenly calls # basicConfig() from multiple threads _acquireLock() try: force = kwargs.pop('force', False) if force: for h in root.handlers[:]: root.removeHandler(h) h.close() if len(root.handlers) == 0: handlers = kwargs.pop("handlers", None) if handlers is None: if "stream" in kwargs and "filename" in kwargs: raise ValueError("'stream' and 'filename' should not be " "specified together") else: if "stream" in kwargs or "filename" in kwargs: raise ValueError("'stream' or 'filename' should not be " "specified together with 'handlers'") if handlers is None: filename = kwargs.pop("filename", None) mode = kwargs.pop("filemode", 'a') if filename: h = FileHandler(filename, mode) else: stream = kwargs.pop("stream", None) h = StreamHandler(stream) handlers = [h] dfs = kwargs.pop("datefmt", None) style = kwargs.pop("style", '%') if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) fs = kwargs.pop("format", _STYLES[style][1]) fmt = Formatter(fs, dfs, style) for h in handlers: if h.formatter is None: h.setFormatter(fmt) root.addHandler(h) level = kwargs.pop("level", None) if level is not None: root.setLevel(level) if kwargs: keys = ', '.join(kwargs.keys()) raise ValueError('Unrecognised argument(s): %s' % keys) finally: _releaseLock() #--------------------------------------------------------------------------- # Utility functions at module level. # Basically delegate everything to the root logger. #--------------------------------------------------------------------------- def getLogger(name=None): """ Return a logger with the specified name, creating it if necessary. If no name is specified, return the root logger. """ if name: return Logger.manager.getLogger(name) else: return root def critical(msg, *args, **kwargs): """ Log a message with severity 'CRITICAL' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.critical(msg, *args, **kwargs) fatal = critical def error(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.error(msg, *args, **kwargs) def exception(msg, *args, exc_info=True, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. If the logger has no handlers, basicConfig() is called to add a console handler with a pre-defined format. """ error(msg, *args, exc_info=exc_info, **kwargs) def warning(msg, *args, **kwargs): """ Log a message with severity 'WARNING' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.warning(msg, *args, **kwargs) def warn(msg, *args, **kwargs): warnings.warn("The 'warn' function is deprecated, " "use 'warning' instead", DeprecationWarning, 2) warning(msg, *args, **kwargs) def info(msg, *args, **kwargs): """ Log a message with severity 'INFO' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.info(msg, *args, **kwargs) def debug(msg, *args, **kwargs): """ Log a message with severity 'DEBUG' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.debug(msg, *args, **kwargs) def log(level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.log(level, msg, *args, **kwargs) def disable(level=CRITICAL): """ Disable all logging calls of severity 'level' and below. """ root.manager.disable = level root.manager._clear_cache() def shutdown(handlerList=_handlerList): """ Perform any cleanup actions in the logging system (e.g. flushing buffers). Should be called at application exit. """ for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: h = wr() if h: try: h.acquire() h.flush() h.close() except (OSError, ValueError): # Ignore errors which might be caused # because handlers have been closed but # references to them are still around at # application exit. pass finally: h.release() except: # ignore everything, as we're shutting down if raiseExceptions: raise #else, swallow #Let's try and shutdown automatically on application exit... import atexit atexit.register(shutdown) # Null handler class NullHandler(Handler): """ This handler does nothing. It's intended to be used to avoid the "No handlers could be found for logger XXX" one-off warning. This is important for library code, which may contain code to log events. If a user of the library does not configure logging, the one-off warning might be produced; to avoid this, the library developer simply needs to instantiate a NullHandler and add it to the top-level logger of the library module or package. """ def handle(self, record): """Stub.""" def emit(self, record): """Stub.""" def createLock(self): self.lock = None # Warnings integration _warnings_showwarning = None def _showwarning(message, category, filename, lineno, file=None, line=None): """ Implementation of showwarnings which redirects to logging, which will first check to see if the file parameter is None. If a file is specified, it will delegate to the original warnings implementation of showwarning. Otherwise, it will call warnings.formatwarning and will log the resulting string to a warnings logger named "py.warnings" with level logging.WARNING. """ if file is not None: if _warnings_showwarning is not None: _warnings_showwarning(message, category, filename, lineno, file, line) else: s = warnings.formatwarning(message, category, filename, lineno, line) logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) logger.warning("%s", s) def captureWarnings(capture): """ If capture is true, redirect all warnings to the logging package. If capture is False, ensure that warnings are not redirected to logging but to their original destinations. """ global _warnings_showwarning if capture: if _warnings_showwarning is None: _warnings_showwarning = warnings.showwarning warnings.showwarning = _showwarning else: if _warnings_showwarning is not None: warnings.showwarning = _warnings_showwarning _warnings_showwarning = None usr/lib64/python3.6/encodings/__init__.py000064400000013012152346572220014134 0ustar00""" Standard "encodings" Package Standard Python encoding modules are stored in this package directory. Codec modules must have names corresponding to normalized encoding names as defined in the normalize_encoding() function below, e.g. 'utf-8' must be implemented by the module 'utf_8.py'. Each codec module must export the following interface: * getregentry() -> codecs.CodecInfo object The getregentry() API must return a CodecInfo object with encoder, decoder, incrementalencoder, incrementaldecoder, streamwriter and streamreader atttributes which adhere to the Python Codec Interface Standard. In addition, a module may optionally also define the following APIs which are then used by the package's codec search function: * getaliases() -> sequence of encoding name strings to use as aliases Alias names returned by getaliases() must be normalized encoding names as defined by normalize_encoding(). Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" import codecs import sys from . import aliases _cache = {} _unknown = '--unknown--' _import_tail = ['*'] _aliases = aliases.aliases class CodecRegistryError(LookupError, SystemError): pass def normalize_encoding(encoding): """ Normalize an encoding name. Normalization works as follows: all non-alphanumeric characters except the dot used for Python package names are collapsed and replaced with a single underscore, e.g. ' -;#' becomes '_'. Leading and trailing underscores are removed. Note that encoding names should be ASCII only; if they do use non-ASCII characters, these must be Latin-1 compatible. """ if isinstance(encoding, bytes): encoding = str(encoding, "ascii") chars = [] punct = False for c in encoding: if c.isalnum() or c == '.': if punct and chars: chars.append('_') chars.append(c) punct = False else: punct = True return ''.join(chars) def search_function(encoding): # Cache lookup entry = _cache.get(encoding, _unknown) if entry is not _unknown: return entry # Import the module: # # First try to find an alias for the normalized encoding # name and lookup the module using the aliased name, then try to # lookup the module using the standard import scheme, i.e. first # try in the encodings package, then at top-level. # norm_encoding = normalize_encoding(encoding) aliased_encoding = _aliases.get(norm_encoding) or \ _aliases.get(norm_encoding.replace('.', '_')) if aliased_encoding is not None: modnames = [aliased_encoding, norm_encoding] else: modnames = [norm_encoding] for modname in modnames: if not modname or '.' in modname: continue try: # Import is absolute to prevent the possibly malicious import of a # module with side-effects that is not in the 'encodings' package. mod = __import__('encodings.' + modname, fromlist=_import_tail, level=0) except ImportError: # ImportError may occur because 'encodings.(modname)' does not exist, # or because it imports a name that does not exist (see mbcs and oem) pass else: break else: mod = None try: getregentry = mod.getregentry except AttributeError: # Not a codec module mod = None if mod is None: # Cache misses _cache[encoding] = None return None # Now ask the module for the registry entry entry = getregentry() if not isinstance(entry, codecs.CodecInfo): if not 4 <= len(entry) <= 7: raise CodecRegistryError('module "%s" (%s) failed to register' % (mod.__name__, mod.__file__)) if not callable(entry[0]) or not callable(entry[1]) or \ (entry[2] is not None and not callable(entry[2])) or \ (entry[3] is not None and not callable(entry[3])) or \ (len(entry) > 4 and entry[4] is not None and not callable(entry[4])) or \ (len(entry) > 5 and entry[5] is not None and not callable(entry[5])): raise CodecRegistryError('incompatible codecs in module "%s" (%s)' % (mod.__name__, mod.__file__)) if len(entry)<7 or entry[6] is None: entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],) entry = codecs.CodecInfo(*entry) # Cache the codec registry entry _cache[encoding] = entry # Register its aliases (without overwriting previously registered # aliases) try: codecaliases = mod.getaliases() except AttributeError: pass else: for alias in codecaliases: if alias not in _aliases: _aliases[alias] = modname # Return the registry entry return entry # Register the search_function in the Python codec registry codecs.register(search_function) if sys.platform == 'win32': def _alias_mbcs(encoding): try: import _bootlocale if encoding == _bootlocale.getpreferredencoding(False): import encodings.mbcs return encodings.mbcs.getregentry() except ImportError: # Imports may fail while we are shutting down pass codecs.register(_alias_mbcs) usr/lib64/python2.7/importlib/__init__.py000064400000002457152346573150014202 0ustar00"""Backport of importlib.import_module from 3.x.""" # While not critical (and in no way guaranteed!), it would be nice to keep this # code compatible with Python 2.3. import sys def _resolve_name(name, package, level): """Return the absolute name of the module to be imported.""" if not hasattr(package, 'rindex'): raise ValueError("'package' not set to a string") dot = len(package) for x in xrange(level, 1, -1): try: dot = package.rindex('.', 0, dot) except ValueError: raise ValueError("attempted relative import beyond top-level " "package") return "%s.%s" % (package[:dot], name) def import_module(name, package=None): """Import a module. The 'package' argument is required when performing a relative import. It specifies the package to use as the anchor point from which to resolve the relative import to an absolute import. """ if name.startswith('.'): if not package: raise TypeError("relative imports require the 'package' argument") level = 0 for character in name: if character != '.': break level += 1 name = _resolve_name(name[level:], package, level) __import__(name) return sys.modules[name] usr/lib64/python3.6/lib2to3/pgen2/__init__.py000064400000000217152346576130014463 0ustar00# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """The pgen2 package.""" lib64/python3.6/http/__init__.py000064400000013501152346613640012336 0ustar00from enum import IntEnum __all__ = ['HTTPStatus'] class HTTPStatus(IntEnum): """HTTP status codes and reason phrases Status codes from the following RFCs are all observed: * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 * RFC 6585: Additional HTTP Status Codes * RFC 3229: Delta encoding in HTTP * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 * RFC 5842: Binding Extensions to WebDAV * RFC 7238: Permanent Redirect * RFC 2295: Transparent Content Negotiation in HTTP * RFC 2774: An HTTP Extension Framework """ def __new__(cls, value, phrase, description=''): obj = int.__new__(cls, value) obj._value_ = value obj.phrase = phrase obj.description = description return obj # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', 'Switching to new protocol; obey Upgrade header') PROCESSING = 102, 'Processing' # success OK = 200, 'OK', 'Request fulfilled, document follows' CREATED = 201, 'Created', 'Document created, URL follows' ACCEPTED = (202, 'Accepted', 'Request accepted, processing continues off-line') NON_AUTHORITATIVE_INFORMATION = (203, 'Non-Authoritative Information', 'Request fulfilled from cache') NO_CONTENT = 204, 'No Content', 'Request fulfilled, nothing follows' RESET_CONTENT = 205, 'Reset Content', 'Clear input form for further input' PARTIAL_CONTENT = 206, 'Partial Content', 'Partial content follows' MULTI_STATUS = 207, 'Multi-Status' ALREADY_REPORTED = 208, 'Already Reported' IM_USED = 226, 'IM Used' # redirection MULTIPLE_CHOICES = (300, 'Multiple Choices', 'Object has several resources -- see URI list') MOVED_PERMANENTLY = (301, 'Moved Permanently', 'Object moved permanently -- see URI list') FOUND = 302, 'Found', 'Object moved temporarily -- see URI list' SEE_OTHER = 303, 'See Other', 'Object moved -- see Method and URL list' NOT_MODIFIED = (304, 'Not Modified', 'Document has not changed since given time') USE_PROXY = (305, 'Use Proxy', 'You must use proxy specified in Location to access this resource') TEMPORARY_REDIRECT = (307, 'Temporary Redirect', 'Object moved temporarily -- see URI list') PERMANENT_REDIRECT = (308, 'Permanent Redirect', 'Object moved temporarily -- see URI list') # client error BAD_REQUEST = (400, 'Bad Request', 'Bad request syntax or unsupported method') UNAUTHORIZED = (401, 'Unauthorized', 'No permission -- see authorization schemes') PAYMENT_REQUIRED = (402, 'Payment Required', 'No payment -- see charging schemes') FORBIDDEN = (403, 'Forbidden', 'Request forbidden -- authorization will not help') NOT_FOUND = (404, 'Not Found', 'Nothing matches the given URI') METHOD_NOT_ALLOWED = (405, 'Method Not Allowed', 'Specified method is invalid for this resource') NOT_ACCEPTABLE = (406, 'Not Acceptable', 'URI not available in preferred format') PROXY_AUTHENTICATION_REQUIRED = (407, 'Proxy Authentication Required', 'You must authenticate with this proxy before proceeding') REQUEST_TIMEOUT = (408, 'Request Timeout', 'Request timed out; try again later') CONFLICT = 409, 'Conflict', 'Request conflict' GONE = (410, 'Gone', 'URI no longer exists and has been permanently removed') LENGTH_REQUIRED = (411, 'Length Required', 'Client must specify Content-Length') PRECONDITION_FAILED = (412, 'Precondition Failed', 'Precondition in headers is false') REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large', 'Entity is too large') REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long', 'URI is too long') UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type', 'Entity body in unsupported format') REQUESTED_RANGE_NOT_SATISFIABLE = (416, 'Requested Range Not Satisfiable', 'Cannot satisfy request range') EXPECTATION_FAILED = (417, 'Expectation Failed', 'Expect condition could not be satisfied') UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity' LOCKED = 423, 'Locked' FAILED_DEPENDENCY = 424, 'Failed Dependency' UPGRADE_REQUIRED = 426, 'Upgrade Required' PRECONDITION_REQUIRED = (428, 'Precondition Required', 'The origin server requires the request to be conditional') TOO_MANY_REQUESTS = (429, 'Too Many Requests', 'The user has sent too many requests in ' 'a given amount of time ("rate limiting")') REQUEST_HEADER_FIELDS_TOO_LARGE = (431, 'Request Header Fields Too Large', 'The server is unwilling to process the request because its header ' 'fields are too large') # server errors INTERNAL_SERVER_ERROR = (500, 'Internal Server Error', 'Server got itself in trouble') NOT_IMPLEMENTED = (501, 'Not Implemented', 'Server does not support this operation') BAD_GATEWAY = (502, 'Bad Gateway', 'Invalid responses from another server/proxy') SERVICE_UNAVAILABLE = (503, 'Service Unavailable', 'The server cannot process the request due to a high load') GATEWAY_TIMEOUT = (504, 'Gateway Timeout', 'The gateway server did not receive a timely response') HTTP_VERSION_NOT_SUPPORTED = (505, 'HTTP Version Not Supported', 'Cannot fulfill request') VARIANT_ALSO_NEGOTIATES = 506, 'Variant Also Negotiates' INSUFFICIENT_STORAGE = 507, 'Insufficient Storage' LOOP_DETECTED = 508, 'Loop Detected' NOT_EXTENDED = 510, 'Not Extended' NETWORK_AUTHENTICATION_REQUIRED = (511, 'Network Authentication Required', 'The client needs to authenticate to gain network access') usr/lib64/python2.7/test/__init__.py000064400000000057152346641130013144 0ustar00# Dummy file to make this directory a package. usr/lib64/python3.12/re/__init__.py000064400000037673152346663500012673 0ustar00# # Secret Labs' Regular Expression Engine # # re-compatible interface for the sre matching engine # # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # # This version of the SRE library can be redistributed under CNRI's # Python 1.6 license. For any other use, please contact Secret Labs # AB (info@pythonware.com). # # Portions of this engine have been developed in cooperation with # CNRI. Hewlett-Packard provided funding for 1.6 integration and # other compatibility work. # r"""Support for regular expressions (RE). This module provides regular expression matching operations similar to those found in Perl. It supports both 8-bit and Unicode strings; both the pattern and the strings being processed can contain null bytes and characters outside the US ASCII range. Regular expressions can contain both special and ordinary characters. Most ordinary characters, like "A", "a", or "0", are the simplest regular expressions; they simply match themselves. You can concatenate ordinary characters, so last matches the string 'last'. The special characters are: "." Matches any character except a newline. "^" Matches the start of the string. "$" Matches the end of the string or just before the newline at the end of the string. "*" Matches 0 or more (greedy) repetitions of the preceding RE. Greedy means that it will match as many repetitions as possible. "+" Matches 1 or more (greedy) repetitions of the preceding RE. "?" Matches 0 or 1 (greedy) of the preceding RE. *?,+?,?? Non-greedy versions of the previous three special characters. {m,n} Matches from m to n repetitions of the preceding RE. {m,n}? Non-greedy version of the above. "\\" Either escapes special characters or signals a special sequence. [] Indicates a set of characters. A "^" as the first character indicates a complementing set. "|" A|B, creates an RE that will match either A or B. (...) Matches the RE inside the parentheses. The contents can be retrieved or matched later in the string. (?aiLmsux) The letters set the corresponding flags defined below. (?:...) Non-grouping version of regular parentheses. (?P...) The substring matched by the group is accessible by name. (?P=name) Matches the text matched earlier by the group named name. (?#...) A comment; ignored. (?=...) Matches if ... matches next, but doesn't consume the string. (?!...) Matches if ... doesn't match next. (?<=...) Matches if preceded by ... (must be fixed length). (?= _MAXCACHE: # Drop the least recently used item. # next(iter(_cache)) is known to have linear amortized time, # but it is used here to avoid a dependency from using OrderedDict. # For the small _MAXCACHE value it doesn't make much of a difference. try: del _cache[next(iter(_cache))] except (StopIteration, RuntimeError, KeyError): pass # Append to the end. _cache[key] = p if len(_cache2) >= _MAXCACHE2: # Drop the oldest item. try: del _cache2[next(iter(_cache2))] except (StopIteration, RuntimeError, KeyError): pass _cache2[key] = p return p @functools.lru_cache(_MAXCACHE) def _compile_template(pattern, repl): # internal: compile replacement pattern return _sre.template(pattern, _parser.parse_template(repl, pattern)) # register myself for pickling import copyreg def _pickle(p): return _compile, (p.pattern, p.flags) copyreg.pickle(Pattern, _pickle, _compile) # -------------------------------------------------------------------- # experimental stuff (see python-dev discussions for details) class Scanner: def __init__(self, lexicon, flags=0): from ._constants import BRANCH, SUBPATTERN if isinstance(flags, RegexFlag): flags = flags.value self.lexicon = lexicon # combine phrases into a compound pattern p = [] s = _parser.State() s.flags = flags for phrase, action in lexicon: gid = s.opengroup() p.append(_parser.SubPattern(s, [ (SUBPATTERN, (gid, 0, 0, _parser.parse(phrase, flags))), ])) s.closegroup(gid, p[-1]) p = _parser.SubPattern(s, [(BRANCH, (None, p))]) self.scanner = _compiler.compile(p) def scan(self, string): result = [] append = result.append match = self.scanner.scanner(string).match i = 0 while True: m = match() if not m: break j = m.end() if i == j: break action = self.lexicon[m.lastindex-1][1] if callable(action): self.match = m action = action(self, m.group()) if action is not None: append(action) i = j return result, string[i:] usr/lib64/python3.6/curses/__init__.py000064400000006446152346671450013511 0ustar00"""curses The main package for curses support for Python. Normally used by importing the package, and perhaps a particular module inside it. import curses from curses import textpad curses.initscr() ... """ from _curses import * import os as _os import sys as _sys # Some constants, most notably the ACS_* ones, are only added to the C # _curses module's dictionary after initscr() is called. (Some # versions of SGI's curses don't define values for those constants # until initscr() has been called.) This wrapper function calls the # underlying C initscr(), and then copies the constants from the # _curses module to the curses package's dictionary. Don't do 'from # curses import *' if you'll be needing the ACS_* constants. def initscr(): import _curses, curses # we call setupterm() here because it raises an error # instead of calling exit() in error cases. setupterm(term=_os.environ.get("TERM", "unknown"), fd=_sys.__stdout__.fileno()) stdscr = _curses.initscr() for key, value in _curses.__dict__.items(): if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): setattr(curses, key, value) return stdscr # This is a similar wrapper for start_color(), which adds the COLORS and # COLOR_PAIRS variables which are only available after start_color() is # called. def start_color(): import _curses, curses retval = _curses.start_color() if hasattr(_curses, 'COLORS'): curses.COLORS = _curses.COLORS if hasattr(_curses, 'COLOR_PAIRS'): curses.COLOR_PAIRS = _curses.COLOR_PAIRS return retval # Import Python has_key() implementation if _curses doesn't contain has_key() try: has_key except NameError: from .has_key import has_key # Wrapper for the entire curses-based application. Runs a function which # should be the rest of your curses-based application. If the application # raises an exception, wrapper() will restore the terminal to a sane state so # you can read the resulting traceback. def wrapper(func, *args, **kwds): """Wrapper function that initializes curses and calls another function, restoring normal keyboard/screen behavior on error. The callable object 'func' is then passed the main window 'stdscr' as its first argument, followed by any other arguments passed to wrapper(). """ try: # Initialize curses stdscr = initscr() # Turn off echoing of keys, and enter cbreak mode, # where no buffering is performed on keyboard input noecho() cbreak() # In keypad mode, escape sequences for special keys # (like the cursor keys) will be interpreted and # a special value like curses.KEY_LEFT will be returned stdscr.keypad(1) # Start color, too. Harmless if the terminal doesn't have # color; user can test with has_color() later on. The try/catch # works around a minor bit of over-conscientiousness in the curses # module -- the error return from C start_color() is ignorable. try: start_color() except: pass return func(stdscr, *args, **kwds) finally: # Set everything back to normal if 'stdscr' in locals(): stdscr.keypad(0) echo() nocbreak() endwin() usr/lib64/python3.8/encodings/__init__.py000064400000012724152346672600014152 0ustar00""" Standard "encodings" Package Standard Python encoding modules are stored in this package directory. Codec modules must have names corresponding to normalized encoding names as defined in the normalize_encoding() function below, e.g. 'utf-8' must be implemented by the module 'utf_8.py'. Each codec module must export the following interface: * getregentry() -> codecs.CodecInfo object The getregentry() API must return a CodecInfo object with encoder, decoder, incrementalencoder, incrementaldecoder, streamwriter and streamreader attributes which adhere to the Python Codec Interface Standard. In addition, a module may optionally also define the following APIs which are then used by the package's codec search function: * getaliases() -> sequence of encoding name strings to use as aliases Alias names returned by getaliases() must be normalized encoding names as defined by normalize_encoding(). Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" import codecs import sys from . import aliases _cache = {} _unknown = '--unknown--' _import_tail = ['*'] _aliases = aliases.aliases class CodecRegistryError(LookupError, SystemError): pass def normalize_encoding(encoding): """ Normalize an encoding name. Normalization works as follows: all non-alphanumeric characters except the dot used for Python package names are collapsed and replaced with a single underscore, e.g. ' -;#' becomes '_'. Leading and trailing underscores are removed. Note that encoding names should be ASCII only. """ if isinstance(encoding, bytes): encoding = str(encoding, "ascii") chars = [] punct = False for c in encoding: if c.isalnum() or c == '.': if punct and chars: chars.append('_') chars.append(c) punct = False else: punct = True return ''.join(chars) def search_function(encoding): # Cache lookup entry = _cache.get(encoding, _unknown) if entry is not _unknown: return entry # Import the module: # # First try to find an alias for the normalized encoding # name and lookup the module using the aliased name, then try to # lookup the module using the standard import scheme, i.e. first # try in the encodings package, then at top-level. # norm_encoding = normalize_encoding(encoding) aliased_encoding = _aliases.get(norm_encoding) or \ _aliases.get(norm_encoding.replace('.', '_')) if aliased_encoding is not None: modnames = [aliased_encoding, norm_encoding] else: modnames = [norm_encoding] for modname in modnames: if not modname or '.' in modname: continue try: # Import is absolute to prevent the possibly malicious import of a # module with side-effects that is not in the 'encodings' package. mod = __import__('encodings.' + modname, fromlist=_import_tail, level=0) except ImportError: # ImportError may occur because 'encodings.(modname)' does not exist, # or because it imports a name that does not exist (see mbcs and oem) pass else: break else: mod = None try: getregentry = mod.getregentry except AttributeError: # Not a codec module mod = None if mod is None: # Cache misses _cache[encoding] = None return None # Now ask the module for the registry entry entry = getregentry() if not isinstance(entry, codecs.CodecInfo): if not 4 <= len(entry) <= 7: raise CodecRegistryError('module "%s" (%s) failed to register' % (mod.__name__, mod.__file__)) if not callable(entry[0]) or not callable(entry[1]) or \ (entry[2] is not None and not callable(entry[2])) or \ (entry[3] is not None and not callable(entry[3])) or \ (len(entry) > 4 and entry[4] is not None and not callable(entry[4])) or \ (len(entry) > 5 and entry[5] is not None and not callable(entry[5])): raise CodecRegistryError('incompatible codecs in module "%s" (%s)' % (mod.__name__, mod.__file__)) if len(entry)<7 or entry[6] is None: entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],) entry = codecs.CodecInfo(*entry) # Cache the codec registry entry _cache[encoding] = entry # Register its aliases (without overwriting previously registered # aliases) try: codecaliases = mod.getaliases() except AttributeError: pass else: for alias in codecaliases: if alias not in _aliases: _aliases[alias] = modname # Return the registry entry return entry # Register the search_function in the Python codec registry codecs.register(search_function) if sys.platform == 'win32': def _alias_mbcs(encoding): try: import _winapi ansi_code_page = "cp%s" % _winapi.GetACP() if encoding == ansi_code_page: import encodings.mbcs return encodings.mbcs.getregentry() except ImportError: # Imports may fail while we are shutting down pass codecs.register(_alias_mbcs) lib64/python3.6/site-packages/cffi/__init__.py000064400000000737152346702360015013 0ustar00__all__ = ['FFI', 'VerificationError', 'VerificationMissing', 'CDefError', 'FFIError'] from .api import FFI from .error import CDefError, FFIError, VerificationError, VerificationMissing __version__ = "1.11.5" __version_info__ = (1, 11, 5) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ # if nothing is clearly incompatible. __version_verifier_modules__ = "0.8.6" usr/lib64/python3.6/concurrent/__init__.py000064400000000046152346723760014357 0ustar00# This directory is a Python package. usr/lib64/python3.8/concurrent/__init__.py000064400000000046152346724030014350 0ustar00# This directory is a Python package. usr/lib/python3.6/site-packages/pycriu/images/__init__.py000064400000000211152346772250017313 0ustar00import sys, os sys.path.append(os.path.dirname(os.path.realpath(__file__))) from .magic import * from .images import * from .pb import * usr/lib/python3.6/site-packages/procfs/__init__.py000075500000000620152347010550016023 0ustar00#! /usr/bin/python3 # -*- python -*- # -*- coding: utf-8 -*- # SPDX-License-Identifier: GPL-2.0-only # # Copyright (C) 2008, 2009 Red Hat, Inc. # """ Copyright (c) 2008, 2009 Red Hat Inc. Abstractions to extract information from the Linux kernel /proc files. """ __author__ = "Arnaldo Carvalho de Melo " __license__ = "GPLv2 License" from .procfs import * from .utilist import * usr/lib64/python3.12/html/__init__.py000064400000011247152347012700013205 0ustar00""" General functions for HTML manipulation. """ import re as _re from html.entities import html5 as _html5 __all__ = ['escape', 'unescape'] def escape(s, quote=True): """ Replace special characters "&", "<" and ">" to HTML-safe sequences. If the optional flag quote is true (the default), the quotation mark characters, both double quote (") and single quote (') characters are also translated. """ s = s.replace("&", "&") # Must be done first! s = s.replace("<", "<") s = s.replace(">", ">") if quote: s = s.replace('"', """) s = s.replace('\'', "'") return s # see https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state _invalid_charrefs = { 0x00: '\ufffd', # REPLACEMENT CHARACTER 0x0d: '\r', # CARRIAGE RETURN 0x80: '\u20ac', # EURO SIGN 0x81: '\x81', # 0x82: '\u201a', # SINGLE LOW-9 QUOTATION MARK 0x83: '\u0192', # LATIN SMALL LETTER F WITH HOOK 0x84: '\u201e', # DOUBLE LOW-9 QUOTATION MARK 0x85: '\u2026', # HORIZONTAL ELLIPSIS 0x86: '\u2020', # DAGGER 0x87: '\u2021', # DOUBLE DAGGER 0x88: '\u02c6', # MODIFIER LETTER CIRCUMFLEX ACCENT 0x89: '\u2030', # PER MILLE SIGN 0x8a: '\u0160', # LATIN CAPITAL LETTER S WITH CARON 0x8b: '\u2039', # SINGLE LEFT-POINTING ANGLE QUOTATION MARK 0x8c: '\u0152', # LATIN CAPITAL LIGATURE OE 0x8d: '\x8d', # 0x8e: '\u017d', # LATIN CAPITAL LETTER Z WITH CARON 0x8f: '\x8f', # 0x90: '\x90', # 0x91: '\u2018', # LEFT SINGLE QUOTATION MARK 0x92: '\u2019', # RIGHT SINGLE QUOTATION MARK 0x93: '\u201c', # LEFT DOUBLE QUOTATION MARK 0x94: '\u201d', # RIGHT DOUBLE QUOTATION MARK 0x95: '\u2022', # BULLET 0x96: '\u2013', # EN DASH 0x97: '\u2014', # EM DASH 0x98: '\u02dc', # SMALL TILDE 0x99: '\u2122', # TRADE MARK SIGN 0x9a: '\u0161', # LATIN SMALL LETTER S WITH CARON 0x9b: '\u203a', # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 0x9c: '\u0153', # LATIN SMALL LIGATURE OE 0x9d: '\x9d', # 0x9e: '\u017e', # LATIN SMALL LETTER Z WITH CARON 0x9f: '\u0178', # LATIN CAPITAL LETTER Y WITH DIAERESIS } _invalid_codepoints = { # 0x0001 to 0x0008 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, # 0x000E to 0x001F 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, # 0x007F to 0x009F 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, # 0xFDD0 to 0xFDEF 0xfdd0, 0xfdd1, 0xfdd2, 0xfdd3, 0xfdd4, 0xfdd5, 0xfdd6, 0xfdd7, 0xfdd8, 0xfdd9, 0xfdda, 0xfddb, 0xfddc, 0xfddd, 0xfdde, 0xfddf, 0xfde0, 0xfde1, 0xfde2, 0xfde3, 0xfde4, 0xfde5, 0xfde6, 0xfde7, 0xfde8, 0xfde9, 0xfdea, 0xfdeb, 0xfdec, 0xfded, 0xfdee, 0xfdef, # others 0xb, 0xfffe, 0xffff, 0x1fffe, 0x1ffff, 0x2fffe, 0x2ffff, 0x3fffe, 0x3ffff, 0x4fffe, 0x4ffff, 0x5fffe, 0x5ffff, 0x6fffe, 0x6ffff, 0x7fffe, 0x7ffff, 0x8fffe, 0x8ffff, 0x9fffe, 0x9ffff, 0xafffe, 0xaffff, 0xbfffe, 0xbffff, 0xcfffe, 0xcffff, 0xdfffe, 0xdffff, 0xefffe, 0xeffff, 0xffffe, 0xfffff, 0x10fffe, 0x10ffff } def _replace_charref(s): s = s.group(1) if s[0] == '#': # numeric charref if s[1] in 'xX': num = int(s[2:].rstrip(';'), 16) else: num = int(s[1:].rstrip(';')) if num in _invalid_charrefs: return _invalid_charrefs[num] if 0xD800 <= num <= 0xDFFF or num > 0x10FFFF: return '\uFFFD' if num in _invalid_codepoints: return '' return chr(num) else: # named charref if s in _html5: return _html5[s] # find the longest matching name (as defined by the standard) for x in range(len(s)-1, 1, -1): if s[:x] in _html5: return _html5[s[:x]] + s[x:] else: return '&' + s _charref = _re.compile(r'&(#[0-9]+;?' r'|#[xX][0-9a-fA-F]+;?' r'|[^\t\n\f <&#;]{1,32};?)') def unescape(s): """ Convert all named and numeric character references (e.g. >, >, &x3e;) in the string s to the corresponding unicode characters. This function uses the rules defined by the HTML 5 standard for both valid and invalid character references, and the list of HTML 5 named character references defined in html.entities.html5. """ if '&' not in s: return s return _charref.sub(_replace_charref, s) lib64/python3.6/logging/__init__.py000064400000213145152347061610013006 0ustar00# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, # provided that the above copyright notice appear in all copies and that # both that copyright notice and this permission notice appear in # supporting documentation, and that the name of Vinay Sajip # not be used in advertising or publicity pertaining to distribution # of the software without specific, written prior permission. # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import sys, os, time, io, traceback, warnings, weakref, collections from string import Template __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', 'lastResort', 'raiseExceptions'] try: import threading except ImportError: #pragma: no cover threading = None __author__ = "Vinay Sajip " __status__ = "production" # The following module attributes are no longer updated. __version__ = "0.5.1.2" __date__ = "07 February 2010" #--------------------------------------------------------------------------- # Miscellaneous module data #--------------------------------------------------------------------------- # #_startTime is used as the base when calculating the relative time of events # _startTime = time.time() # #raiseExceptions is used to see if exceptions during handling should be #propagated # raiseExceptions = True # # If you don't want threading information in the log, set this to zero # logThreads = True # # If you don't want multiprocessing information in the log, set this to zero # logMultiprocessing = True # # If you don't want process information in the log, set this to zero # logProcesses = True #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- # # Default levels and level names, these can be replaced with any positive set # of values having corresponding names. There is a pseudo-level, NOTSET, which # is only really there as a lower limit for user-defined levels. Handlers and # loggers are initialized with NOTSET so that they will log all messages, even # at user-defined levels. # CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 _levelToName = { CRITICAL: 'CRITICAL', ERROR: 'ERROR', WARNING: 'WARNING', INFO: 'INFO', DEBUG: 'DEBUG', NOTSET: 'NOTSET', } _nameToLevel = { 'CRITICAL': CRITICAL, 'FATAL': FATAL, 'ERROR': ERROR, 'WARN': WARNING, 'WARNING': WARNING, 'INFO': INFO, 'DEBUG': DEBUG, 'NOTSET': NOTSET, } def getLevelName(level): """ Return the textual representation of logging level 'level'. If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, INFO, DEBUG) then you get the corresponding string. If you have associated levels with names using addLevelName then the name you have associated with 'level' is returned. If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned. Otherwise, the string "Level %s" % level is returned. """ # See Issues #22386, #27937 and #29220 for why it's this way result = _levelToName.get(level) if result is not None: return result result = _nameToLevel.get(level) if result is not None: return result return "Level %s" % level def addLevelName(level, levelName): """ Associate 'levelName' with 'level'. This is used when converting levels to text during message formatting. """ _acquireLock() try: #unlikely to cause an exception, but you never know... _levelToName[level] = levelName _nameToLevel[levelName] = level finally: _releaseLock() if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) else: #pragma: no cover def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise Exception except Exception: return sys.exc_info()[2].tb_frame.f_back # # _srcfile is used when walking the stack to check when we've got the first # caller stack frame, by skipping frames whose filename is that of this # module's source. It therefore should contain the filename of this module's # source file. # # Ordinarily we would use __file__ for this, but frozen modules don't always # have __file__ set, for some reason (see Issue #21736). Thus, we get the # filename from a handy code object from a function defined in this module. # (There's no particular reason for picking addLevelName.) # _srcfile = os.path.normcase(addLevelName.__code__.co_filename) # _srcfile is only used in conjunction with sys._getframe(). # To provide compatibility with older versions of Python, set _srcfile # to None if _getframe() is not available; this value will prevent # findCaller() from being called. You can also do this if you want to avoid # the overhead of fetching caller information, even when _getframe() is # available. #if not hasattr(sys, '_getframe'): # _srcfile = None def _checkLevel(level): if isinstance(level, int): rv = level elif str(level) == level: if level not in _nameToLevel: raise ValueError("Unknown level: %r" % level) rv = _nameToLevel[level] else: raise TypeError("Level not an integer or a valid string: %r" % level) return rv #--------------------------------------------------------------------------- # Thread-related stuff #--------------------------------------------------------------------------- # #_lock is used to serialize access to shared data structures in this module. #This needs to be an RLock because fileConfig() creates and configures #Handlers, and so might arbitrary user threads. Since Handler code updates the #shared dictionary _handlers, it needs to acquire the lock. But if configuring, #the lock would already have been acquired - so we need an RLock. #The same argument applies to Loggers and Manager.loggerDict. # if threading: _lock = threading.RLock() else: #pragma: no cover _lock = None def _acquireLock(): """ Acquire the module-level lock for serializing access to shared data. This should be released with _releaseLock(). """ if _lock: _lock.acquire() def _releaseLock(): """ Release the module-level lock acquired by calling _acquireLock(). """ if _lock: _lock.release() #--------------------------------------------------------------------------- # The logging record #--------------------------------------------------------------------------- class LogRecord(object): """ A LogRecord instance represents an event being logged. LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is in msg and args, which are combined using str(msg) % args to create the message field of the record. The record also includes information such as when the record was created, the source line where the logging call was made, and any exception information to be logged. """ def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None, **kwargs): """ Initialize a logging record with interesting information. """ ct = time.time() self.name = name self.msg = msg # # The following statement allows passing of a dictionary as a sole # argument, so that you can do something like # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) # Suggested by Stefan Behnel. # Note that without the test for args[0], we get a problem because # during formatting, we test to see if the arg is present using # 'if self.args:'. If the event being logged is e.g. 'Value is %d' # and if the passed arg fails 'if self.args:' then no formatting # is done. For example, logger.warning('Value is %d', 0) would log # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. # Issue #21172: a request was made to relax the isinstance check # to hasattr(args[0], '__getitem__'). However, the docs on string # formatting still seem to suggest a mapping object is required. # Thus, while not removing the isinstance check, it does now look # for collections.Mapping rather than, as before, dict. if (args and len(args) == 1 and isinstance(args[0], collections.Mapping) and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) self.levelno = level self.pathname = pathname try: self.filename = os.path.basename(pathname) self.module = os.path.splitext(self.filename)[0] except (TypeError, ValueError, AttributeError): self.filename = pathname self.module = "Unknown module" self.exc_info = exc_info self.exc_text = None # used to cache the traceback text self.stack_info = sinfo self.lineno = lineno self.funcName = func self.created = ct self.msecs = (ct - int(ct)) * 1000 self.relativeCreated = (self.created - _startTime) * 1000 if logThreads and threading: self.thread = threading.get_ident() self.threadName = threading.current_thread().name else: # pragma: no cover self.thread = None self.threadName = None if not logMultiprocessing: # pragma: no cover self.processName = None else: self.processName = 'MainProcess' mp = sys.modules.get('multiprocessing') if mp is not None: # Errors may occur if multiprocessing has not finished loading # yet - e.g. if a custom import hook causes third-party code # to run when multiprocessing calls import. See issue 8200 # for an example try: self.processName = mp.current_process().name except Exception: #pragma: no cover pass if logProcesses and hasattr(os, 'getpid'): self.process = os.getpid() else: self.process = None def __str__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) __repr__ = __str__ def getMessage(self): """ Return the message for this LogRecord. Return the message for this LogRecord after merging any user-supplied arguments with the message. """ msg = str(self.msg) if self.args: msg = msg % self.args return msg # # Determine which class to use when instantiating log records. # _logRecordFactory = LogRecord def setLogRecordFactory(factory): """ Set the factory to be used when instantiating a log record. :param factory: A callable which will be called to instantiate a log record. """ global _logRecordFactory _logRecordFactory = factory def getLogRecordFactory(): """ Return the factory to be used when instantiating a log record. """ return _logRecordFactory def makeLogRecord(dict): """ Make a LogRecord whose attributes are defined by the specified dictionary, This function is useful for converting a logging event received over a socket connection (which is sent as a dictionary) into a LogRecord instance. """ rv = _logRecordFactory(None, None, "", 0, "", (), None, None) rv.__dict__.update(dict) return rv #--------------------------------------------------------------------------- # Formatter classes and functions #--------------------------------------------------------------------------- class PercentStyle(object): default_format = '%(message)s' asctime_format = '%(asctime)s' asctime_search = '%(asctime)' def __init__(self, fmt): self._fmt = fmt or self.default_format def usesTime(self): return self._fmt.find(self.asctime_search) >= 0 def format(self, record): return self._fmt % record.__dict__ class StrFormatStyle(PercentStyle): default_format = '{message}' asctime_format = '{asctime}' asctime_search = '{asctime' def format(self, record): return self._fmt.format(**record.__dict__) class StringTemplateStyle(PercentStyle): default_format = '${message}' asctime_format = '${asctime}' asctime_search = '${asctime}' def __init__(self, fmt): self._fmt = fmt or self.default_format self._tpl = Template(self._fmt) def usesTime(self): fmt = self._fmt return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0 def format(self, record): return self._tpl.substitute(**record.__dict__) BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" _STYLES = { '%': (PercentStyle, BASIC_FORMAT), '{': (StrFormatStyle, '{levelname}:{name}:{message}'), '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), } class Formatter(object): """ Formatter instances are used to convert a LogRecord to text. Formatters need to know how a LogRecord is constructed. They are responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the the style-dependent default value, "%(message)s", "{message}", or "${message}", is used. The Formatter can be initialized with a format string which makes use of knowledge of the LogRecord attributes - e.g. the default value mentioned above makes use of the fact that the user's message and arguments are pre- formatted into a LogRecord's message attribute. Currently, the useful attributes in a LogRecord are described by: %(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted """ converter = time.localtime def __init__(self, fmt=None, datefmt=None, style='%'): """ Initialize the formatter with specified format strings. Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument. If datefmt is omitted, you get an ISO8601-like (or RFC 3339-like) format. Use a style parameter of '%', '{' or '$' to specify that you want to use one of %-formatting, :meth:`str.format` (``{}``) formatting or :class:`string.Template` formatting in your format string. .. versionchanged:: 3.2 Added the ``style`` parameter. """ if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) self._style = _STYLES[style][0](fmt) self._fmt = self._style._fmt self.datefmt = datefmt default_time_format = '%Y-%m-%d %H:%M:%S' default_msec_format = '%s,%03d' def formatTime(self, record, datefmt=None): """ Return the creation time of the specified LogRecord as formatted text. This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class. """ ct = self.converter(record.created) if datefmt: s = time.strftime(datefmt, ct) else: t = time.strftime(self.default_time_format, ct) s = self.default_msec_format % (t, record.msecs) return s def formatException(self, ei): """ Format and return the specified exception information as a string. This default implementation just uses traceback.print_exception() """ sio = io.StringIO() tb = ei[2] # See issues #9427, #1553375. Commented out for now. #if getattr(self, 'fullstack', False): # traceback.print_stack(tb.tb_frame.f_back, file=sio) traceback.print_exception(ei[0], ei[1], tb, None, sio) s = sio.getvalue() sio.close() if s[-1:] == "\n": s = s[:-1] return s def usesTime(self): """ Check if the format uses the creation time of the record. """ return self._style.usesTime() def formatMessage(self, record): return self._style.format(record) def formatStack(self, stack_info): """ This method is provided as an extension point for specialized formatting of stack information. The input data is a string as returned from a call to :func:`traceback.print_stack`, but with the last trailing newline removed. The base implementation just returns the value passed in. """ return stack_info def format(self, record): """ Format the specified record as text. The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message. """ record.message = record.getMessage() if self.usesTime(): record.asctime = self.formatTime(record, self.datefmt) s = self.formatMessage(record) if record.exc_info: # Cache the traceback text to avoid converting it multiple times # (it's constant anyway) if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: if s[-1:] != "\n": s = s + "\n" s = s + record.exc_text if record.stack_info: if s[-1:] != "\n": s = s + "\n" s = s + self.formatStack(record.stack_info) return s # # The default formatter to use when no other is specified # _defaultFormatter = Formatter() class BufferingFormatter(object): """ A formatter suitable for formatting a number of records. """ def __init__(self, linefmt=None): """ Optionally specify a formatter which will be used to format each individual record. """ if linefmt: self.linefmt = linefmt else: self.linefmt = _defaultFormatter def formatHeader(self, records): """ Return the header string for the specified records. """ return "" def formatFooter(self, records): """ Return the footer string for the specified records. """ return "" def format(self, records): """ Format the specified records and return the result as a string. """ rv = "" if len(records) > 0: rv = rv + self.formatHeader(records) for record in records: rv = rv + self.linefmt.format(record) rv = rv + self.formatFooter(records) return rv #--------------------------------------------------------------------------- # Filter classes and functions #--------------------------------------------------------------------------- class Filter(object): """ Filter instances are used to perform arbitrary filtering of LogRecords. Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed. """ def __init__(self, name=''): """ Initialize a filter. Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event. """ self.name = name self.nlen = len(name) def filter(self, record): """ Determine if the specified record is to be logged. Is the specified record to be logged? Returns 0 for no, nonzero for yes. If deemed appropriate, the record may be modified in-place. """ if self.nlen == 0: return True elif self.name == record.name: return True elif record.name.find(self.name, 0, self.nlen) != 0: return False return (record.name[self.nlen] == ".") class Filterer(object): """ A base class for loggers and handlers which allows them to share common code. """ def __init__(self): """ Initialize the list of filters to be an empty list. """ self.filters = [] def addFilter(self, filter): """ Add the specified filter to this handler. """ if not (filter in self.filters): self.filters.append(filter) def removeFilter(self, filter): """ Remove the specified filter from this handler. """ if filter in self.filters: self.filters.remove(filter) def filter(self, record): """ Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto this and the record is then dropped. Returns a zero value if a record is to be dropped, else non-zero. .. versionchanged:: 3.2 Allow filters to be just callables. """ rv = True for f in self.filters: if hasattr(f, 'filter'): result = f.filter(record) else: result = f(record) # assume callable - will raise if not if not result: rv = False break return rv #--------------------------------------------------------------------------- # Handler classes and functions #--------------------------------------------------------------------------- _handlers = weakref.WeakValueDictionary() #map of handler names to handlers _handlerList = [] # added to allow handlers to be removed in reverse of order initialized def _removeHandlerRef(wr): """ Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are # set to None. It can also be called from another thread. So we need to # pre-emptively grab the necessary globals and check if they're None, # to prevent race conditions and failures during interpreter shutdown. acquire, release, handlers = _acquireLock, _releaseLock, _handlerList if acquire and release and handlers: acquire() try: if wr in handlers: handlers.remove(wr) finally: release() def _addHandlerRef(handler): """ Add a handler to the internal cleanup list using a weak reference. """ _acquireLock() try: _handlerList.append(weakref.ref(handler, _removeHandlerRef)) finally: _releaseLock() class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. The base handler class. Acts as a placeholder which defines the Handler interface. Handlers can optionally use Formatter instances to format records as desired. By default, no formatter is specified; in this case, the 'raw' message as determined by record.message is logged. """ def __init__(self, level=NOTSET): """ Initializes the instance - basically setting the formatter to None and the filter list to empty. """ Filterer.__init__(self) self._name = None self.level = _checkLevel(level) self.formatter = None # Add the handler to the global _handlerList (for cleanup on shutdown) _addHandlerRef(self) self.createLock() def get_name(self): return self._name def set_name(self, name): _acquireLock() try: if self._name in _handlers: del _handlers[self._name] self._name = name if name: _handlers[name] = self finally: _releaseLock() name = property(get_name, set_name) def createLock(self): """ Acquire a thread lock for serializing access to the underlying I/O. """ if threading: self.lock = threading.RLock() else: #pragma: no cover self.lock = None def acquire(self): """ Acquire the I/O thread lock. """ if self.lock: self.lock.acquire() def release(self): """ Release the I/O thread lock. """ if self.lock: self.lock.release() def setLevel(self, level): """ Set the logging level of this handler. level must be an int or a str. """ self.level = _checkLevel(level) def format(self, record): """ Format the specified record. If a formatter is set, use it. Otherwise, use the default formatter for the module. """ if self.formatter: fmt = self.formatter else: fmt = _defaultFormatter return fmt.format(record) def emit(self, record): """ Do whatever it takes to actually log the specified logging record. This version is intended to be implemented by subclasses and so raises a NotImplementedError. """ raise NotImplementedError('emit must be implemented ' 'by Handler subclasses') def handle(self, record): """ Conditionally emit the specified logging record. Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns whether the filter passed the record for emission. """ rv = self.filter(record) if rv: self.acquire() try: self.emit(record) finally: self.release() return rv def setFormatter(self, fmt): """ Set the formatter for this handler. """ self.formatter = fmt def flush(self): """ Ensure all logging output has been flushed. This version does nothing and is intended to be implemented by subclasses. """ pass def close(self): """ Tidy up any resources used by the handler. This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods. """ #get the module data lock, as we're updating a shared structure. _acquireLock() try: #unlikely to raise an exception, but you never know... if self._name and self._name in _handlers: del _handlers[self._name] finally: _releaseLock() def handleError(self, record): """ Handle errors which occur during an emit() call. This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method. """ if raiseExceptions and sys.stderr: # see issue 13807 t, v, tb = sys.exc_info() try: sys.stderr.write('--- Logging error ---\n') traceback.print_exception(t, v, tb, None, sys.stderr) sys.stderr.write('Call stack:\n') # Walk the stack frame up until we're out of logging, # so as to print the calling context. frame = tb.tb_frame while (frame and os.path.dirname(frame.f_code.co_filename) == __path__[0]): frame = frame.f_back if frame: traceback.print_stack(frame, file=sys.stderr) else: # couldn't find the right stack frame, for some reason sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) # Issue 18671: output logging message and arguments try: sys.stderr.write('Message: %r\n' 'Arguments: %s\n' % (record.msg, record.args)) except Exception: sys.stderr.write('Unable to print the message and arguments' ' - possible formatting error.\nUse the' ' traceback above to help find the error.\n' ) except OSError: #pragma: no cover pass # see issue 5971 finally: del t, v, tb def __repr__(self): level = getLevelName(self.level) return '<%s (%s)>' % (self.__class__.__name__, level) class StreamHandler(Handler): """ A handler class which writes logging records, appropriately formatted, to a stream. Note that this class does not close the stream, as sys.stdout or sys.stderr may be used. """ terminator = '\n' def __init__(self, stream=None): """ Initialize the handler. If stream is not specified, sys.stderr is used. """ Handler.__init__(self) if stream is None: stream = sys.stderr self.stream = stream def flush(self): """ Flushes the stream. """ self.acquire() try: if self.stream and hasattr(self.stream, "flush"): self.stream.flush() finally: self.release() def emit(self, record): """ Emit a record. If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an 'encoding' attribute, it is used to determine how to do the output to the stream. """ try: msg = self.format(record) stream = self.stream stream.write(msg) stream.write(self.terminator) self.flush() except Exception: self.handleError(record) def __repr__(self): level = getLevelName(self.level) name = getattr(self.stream, 'name', '') if name: name += ' ' return '<%s %s(%s)>' % (self.__class__.__name__, name, level) class FileHandler(StreamHandler): """ A handler class which writes formatted logging records to disk files. """ def __init__(self, filename, mode='a', encoding=None, delay=False): """ Open the specified file and use it as the stream for logging. """ # Issue #27493: add support for Path objects to be passed in filename = os.fspath(filename) #keep the absolute path, otherwise derived classes which use this #may come a cropper when the current directory changes self.baseFilename = os.path.abspath(filename) self.mode = mode self.encoding = encoding self.delay = delay if delay: #We don't open the stream, but we still need to call the #Handler constructor to set level, formatter, lock etc. Handler.__init__(self) self.stream = None else: StreamHandler.__init__(self, self._open()) def close(self): """ Closes the stream. """ self.acquire() try: try: if self.stream: try: self.flush() finally: stream = self.stream self.stream = None if hasattr(stream, "close"): stream.close() finally: # Issue #19523: call unconditionally to # prevent a handler leak when delay is set StreamHandler.close(self) finally: self.release() def _open(self): """ Open the current base file with the (original) mode and encoding. Return the resulting stream. """ return open(self.baseFilename, self.mode, encoding=self.encoding) def emit(self, record): """ Emit a record. If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit. """ if self.stream is None: self.stream = self._open() StreamHandler.emit(self, record) def __repr__(self): level = getLevelName(self.level) return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level) class _StderrHandler(StreamHandler): """ This class is like a StreamHandler using sys.stderr, but always uses whatever sys.stderr is currently set to rather than the value of sys.stderr at handler construction time. """ def __init__(self, level=NOTSET): """ Initialize the handler. """ Handler.__init__(self, level) @property def stream(self): return sys.stderr _defaultLastResort = _StderrHandler(WARNING) lastResort = _defaultLastResort #--------------------------------------------------------------------------- # Manager classes and functions #--------------------------------------------------------------------------- class PlaceHolder(object): """ PlaceHolder instances are used in the Manager logger hierarchy to take the place of nodes for which no loggers have been defined. This class is intended for internal use only and not as part of the public API. """ def __init__(self, alogger): """ Initialize with the specified logger being a child of this placeholder. """ self.loggerMap = { alogger : None } def append(self, alogger): """ Add the specified logger as a child of this placeholder. """ if alogger not in self.loggerMap: self.loggerMap[alogger] = None # # Determine which class to use when instantiating loggers. # def setLoggerClass(klass): """ Set the class to be used when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__() """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) global _loggerClass _loggerClass = klass def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ return _loggerClass class Manager(object): """ There is [under normal circumstances] just one Manager instance, which holds the hierarchy of loggers. """ def __init__(self, rootnode): """ Initialize the manager with the root node of the logger hierarchy. """ self.root = rootnode self.disable = 0 self.emittedNoHandlerWarning = False self.loggerDict = {} self.loggerClass = None self.logRecordFactory = None def getLogger(self, name): """ Get a logger with the specified name (channel name), creating it if it doesn't yet exist. This name is a dot-separated hierarchical name, such as "a", "a.b", "a.b.c" or similar. If a PlaceHolder existed for the specified name [i.e. the logger didn't exist but a child of it did], replace it with the created logger and fix up the parent/child references which pointed to the placeholder to now point to the logger. """ rv = None if not isinstance(name, str): raise TypeError('A logger name must be a string') _acquireLock() try: if name in self.loggerDict: rv = self.loggerDict[name] if isinstance(rv, PlaceHolder): ph = rv rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupChildren(ph, rv) self._fixupParents(rv) else: rv = (self.loggerClass or _loggerClass)(name) rv.manager = self self.loggerDict[name] = rv self._fixupParents(rv) finally: _releaseLock() return rv def setLoggerClass(self, klass): """ Set the class to be used when instantiating a logger with this Manager. """ if klass != Logger: if not issubclass(klass, Logger): raise TypeError("logger not derived from logging.Logger: " + klass.__name__) self.loggerClass = klass def setLogRecordFactory(self, factory): """ Set the factory to be used when instantiating a log record with this Manager. """ self.logRecordFactory = factory def _fixupParents(self, alogger): """ Ensure that there are either loggers or placeholders all the way from the specified logger to the root of the logger hierarchy. """ name = alogger.name i = name.rfind(".") rv = None while (i > 0) and not rv: substr = name[:i] if substr not in self.loggerDict: self.loggerDict[substr] = PlaceHolder(alogger) else: obj = self.loggerDict[substr] if isinstance(obj, Logger): rv = obj else: assert isinstance(obj, PlaceHolder) obj.append(alogger) i = name.rfind(".", 0, i - 1) if not rv: rv = self.root alogger.parent = rv def _fixupChildren(self, ph, alogger): """ Ensure that children of the placeholder ph are connected to the specified logger. """ name = alogger.name namelen = len(name) for c in ph.loggerMap.keys(): #The if means ... if not c.parent.name.startswith(nm) if c.parent.name[:namelen] != name: alogger.parent = c.parent c.parent = alogger #--------------------------------------------------------------------------- # Logger classes and functions #--------------------------------------------------------------------------- class Logger(Filterer): """ Instances of the Logger class represent a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting. """ def __init__(self, name, level=NOTSET): """ Initialize the logger with a name and an optional level. """ Filterer.__init__(self) self.name = name self.level = _checkLevel(level) self.parent = None self.propagate = True self.handlers = [] self.disabled = False def setLevel(self, level): """ Set the logging level of this logger. level must be an int or a str. """ self.level = _checkLevel(level) def debug(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'DEBUG'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.debug("Houston, we have a %s", "thorny problem", exc_info=1) """ if self.isEnabledFor(DEBUG): self._log(DEBUG, msg, args, **kwargs) def info(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'INFO'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.info("Houston, we have a %s", "interesting problem", exc_info=1) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) def warning(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'WARNING'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1) """ if self.isEnabledFor(WARNING): self._log(WARNING, msg, args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'ERROR'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.error("Houston, we have a %s", "major problem", exc_info=1) """ if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Convenience method for logging an ERROR with exception information. """ self.error(msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Log 'msg % args' with severity 'CRITICAL'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.critical("Houston, we have a %s", "major disaster", exc_info=1) """ if self.isEnabledFor(CRITICAL): self._log(CRITICAL, msg, args, **kwargs) fatal = critical def log(self, level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level'. To pass exception information, use the keyword argument exc_info with a true value, e.g. logger.log(level, "We have a %s", "mysterious problem", exc_info=1) """ if not isinstance(level, int): if raiseExceptions: raise TypeError("level must be an integer") else: return if self.isEnabledFor(level): self._log(level, msg, args, **kwargs) def findCaller(self, stack_info=False): """ Find the stack frame of the caller so that we can note the source file name, line number and function name. """ f = currentframe() #On some versions of IronPython, currentframe() returns None if #IronPython isn't run with -X:Frames. if f is not None: f = f.f_back rv = "(unknown file)", 0, "(unknown function)", None while hasattr(f, "f_code"): co = f.f_code filename = os.path.normcase(co.co_filename) if filename == _srcfile: f = f.f_back continue sinfo = None if stack_info: sio = io.StringIO() sio.write('Stack (most recent call last):\n') traceback.print_stack(f, file=sio) sinfo = sio.getvalue() if sinfo[-1] == '\n': sinfo = sinfo[:-1] sio.close() rv = (co.co_filename, f.f_lineno, co.co_name, sinfo) break return rv def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None): """ A factory method which can be overridden in subclasses to create specialized LogRecords. """ rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func, sinfo) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] return rv def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): """ Low-level logging routine which creates a LogRecord and then calls all the handlers of this logger to handle the record. """ sinfo = None if _srcfile: #IronPython doesn't track Python frames, so findCaller raises an #exception on some versions of IronPython. We trap it here so that #IronPython can use logging. try: fn, lno, func, sinfo = self.findCaller(stack_info) except ValueError: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" else: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: if isinstance(exc_info, BaseException): exc_info = (type(exc_info), exc_info, exc_info.__traceback__) elif not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra, sinfo) self.handle(record) def handle(self, record): """ Call the handlers for the specified record. This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ if (not self.disabled) and self.filter(record): self.callHandlers(record) def addHandler(self, hdlr): """ Add the specified handler to this logger. """ _acquireLock() try: if not (hdlr in self.handlers): self.handlers.append(hdlr) finally: _releaseLock() def removeHandler(self, hdlr): """ Remove the specified handler from this logger. """ _acquireLock() try: if hdlr in self.handlers: self.handlers.remove(hdlr) finally: _releaseLock() def hasHandlers(self): """ See if this logger has any handlers configured. Loop through all handlers for this logger and its parents in the logger hierarchy. Return True if a handler was found, else False. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger which is checked for the existence of handlers. """ c = self rv = False while c: if c.handlers: rv = True break if not c.propagate: break else: c = c.parent return rv def callHandlers(self, record): """ Pass a record to all relevant handlers. Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called. """ c = self found = 0 while c: for hdlr in c.handlers: found = found + 1 if record.levelno >= hdlr.level: hdlr.handle(record) if not c.propagate: c = None #break out else: c = c.parent if (found == 0): if lastResort: if record.levelno >= lastResort.level: lastResort.handle(record) elif raiseExceptions and not self.manager.emittedNoHandlerWarning: sys.stderr.write("No handlers could be found for logger" " \"%s\"\n" % self.name) self.manager.emittedNoHandlerWarning = True def getEffectiveLevel(self): """ Get the effective level for this logger. Loop through this logger and its parents in the logger hierarchy, looking for a non-zero logging level. Return the first one found. """ logger = self while logger: if logger.level: return logger.level logger = logger.parent return NOTSET def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.manager.disable >= level: return False return level >= self.getEffectiveLevel() def getChild(self, suffix): """ Get a logger which is a descendant to this one. This is a convenience method, such that logging.getLogger('abc').getChild('def.ghi') is the same as logging.getLogger('abc.def.ghi') It's useful, for example, when the parent logger is named using __name__ rather than a literal string. """ if self.root is not self: suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) def __repr__(self): level = getLevelName(self.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) class RootLogger(Logger): """ A root logger is not that different to any other logger, except that it must have a logging level and there is only one instance of it in the hierarchy. """ def __init__(self, level): """ Initialize the logger with the name "root". """ Logger.__init__(self, "root", level) _loggerClass = Logger class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. """ def __init__(self, logger, extra): """ Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows easy stacking of LoggerAdapters, if so desired. You can effectively pass keyword arguments as shown in the following example: adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) """ self.logger = logger self.extra = extra def process(self, msg, kwargs): """ Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs. Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs. """ kwargs["extra"] = self.extra return msg, kwargs # # Boilerplate convenience methods # def debug(self, msg, *args, **kwargs): """ Delegate a debug call to the underlying logger. """ self.log(DEBUG, msg, *args, **kwargs) def info(self, msg, *args, **kwargs): """ Delegate an info call to the underlying logger. """ self.log(INFO, msg, *args, **kwargs) def warning(self, msg, *args, **kwargs): """ Delegate a warning call to the underlying logger. """ self.log(WARNING, msg, *args, **kwargs) def warn(self, msg, *args, **kwargs): warnings.warn("The 'warn' method is deprecated, " "use 'warning' instead", DeprecationWarning, 2) self.warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): """ Delegate an error call to the underlying logger. """ self.log(ERROR, msg, *args, **kwargs) def exception(self, msg, *args, exc_info=True, **kwargs): """ Delegate an exception call to the underlying logger. """ self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ Delegate a critical call to the underlying logger. """ self.log(CRITICAL, msg, *args, **kwargs) def log(self, level, msg, *args, **kwargs): """ Delegate a log call to the underlying logger, after adding contextual information from this adapter instance. """ if self.isEnabledFor(level): msg, kwargs = self.process(msg, kwargs) self.logger.log(level, msg, *args, **kwargs) def isEnabledFor(self, level): """ Is this logger enabled for level 'level'? """ if self.logger.manager.disable >= level: return False return level >= self.getEffectiveLevel() def setLevel(self, level): """ Set the specified level on the underlying logger. """ self.logger.setLevel(level) def getEffectiveLevel(self): """ Get the effective level for the underlying logger. """ return self.logger.getEffectiveLevel() def hasHandlers(self): """ See if the underlying logger has any handlers. """ return self.logger.hasHandlers() def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): """ Low-level log implementation, proxied to allow nested logger adapters. """ return self.logger._log( level, msg, args, exc_info=exc_info, extra=extra, stack_info=stack_info, ) @property def manager(self): return self.logger.manager @manager.setter def manager(self, value): self.logger.manager = value @property def name(self): return self.logger.name def __repr__(self): logger = self.logger level = getLevelName(logger.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level) root = RootLogger(WARNING) Logger.root = root Logger.manager = Manager(Logger.root) #--------------------------------------------------------------------------- # Configuration classes and functions #--------------------------------------------------------------------------- def basicConfig(**kwargs): """ Do basic configuration for the logging system. This function does nothing if the root logger already has handlers configured. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package. The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger. A number of optional keyword arguments may be specified, which can alter the default behaviour. filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler. filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format Use the specified format string for the handler. datefmt Use the specified date/time format. style If a format string is specified, use this to specify the type of format string (possible values '%', '{', '$', for %-formatting, :meth:`str.format` and :class:`string.Template` - defaults to '%'). level Set the root logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored. handlers If specified, this should be an iterable of already created handlers, which will be added to the root handler. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function. Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed. .. versionchanged:: 3.2 Added the ``style`` parameter. .. versionchanged:: 3.3 Added the ``handlers`` parameter. A ``ValueError`` is now thrown for incompatible arguments (e.g. ``handlers`` specified together with ``filename``/``filemode``, or ``filename``/``filemode`` specified together with ``stream``, or ``handlers`` specified together with ``stream``. """ # Add thread safety in case someone mistakenly calls # basicConfig() from multiple threads _acquireLock() try: if len(root.handlers) == 0: handlers = kwargs.pop("handlers", None) if handlers is None: if "stream" in kwargs and "filename" in kwargs: raise ValueError("'stream' and 'filename' should not be " "specified together") else: if "stream" in kwargs or "filename" in kwargs: raise ValueError("'stream' or 'filename' should not be " "specified together with 'handlers'") if handlers is None: filename = kwargs.pop("filename", None) mode = kwargs.pop("filemode", 'a') if filename: h = FileHandler(filename, mode) else: stream = kwargs.pop("stream", None) h = StreamHandler(stream) handlers = [h] dfs = kwargs.pop("datefmt", None) style = kwargs.pop("style", '%') if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) fs = kwargs.pop("format", _STYLES[style][1]) fmt = Formatter(fs, dfs, style) for h in handlers: if h.formatter is None: h.setFormatter(fmt) root.addHandler(h) level = kwargs.pop("level", None) if level is not None: root.setLevel(level) if kwargs: keys = ', '.join(kwargs.keys()) raise ValueError('Unrecognised argument(s): %s' % keys) finally: _releaseLock() #--------------------------------------------------------------------------- # Utility functions at module level. # Basically delegate everything to the root logger. #--------------------------------------------------------------------------- def getLogger(name=None): """ Return a logger with the specified name, creating it if necessary. If no name is specified, return the root logger. """ if name: return Logger.manager.getLogger(name) else: return root def critical(msg, *args, **kwargs): """ Log a message with severity 'CRITICAL' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.critical(msg, *args, **kwargs) fatal = critical def error(msg, *args, **kwargs): """ Log a message with severity 'ERROR' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.error(msg, *args, **kwargs) def exception(msg, *args, exc_info=True, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. If the logger has no handlers, basicConfig() is called to add a console handler with a pre-defined format. """ error(msg, *args, exc_info=exc_info, **kwargs) def warning(msg, *args, **kwargs): """ Log a message with severity 'WARNING' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.warning(msg, *args, **kwargs) def warn(msg, *args, **kwargs): warnings.warn("The 'warn' function is deprecated, " "use 'warning' instead", DeprecationWarning, 2) warning(msg, *args, **kwargs) def info(msg, *args, **kwargs): """ Log a message with severity 'INFO' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.info(msg, *args, **kwargs) def debug(msg, *args, **kwargs): """ Log a message with severity 'DEBUG' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.debug(msg, *args, **kwargs) def log(level, msg, *args, **kwargs): """ Log 'msg % args' with the integer severity 'level' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format. """ if len(root.handlers) == 0: basicConfig() root.log(level, msg, *args, **kwargs) def disable(level): """ Disable all logging calls of severity 'level' and below. """ root.manager.disable = level def shutdown(handlerList=_handlerList): """ Perform any cleanup actions in the logging system (e.g. flushing buffers). Should be called at application exit. """ for wr in reversed(handlerList[:]): #errors might occur, for example, if files are locked #we just ignore them if raiseExceptions is not set try: h = wr() if h: try: h.acquire() h.flush() h.close() except (OSError, ValueError): # Ignore errors which might be caused # because handlers have been closed but # references to them are still around at # application exit. pass finally: h.release() except: # ignore everything, as we're shutting down if raiseExceptions: raise #else, swallow #Let's try and shutdown automatically on application exit... import atexit atexit.register(shutdown) # Null handler class NullHandler(Handler): """ This handler does nothing. It's intended to be used to avoid the "No handlers could be found for logger XXX" one-off warning. This is important for library code, which may contain code to log events. If a user of the library does not configure logging, the one-off warning might be produced; to avoid this, the library developer simply needs to instantiate a NullHandler and add it to the top-level logger of the library module or package. """ def handle(self, record): """Stub.""" def emit(self, record): """Stub.""" def createLock(self): self.lock = None # Warnings integration _warnings_showwarning = None def _showwarning(message, category, filename, lineno, file=None, line=None): """ Implementation of showwarnings which redirects to logging, which will first check to see if the file parameter is None. If a file is specified, it will delegate to the original warnings implementation of showwarning. Otherwise, it will call warnings.formatwarning and will log the resulting string to a warnings logger named "py.warnings" with level logging.WARNING. """ if file is not None: if _warnings_showwarning is not None: _warnings_showwarning(message, category, filename, lineno, file, line) else: s = warnings.formatwarning(message, category, filename, lineno, line) logger = getLogger("py.warnings") if not logger.handlers: logger.addHandler(NullHandler()) logger.warning("%s", s) def captureWarnings(capture): """ If capture is true, redirect all warnings to the logging package. If capture is False, ensure that warnings are not redirected to logging but to their original destinations. """ global _warnings_showwarning if capture: if _warnings_showwarning is None: _warnings_showwarning = warnings.showwarning warnings.showwarning = _showwarning else: if _warnings_showwarning is not None: warnings.showwarning = _warnings_showwarning _warnings_showwarning = None usr/lib/python3.6/site-packages/idna/__init__.py000064400000000024152347062050015437 0ustar00from .core import * lib64/python3.6/test/support/__init__.py000064400000311635152347064420014060 0ustar00"""Supporting definitions for the Python regression tests.""" if __name__ != 'test.support': raise ImportError('support must be imported from the test package') import collections.abc import contextlib import datetime import errno import faulthandler import fnmatch import functools import gc import hashlib import importlib import importlib.util import io import logging.handlers import nntplib import os import platform import re import shutil import socket import stat import struct import subprocess import sys import sysconfig import tempfile import time import types import unittest import urllib.error import warnings from .testresult import get_test_runner try: import _thread, threading except ImportError: _thread = None threading = None try: import multiprocessing.process except ImportError: multiprocessing = None try: import zlib except ImportError: zlib = None try: import gzip except ImportError: gzip = None try: import bz2 except ImportError: bz2 = None try: import lzma except ImportError: lzma = None try: import resource except ImportError: resource = None try: import _hashlib except ImportError: _hashlib = None __all__ = [ # globals "PIPE_MAX_SIZE", "verbose", "max_memuse", "use_resources", "failfast", # exceptions "Error", "TestFailed", "TestDidNotRun", "ResourceDenied", # imports "import_module", "import_fresh_module", "CleanImport", # modules "unload", "forget", # io "record_original_stdout", "get_original_stdout", "captured_stdout", "captured_stdin", "captured_stderr", # filesystem "TESTFN", "SAVEDCWD", "unlink", "rmtree", "temp_cwd", "findfile", "create_empty_file", "can_symlink", "fs_is_case_insensitive", # unittest "is_resource_enabled", "requires", "requires_freebsd_version", "requires_linux_version", "requires_mac_ver", "requires_hashdigest", "check_syntax_error", "TransientResource", "time_out", "socket_peer_reset", "ioerror_peer_reset", "transient_internet", "BasicTestRunner", "run_unittest", "run_doctest", "skip_unless_symlink", "requires_gzip", "requires_bz2", "requires_lzma", "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", "requires_IEEE_754", "skip_unless_xattr", "requires_zlib", "anticipate_failure", "load_package_tests", "detect_api_mismatch", "check__all__", "requires_android_level", "requires_multiprocessing_queue", # sys "is_jython", "is_android", "check_impl_detail", "unix_shell", "setswitchinterval", # network "HOST", "IPV6_ENABLED", "find_unused_port", "bind_port", "open_urlresource", "bind_unix_socket", # processes 'temp_umask', "reap_children", # logging "TestHandler", # threads "threading_setup", "threading_cleanup", "reap_threads", "start_threads", # miscellaneous "check_warnings", "check_no_resource_warning", "EnvironmentVarGuard", "run_with_locale", "swap_item", "swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict", "run_with_tz", "PGO", "missing_compiler_executable", "fd_count", ] class Error(Exception): """Base class for regression test exceptions.""" class TestFailed(Error): """Test failed.""" class TestDidNotRun(Error): """Test did not run any subtests.""" class ResourceDenied(unittest.SkipTest): """Test skipped because it requested a disallowed resource. This is raised when a test calls requires() for a resource that has not be enabled. It is used to distinguish between expected and unexpected skips. """ @contextlib.contextmanager def _ignore_deprecated_imports(ignore=True): """Context manager to suppress package and module deprecation warnings when importing them. If ignore is False, this context manager has no effect. """ if ignore: with warnings.catch_warnings(): warnings.filterwarnings("ignore", ".+ (module|package)", DeprecationWarning) yield else: yield def import_module(name, deprecated=False, *, required_on=()): """Import and return the module to be tested, raising SkipTest if it is not available. If deprecated is True, any module or package deprecation messages will be suppressed. If a module is required on a platform but optional for others, set required_on to an iterable of platform prefixes which will be compared against sys.platform. """ with _ignore_deprecated_imports(deprecated): try: return importlib.import_module(name) except ImportError as msg: if sys.platform.startswith(tuple(required_on)): raise raise unittest.SkipTest(str(msg)) def _save_and_remove_module(name, orig_modules): """Helper function to save and remove a module from sys.modules Raise ImportError if the module can't be imported. """ # try to import the module and raise an error if it can't be imported if name not in sys.modules: __import__(name) del sys.modules[name] for modname in list(sys.modules): if modname == name or modname.startswith(name + '.'): orig_modules[modname] = sys.modules[modname] del sys.modules[modname] def _save_and_block_module(name, orig_modules): """Helper function to save and block a module in sys.modules Return True if the module was in sys.modules, False otherwise. """ saved = True try: orig_modules[name] = sys.modules[name] except KeyError: saved = False sys.modules[name] = None return saved def anticipate_failure(condition): """Decorator to mark a test that is known to be broken in some cases Any use of this decorator should have a comment identifying the associated tracker issue. """ if condition: return unittest.expectedFailure return lambda f: f def load_package_tests(pkg_dir, loader, standard_tests, pattern): """Generic load_tests implementation for simple test packages. Most packages can implement load_tests using this function as follows: def load_tests(*args): return load_package_tests(os.path.dirname(__file__), *args) """ if pattern is None: pattern = "test*" top_dir = os.path.dirname( # Lib os.path.dirname( # test os.path.dirname(__file__))) # support package_tests = loader.discover(start_dir=pkg_dir, top_level_dir=top_dir, pattern=pattern) standard_tests.addTests(package_tests) return standard_tests def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): """Import and return a module, deliberately bypassing sys.modules. This function imports and returns a fresh copy of the named Python module by removing the named module from sys.modules before doing the import. Note that unlike reload, the original module is not affected by this operation. *fresh* is an iterable of additional module names that are also removed from the sys.modules cache before doing the import. *blocked* is an iterable of module names that are replaced with None in the module cache during the import to ensure that attempts to import them raise ImportError. The named module and any modules named in the *fresh* and *blocked* parameters are saved before starting the import and then reinserted into sys.modules when the fresh import is complete. Module and package deprecation messages are suppressed during this import if *deprecated* is True. This function will raise ImportError if the named module cannot be imported. """ # NOTE: test_heapq, test_json and test_warnings include extra sanity checks # to make sure that this utility function is working as expected with _ignore_deprecated_imports(deprecated): # Keep track of modules saved for later restoration as well # as those which just need a blocking entry removed orig_modules = {} names_to_remove = [] _save_and_remove_module(name, orig_modules) try: for fresh_name in fresh: _save_and_remove_module(fresh_name, orig_modules) for blocked_name in blocked: if not _save_and_block_module(blocked_name, orig_modules): names_to_remove.append(blocked_name) fresh_module = importlib.import_module(name) except ImportError: fresh_module = None finally: for orig_name, module in orig_modules.items(): sys.modules[orig_name] = module for name_to_remove in names_to_remove: del sys.modules[name_to_remove] return fresh_module def get_attribute(obj, name): """Get an attribute, raising SkipTest if AttributeError is raised.""" try: attribute = getattr(obj, name) except AttributeError: raise unittest.SkipTest("object %r has no attribute %r" % (obj, name)) else: return attribute verbose = 1 # Flag set to 0 by regrtest.py use_resources = None # Flag set to [] by regrtest.py max_memuse = 0 # Disable bigmem tests (they will still be run with # small sizes, to make sure they work.) real_max_memuse = 0 junit_xml_list = None # list of testsuite XML elements failfast = False # _original_stdout is meant to hold stdout at the time regrtest began. # This may be "the real" stdout, or IDLE's emulation of stdout, or whatever. # The point is to have some flavor of stdout the user can actually see. _original_stdout = None def record_original_stdout(stdout): global _original_stdout _original_stdout = stdout def get_original_stdout(): return _original_stdout or sys.stdout def unload(name): try: del sys.modules[name] except KeyError: pass def _force_run(path, func, *args): try: return func(*args) except OSError as err: if verbose >= 2: print('%s: %s' % (err.__class__.__name__, err)) print('re-run %s%r' % (func.__name__, args)) os.chmod(path, stat.S_IRWXU) return func(*args) if sys.platform.startswith("win"): def _waitfor(func, pathname, waitall=False): # Perform the operation func(pathname) # Now setup the wait loop if waitall: dirname = pathname else: dirname, name = os.path.split(pathname) dirname = dirname or '.' # Check for `pathname` to be removed from the filesystem. # The exponential backoff of the timeout amounts to a total # of ~1 second after which the deletion is probably an error # anyway. # Testing on an i7@4.3GHz shows that usually only 1 iteration is # required when contention occurs. timeout = 0.001 while timeout < 1.0: # Note we are only testing for the existence of the file(s) in # the contents of the directory regardless of any security or # access rights. If we have made it this far, we have sufficient # permissions to do that much using Python's equivalent of the # Windows API FindFirstFile. # Other Windows APIs can fail or give incorrect results when # dealing with files that are pending deletion. L = os.listdir(dirname) if not (L if waitall else name in L): return # Increase the timeout and try again time.sleep(timeout) timeout *= 2 warnings.warn('tests may fail, delete still pending for ' + pathname, RuntimeWarning, stacklevel=4) def _unlink(filename): _waitfor(os.unlink, filename) def _rmdir(dirname): _waitfor(os.rmdir, dirname) def _rmtree(path): def _rmtree_inner(path): for name in _force_run(path, os.listdir, path): fullname = os.path.join(path, name) try: mode = os.lstat(fullname).st_mode except OSError as exc: print("support.rmtree(): os.lstat(%r) failed with %s" % (fullname, exc), file=sys.__stderr__) mode = 0 if stat.S_ISDIR(mode): _waitfor(_rmtree_inner, fullname, waitall=True) _force_run(fullname, os.rmdir, fullname) else: _force_run(fullname, os.unlink, fullname) _waitfor(_rmtree_inner, path, waitall=True) _waitfor(lambda p: _force_run(p, os.rmdir, p), path) def _longpath(path): try: import ctypes except ImportError: # No ctypes means we can't expands paths. pass else: buffer = ctypes.create_unicode_buffer(len(path) * 2) length = ctypes.windll.kernel32.GetLongPathNameW(path, buffer, len(buffer)) if length: return buffer[:length] return path else: _unlink = os.unlink _rmdir = os.rmdir def _rmtree(path): try: shutil.rmtree(path) return except OSError: pass def _rmtree_inner(path): for name in _force_run(path, os.listdir, path): fullname = os.path.join(path, name) try: mode = os.lstat(fullname).st_mode except OSError: mode = 0 if stat.S_ISDIR(mode): _rmtree_inner(fullname) _force_run(path, os.rmdir, fullname) else: _force_run(path, os.unlink, fullname) _rmtree_inner(path) os.rmdir(path) def _longpath(path): return path def unlink(filename): try: _unlink(filename) except (FileNotFoundError, NotADirectoryError): pass def rmdir(dirname): try: _rmdir(dirname) except FileNotFoundError: pass def rmtree(path): try: _rmtree(path) except FileNotFoundError: pass def make_legacy_pyc(source): """Move a PEP 3147/488 pyc file to its legacy pyc location. :param source: The file system path to the source file. The source file does not need to exist, however the PEP 3147/488 pyc file must exist. :return: The file system path to the legacy pyc file. """ pyc_file = importlib.util.cache_from_source(source) up_one = os.path.dirname(os.path.abspath(source)) legacy_pyc = os.path.join(up_one, source + 'c') os.rename(pyc_file, legacy_pyc) return legacy_pyc def forget(modname): """'Forget' a module was ever imported. This removes the module from sys.modules and deletes any PEP 3147/488 or legacy .pyc files. """ unload(modname) for dirname in sys.path: source = os.path.join(dirname, modname + '.py') # It doesn't matter if they exist or not, unlink all possible # combinations of PEP 3147/488 and legacy pyc files. unlink(source + 'c') for opt in ('', 1, 2): unlink(importlib.util.cache_from_source(source, optimization=opt)) # Check whether a gui is actually available def _is_gui_available(): if hasattr(_is_gui_available, 'result'): return _is_gui_available.result reason = None if sys.platform.startswith('win'): # if Python is running as a service (such as the buildbot service), # gui interaction may be disallowed import ctypes import ctypes.wintypes UOI_FLAGS = 1 WSF_VISIBLE = 0x0001 class USEROBJECTFLAGS(ctypes.Structure): _fields_ = [("fInherit", ctypes.wintypes.BOOL), ("fReserved", ctypes.wintypes.BOOL), ("dwFlags", ctypes.wintypes.DWORD)] dll = ctypes.windll.user32 h = dll.GetProcessWindowStation() if not h: raise ctypes.WinError() uof = USEROBJECTFLAGS() needed = ctypes.wintypes.DWORD() res = dll.GetUserObjectInformationW(h, UOI_FLAGS, ctypes.byref(uof), ctypes.sizeof(uof), ctypes.byref(needed)) if not res: raise ctypes.WinError() if not bool(uof.dwFlags & WSF_VISIBLE): reason = "gui not available (WSF_VISIBLE flag not set)" elif sys.platform == 'darwin': # The Aqua Tk implementations on OS X can abort the process if # being called in an environment where a window server connection # cannot be made, for instance when invoked by a buildbot or ssh # process not running under the same user id as the current console # user. To avoid that, raise an exception if the window manager # connection is not available. from ctypes import cdll, c_int, pointer, Structure from ctypes.util import find_library app_services = cdll.LoadLibrary(find_library("ApplicationServices")) if app_services.CGMainDisplayID() == 0: reason = "gui tests cannot run without OS X window manager" else: class ProcessSerialNumber(Structure): _fields_ = [("highLongOfPSN", c_int), ("lowLongOfPSN", c_int)] psn = ProcessSerialNumber() psn_p = pointer(psn) if ( (app_services.GetCurrentProcess(psn_p) < 0) or (app_services.SetFrontProcess(psn_p) < 0) ): reason = "cannot run without OS X gui process" # check on every platform whether tkinter can actually do anything if not reason: try: from tkinter import Tk root = Tk() root.withdraw() root.update() root.destroy() except Exception as e: err_string = str(e) if len(err_string) > 50: err_string = err_string[:50] + ' [...]' reason = 'Tk unavailable due to {}: {}'.format(type(e).__name__, err_string) _is_gui_available.reason = reason _is_gui_available.result = not reason return _is_gui_available.result def is_resource_enabled(resource): """Test whether a resource is enabled. Known resources are set by regrtest.py. If not running under regrtest.py, all resources are assumed enabled unless use_resources has been set. """ return use_resources is None or resource in use_resources def requires(resource, msg=None): """Raise ResourceDenied if the specified resource is not available.""" if not is_resource_enabled(resource): if msg is None: msg = "Use of the %r resource not enabled" % resource raise ResourceDenied(msg) if resource == 'gui' and not _is_gui_available(): raise ResourceDenied(_is_gui_available.reason) def _requires_unix_version(sysname, min_version): """Decorator raising SkipTest if the OS is `sysname` and the version is less than `min_version`. For example, @_requires_unix_version('FreeBSD', (7, 2)) raises SkipTest if the FreeBSD version is less than 7.2. """ def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): if platform.system() == sysname: version_txt = platform.release().split('-', 1)[0] try: version = tuple(map(int, version_txt.split('.'))) except ValueError: pass else: if version < min_version: min_version_txt = '.'.join(map(str, min_version)) raise unittest.SkipTest( "%s version %s or higher required, not %s" % (sysname, min_version_txt, version_txt)) return func(*args, **kw) wrapper.min_version = min_version return wrapper return decorator def requires_freebsd_version(*min_version): """Decorator raising SkipTest if the OS is FreeBSD and the FreeBSD version is less than `min_version`. For example, @requires_freebsd_version(7, 2) raises SkipTest if the FreeBSD version is less than 7.2. """ return _requires_unix_version('FreeBSD', min_version) def requires_linux_version(*min_version): """Decorator raising SkipTest if the OS is Linux and the Linux version is less than `min_version`. For example, @requires_linux_version(2, 6, 32) raises SkipTest if the Linux version is less than 2.6.32. """ return _requires_unix_version('Linux', min_version) def requires_mac_ver(*min_version): """Decorator raising SkipTest if the OS is Mac OS X and the OS X version if less than min_version. For example, @requires_mac_ver(10, 5) raises SkipTest if the OS X version is lesser than 10.5. """ def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): if sys.platform == 'darwin': version_txt = platform.mac_ver()[0] try: version = tuple(map(int, version_txt.split('.'))) except ValueError: pass else: if version < min_version: min_version_txt = '.'.join(map(str, min_version)) raise unittest.SkipTest( "Mac OS X %s or higher required, not %s" % (min_version_txt, version_txt)) return func(*args, **kw) wrapper.min_version = min_version return wrapper return decorator def requires_hashdigest(digestname, openssl=None): """Decorator raising SkipTest if a hashing algorithm is not available The hashing algorithm could be missing or blocked by a strict crypto policy. If 'openssl' is True, then the decorator checks that OpenSSL provides the algorithm. Otherwise the check falls back to built-in implementations. ValueError: [digital envelope routines: EVP_DigestInit_ex] disabled for FIPS ValueError: unsupported hash type md4 """ def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): try: if openssl and _hashlib is not None: _hashlib.new(digestname) else: hashlib.new(digestname) except ValueError: raise unittest.SkipTest( f"hash digest '{digestname}' is not available." ) return func(*args, **kwargs) return wrapper return decorator # Don't use "localhost", since resolving it uses the DNS under recent # Windows versions (see issue #18792). HOST = "127.0.0.1" HOSTv6 = "::1" def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM): """Returns an unused port that should be suitable for binding. This is achieved by creating a temporary socket with the same family and type as the 'sock' parameter (default is AF_INET, SOCK_STREAM), and binding it to the specified host address (defaults to 0.0.0.0) with the port set to 0, eliciting an unused ephemeral port from the OS. The temporary socket is then closed and deleted, and the ephemeral port is returned. Either this method or bind_port() should be used for any tests where a server socket needs to be bound to a particular port for the duration of the test. Which one to use depends on whether the calling code is creating a python socket, or if an unused port needs to be provided in a constructor or passed to an external program (i.e. the -accept argument to openssl's s_server mode). Always prefer bind_port() over find_unused_port() where possible. Hard coded ports should *NEVER* be used. As soon as a server socket is bound to a hard coded port, the ability to run multiple instances of the test simultaneously on the same host is compromised, which makes the test a ticking time bomb in a buildbot environment. On Unix buildbots, this may simply manifest as a failed test, which can be recovered from without intervention in most cases, but on Windows, the entire python process can completely and utterly wedge, requiring someone to log in to the buildbot and manually kill the affected process. (This is easy to reproduce on Windows, unfortunately, and can be traced to the SO_REUSEADDR socket option having different semantics on Windows versus Unix/Linux. On Unix, you can't have two AF_INET SOCK_STREAM sockets bind, listen and then accept connections on identical host/ports. An EADDRINUSE OSError will be raised at some point (depending on the platform and the order bind and listen were called on each socket). However, on Windows, if SO_REUSEADDR is set on the sockets, no EADDRINUSE will ever be raised when attempting to bind two identical host/ports. When accept() is called on each socket, the second caller's process will steal the port from the first caller, leaving them both in an awkwardly wedged state where they'll no longer respond to any signals or graceful kills, and must be forcibly killed via OpenProcess()/TerminateProcess(). The solution on Windows is to use the SO_EXCLUSIVEADDRUSE socket option instead of SO_REUSEADDR, which effectively affords the same semantics as SO_REUSEADDR on Unix. Given the propensity of Unix developers in the Open Source world compared to Windows ones, this is a common mistake. A quick look over OpenSSL's 0.9.8g source shows that they use SO_REUSEADDR when openssl.exe is called with the 's_server' option, for example. See http://bugs.python.org/issue2550 for more info. The following site also has a very thorough description about the implications of both REUSEADDR and EXCLUSIVEADDRUSE on Windows: http://msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx) XXX: although this approach is a vast improvement on previous attempts to elicit unused ports, it rests heavily on the assumption that the ephemeral port returned to us by the OS won't immediately be dished back out to some other process when we close and delete our temporary socket but before our calling code has a chance to bind the returned port. We can deal with this issue if/when we come across it. """ tempsock = socket.socket(family, socktype) port = bind_port(tempsock) tempsock.close() del tempsock return port def bind_port(sock, host=HOST): """Bind the socket to a free port and return the port number. Relies on ephemeral ports in order to ensure we are using an unbound port. This is important as many tests may be running simultaneously, especially in a buildbot environment. This method raises an exception if the sock.family is AF_INET and sock.type is SOCK_STREAM, *and* the socket has SO_REUSEADDR or SO_REUSEPORT set on it. Tests should *never* set these socket options for TCP/IP sockets. The only case for setting these options is testing multicasting via multiple UDP sockets. Additionally, if the SO_EXCLUSIVEADDRUSE socket option is available (i.e. on Windows), it will be set on the socket. This will prevent anyone else from bind()'ing to our host/port for the duration of the test. """ if sock.family == socket.AF_INET and sock.type == socket.SOCK_STREAM: if hasattr(socket, 'SO_REUSEADDR'): if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 1: raise TestFailed("tests should never set the SO_REUSEADDR " \ "socket option on TCP/IP sockets!") if hasattr(socket, 'SO_REUSEPORT'): try: if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 1: raise TestFailed("tests should never set the SO_REUSEPORT " \ "socket option on TCP/IP sockets!") except OSError: # Python's socket module was compiled using modern headers # thus defining SO_REUSEPORT but this process is running # under an older kernel that does not support SO_REUSEPORT. pass if hasattr(socket, 'SO_EXCLUSIVEADDRUSE'): sock.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) sock.bind((host, 0)) port = sock.getsockname()[1] return port def bind_unix_socket(sock, addr): """Bind a unix socket, raising SkipTest if PermissionError is raised.""" assert sock.family == socket.AF_UNIX try: sock.bind(addr) except PermissionError: sock.close() raise unittest.SkipTest('cannot bind AF_UNIX sockets') def _is_ipv6_enabled(): """Check whether IPv6 is enabled on this host.""" if socket.has_ipv6: sock = None try: sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) sock.bind((HOSTv6, 0)) return True except OSError: pass finally: if sock: sock.close() return False IPV6_ENABLED = _is_ipv6_enabled() def system_must_validate_cert(f): """Skip the test on TLS certificate validation failures.""" @functools.wraps(f) def dec(*args, **kwargs): try: f(*args, **kwargs) except IOError as e: if "CERTIFICATE_VERIFY_FAILED" in str(e): raise unittest.SkipTest("system does not contain " "necessary certificates") raise return dec # A constant likely larger than the underlying OS pipe buffer size, to # make writes blocking. # Windows limit seems to be around 512 B, and many Unix kernels have a # 64 KiB pipe buffer size or 16 * PAGE_SIZE: take a few megs to be sure. # (see issue #17835 for a discussion of this number). PIPE_MAX_SIZE = 4 * 1024 * 1024 + 1 # A constant likely larger than the underlying OS socket buffer size, to make # writes blocking. # The socket buffer sizes can usually be tuned system-wide (e.g. through sysctl # on Linux), or on a per-socket basis (SO_SNDBUF/SO_RCVBUF). See issue #18643 # for a discussion of this number). SOCK_MAX_SIZE = 16 * 1024 * 1024 + 1 # decorator for skipping tests on non-IEEE 754 platforms requires_IEEE_754 = unittest.skipUnless( float.__getformat__("double").startswith("IEEE"), "test requires IEEE 754 doubles") requires_zlib = unittest.skipUnless(zlib, 'requires zlib') requires_gzip = unittest.skipUnless(gzip, 'requires gzip') requires_bz2 = unittest.skipUnless(bz2, 'requires bz2') requires_lzma = unittest.skipUnless(lzma, 'requires lzma') is_jython = sys.platform.startswith('java') _ANDROID_API_LEVEL = sysconfig.get_config_var('ANDROID_API_LEVEL') is_android = (_ANDROID_API_LEVEL is not None and _ANDROID_API_LEVEL > 0) if sys.platform != 'win32': unix_shell = '/system/bin/sh' if is_android else '/bin/sh' else: unix_shell = None # Filename used for testing if os.name == 'java': # Jython disallows @ in module names TESTFN = '$test' else: TESTFN = '@test' # Disambiguate TESTFN for parallel testing, while letting it remain a valid # module name. TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid()) # FS_NONASCII: non-ASCII character encodable by os.fsencode(), # or None if there is no such character. FS_NONASCII = None for character in ( # First try printable and common characters to have a readable filename. # For each character, the encoding list are just example of encodings able # to encode the character (the list is not exhaustive). # U+00E6 (Latin Small Letter Ae): cp1252, iso-8859-1 '\u00E6', # U+0130 (Latin Capital Letter I With Dot Above): cp1254, iso8859_3 '\u0130', # U+0141 (Latin Capital Letter L With Stroke): cp1250, cp1257 '\u0141', # U+03C6 (Greek Small Letter Phi): cp1253 '\u03C6', # U+041A (Cyrillic Capital Letter Ka): cp1251 '\u041A', # U+05D0 (Hebrew Letter Alef): Encodable to cp424 '\u05D0', # U+060C (Arabic Comma): cp864, cp1006, iso8859_6, mac_arabic '\u060C', # U+062A (Arabic Letter Teh): cp720 '\u062A', # U+0E01 (Thai Character Ko Kai): cp874 '\u0E01', # Then try more "special" characters. "special" because they may be # interpreted or displayed differently depending on the exact locale # encoding and the font. # U+00A0 (No-Break Space) '\u00A0', # U+20AC (Euro Sign) '\u20AC', ): try: # If Python is set up to use the legacy 'mbcs' in Windows, # 'replace' error mode is used, and encode() returns b'?' # for characters missing in the ANSI codepage if os.fsdecode(os.fsencode(character)) != character: raise UnicodeError except UnicodeError: pass else: FS_NONASCII = character break # TESTFN_UNICODE is a non-ascii filename TESTFN_UNICODE = TESTFN + "-\xe0\xf2\u0258\u0141\u011f" if sys.platform == 'darwin': # In Mac OS X's VFS API file names are, by definition, canonically # decomposed Unicode, encoded using UTF-8. See QA1173: # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html import unicodedata TESTFN_UNICODE = unicodedata.normalize('NFD', TESTFN_UNICODE) TESTFN_ENCODING = sys.getfilesystemencoding() # TESTFN_UNENCODABLE is a filename (str type) that should *not* be able to be # encoded by the filesystem encoding (in strict mode). It can be None if we # cannot generate such filename. TESTFN_UNENCODABLE = None if os.name == 'nt': # skip win32s (0) or Windows 9x/ME (1) if sys.getwindowsversion().platform >= 2: # Different kinds of characters from various languages to minimize the # probability that the whole name is encodable to MBCS (issue #9819) TESTFN_UNENCODABLE = TESTFN + "-\u5171\u0141\u2661\u0363\uDC80" try: TESTFN_UNENCODABLE.encode(TESTFN_ENCODING) except UnicodeEncodeError: pass else: print('WARNING: The filename %r CAN be encoded by the filesystem encoding (%s). ' 'Unicode filename tests may not be effective' % (TESTFN_UNENCODABLE, TESTFN_ENCODING)) TESTFN_UNENCODABLE = None # Mac OS X denies unencodable filenames (invalid utf-8) elif sys.platform != 'darwin': try: # ascii and utf-8 cannot encode the byte 0xff b'\xff'.decode(TESTFN_ENCODING) except UnicodeDecodeError: # 0xff will be encoded using the surrogate character u+DCFF TESTFN_UNENCODABLE = TESTFN \ + b'-\xff'.decode(TESTFN_ENCODING, 'surrogateescape') else: # File system encoding (eg. ISO-8859-* encodings) can encode # the byte 0xff. Skip some unicode filename tests. pass # TESTFN_UNDECODABLE is a filename (bytes type) that should *not* be able to be # decoded from the filesystem encoding (in strict mode). It can be None if we # cannot generate such filename (ex: the latin1 encoding can decode any byte # sequence). On UNIX, TESTFN_UNDECODABLE can be decoded by os.fsdecode() thanks # to the surrogateescape error handler (PEP 383), but not from the filesystem # encoding in strict mode. TESTFN_UNDECODABLE = None for name in ( # b'\xff' is not decodable by os.fsdecode() with code page 932. Windows # accepts it to create a file or a directory, or don't accept to enter to # such directory (when the bytes name is used). So test b'\xe7' first: it is # not decodable from cp932. b'\xe7w\xf0', # undecodable from ASCII, UTF-8 b'\xff', # undecodable from iso8859-3, iso8859-6, iso8859-7, cp424, iso8859-8, cp856 # and cp857 b'\xae\xd5' # undecodable from UTF-8 (UNIX and Mac OS X) b'\xed\xb2\x80', b'\xed\xb4\x80', # undecodable from shift_jis, cp869, cp874, cp932, cp1250, cp1251, cp1252, # cp1253, cp1254, cp1255, cp1257, cp1258 b'\x81\x98', ): try: name.decode(TESTFN_ENCODING) except UnicodeDecodeError: TESTFN_UNDECODABLE = os.fsencode(TESTFN) + name break if FS_NONASCII: TESTFN_NONASCII = TESTFN + '-' + FS_NONASCII else: TESTFN_NONASCII = None # Save the initial cwd SAVEDCWD = os.getcwd() # Set by libregrtest/main.py so we can skip tests that are not # useful for PGO PGO = False # Set by libregrtest/main.py if we are running the extended (time consuming) # PGO task. If this is True, PGO is also True. PGO_EXTENDED = False @contextlib.contextmanager def temp_dir(path=None, quiet=False): """Return a context manager that creates a temporary directory. Arguments: path: the directory to create temporarily. If omitted or None, defaults to creating a temporary directory using tempfile.mkdtemp. quiet: if False (the default), the context manager raises an exception on error. Otherwise, if the path is specified and cannot be created, only a warning is issued. """ dir_created = False if path is None: path = tempfile.mkdtemp() dir_created = True path = os.path.realpath(path) else: try: os.mkdir(path) dir_created = True except OSError: if not quiet: raise warnings.warn('tests may fail, unable to create temp dir: ' + path, RuntimeWarning, stacklevel=3) if dir_created: pid = os.getpid() try: yield path finally: # In case the process forks, let only the parent remove the # directory. The child has a diffent process id. (bpo-30028) if dir_created and pid == os.getpid(): rmtree(path) @contextlib.contextmanager def change_cwd(path, quiet=False): """Return a context manager that changes the current working directory. Arguments: path: the directory to use as the temporary current working directory. quiet: if False (the default), the context manager raises an exception on error. Otherwise, it issues only a warning and keeps the current working directory the same. """ saved_dir = os.getcwd() try: os.chdir(path) except OSError: if not quiet: raise warnings.warn('tests may fail, unable to change CWD to: ' + path, RuntimeWarning, stacklevel=3) try: yield os.getcwd() finally: os.chdir(saved_dir) @contextlib.contextmanager def temp_cwd(name='tempcwd', quiet=False): """ Context manager that temporarily creates and changes the CWD. The function temporarily changes the current working directory after creating a temporary directory in the current directory with name *name*. If *name* is None, the temporary directory is created using tempfile.mkdtemp. If *quiet* is False (default) and it is not possible to create or change the CWD, an error is raised. If *quiet* is True, only a warning is raised and the original CWD is used. """ with temp_dir(path=name, quiet=quiet) as temp_path: with change_cwd(temp_path, quiet=quiet) as cwd_dir: yield cwd_dir if hasattr(os, "umask"): @contextlib.contextmanager def temp_umask(umask): """Context manager that temporarily sets the process umask.""" oldmask = os.umask(umask) try: yield finally: os.umask(oldmask) # TEST_HOME_DIR refers to the top level directory of the "test" package # that contains Python's regression test suite TEST_SUPPORT_DIR = os.path.dirname(os.path.abspath(__file__)) TEST_HOME_DIR = os.path.dirname(TEST_SUPPORT_DIR) # TEST_DATA_DIR is used as a target download location for remote resources TEST_DATA_DIR = os.path.join(TEST_HOME_DIR, "data") def findfile(filename, subdir=None): """Try to find a file on sys.path or in the test directory. If it is not found the argument passed to the function is returned (this does not necessarily signal failure; could still be the legitimate path). Setting *subdir* indicates a relative path to use to find the file rather than looking directly in the path directories. """ if os.path.isabs(filename): return filename if subdir is not None: filename = os.path.join(subdir, filename) path = [TEST_HOME_DIR] + sys.path for dn in path: fn = os.path.join(dn, filename) if os.path.exists(fn): return fn return filename def create_empty_file(filename): """Create an empty file. If the file already exists, truncate it.""" fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC) os.close(fd) def sortdict(dict): "Like repr(dict), but in sorted order." items = sorted(dict.items()) reprpairs = ["%r: %r" % pair for pair in items] withcommas = ", ".join(reprpairs) return "{%s}" % withcommas def make_bad_fd(): """ Create an invalid file descriptor by opening and closing a file and return its fd. """ file = open(TESTFN, "wb") try: return file.fileno() finally: file.close() unlink(TESTFN) def check_syntax_error(testcase, statement, *, lineno=None, offset=None): with testcase.assertRaises(SyntaxError) as cm: compile(statement, '', 'exec') err = cm.exception testcase.assertIsNotNone(err.lineno) if lineno is not None: testcase.assertEqual(err.lineno, lineno) testcase.assertIsNotNone(err.offset) if offset is not None: testcase.assertEqual(err.offset, offset) def open_urlresource(url, *args, **kw): import urllib.request, urllib.parse check = kw.pop('check', None) filename = urllib.parse.urlparse(url)[2].split('/')[-1] # '/': it's URL! fn = os.path.join(TEST_DATA_DIR, filename) def check_valid_file(fn): f = open(fn, *args, **kw) if check is None: return f elif check(f): f.seek(0) return f f.close() if os.path.exists(fn): f = check_valid_file(fn) if f is not None: return f unlink(fn) # Verify the requirement before downloading the file requires('urlfetch') if verbose: print('\tfetching %s ...' % url, file=get_original_stdout()) opener = urllib.request.build_opener() if gzip: opener.addheaders.append(('Accept-Encoding', 'gzip')) f = opener.open(url, timeout=15) if gzip and f.headers.get('Content-Encoding') == 'gzip': f = gzip.GzipFile(fileobj=f) try: with open(fn, "wb") as out: s = f.read() while s: out.write(s) s = f.read() finally: f.close() f = check_valid_file(fn) if f is not None: return f raise TestFailed('invalid resource %r' % fn) class WarningsRecorder(object): """Convenience wrapper for the warnings list returned on entry to the warnings.catch_warnings() context manager. """ def __init__(self, warnings_list): self._warnings = warnings_list self._last = 0 def __getattr__(self, attr): if len(self._warnings) > self._last: return getattr(self._warnings[-1], attr) elif attr in warnings.WarningMessage._WARNING_DETAILS: return None raise AttributeError("%r has no attribute %r" % (self, attr)) @property def warnings(self): return self._warnings[self._last:] def reset(self): self._last = len(self._warnings) def _filterwarnings(filters, quiet=False): """Catch the warnings, then check if all the expected warnings have been raised and re-raise unexpected warnings. If 'quiet' is True, only re-raise the unexpected warnings. """ # Clear the warning registry of the calling module # in order to re-raise the warnings. frame = sys._getframe(2) registry = frame.f_globals.get('__warningregistry__') if registry: registry.clear() with warnings.catch_warnings(record=True) as w: # Set filter "always" to record all warnings. Because # test_warnings swap the module, we need to look up in # the sys.modules dictionary. sys.modules['warnings'].simplefilter("always") yield WarningsRecorder(w) # Filter the recorded warnings reraise = list(w) missing = [] for msg, cat in filters: seen = False for w in reraise[:]: warning = w.message # Filter out the matching messages if (re.match(msg, str(warning), re.I) and issubclass(warning.__class__, cat)): seen = True reraise.remove(w) if not seen and not quiet: # This filter caught nothing missing.append((msg, cat.__name__)) if reraise: raise AssertionError("unhandled warning %s" % reraise[0]) if missing: raise AssertionError("filter (%r, %s) did not catch any warning" % missing[0]) @contextlib.contextmanager def check_warnings(*filters, **kwargs): """Context manager to silence warnings. Accept 2-tuples as positional arguments: ("message regexp", WarningCategory) Optional argument: - if 'quiet' is True, it does not fail if a filter catches nothing (default True without argument, default False if some filters are defined) Without argument, it defaults to: check_warnings(("", Warning), quiet=True) """ quiet = kwargs.get('quiet') if not filters: filters = (("", Warning),) # Preserve backward compatibility if quiet is None: quiet = True return _filterwarnings(filters, quiet) @contextlib.contextmanager def check_no_warnings(testcase, message='', category=Warning, force_gc=False): """Context manager to check that no warnings are emitted. This context manager enables a given warning within its scope and checks that no warnings are emitted even with that warning enabled. If force_gc is True, a garbage collection is attempted before checking for warnings. This may help to catch warnings emitted when objects are deleted, such as ResourceWarning. Other keyword arguments are passed to warnings.filterwarnings(). """ with warnings.catch_warnings(record=True) as warns: warnings.filterwarnings('always', message=message, category=category) yield if force_gc: gc_collect() testcase.assertEqual(warns, []) @contextlib.contextmanager def check_no_resource_warning(testcase): """Context manager to check that no ResourceWarning is emitted. Usage: with check_no_resource_warning(self): f = open(...) ... del f You must remove the object which may emit ResourceWarning before the end of the context manager. """ with warnings.catch_warnings(record=True) as warns: warnings.filterwarnings('always', category=ResourceWarning) yield gc_collect() testcase.assertEqual(warns, []) class CleanImport(object): """Context manager to force import to return a new module reference. This is useful for testing module-level behaviours, such as the emission of a DeprecationWarning on import. Use like this: with CleanImport("foo"): importlib.import_module("foo") # new reference """ def __init__(self, *module_names): self.original_modules = sys.modules.copy() for module_name in module_names: if module_name in sys.modules: module = sys.modules[module_name] # It is possible that module_name is just an alias for # another module (e.g. stub for modules renamed in 3.x). # In that case, we also need delete the real module to clear # the import cache. if module.__name__ != module_name: del sys.modules[module.__name__] del sys.modules[module_name] def __enter__(self): return self def __exit__(self, *ignore_exc): sys.modules.update(self.original_modules) class EnvironmentVarGuard(collections.abc.MutableMapping): """Class to help protect the environment variable properly. Can be used as a context manager.""" def __init__(self): self._environ = os.environ self._changed = {} def __getitem__(self, envvar): return self._environ[envvar] def __setitem__(self, envvar, value): # Remember the initial value on the first access if envvar not in self._changed: self._changed[envvar] = self._environ.get(envvar) self._environ[envvar] = value def __delitem__(self, envvar): # Remember the initial value on the first access if envvar not in self._changed: self._changed[envvar] = self._environ.get(envvar) if envvar in self._environ: del self._environ[envvar] def keys(self): return self._environ.keys() def __iter__(self): return iter(self._environ) def __len__(self): return len(self._environ) def set(self, envvar, value): self[envvar] = value def unset(self, envvar): del self[envvar] def __enter__(self): return self def __exit__(self, *ignore_exc): for (k, v) in self._changed.items(): if v is None: if k in self._environ: del self._environ[k] else: self._environ[k] = v os.environ = self._environ class DirsOnSysPath(object): """Context manager to temporarily add directories to sys.path. This makes a copy of sys.path, appends any directories given as positional arguments, then reverts sys.path to the copied settings when the context ends. Note that *all* sys.path modifications in the body of the context manager, including replacement of the object, will be reverted at the end of the block. """ def __init__(self, *paths): self.original_value = sys.path[:] self.original_object = sys.path sys.path.extend(paths) def __enter__(self): return self def __exit__(self, *ignore_exc): sys.path = self.original_object sys.path[:] = self.original_value class TransientResource(object): """Raise ResourceDenied if an exception is raised while the context manager is in effect that matches the specified exception and attributes.""" def __init__(self, exc, **kwargs): self.exc = exc self.attrs = kwargs def __enter__(self): return self def __exit__(self, type_=None, value=None, traceback=None): """If type_ is a subclass of self.exc and value has attributes matching self.attrs, raise ResourceDenied. Otherwise let the exception propagate (if any).""" if type_ is not None and issubclass(self.exc, type_): for attr, attr_value in self.attrs.items(): if not hasattr(value, attr): break if getattr(value, attr) != attr_value: break else: raise ResourceDenied("an optional resource is not available") # Context managers that raise ResourceDenied when various issues # with the Internet connection manifest themselves as exceptions. # XXX deprecate these and use transient_internet() instead time_out = TransientResource(OSError, errno=errno.ETIMEDOUT) socket_peer_reset = TransientResource(OSError, errno=errno.ECONNRESET) ioerror_peer_reset = TransientResource(OSError, errno=errno.ECONNRESET) @contextlib.contextmanager def transient_internet(resource_name, *, timeout=30.0, errnos=()): """Return a context manager that raises ResourceDenied when various issues with the Internet connection manifest themselves as exceptions.""" default_errnos = [ ('ECONNREFUSED', 111), ('ECONNRESET', 104), ('EHOSTUNREACH', 113), ('ENETUNREACH', 101), ('ETIMEDOUT', 110), # socket.create_connection() fails randomly with # EADDRNOTAVAIL on Travis CI. ('EADDRNOTAVAIL', 99), ] default_gai_errnos = [ ('EAI_AGAIN', -3), ('EAI_FAIL', -4), ('EAI_NONAME', -2), ('EAI_NODATA', -5), # Encountered when trying to resolve IPv6-only hostnames ('WSANO_DATA', 11004), ] denied = ResourceDenied("Resource %r is not available" % resource_name) captured_errnos = errnos gai_errnos = [] if not captured_errnos: captured_errnos = [getattr(errno, name, num) for (name, num) in default_errnos] gai_errnos = [getattr(socket, name, num) for (name, num) in default_gai_errnos] def filter_error(err): n = getattr(err, 'errno', None) if (isinstance(err, socket.timeout) or (isinstance(err, socket.gaierror) and n in gai_errnos) or (isinstance(err, urllib.error.HTTPError) and 500 <= err.code <= 599) or (isinstance(err, urllib.error.URLError) and (("ConnectionRefusedError" in err.reason) or ("TimeoutError" in err.reason) or ("EOFError" in err.reason))) or n in captured_errnos): if not verbose: sys.stderr.write(denied.args[0] + "\n") raise denied from err old_timeout = socket.getdefaulttimeout() try: if timeout is not None: socket.setdefaulttimeout(timeout) yield except nntplib.NNTPTemporaryError as err: if verbose: sys.stderr.write(denied.args[0] + "\n") raise denied from err except OSError as err: # urllib can wrap original socket errors multiple times (!), we must # unwrap to get at the original error. while True: a = err.args if len(a) >= 1 and isinstance(a[0], OSError): err = a[0] # The error can also be wrapped as args[1]: # except socket.error as msg: # raise OSError('socket error', msg).with_traceback(sys.exc_info()[2]) elif len(a) >= 2 and isinstance(a[1], OSError): err = a[1] else: break filter_error(err) raise # XXX should we catch generic exceptions and look for their # __cause__ or __context__? finally: socket.setdefaulttimeout(old_timeout) @contextlib.contextmanager def captured_output(stream_name): """Return a context manager used by captured_stdout/stdin/stderr that temporarily replaces the sys stream *stream_name* with a StringIO.""" import io orig_stdout = getattr(sys, stream_name) setattr(sys, stream_name, io.StringIO()) try: yield getattr(sys, stream_name) finally: setattr(sys, stream_name, orig_stdout) def captured_stdout(): """Capture the output of sys.stdout: with captured_stdout() as stdout: print("hello") self.assertEqual(stdout.getvalue(), "hello\\n") """ return captured_output("stdout") def captured_stderr(): """Capture the output of sys.stderr: with captured_stderr() as stderr: print("hello", file=sys.stderr) self.assertEqual(stderr.getvalue(), "hello\\n") """ return captured_output("stderr") def captured_stdin(): """Capture the input to sys.stdin: with captured_stdin() as stdin: stdin.write('hello\\n') stdin.seek(0) # call test code that consumes from sys.stdin captured = input() self.assertEqual(captured, "hello") """ return captured_output("stdin") def gc_collect(): """Force as many objects as possible to be collected. In non-CPython implementations of Python, this is needed because timely deallocation is not guaranteed by the garbage collector. (Even in CPython this can be the case in case of reference cycles.) This means that __del__ methods may be called later than expected and weakrefs may remain alive for longer than expected. This function tries its best to force all garbage objects to disappear. """ gc.collect() if is_jython: time.sleep(0.1) gc.collect() gc.collect() @contextlib.contextmanager def disable_gc(): have_gc = gc.isenabled() gc.disable() try: yield finally: if have_gc: gc.enable() def python_is_optimized(): """Find if Python was built with optimizations.""" cflags = sysconfig.get_config_var('PY_CFLAGS') or '' final_opt = "" for opt in cflags.split(): if opt.startswith('-O'): final_opt = opt return final_opt not in ('', '-O0', '-Og') _header = 'nP' _align = '0n' if hasattr(sys, "gettotalrefcount"): _header = '2P' + _header _align = '0P' _vheader = _header + 'n' def calcobjsize(fmt): return struct.calcsize(_header + fmt + _align) def calcvobjsize(fmt): return struct.calcsize(_vheader + fmt + _align) _TPFLAGS_HAVE_GC = 1<<14 _TPFLAGS_HEAPTYPE = 1<<9 def check_sizeof(test, o, size): import _testcapi result = sys.getsizeof(o) # add GC header size if ((type(o) == type) and (o.__flags__ & _TPFLAGS_HEAPTYPE) or\ ((type(o) != type) and (type(o).__flags__ & _TPFLAGS_HAVE_GC))): size += _testcapi.SIZEOF_PYGC_HEAD msg = 'wrong size for %s: got %d, expected %d' \ % (type(o), result, size) test.assertEqual(result, size, msg) #======================================================================= # Decorator for running a function in a different locale, correctly resetting # it afterwards. def run_with_locale(catstr, *locales): def decorator(func): def inner(*args, **kwds): try: import locale category = getattr(locale, catstr) orig_locale = locale.setlocale(category) except AttributeError: # if the test author gives us an invalid category string raise except: # cannot retrieve original locale, so do nothing locale = orig_locale = None else: for loc in locales: try: locale.setlocale(category, loc) break except: pass # now run the function, resetting the locale on exceptions try: return func(*args, **kwds) finally: if locale and orig_locale: locale.setlocale(category, orig_locale) inner.__name__ = func.__name__ inner.__doc__ = func.__doc__ return inner return decorator #======================================================================= # Decorator for running a function in a specific timezone, correctly # resetting it afterwards. def run_with_tz(tz): def decorator(func): def inner(*args, **kwds): try: tzset = time.tzset except AttributeError: raise unittest.SkipTest("tzset required") if 'TZ' in os.environ: orig_tz = os.environ['TZ'] else: orig_tz = None os.environ['TZ'] = tz tzset() # now run the function, resetting the tz on exceptions try: return func(*args, **kwds) finally: if orig_tz is None: del os.environ['TZ'] else: os.environ['TZ'] = orig_tz time.tzset() inner.__name__ = func.__name__ inner.__doc__ = func.__doc__ return inner return decorator #======================================================================= # Big-memory-test support. Separate from 'resources' because memory use # should be configurable. # Some handy shorthands. Note that these are used for byte-limits as well # as size-limits, in the various bigmem tests _1M = 1024*1024 _1G = 1024 * _1M _2G = 2 * _1G _4G = 4 * _1G MAX_Py_ssize_t = sys.maxsize def set_memlimit(limit): global max_memuse global real_max_memuse sizes = { 'k': 1024, 'm': _1M, 'g': _1G, 't': 1024*_1G, } m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit, re.IGNORECASE | re.VERBOSE) if m is None: raise ValueError('Invalid memory limit %r' % (limit,)) memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()]) real_max_memuse = memlimit if memlimit > MAX_Py_ssize_t: memlimit = MAX_Py_ssize_t if memlimit < _2G - 1: raise ValueError('Memory limit %r too low to be useful' % (limit,)) max_memuse = memlimit class _MemoryWatchdog: """An object which periodically watches the process' memory consumption and prints it out. """ def __init__(self): self.procfile = '/proc/{pid}/statm'.format(pid=os.getpid()) self.started = False def start(self): try: f = open(self.procfile, 'r') except OSError as e: warnings.warn('/proc not available for stats: {}'.format(e), RuntimeWarning) sys.stderr.flush() return watchdog_script = findfile("memory_watchdog.py") self.mem_watchdog = subprocess.Popen([sys.executable, watchdog_script], stdin=f, stderr=subprocess.DEVNULL) f.close() self.started = True def stop(self): if self.started: self.mem_watchdog.terminate() self.mem_watchdog.wait() def bigmemtest(size, memuse, dry_run=True): """Decorator for bigmem tests. 'size' is a requested size for the test (in arbitrary, test-interpreted units.) 'memuse' is the number of bytes per unit for the test, or a good estimate of it. For example, a test that needs two byte buffers, of 4 GiB each, could be decorated with @bigmemtest(size=_4G, memuse=2). The 'size' argument is normally passed to the decorated test method as an extra argument. If 'dry_run' is true, the value passed to the test method may be less than the requested value. If 'dry_run' is false, it means the test doesn't support dummy runs when -M is not specified. """ def decorator(f): def wrapper(self): size = wrapper.size memuse = wrapper.memuse if not real_max_memuse: maxsize = 5147 else: maxsize = size if ((real_max_memuse or not dry_run) and real_max_memuse < maxsize * memuse): raise unittest.SkipTest( "not enough memory: %.1fG minimum needed" % (size * memuse / (1024 ** 3))) if real_max_memuse and verbose: print() print(" ... expected peak memory use: {peak:.1f}G" .format(peak=size * memuse / (1024 ** 3))) watchdog = _MemoryWatchdog() watchdog.start() else: watchdog = None try: return f(self, maxsize) finally: if watchdog: watchdog.stop() wrapper.size = size wrapper.memuse = memuse return wrapper return decorator def bigaddrspacetest(f): """Decorator for tests that fill the address space.""" def wrapper(self): if max_memuse < MAX_Py_ssize_t: if MAX_Py_ssize_t >= 2**63 - 1 and max_memuse >= 2**31: raise unittest.SkipTest( "not enough memory: try a 32-bit build instead") else: raise unittest.SkipTest( "not enough memory: %.1fG minimum needed" % (MAX_Py_ssize_t / (1024 ** 3))) else: return f(self) return wrapper #======================================================================= # unittest integration. class BasicTestRunner: def run(self, test): result = unittest.TestResult() test(result) return result def _id(obj): return obj def requires_resource(resource): if resource == 'gui' and not _is_gui_available(): return unittest.skip(_is_gui_available.reason) if is_resource_enabled(resource): return _id else: return unittest.skip("resource {0!r} is not enabled".format(resource)) def requires_android_level(level, reason): if is_android and _ANDROID_API_LEVEL < level: return unittest.skip('%s at Android API level %d' % (reason, _ANDROID_API_LEVEL)) else: return _id def cpython_only(test): """ Decorator for tests only applicable on CPython. """ return impl_detail(cpython=True)(test) def impl_detail(msg=None, **guards): if check_impl_detail(**guards): return _id if msg is None: guardnames, default = _parse_guards(guards) if default: msg = "implementation detail not available on {0}" else: msg = "implementation detail specific to {0}" guardnames = sorted(guardnames.keys()) msg = msg.format(' or '.join(guardnames)) return unittest.skip(msg) _have_mp_queue = None def requires_multiprocessing_queue(test): """Skip decorator for tests that use multiprocessing.Queue.""" global _have_mp_queue if _have_mp_queue is None: import multiprocessing # Without a functioning shared semaphore implementation attempts to # instantiate a Queue will result in an ImportError (issue #3770). try: multiprocessing.Queue() _have_mp_queue = True except ImportError: _have_mp_queue = False msg = "requires a functioning shared semaphore implementation" return test if _have_mp_queue else unittest.skip(msg)(test) def _parse_guards(guards): # Returns a tuple ({platform_name: run_me}, default_value) if not guards: return ({'cpython': True}, False) is_true = list(guards.values())[0] assert list(guards.values()) == [is_true] * len(guards) # all True or all False return (guards, not is_true) # Use the following check to guard CPython's implementation-specific tests -- # or to run them only on the implementation(s) guarded by the arguments. def check_impl_detail(**guards): """This function returns True or False depending on the host platform. Examples: if check_impl_detail(): # only on CPython (default) if check_impl_detail(jython=True): # only on Jython if check_impl_detail(cpython=False): # everywhere except on CPython """ guards, default = _parse_guards(guards) return guards.get(platform.python_implementation().lower(), default) def no_tracing(func): """Decorator to temporarily turn off tracing for the duration of a test.""" if not hasattr(sys, 'gettrace'): return func else: @functools.wraps(func) def wrapper(*args, **kwargs): original_trace = sys.gettrace() try: sys.settrace(None) return func(*args, **kwargs) finally: sys.settrace(original_trace) return wrapper def refcount_test(test): """Decorator for tests which involve reference counting. To start, the decorator does not run the test if is not run by CPython. After that, any trace function is unset during the test to prevent unexpected refcounts caused by the trace function. """ return no_tracing(cpython_only(test)) def _filter_suite(suite, pred): """Recursively filter test cases in a suite based on a predicate.""" newtests = [] for test in suite._tests: if isinstance(test, unittest.TestSuite): _filter_suite(test, pred) newtests.append(test) else: if pred(test): newtests.append(test) suite._tests = newtests def _run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" runner = get_test_runner(sys.stdout, verbosity=verbose, capture_output=(junit_xml_list is not None)) result = runner.run(suite) if junit_xml_list is not None: junit_xml_list.append(result.get_xml_element()) if not result.testsRun: raise TestDidNotRun if not result.wasSuccessful(): if len(result.errors) == 1 and not result.failures: err = result.errors[0][1] elif len(result.failures) == 1 and not result.errors: err = result.failures[0][1] else: err = "multiple errors occurred" if not verbose: err += "; run in verbose mode for details" raise TestFailed(err) # By default, don't filter tests _match_test_func = None _match_test_patterns = None def match_test(test): # Function used by support.run_unittest() and regrtest --list-cases if _match_test_func is None: return True else: return _match_test_func(test.id()) def _is_full_match_test(pattern): # If a pattern contains at least one dot, it's considered # as a full test identifier. # Example: 'test.test_os.FileTests.test_access'. # # Reject patterns which contain fnmatch patterns: '*', '?', '[...]' # or '[!...]'. For example, reject 'test_access*'. return ('.' in pattern) and (not re.search(r'[?*\[\]]', pattern)) def set_match_tests(patterns): global _match_test_func, _match_test_patterns if patterns == _match_test_patterns: # No change: no need to recompile patterns. return if not patterns: func = None # set_match_tests(None) behaves as set_match_tests(()) patterns = () elif all(map(_is_full_match_test, patterns)): # Simple case: all patterns are full test identifier. # The test.bisect utility only uses such full test identifiers. func = set(patterns).__contains__ else: regex = '|'.join(map(fnmatch.translate, patterns)) # The search *is* case sensitive on purpose: # don't use flags=re.IGNORECASE regex_match = re.compile(regex).match def match_test_regex(test_id): if regex_match(test_id): # The regex matchs the whole identifier like # 'test.test_os.FileTests.test_access' return True else: # Try to match parts of the test identifier. # For example, split 'test.test_os.FileTests.test_access' # into: 'test', 'test_os', 'FileTests' and 'test_access'. return any(map(regex_match, test_id.split("."))) func = match_test_regex # Create a copy since patterns can be mutable and so modified later _match_test_patterns = tuple(patterns) _match_test_func = func def run_unittest(*classes): """Run tests from unittest.TestCase-derived classes.""" valid_types = (unittest.TestSuite, unittest.TestCase) suite = unittest.TestSuite() for cls in classes: if isinstance(cls, str): if cls in sys.modules: suite.addTest(unittest.findTestCases(sys.modules[cls])) else: raise ValueError("str arguments must be keys in sys.modules") elif isinstance(cls, valid_types): suite.addTest(cls) else: suite.addTest(unittest.makeSuite(cls)) _filter_suite(suite, match_test) _run_suite(suite) #======================================================================= # Check for the presence of docstrings. # Rather than trying to enumerate all the cases where docstrings may be # disabled, we just check for that directly def _check_docstrings(): """Just used to check if docstrings are enabled""" MISSING_C_DOCSTRINGS = (check_impl_detail() and sys.platform != 'win32' and not sysconfig.get_config_var('WITH_DOC_STRINGS')) HAVE_DOCSTRINGS = (_check_docstrings.__doc__ is not None and not MISSING_C_DOCSTRINGS) requires_docstrings = unittest.skipUnless(HAVE_DOCSTRINGS, "test requires docstrings") #======================================================================= # doctest driver. def run_doctest(module, verbosity=None, optionflags=0): """Run doctest on the given module. Return (#failures, #tests). If optional argument verbosity is not specified (or is None), pass support's belief about verbosity on to doctest. Else doctest's usual behavior is used (it searches sys.argv for -v). """ import doctest if verbosity is None: verbosity = verbose else: verbosity = None f, t = doctest.testmod(module, verbose=verbosity, optionflags=optionflags) if f: raise TestFailed("%d of %d doctests failed" % (f, t)) if verbose: print('doctest (%s) ... %d tests with zero failures' % (module.__name__, t)) return f, t #======================================================================= # Support for saving and restoring the imported modules. def modules_setup(): return sys.modules.copy(), def modules_cleanup(oldmodules): # Encoders/decoders are registered permanently within the internal # codec cache. If we destroy the corresponding modules their # globals will be set to None which will trip up the cached functions. encodings = [(k, v) for k, v in sys.modules.items() if k.startswith('encodings.')] sys.modules.clear() sys.modules.update(encodings) # XXX: This kind of problem can affect more than just encodings. In particular # extension modules (such as _ssl) don't cope with reloading properly. # Really, test modules should be cleaning out the test specific modules they # know they added (ala test_runpy) rather than relying on this function (as # test_importhooks and test_pkg do currently). # Implicitly imported *real* modules should be left alone (see issue 10556). sys.modules.update(oldmodules) #======================================================================= # Threading support to prevent reporting refleaks when running regrtest.py -R # Flag used by saved_test_environment of test.libregrtest.save_env, # to check if a test modified the environment. The flag should be set to False # before running a new test. # # For example, threading_cleanup() sets the flag is the function fails # to cleanup threads. environment_altered = False # NOTE: we use thread._count() rather than threading.enumerate() (or the # moral equivalent thereof) because a threading.Thread object is still alive # until its __bootstrap() method has returned, even after it has been # unregistered from the threading module. # thread._count(), on the other hand, only gets decremented *after* the # __bootstrap() method has returned, which gives us reliable reference counts # at the end of a test run. def threading_setup(): if _thread: return _thread._count(), threading._dangling.copy() else: return 1, () def threading_cleanup(*original_values): if not _thread: return _MAX_COUNT = 100 for count in range(_MAX_COUNT): values = _thread._count(), threading._dangling if values == original_values: break time.sleep(0.01) gc_collect() # XXX print a warning in case of failure? def reap_threads(func): """Use this function when threads are being used. This will ensure that the threads are cleaned up even when the test fails. If threading is unavailable this function does nothing. """ if not _thread: return func @functools.wraps(func) def decorator(*args): key = threading_setup() try: return func(*args) finally: threading_cleanup(*key) return decorator @contextlib.contextmanager def wait_threads_exit(timeout=60.0): """ bpo-31234: Context manager to wait until all threads created in the with statement exit. Use _thread.count() to check if threads exited. Indirectly, wait until threads exit the internal t_bootstrap() C function of the _thread module. threading_setup() and threading_cleanup() are designed to emit a warning if a test leaves running threads in the background. This context manager is designed to cleanup threads started by the _thread.start_new_thread() which doesn't allow to wait for thread exit, whereas thread.Thread has a join() method. """ old_count = _thread._count() try: yield finally: start_time = time.monotonic() deadline = start_time + timeout while True: count = _thread._count() if count <= old_count: break if time.monotonic() > deadline: dt = time.monotonic() - start_time msg = (f"wait_threads() failed to cleanup {count - old_count} " f"threads after {dt:.1f} seconds " f"(count: {count}, old count: {old_count})") raise AssertionError(msg) time.sleep(0.010) gc_collect() def reap_children(): """Use this function at the end of test_main() whenever sub-processes are started. This will help ensure that no extra children (zombies) stick around to hog resources and create problems when looking for refleaks. """ # Reap all our dead child processes so we don't leave zombies around. # These hog resources and might be causing some of the buildbots to die. if hasattr(os, 'waitpid'): any_process = -1 while True: try: # This will raise an exception on Windows. That's ok. pid, status = os.waitpid(any_process, os.WNOHANG) if pid == 0: break print("Warning -- reap_children() reaped child process %s" % pid, file=sys.stderr) except: break @contextlib.contextmanager def start_threads(threads, unlock=None): threads = list(threads) started = [] try: try: for t in threads: t.start() started.append(t) except: if verbose: print("Can't start %d threads, only %d threads started" % (len(threads), len(started))) raise yield finally: try: if unlock: unlock() endtime = starttime = time.time() for timeout in range(1, 16): endtime += 60 for t in started: t.join(max(endtime - time.time(), 0.01)) started = [t for t in started if t.isAlive()] if not started: break if verbose: print('Unable to join %d threads during a period of ' '%d minutes' % (len(started), timeout)) finally: started = [t for t in started if t.isAlive()] if started: faulthandler.dump_traceback(sys.stdout) raise AssertionError('Unable to join %d threads' % len(started)) @contextlib.contextmanager def swap_attr(obj, attr, new_val): """Temporary swap out an attribute with a new object. Usage: with swap_attr(obj, "attr", 5): ... This will set obj.attr to 5 for the duration of the with: block, restoring the old value at the end of the block. If `attr` doesn't exist on `obj`, it will be created and then deleted at the end of the block. The old value (or None if it doesn't exist) will be assigned to the target of the "as" clause, if there is one. """ if hasattr(obj, attr): real_val = getattr(obj, attr) setattr(obj, attr, new_val) try: yield real_val finally: setattr(obj, attr, real_val) else: setattr(obj, attr, new_val) try: yield finally: if hasattr(obj, attr): delattr(obj, attr) @contextlib.contextmanager def swap_item(obj, item, new_val): """Temporary swap out an item with a new object. Usage: with swap_item(obj, "item", 5): ... This will set obj["item"] to 5 for the duration of the with: block, restoring the old value at the end of the block. If `item` doesn't exist on `obj`, it will be created and then deleted at the end of the block. The old value (or None if it doesn't exist) will be assigned to the target of the "as" clause, if there is one. """ if item in obj: real_val = obj[item] obj[item] = new_val try: yield real_val finally: obj[item] = real_val else: obj[item] = new_val try: yield finally: if item in obj: del obj[item] def strip_python_stderr(stderr): """Strip the stderr of a Python process from potential debug output emitted by the interpreter. This will typically be run on the result of the communicate() method of a subprocess.Popen object. """ stderr = re.sub(br"\[\d+ refs, \d+ blocks\]\r?\n?", b"", stderr).strip() return stderr requires_type_collecting = unittest.skipIf(hasattr(sys, 'getcounts'), 'types are immortal if COUNT_ALLOCS is defined') def args_from_interpreter_flags(): """Return a list of command-line arguments reproducing the current settings in sys.flags and sys.warnoptions.""" return subprocess._args_from_interpreter_flags() def optim_args_from_interpreter_flags(): """Return a list of command-line arguments reproducing the current optimization settings in sys.flags.""" return subprocess._optim_args_from_interpreter_flags() #============================================================ # Support for assertions about logging. #============================================================ class TestHandler(logging.handlers.BufferingHandler): def __init__(self, matcher): # BufferingHandler takes a "capacity" argument # so as to know when to flush. As we're overriding # shouldFlush anyway, we can set a capacity of zero. # You can call flush() manually to clear out the # buffer. logging.handlers.BufferingHandler.__init__(self, 0) self.matcher = matcher def shouldFlush(self): return False def emit(self, record): self.format(record) self.buffer.append(record.__dict__) def matches(self, **kwargs): """ Look for a saved dict whose keys/values match the supplied arguments. """ result = False for d in self.buffer: if self.matcher.matches(d, **kwargs): result = True break return result class Matcher(object): _partial_matches = ('msg', 'message') def matches(self, d, **kwargs): """ Try to match a single dict with the supplied arguments. Keys whose values are strings and which are in self._partial_matches will be checked for partial (i.e. substring) matches. You can extend this scheme to (for example) do regular expression matching, etc. """ result = True for k in kwargs: v = kwargs[k] dv = d.get(k) if not self.match_value(k, dv, v): result = False break return result def match_value(self, k, dv, v): """ Try to match a single stored value (dv) with a supplied value (v). """ if type(v) != type(dv): result = False elif type(dv) is not str or k not in self._partial_matches: result = (v == dv) else: result = dv.find(v) >= 0 return result _can_symlink = None def can_symlink(): global _can_symlink if _can_symlink is not None: return _can_symlink symlink_path = TESTFN + "can_symlink" try: os.symlink(TESTFN, symlink_path) can = True except (OSError, NotImplementedError, AttributeError): can = False else: os.remove(symlink_path) _can_symlink = can return can def skip_unless_symlink(test): """Skip decorator for tests that require functional symlink""" ok = can_symlink() msg = "Requires functional symlink implementation" return test if ok else unittest.skip(msg)(test) _can_xattr = None def can_xattr(): global _can_xattr if _can_xattr is not None: return _can_xattr if not hasattr(os, "setxattr"): can = False else: tmp_dir = tempfile.mkdtemp() tmp_fp, tmp_name = tempfile.mkstemp(dir=tmp_dir) try: with open(TESTFN, "wb") as fp: try: # TESTFN & tempfile may use different file systems with # different capabilities os.setxattr(tmp_fp, b"user.test", b"") os.setxattr(tmp_name, b"trusted.foo", b"42") os.setxattr(fp.fileno(), b"user.test", b"") # Kernels < 2.6.39 don't respect setxattr flags. kernel_version = platform.release() m = re.match(r"2.6.(\d{1,2})", kernel_version) can = m is None or int(m.group(1)) >= 39 except OSError: can = False finally: unlink(TESTFN) unlink(tmp_name) rmdir(tmp_dir) _can_xattr = can return can def skip_unless_xattr(test): """Skip decorator for tests that require functional extended attributes""" ok = can_xattr() msg = "no non-broken extended attribute support" return test if ok else unittest.skip(msg)(test) def skip_if_pgo_task(test): """Skip decorator for tests not run in (non-extended) PGO task""" ok = not PGO or PGO_EXTENDED msg = "Not run for (non-extended) PGO task" return test if ok else unittest.skip(msg)(test) def fs_is_case_insensitive(directory): """Detects if the file system for the specified directory is case-insensitive.""" with tempfile.NamedTemporaryFile(dir=directory) as base: base_path = base.name case_path = base_path.upper() if case_path == base_path: case_path = base_path.lower() try: return os.path.samefile(base_path, case_path) except FileNotFoundError: return False def detect_api_mismatch(ref_api, other_api, *, ignore=()): """Returns the set of items in ref_api not in other_api, except for a defined list of items to be ignored in this check. By default this skips private attributes beginning with '_' but includes all magic methods, i.e. those starting and ending in '__'. """ missing_items = set(dir(ref_api)) - set(dir(other_api)) if ignore: missing_items -= set(ignore) missing_items = set(m for m in missing_items if not m.startswith('_') or m.endswith('__')) return missing_items def check__all__(test_case, module, name_of_module=None, extra=(), blacklist=()): """Assert that the __all__ variable of 'module' contains all public names. The module's public names (its API) are detected automatically based on whether they match the public name convention and were defined in 'module'. The 'name_of_module' argument can specify (as a string or tuple thereof) what module(s) an API could be defined in in order to be detected as a public API. One case for this is when 'module' imports part of its public API from other modules, possibly a C backend (like 'csv' and its '_csv'). The 'extra' argument can be a set of names that wouldn't otherwise be automatically detected as "public", like objects without a proper '__module__' attribute. If provided, it will be added to the automatically detected ones. The 'blacklist' argument can be a set of names that must not be treated as part of the public API even though their names indicate otherwise. Usage: import bar import foo import unittest from test import support class MiscTestCase(unittest.TestCase): def test__all__(self): support.check__all__(self, foo) class OtherTestCase(unittest.TestCase): def test__all__(self): extra = {'BAR_CONST', 'FOO_CONST'} blacklist = {'baz'} # Undocumented name. # bar imports part of its API from _bar. support.check__all__(self, bar, ('bar', '_bar'), extra=extra, blacklist=blacklist) """ if name_of_module is None: name_of_module = (module.__name__, ) elif isinstance(name_of_module, str): name_of_module = (name_of_module, ) expected = set(extra) for name in dir(module): if name.startswith('_') or name in blacklist: continue obj = getattr(module, name) if (getattr(obj, '__module__', None) in name_of_module or (not hasattr(obj, '__module__') and not isinstance(obj, types.ModuleType))): expected.add(name) test_case.assertCountEqual(module.__all__, expected) class SuppressCrashReport: """Try to prevent a crash report from popping up. On Windows, don't display the Windows Error Reporting dialog. On UNIX, disable the creation of coredump file. """ old_value = None old_modes = None def __enter__(self): """On Windows, disable Windows Error Reporting dialogs using SetErrorMode. On UNIX, try to save the previous core file size limit, then set soft limit to 0. """ if sys.platform.startswith('win'): # see http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx # GetErrorMode is not available on Windows XP and Windows Server 2003, # but SetErrorMode returns the previous value, so we can use that import ctypes self._k32 = ctypes.windll.kernel32 SEM_NOGPFAULTERRORBOX = 0x02 self.old_value = self._k32.SetErrorMode(SEM_NOGPFAULTERRORBOX) self._k32.SetErrorMode(self.old_value | SEM_NOGPFAULTERRORBOX) # Suppress assert dialogs in debug builds # (see http://bugs.python.org/issue23314) try: import msvcrt msvcrt.CrtSetReportMode except (AttributeError, ImportError): # no msvcrt or a release build pass else: self.old_modes = {} for report_type in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: old_mode = msvcrt.CrtSetReportMode(report_type, msvcrt.CRTDBG_MODE_FILE) old_file = msvcrt.CrtSetReportFile(report_type, msvcrt.CRTDBG_FILE_STDERR) self.old_modes[report_type] = old_mode, old_file else: if resource is not None: try: self.old_value = resource.getrlimit(resource.RLIMIT_CORE) resource.setrlimit(resource.RLIMIT_CORE, (0, self.old_value[1])) except (ValueError, OSError): pass if sys.platform == 'darwin': # Check if the 'Crash Reporter' on OSX was configured # in 'Developer' mode and warn that it will get triggered # when it is. # # This assumes that this context manager is used in tests # that might trigger the next manager. cmd = ['/usr/bin/defaults', 'read', 'com.apple.CrashReporter', 'DialogType'] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) with proc: stdout = proc.communicate()[0] if stdout.strip() == b'developer': print("this test triggers the Crash Reporter, " "that is intentional", end='', flush=True) return self def __exit__(self, *ignore_exc): """Restore Windows ErrorMode or core file behavior to initial value.""" if self.old_value is None: return if sys.platform.startswith('win'): self._k32.SetErrorMode(self.old_value) if self.old_modes: import msvcrt for report_type, (old_mode, old_file) in self.old_modes.items(): msvcrt.CrtSetReportMode(report_type, old_mode) msvcrt.CrtSetReportFile(report_type, old_file) else: if resource is not None: try: resource.setrlimit(resource.RLIMIT_CORE, self.old_value) except (ValueError, OSError): pass def patch(test_instance, object_to_patch, attr_name, new_value): """Override 'object_to_patch'.'attr_name' with 'new_value'. Also, add a cleanup procedure to 'test_instance' to restore 'object_to_patch' value for 'attr_name'. The 'attr_name' should be a valid attribute for 'object_to_patch'. """ # check that 'attr_name' is a real attribute for 'object_to_patch' # will raise AttributeError if it does not exist getattr(object_to_patch, attr_name) # keep a copy of the old value attr_is_local = False try: old_value = object_to_patch.__dict__[attr_name] except (AttributeError, KeyError): old_value = getattr(object_to_patch, attr_name, None) else: attr_is_local = True # restore the value when the test is done def cleanup(): if attr_is_local: setattr(object_to_patch, attr_name, old_value) else: delattr(object_to_patch, attr_name) test_instance.addCleanup(cleanup) # actually override the attribute setattr(object_to_patch, attr_name, new_value) def run_in_subinterp(code): """ Run code in a subinterpreter. Raise unittest.SkipTest if the tracemalloc module is enabled. """ # Issue #10915, #15751: PyGILState_*() functions don't work with # sub-interpreters, the tracemalloc module uses these functions internally try: import tracemalloc except ImportError: pass else: if tracemalloc.is_tracing(): raise unittest.SkipTest("run_in_subinterp() cannot be used " "if tracemalloc module is tracing " "memory allocations") import _testcapi return _testcapi.run_in_subinterp(code) def check_free_after_iterating(test, iter, cls, args=()): class A(cls): def __del__(self): nonlocal done done = True try: next(it) except StopIteration: pass done = False it = iter(A(*args)) # Issue 26494: Shouldn't crash test.assertRaises(StopIteration, next, it) # The sequence should be deallocated just after the end of iterating gc_collect() test.assertTrue(done) def missing_compiler_executable(cmd_names=[]): """Check if the compiler components used to build the interpreter exist. Check for the existence of the compiler executables whose names are listed in 'cmd_names' or all the compiler executables when 'cmd_names' is empty and return the first missing executable or None when none is found missing. """ from distutils import ccompiler, sysconfig, spawn compiler = ccompiler.new_compiler() sysconfig.customize_compiler(compiler) for name in compiler.executables: if cmd_names and name not in cmd_names: continue cmd = getattr(compiler, name) if cmd_names: assert cmd is not None, \ "the '%s' executable is not configured" % name elif cmd is None: continue if spawn.find_executable(cmd[0]) is None: return cmd[0] _is_android_emulator = None def setswitchinterval(interval): # Setting a very low gil interval on the Android emulator causes python # to hang (issue #26939). minimum_interval = 1e-5 if is_android and interval < minimum_interval: global _is_android_emulator if _is_android_emulator is None: _is_android_emulator = (subprocess.check_output( ['getprop', 'ro.kernel.qemu']).strip() == b'1') if _is_android_emulator: interval = minimum_interval return sys.setswitchinterval(interval) @contextlib.contextmanager def disable_faulthandler(): # use sys.__stderr__ instead of sys.stderr, since regrtest replaces # sys.stderr with a StringIO which has no file descriptor when a test # is run with -W/--verbose3. fd = sys.__stderr__.fileno() is_enabled = faulthandler.is_enabled() try: faulthandler.disable() yield finally: if is_enabled: faulthandler.enable(file=fd, all_threads=True) def fd_count(): """Count the number of open file descriptors. """ if sys.platform.startswith(('linux', 'freebsd')): try: names = os.listdir("/proc/self/fd") # Substract one because listdir() opens internally a file # descriptor to list the content of the /proc/self/fd/ directory. return len(names) - 1 except FileNotFoundError: pass MAXFD = 256 if hasattr(os, 'sysconf'): try: MAXFD = os.sysconf("SC_OPEN_MAX") except OSError: pass old_modes = None if sys.platform == 'win32': # bpo-25306, bpo-31009: Call CrtSetReportMode() to not kill the process # on invalid file descriptor if Python is compiled in debug mode try: import msvcrt msvcrt.CrtSetReportMode except (AttributeError, ImportError): # no msvcrt or a release build pass else: old_modes = {} for report_type in (msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT): old_modes[report_type] = msvcrt.CrtSetReportMode(report_type, 0) try: count = 0 for fd in range(MAXFD): try: # Prefer dup() over fstat(). fstat() can require input/output # whereas dup() doesn't. fd2 = os.dup(fd) except OSError as e: if e.errno != errno.EBADF: raise else: os.close(fd2) count += 1 finally: if old_modes is not None: for report_type in (msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT): msvcrt.CrtSetReportMode(report_type, old_modes[report_type]) return count class SaveSignals: """ Save an restore signal handlers. This class is only able to save/restore signal handlers registered by the Python signal module: see bpo-13285 for "external" signal handlers. """ def __init__(self): import signal self.signal = signal self.signals = list(range(1, signal.NSIG)) # SIGKILL and SIGSTOP signals cannot be ignored nor catched for signame in ('SIGKILL', 'SIGSTOP'): try: signum = getattr(signal, signame) except AttributeError: continue self.signals.remove(signum) self.handlers = {} def save(self): for signum in self.signals: handler = self.signal.getsignal(signum) if handler is None: # getsignal() returns None if a signal handler was not # registered by the Python signal module, # and the handler is not SIG_DFL nor SIG_IGN. # # Ignore the signal: we cannot restore the handler. continue self.handlers[signum] = handler def restore(self): for signum, handler in self.handlers.items(): self.signal.signal(signum, handler) class FakePath: """Simple implementing of the path protocol. """ def __init__(self, path): self.path = path def __repr__(self): return f'' def __fspath__(self): if (isinstance(self.path, BaseException) or isinstance(self.path, type) and issubclass(self.path, BaseException)): raise self.path else: return self.path @contextlib.contextmanager def adjust_int_max_str_digits(max_digits): """Temporarily change the integer string conversion length limit.""" current = sys.get_int_max_str_digits() try: sys.set_int_max_str_digits(max_digits) yield finally: sys.set_int_max_str_digits(current) def control_characters_c0(): """Returns a list of C0 control characters as strings. C0 control characters defined as the byte range 0x00-0x1F, and 0x7F. """ return [chr(c) for c in range(0x00, 0x20)] + ["\x7F"] usr/lib64/python3.8/lib2to3/pgen2/__init__.py000064400000000217152347077720014467 0ustar00# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """The pgen2 package.""" usr/lib64/python2.7/ensurepip/__init__.py000064400000016052152347106430014201 0ustar00#! /usr/bin/python2.7 from __future__ import print_function import distutils.version import glob import os import os.path import shutil import sys import tempfile __all__ = ["version", "bootstrap"] _WHEEL_DIR = "/usr/share/python{}-wheels/".format(sys.version_info[0]) def _get_most_recent_wheel_version(pkg): prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) suffix = "-py2.py3-none-any.whl" pattern = "{}*{}".format(prefix, suffix) versions = (p[len(prefix):-len(suffix)] for p in glob.glob(pattern)) return str(max(versions, key=distutils.version.LooseVersion)) _SETUPTOOLS_VERSION = _get_most_recent_wheel_version("setuptools") _PIP_VERSION = _get_most_recent_wheel_version("pip") _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION), ("pip", _PIP_VERSION), ] def _run_pip(args, additional_paths=None): # Add our bundled software to the sys.path so we can import it if additional_paths is not None: sys.path = additional_paths + sys.path # Install the bundled software try: # pip 10 from pip._internal import main except ImportError: # pip 9 from pip import main return main(args) def version(): """ Returns a string specifying the bundled version of pip. """ return _PIP_VERSION def _disable_pip_configuration_settings(): # We deliberately ignore all pip environment variables # when invoking pip # See http://bugs.python.org/issue19734 for details keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] for k in keys_to_remove: del os.environ[k] # We also ignore the settings in the default pip configuration file # See http://bugs.python.org/issue20053 for details os.environ['PIP_CONFIG_FILE'] = os.devnull def bootstrap(root=None, upgrade=False, user=False, altinstall=False, default_pip=True, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Note that calling this function will alter both sys.path and os.environ. """ # Discard the return value _bootstrap(root=root, upgrade=upgrade, user=user, altinstall=altinstall, default_pip=default_pip, verbosity=verbosity) def _bootstrap(root=None, upgrade=False, user=False, altinstall=False, default_pip=True, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Returns pip command status code. Note that calling this function will alter both sys.path and os.environ. """ if altinstall and default_pip: raise ValueError("Cannot use altinstall and default_pip together") _disable_pip_configuration_settings() # By default, installing pip and setuptools installs all of the # following scripts (X.Y == running Python version): # # pip, pipX, pipX.Y, easy_install, easy_install-X.Y # # pip 1.5+ allows ensurepip to request that some of those be left out if altinstall: # omit pip, pipX and easy_install os.environ["ENSUREPIP_OPTIONS"] = "altinstall" elif not default_pip: # omit pip and easy_install os.environ["ENSUREPIP_OPTIONS"] = "install" tmpdir = tempfile.mkdtemp() try: # Put our bundled wheels into a temporary directory and construct the # additional paths that need added to sys.path additional_paths = [] for project, version in _PROJECTS: wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version) with open(os.path.join(_WHEEL_DIR, wheel_name), "rb") as sfp: with open(os.path.join(tmpdir, wheel_name), "wb") as fp: fp.write(sfp.read()) additional_paths.append(os.path.join(tmpdir, wheel_name)) # Construct the arguments to be passed to the pip command args = ["install", "--no-index", "--find-links", tmpdir] if root: args += ["--root", root] if upgrade: args += ["--upgrade"] if user: args += ["--user"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) finally: shutil.rmtree(tmpdir, ignore_errors=True) def _uninstall_helper(verbosity=0): """Helper to support a clean default uninstall process on Windows Note that calling this function may alter os.environ. """ # Nothing to do if pip was never installed, or has been removed try: import pip except ImportError: return # If the pip version doesn't match the bundled one, leave it alone if pip.__version__ != _PIP_VERSION: msg = ("ensurepip will only uninstall a matching version " "({!r} installed, {!r} bundled)") print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) return _disable_pip_configuration_settings() # Construct the arguments to be passed to the pip command args = ["uninstall", "-y", "--disable-pip-version-check"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) def _main(argv=None): import argparse parser = argparse.ArgumentParser(prog="python -m ensurepip") parser.add_argument( "--version", action="version", version="pip {}".format(version()), help="Show the version of pip that is bundled with this Python.", ) parser.add_argument( "-v", "--verbose", action="count", default=0, dest="verbosity", help=("Give more output. Option is additive, and can be used up to 3 " "times."), ) parser.add_argument( "-U", "--upgrade", action="store_true", default=False, help="Upgrade pip and dependencies, even if already installed.", ) parser.add_argument( "--user", action="store_true", default=False, help="Install using the user scheme.", ) parser.add_argument( "--root", default=None, help="Install everything relative to this alternate root directory.", ) parser.add_argument( "--altinstall", action="store_true", default=False, help=("Make an alternate install, installing only the X.Y versioned " "scripts (Default: pipX, pipX.Y, easy_install-X.Y)."), ) parser.add_argument( "--default-pip", action="store_true", default=True, dest="default_pip", help=argparse.SUPPRESS, ) parser.add_argument( "--no-default-pip", action="store_false", dest="default_pip", help=("Make a non default install, installing only the X and X.Y " "versioned scripts."), ) args = parser.parse_args(argv) return _bootstrap( root=args.root, upgrade=args.upgrade, user=args.user, verbosity=args.verbosity, altinstall=args.altinstall, default_pip=args.default_pip, ) lib64/python2.7/lib2to3/__init__.py000064400000000007152347113440012624 0ustar00#empty lib64/python3.6/site-packages/rpm/__init__.py000064400000006334152347120240014671 0ustar00r"""RPM Module This module enables you to manipulate rpms and the rpm database. The rpm base module provides the main starting point for accessing RPM from Python. For most usage, call the TransactionSet method to get a transaction set (rpmts). For example: import rpm ts = rpm.TransactionSet() The transaction set will open the RPM database as needed, so in most cases, you do not need to explicitly open the database. The transaction set is the workhorse of RPM. You can open another RPM database, such as one that holds all packages for a given Linux distribution, to provide packages used to solve dependencies. To do this, use the following code: rpm.addMacro('_dbpath', '/path/to/alternate/database') solvets = rpm.TransactionSet() solvets.openDB() rpm.delMacro('_dbpath') # Open default database ts = rpm.TransactionSet() This code gives you access to two RPM databases through two transaction sets (rpmts): ts is a transaction set associated with the default RPM database and solvets is a transaction set tied to an alternate database, which is very useful for resolving dependencies. """ import warnings from rpm._rpm import * from rpm.transaction import * import rpm._rpm as _rpm _RPMVSF_NODIGESTS = _rpm._RPMVSF_NODIGESTS _RPMVSF_NOHEADER = _rpm._RPMVSF_NOHEADER _RPMVSF_NOPAYLOAD = _rpm._RPMVSF_NOPAYLOAD _RPMVSF_NOSIGNATURES = _rpm._RPMVSF_NOSIGNATURES __version__ = _rpm.__version__ __version_info__ = tuple(__version__.split('.')) # try to import build bits but dont require it try: from rpm._rpmb import * except ImportError: pass # try to import signing bits but dont require it try: from rpm._rpms import * except ImportError: pass # backwards compatibility + give the same class both ways ts = TransactionSet def headerLoad(*args, **kwds): """DEPRECATED! Use rpm.hdr() instead.""" warnings.warn("Use rpm.hdr() instead.", DeprecationWarning, stacklevel=2) return hdr(*args, **kwds) def _doHeaderListFromFD(rpm_fd, retrofit): hlist = [] while 1: try: h = hdr(rpm_fd) if retrofit: h.convert(HEADERCONV_RETROFIT_V3) hlist.append(h) except _rpm.error: break return hlist def readHeaderListFromFD(file_desc, retrofit=True): if not isinstance(file_desc, fd): file_desc = fd(file_desc) return _doHeaderListFromFD(file_desc, retrofit) def readHeaderListFromFile(path, retrofit=True): f = fd(path) hlist = _doHeaderListFromFD(f, retrofit) f.close() return hlist def readHeaderFromFD(file_desc): """Return (header, pos_before_hdr)""" if not isinstance(file_desc, fd): file_desc = fd(file_desc) try: offset = file_desc.tell() h = hdr(file_desc) except (_rpm.error, IOError): offset = None h = None return (h, offset) def signalsCaught(siglist): """Returns list of signals that were caught.""" caught = [] for sig in siglist: if signalCaught(sig): caught.append(sig) return caught def dsSingle(TagN, N, EVR="", Flags=RPMSENSE_ANY): """ Creates a single entry dependency set (ds) dsSingle(RPMTAG_CONFLICTNAME, "rpm") corresponds to "Conflicts: rpm" """ return ds((N, Flags, EVR), TagN) usr/lib64/python3.8/multiprocessing/dummy/__init__.py000064400000005765152347140570016567 0ustar00# # Support for the API of the multiprocessing package using threads # # multiprocessing/dummy/__init__.py # # Copyright (c) 2006-2008, R Oudkerk # Licensed to PSF under a Contributor Agreement. # __all__ = [ 'Process', 'current_process', 'active_children', 'freeze_support', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event', 'Barrier', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue' ] # # Imports # import threading import sys import weakref import array from .connection import Pipe from threading import Lock, RLock, Semaphore, BoundedSemaphore from threading import Event, Condition, Barrier from queue import Queue # # # class DummyProcess(threading.Thread): def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): threading.Thread.__init__(self, group, target, name, args, kwargs) self._pid = None self._children = weakref.WeakKeyDictionary() self._start_called = False self._parent = current_process() def start(self): if self._parent is not current_process(): raise RuntimeError( "Parent is {0!r} but current_process is {1!r}".format( self._parent, current_process())) self._start_called = True if hasattr(self._parent, '_children'): self._parent._children[self] = None threading.Thread.start(self) @property def exitcode(self): if self._start_called and not self.is_alive(): return 0 else: return None # # # Process = DummyProcess current_process = threading.current_thread current_process()._children = weakref.WeakKeyDictionary() def active_children(): children = current_process()._children for p in list(children): if not p.is_alive(): children.pop(p, None) return list(children) def freeze_support(): pass # # # class Namespace(object): def __init__(self, /, **kwds): self.__dict__.update(kwds) def __repr__(self): items = list(self.__dict__.items()) temp = [] for name, value in items: if not name.startswith('_'): temp.append('%s=%r' % (name, value)) temp.sort() return '%s(%s)' % (self.__class__.__name__, ', '.join(temp)) dict = dict list = list def Array(typecode, sequence, lock=True): return array.array(typecode, sequence) class Value(object): def __init__(self, typecode, value, lock=True): self._typecode = typecode self._value = value @property def value(self): return self._value @value.setter def value(self, value): self._value = value def __repr__(self): return '<%s(%r, %r)>'%(type(self).__name__,self._typecode,self._value) def Manager(): return sys.modules[__name__] def shutdown(): pass def Pool(processes=None, initializer=None, initargs=()): from ..pool import ThreadPool return ThreadPool(processes, initializer, initargs) JoinableQueue = Queue usr/lib64/python3.8/venv/__init__.py000064400000051106152347151260013147 0ustar00""" Virtual environment (venv) package for Python. Based on PEP 405. Copyright (C) 2011-2014 Vinay Sajip. Licensed to the PSF under a contributor agreement. """ import logging import os import shutil import subprocess import sys import sysconfig import types logger = logging.getLogger(__name__) class EnvBuilder: """ This class exists to allow virtual environment creation to be customized. The constructor parameters determine the builder's behaviour when called upon to create a virtual environment. By default, the builder makes the system (global) site-packages dir *un*available to the created environment. If invoked using the Python -m option, the default is to use copying on Windows platforms but symlinks elsewhere. If instantiated some other way, the default is to *not* use symlinks. :param system_site_packages: If True, the system (global) site-packages dir is available to created environments. :param clear: If True, delete the contents of the environment directory if it already exists, before environment creation. :param symlinks: If True, attempt to symlink rather than copy files into virtual environment. :param upgrade: If True, upgrade an existing virtual environment. :param with_pip: If True, ensure pip is installed in the virtual environment :param prompt: Alternative terminal prefix for the environment. """ def __init__(self, system_site_packages=False, clear=False, symlinks=False, upgrade=False, with_pip=False, prompt=None): self.system_site_packages = system_site_packages self.clear = clear self.symlinks = symlinks self.upgrade = upgrade self.with_pip = with_pip self.prompt = prompt def create(self, env_dir): """ Create a virtual environment in a directory. :param env_dir: The target directory to create an environment in. """ env_dir = os.path.abspath(env_dir) context = self.ensure_directories(env_dir) # See issue 24875. We need system_site_packages to be False # until after pip is installed. true_system_site_packages = self.system_site_packages self.system_site_packages = False self.create_configuration(context) self.setup_python(context) if self.with_pip: self._setup_pip(context) if not self.upgrade: self.setup_scripts(context) self.post_setup(context) if true_system_site_packages: # We had set it to False before, now # restore it and rewrite the configuration self.system_site_packages = True self.create_configuration(context) def clear_directory(self, path): for fn in os.listdir(path): fn = os.path.join(path, fn) if os.path.islink(fn) or os.path.isfile(fn): os.remove(fn) elif os.path.isdir(fn): shutil.rmtree(fn) def ensure_directories(self, env_dir): """ Create the directories for the environment. Returns a context object which holds paths in the environment, for use by subsequent logic. """ def create_if_needed(d): if not os.path.exists(d): os.makedirs(d) elif os.path.islink(d) or os.path.isfile(d): raise ValueError('Unable to create directory %r' % d) if os.path.exists(env_dir) and self.clear: self.clear_directory(env_dir) context = types.SimpleNamespace() context.env_dir = env_dir context.env_name = os.path.split(env_dir)[1] prompt = self.prompt if self.prompt is not None else context.env_name context.prompt = '(%s) ' % prompt create_if_needed(env_dir) executable = sys._base_executable dirname, exename = os.path.split(os.path.abspath(executable)) context.executable = executable context.python_dir = dirname context.python_exe = exename if sys.platform == 'win32': binname = 'Scripts' incpath = 'Include' libpath = os.path.join(env_dir, 'Lib', 'site-packages') else: binname = 'bin' incpath = 'include' libpath = os.path.join(env_dir, 'lib', 'python%d.%d' % sys.version_info[:2], 'site-packages') context.inc_path = path = os.path.join(env_dir, incpath) create_if_needed(path) create_if_needed(libpath) # Issue 21197: create lib64 as a symlink to lib on 64-bit non-OS X POSIX if ((sys.maxsize > 2**32) and (os.name == 'posix') and (sys.platform != 'darwin')): link_path = os.path.join(env_dir, 'lib64') if not os.path.exists(link_path): # Issue #21643 os.symlink('lib', link_path) context.bin_path = binpath = os.path.join(env_dir, binname) context.bin_name = binname context.env_exe = os.path.join(binpath, exename) create_if_needed(binpath) return context def create_configuration(self, context): """ Create a configuration file indicating where the environment's Python was copied from, and whether the system site-packages should be made available in the environment. :param context: The information for the environment creation request being processed. """ context.cfg_path = path = os.path.join(context.env_dir, 'pyvenv.cfg') with open(path, 'w', encoding='utf-8') as f: f.write('home = %s\n' % context.python_dir) if self.system_site_packages: incl = 'true' else: incl = 'false' f.write('include-system-site-packages = %s\n' % incl) f.write('version = %d.%d.%d\n' % sys.version_info[:3]) if self.prompt is not None: f.write(f'prompt = {self.prompt!r}\n') if os.name != 'nt': def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): """ Try symlinking a file, and if that fails, fall back to copying. """ force_copy = not self.symlinks if not force_copy: try: if not os.path.islink(dst): # can't link to itself! if relative_symlinks_ok: assert os.path.dirname(src) == os.path.dirname(dst) os.symlink(os.path.basename(src), dst) else: os.symlink(src, dst) except Exception: # may need to use a more specific exception logger.warning('Unable to symlink %r to %r', src, dst) force_copy = True if force_copy: shutil.copyfile(src, dst) else: def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): """ Try symlinking a file, and if that fails, fall back to copying. """ bad_src = os.path.lexists(src) and not os.path.exists(src) if self.symlinks and not bad_src and not os.path.islink(dst): try: if relative_symlinks_ok: assert os.path.dirname(src) == os.path.dirname(dst) os.symlink(os.path.basename(src), dst) else: os.symlink(src, dst) return except Exception: # may need to use a more specific exception logger.warning('Unable to symlink %r to %r', src, dst) # On Windows, we rewrite symlinks to our base python.exe into # copies of venvlauncher.exe basename, ext = os.path.splitext(os.path.basename(src)) srcfn = os.path.join(os.path.dirname(__file__), "scripts", "nt", basename + ext) # Builds or venv's from builds need to remap source file # locations, as we do not put them into Lib/venv/scripts if sysconfig.is_python_build(True) or not os.path.isfile(srcfn): if basename.endswith('_d'): ext = '_d' + ext basename = basename[:-2] if basename == 'python': basename = 'venvlauncher' elif basename == 'pythonw': basename = 'venvwlauncher' src = os.path.join(os.path.dirname(src), basename + ext) else: src = srcfn if not os.path.exists(src): if not bad_src: logger.warning('Unable to copy %r', src) return shutil.copyfile(src, dst) def setup_python(self, context): """ Set up a Python executable in the environment. :param context: The information for the environment creation request being processed. """ binpath = context.bin_path path = context.env_exe copier = self.symlink_or_copy dirname = context.python_dir if os.name != 'nt': copier(context.executable, path) if not os.path.islink(path): os.chmod(path, 0o755) for suffix in ('python', 'python3'): path = os.path.join(binpath, suffix) if not os.path.exists(path): # Issue 18807: make copies if # symlinks are not wanted copier(context.env_exe, path, relative_symlinks_ok=True) if not os.path.islink(path): os.chmod(path, 0o755) else: if self.symlinks: # For symlinking, we need a complete copy of the root directory # If symlinks fail, you'll get unnecessary copies of files, but # we assume that if you've opted into symlinks on Windows then # you know what you're doing. suffixes = [ f for f in os.listdir(dirname) if os.path.normcase(os.path.splitext(f)[1]) in ('.exe', '.dll') ] if sysconfig.is_python_build(True): suffixes = [ f for f in suffixes if os.path.normcase(f).startswith(('python', 'vcruntime')) ] else: suffixes = ['python.exe', 'python_d.exe', 'pythonw.exe', 'pythonw_d.exe'] for suffix in suffixes: src = os.path.join(dirname, suffix) if os.path.lexists(src): copier(src, os.path.join(binpath, suffix)) if sysconfig.is_python_build(True): # copy init.tcl for root, dirs, files in os.walk(context.python_dir): if 'init.tcl' in files: tcldir = os.path.basename(root) tcldir = os.path.join(context.env_dir, 'Lib', tcldir) if not os.path.exists(tcldir): os.makedirs(tcldir) src = os.path.join(root, 'init.tcl') dst = os.path.join(tcldir, 'init.tcl') shutil.copyfile(src, dst) break def _setup_pip(self, context): """Installs or upgrades pip in a virtual environment""" # We run ensurepip in isolated mode to avoid side effects from # environment vars, the current directory and anything else # intended for the global Python environment cmd = [context.env_exe, '-Im', 'ensurepip', '--upgrade', '--default-pip'] subprocess.check_output(cmd, stderr=subprocess.STDOUT) def setup_scripts(self, context): """ Set up scripts into the created environment from a directory. This method installs the default scripts into the environment being created. You can prevent the default installation by overriding this method if you really need to, or if you need to specify a different location for the scripts to install. By default, the 'scripts' directory in the venv package is used as the source of scripts to install. """ path = os.path.abspath(os.path.dirname(__file__)) path = os.path.join(path, 'scripts') self.install_scripts(context, path) def post_setup(self, context): """ Hook for post-setup modification of the venv. Subclasses may install additional packages or scripts here, add activation shell scripts, etc. :param context: The information for the environment creation request being processed. """ pass def replace_variables(self, text, context): """ Replace variable placeholders in script text with context-specific variables. Return the text passed in , but with variables replaced. :param text: The text in which to replace placeholder variables. :param context: The information for the environment creation request being processed. """ text = text.replace('__VENV_DIR__', context.env_dir) text = text.replace('__VENV_NAME__', context.env_name) text = text.replace('__VENV_PROMPT__', context.prompt) text = text.replace('__VENV_BIN_NAME__', context.bin_name) text = text.replace('__VENV_PYTHON__', context.env_exe) return text def install_scripts(self, context, path): """ Install scripts into the created environment from a directory. :param context: The information for the environment creation request being processed. :param path: Absolute pathname of a directory containing script. Scripts in the 'common' subdirectory of this directory, and those in the directory named for the platform being run on, are installed in the created environment. Placeholder variables are replaced with environment- specific values. """ binpath = context.bin_path plen = len(path) for root, dirs, files in os.walk(path): if root == path: # at top-level, remove irrelevant dirs for d in dirs[:]: if d not in ('common', os.name): dirs.remove(d) continue # ignore files in top level for f in files: if (os.name == 'nt' and f.startswith('python') and f.endswith(('.exe', '.pdb'))): continue srcfile = os.path.join(root, f) suffix = root[plen:].split(os.sep)[2:] if not suffix: dstdir = binpath else: dstdir = os.path.join(binpath, *suffix) if not os.path.exists(dstdir): os.makedirs(dstdir) dstfile = os.path.join(dstdir, f) with open(srcfile, 'rb') as f: data = f.read() if not srcfile.endswith(('.exe', '.pdb')): try: data = data.decode('utf-8') data = self.replace_variables(data, context) data = data.encode('utf-8') except UnicodeError as e: data = None logger.warning('unable to copy script %r, ' 'may be binary: %s', srcfile, e) if data is not None: with open(dstfile, 'wb') as f: f.write(data) shutil.copymode(srcfile, dstfile) def create(env_dir, system_site_packages=False, clear=False, symlinks=False, with_pip=False, prompt=None): """Create a virtual environment in a directory.""" builder = EnvBuilder(system_site_packages=system_site_packages, clear=clear, symlinks=symlinks, with_pip=with_pip, prompt=prompt) builder.create(env_dir) def main(args=None): compatible = True if sys.version_info < (3, 3): compatible = False elif not hasattr(sys, 'base_prefix'): compatible = False if not compatible: raise ValueError('This script is only for use with Python >= 3.3') else: import argparse parser = argparse.ArgumentParser(prog=__name__, description='Creates virtual Python ' 'environments in one or ' 'more target ' 'directories.', epilog='Once an environment has been ' 'created, you may wish to ' 'activate it, e.g. by ' 'sourcing an activate script ' 'in its bin directory.') parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', help='A directory to create the environment in.') parser.add_argument('--system-site-packages', default=False, action='store_true', dest='system_site', help='Give the virtual environment access to the ' 'system site-packages dir.') if os.name == 'nt': use_symlinks = False else: use_symlinks = True group = parser.add_mutually_exclusive_group() group.add_argument('--symlinks', default=use_symlinks, action='store_true', dest='symlinks', help='Try to use symlinks rather than copies, ' 'when symlinks are not the default for ' 'the platform.') group.add_argument('--copies', default=not use_symlinks, action='store_false', dest='symlinks', help='Try to use copies rather than symlinks, ' 'even when symlinks are the default for ' 'the platform.') parser.add_argument('--clear', default=False, action='store_true', dest='clear', help='Delete the contents of the ' 'environment directory if it ' 'already exists, before ' 'environment creation.') parser.add_argument('--upgrade', default=False, action='store_true', dest='upgrade', help='Upgrade the environment ' 'directory to use this version ' 'of Python, assuming Python ' 'has been upgraded in-place.') parser.add_argument('--without-pip', dest='with_pip', default=True, action='store_false', help='Skips installing or upgrading pip in the ' 'virtual environment (pip is bootstrapped ' 'by default)') parser.add_argument('--prompt', help='Provides an alternative prompt prefix for ' 'this environment.') options = parser.parse_args(args) if options.upgrade and options.clear: raise ValueError('you cannot supply --upgrade and --clear together.') builder = EnvBuilder(system_site_packages=options.system_site, clear=options.clear, symlinks=options.symlinks, upgrade=options.upgrade, with_pip=options.with_pip, prompt=options.prompt) for d in options.dirs: builder.create(d) if __name__ == '__main__': rc = 1 try: main() rc = 0 except Exception as e: print('Error: %s' % e, file=sys.stderr) sys.exit(rc) usr/lib64/python2.7/compiler/__init__.py000064400000001777152347153310014010 0ustar00"""Package for parsing and compiling Python source code There are several functions defined at the top level that are imported from modules contained in the package. parse(buf, mode="exec") -> AST Converts a string containing Python source code to an abstract syntax tree (AST). The AST is defined in compiler.ast. parseFile(path) -> AST The same as parse(open(path)) walk(ast, visitor, verbose=None) Does a pre-order walk over the ast using the visitor instance. See compiler.visitor for details. compile(source, filename, mode, flags=None, dont_inherit=None) Returns a code object. A replacement for the builtin compile() function. compileFile(filename) Generates a .pyc file by compiling filename. """ import warnings warnings.warn("The compiler package is deprecated and removed in Python 3.x.", DeprecationWarning, stacklevel=2) from compiler.transformer import parse, parseFile from compiler.visitor import walk from compiler.pycodegen import compile, compileFile lib64/python2.7/xml/__init__.py000064400000001724152347155410012160 0ustar00"""Core XML support for Python. This package contains four sub-packages: dom -- The W3C Document Object Model. This supports DOM Level 1 + Namespaces. parsers -- Python wrappers for XML parsers (currently only supports Expat). sax -- The Simple API for XML, developed by XML-Dev, led by David Megginson and ported to Python by Lars Marius Garshol. This supports the SAX 2 API. etree -- The ElementTree XML library. This is a subset of the full ElementTree XML release. """ __all__ = ["dom", "parsers", "sax", "etree"] _MINIMUM_XMLPLUS_VERSION = (0, 8, 4) try: import _xmlplus except ImportError: pass else: try: v = _xmlplus.version_info except AttributeError: # _xmlplus is too old; ignore it pass else: if v >= _MINIMUM_XMLPLUS_VERSION: import sys _xmlplus.__path__.extend(__path__) sys.modules[__name__] = _xmlplus else: del v usr/lib64/python3.12/http/__init__.py000064400000020164152347157020013223 0ustar00from enum import StrEnum, IntEnum, _simple_enum __all__ = ['HTTPStatus', 'HTTPMethod'] @_simple_enum(IntEnum) class HTTPStatus: """HTTP status codes and reason phrases Status codes from the following RFCs are all observed: * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 * RFC 6585: Additional HTTP Status Codes * RFC 3229: Delta encoding in HTTP * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 * RFC 5842: Binding Extensions to WebDAV * RFC 7238: Permanent Redirect * RFC 2295: Transparent Content Negotiation in HTTP * RFC 2774: An HTTP Extension Framework * RFC 7725: An HTTP Status Code to Report Legal Obstacles * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2) * RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) * RFC 8297: An HTTP Status Code for Indicating Hints * RFC 8470: Using Early Data in HTTP """ def __new__(cls, value, phrase, description=''): obj = int.__new__(cls, value) obj._value_ = value obj.phrase = phrase obj.description = description return obj @property def is_informational(self): return 100 <= self <= 199 @property def is_success(self): return 200 <= self <= 299 @property def is_redirection(self): return 300 <= self <= 399 @property def is_client_error(self): return 400 <= self <= 499 @property def is_server_error(self): return 500 <= self <= 599 # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', 'Switching to new protocol; obey Upgrade header') PROCESSING = 102, 'Processing' EARLY_HINTS = 103, 'Early Hints' # success OK = 200, 'OK', 'Request fulfilled, document follows' CREATED = 201, 'Created', 'Document created, URL follows' ACCEPTED = (202, 'Accepted', 'Request accepted, processing continues off-line') NON_AUTHORITATIVE_INFORMATION = (203, 'Non-Authoritative Information', 'Request fulfilled from cache') NO_CONTENT = 204, 'No Content', 'Request fulfilled, nothing follows' RESET_CONTENT = 205, 'Reset Content', 'Clear input form for further input' PARTIAL_CONTENT = 206, 'Partial Content', 'Partial content follows' MULTI_STATUS = 207, 'Multi-Status' ALREADY_REPORTED = 208, 'Already Reported' IM_USED = 226, 'IM Used' # redirection MULTIPLE_CHOICES = (300, 'Multiple Choices', 'Object has several resources -- see URI list') MOVED_PERMANENTLY = (301, 'Moved Permanently', 'Object moved permanently -- see URI list') FOUND = 302, 'Found', 'Object moved temporarily -- see URI list' SEE_OTHER = 303, 'See Other', 'Object moved -- see Method and URL list' NOT_MODIFIED = (304, 'Not Modified', 'Document has not changed since given time') USE_PROXY = (305, 'Use Proxy', 'You must use proxy specified in Location to access this resource') TEMPORARY_REDIRECT = (307, 'Temporary Redirect', 'Object moved temporarily -- see URI list') PERMANENT_REDIRECT = (308, 'Permanent Redirect', 'Object moved permanently -- see URI list') # client error BAD_REQUEST = (400, 'Bad Request', 'Bad request syntax or unsupported method') UNAUTHORIZED = (401, 'Unauthorized', 'No permission -- see authorization schemes') PAYMENT_REQUIRED = (402, 'Payment Required', 'No payment -- see charging schemes') FORBIDDEN = (403, 'Forbidden', 'Request forbidden -- authorization will not help') NOT_FOUND = (404, 'Not Found', 'Nothing matches the given URI') METHOD_NOT_ALLOWED = (405, 'Method Not Allowed', 'Specified method is invalid for this resource') NOT_ACCEPTABLE = (406, 'Not Acceptable', 'URI not available in preferred format') PROXY_AUTHENTICATION_REQUIRED = (407, 'Proxy Authentication Required', 'You must authenticate with this proxy before proceeding') REQUEST_TIMEOUT = (408, 'Request Timeout', 'Request timed out; try again later') CONFLICT = 409, 'Conflict', 'Request conflict' GONE = (410, 'Gone', 'URI no longer exists and has been permanently removed') LENGTH_REQUIRED = (411, 'Length Required', 'Client must specify Content-Length') PRECONDITION_FAILED = (412, 'Precondition Failed', 'Precondition in headers is false') REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large', 'Entity is too large') REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long', 'URI is too long') UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type', 'Entity body in unsupported format') REQUESTED_RANGE_NOT_SATISFIABLE = (416, 'Requested Range Not Satisfiable', 'Cannot satisfy request range') EXPECTATION_FAILED = (417, 'Expectation Failed', 'Expect condition could not be satisfied') IM_A_TEAPOT = (418, 'I\'m a Teapot', 'Server refuses to brew coffee because it is a teapot.') MISDIRECTED_REQUEST = (421, 'Misdirected Request', 'Server is not able to produce a response') UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity' LOCKED = 423, 'Locked' FAILED_DEPENDENCY = 424, 'Failed Dependency' TOO_EARLY = 425, 'Too Early' UPGRADE_REQUIRED = 426, 'Upgrade Required' PRECONDITION_REQUIRED = (428, 'Precondition Required', 'The origin server requires the request to be conditional') TOO_MANY_REQUESTS = (429, 'Too Many Requests', 'The user has sent too many requests in ' 'a given amount of time ("rate limiting")') REQUEST_HEADER_FIELDS_TOO_LARGE = (431, 'Request Header Fields Too Large', 'The server is unwilling to process the request because its header ' 'fields are too large') UNAVAILABLE_FOR_LEGAL_REASONS = (451, 'Unavailable For Legal Reasons', 'The server is denying access to the ' 'resource as a consequence of a legal demand') # server errors INTERNAL_SERVER_ERROR = (500, 'Internal Server Error', 'Server got itself in trouble') NOT_IMPLEMENTED = (501, 'Not Implemented', 'Server does not support this operation') BAD_GATEWAY = (502, 'Bad Gateway', 'Invalid responses from another server/proxy') SERVICE_UNAVAILABLE = (503, 'Service Unavailable', 'The server cannot process the request due to a high load') GATEWAY_TIMEOUT = (504, 'Gateway Timeout', 'The gateway server did not receive a timely response') HTTP_VERSION_NOT_SUPPORTED = (505, 'HTTP Version Not Supported', 'Cannot fulfill request') VARIANT_ALSO_NEGOTIATES = 506, 'Variant Also Negotiates' INSUFFICIENT_STORAGE = 507, 'Insufficient Storage' LOOP_DETECTED = 508, 'Loop Detected' NOT_EXTENDED = 510, 'Not Extended' NETWORK_AUTHENTICATION_REQUIRED = (511, 'Network Authentication Required', 'The client needs to authenticate to gain network access') @_simple_enum(StrEnum) class HTTPMethod: """HTTP methods and descriptions Methods from the following RFCs are all observed: * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 * RFC 5789: PATCH Method for HTTP """ def __new__(cls, value, description): obj = str.__new__(cls, value) obj._value_ = value obj.description = description return obj def __repr__(self): return "<%s.%s>" % (self.__class__.__name__, self._name_) CONNECT = 'CONNECT', 'Establish a connection to the server.' DELETE = 'DELETE', 'Remove the target.' GET = 'GET', 'Retrieve the target.' HEAD = 'HEAD', 'Same as GET, but only retrieve the status line and header section.' OPTIONS = 'OPTIONS', 'Describe the communication options for the target.' PATCH = 'PATCH', 'Apply partial modifications to a target.' POST = 'POST', 'Perform target-specific processing with the request payload.' PUT = 'PUT', 'Replace the target with the request payload.' TRACE = 'TRACE', 'Perform a message loop-back test along the path to the target.' usr/lib/python3.6/site-packages/chardet/__init__.py000064400000003027152347157630016155 0ustar00######################## BEGIN LICENSE BLOCK ######################## # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA # 02110-1301 USA ######################### END LICENSE BLOCK ######################### from .compat import PY2, PY3 from .universaldetector import UniversalDetector from .version import __version__, VERSION def detect(byte_str): """ Detect the encoding of the given byte string. :param byte_str: The byte sequence to examine. :type byte_str: ``bytes`` or ``bytearray`` """ if not isinstance(byte_str, bytearray): if not isinstance(byte_str, bytes): raise TypeError('Expected object of type bytes or bytearray, got: ' '{0}'.format(type(byte_str))) else: byte_str = bytearray(byte_str) detector = UniversalDetector() detector.feed(byte_str) return detector.close() usr/lib64/python3.8/lib2to3/fixes/__init__.py000064400000000057152347201270014561 0ustar00# Dummy file to make this directory a package. usr/lib64/python2.7/distutils/__init__.py000064400000000354152347203620014210 0ustar00"""distutils The main package for the Python Module Distribution Utilities. Normally used from a setup script as from distutils.core import setup setup (...) """ import sys __version__ = sys.version[:sys.version.index(' ')] usr/lib64/python2.7/bsddb/__init__.py000064400000037164152347203630013254 0ustar00#---------------------------------------------------------------------- # Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA # and Andrew Kuchling. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # o Redistributions of source code must retain the above copyright # notice, this list of conditions, and the disclaimer that follows. # # o Redistributions in binary form must reproduce the above copyright # notice, this list of conditions, and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # # o Neither the name of Digital Creations nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS # IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL # CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH # DAMAGE. #---------------------------------------------------------------------- """Support for Berkeley DB 4.3 through 5.3 with a simple interface. For the full featured object oriented interface use the bsddb.db module instead. It mirrors the Oracle Berkeley DB C API. """ import sys absolute_import = (sys.version_info[0] >= 3) if (sys.version_info >= (2, 6)) and (sys.version_info < (3, 0)) : import warnings if sys.py3kwarning and (__name__ != 'bsddb3') : warnings.warnpy3k("in 3.x, the bsddb module has been removed; " "please use the pybsddb project instead", DeprecationWarning, 2) warnings.filterwarnings("ignore", ".*CObject.*", DeprecationWarning, "bsddb.__init__") try: if __name__ == 'bsddb3': # import _pybsddb binary as it should be the more recent version from # a standalone pybsddb addon package than the version included with # python as bsddb._bsddb. if absolute_import : # Because this syntaxis is not valid before Python 2.5 exec("from . import _pybsddb") else : import _pybsddb _bsddb = _pybsddb from bsddb3.dbutils import DeadlockWrap as _DeadlockWrap else: import _bsddb from bsddb.dbutils import DeadlockWrap as _DeadlockWrap except ImportError: # Remove ourselves from sys.modules import sys del sys.modules[__name__] raise # bsddb3 calls it db, but provide _db for backwards compatibility db = _db = _bsddb __version__ = db.__version__ error = db.DBError # So bsddb.error will mean something... #---------------------------------------------------------------------- import sys, os from weakref import ref if sys.version_info < (2, 6) : import UserDict MutableMapping = UserDict.DictMixin else : import collections MutableMapping = collections.MutableMapping class _iter_mixin(MutableMapping): def _make_iter_cursor(self): cur = _DeadlockWrap(self.db.cursor) key = id(cur) self._cursor_refs[key] = ref(cur, self._gen_cref_cleaner(key)) return cur def _gen_cref_cleaner(self, key): # use generate the function for the weakref callback here # to ensure that we do not hold a strict reference to cur # in the callback. return lambda ref: self._cursor_refs.pop(key, None) def __iter__(self): self._kill_iteration = False self._in_iter += 1 try: try: cur = self._make_iter_cursor() # FIXME-20031102-greg: race condition. cursor could # be closed by another thread before this call. # since we're only returning keys, we call the cursor # methods with flags=0, dlen=0, dofs=0 key = _DeadlockWrap(cur.first, 0,0,0)[0] yield key next = getattr(cur, "next") while 1: try: key = _DeadlockWrap(next, 0,0,0)[0] yield key except _bsddb.DBCursorClosedError: if self._kill_iteration: raise RuntimeError('Database changed size ' 'during iteration.') cur = self._make_iter_cursor() # FIXME-20031101-greg: race condition. cursor could # be closed by another thread before this call. _DeadlockWrap(cur.set, key,0,0,0) next = getattr(cur, "next") except _bsddb.DBNotFoundError: pass except _bsddb.DBCursorClosedError: # the database was modified during iteration. abort. pass # When Python 2.4 not supported in bsddb3, we can change this to "finally" except : self._in_iter -= 1 raise self._in_iter -= 1 def iteritems(self): if not self.db: return self._kill_iteration = False self._in_iter += 1 try: try: cur = self._make_iter_cursor() # FIXME-20031102-greg: race condition. cursor could # be closed by another thread before this call. kv = _DeadlockWrap(cur.first) key = kv[0] yield kv next = getattr(cur, "next") while 1: try: kv = _DeadlockWrap(next) key = kv[0] yield kv except _bsddb.DBCursorClosedError: if self._kill_iteration: raise RuntimeError('Database changed size ' 'during iteration.') cur = self._make_iter_cursor() # FIXME-20031101-greg: race condition. cursor could # be closed by another thread before this call. _DeadlockWrap(cur.set, key,0,0,0) next = getattr(cur, "next") except _bsddb.DBNotFoundError: pass except _bsddb.DBCursorClosedError: # the database was modified during iteration. abort. pass # When Python 2.4 not supported in bsddb3, we can change this to "finally" except : self._in_iter -= 1 raise self._in_iter -= 1 class _DBWithCursor(_iter_mixin): """ A simple wrapper around DB that makes it look like the bsddbobject in the old module. It uses a cursor as needed to provide DB traversal. """ def __init__(self, db): self.db = db self.db.set_get_returns_none(0) # FIXME-20031101-greg: I believe there is still the potential # for deadlocks in a multithreaded environment if someone # attempts to use the any of the cursor interfaces in one # thread while doing a put or delete in another thread. The # reason is that _checkCursor and _closeCursors are not atomic # operations. Doing our own locking around self.dbc, # self.saved_dbc_key and self._cursor_refs could prevent this. # TODO: A test case demonstrating the problem needs to be written. # self.dbc is a DBCursor object used to implement the # first/next/previous/last/set_location methods. self.dbc = None self.saved_dbc_key = None # a collection of all DBCursor objects currently allocated # by the _iter_mixin interface. self._cursor_refs = {} self._in_iter = 0 self._kill_iteration = False def __del__(self): self.close() def _checkCursor(self): if self.dbc is None: self.dbc = _DeadlockWrap(self.db.cursor) if self.saved_dbc_key is not None: _DeadlockWrap(self.dbc.set, self.saved_dbc_key) self.saved_dbc_key = None # This method is needed for all non-cursor DB calls to avoid # Berkeley DB deadlocks (due to being opened with DB_INIT_LOCK # and DB_THREAD to be thread safe) when intermixing database # operations that use the cursor internally with those that don't. def _closeCursors(self, save=1): if self.dbc: c = self.dbc self.dbc = None if save: try: self.saved_dbc_key = _DeadlockWrap(c.current, 0,0,0)[0] except db.DBError: pass _DeadlockWrap(c.close) del c for cref in self._cursor_refs.values(): c = cref() if c is not None: _DeadlockWrap(c.close) def _checkOpen(self): if self.db is None: raise error, "BSDDB object has already been closed" def isOpen(self): return self.db is not None def __len__(self): self._checkOpen() return _DeadlockWrap(lambda: len(self.db)) # len(self.db) if sys.version_info >= (2, 6) : def __repr__(self) : if self.isOpen() : return repr(dict(_DeadlockWrap(self.db.items))) return repr(dict()) def __getitem__(self, key): self._checkOpen() return _DeadlockWrap(lambda: self.db[key]) # self.db[key] def __setitem__(self, key, value): self._checkOpen() self._closeCursors() if self._in_iter and key not in self: self._kill_iteration = True def wrapF(): self.db[key] = value _DeadlockWrap(wrapF) # self.db[key] = value def __delitem__(self, key): self._checkOpen() self._closeCursors() if self._in_iter and key in self: self._kill_iteration = True def wrapF(): del self.db[key] _DeadlockWrap(wrapF) # del self.db[key] def close(self): self._closeCursors(save=0) if self.dbc is not None: _DeadlockWrap(self.dbc.close) v = 0 if self.db is not None: v = _DeadlockWrap(self.db.close) self.dbc = None self.db = None return v def keys(self): self._checkOpen() return _DeadlockWrap(self.db.keys) def has_key(self, key): self._checkOpen() return _DeadlockWrap(self.db.has_key, key) def set_location(self, key): self._checkOpen() self._checkCursor() return _DeadlockWrap(self.dbc.set_range, key) def next(self): # Renamed by "2to3" self._checkOpen() self._checkCursor() rv = _DeadlockWrap(getattr(self.dbc, "next")) return rv if sys.version_info[0] >= 3 : # For "2to3" conversion next = __next__ def previous(self): self._checkOpen() self._checkCursor() rv = _DeadlockWrap(self.dbc.prev) return rv def first(self): self._checkOpen() # fix 1725856: don't needlessly try to restore our cursor position self.saved_dbc_key = None self._checkCursor() rv = _DeadlockWrap(self.dbc.first) return rv def last(self): self._checkOpen() # fix 1725856: don't needlessly try to restore our cursor position self.saved_dbc_key = None self._checkCursor() rv = _DeadlockWrap(self.dbc.last) return rv def sync(self): self._checkOpen() return _DeadlockWrap(self.db.sync) #---------------------------------------------------------------------- # Compatibility object factory functions def hashopen(file, flag='c', mode=0666, pgsize=None, ffactor=None, nelem=None, cachesize=None, lorder=None, hflags=0): flags = _checkflag(flag, file) e = _openDBEnv(cachesize) d = db.DB(e) d.set_flags(hflags) if pgsize is not None: d.set_pagesize(pgsize) if lorder is not None: d.set_lorder(lorder) if ffactor is not None: d.set_h_ffactor(ffactor) if nelem is not None: d.set_h_nelem(nelem) d.open(file, db.DB_HASH, flags, mode) return _DBWithCursor(d) #---------------------------------------------------------------------- def btopen(file, flag='c', mode=0666, btflags=0, cachesize=None, maxkeypage=None, minkeypage=None, pgsize=None, lorder=None): flags = _checkflag(flag, file) e = _openDBEnv(cachesize) d = db.DB(e) if pgsize is not None: d.set_pagesize(pgsize) if lorder is not None: d.set_lorder(lorder) d.set_flags(btflags) if minkeypage is not None: d.set_bt_minkey(minkeypage) if maxkeypage is not None: d.set_bt_maxkey(maxkeypage) d.open(file, db.DB_BTREE, flags, mode) return _DBWithCursor(d) #---------------------------------------------------------------------- def rnopen(file, flag='c', mode=0666, rnflags=0, cachesize=None, pgsize=None, lorder=None, rlen=None, delim=None, source=None, pad=None): flags = _checkflag(flag, file) e = _openDBEnv(cachesize) d = db.DB(e) if pgsize is not None: d.set_pagesize(pgsize) if lorder is not None: d.set_lorder(lorder) d.set_flags(rnflags) if delim is not None: d.set_re_delim(delim) if rlen is not None: d.set_re_len(rlen) if source is not None: d.set_re_source(source) if pad is not None: d.set_re_pad(pad) d.open(file, db.DB_RECNO, flags, mode) return _DBWithCursor(d) #---------------------------------------------------------------------- def _openDBEnv(cachesize): e = db.DBEnv() if cachesize is not None: if cachesize >= 20480: e.set_cachesize(0, cachesize) else: raise error, "cachesize must be >= 20480" e.set_lk_detect(db.DB_LOCK_DEFAULT) e.open('.', db.DB_PRIVATE | db.DB_CREATE | db.DB_THREAD | db.DB_INIT_LOCK | db.DB_INIT_MPOOL) return e def _checkflag(flag, file): if flag == 'r': flags = db.DB_RDONLY elif flag == 'rw': flags = 0 elif flag == 'w': flags = db.DB_CREATE elif flag == 'c': flags = db.DB_CREATE elif flag == 'n': flags = db.DB_CREATE #flags = db.DB_CREATE | db.DB_TRUNCATE # we used db.DB_TRUNCATE flag for this before but Berkeley DB # 4.2.52 changed to disallowed truncate with txn environments. if file is not None and os.path.isfile(file): os.unlink(file) else: raise error, "flags should be one of 'r', 'w', 'c' or 'n'" return flags | db.DB_THREAD #---------------------------------------------------------------------- # This is a silly little hack that allows apps to continue to use the # DB_THREAD flag even on systems without threads without freaking out # Berkeley DB. # # This assumes that if Python was built with thread support then # Berkeley DB was too. try: # 2to3 automatically changes "import thread" to "import _thread" import thread as T del T except ImportError: db.DB_THREAD = 0 #---------------------------------------------------------------------- lib64/python3.12/concurrent/futures/__init__.py000064400000003057152347205770015322 0ustar00# Copyright 2009 Brian Quinlan. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """Execute computations asynchronously using threads or processes.""" __author__ = 'Brian Quinlan (brian@sweetapp.com)' from concurrent.futures._base import (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED, CancelledError, TimeoutError, InvalidStateError, BrokenExecutor, Future, Executor, wait, as_completed) __all__ = ( 'FIRST_COMPLETED', 'FIRST_EXCEPTION', 'ALL_COMPLETED', 'CancelledError', 'TimeoutError', 'InvalidStateError', 'BrokenExecutor', 'Future', 'Executor', 'wait', 'as_completed', 'ProcessPoolExecutor', 'ThreadPoolExecutor', ) def __dir__(): return __all__ + ('__author__', '__doc__') def __getattr__(name): global ProcessPoolExecutor, ThreadPoolExecutor if name == 'ProcessPoolExecutor': from .process import ProcessPoolExecutor as pe ProcessPoolExecutor = pe return pe if name == 'ThreadPoolExecutor': from .thread import ThreadPoolExecutor as te ThreadPoolExecutor = te return te raise AttributeError(f"module {__name__!r} has no attribute {name!r}") lib64/python2.7/compiler/__init__.py000064400000001777152347243400013177 0ustar00"""Package for parsing and compiling Python source code There are several functions defined at the top level that are imported from modules contained in the package. parse(buf, mode="exec") -> AST Converts a string containing Python source code to an abstract syntax tree (AST). The AST is defined in compiler.ast. parseFile(path) -> AST The same as parse(open(path)) walk(ast, visitor, verbose=None) Does a pre-order walk over the ast using the visitor instance. See compiler.visitor for details. compile(source, filename, mode, flags=None, dont_inherit=None) Returns a code object. A replacement for the builtin compile() function. compileFile(filename) Generates a .pyc file by compiling filename. """ import warnings warnings.warn("The compiler package is deprecated and removed in Python 3.x.", DeprecationWarning, stacklevel=2) from compiler.transformer import parse, parseFile from compiler.visitor import walk from compiler.pycodegen import compile, compileFile lib64/python3.12/multiprocessing/__init__.py000064400000001624152347244640014667 0ustar00# # Package analogous to 'threading.py' but using processes # # multiprocessing/__init__.py # # This package is intended to duplicate the functionality (and much of # the API) of threading.py but uses processes instead of threads. A # subpackage 'multiprocessing.dummy' has the same API but is a simple # wrapper for 'threading'. # # Copyright (c) 2006-2008, R Oudkerk # Licensed to PSF under a Contributor Agreement. # import sys from . import context # # Copy stuff from default context # __all__ = [x for x in dir(context._default_context) if not x.startswith('_')] globals().update((name, getattr(context._default_context, name)) for name in __all__) # # XXX These should not really be documented or public. # SUBDEBUG = 5 SUBWARNING = 25 # # Alias for main module -- will be reset by bootstrapping child processes # if '__main__' in sys.modules: sys.modules['__mp_main__'] = sys.modules['__main__'] usr/lib/python3.6/site-packages/tuned/__init__.py000064400000001671152347247110015656 0ustar00# # tuned: daemon for monitoring and adaptive tuning of system devices # # Copyright (C) 2008-2013 Red Hat, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # __copyright__ = "Copyright 2008-2013 Red Hat, Inc." __license__ = "GPLv2+" __email__ = "power-management@lists.fedoraproject.org" lib64/python3.12/http/__init__.py000064400000020164152347251610012412 0ustar00from enum import StrEnum, IntEnum, _simple_enum __all__ = ['HTTPStatus', 'HTTPMethod'] @_simple_enum(IntEnum) class HTTPStatus: """HTTP status codes and reason phrases Status codes from the following RFCs are all observed: * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 * RFC 6585: Additional HTTP Status Codes * RFC 3229: Delta encoding in HTTP * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 * RFC 5842: Binding Extensions to WebDAV * RFC 7238: Permanent Redirect * RFC 2295: Transparent Content Negotiation in HTTP * RFC 2774: An HTTP Extension Framework * RFC 7725: An HTTP Status Code to Report Legal Obstacles * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2) * RFC 2324: Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0) * RFC 8297: An HTTP Status Code for Indicating Hints * RFC 8470: Using Early Data in HTTP """ def __new__(cls, value, phrase, description=''): obj = int.__new__(cls, value) obj._value_ = value obj.phrase = phrase obj.description = description return obj @property def is_informational(self): return 100 <= self <= 199 @property def is_success(self): return 200 <= self <= 299 @property def is_redirection(self): return 300 <= self <= 399 @property def is_client_error(self): return 400 <= self <= 499 @property def is_server_error(self): return 500 <= self <= 599 # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', 'Switching to new protocol; obey Upgrade header') PROCESSING = 102, 'Processing' EARLY_HINTS = 103, 'Early Hints' # success OK = 200, 'OK', 'Request fulfilled, document follows' CREATED = 201, 'Created', 'Document created, URL follows' ACCEPTED = (202, 'Accepted', 'Request accepted, processing continues off-line') NON_AUTHORITATIVE_INFORMATION = (203, 'Non-Authoritative Information', 'Request fulfilled from cache') NO_CONTENT = 204, 'No Content', 'Request fulfilled, nothing follows' RESET_CONTENT = 205, 'Reset Content', 'Clear input form for further input' PARTIAL_CONTENT = 206, 'Partial Content', 'Partial content follows' MULTI_STATUS = 207, 'Multi-Status' ALREADY_REPORTED = 208, 'Already Reported' IM_USED = 226, 'IM Used' # redirection MULTIPLE_CHOICES = (300, 'Multiple Choices', 'Object has several resources -- see URI list') MOVED_PERMANENTLY = (301, 'Moved Permanently', 'Object moved permanently -- see URI list') FOUND = 302, 'Found', 'Object moved temporarily -- see URI list' SEE_OTHER = 303, 'See Other', 'Object moved -- see Method and URL list' NOT_MODIFIED = (304, 'Not Modified', 'Document has not changed since given time') USE_PROXY = (305, 'Use Proxy', 'You must use proxy specified in Location to access this resource') TEMPORARY_REDIRECT = (307, 'Temporary Redirect', 'Object moved temporarily -- see URI list') PERMANENT_REDIRECT = (308, 'Permanent Redirect', 'Object moved permanently -- see URI list') # client error BAD_REQUEST = (400, 'Bad Request', 'Bad request syntax or unsupported method') UNAUTHORIZED = (401, 'Unauthorized', 'No permission -- see authorization schemes') PAYMENT_REQUIRED = (402, 'Payment Required', 'No payment -- see charging schemes') FORBIDDEN = (403, 'Forbidden', 'Request forbidden -- authorization will not help') NOT_FOUND = (404, 'Not Found', 'Nothing matches the given URI') METHOD_NOT_ALLOWED = (405, 'Method Not Allowed', 'Specified method is invalid for this resource') NOT_ACCEPTABLE = (406, 'Not Acceptable', 'URI not available in preferred format') PROXY_AUTHENTICATION_REQUIRED = (407, 'Proxy Authentication Required', 'You must authenticate with this proxy before proceeding') REQUEST_TIMEOUT = (408, 'Request Timeout', 'Request timed out; try again later') CONFLICT = 409, 'Conflict', 'Request conflict' GONE = (410, 'Gone', 'URI no longer exists and has been permanently removed') LENGTH_REQUIRED = (411, 'Length Required', 'Client must specify Content-Length') PRECONDITION_FAILED = (412, 'Precondition Failed', 'Precondition in headers is false') REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large', 'Entity is too large') REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long', 'URI is too long') UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type', 'Entity body in unsupported format') REQUESTED_RANGE_NOT_SATISFIABLE = (416, 'Requested Range Not Satisfiable', 'Cannot satisfy request range') EXPECTATION_FAILED = (417, 'Expectation Failed', 'Expect condition could not be satisfied') IM_A_TEAPOT = (418, 'I\'m a Teapot', 'Server refuses to brew coffee because it is a teapot.') MISDIRECTED_REQUEST = (421, 'Misdirected Request', 'Server is not able to produce a response') UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity' LOCKED = 423, 'Locked' FAILED_DEPENDENCY = 424, 'Failed Dependency' TOO_EARLY = 425, 'Too Early' UPGRADE_REQUIRED = 426, 'Upgrade Required' PRECONDITION_REQUIRED = (428, 'Precondition Required', 'The origin server requires the request to be conditional') TOO_MANY_REQUESTS = (429, 'Too Many Requests', 'The user has sent too many requests in ' 'a given amount of time ("rate limiting")') REQUEST_HEADER_FIELDS_TOO_LARGE = (431, 'Request Header Fields Too Large', 'The server is unwilling to process the request because its header ' 'fields are too large') UNAVAILABLE_FOR_LEGAL_REASONS = (451, 'Unavailable For Legal Reasons', 'The server is denying access to the ' 'resource as a consequence of a legal demand') # server errors INTERNAL_SERVER_ERROR = (500, 'Internal Server Error', 'Server got itself in trouble') NOT_IMPLEMENTED = (501, 'Not Implemented', 'Server does not support this operation') BAD_GATEWAY = (502, 'Bad Gateway', 'Invalid responses from another server/proxy') SERVICE_UNAVAILABLE = (503, 'Service Unavailable', 'The server cannot process the request due to a high load') GATEWAY_TIMEOUT = (504, 'Gateway Timeout', 'The gateway server did not receive a timely response') HTTP_VERSION_NOT_SUPPORTED = (505, 'HTTP Version Not Supported', 'Cannot fulfill request') VARIANT_ALSO_NEGOTIATES = 506, 'Variant Also Negotiates' INSUFFICIENT_STORAGE = 507, 'Insufficient Storage' LOOP_DETECTED = 508, 'Loop Detected' NOT_EXTENDED = 510, 'Not Extended' NETWORK_AUTHENTICATION_REQUIRED = (511, 'Network Authentication Required', 'The client needs to authenticate to gain network access') @_simple_enum(StrEnum) class HTTPMethod: """HTTP methods and descriptions Methods from the following RFCs are all observed: * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 * RFC 5789: PATCH Method for HTTP """ def __new__(cls, value, description): obj = str.__new__(cls, value) obj._value_ = value obj.description = description return obj def __repr__(self): return "<%s.%s>" % (self.__class__.__name__, self._name_) CONNECT = 'CONNECT', 'Establish a connection to the server.' DELETE = 'DELETE', 'Remove the target.' GET = 'GET', 'Retrieve the target.' HEAD = 'HEAD', 'Same as GET, but only retrieve the status line and header section.' OPTIONS = 'OPTIONS', 'Describe the communication options for the target.' PATCH = 'PATCH', 'Apply partial modifications to a target.' POST = 'POST', 'Perform target-specific processing with the request payload.' PUT = 'PUT', 'Replace the target with the request payload.' TRACE = 'TRACE', 'Perform a message loop-back test along the path to the target.' lib64/python3.6/distutils/command/__init__.py000064400000001437152347253070015024 0ustar00"""distutils.command Package containing implementation of all the standard Distutils commands.""" __all__ = ['build', 'build_py', 'build_ext', 'build_clib', 'build_scripts', 'clean', 'install', 'install_lib', 'install_headers', 'install_scripts', 'install_data', 'sdist', 'register', 'bdist', 'bdist_dumb', 'bdist_rpm', 'bdist_wininst', 'check', 'upload', # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', # Note: # bdist_packager is not included because it only provides # an abstract base class ] usr/lib64/python3.12/zoneinfo/__init__.py000064400000001277152347262310014076 0ustar00__all__ = [ "ZoneInfo", "reset_tzpath", "available_timezones", "TZPATH", "ZoneInfoNotFoundError", "InvalidTZPathWarning", ] from . import _tzpath from ._common import ZoneInfoNotFoundError try: from _zoneinfo import ZoneInfo except ImportError: # pragma: nocover from ._zoneinfo import ZoneInfo reset_tzpath = _tzpath.reset_tzpath available_timezones = _tzpath.available_timezones InvalidTZPathWarning = _tzpath.InvalidTZPathWarning def __getattr__(name): if name == "TZPATH": return _tzpath.TZPATH else: raise AttributeError(f"module {__name__!r} has no attribute {name!r}") def __dir__(): return sorted(list(globals()) + ["TZPATH"]) usr/lib64/python3.12/asyncio/__init__.py000064400000002304152347273460013714 0ustar00"""The asyncio package, tracking PEP 3156.""" # flake8: noqa import sys # This relies on each of the submodules having an __all__ variable. from .base_events import * from .coroutines import * from .events import * from .exceptions import * from .futures import * from .locks import * from .protocols import * from .runners import * from .queues import * from .streams import * from .subprocess import * from .tasks import * from .taskgroups import * from .timeouts import * from .threads import * from .transports import * __all__ = (base_events.__all__ + coroutines.__all__ + events.__all__ + exceptions.__all__ + futures.__all__ + locks.__all__ + protocols.__all__ + runners.__all__ + queues.__all__ + streams.__all__ + subprocess.__all__ + tasks.__all__ + taskgroups.__all__ + threads.__all__ + timeouts.__all__ + transports.__all__) if sys.platform == 'win32': # pragma: no cover from .windows_events import * __all__ += windows_events.__all__ else: from .unix_events import * # pragma: no cover __all__ += unix_events.__all__ usr/lib64/python2.7/ctypes/__init__.py000064400000041366152347324560013512 0ustar00"""create and manipulate C data types in Python""" import os as _os, sys as _sys __version__ = "1.1.0" from _ctypes import Union, Structure, Array from _ctypes import _Pointer from _ctypes import CFuncPtr as _CFuncPtr from _ctypes import __version__ as _ctypes_version from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import ArgumentError from struct import calcsize as _calcsize if __version__ != _ctypes_version: raise Exception("Version number mismatch", __version__, _ctypes_version) if _os.name in ("nt", "ce"): from _ctypes import FormatError DEFAULT_MODE = RTLD_LOCAL if _os.name == "posix" and _sys.platform == "darwin": # On OS X 10.3, we use RTLD_GLOBAL as default mode # because RTLD_LOCAL does not work at least on some # libraries. OS X 10.3 is Darwin 7, so we check for # that. if int(_os.uname()[2].split('.')[0]) < 8: DEFAULT_MODE = RTLD_GLOBAL from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \ FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \ FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR """ WINOLEAPI -> HRESULT WINOLEAPI_(type) STDMETHODCALLTYPE STDMETHOD(name) STDMETHOD_(type, name) STDAPICALLTYPE """ def create_string_buffer(init, size=None): """create_string_buffer(aString) -> character array create_string_buffer(anInteger) -> character array create_string_buffer(aString, anInteger) -> character array """ if isinstance(init, (str, unicode)): if size is None: size = len(init)+1 buftype = c_char * size buf = buftype() buf.value = init return buf elif isinstance(init, (int, long)): buftype = c_char * init buf = buftype() return buf raise TypeError(init) def c_buffer(init, size=None): ## "deprecated, use create_string_buffer instead" ## import warnings ## warnings.warn("c_buffer is deprecated, use create_string_buffer instead", ## DeprecationWarning, stacklevel=2) return create_string_buffer(init, size) _c_functype_cache = {} def CFUNCTYPE(restype, *argtypes, **kw): """CFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) -> function prototype. restype: the result type argtypes: a sequence specifying the argument types The function prototype can be called in different ways to create a callable object: prototype(integer address) -> foreign function prototype(callable) -> create and return a C callable function from callable prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal prototype((function name, dll object)[, paramflags]) -> foreign function exported by name """ flags = _FUNCFLAG_CDECL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _c_functype_cache[(restype, argtypes, flags)] except KeyError: class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _c_functype_cache[(restype, argtypes, flags)] = CFunctionType return CFunctionType if _os.name in ("nt", "ce"): from _ctypes import LoadLibrary as _dlopen from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL if _os.name == "ce": # 'ce' doesn't have the stdcall calling convention _FUNCFLAG_STDCALL = _FUNCFLAG_CDECL _win_functype_cache = {} def WINFUNCTYPE(restype, *argtypes, **kw): # docstring set later (very similar to CFUNCTYPE.__doc__) flags = _FUNCFLAG_STDCALL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _win_functype_cache[(restype, argtypes, flags)] except KeyError: class WinFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType return WinFunctionType if WINFUNCTYPE.__doc__: WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE") elif _os.name == "posix": from _ctypes import dlopen as _dlopen from _ctypes import sizeof, byref, addressof, alignment, resize from _ctypes import get_errno, set_errno from _ctypes import _SimpleCData def _check_size(typ, typecode=None): # Check if sizeof(ctypes_type) against struct.calcsize. This # should protect somewhat against a misconfigured libffi. from struct import calcsize if typecode is None: # Most _type_ codes are the same as used in struct typecode = typ._type_ actual, required = sizeof(typ), calcsize(typecode) if actual != required: raise SystemError("sizeof(%s) wrong: %d instead of %d" % \ (typ, actual, required)) class py_object(_SimpleCData): _type_ = "O" def __repr__(self): try: return super(py_object, self).__repr__() except ValueError: return "%s()" % type(self).__name__ _check_size(py_object, "P") class c_short(_SimpleCData): _type_ = "h" _check_size(c_short) class c_ushort(_SimpleCData): _type_ = "H" _check_size(c_ushort) class c_long(_SimpleCData): _type_ = "l" _check_size(c_long) class c_ulong(_SimpleCData): _type_ = "L" _check_size(c_ulong) if _calcsize("i") == _calcsize("l"): # if int and long have the same size, make c_int an alias for c_long c_int = c_long c_uint = c_ulong else: class c_int(_SimpleCData): _type_ = "i" _check_size(c_int) class c_uint(_SimpleCData): _type_ = "I" _check_size(c_uint) class c_float(_SimpleCData): _type_ = "f" _check_size(c_float) class c_double(_SimpleCData): _type_ = "d" _check_size(c_double) class c_longdouble(_SimpleCData): _type_ = "g" if sizeof(c_longdouble) == sizeof(c_double): c_longdouble = c_double if _calcsize("l") == _calcsize("q"): # if long and long long have the same size, make c_longlong an alias for c_long c_longlong = c_long c_ulonglong = c_ulong else: class c_longlong(_SimpleCData): _type_ = "q" _check_size(c_longlong) class c_ulonglong(_SimpleCData): _type_ = "Q" ## def from_param(cls, val): ## return ('d', float(val), val) ## from_param = classmethod(from_param) _check_size(c_ulonglong) class c_ubyte(_SimpleCData): _type_ = "B" c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte # backward compatibility: ##c_uchar = c_ubyte _check_size(c_ubyte) class c_byte(_SimpleCData): _type_ = "b" c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte _check_size(c_byte) class c_char(_SimpleCData): _type_ = "c" c_char.__ctype_le__ = c_char.__ctype_be__ = c_char _check_size(c_char) class c_char_p(_SimpleCData): _type_ = "z" if _os.name == "nt": def __repr__(self): if not windll.kernel32.IsBadStringPtrA(self, -1): return "%s(%r)" % (self.__class__.__name__, self.value) return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value) else: def __repr__(self): return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value) _check_size(c_char_p, "P") class c_void_p(_SimpleCData): _type_ = "P" c_voidp = c_void_p # backwards compatibility (to a bug) _check_size(c_void_p) class c_bool(_SimpleCData): _type_ = "?" from _ctypes import POINTER, pointer, _pointer_type_cache def _reset_cache(): _pointer_type_cache.clear() _c_functype_cache.clear() if _os.name in ("nt", "ce"): _win_functype_cache.clear() # _SimpleCData.c_wchar_p_from_param POINTER(c_wchar).from_param = c_wchar_p.from_param # _SimpleCData.c_char_p_from_param POINTER(c_char).from_param = c_char_p.from_param _pointer_type_cache[None] = c_void_p try: from _ctypes import set_conversion_mode except ImportError: pass else: if _os.name in ("nt", "ce"): set_conversion_mode("mbcs", "ignore") else: set_conversion_mode("ascii", "strict") class c_wchar_p(_SimpleCData): _type_ = "Z" class c_wchar(_SimpleCData): _type_ = "u" def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array create_unicode_buffer(aString, anInteger) -> character array """ if isinstance(init, (str, unicode)): if size is None: size = len(init)+1 buftype = c_wchar * size buf = buftype() buf.value = init return buf elif isinstance(init, (int, long)): buftype = c_wchar * init buf = buftype() return buf raise TypeError(init) # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: raise RuntimeError("This type already exists in the cache") if id(pointer) not in _pointer_type_cache: raise RuntimeError("What's this???") pointer.set_type(cls) _pointer_type_cache[cls] = pointer del _pointer_type_cache[id(pointer)] # XXX Deprecated def ARRAY(typ, len): return typ * len ################################################################ class CDLL(object): """An instance of this class represents a loaded dll/shared library, exporting functions using the standard C calling convention (named 'cdecl' on Windows). The exported functions can be accessed as attributes, or by indexing with the function name. Examples: .qsort -> callable object ['qsort'] -> callable object Calling the functions releases the Python GIL during the call and reacquires it afterwards. """ _func_flags_ = _FUNCFLAG_CDECL _func_restype_ = c_int # default values for repr _name = '' _handle = 0 _FuncPtr = None def __init__(self, name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False): self._name = name flags = self._func_flags_ if use_errno: flags |= _FUNCFLAG_USE_ERRNO if use_last_error: flags |= _FUNCFLAG_USE_LASTERROR class _FuncPtr(_CFuncPtr): _flags_ = flags _restype_ = self._func_restype_ self._FuncPtr = _FuncPtr if handle is None: self._handle = _dlopen(self._name, mode) else: self._handle = handle def __repr__(self): return "<%s '%s', handle %x at %x>" % \ (self.__class__.__name__, self._name, (self._handle & (_sys.maxint*2 + 1)), id(self) & (_sys.maxint*2 + 1)) def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): raise AttributeError(name) func = self.__getitem__(name) setattr(self, name, func) return func def __getitem__(self, name_or_ordinal): func = self._FuncPtr((name_or_ordinal, self)) if not isinstance(name_or_ordinal, (int, long)): func.__name__ = name_or_ordinal return func class PyDLL(CDLL): """This class represents the Python library itself. It allows accessing Python API functions. The GIL is not released, and Python exceptions are handled correctly. """ _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI if _os.name in ("nt", "ce"): class WinDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention. """ _func_flags_ = _FUNCFLAG_STDCALL # XXX Hm, what about HRESULT as normal parameter? # Mustn't it derive from c_long then? from _ctypes import _check_HRESULT, _SimpleCData class HRESULT(_SimpleCData): _type_ = "l" # _check_retval_ is called with the function's result when it # is used as restype. It checks for the FAILED bit, and # raises a WindowsError if it is set. # # The _check_retval_ method is implemented in C, so that the # method definition itself is not included in the traceback # when it raises an error - that is what we want (and Python # doesn't have a way to raise an exception in the caller's # frame). _check_retval_ = _check_HRESULT class OleDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention, and returning HRESULT. HRESULT error values are automatically raised as WindowsError exceptions. """ _func_flags_ = _FUNCFLAG_STDCALL _func_restype_ = HRESULT class LibraryLoader(object): def __init__(self, dlltype): self._dlltype = dlltype def __getattr__(self, name): if name[0] == '_': raise AttributeError(name) dll = self._dlltype(name) setattr(self, name, dll) return dll def __getitem__(self, name): return getattr(self, name) def LoadLibrary(self, name): return self._dlltype(name) cdll = LibraryLoader(CDLL) pydll = LibraryLoader(PyDLL) if _os.name in ("nt", "ce"): pythonapi = PyDLL("python dll", None, _sys.dllhandle) elif _sys.platform == "cygwin": pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) else: pythonapi = PyDLL(None) if _os.name in ("nt", "ce"): windll = LibraryLoader(WinDLL) oledll = LibraryLoader(OleDLL) if _os.name == "nt": GetLastError = windll.kernel32.GetLastError else: GetLastError = windll.coredll.GetLastError from _ctypes import get_last_error, set_last_error def WinError(code=None, descr=None): if code is None: code = GetLastError() if descr is None: descr = FormatError(code).strip() return WindowsError(code, descr) if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int elif sizeof(c_ulong) == sizeof(c_void_p): c_size_t = c_ulong c_ssize_t = c_long elif sizeof(c_ulonglong) == sizeof(c_void_p): c_size_t = c_ulonglong c_ssize_t = c_longlong # functions from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr ## void *memmove(void *, const void *, size_t); memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) ## void *memset(void *, int, size_t) memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) def PYFUNCTYPE(restype, *argtypes): class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI return CFunctionType _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) def cast(obj, typ): return _cast(obj, obj, typ) _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) def string_at(ptr, size=-1): """string_at(addr[, size]) -> string Return the string at addr.""" return _string_at(ptr, size) try: from _ctypes import _wstring_at_addr except ImportError: pass else: _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) def wstring_at(ptr, size=-1): """wstring_at(addr[, size]) -> string Return the string at addr.""" return _wstring_at(ptr, size) if _os.name in ("nt", "ce"): # COM stuff def DllGetClassObject(rclsid, riid, ppv): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return -2147221231 # CLASS_E_CLASSNOTAVAILABLE else: return ccom.DllGetClassObject(rclsid, riid, ppv) def DllCanUnloadNow(): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return 0 # S_OK return ccom.DllCanUnloadNow() from ctypes._endian import BigEndianStructure, LittleEndianStructure # Fill in specifically-sized types c_int8 = c_byte c_uint8 = c_ubyte for kind in [c_short, c_int, c_long, c_longlong]: if sizeof(kind) == 2: c_int16 = kind elif sizeof(kind) == 4: c_int32 = kind elif sizeof(kind) == 8: c_int64 = kind for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]: if sizeof(kind) == 2: c_uint16 = kind elif sizeof(kind) == 4: c_uint32 = kind elif sizeof(kind) == 8: c_uint64 = kind del(kind) _reset_cache() lib64/python3.8/http/__init__.py000064400000014352152347331100012332 0ustar00from enum import IntEnum __all__ = ['HTTPStatus'] class HTTPStatus(IntEnum): """HTTP status codes and reason phrases Status codes from the following RFCs are all observed: * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 * RFC 6585: Additional HTTP Status Codes * RFC 3229: Delta encoding in HTTP * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 * RFC 5842: Binding Extensions to WebDAV * RFC 7238: Permanent Redirect * RFC 2295: Transparent Content Negotiation in HTTP * RFC 2774: An HTTP Extension Framework * RFC 7725: An HTTP Status Code to Report Legal Obstacles * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2) """ def __new__(cls, value, phrase, description=''): obj = int.__new__(cls, value) obj._value_ = value obj.phrase = phrase obj.description = description return obj # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', 'Switching to new protocol; obey Upgrade header') PROCESSING = 102, 'Processing' # success OK = 200, 'OK', 'Request fulfilled, document follows' CREATED = 201, 'Created', 'Document created, URL follows' ACCEPTED = (202, 'Accepted', 'Request accepted, processing continues off-line') NON_AUTHORITATIVE_INFORMATION = (203, 'Non-Authoritative Information', 'Request fulfilled from cache') NO_CONTENT = 204, 'No Content', 'Request fulfilled, nothing follows' RESET_CONTENT = 205, 'Reset Content', 'Clear input form for further input' PARTIAL_CONTENT = 206, 'Partial Content', 'Partial content follows' MULTI_STATUS = 207, 'Multi-Status' ALREADY_REPORTED = 208, 'Already Reported' IM_USED = 226, 'IM Used' # redirection MULTIPLE_CHOICES = (300, 'Multiple Choices', 'Object has several resources -- see URI list') MOVED_PERMANENTLY = (301, 'Moved Permanently', 'Object moved permanently -- see URI list') FOUND = 302, 'Found', 'Object moved temporarily -- see URI list' SEE_OTHER = 303, 'See Other', 'Object moved -- see Method and URL list' NOT_MODIFIED = (304, 'Not Modified', 'Document has not changed since given time') USE_PROXY = (305, 'Use Proxy', 'You must use proxy specified in Location to access this resource') TEMPORARY_REDIRECT = (307, 'Temporary Redirect', 'Object moved temporarily -- see URI list') PERMANENT_REDIRECT = (308, 'Permanent Redirect', 'Object moved permanently -- see URI list') # client error BAD_REQUEST = (400, 'Bad Request', 'Bad request syntax or unsupported method') UNAUTHORIZED = (401, 'Unauthorized', 'No permission -- see authorization schemes') PAYMENT_REQUIRED = (402, 'Payment Required', 'No payment -- see charging schemes') FORBIDDEN = (403, 'Forbidden', 'Request forbidden -- authorization will not help') NOT_FOUND = (404, 'Not Found', 'Nothing matches the given URI') METHOD_NOT_ALLOWED = (405, 'Method Not Allowed', 'Specified method is invalid for this resource') NOT_ACCEPTABLE = (406, 'Not Acceptable', 'URI not available in preferred format') PROXY_AUTHENTICATION_REQUIRED = (407, 'Proxy Authentication Required', 'You must authenticate with this proxy before proceeding') REQUEST_TIMEOUT = (408, 'Request Timeout', 'Request timed out; try again later') CONFLICT = 409, 'Conflict', 'Request conflict' GONE = (410, 'Gone', 'URI no longer exists and has been permanently removed') LENGTH_REQUIRED = (411, 'Length Required', 'Client must specify Content-Length') PRECONDITION_FAILED = (412, 'Precondition Failed', 'Precondition in headers is false') REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large', 'Entity is too large') REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long', 'URI is too long') UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type', 'Entity body in unsupported format') REQUESTED_RANGE_NOT_SATISFIABLE = (416, 'Requested Range Not Satisfiable', 'Cannot satisfy request range') EXPECTATION_FAILED = (417, 'Expectation Failed', 'Expect condition could not be satisfied') MISDIRECTED_REQUEST = (421, 'Misdirected Request', 'Server is not able to produce a response') UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity' LOCKED = 423, 'Locked' FAILED_DEPENDENCY = 424, 'Failed Dependency' UPGRADE_REQUIRED = 426, 'Upgrade Required' PRECONDITION_REQUIRED = (428, 'Precondition Required', 'The origin server requires the request to be conditional') TOO_MANY_REQUESTS = (429, 'Too Many Requests', 'The user has sent too many requests in ' 'a given amount of time ("rate limiting")') REQUEST_HEADER_FIELDS_TOO_LARGE = (431, 'Request Header Fields Too Large', 'The server is unwilling to process the request because its header ' 'fields are too large') UNAVAILABLE_FOR_LEGAL_REASONS = (451, 'Unavailable For Legal Reasons', 'The server is denying access to the ' 'resource as a consequence of a legal demand') # server errors INTERNAL_SERVER_ERROR = (500, 'Internal Server Error', 'Server got itself in trouble') NOT_IMPLEMENTED = (501, 'Not Implemented', 'Server does not support this operation') BAD_GATEWAY = (502, 'Bad Gateway', 'Invalid responses from another server/proxy') SERVICE_UNAVAILABLE = (503, 'Service Unavailable', 'The server cannot process the request due to a high load') GATEWAY_TIMEOUT = (504, 'Gateway Timeout', 'The gateway server did not receive a timely response') HTTP_VERSION_NOT_SUPPORTED = (505, 'HTTP Version Not Supported', 'Cannot fulfill request') VARIANT_ALSO_NEGOTIATES = 506, 'Variant Also Negotiates' INSUFFICIENT_STORAGE = 507, 'Insufficient Storage' LOOP_DETECTED = 508, 'Loop Detected' NOT_EXTENDED = 510, 'Not Extended' NETWORK_AUTHENTICATION_REQUIRED = (511, 'Network Authentication Required', 'The client needs to authenticate to gain network access') lib64/python3.8/html/__init__.py000064400000011224152347331220012315 0ustar00""" General functions for HTML manipulation. """ import re as _re from html.entities import html5 as _html5 __all__ = ['escape', 'unescape'] def escape(s, quote=True): """ Replace special characters "&", "<" and ">" to HTML-safe sequences. If the optional flag quote is true (the default), the quotation mark characters, both double quote (") and single quote (') characters are also translated. """ s = s.replace("&", "&") # Must be done first! s = s.replace("<", "<") s = s.replace(">", ">") if quote: s = s.replace('"', """) s = s.replace('\'', "'") return s # see http://www.w3.org/TR/html5/syntax.html#tokenizing-character-references _invalid_charrefs = { 0x00: '\ufffd', # REPLACEMENT CHARACTER 0x0d: '\r', # CARRIAGE RETURN 0x80: '\u20ac', # EURO SIGN 0x81: '\x81', # 0x82: '\u201a', # SINGLE LOW-9 QUOTATION MARK 0x83: '\u0192', # LATIN SMALL LETTER F WITH HOOK 0x84: '\u201e', # DOUBLE LOW-9 QUOTATION MARK 0x85: '\u2026', # HORIZONTAL ELLIPSIS 0x86: '\u2020', # DAGGER 0x87: '\u2021', # DOUBLE DAGGER 0x88: '\u02c6', # MODIFIER LETTER CIRCUMFLEX ACCENT 0x89: '\u2030', # PER MILLE SIGN 0x8a: '\u0160', # LATIN CAPITAL LETTER S WITH CARON 0x8b: '\u2039', # SINGLE LEFT-POINTING ANGLE QUOTATION MARK 0x8c: '\u0152', # LATIN CAPITAL LIGATURE OE 0x8d: '\x8d', # 0x8e: '\u017d', # LATIN CAPITAL LETTER Z WITH CARON 0x8f: '\x8f', # 0x90: '\x90', # 0x91: '\u2018', # LEFT SINGLE QUOTATION MARK 0x92: '\u2019', # RIGHT SINGLE QUOTATION MARK 0x93: '\u201c', # LEFT DOUBLE QUOTATION MARK 0x94: '\u201d', # RIGHT DOUBLE QUOTATION MARK 0x95: '\u2022', # BULLET 0x96: '\u2013', # EN DASH 0x97: '\u2014', # EM DASH 0x98: '\u02dc', # SMALL TILDE 0x99: '\u2122', # TRADE MARK SIGN 0x9a: '\u0161', # LATIN SMALL LETTER S WITH CARON 0x9b: '\u203a', # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 0x9c: '\u0153', # LATIN SMALL LIGATURE OE 0x9d: '\x9d', # 0x9e: '\u017e', # LATIN SMALL LETTER Z WITH CARON 0x9f: '\u0178', # LATIN CAPITAL LETTER Y WITH DIAERESIS } _invalid_codepoints = { # 0x0001 to 0x0008 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, # 0x000E to 0x001F 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, # 0x007F to 0x009F 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, # 0xFDD0 to 0xFDEF 0xfdd0, 0xfdd1, 0xfdd2, 0xfdd3, 0xfdd4, 0xfdd5, 0xfdd6, 0xfdd7, 0xfdd8, 0xfdd9, 0xfdda, 0xfddb, 0xfddc, 0xfddd, 0xfdde, 0xfddf, 0xfde0, 0xfde1, 0xfde2, 0xfde3, 0xfde4, 0xfde5, 0xfde6, 0xfde7, 0xfde8, 0xfde9, 0xfdea, 0xfdeb, 0xfdec, 0xfded, 0xfdee, 0xfdef, # others 0xb, 0xfffe, 0xffff, 0x1fffe, 0x1ffff, 0x2fffe, 0x2ffff, 0x3fffe, 0x3ffff, 0x4fffe, 0x4ffff, 0x5fffe, 0x5ffff, 0x6fffe, 0x6ffff, 0x7fffe, 0x7ffff, 0x8fffe, 0x8ffff, 0x9fffe, 0x9ffff, 0xafffe, 0xaffff, 0xbfffe, 0xbffff, 0xcfffe, 0xcffff, 0xdfffe, 0xdffff, 0xefffe, 0xeffff, 0xffffe, 0xfffff, 0x10fffe, 0x10ffff } def _replace_charref(s): s = s.group(1) if s[0] == '#': # numeric charref if s[1] in 'xX': num = int(s[2:].rstrip(';'), 16) else: num = int(s[1:].rstrip(';')) if num in _invalid_charrefs: return _invalid_charrefs[num] if 0xD800 <= num <= 0xDFFF or num > 0x10FFFF: return '\uFFFD' if num in _invalid_codepoints: return '' return chr(num) else: # named charref if s in _html5: return _html5[s] # find the longest matching name (as defined by the standard) for x in range(len(s)-1, 1, -1): if s[:x] in _html5: return _html5[s[:x]] + s[x:] else: return '&' + s _charref = _re.compile(r'&(#[0-9]+;?' r'|#[xX][0-9a-fA-F]+;?' r'|[^\t\n\f <&#;]{1,32};?)') def unescape(s): """ Convert all named and numeric character references (e.g. >, >, &x3e;) in the string s to the corresponding unicode characters. This function uses the rules defined by the HTML 5 standard for both valid and invalid character references, and the list of HTML 5 named character references defined in html.entities.html5. """ if '&' not in s: return s return _charref.sub(_replace_charref, s) usr/lib/python3.6/site-packages/sepolicy/__init__.py000064400000111172152347355040016366 0ustar00# Author: Dan Walsh # Author: Ryan Hallisey # Author: Jason Zaman import errno import selinux import setools import glob import sepolgen.defaults as defaults import sepolgen.interfaces as interfaces import sys import os import re import gzip PROGNAME = "selinux-python" try: import gettext kwargs = {} if sys.version_info < (3,): kwargs['unicode'] = True gettext.install(PROGNAME, localedir="/usr/share/locale", codeset='utf-8', **kwargs) except: try: import builtins builtins.__dict__['_'] = str except ImportError: import __builtin__ __builtin__.__dict__['_'] = unicode TYPE = 1 ROLE = 2 ATTRIBUTE = 3 PORT = 4 USER = 5 BOOLEAN = 6 TCLASS = 7 ALLOW = 'allow' AUDITALLOW = 'auditallow' NEVERALLOW = 'neverallow' DONTAUDIT = 'dontaudit' SOURCE = 'source' TARGET = 'target' PERMS = 'permlist' CLASS = 'class' TRANSITION = 'transition' ROLE_ALLOW = 'role_allow' # Autofill for adding files ************************* DEFAULT_DIRS = {} DEFAULT_DIRS["/etc"] = "etc_t" DEFAULT_DIRS["/tmp"] = "tmp_t" DEFAULT_DIRS["/usr/lib/systemd/system"] = "unit_file_t" DEFAULT_DIRS["/lib/systemd/system"] = "unit_file_t" DEFAULT_DIRS["/etc/systemd/system"] = "unit_file_t" DEFAULT_DIRS["/var/cache"] = "var_cache_t" DEFAULT_DIRS["/var/lib"] = "var_lib_t" DEFAULT_DIRS["/var/log"] = "log_t" DEFAULT_DIRS["/var/run"] = "var_run_t" DEFAULT_DIRS["/run"] = "var_run_t" DEFAULT_DIRS["/run/lock"] = "var_lock_t" DEFAULT_DIRS["/var/run/lock"] = "var_lock_t" DEFAULT_DIRS["/var/spool"] = "var_spool_t" DEFAULT_DIRS["/var/www"] = "content_t" file_type_str = {} file_type_str["a"] = _("all files") file_type_str["f"] = _("regular file") file_type_str["d"] = _("directory") file_type_str["c"] = _("character device") file_type_str["b"] = _("block device") file_type_str["s"] = _("socket file") file_type_str["l"] = _("symbolic link") file_type_str["p"] = _("named pipe") trans_file_type_str = {} trans_file_type_str[""] = "a" trans_file_type_str["--"] = "f" trans_file_type_str["-d"] = "d" trans_file_type_str["-c"] = "c" trans_file_type_str["-b"] = "b" trans_file_type_str["-s"] = "s" trans_file_type_str["-l"] = "l" trans_file_type_str["-p"] = "p" # the setools policy handle _pol = None # cache the lookup results file_equiv_modified = None file_equiv = None local_files = None fcdict = None methods = [] all_types = None all_types_info = None user_types = None role_allows = None portrecs = None portrecsbynum = None all_domains = None roles = None selinux_user_list = None login_mappings = None file_types = None port_types = None bools = None all_attributes = None booleans = None booleans_dict = None all_allow_rules = None all_bool_rules = None all_transitions = None def policy_sortkey(policy_path): # Parse the extension of a policy path which looks like .../policy/policy.31 extension = policy_path.rsplit('/policy.', 1)[1] try: return int(extension), policy_path except ValueError: # Fallback with sorting on the full path return 0, policy_path def get_installed_policy(root="/"): try: path = root + selinux.selinux_binary_policy_path() policies = glob.glob("%s.*" % path) policies.sort(key=policy_sortkey) return policies[-1] except: pass raise ValueError(_("No SELinux Policy installed")) def get_store_policy(store): """Get the path to the policy file located in the given store name""" policies = glob.glob("%s%s/policy/policy.*" % (selinux.selinux_path(), store)) if not policies: return None # Return the policy with the higher version number policies.sort(key=policy_sortkey) return policies[-1] def policy(policy_file): global all_domains global all_attributes global bools global all_types global role_allows global users global roles global file_types global port_types all_domains = None all_attributes = None bools = None all_types = None role_allows = None users = None roles = None file_types = None port_types = None global _pol try: _pol = setools.SELinuxPolicy(policy_file) except: raise ValueError(_("Failed to read %s policy file") % policy_file) def load_store_policy(store): policy_file = get_store_policy(store) if not policy_file: return None policy(policy_file) try: policy_file = get_installed_policy() policy(policy_file) except ValueError as e: if selinux.is_selinux_enabled() == 1: raise e def info(setype, name=None): if setype == TYPE: q = setools.TypeQuery(_pol) q.name = name results = list(q.results()) if name and len(results) < 1: # type not found, try alias q.name = None q.alias = name results = list(q.results()) return ({ 'aliases': list(map(str, x.aliases())), 'name': str(x), 'permissive': bool(x.ispermissive), 'attributes': list(map(str, x.attributes())) } for x in results) elif setype == ROLE: q = setools.RoleQuery(_pol) if name: q.name = name return ({ 'name': str(x), 'roles': list(map(str, x.expand())), 'types': list(map(str, x.types())), } for x in q.results()) elif setype == ATTRIBUTE: q = setools.TypeAttributeQuery(_pol) if name: q.name = name return ({ 'name': str(x), 'types': list(map(str, x.expand())), } for x in q.results()) elif setype == PORT: q = setools.PortconQuery(_pol) if name: ports = [int(i) for i in name.split("-")] if len(ports) == 2: q.ports = ports elif len(ports) == 1: q.ports = (ports[0], ports[0]) if _pol.mls: return ({ 'high': x.ports.high, 'protocol': str(x.protocol), 'range': str(x.context.range_), 'type': str(x.context.type_), 'low': x.ports.low, } for x in q.results()) return ({ 'high': x.ports.high, 'protocol': str(x.protocol), 'type': str(x.context.type_), 'low': x.ports.low, } for x in q.results()) elif setype == USER: q = setools.UserQuery(_pol) if name: q.name = name if _pol.mls: return ({ 'range': str(x.mls_range), 'name': str(x), 'roles': list(map(str, x.roles)), 'level': str(x.mls_level), } for x in q.results()) return ({ 'name': str(x), 'roles': list(map(str, x.roles)), } for x in q.results()) elif setype == BOOLEAN: q = setools.BoolQuery(_pol) if name: q.name = name return ({ 'name': str(x), 'state': x.state, } for x in q.results()) elif setype == TCLASS: q = setools.ObjClassQuery(_pol) if name: q.name = name return ({ 'name': str(x), 'permlist': list(x.perms), } for x in q.results()) else: raise ValueError("Invalid type") def _setools_rule_to_dict(rule): d = { 'type': str(rule.ruletype), 'source': str(rule.source), 'target': str(rule.target), 'class': str(rule.tclass), } # Evaluate boolean expression associated with given rule (if there is any) try: # Get state of all booleans in the conditional expression boolstate = {} for boolean in rule.conditional.booleans: boolstate[str(boolean)] = boolean.state # evaluate if the rule is enabled enabled = rule.conditional.evaluate(**boolstate) == rule.conditional_block except AttributeError: # non-conditional rules are always enabled enabled = True d['enabled'] = enabled try: d['permlist'] = list(map(str, rule.perms)) except AttributeError: pass try: d['transtype'] = str(rule.default) except AttributeError: pass try: d['booleans'] = [(str(b), b.state) for b in rule.conditional.booleans] except AttributeError: pass try: d['conditional'] = str(rule.conditional) except AttributeError: pass try: d['filename'] = rule.filename except AttributeError: pass return d def search(types, seinfo=None): if not seinfo: seinfo = {} valid_types = set([ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT, TRANSITION, ROLE_ALLOW]) for setype in types: if setype not in valid_types: raise ValueError("Type has to be in %s" % " ".join(valid_types)) source = None if SOURCE in seinfo: source = str(seinfo[SOURCE]) target = None if TARGET in seinfo: target = str(seinfo[TARGET]) tclass = None if CLASS in seinfo: tclass = str(seinfo[CLASS]).split(',') toret = [] tertypes = [] if ALLOW in types: tertypes.append(ALLOW) if NEVERALLOW in types: tertypes.append(NEVERALLOW) if AUDITALLOW in types: tertypes.append(AUDITALLOW) if DONTAUDIT in types: tertypes.append(DONTAUDIT) if len(tertypes) > 0: q = setools.TERuleQuery(_pol, ruletype=tertypes, source=source, target=target, tclass=tclass) if PERMS in seinfo: q.perms = seinfo[PERMS] toret += [_setools_rule_to_dict(x) for x in q.results()] if TRANSITION in types: rtypes = ['type_transition', 'type_change', 'type_member'] q = setools.TERuleQuery(_pol, ruletype=rtypes, source=source, target=target, tclass=tclass) if PERMS in seinfo: q.perms = seinfo[PERMS] toret += [_setools_rule_to_dict(x) for x in q.results()] if ROLE_ALLOW in types: ratypes = ['allow'] q = setools.RBACRuleQuery(_pol, ruletype=ratypes, source=source, target=target, tclass=tclass) for r in q.results(): toret.append({'source': str(r.source), 'target': str(r.target)}) return toret def get_conditionals(src, dest, tclass, perm): tdict = {} tlist = [] src_list = [src] dest_list = [dest] # add assigned attributes try: src_list += list(filter(lambda x: x['name'] == src, get_all_types_info()))[0]['attributes'] except: pass try: dest_list += list(filter(lambda x: x['name'] == dest, get_all_types_info()))[0]['attributes'] except: pass allows = map(lambda y: y, filter(lambda x: x['source'] in src_list and x['target'] in dest_list and set(perm).issubset(x[PERMS]) and 'conditional' in x, get_all_allow_rules())) try: for i in allows: tdict.update({'source': i['source'], 'conditional': (i['conditional'], i['enabled'])}) if tdict not in tlist: tlist.append(tdict) tdict = {} except KeyError: return(tlist) return (tlist) def get_conditionals_format_text(cond): enabled = False for x in cond: if x['conditional'][1]: enabled = True break return _("-- Allowed %s [ %s ]") % (enabled, " || ".join(set(map(lambda x: "%s=%d" % (x['conditional'][0], x['conditional'][1]), cond)))) def get_types_from_attribute(attribute): return list(info(ATTRIBUTE, attribute))[0]["types"] def get_file_types(setype): flist = [] mpaths = {} for f in get_all_file_types(): if f.startswith(gen_short_name(setype)): flist.append(f) fcdict = get_fcdict() for f in flist: try: mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]]) except KeyError: mpaths[f] = [] return mpaths def get_real_type_name(name): """Return the real name of a type * If 'name' refers to a type alias, return the corresponding type name. * Otherwise return the original name (even if the type does not exist). """ if not name: return name try: return next(info(TYPE, name))["name"] except (RuntimeError, StopIteration): return name def get_writable_files(setype): file_types = get_all_file_types() all_writes = [] mpaths = {} permlist = search([ALLOW], {'source': setype, 'permlist': ['open', 'write'], 'class': 'file'}) if permlist is None or len(permlist) == 0: return mpaths fcdict = get_fcdict() attributes = ["proc_type", "sysctl_type"] for i in permlist: if i['target'] in attributes: continue if "enabled" in i: if not i["enabled"]: continue if i['target'].endswith("_t"): if i['target'] not in file_types: continue if i['target'] not in all_writes: if i['target'] != setype: all_writes.append(i['target']) else: for t in get_types_from_attribute(i['target']): if t not in all_writes: all_writes.append(t) for f in all_writes: try: mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]]) except KeyError: mpaths[f] = [] # {"regex":[],"paths":[]} return mpaths def find_file(reg): if os.path.exists(reg): return [reg] try: pat = re.compile(r"%s$" % reg) except: print("bad reg:", reg) return [] p = reg if p.endswith("(/.*)?"): p = p[:-6] + "/" path = os.path.dirname(p) try: # Bug fix: when "all files on system" if path[-1] != "/": # is pass in it breaks without try block path += "/" except IndexError: print("try failed got an IndexError") pass try: pat = re.compile(r"%s$" % reg) return [x for x in map(lambda x: path + x, os.listdir(path)) if pat.match(x)] except: return [] def find_all_files(domain, exclude_list=[]): executable_files = get_entrypoints(domain) for exe in executable_files.keys(): if exe.endswith("_exec_t") and exe not in exclude_list: for path in executable_files[exe]: for f in find_file(path): return f return None def find_entrypoint_path(exe, exclude_list=[]): fcdict = get_fcdict() try: if exe.endswith("_exec_t") and exe not in exclude_list: for path in fcdict[exe]["regex"]: for f in find_file(path): return f except KeyError: pass return None def read_file_equiv(edict, fc_path, modify): try: with open(fc_path, "r") as fd: for e in fd: f = e.split() if f and not f[0].startswith('#'): edict[f[0]] = {"equiv": f[1], "modify": modify} except OSError as e: if e.errno != errno.ENOENT: raise return edict def get_file_equiv_modified(fc_path=selinux.selinux_file_context_path()): global file_equiv_modified if file_equiv_modified: return file_equiv_modified file_equiv_modified = {} file_equiv_modified = read_file_equiv(file_equiv_modified, fc_path + ".subs", modify=True) return file_equiv_modified def get_file_equiv(fc_path=selinux.selinux_file_context_path()): global file_equiv if file_equiv: return file_equiv file_equiv = get_file_equiv_modified(fc_path) file_equiv = read_file_equiv(file_equiv, fc_path + ".subs_dist", modify=False) return file_equiv def get_local_file_paths(fc_path=selinux.selinux_file_context_path()): global local_files if local_files: return local_files local_files = [] try: with open(fc_path + ".local", "r") as fd: fc = fd.readlines() except OSError as e: if e.errno != errno.ENOENT: raise return [] for i in fc: rec = i.split() if len(rec) == 0: continue try: if len(rec) > 2: ftype = trans_file_type_str[rec[1]] else: ftype = "a" local_files.append((rec[0], ftype)) except KeyError: pass return local_files def get_fcdict(fc_path=selinux.selinux_file_context_path()): global fcdict if fcdict: return fcdict fd = open(fc_path, "r") fc = fd.readlines() fd.close() fd = open(fc_path + ".homedirs", "r") fc += fd.readlines() fd.close() fcdict = {} try: with open(fc_path + ".local", "r") as fd: fc += fd.readlines() except OSError as e: if e.errno != errno.ENOENT: raise for i in fc: rec = i.split() try: if len(rec) > 2: ftype = trans_file_type_str[rec[1]] else: ftype = "a" t = rec[-1].split(":")[2] if t in fcdict: fcdict[t]["regex"].append(rec[0]) else: fcdict[t] = {"regex": [rec[0]], "ftype": ftype} except: pass fcdict["logfile"] = {"regex": ["all log files"]} fcdict["user_tmp_type"] = {"regex": ["all user tmp files"]} fcdict["user_home_type"] = {"regex": ["all user home files"]} fcdict["virt_image_type"] = {"regex": ["all virtual image files"]} fcdict["noxattrfs"] = {"regex": ["all files on file systems which do not support extended attributes"]} fcdict["sandbox_tmpfs_type"] = {"regex": ["all sandbox content in tmpfs file systems"]} fcdict["user_tmpfs_type"] = {"regex": ["all user content in tmpfs file systems"]} fcdict["file_type"] = {"regex": ["all files on the system"]} fcdict["samba_share_t"] = {"regex": ["use this label for random content that will be shared using samba"]} return fcdict def get_transitions_into(setype): try: return [x for x in search([TRANSITION], {'class': 'process'}) if x["transtype"] == setype] except (TypeError, AttributeError): pass return None def get_transitions(setype): try: return search([TRANSITION], {'source': setype, 'class': 'process'}) except (TypeError, AttributeError): pass return None def get_file_transitions(setype): try: return [x for x in search([TRANSITION], {'source': setype}) if x['class'] != "process"] except (TypeError, AttributeError): pass return None def get_boolean_rules(setype, boolean): boollist = [] permlist = search([ALLOW], {'source': setype}) for p in permlist: if "booleans" in p: try: for b in p["booleans"]: if boolean in b: boollist.append(p) except: pass return boollist def get_all_entrypoints(): return get_types_from_attribute("entry_type") def get_entrypoint_types(setype): q = setools.TERuleQuery(_pol, ruletype=[ALLOW], source=setype, tclass=["file"], perms=["entrypoint"]) return [str(x.target) for x in q.results() if x.source == setype] def get_init_transtype(path): entrypoint = selinux.getfilecon(path)[1].split(":")[2] try: entrypoints = list(filter(lambda x: x['target'] == entrypoint, search([TRANSITION], {'source': "init_t", 'class': 'process'}))) return entrypoints[0]["transtype"] except (TypeError, AttributeError, IndexError): pass return None def get_init_entrypoint(transtype): q = setools.TERuleQuery(_pol, ruletype=["type_transition"], source="init_t", tclass=["process"]) entrypoints = [] for i in q.results(): try: if i.default == transtype: entrypoints.append(i.target) except AttributeError: continue return entrypoints def get_init_entrypoints_str(): q = setools.TERuleQuery(_pol, ruletype=["type_transition"], source="init_t", tclass=["process"]) entrypoints = {} for i in q.results(): try: transtype = str(i.default) if transtype in entrypoints: entrypoints[transtype].append(str(i.target)) else: entrypoints[transtype] = [str(i.target)] except AttributeError: continue return entrypoints def get_init_entrypoint_target(entrypoint): try: entrypoints = map(lambda x: x['transtype'], search([TRANSITION], {'source': "init_t", 'target': entrypoint, 'class': 'process'})) return list(entrypoints)[0] except (TypeError, IndexError): pass return None def get_entrypoints(setype): fcdict = get_fcdict() mpaths = {} for f in get_entrypoint_types(setype): try: mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]]) except KeyError: mpaths[f] = [] return mpaths def get_methods(): global methods if len(methods) > 0: return methods gen_interfaces() fn = defaults.interface_info() try: fd = open(fn) # List of per_role_template interfaces ifs = interfaces.InterfaceSet() ifs.from_file(fd) methods = list(ifs.interfaces.keys()) fd.close() except: sys.stderr.write("could not open interface info [%s]\n" % fn) sys.exit(1) methods.sort() return methods def get_all_types(): global all_types if all_types is None: all_types = [x['name'] for x in info(TYPE)] return all_types def get_all_types_info(): global all_types_info if all_types_info is None: all_types_info = list(info(TYPE)) return all_types_info def get_user_types(): global user_types if user_types is None: user_types = list(list(info(ATTRIBUTE, "userdomain"))[0]["types"]) return user_types def get_all_role_allows(): global role_allows if role_allows: return role_allows role_allows = {} q = setools.RBACRuleQuery(_pol, ruletype=[ALLOW]) for r in q.results(): src = str(r.source) tgt = str(r.target) if src == "system_r" or tgt == "system_r": continue if src in role_allows: role_allows[src].append(tgt) else: role_allows[src] = [tgt] return role_allows def get_all_entrypoint_domains(): import re all_domains = [] types = sorted(get_all_types()) for i in types: m = re.findall("(.*)%s" % "_exec_t$", i) if len(m) > 0: if len(re.findall("(.*)%s" % "_initrc$", m[0])) == 0 and m[0] not in all_domains: all_domains.append(m[0]) return all_domains def gen_interfaces(): try: from commands import getstatusoutput except ImportError: from subprocess import getstatusoutput ifile = defaults.interface_info() headers = defaults.headers() try: if os.stat(headers).st_mtime <= os.stat(ifile).st_mtime: return except OSError: pass if os.getuid() != 0: raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen")) print(getstatusoutput("/usr/bin/sepolgen-ifgen")[1]) def gen_port_dict(): global portrecs global portrecsbynum if portrecs: return (portrecs, portrecsbynum) portrecsbynum = {} portrecs = {} for i in info(PORT): if i['low'] == i['high']: port = str(i['low']) else: port = "%s-%s" % (str(i['low']), str(i['high'])) if (i['type'], i['protocol']) in portrecs: portrecs[(i['type'], i['protocol'])].append(port) else: portrecs[(i['type'], i['protocol'])] = [port] if 'range' in i: portrecsbynum[(i['low'], i['high'], i['protocol'])] = (i['type'], i['range']) else: portrecsbynum[(i['low'], i['high'], i['protocol'])] = (i['type']) return (portrecs, portrecsbynum) def get_all_domains(): global all_domains if not all_domains: all_domains = list(list(info(ATTRIBUTE, "domain"))[0]["types"]) return all_domains def get_all_roles(): global roles if roles: return roles q = setools.RoleQuery(_pol) roles = [str(x) for x in q.results() if str(x) != "object_r"] return roles def get_selinux_users(): global selinux_user_list if not selinux_user_list: selinux_user_list = list(info(USER)) if _pol.mls: for x in selinux_user_list: x['range'] = "".join(x['range'].split(" ")) return selinux_user_list def get_login_mappings(): global login_mappings if login_mappings: return login_mappings fd = open(selinux.selinux_usersconf_path(), "r") buf = fd.read() fd.close() login_mappings = [] for b in buf.split("\n"): b = b.strip() if len(b) == 0 or b.startswith("#"): continue x = b.split(":") login_mappings.append({"name": x[0], "seuser": x[1], "mls": ":".join(x[2:])}) return login_mappings def get_all_users(): return sorted(map(lambda x: x['name'], get_selinux_users())) def get_all_file_types(): global file_types if file_types: return file_types file_types = list(sorted(info(ATTRIBUTE, "file_type"))[0]["types"]) return file_types def get_all_port_types(): global port_types if port_types: return port_types port_types = list(sorted(info(ATTRIBUTE, "port_type"))[0]["types"]) return port_types def get_all_bools(): global bools if not bools: bools = list(info(BOOLEAN)) return bools def prettyprint(f, trim): return " ".join(f[:-len(trim)].split("_")) def markup(f): return f def get_description(f, markup=markup): txt = "Set files with the %s type, if you want to " % markup(f) if f.endswith("_var_run_t"): return txt + "store the %s files under the /run or /var/run directory." % prettyprint(f, "_var_run_t") if f.endswith("_pid_t"): return txt + "store the %s files under the /run directory." % prettyprint(f, "_pid_t") if f.endswith("_var_lib_t"): return txt + "store the %s files under the /var/lib directory." % prettyprint(f, "_var_lib_t") if f.endswith("_var_t"): return txt + "store the %s files under the /var directory." % prettyprint(f, "_var_lib_t") if f.endswith("_var_spool_t"): return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t") if f.endswith("_spool_t"): return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t") if f.endswith("_cache_t") or f.endswith("_var_cache_t"): return txt + "store the files under the /var/cache directory." if f.endswith("_keytab_t"): return txt + "treat the files as kerberos keytab files." if f.endswith("_lock_t"): return txt + "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f, "_lock_t") if f.endswith("_log_t"): return txt + "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f, "_log_t") if f.endswith("_config_t"): return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f, "_config_t") if f.endswith("_conf_t"): return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f, "_conf_t") if f.endswith("_exec_t"): return txt + "transition an executable to the %s_t domain." % f[:-len("_exec_t")] if f.endswith("_cgi_content_t"): return txt + "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t") if f.endswith("_rw_content_t"): return txt + "treat the files as %s read/write content." % prettyprint(f, "_rw_content_t") if f.endswith("_rw_t"): return txt + "treat the files as %s read/write content." % prettyprint(f, "_rw_t") if f.endswith("_write_t"): return txt + "treat the files as %s read/write content." % prettyprint(f, "_write_t") if f.endswith("_db_t"): return txt + "treat the files as %s database content." % prettyprint(f, "_db_t") if f.endswith("_ra_content_t"): return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_content_t") if f.endswith("_cert_t"): return txt + "treat the files as %s certificate data." % prettyprint(f, "_cert_t") if f.endswith("_key_t"): return txt + "treat the files as %s key data." % prettyprint(f, "_key_t") if f.endswith("_secret_t"): return txt + "treat the files as %s secret data." % prettyprint(f, "_key_t") if f.endswith("_ra_t"): return txt + "treat the files as %s read/append content." % prettyprint(f, "_ra_t") if f.endswith("_ro_t"): return txt + "treat the files as %s read/only content." % prettyprint(f, "_ro_t") if f.endswith("_modules_t"): return txt + "treat the files as %s modules." % prettyprint(f, "_modules_t") if f.endswith("_content_t"): return txt + "treat the files as %s content." % prettyprint(f, "_content_t") if f.endswith("_state_t"): return txt + "treat the files as %s state data." % prettyprint(f, "_state_t") if f.endswith("_files_t"): return txt + "treat the files as %s content." % prettyprint(f, "_files_t") if f.endswith("_file_t"): return txt + "treat the files as %s content." % prettyprint(f, "_file_t") if f.endswith("_data_t"): return txt + "treat the files as %s content." % prettyprint(f, "_data_t") if f.endswith("_file_t"): return txt + "treat the data as %s content." % prettyprint(f, "_file_t") if f.endswith("_tmp_t"): return txt + "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t") if f.endswith("_etc_t"): return txt + "store %s files in the /etc directories." % prettyprint(f, "_tmp_t") if f.endswith("_home_t"): return txt + "store %s files in the users home directory." % prettyprint(f, "_home_t") if f.endswith("_tmpfs_t"): return txt + "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t") if f.endswith("_unit_file_t"): return txt + "treat files as a systemd unit file." if f.endswith("_htaccess_t"): return txt + "treat the file as a %s access file." % prettyprint(f, "_htaccess_t") return txt + "treat the files as %s data." % prettyprint(f, "_t") def get_all_attributes(): global all_attributes if not all_attributes: all_attributes = list(sorted(map(lambda x: x['name'], info(ATTRIBUTE)))) return all_attributes def _dict_has_perms(dict, perms): for perm in perms: if perm not in dict[PERMS]: return False return True def gen_short_name(setype): all_domains = get_all_domains() if setype.endswith("_t"): # replace aliases with corresponding types setype = get_real_type_name(setype) domainname = setype[:-2] else: domainname = setype if domainname + "_t" not in all_domains: raise ValueError("domain %s_t does not exist" % domainname) if domainname[-1] == 'd': short_name = domainname[:-1] + "_" else: short_name = domainname + "_" return (domainname, short_name) def get_all_allow_rules(): global all_allow_rules if not all_allow_rules: all_allow_rules = search([ALLOW]) return all_allow_rules def get_all_bool_rules(): global all_bool_rules if not all_bool_rules: q = setools.TERuleQuery(_pol, boolean=".*", boolean_regex=True, ruletype=[ALLOW, DONTAUDIT]) all_bool_rules = [_setools_rule_to_dict(x) for x in q.results()] return all_bool_rules def get_all_transitions(): global all_transitions if not all_transitions: all_transitions = list(search([TRANSITION])) return all_transitions def get_bools(setype): bools = [] domainbools = [] domainname, short_name = gen_short_name(setype) for i in map(lambda x: x['booleans'], filter(lambda x: 'booleans' in x and x['source'] == setype, get_all_bool_rules())): for b in i: if not isinstance(b, tuple): continue try: enabled = selinux.security_get_boolean_active(b[0]) except OSError: enabled = b[1] if b[0].startswith(short_name) or b[0].startswith(domainname): if (b[0], enabled) not in domainbools and (b[0], not enabled) not in domainbools: domainbools.append((b[0], enabled)) else: if (b[0], enabled) not in bools and (b[0], not enabled) not in bools: bools.append((b[0], enabled)) return (domainbools, bools) def get_all_booleans(): global booleans if not booleans: booleans = selinux.security_get_boolean_names()[1] return booleans def policy_xml(path="/usr/share/selinux/devel/policy.xml"): try: fd = gzip.open(path) buf = fd.read() fd.close() except IOError: fd = open(path) buf = fd.read() fd.close() return buf def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"): global booleans_dict if booleans_dict: return booleans_dict import xml.etree.ElementTree booleans_dict = {} try: tree = xml.etree.ElementTree.fromstring(policy_xml(path)) for l in tree.findall("layer"): for m in l.findall("module"): for b in m.findall("tunable"): desc = b.find("desc").find("p").text.strip("\n") desc = re.sub("\n", " ", desc) booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc) for b in m.findall("bool"): desc = b.find("desc").find("p").text.strip("\n") desc = re.sub("\n", " ", desc) booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc) for i in tree.findall("bool"): desc = i.find("desc").find("p").text.strip("\n") desc = re.sub("\n", " ", desc) booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc) for i in tree.findall("tunable"): desc = i.find("desc").find("p").text.strip("\n") desc = re.sub("\n", " ", desc) booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc) except IOError: pass return booleans_dict def boolean_category(boolean): booleans_dict = gen_bool_dict() if boolean in booleans_dict: return _(booleans_dict[boolean][0]) else: return _("unknown") def boolean_desc(boolean): booleans_dict = gen_bool_dict() if boolean in booleans_dict: return _(booleans_dict[boolean][2]) else: desc = boolean.split("_") return "Allow %s to %s" % (desc[0], " ".join(desc[1:])) def get_os_version(): system_release = "" try: with open('/etc/system-release') as f: system_release = f.readline().rstrip() except IOError: system_release = "Misc" return system_release def reinit(): global all_attributes global all_domains global all_types global booleans global booleans_dict global bools global fcdict global file_types global local_files global methods global methods global portrecs global portrecsbynum global port_types global role_allows global roles global login_mappings global selinux_user_list global user_types all_attributes = None all_domains = None all_types = None booleans = None booleans_dict = None bools = None fcdict = None file_types = None local_files = None methods = None methods = None portrecs = None portrecsbynum = None port_types = None role_allows = None roles = None user_types = None login_mappings = None selinux_user_list = None usr/lib64/python2.7/unittest/__init__.py000064400000005336152347373170014060 0ustar00""" Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's Smalltalk testing framework. This module contains the core framework classes that form the basis of specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results (TextTestRunner). Simple usage: import unittest class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): ## test method names begin 'test*' self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main() Further information is available in the bundled documentation, and from http://docs.python.org/library/unittest.html Copyright (c) 1999-2003 Steve Purcell Copyright (c) 2003-2010 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', 'registerResult', 'removeResult', 'removeHandler'] # Expose obsolete functions for backwards compatibility __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) __unittest = True from .result import TestResult from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf, skipUnless, expectedFailure, _skipInRpmBuild, _expectedFailureInRpmBuild) from .suite import BaseTestSuite, TestSuite from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, findTestCases) from .main import TestProgram, main from .runner import TextTestRunner, TextTestResult from .signals import installHandler, registerResult, removeResult, removeHandler # deprecated _TextTestResult = TextTestResult usr/lib64/python3.6/ensurepip/__init__.py000064400000015520152347470000014175 0ustar00import distutils.version import glob import os import os.path import sys import tempfile __all__ = ["version", "bootstrap"] _WHEEL_DIR = "/usr/share/python{}-wheels/".format(sys.version_info[0]) def _get_most_recent_wheel_version(pkg): prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) suffix = "-py2.py3-none-any.whl" pattern = "{}*{}".format(prefix, suffix) versions = (p[len(prefix):-len(suffix)] for p in glob.glob(pattern)) return str(max(versions, key=distutils.version.LooseVersion)) _SETUPTOOLS_VERSION = _get_most_recent_wheel_version("setuptools") _PIP_VERSION = _get_most_recent_wheel_version("pip") _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION), ("pip", _PIP_VERSION), ] def _run_pip(args, additional_paths=None): # Add our bundled software to the sys.path so we can import it if additional_paths is not None: sys.path = additional_paths + sys.path try: # pip 10 from pip._internal import main except ImportError: # pip 9 from pip import main if args[0] in ["install", "list", "wheel"]: args.append('--pre') return main(args) def version(): """ Returns a string specifying the bundled version of pip. """ return _PIP_VERSION def _disable_pip_configuration_settings(): # We deliberately ignore all pip environment variables # when invoking pip # See http://bugs.python.org/issue19734 for details keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] for k in keys_to_remove: del os.environ[k] # We also ignore the settings in the default pip configuration file # See http://bugs.python.org/issue20053 for details os.environ['PIP_CONFIG_FILE'] = os.devnull def bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Note that calling this function will alter both sys.path and os.environ. """ # Discard the return value _bootstrap(root=root, upgrade=upgrade, user=user, altinstall=altinstall, default_pip=default_pip, verbosity=verbosity) def _bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Returns pip command status code. Note that calling this function will alter both sys.path and os.environ. """ if altinstall and default_pip: raise ValueError("Cannot use altinstall and default_pip together") _disable_pip_configuration_settings() # By default, installing pip and setuptools installs all of the # following scripts (X.Y == running Python version): # # pip, pipX, pipX.Y, easy_install, easy_install-X.Y # # pip 1.5+ allows ensurepip to request that some of those be left out if altinstall: # omit pip, pipX and easy_install os.environ["ENSUREPIP_OPTIONS"] = "altinstall" elif not default_pip: # omit pip and easy_install os.environ["ENSUREPIP_OPTIONS"] = "install" with tempfile.TemporaryDirectory() as tmpdir: # Put our bundled wheels into a temporary directory and construct the # additional paths that need added to sys.path additional_paths = [] for project, version in _PROJECTS: wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version) with open(os.path.join(_WHEEL_DIR, wheel_name), "rb") as sfp: with open(os.path.join(tmpdir, wheel_name), "wb") as fp: fp.write(sfp.read()) additional_paths.append(os.path.join(tmpdir, wheel_name)) # Construct the arguments to be passed to the pip command args = ["install", "--no-index", "--find-links", tmpdir] if root: args += ["--root", root] if upgrade: args += ["--upgrade"] if user: args += ["--user"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) def _uninstall_helper(*, verbosity=0): """Helper to support a clean default uninstall process on Windows Note that calling this function may alter os.environ. """ # Nothing to do if pip was never installed, or has been removed try: import pip except ImportError: return # If the pip version doesn't match the bundled one, leave it alone if pip.__version__ != _PIP_VERSION: msg = ("ensurepip will only uninstall a matching version " "({!r} installed, {!r} bundled)") print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) return _disable_pip_configuration_settings() # Construct the arguments to be passed to the pip command args = ["uninstall", "-y", "--disable-pip-version-check"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) def _main(argv=None): import argparse parser = argparse.ArgumentParser(prog="python -m ensurepip") parser.add_argument( "--version", action="version", version="pip {}".format(version()), help="Show the version of pip that is bundled with this Python.", ) parser.add_argument( "-v", "--verbose", action="count", default=0, dest="verbosity", help=("Give more output. Option is additive, and can be used up to 3 " "times."), ) parser.add_argument( "-U", "--upgrade", action="store_true", default=False, help="Upgrade pip and dependencies, even if already installed.", ) parser.add_argument( "--user", action="store_true", default=False, help="Install using the user scheme.", ) parser.add_argument( "--root", default=None, help="Install everything relative to this alternate root directory.", ) parser.add_argument( "--altinstall", action="store_true", default=False, help=("Make an alternate install, installing only the X.Y versioned " "scripts (Default: pipX, pipX.Y, easy_install-X.Y)."), ) parser.add_argument( "--default-pip", action="store_true", default=False, help=("Make a default pip install, installing the unqualified pip " "and easy_install in addition to the versioned scripts."), ) args = parser.parse_args(argv) return _bootstrap( root=args.root, upgrade=args.upgrade, user=args.user, verbosity=args.verbosity, altinstall=args.altinstall, default_pip=args.default_pip, ) usr/lib64/python3.8/ensurepip/__init__.py000064400000016542152347470170014214 0ustar00import distutils.version import glob import os import os.path import sys import runpy import tempfile import subprocess __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') _WHEEL_DIR = "/usr/share/python38-wheels/" _wheels = {} def _get_most_recent_wheel_version(pkg): prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) _wheels[pkg] = {} for suffix in "-py2.py3-none-any.whl", "-py3-none-any.whl": pattern = "{}*{}".format(prefix, suffix) for path in glob.glob(pattern): version_str = path[len(prefix):-len(suffix)] _wheels[pkg][version_str] = os.path.basename(path) return str(max(_wheels[pkg], key=distutils.version.LooseVersion)) _SETUPTOOLS_VERSION = _get_most_recent_wheel_version("setuptools") _PIP_VERSION = _get_most_recent_wheel_version("pip") _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), ] def _run_pip(args, additional_paths=None): # Run the bootstraping in a subprocess to avoid leaking any state that happens # after pip has executed. Particulary, this avoids the case when pip holds onto # the files in *additional_paths*, preventing us to remove them at the end of the # invocation. code = f""" import runpy import sys sys.path = {additional_paths or []} + sys.path sys.argv[1:] = {args} runpy.run_module("pip", run_name="__main__", alter_sys=True) """ cmd = [sys.executable, '-c', code] if sys.flags.isolated: # run code in isolated mode if currently running isolated cmd.insert(1, '-I') return subprocess.run(cmd, check=True).returncode def version(): """ Returns a string specifying the bundled version of pip. """ return _PIP_VERSION def _disable_pip_configuration_settings(): # We deliberately ignore all pip environment variables # when invoking pip # See http://bugs.python.org/issue19734 for details keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] for k in keys_to_remove: del os.environ[k] # We also ignore the settings in the default pip configuration file # See http://bugs.python.org/issue20053 for details os.environ['PIP_CONFIG_FILE'] = os.devnull def bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Note that calling this function will alter both sys.path and os.environ. """ # Discard the return value _bootstrap(root=root, upgrade=upgrade, user=user, altinstall=altinstall, default_pip=default_pip, verbosity=verbosity) def _bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Returns pip command status code. Note that calling this function will alter both sys.path and os.environ. """ if altinstall and default_pip: raise ValueError("Cannot use altinstall and default_pip together") sys.audit("ensurepip.bootstrap", root) _disable_pip_configuration_settings() # By default, installing pip and setuptools installs all of the # following scripts (X.Y == running Python version): # # pip, pipX, pipX.Y, easy_install, easy_install-X.Y # # pip 1.5+ allows ensurepip to request that some of those be left out if altinstall: # omit pip, pipX and easy_install os.environ["ENSUREPIP_OPTIONS"] = "altinstall" elif not default_pip: # omit pip and easy_install os.environ["ENSUREPIP_OPTIONS"] = "install" with tempfile.TemporaryDirectory() as tmpdir: # Put our bundled wheels into a temporary directory and construct the # additional paths that need added to sys.path additional_paths = [] for project, version, py_tag in _PROJECTS: wheel_name = _wheels[project][version] with open(os.path.join(_WHEEL_DIR, wheel_name), "rb") as sfp: with open(os.path.join(tmpdir, wheel_name), "wb") as fp: fp.write(sfp.read()) additional_paths.append(os.path.join(tmpdir, wheel_name)) # Construct the arguments to be passed to the pip command args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir] if root: args += ["--root", root] if upgrade: args += ["--upgrade"] if user: args += ["--user"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) def _uninstall_helper(*, verbosity=0): """Helper to support a clean default uninstall process on Windows Note that calling this function may alter os.environ. """ # Nothing to do if pip was never installed, or has been removed try: import pip except ImportError: return # If the pip version doesn't match the bundled one, leave it alone if pip.__version__ != _PIP_VERSION: msg = ("ensurepip will only uninstall a matching version " "({!r} installed, {!r} bundled)") print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) return _disable_pip_configuration_settings() # Construct the arguments to be passed to the pip command args = ["uninstall", "-y", "--disable-pip-version-check"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) def _main(argv=None): import argparse parser = argparse.ArgumentParser(prog="python -m ensurepip") parser.add_argument( "--version", action="version", version="pip {}".format(version()), help="Show the version of pip that is bundled with this Python.", ) parser.add_argument( "-v", "--verbose", action="count", default=0, dest="verbosity", help=("Give more output. Option is additive, and can be used up to 3 " "times."), ) parser.add_argument( "-U", "--upgrade", action="store_true", default=False, help="Upgrade pip and dependencies, even if already installed.", ) parser.add_argument( "--user", action="store_true", default=False, help="Install using the user scheme.", ) parser.add_argument( "--root", default=None, help="Install everything relative to this alternate root directory.", ) parser.add_argument( "--altinstall", action="store_true", default=False, help=("Make an alternate install, installing only the X.Y versioned " "scripts (Default: pipX, pipX.Y, easy_install-X.Y)."), ) parser.add_argument( "--default-pip", action="store_true", default=False, help=("Make a default pip install, installing the unqualified pip " "and easy_install in addition to the versioned scripts."), ) args = parser.parse_args(argv) return _bootstrap( root=args.root, upgrade=args.upgrade, user=args.user, verbosity=args.verbosity, altinstall=args.altinstall, default_pip=args.default_pip, ) lib64/python3.8/tkinter/__init__.py000064400000512715152347506040013050 0ustar00"""Wrapper functions for Tcl/Tk. Tkinter provides classes which allow the display, positioning and control of widgets. Toplevel widgets are Tk and Toplevel. Other widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox LabelFrame and PanedWindow. Properties of the widgets are specified with keyword arguments. Keyword arguments have the same name as the corresponding resource under Tk. Widgets are positioned with one of the geometry managers Place, Pack or Grid. These managers can be called with methods place, pack, grid available in every Widget. Actions are bound to events by resources (e.g. keyword argument command) or with the method bind. Example (Hello, World): import tkinter from tkinter.constants import * tk = tkinter.Tk() frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2) frame.pack(fill=BOTH,expand=1) label = tkinter.Label(frame, text="Hello, World") label.pack(fill=X, expand=1) button = tkinter.Button(frame,text="Exit",command=tk.destroy) button.pack(side=BOTTOM) tk.mainloop() """ import enum import sys import _tkinter # If this fails your Python may not be configured for Tk TclError = _tkinter.TclError from tkinter.constants import * import re wantobjects = 1 TkVersion = float(_tkinter.TK_VERSION) TclVersion = float(_tkinter.TCL_VERSION) READABLE = _tkinter.READABLE WRITABLE = _tkinter.WRITABLE EXCEPTION = _tkinter.EXCEPTION _magic_re = re.compile(r'([\\{}])') _space_re = re.compile(r'([\s])', re.ASCII) def _join(value): """Internal function.""" return ' '.join(map(_stringify, value)) def _stringify(value): """Internal function.""" if isinstance(value, (list, tuple)): if len(value) == 1: value = _stringify(value[0]) if _magic_re.search(value): value = '{%s}' % value else: value = '{%s}' % _join(value) else: value = str(value) if not value: value = '{}' elif _magic_re.search(value): # add '\' before special characters and spaces value = _magic_re.sub(r'\\\1', value) value = value.replace('\n', r'\n') value = _space_re.sub(r'\\\1', value) if value[0] == '"': value = '\\' + value elif value[0] == '"' or _space_re.search(value): value = '{%s}' % value return value def _flatten(seq): """Internal function.""" res = () for item in seq: if isinstance(item, (tuple, list)): res = res + _flatten(item) elif item is not None: res = res + (item,) return res try: _flatten = _tkinter._flatten except AttributeError: pass def _cnfmerge(cnfs): """Internal function.""" if isinstance(cnfs, dict): return cnfs elif isinstance(cnfs, (type(None), str)): return cnfs else: cnf = {} for c in _flatten(cnfs): try: cnf.update(c) except (AttributeError, TypeError) as msg: print("_cnfmerge: fallback due to:", msg) for k, v in c.items(): cnf[k] = v return cnf try: _cnfmerge = _tkinter._cnfmerge except AttributeError: pass def _splitdict(tk, v, cut_minus=True, conv=None): """Return a properly formatted dict built from Tcl list pairs. If cut_minus is True, the supposed '-' prefix will be removed from keys. If conv is specified, it is used to convert values. Tcl list is expected to contain an even number of elements. """ t = tk.splitlist(v) if len(t) % 2: raise RuntimeError('Tcl list representing a dict is expected ' 'to contain an even number of elements') it = iter(t) dict = {} for key, value in zip(it, it): key = str(key) if cut_minus and key[0] == '-': key = key[1:] if conv: value = conv(value) dict[key] = value return dict class EventType(str, enum.Enum): KeyPress = '2' Key = KeyPress KeyRelease = '3' ButtonPress = '4' Button = ButtonPress ButtonRelease = '5' Motion = '6' Enter = '7' Leave = '8' FocusIn = '9' FocusOut = '10' Keymap = '11' # undocumented Expose = '12' GraphicsExpose = '13' # undocumented NoExpose = '14' # undocumented Visibility = '15' Create = '16' Destroy = '17' Unmap = '18' Map = '19' MapRequest = '20' Reparent = '21' Configure = '22' ConfigureRequest = '23' Gravity = '24' ResizeRequest = '25' Circulate = '26' CirculateRequest = '27' Property = '28' SelectionClear = '29' # undocumented SelectionRequest = '30' # undocumented Selection = '31' # undocumented Colormap = '32' ClientMessage = '33' # undocumented Mapping = '34' # undocumented VirtualEvent = '35' # undocumented Activate = '36' Deactivate = '37' MouseWheel = '38' __str__ = str.__str__ class Event: """Container for the properties of an event. Instances of this type are generated if one of the following events occurs: KeyPress, KeyRelease - for keyboard events ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, Colormap, Gravity, Reparent, Property, Destroy, Activate, Deactivate - for window events. If a callback function for one of these events is registered using bind, bind_all, bind_class, or tag_bind, the callback is called with an Event as first argument. It will have the following attributes (in braces are the event types for which the attribute is valid): serial - serial number of event num - mouse button pressed (ButtonPress, ButtonRelease) focus - whether the window has the focus (Enter, Leave) height - height of the exposed window (Configure, Expose) width - width of the exposed window (Configure, Expose) keycode - keycode of the pressed key (KeyPress, KeyRelease) state - state of the event as a number (ButtonPress, ButtonRelease, Enter, KeyPress, KeyRelease, Leave, Motion) state - state as a string (Visibility) time - when the event occurred x - x-position of the mouse y - y-position of the mouse x_root - x-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) y_root - y-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) char - pressed character (KeyPress, KeyRelease) send_event - see X/Windows documentation keysym - keysym of the event as a string (KeyPress, KeyRelease) keysym_num - keysym of the event as a number (KeyPress, KeyRelease) type - type of the event as a number widget - widget in which the event occurred delta - delta of wheel movement (MouseWheel) """ def __repr__(self): attrs = {k: v for k, v in self.__dict__.items() if v != '??'} if not self.char: del attrs['char'] elif self.char != '??': attrs['char'] = repr(self.char) if not getattr(self, 'send_event', True): del attrs['send_event'] if self.state == 0: del attrs['state'] elif isinstance(self.state, int): state = self.state mods = ('Shift', 'Lock', 'Control', 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Button1', 'Button2', 'Button3', 'Button4', 'Button5') s = [] for i, n in enumerate(mods): if state & (1 << i): s.append(n) state = state & ~((1<< len(mods)) - 1) if state or not s: s.append(hex(state)) attrs['state'] = '|'.join(s) if self.delta == 0: del attrs['delta'] # widget usually is known # serial and time are not very interesting # keysym_num duplicates keysym # x_root and y_root mostly duplicate x and y keys = ('send_event', 'state', 'keysym', 'keycode', 'char', 'num', 'delta', 'focus', 'x', 'y', 'width', 'height') return '<%s event%s>' % ( getattr(self.type, 'name', self.type), ''.join(' %s=%s' % (k, attrs[k]) for k in keys if k in attrs) ) _support_default_root = True _default_root = None def NoDefaultRoot(): """Inhibit setting of default root window. Call this function to inhibit that the first instance of Tk is used for windows without an explicit parent window. """ global _support_default_root, _default_root _support_default_root = False # Delete, so any use of _default_root will immediately raise an exception. # Rebind before deletion, so repeated calls will not fail. _default_root = None del _default_root def _get_default_root(what=None): if not _support_default_root: raise RuntimeError("No master specified and tkinter is " "configured to not support default root") if not _default_root: if what: raise RuntimeError(f"Too early to {what}: no default root window") root = Tk() assert _default_root is root return _default_root def _tkerror(err): """Internal function.""" pass def _exit(code=0): """Internal function. Calling it will raise the exception SystemExit.""" try: code = int(code) except ValueError: pass raise SystemExit(code) _varnum = 0 class Variable: """Class to define value holders for e.g. buttons. Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations that constrain the type of the value returned from get().""" _default = "" _tk = None _tclCommands = None def __init__(self, master=None, value=None, name=None): """Construct a variable MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ # check for type of NAME parameter to override weird error message # raised from Modules/_tkinter.c:SetVar like: # TypeError: setvar() takes exactly 3 arguments (2 given) if name is not None and not isinstance(name, str): raise TypeError("name must be a string") global _varnum if not master: master = _get_default_root('create variable') self._root = master._root() self._tk = master.tk if name: self._name = name else: self._name = 'PY_VAR' + repr(_varnum) _varnum += 1 if value is not None: self.initialize(value) elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)): self.initialize(self._default) def __del__(self): """Unset the variable in Tcl.""" if self._tk is None: return if self._tk.getboolean(self._tk.call("info", "exists", self._name)): self._tk.globalunsetvar(self._name) if self._tclCommands is not None: for name in self._tclCommands: #print '- Tkinter: deleted command', name self._tk.deletecommand(name) self._tclCommands = None def __str__(self): """Return the name of the variable in Tcl.""" return self._name def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, value) initialize = set def get(self): """Return value of variable.""" return self._tk.globalgetvar(self._name) def _register(self, callback): f = CallWrapper(callback, None, self._root).__call__ cbname = repr(id(f)) try: callback = callback.__func__ except AttributeError: pass try: cbname = cbname + callback.__name__ except AttributeError: pass self._tk.createcommand(cbname, f) if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(cbname) return cbname def trace_add(self, mode, callback): """Define a trace callback for the variable. Mode is one of "read", "write", "unset", or a list or tuple of such strings. Callback must be a function which is called when the variable is read, written or unset. Return the name of the callback. """ cbname = self._register(callback) self._tk.call('trace', 'add', 'variable', self._name, mode, (cbname,)) return cbname def trace_remove(self, mode, cbname): """Delete the trace callback for a variable. Mode is one of "read", "write", "unset" or a list or tuple of such strings. Must be same as were specified in trace_add(). cbname is the name of the callback returned from trace_add(). """ self._tk.call('trace', 'remove', 'variable', self._name, mode, cbname) for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_info(self): """Return all trace callback information.""" splitlist = self._tk.splitlist return [(splitlist(k), v) for k, v in map(splitlist, splitlist(self._tk.call('trace', 'info', 'variable', self._name)))] def trace_variable(self, mode, callback): """Define a trace callback for the variable. MODE is one of "r", "w", "u" for read, write, undefine. CALLBACK must be a function which is called when the variable is read, written or undefined. Return the name of the callback. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_add() instead. """ # TODO: Add deprecation warning cbname = self._register(callback) self._tk.call("trace", "variable", self._name, mode, cbname) return cbname trace = trace_variable def trace_vdelete(self, mode, cbname): """Delete the trace callback for a variable. MODE is one of "r", "w", "u" for read, write, undefine. CBNAME is the name of the callback returned from trace_variable or trace. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_remove() instead. """ # TODO: Add deprecation warning self._tk.call("trace", "vdelete", self._name, mode, cbname) cbname = self._tk.splitlist(cbname)[0] for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_vinfo(self): """Return all trace callback information. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_info() instead. """ # TODO: Add deprecation warning return [self._tk.splitlist(x) for x in self._tk.splitlist( self._tk.call("trace", "vinfo", self._name))] def __eq__(self, other): if not isinstance(other, Variable): return NotImplemented return (self._name == other._name and self.__class__.__name__ == other.__class__.__name__ and self._tk == other._tk) class StringVar(Variable): """Value holder for strings variables.""" _default = "" def __init__(self, master=None, value=None, name=None): """Construct a string variable. MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return value of variable as string.""" value = self._tk.globalgetvar(self._name) if isinstance(value, str): return value return str(value) class IntVar(Variable): """Value holder for integer variables.""" _default = 0 def __init__(self, master=None, value=None, name=None): """Construct an integer variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as an integer.""" value = self._tk.globalgetvar(self._name) try: return self._tk.getint(value) except (TypeError, TclError): return int(self._tk.getdouble(value)) class DoubleVar(Variable): """Value holder for float variables.""" _default = 0.0 def __init__(self, master=None, value=None, name=None): """Construct a float variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0.0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as a float.""" return self._tk.getdouble(self._tk.globalgetvar(self._name)) class BooleanVar(Variable): """Value holder for boolean variables.""" _default = False def __init__(self, master=None, value=None, name=None): """Construct a boolean variable. MASTER can be given as master widget. VALUE is an optional value (defaults to False) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, self._tk.getboolean(value)) initialize = set def get(self): """Return the value of the variable as a bool.""" try: return self._tk.getboolean(self._tk.globalgetvar(self._name)) except TclError: raise ValueError("invalid literal for getboolean()") def mainloop(n=0): """Run the main loop of Tcl.""" _get_default_root('run the main loop').tk.mainloop(n) getint = int getdouble = float def getboolean(s): """Convert Tcl object to True or False.""" try: return _get_default_root('use getboolean()').tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") # Methods defined on both toplevel and interior widgets class Misc: """Internal class. Base class which defines methods common for interior widgets.""" # used for generating child widget names _last_child_ids = None # XXX font command? _tclCommands = None def destroy(self): """Internal function. Delete all Tcl commands created for this widget in the Tcl interpreter.""" if self._tclCommands is not None: for name in self._tclCommands: #print '- Tkinter: deleted command', name self.tk.deletecommand(name) self._tclCommands = None def deletecommand(self, name): """Internal function. Delete the Tcl command provided in NAME.""" #print '- Tkinter: deleted command', name self.tk.deletecommand(name) try: self._tclCommands.remove(name) except ValueError: pass def tk_strictMotif(self, boolean=None): """Set Tcl internal variable, whether the look and feel should adhere to Motif. A parameter of 1 means adhere to Motif (e.g. no color change if mouse passes over slider). Returns the set value.""" return self.tk.getboolean(self.tk.call( 'set', 'tk_strictMotif', boolean)) def tk_bisque(self): """Change the color scheme to light brown as used in Tk 3.6 and before.""" self.tk.call('tk_bisque') def tk_setPalette(self, *args, **kw): """Set a new color scheme for all widget elements. A single color as argument will cause that all colors of Tk widget elements are derived from this. Alternatively several keyword parameters and its associated colors can be given. The following keywords are valid: activeBackground, foreground, selectColor, activeForeground, highlightBackground, selectBackground, background, highlightColor, selectForeground, disabledForeground, insertBackground, troughColor.""" self.tk.call(('tk_setPalette',) + _flatten(args) + _flatten(list(kw.items()))) def wait_variable(self, name='PY_VAR'): """Wait until the variable is modified. A parameter of type IntVar, StringVar, DoubleVar or BooleanVar must be given.""" self.tk.call('tkwait', 'variable', name) waitvar = wait_variable # XXX b/w compat def wait_window(self, window=None): """Wait until a WIDGET is destroyed. If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'window', window._w) def wait_visibility(self, window=None): """Wait until the visibility of a WIDGET changes (e.g. it appears). If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'visibility', window._w) def setvar(self, name='PY_VAR', value='1'): """Set Tcl variable NAME to VALUE.""" self.tk.setvar(name, value) def getvar(self, name='PY_VAR'): """Return value of Tcl variable NAME.""" return self.tk.getvar(name) def getint(self, s): try: return self.tk.getint(s) except TclError as exc: raise ValueError(str(exc)) def getdouble(self, s): try: return self.tk.getdouble(s) except TclError as exc: raise ValueError(str(exc)) def getboolean(self, s): """Return a boolean value for Tcl boolean values true and false given as parameter.""" try: return self.tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") def focus_set(self): """Direct input focus to this widget. If the application currently does not have the focus this widget will get the focus if the application gets the focus through the window manager.""" self.tk.call('focus', self._w) focus = focus_set # XXX b/w compat? def focus_force(self): """Direct input focus to this widget even if the application does not have the focus. Use with caution!""" self.tk.call('focus', '-force', self._w) def focus_get(self): """Return the widget which has currently the focus in the application. Use focus_displayof to allow working with several displays. Return None if application does not have the focus.""" name = self.tk.call('focus') if name == 'none' or not name: return None return self._nametowidget(name) def focus_displayof(self): """Return the widget which has currently the focus on the display where this widget is located. Return None if the application does not have the focus.""" name = self.tk.call('focus', '-displayof', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def focus_lastfor(self): """Return the widget which would have the focus if top level for this widget gets the focus from the window manager.""" name = self.tk.call('focus', '-lastfor', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def tk_focusFollowsMouse(self): """The widget under mouse will get automatically focus. Can not be disabled easily.""" self.tk.call('tk_focusFollowsMouse') def tk_focusNext(self): """Return the next widget in the focus order which follows widget which has currently the focus. The focus order first goes to the next child, then to the children of the child recursively and then to the next sibling which is higher in the stacking order. A widget is omitted if it has the takefocus resource set to 0.""" name = self.tk.call('tk_focusNext', self._w) if not name: return None return self._nametowidget(name) def tk_focusPrev(self): """Return previous widget in the focus order. See tk_focusNext for details.""" name = self.tk.call('tk_focusPrev', self._w) if not name: return None return self._nametowidget(name) def after(self, ms, func=None, *args): """Call function once after given time. MS specifies the time in milliseconds. FUNC gives the function which shall be called. Additional parameters are given as parameters to the function call. Return identifier to cancel scheduling with after_cancel.""" if not func: # I'd rather use time.sleep(ms*0.001) self.tk.call('after', ms) return None else: def callit(): try: func(*args) finally: try: self.deletecommand(name) except TclError: pass callit.__name__ = func.__name__ name = self._register(callit) return self.tk.call('after', ms, name) def after_idle(self, func, *args): """Call FUNC once if the Tcl main loop has no event to process. Return an identifier to cancel the scheduling with after_cancel.""" return self.after('idle', func, *args) def after_cancel(self, id): """Cancel scheduling of function identified with ID. Identifier returned by after or after_idle must be given as first parameter. """ if not id: raise ValueError('id must be a valid identifier returned from ' 'after or after_idle') try: data = self.tk.call('after', 'info', id) script = self.tk.splitlist(data)[0] self.deletecommand(script) except TclError: pass self.tk.call('after', 'cancel', id) def bell(self, displayof=0): """Ring a display's bell.""" self.tk.call(('bell',) + self._displayof(displayof)) # Clipboard handling: def clipboard_get(self, **kw): """Retrieve data from the clipboard on window's display. The window keyword defaults to the root window of the Tkinter application. The type keyword specifies the form in which the data is to be returned and should be an atom name such as STRING or FILE_NAME. Type defaults to STRING, except on X11, where the default is to try UTF8_STRING and fall back to STRING. This command is equivalent to: selection_get(CLIPBOARD) """ if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('clipboard', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('clipboard', 'get') + self._options(kw)) def clipboard_clear(self, **kw): """Clear the data in the Tk clipboard. A widget specified for the optional displayof keyword argument specifies the target display.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'clear') + self._options(kw)) def clipboard_append(self, string, **kw): """Append STRING to the Tk clipboard. A widget specified at the optional displayof keyword argument specifies the target display. The clipboard can be retrieved with selection_get.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'append') + self._options(kw) + ('--', string)) # XXX grab current w/o window argument def grab_current(self): """Return widget which has currently the grab in this application or None.""" name = self.tk.call('grab', 'current', self._w) if not name: return None return self._nametowidget(name) def grab_release(self): """Release grab for this widget if currently set.""" self.tk.call('grab', 'release', self._w) def grab_set(self): """Set grab for this widget. A grab directs all events to this and descendant widgets in the application.""" self.tk.call('grab', 'set', self._w) def grab_set_global(self): """Set global grab for this widget. A global grab directs all events to this and descendant widgets on the display. Use with caution - other applications do not get events anymore.""" self.tk.call('grab', 'set', '-global', self._w) def grab_status(self): """Return None, "local" or "global" if this widget has no, a local or a global grab.""" status = self.tk.call('grab', 'status', self._w) if status == 'none': status = None return status def option_add(self, pattern, value, priority = None): """Set a VALUE (second parameter) for an option PATTERN (first parameter). An optional third parameter gives the numeric priority (defaults to 80).""" self.tk.call('option', 'add', pattern, value, priority) def option_clear(self): """Clear the option database. It will be reloaded if option_add is called.""" self.tk.call('option', 'clear') def option_get(self, name, className): """Return the value for an option NAME for this widget with CLASSNAME. Values with higher priority override lower values.""" return self.tk.call('option', 'get', self._w, name, className) def option_readfile(self, fileName, priority = None): """Read file FILENAME into the option database. An optional second parameter gives the numeric priority.""" self.tk.call('option', 'readfile', fileName, priority) def selection_clear(self, **kw): """Clear the current X selection.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('selection', 'clear') + self._options(kw)) def selection_get(self, **kw): """Return the contents of the current X selection. A keyword parameter selection specifies the name of the selection and defaults to PRIMARY. A keyword parameter displayof specifies a widget on the display to use. A keyword parameter type specifies the form of data to be fetched, defaulting to STRING except on X11, where UTF8_STRING is tried before STRING.""" if 'displayof' not in kw: kw['displayof'] = self._w if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('selection', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('selection', 'get') + self._options(kw)) def selection_handle(self, command, **kw): """Specify a function COMMAND to call if the X selection owned by this widget is queried by another application. This function must return the contents of the selection. The function will be called with the arguments OFFSET and LENGTH which allows the chunking of very long selections. The following keyword parameters can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" name = self._register(command) self.tk.call(('selection', 'handle') + self._options(kw) + (self._w, name)) def selection_own(self, **kw): """Become owner of X selection. A keyword parameter selection specifies the name of the selection (default PRIMARY).""" self.tk.call(('selection', 'own') + self._options(kw) + (self._w,)) def selection_own_get(self, **kw): """Return owner of X selection. The following keyword parameter can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" if 'displayof' not in kw: kw['displayof'] = self._w name = self.tk.call(('selection', 'own') + self._options(kw)) if not name: return None return self._nametowidget(name) def send(self, interp, cmd, *args): """Send Tcl command CMD to different interpreter INTERP to be executed.""" return self.tk.call(('send', interp, cmd) + args) def lower(self, belowThis=None): """Lower this widget in the stacking order.""" self.tk.call('lower', self._w, belowThis) def tkraise(self, aboveThis=None): """Raise this widget in the stacking order.""" self.tk.call('raise', self._w, aboveThis) lift = tkraise def winfo_atom(self, name, displayof=0): """Return integer which represents atom NAME.""" args = ('winfo', 'atom') + self._displayof(displayof) + (name,) return self.tk.getint(self.tk.call(args)) def winfo_atomname(self, id, displayof=0): """Return name of atom with identifier ID.""" args = ('winfo', 'atomname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_cells(self): """Return number of cells in the colormap for this widget.""" return self.tk.getint( self.tk.call('winfo', 'cells', self._w)) def winfo_children(self): """Return a list of all widgets which are children of this widget.""" result = [] for child in self.tk.splitlist( self.tk.call('winfo', 'children', self._w)): try: # Tcl sometimes returns extra windows, e.g. for # menus; those need to be skipped result.append(self._nametowidget(child)) except KeyError: pass return result def winfo_class(self): """Return window class name of this widget.""" return self.tk.call('winfo', 'class', self._w) def winfo_colormapfull(self): """Return True if at the last color request the colormap was full.""" return self.tk.getboolean( self.tk.call('winfo', 'colormapfull', self._w)) def winfo_containing(self, rootX, rootY, displayof=0): """Return the widget which is at the root coordinates ROOTX, ROOTY.""" args = ('winfo', 'containing') \ + self._displayof(displayof) + (rootX, rootY) name = self.tk.call(args) if not name: return None return self._nametowidget(name) def winfo_depth(self): """Return the number of bits per pixel.""" return self.tk.getint(self.tk.call('winfo', 'depth', self._w)) def winfo_exists(self): """Return true if this widget exists.""" return self.tk.getint( self.tk.call('winfo', 'exists', self._w)) def winfo_fpixels(self, number): """Return the number of pixels for the given distance NUMBER (e.g. "3c") as float.""" return self.tk.getdouble(self.tk.call( 'winfo', 'fpixels', self._w, number)) def winfo_geometry(self): """Return geometry string for this widget in the form "widthxheight+X+Y".""" return self.tk.call('winfo', 'geometry', self._w) def winfo_height(self): """Return height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'height', self._w)) def winfo_id(self): """Return identifier ID for this widget.""" return int(self.tk.call('winfo', 'id', self._w), 0) def winfo_interps(self, displayof=0): """Return the name of all Tcl interpreters for this display.""" args = ('winfo', 'interps') + self._displayof(displayof) return self.tk.splitlist(self.tk.call(args)) def winfo_ismapped(self): """Return true if this widget is mapped.""" return self.tk.getint( self.tk.call('winfo', 'ismapped', self._w)) def winfo_manager(self): """Return the window manager name for this widget.""" return self.tk.call('winfo', 'manager', self._w) def winfo_name(self): """Return the name of this widget.""" return self.tk.call('winfo', 'name', self._w) def winfo_parent(self): """Return the name of the parent of this widget.""" return self.tk.call('winfo', 'parent', self._w) def winfo_pathname(self, id, displayof=0): """Return the pathname of the widget given by ID.""" args = ('winfo', 'pathname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_pixels(self, number): """Rounded integer value of winfo_fpixels.""" return self.tk.getint( self.tk.call('winfo', 'pixels', self._w, number)) def winfo_pointerx(self): """Return the x coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointerx', self._w)) def winfo_pointerxy(self): """Return a tuple of x and y coordinates of the pointer on the root window.""" return self._getints( self.tk.call('winfo', 'pointerxy', self._w)) def winfo_pointery(self): """Return the y coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointery', self._w)) def winfo_reqheight(self): """Return requested height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqheight', self._w)) def winfo_reqwidth(self): """Return requested width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqwidth', self._w)) def winfo_rgb(self, color): """Return a tuple of integer RGB values in range(65536) for color in this widget.""" return self._getints( self.tk.call('winfo', 'rgb', self._w, color)) def winfo_rootx(self): """Return x coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rootx', self._w)) def winfo_rooty(self): """Return y coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rooty', self._w)) def winfo_screen(self): """Return the screen name of this widget.""" return self.tk.call('winfo', 'screen', self._w) def winfo_screencells(self): """Return the number of the cells in the colormap of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screencells', self._w)) def winfo_screendepth(self): """Return the number of bits per pixel of the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screendepth', self._w)) def winfo_screenheight(self): """Return the number of pixels of the height of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenheight', self._w)) def winfo_screenmmheight(self): """Return the number of pixels of the height of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmheight', self._w)) def winfo_screenmmwidth(self): """Return the number of pixels of the width of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmwidth', self._w)) def winfo_screenvisual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the default colormodel of this screen.""" return self.tk.call('winfo', 'screenvisual', self._w) def winfo_screenwidth(self): """Return the number of pixels of the width of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenwidth', self._w)) def winfo_server(self): """Return information of the X-Server of the screen of this widget in the form "XmajorRminor vendor vendorVersion".""" return self.tk.call('winfo', 'server', self._w) def winfo_toplevel(self): """Return the toplevel widget of this widget.""" return self._nametowidget(self.tk.call( 'winfo', 'toplevel', self._w)) def winfo_viewable(self): """Return true if the widget and all its higher ancestors are mapped.""" return self.tk.getint( self.tk.call('winfo', 'viewable', self._w)) def winfo_visual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the colormodel of this widget.""" return self.tk.call('winfo', 'visual', self._w) def winfo_visualid(self): """Return the X identifier for the visual for this widget.""" return self.tk.call('winfo', 'visualid', self._w) def winfo_visualsavailable(self, includeids=False): """Return a list of all visuals available for the screen of this widget. Each item in the list consists of a visual name (see winfo_visual), a depth and if includeids is true is given also the X identifier.""" data = self.tk.call('winfo', 'visualsavailable', self._w, 'includeids' if includeids else None) data = [self.tk.splitlist(x) for x in self.tk.splitlist(data)] return [self.__winfo_parseitem(x) for x in data] def __winfo_parseitem(self, t): """Internal function.""" return t[:1] + tuple(map(self.__winfo_getint, t[1:])) def __winfo_getint(self, x): """Internal function.""" return int(x, 0) def winfo_vrootheight(self): """Return the height of the virtual root window associated with this widget in pixels. If there is no virtual root window return the height of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootheight', self._w)) def winfo_vrootwidth(self): """Return the width of the virtual root window associated with this widget in pixel. If there is no virtual root window return the width of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootwidth', self._w)) def winfo_vrootx(self): """Return the x offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrootx', self._w)) def winfo_vrooty(self): """Return the y offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrooty', self._w)) def winfo_width(self): """Return the width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'width', self._w)) def winfo_x(self): """Return the x coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'x', self._w)) def winfo_y(self): """Return the y coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'y', self._w)) def update(self): """Enter event loop until all pending events have been processed by Tcl.""" self.tk.call('update') def update_idletasks(self): """Enter event loop until all idle callbacks have been called. This will update the display of windows but not process events caused by the user.""" self.tk.call('update', 'idletasks') def bindtags(self, tagList=None): """Set or get the list of bindtags for this widget. With no argument return the list of all bindtags associated with this widget. With a list of strings as argument the bindtags are set to this list. The bindtags determine in which order events are processed (see bind).""" if tagList is None: return self.tk.splitlist( self.tk.call('bindtags', self._w)) else: self.tk.call('bindtags', self._w, tagList) def _bind(self, what, sequence, func, add, needcleanup=1): """Internal function.""" if isinstance(func, str): self.tk.call(what + (sequence, func)) elif func: funcid = self._register(func, self._substitute, needcleanup) cmd = ('%sif {"[%s %s]" == "break"} break\n' % (add and '+' or '', funcid, self._subst_format_str)) self.tk.call(what + (sequence, cmd)) return funcid elif sequence: return self.tk.call(what + (sequence,)) else: return self.tk.splitlist(self.tk.call(what)) def bind(self, sequence=None, func=None, add=None): """Bind to this widget at event SEQUENCE a call to function FUNC. SEQUENCE is a string of concatenated event patterns. An event pattern is of the form where MODIFIER is one of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, B3, Alt, Button4, B4, Double, Button5, B5 Triple, Mod1, M1. TYPE is one of Activate, Enter, Map, ButtonPress, Button, Expose, Motion, ButtonRelease FocusIn, MouseWheel, Circulate, FocusOut, Property, Colormap, Gravity Reparent, Configure, KeyPress, Key, Unmap, Deactivate, KeyRelease Visibility, Destroy, Leave and DETAIL is the button number for ButtonPress, ButtonRelease and DETAIL is the Keysym for KeyPress and KeyRelease. Examples are for pressing Control and mouse button 1 or for pressing A and the Alt key (KeyPress can be omitted). An event pattern can also be a virtual event of the form <> where AString can be arbitrary. This event can be generated by event_generate. If events are concatenated they must appear shortly after each other. FUNC will be called if the event sequence occurs with an instance of Event as argument. If the return value of FUNC is "break" no further bound function is invoked. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. Bind will return an identifier to allow deletion of the bound function with unbind without memory leak. If FUNC or SEQUENCE is omitted the bound function or list of bound events are returned.""" return self._bind(('bind', self._w), sequence, func, add) def unbind(self, sequence, funcid=None): """Unbind for this widget for event SEQUENCE the function identified with FUNCID.""" self.tk.call('bind', self._w, sequence, '') if funcid: self.deletecommand(funcid) def bind_all(self, sequence=None, func=None, add=None): """Bind to all widgets at an event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind(('bind', 'all'), sequence, func, add, 0) def unbind_all(self, sequence): """Unbind for all widgets for event SEQUENCE all functions.""" self.tk.call('bind', 'all' , sequence, '') def bind_class(self, className, sequence=None, func=None, add=None): """Bind to widgets with bindtag CLASSNAME at event SEQUENCE a call of function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind(('bind', className), sequence, func, add, 0) def unbind_class(self, className, sequence): """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self.tk.call('bind', className , sequence, '') def mainloop(self, n=0): """Call the mainloop of Tk.""" self.tk.mainloop(n) def quit(self): """Quit the Tcl interpreter. All widgets will be destroyed.""" self.tk.quit() def _getints(self, string): """Internal function.""" if string: return tuple(map(self.tk.getint, self.tk.splitlist(string))) def _getdoubles(self, string): """Internal function.""" if string: return tuple(map(self.tk.getdouble, self.tk.splitlist(string))) def _getboolean(self, string): """Internal function.""" if string: return self.tk.getboolean(string) def _displayof(self, displayof): """Internal function.""" if displayof: return ('-displayof', displayof) if displayof is None: return ('-displayof', self._w) return () @property def _windowingsystem(self): """Internal function.""" try: return self._root()._windowingsystem_cached except AttributeError: ws = self._root()._windowingsystem_cached = \ self.tk.call('tk', 'windowingsystem') return ws def _options(self, cnf, kw = None): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) else: cnf = _cnfmerge(cnf) res = () for k, v in cnf.items(): if v is not None: if k[-1] == '_': k = k[:-1] if callable(v): v = self._register(v) elif isinstance(v, (tuple, list)): nv = [] for item in v: if isinstance(item, int): nv.append(str(item)) elif isinstance(item, str): nv.append(_stringify(item)) else: break else: v = ' '.join(nv) res = res + ('-'+k, v) return res def nametowidget(self, name): """Return the Tkinter instance of a widget identified by its Tcl name NAME.""" name = str(name).split('.') w = self if not name[0]: w = w._root() name = name[1:] for n in name: if not n: break w = w.children[n] return w _nametowidget = nametowidget def _register(self, func, subst=None, needcleanup=1): """Return a newly created Tcl function. If this function is called, the Python function FUNC will be executed. An optional function SUBST can be given which will be executed before FUNC.""" f = CallWrapper(func, subst, self).__call__ name = repr(id(f)) try: func = func.__func__ except AttributeError: pass try: name = name + func.__name__ except AttributeError: pass self.tk.createcommand(name, f) if needcleanup: if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(name) return name register = _register def _root(self): """Internal function.""" w = self while w.master: w = w.master return w _subst_format = ('%#', '%b', '%f', '%h', '%k', '%s', '%t', '%w', '%x', '%y', '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') _subst_format_str = " ".join(_subst_format) def _substitute(self, *args): """Internal function.""" if len(args) != len(self._subst_format): return args getboolean = self.tk.getboolean getint = self.tk.getint def getint_event(s): """Tk changed behavior in 8.4.2, returning "??" rather more often.""" try: return getint(s) except (ValueError, TclError): return s nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args # Missing: (a, c, d, m, o, v, B, R) e = Event() # serial field: valid for all events # number of button: ButtonPress and ButtonRelease events only # height field: Configure, ConfigureRequest, Create, # ResizeRequest, and Expose events only # keycode field: KeyPress and KeyRelease events only # time field: "valid for events that contain a time field" # width field: Configure, ConfigureRequest, Create, ResizeRequest, # and Expose events only # x field: "valid for events that contain an x field" # y field: "valid for events that contain a y field" # keysym as decimal: KeyPress and KeyRelease events only # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, # KeyRelease, and Motion events e.serial = getint(nsign) e.num = getint_event(b) try: e.focus = getboolean(f) except TclError: pass e.height = getint_event(h) e.keycode = getint_event(k) e.state = getint_event(s) e.time = getint_event(t) e.width = getint_event(w) e.x = getint_event(x) e.y = getint_event(y) e.char = A try: e.send_event = getboolean(E) except TclError: pass e.keysym = K e.keysym_num = getint_event(N) try: e.type = EventType(T) except ValueError: e.type = T try: e.widget = self._nametowidget(W) except KeyError: e.widget = W e.x_root = getint_event(X) e.y_root = getint_event(Y) try: e.delta = getint(D) except (ValueError, TclError): e.delta = 0 return (e,) def _report_exception(self): """Internal function.""" exc, val, tb = sys.exc_info() root = self._root() root.report_callback_exception(exc, val, tb) def _getconfigure(self, *args): """Call Tcl configure command and return the result as a dict.""" cnf = {} for x in self.tk.splitlist(self.tk.call(*args)): x = self.tk.splitlist(x) cnf[x[0][1:]] = (x[0][1:],) + x[1:] return cnf def _getconfigure1(self, *args): x = self.tk.splitlist(self.tk.call(*args)) return (x[0][1:],) + x[1:] def _configure(self, cmd, cnf, kw): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) elif cnf: cnf = _cnfmerge(cnf) if cnf is None: return self._getconfigure(_flatten((self._w, cmd))) if isinstance(cnf, str): return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) # These used to be defined in Widget: def configure(self, cnf=None, **kw): """Configure resources of a widget. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method keys. """ return self._configure('configure', cnf, kw) config = configure def cget(self, key): """Return the resource value for a KEY given as string.""" return self.tk.call(self._w, 'cget', '-' + key) __getitem__ = cget def __setitem__(self, key, value): self.configure({key: value}) def keys(self): """Return a list of all resource names of this widget.""" splitlist = self.tk.splitlist return [splitlist(x)[0][1:] for x in splitlist(self.tk.call(self._w, 'configure'))] def __str__(self): """Return the window path name of this widget.""" return self._w def __repr__(self): return '<%s.%s object %s>' % ( self.__class__.__module__, self.__class__.__qualname__, self._w) # Pack methods that apply to the master _noarg_ = ['_noarg_'] def pack_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'pack', 'propagate', self._w)) else: self.tk.call('pack', 'propagate', self._w, flag) propagate = pack_propagate def pack_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call('pack', 'slaves', self._w))] slaves = pack_slaves # Place method that applies to the master def place_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call( 'place', 'slaves', self._w))] # Grid methods that apply to the master def grid_anchor(self, anchor=None): # new in Tk 8.5 """The anchor value controls how to place the grid within the master when no row/column has any weight. The default anchor is nw.""" self.tk.call('grid', 'anchor', self._w, anchor) anchor = grid_anchor def grid_bbox(self, column=None, row=None, col2=None, row2=None): """Return a tuple of integer coordinates for the bounding box of this widget controlled by the geometry manager grid. If COLUMN, ROW is given the bounding box applies from the cell with row and column 0 to the specified cell. If COL2 and ROW2 are given the bounding box starts at that cell. The returned integers specify the offset of the upper left corner in the master widget and the width and height. """ args = ('grid', 'bbox', self._w) if column is not None and row is not None: args = args + (column, row) if col2 is not None and row2 is not None: args = args + (col2, row2) return self._getints(self.tk.call(*args)) or None bbox = grid_bbox def _gridconvvalue(self, value): if isinstance(value, (str, _tkinter.Tcl_Obj)): try: svalue = str(value) if not svalue: return None elif '.' in svalue: return self.tk.getdouble(svalue) else: return self.tk.getint(svalue) except (ValueError, TclError): pass return value def _grid_configure(self, command, index, cnf, kw): """Internal function.""" if isinstance(cnf, str) and not kw: if cnf[-1:] == '_': cnf = cnf[:-1] if cnf[:1] != '-': cnf = '-'+cnf options = (cnf,) else: options = self._options(cnf, kw) if not options: return _splitdict( self.tk, self.tk.call('grid', command, self._w, index), conv=self._gridconvvalue) res = self.tk.call( ('grid', command, self._w, index) + options) if len(options) == 1: return self._gridconvvalue(res) def grid_columnconfigure(self, index, cnf={}, **kw): """Configure column INDEX of a grid. Valid resources are minsize (minimum size of the column), weight (how much does additional space propagate to this column) and pad (how much space to let additionally).""" return self._grid_configure('columnconfigure', index, cnf, kw) columnconfigure = grid_columnconfigure def grid_location(self, x, y): """Return a tuple of column and row which identify the cell at which the pixel at position X and Y inside the master widget is located.""" return self._getints( self.tk.call( 'grid', 'location', self._w, x, y)) or None def grid_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given, the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'grid', 'propagate', self._w)) else: self.tk.call('grid', 'propagate', self._w, flag) def grid_rowconfigure(self, index, cnf={}, **kw): """Configure row INDEX of a grid. Valid resources are minsize (minimum size of the row), weight (how much does additional space propagate to this row) and pad (how much space to let additionally).""" return self._grid_configure('rowconfigure', index, cnf, kw) rowconfigure = grid_rowconfigure def grid_size(self): """Return a tuple of the number of column and rows in the grid.""" return self._getints( self.tk.call('grid', 'size', self._w)) or None size = grid_size def grid_slaves(self, row=None, column=None): """Return a list of all slaves of this widget in its packing order.""" args = () if row is not None: args = args + ('-row', row) if column is not None: args = args + ('-column', column) return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call( ('grid', 'slaves', self._w) + args))] # Support for the "event" command, new in Tk 4.2. # By Case Roole. def event_add(self, virtual, *sequences): """Bind a virtual event VIRTUAL (of the form <>) to an event SEQUENCE such that the virtual event is triggered whenever SEQUENCE occurs.""" args = ('event', 'add', virtual) + sequences self.tk.call(args) def event_delete(self, virtual, *sequences): """Unbind a virtual event VIRTUAL from SEQUENCE.""" args = ('event', 'delete', virtual) + sequences self.tk.call(args) def event_generate(self, sequence, **kw): """Generate an event SEQUENCE. Additional keyword arguments specify parameter of the event (e.g. x, y, rootx, rooty).""" args = ('event', 'generate', self._w, sequence) for k, v in kw.items(): args = args + ('-%s' % k, str(v)) self.tk.call(args) def event_info(self, virtual=None): """Return a list of all virtual events or the information about the SEQUENCE bound to the virtual event VIRTUAL.""" return self.tk.splitlist( self.tk.call('event', 'info', virtual)) # Image related commands def image_names(self): """Return a list of all existing image names.""" return self.tk.splitlist(self.tk.call('image', 'names')) def image_types(self): """Return a list of all available image types (e.g. photo bitmap).""" return self.tk.splitlist(self.tk.call('image', 'types')) class CallWrapper: """Internal class. Stores function to call when some user defined Tcl function is called e.g. after an event occurred.""" def __init__(self, func, subst, widget): """Store FUNC, SUBST and WIDGET as members.""" self.func = func self.subst = subst self.widget = widget def __call__(self, *args): """Apply first function SUBST to arguments, than FUNC.""" try: if self.subst: args = self.subst(*args) return self.func(*args) except SystemExit: raise except: self.widget._report_exception() class XView: """Mix-in class for querying and changing the horizontal position of a widget's window.""" def xview(self, *args): """Query and change the horizontal position of the view.""" res = self.tk.call(self._w, 'xview', *args) if not args: return self._getdoubles(res) def xview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total width of the canvas is off-screen to the left.""" self.tk.call(self._w, 'xview', 'moveto', fraction) def xview_scroll(self, number, what): """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'xview', 'scroll', number, what) class YView: """Mix-in class for querying and changing the vertical position of a widget's window.""" def yview(self, *args): """Query and change the vertical position of the view.""" res = self.tk.call(self._w, 'yview', *args) if not args: return self._getdoubles(res) def yview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total height of the canvas is off-screen to the top.""" self.tk.call(self._w, 'yview', 'moveto', fraction) def yview_scroll(self, number, what): """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'yview', 'scroll', number, what) class Wm: """Provides functions for the communication with the window manager.""" def wm_aspect(self, minNumer=None, minDenom=None, maxNumer=None, maxDenom=None): """Instruct the window manager to set the aspect ratio (width/height) of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple of the actual values if no argument is given.""" return self._getints( self.tk.call('wm', 'aspect', self._w, minNumer, minDenom, maxNumer, maxDenom)) aspect = wm_aspect def wm_attributes(self, *args): """This subcommand returns or sets platform specific attributes The first form returns a list of the platform specific flags and their values. The second form returns the value for the specific option. The third form sets one or more of the values. The values are as follows: On Windows, -disabled gets or sets whether the window is in a disabled state. -toolwindow gets or sets the style of the window to toolwindow (as defined in the MSDN). -topmost gets or sets whether this is a topmost window (displays above all other windows). On Macintosh, XXXXX On Unix, there are currently no special attribute values. """ args = ('wm', 'attributes', self._w) + args return self.tk.call(args) attributes = wm_attributes def wm_client(self, name=None): """Store NAME in WM_CLIENT_MACHINE property of this widget. Return current value.""" return self.tk.call('wm', 'client', self._w, name) client = wm_client def wm_colormapwindows(self, *wlist): """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property of this widget. This list contains windows whose colormaps differ from their parents. Return current list of widgets if WLIST is empty.""" if len(wlist) > 1: wlist = (wlist,) # Tk needs a list of windows here args = ('wm', 'colormapwindows', self._w) + wlist if wlist: self.tk.call(args) else: return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call(args))] colormapwindows = wm_colormapwindows def wm_command(self, value=None): """Store VALUE in WM_COMMAND property. It is the command which shall be used to invoke the application. Return current command if VALUE is None.""" return self.tk.call('wm', 'command', self._w, value) command = wm_command def wm_deiconify(self): """Deiconify this widget. If it was never mapped it will not be mapped. On Windows it will raise this widget and give it the focus.""" return self.tk.call('wm', 'deiconify', self._w) deiconify = wm_deiconify def wm_focusmodel(self, model=None): """Set focus model to MODEL. "active" means that this widget will claim the focus itself, "passive" means that the window manager shall give the focus. Return current focus model if MODEL is None.""" return self.tk.call('wm', 'focusmodel', self._w, model) focusmodel = wm_focusmodel def wm_forget(self, window): # new in Tk 8.5 """The window will be unmapped from the screen and will no longer be managed by wm. toplevel windows will be treated like frame windows once they are no longer managed by wm, however, the menu option configuration will be remembered and the menus will return once the widget is managed again.""" self.tk.call('wm', 'forget', window) forget = wm_forget def wm_frame(self): """Return identifier for decorative frame of this widget if present.""" return self.tk.call('wm', 'frame', self._w) frame = wm_frame def wm_geometry(self, newGeometry=None): """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return current value if None is given.""" return self.tk.call('wm', 'geometry', self._w, newGeometry) geometry = wm_geometry def wm_grid(self, baseWidth=None, baseHeight=None, widthInc=None, heightInc=None): """Instruct the window manager that this widget shall only be resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the number of grid units requested in Tk_GeometryRequest.""" return self._getints(self.tk.call( 'wm', 'grid', self._w, baseWidth, baseHeight, widthInc, heightInc)) grid = wm_grid def wm_group(self, pathName=None): """Set the group leader widgets for related widgets to PATHNAME. Return the group leader of this widget if None is given.""" return self.tk.call('wm', 'group', self._w, pathName) group = wm_group def wm_iconbitmap(self, bitmap=None, default=None): """Set bitmap for the iconified widget to BITMAP. Return the bitmap if None is given. Under Windows, the DEFAULT parameter can be used to set the icon for the widget and any descendents that don't have an icon set explicitly. DEFAULT can be the relative path to a .ico file (example: root.iconbitmap(default='myicon.ico') ). See Tk documentation for more information.""" if default: return self.tk.call('wm', 'iconbitmap', self._w, '-default', default) else: return self.tk.call('wm', 'iconbitmap', self._w, bitmap) iconbitmap = wm_iconbitmap def wm_iconify(self): """Display widget as icon.""" return self.tk.call('wm', 'iconify', self._w) iconify = wm_iconify def wm_iconmask(self, bitmap=None): """Set mask for the icon bitmap of this widget. Return the mask if None is given.""" return self.tk.call('wm', 'iconmask', self._w, bitmap) iconmask = wm_iconmask def wm_iconname(self, newName=None): """Set the name of the icon for this widget. Return the name if None is given.""" return self.tk.call('wm', 'iconname', self._w, newName) iconname = wm_iconname def wm_iconphoto(self, default=False, *args): # new in Tk 8.5 """Sets the titlebar icon for this window based on the named photo images passed through args. If default is True, this is applied to all future created toplevels as well. The data in the images is taken as a snapshot at the time of invocation. If the images are later changed, this is not reflected to the titlebar icons. Multiple images are accepted to allow different images sizes to be provided. The window manager may scale provided icons to an appropriate size. On Windows, the images are packed into a Windows icon structure. This will override an icon specified to wm_iconbitmap, and vice versa. On X, the images are arranged into the _NET_WM_ICON X property, which most modern window managers support. An icon specified by wm_iconbitmap may exist simultaneously. On Macintosh, this currently does nothing.""" if default: self.tk.call('wm', 'iconphoto', self._w, "-default", *args) else: self.tk.call('wm', 'iconphoto', self._w, *args) iconphoto = wm_iconphoto def wm_iconposition(self, x=None, y=None): """Set the position of the icon of this widget to X and Y. Return a tuple of the current values of X and X if None is given.""" return self._getints(self.tk.call( 'wm', 'iconposition', self._w, x, y)) iconposition = wm_iconposition def wm_iconwindow(self, pathName=None): """Set widget PATHNAME to be displayed instead of icon. Return the current value if None is given.""" return self.tk.call('wm', 'iconwindow', self._w, pathName) iconwindow = wm_iconwindow def wm_manage(self, widget): # new in Tk 8.5 """The widget specified will become a stand alone top-level window. The window will be decorated with the window managers title bar, etc.""" self.tk.call('wm', 'manage', widget) manage = wm_manage def wm_maxsize(self, width=None, height=None): """Set max WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'maxsize', self._w, width, height)) maxsize = wm_maxsize def wm_minsize(self, width=None, height=None): """Set min WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'minsize', self._w, width, height)) minsize = wm_minsize def wm_overrideredirect(self, boolean=None): """Instruct the window manager to ignore this widget if BOOLEAN is given with 1. Return the current value if None is given.""" return self._getboolean(self.tk.call( 'wm', 'overrideredirect', self._w, boolean)) overrideredirect = wm_overrideredirect def wm_positionfrom(self, who=None): """Instruct the window manager that the position of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'positionfrom', self._w, who) positionfrom = wm_positionfrom def wm_protocol(self, name=None, func=None): """Bind function FUNC to command NAME for this widget. Return the function bound to NAME if None is given. NAME could be e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" if callable(func): command = self._register(func) else: command = func return self.tk.call( 'wm', 'protocol', self._w, name, command) protocol = wm_protocol def wm_resizable(self, width=None, height=None): """Instruct the window manager whether this width can be resized in WIDTH or HEIGHT. Both values are boolean values.""" return self.tk.call('wm', 'resizable', self._w, width, height) resizable = wm_resizable def wm_sizefrom(self, who=None): """Instruct the window manager that the size of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'sizefrom', self._w, who) sizefrom = wm_sizefrom def wm_state(self, newstate=None): """Query or set the state of this widget as one of normal, icon, iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" return self.tk.call('wm', 'state', self._w, newstate) state = wm_state def wm_title(self, string=None): """Set the title of this widget.""" return self.tk.call('wm', 'title', self._w, string) title = wm_title def wm_transient(self, master=None): """Instruct the window manager that this widget is transient with regard to widget MASTER.""" return self.tk.call('wm', 'transient', self._w, master) transient = wm_transient def wm_withdraw(self): """Withdraw this widget from the screen such that it is unmapped and forgotten by the window manager. Re-draw it with wm_deiconify.""" return self.tk.call('wm', 'withdraw', self._w) withdraw = wm_withdraw class Tk(Misc, Wm): """Toplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.""" _w = '.' def __init__(self, screenName=None, baseName=None, className='Tk', useTk=1, sync=0, use=None): """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will be created. BASENAME will be used for the identification of the profile file (see readprofile). It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME is the name of the widget class.""" self.master = None self.children = {} self._tkloaded = False # to avoid recursions in the getattr code in case of failure, we # ensure that self.tk is always _something_. self.tk = None if baseName is None: import os baseName = os.path.basename(sys.argv[0]) baseName, ext = os.path.splitext(baseName) if ext not in ('.py', '.pyc'): baseName = baseName + ext interactive = 0 self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) if useTk: self._loadtk() if not sys.flags.ignore_environment: # Issue #16248: Honor the -E flag to avoid code injection. self.readprofile(baseName, className) def loadtk(self): if not self._tkloaded: self.tk.loadtk() self._loadtk() def _loadtk(self): self._tkloaded = True global _default_root # Version sanity checks tk_version = self.tk.getvar('tk_version') if tk_version != _tkinter.TK_VERSION: raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)" % (_tkinter.TK_VERSION, tk_version)) # Under unknown circumstances, tcl_version gets coerced to float tcl_version = str(self.tk.getvar('tcl_version')) if tcl_version != _tkinter.TCL_VERSION: raise RuntimeError("tcl.h version (%s) doesn't match libtcl.a version (%s)" \ % (_tkinter.TCL_VERSION, tcl_version)) # Create and register the tkerror and exit commands # We need to inline parts of _register here, _ register # would register differently-named commands. if self._tclCommands is None: self._tclCommands = [] self.tk.createcommand('tkerror', _tkerror) self.tk.createcommand('exit', _exit) self._tclCommands.append('tkerror') self._tclCommands.append('exit') if _support_default_root and not _default_root: _default_root = self self.protocol("WM_DELETE_WINDOW", self.destroy) def destroy(self): """Destroy this and all descendants widgets. This will end the application of this Tcl interpreter.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) Misc.destroy(self) global _default_root if _support_default_root and _default_root is self: _default_root = None def readprofile(self, baseName, className): """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into the Tcl Interpreter and calls exec on the contents of BASENAME.py and CLASSNAME.py if such a file exists in the home directory.""" import os if 'HOME' in os.environ: home = os.environ['HOME'] else: home = os.curdir class_tcl = os.path.join(home, '.%s.tcl' % className) class_py = os.path.join(home, '.%s.py' % className) base_tcl = os.path.join(home, '.%s.tcl' % baseName) base_py = os.path.join(home, '.%s.py' % baseName) dir = {'self': self} exec('from tkinter import *', dir) if os.path.isfile(class_tcl): self.tk.call('source', class_tcl) if os.path.isfile(class_py): exec(open(class_py).read(), dir) if os.path.isfile(base_tcl): self.tk.call('source', base_tcl) if os.path.isfile(base_py): exec(open(base_py).read(), dir) def report_callback_exception(self, exc, val, tb): """Report callback exception on sys.stderr. Applications may want to override this internal function, and should when sys.stderr is None.""" import traceback print("Exception in Tkinter callback", file=sys.stderr) sys.last_type = exc sys.last_value = val sys.last_traceback = tb traceback.print_exception(exc, val, tb) def __getattr__(self, attr): "Delegate attribute access to the interpreter object" return getattr(self.tk, attr) # Ideally, the classes Pack, Place and Grid disappear, the # pack/place/grid methods are defined on the Widget class, and # everybody uses w.pack_whatever(...) instead of Pack.whatever(w, # ...), with pack(), place() and grid() being short for # pack_configure(), place_configure() and grid_columnconfigure(), and # forget() being short for pack_forget(). As a practical matter, I'm # afraid that there is too much code out there that may be using the # Pack, Place or Grid class, so I leave them intact -- but only as # backwards compatibility features. Also note that those methods that # take a master as argument (e.g. pack_propagate) have been moved to # the Misc class (which now incorporates all methods common between # toplevel and interior widgets). Again, for compatibility, these are # copied into the Pack, Place or Grid class. def Tcl(screenName=None, baseName=None, className='Tk', useTk=0): return Tk(screenName, baseName, className, useTk) class Pack: """Geometry manager Pack. Base class to use the methods pack_* in every widget.""" def pack_configure(self, cnf={}, **kw): """Pack a widget in the parent widget. Use as options: after=widget - pack it after you have packed widget anchor=NSEW (or subset) - position widget according to given direction before=widget - pack it before you will pack widget expand=bool - expand widget if parent size grows fill=NONE or X or Y or BOTH - fill widget if widget grows in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. """ self.tk.call( ('pack', 'configure', self._w) + self._options(cnf, kw)) pack = configure = config = pack_configure def pack_forget(self): """Unmap this widget and do not use it for the packing order.""" self.tk.call('pack', 'forget', self._w) forget = pack_forget def pack_info(self): """Return information about the packing options for this widget.""" d = _splitdict(self.tk, self.tk.call('pack', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = pack_info propagate = pack_propagate = Misc.pack_propagate slaves = pack_slaves = Misc.pack_slaves class Place: """Geometry manager Place. Base class to use the methods place_* in every widget.""" def place_configure(self, cnf={}, **kw): """Place a widget in the parent widget. Use as options: in=master - master relative to which the widget is placed in_=master - see 'in' option description x=amount - locate anchor of this widget at position x of master y=amount - locate anchor of this widget at position y of master relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge) rely=amount - locate anchor of this widget between 0.0 and 1.0 relative to height of master (1.0 is bottom edge) anchor=NSEW (or subset) - position anchor according to given direction width=amount - width of this widget in pixel height=amount - height of this widget in pixel relwidth=amount - width of this widget between 0.0 and 1.0 relative to width of master (1.0 is the same width as the master) relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master) bordermode="inside" or "outside" - whether to take border width of master widget into account """ self.tk.call( ('place', 'configure', self._w) + self._options(cnf, kw)) place = configure = config = place_configure def place_forget(self): """Unmap this widget.""" self.tk.call('place', 'forget', self._w) forget = place_forget def place_info(self): """Return information about the placing options for this widget.""" d = _splitdict(self.tk, self.tk.call('place', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = place_info slaves = place_slaves = Misc.place_slaves class Grid: """Geometry manager Grid. Base class to use the methods grid_* in every widget.""" # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) def grid_configure(self, cnf={}, **kw): """Position a widget in the parent widget in a grid. Use as options: column=number - use cell identified with given column (starting with 0) columnspan=number - this widget will span several columns in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction row=number - use cell identified with given row (starting with 0) rowspan=number - this widget will span several rows sticky=NSEW - if cell is larger on which sides will this widget stick to the cell boundary """ self.tk.call( ('grid', 'configure', self._w) + self._options(cnf, kw)) grid = configure = config = grid_configure bbox = grid_bbox = Misc.grid_bbox columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure def grid_forget(self): """Unmap this widget.""" self.tk.call('grid', 'forget', self._w) forget = grid_forget def grid_remove(self): """Unmap this widget but remember the grid options.""" self.tk.call('grid', 'remove', self._w) def grid_info(self): """Return information about the options for positioning this widget in a grid.""" d = _splitdict(self.tk, self.tk.call('grid', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = grid_info location = grid_location = Misc.grid_location propagate = grid_propagate = Misc.grid_propagate rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure size = grid_size = Misc.grid_size slaves = grid_slaves = Misc.grid_slaves class BaseWidget(Misc): """Internal class.""" def _setup(self, master, cnf): """Internal function. Sets up information about children.""" if not master: master = _get_default_root() self.master = master self.tk = master.tk name = None if 'name' in cnf: name = cnf['name'] del cnf['name'] if not name: name = self.__class__.__name__.lower() if master._last_child_ids is None: master._last_child_ids = {} count = master._last_child_ids.get(name, 0) + 1 master._last_child_ids[name] = count if count == 1: name = '!%s' % (name,) else: name = '!%s%d' % (name, count) self._name = name if master._w=='.': self._w = '.' + name else: self._w = master._w + '.' + name self.children = {} if self._name in self.master.children: self.master.children[self._name].destroy() self.master.children[self._name] = self def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): """Construct a widget with the parent widget MASTER, a name WIDGETNAME and appropriate options.""" if kw: cnf = _cnfmerge((cnf, kw)) self.widgetName = widgetName BaseWidget._setup(self, master, cnf) if self._tclCommands is None: self._tclCommands = [] classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)] for k, v in classes: del cnf[k] self.tk.call( (widgetName, self._w) + extra + self._options(cnf)) for k, v in classes: k.configure(self, v) def destroy(self): """Destroy this and all descendants widgets.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) if self._name in self.master.children: del self.master.children[self._name] Misc.destroy(self) def _do(self, name, args=()): # XXX Obsolete -- better use self.tk.call directly! return self.tk.call((self._w, name) + args) class Widget(BaseWidget, Pack, Place, Grid): """Internal class. Base class for a widget which can be positioned with the geometry managers Pack, Place or Grid.""" pass class Toplevel(BaseWidget, Wm): """Toplevel widget, e.g. for dialogs.""" def __init__(self, master=None, cnf={}, **kw): """Construct a toplevel widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, menu, relief, screen, takefocus, use, visual, width.""" if kw: cnf = _cnfmerge((cnf, kw)) extra = () for wmkey in ['screen', 'class_', 'class', 'visual', 'colormap']: if wmkey in cnf: val = cnf[wmkey] # TBD: a hack needed because some keys # are not valid as keyword arguments if wmkey[-1] == '_': opt = '-'+wmkey[:-1] else: opt = '-'+wmkey extra = extra + (opt, val) del cnf[wmkey] BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) root = self._root() self.iconname(root.iconname()) self.title(root.title()) self.protocol("WM_DELETE_WINDOW", self.destroy) class Button(Widget): """Button widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a button widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, repeatdelay, repeatinterval, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS command, compound, default, height, overrelief, state, width """ Widget.__init__(self, master, 'button', cnf, kw) def flash(self): """Flash the button. This is accomplished by redisplaying the button several times, alternating between active and normal colors. At the end of the flash the button is left in the same normal/active state as when the command was invoked. This command is ignored if the button's state is disabled. """ self.tk.call(self._w, 'flash') def invoke(self): """Invoke the command associated with the button. The return value is the return value from the command, or an empty string if there is no command associated with the button. This command is ignored if the button's state is disabled. """ return self.tk.call(self._w, 'invoke') class Canvas(Widget, XView, YView): """Canvas widget to display graphical elements like lines or text.""" def __init__(self, master=None, cnf={}, **kw): """Construct a canvas widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, closeenough, confine, cursor, height, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, offset, relief, scrollregion, selectbackground, selectborderwidth, selectforeground, state, takefocus, width, xscrollcommand, xscrollincrement, yscrollcommand, yscrollincrement.""" Widget.__init__(self, master, 'canvas', cnf, kw) def addtag(self, *args): """Internal function.""" self.tk.call((self._w, 'addtag') + args) def addtag_above(self, newtag, tagOrId): """Add tag NEWTAG to all items above TAGORID.""" self.addtag(newtag, 'above', tagOrId) def addtag_all(self, newtag): """Add tag NEWTAG to all items.""" self.addtag(newtag, 'all') def addtag_below(self, newtag, tagOrId): """Add tag NEWTAG to all items below TAGORID.""" self.addtag(newtag, 'below', tagOrId) def addtag_closest(self, newtag, x, y, halo=None, start=None): """Add tag NEWTAG to item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closests). If START is specified the next below this tag is taken.""" self.addtag(newtag, 'closest', x, y, halo, start) def addtag_enclosed(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items in the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'enclosed', x1, y1, x2, y2) def addtag_overlapping(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'overlapping', x1, y1, x2, y2) def addtag_withtag(self, newtag, tagOrId): """Add tag NEWTAG to all items with TAGORID.""" self.addtag(newtag, 'withtag', tagOrId) def bbox(self, *args): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses all items with tags specified as arguments.""" return self._getints( self.tk.call((self._w, 'bbox') + args)) or None def tag_unbind(self, tagOrId, sequence, funcid=None): """Unbind for all items with TAGORID for event SEQUENCE the function identified with FUNCID.""" self.tk.call(self._w, 'bind', tagOrId, sequence, '') if funcid: self.deletecommand(funcid) def tag_bind(self, tagOrId, sequence=None, func=None, add=None): """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'bind', tagOrId), sequence, func, add) def canvasx(self, screenx, gridspacing=None): """Return the canvas x coordinate of pixel position SCREENX rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasx', screenx, gridspacing)) def canvasy(self, screeny, gridspacing=None): """Return the canvas y coordinate of pixel position SCREENY rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasy', screeny, gridspacing)) def coords(self, *args): """Return a list of coordinates for the item given in ARGS.""" # XXX Should use _flatten on args return [self.tk.getdouble(x) for x in self.tk.splitlist( self.tk.call((self._w, 'coords') + args))] def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) """Internal function.""" args = _flatten(args) cnf = args[-1] if isinstance(cnf, (dict, tuple)): args = args[:-1] else: cnf = {} return self.tk.getint(self.tk.call( self._w, 'create', itemType, *(args + self._options(cnf, kw)))) def create_arc(self, *args, **kw): """Create arc shaped region with coordinates x1,y1,x2,y2.""" return self._create('arc', args, kw) def create_bitmap(self, *args, **kw): """Create bitmap with coordinates x1,y1.""" return self._create('bitmap', args, kw) def create_image(self, *args, **kw): """Create image item with coordinates x1,y1.""" return self._create('image', args, kw) def create_line(self, *args, **kw): """Create line with coordinates x1,y1,...,xn,yn.""" return self._create('line', args, kw) def create_oval(self, *args, **kw): """Create oval with coordinates x1,y1,x2,y2.""" return self._create('oval', args, kw) def create_polygon(self, *args, **kw): """Create polygon with coordinates x1,y1,...,xn,yn.""" return self._create('polygon', args, kw) def create_rectangle(self, *args, **kw): """Create rectangle with coordinates x1,y1,x2,y2.""" return self._create('rectangle', args, kw) def create_text(self, *args, **kw): """Create text with coordinates x1,y1.""" return self._create('text', args, kw) def create_window(self, *args, **kw): """Create window with coordinates x1,y1,x2,y2.""" return self._create('window', args, kw) def dchars(self, *args): """Delete characters of text items identified by tag or id in ARGS (possibly several times) from FIRST to LAST character (including).""" self.tk.call((self._w, 'dchars') + args) def delete(self, *args): """Delete items identified by all tag or ids contained in ARGS.""" self.tk.call((self._w, 'delete') + args) def dtag(self, *args): """Delete tag or id given as last arguments in ARGS from items identified by first argument in ARGS.""" self.tk.call((self._w, 'dtag') + args) def find(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'find') + args)) or () def find_above(self, tagOrId): """Return items above TAGORID.""" return self.find('above', tagOrId) def find_all(self): """Return all items.""" return self.find('all') def find_below(self, tagOrId): """Return all items below TAGORID.""" return self.find('below', tagOrId) def find_closest(self, x, y, halo=None, start=None): """Return item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.""" return self.find('closest', x, y, halo, start) def find_enclosed(self, x1, y1, x2, y2): """Return all items in rectangle defined by X1,Y1,X2,Y2.""" return self.find('enclosed', x1, y1, x2, y2) def find_overlapping(self, x1, y1, x2, y2): """Return all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" return self.find('overlapping', x1, y1, x2, y2) def find_withtag(self, tagOrId): """Return all items with TAGORID.""" return self.find('withtag', tagOrId) def focus(self, *args): """Set focus to the first item specified in ARGS.""" return self.tk.call((self._w, 'focus') + args) def gettags(self, *args): """Return tags associated with the first item specified in ARGS.""" return self.tk.splitlist( self.tk.call((self._w, 'gettags') + args)) def icursor(self, *args): """Set cursor at position POS in the item identified by TAGORID. In ARGS TAGORID must be first.""" self.tk.call((self._w, 'icursor') + args) def index(self, *args): """Return position of cursor as integer in item specified in ARGS.""" return self.tk.getint(self.tk.call((self._w, 'index') + args)) def insert(self, *args): """Insert TEXT in item TAGORID at position POS. ARGS must be TAGORID POS TEXT.""" self.tk.call((self._w, 'insert') + args) def itemcget(self, tagOrId, option): """Return the resource value for an OPTION for item TAGORID.""" return self.tk.call( (self._w, 'itemcget') + (tagOrId, '-'+option)) def itemconfigure(self, tagOrId, cnf=None, **kw): """Configure resources of an item TAGORID. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. """ return self._configure(('itemconfigure', tagOrId), cnf, kw) itemconfig = itemconfigure # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, # so the preferred name for them is tag_lower, tag_raise # (similar to tag_bind, and similar to the Text widget); # unfortunately can't delete the old ones yet (maybe in 1.6) def tag_lower(self, *args): """Lower an item TAGORID given in ARGS (optional below another item).""" self.tk.call((self._w, 'lower') + args) lower = tag_lower def move(self, *args): """Move an item TAGORID given in ARGS.""" self.tk.call((self._w, 'move') + args) def moveto(self, tagOrId, x='', y=''): """Move the items given by TAGORID in the canvas coordinate space so that the first coordinate pair of the bottommost item with tag TAGORID is located at position (X,Y). X and Y may be the empty string, in which case the corresponding coordinate will be unchanged. All items matching TAGORID remain in the same positions relative to each other.""" self.tk.call(self._w, 'moveto', tagOrId, x, y) def postscript(self, cnf={}, **kw): """Print the contents of the canvas to a postscript file. Valid options: colormap, colormode, file, fontmap, height, pageanchor, pageheight, pagewidth, pagex, pagey, rotate, width, x, y.""" return self.tk.call((self._w, 'postscript') + self._options(cnf, kw)) def tag_raise(self, *args): """Raise an item TAGORID given in ARGS (optional above another item).""" self.tk.call((self._w, 'raise') + args) lift = tkraise = tag_raise def scale(self, *args): """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" self.tk.call((self._w, 'scale') + args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y, gain=10): """Adjust the view of the canvas to GAIN times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y, gain) def select_adjust(self, tagOrId, index): """Adjust the end of the selection near the cursor of an item TAGORID to index.""" self.tk.call(self._w, 'select', 'adjust', tagOrId, index) def select_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'select', 'clear') def select_from(self, tagOrId, index): """Set the fixed end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'from', tagOrId, index) def select_item(self): """Return the item which has the selection.""" return self.tk.call(self._w, 'select', 'item') or None def select_to(self, tagOrId, index): """Set the variable end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'to', tagOrId, index) def type(self, tagOrId): """Return the type of the item TAGORID.""" return self.tk.call(self._w, 'type', tagOrId) or None class Checkbutton(Widget): """Checkbutton widget which is either in on- or off-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a checkbutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, offvalue, onvalue, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, variable, width, wraplength.""" Widget.__init__(self, master, 'checkbutton', cnf, kw) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') def toggle(self): """Toggle the button.""" self.tk.call(self._w, 'toggle') class Entry(Widget, XView): """Entry widget which allows displaying simple text.""" def __init__(self, master=None, cnf={}, **kw): """Construct an entry widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, invalidcommand, invcmd, justify, relief, selectbackground, selectborderwidth, selectforeground, show, state, takefocus, textvariable, validate, validatecommand, vcmd, width, xscrollcommand.""" Widget.__init__(self, master, 'entry', cnf, kw) def delete(self, first, last=None): """Delete text from FIRST to LAST (not included).""" self.tk.call(self._w, 'delete', first, last) def get(self): """Return the text.""" return self.tk.call(self._w, 'get') def icursor(self, index): """Insert cursor at INDEX.""" self.tk.call(self._w, 'icursor', index) def index(self, index): """Return position of cursor.""" return self.tk.getint(self.tk.call( self._w, 'index', index)) def insert(self, index, string): """Insert STRING at INDEX.""" self.tk.call(self._w, 'insert', index, string) def scan_mark(self, x): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x) def scan_dragto(self, x): """Adjust the view of the canvas to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x) def selection_adjust(self, index): """Adjust the end of the selection near the cursor to INDEX.""" self.tk.call(self._w, 'selection', 'adjust', index) select_adjust = selection_adjust def selection_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'selection', 'clear') select_clear = selection_clear def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'from', index) select_from = selection_from def selection_present(self): """Return True if there are characters selected in the entry, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) select_present = selection_present def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.tk.call(self._w, 'selection', 'range', start, end) select_range = selection_range def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'to', index) select_to = selection_to class Frame(Widget): """Frame widget which may contain other widgets and can have a 3D border.""" def __init__(self, master=None, cnf={}, **kw): """Construct a frame widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.""" cnf = _cnfmerge((cnf, kw)) extra = () if 'class_' in cnf: extra = ('-class', cnf['class_']) del cnf['class_'] elif 'class' in cnf: extra = ('-class', cnf['class']) del cnf['class'] Widget.__init__(self, master, 'frame', cnf, {}, extra) class Label(Widget): """Label widget which can display text and bitmaps.""" def __init__(self, master=None, cnf={}, **kw): """Construct a label widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground, highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS height, state, width """ Widget.__init__(self, master, 'label', cnf, kw) class Listbox(Widget, XView, YView): """Listbox widget which can display a list of strings.""" def __init__(self, master=None, cnf={}, **kw): """Construct a listbox widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, relief, selectbackground, selectborderwidth, selectforeground, selectmode, setgrid, takefocus, width, xscrollcommand, yscrollcommand, listvariable.""" Widget.__init__(self, master, 'listbox', cnf, kw) def activate(self, index): """Activate item identified by INDEX.""" self.tk.call(self._w, 'activate', index) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the item identified by the given index.""" return self._getints(self.tk.call(self._w, 'bbox', index)) or None def curselection(self): """Return the indices of currently selected item.""" return self._getints(self.tk.call(self._w, 'curselection')) or () def delete(self, first, last=None): """Delete items from FIRST to LAST (included).""" self.tk.call(self._w, 'delete', first, last) def get(self, first, last=None): """Get list of items from FIRST to LAST (included).""" if last is not None: return self.tk.splitlist(self.tk.call( self._w, 'get', first, last)) else: return self.tk.call(self._w, 'get', first) def index(self, index): """Return index of item identified with INDEX.""" i = self.tk.call(self._w, 'index', index) if i == 'none': return None return self.tk.getint(i) def insert(self, index, *elements): """Insert ELEMENTS at INDEX.""" self.tk.call((self._w, 'insert', index) + elements) def nearest(self, y): """Get index of item which is nearest to y coordinate Y.""" return self.tk.getint(self.tk.call( self._w, 'nearest', y)) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the listbox to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def see(self, index): """Scroll such that INDEX is visible.""" self.tk.call(self._w, 'see', index) def selection_anchor(self, index): """Set the fixed end oft the selection to INDEX.""" self.tk.call(self._w, 'selection', 'anchor', index) select_anchor = selection_anchor def selection_clear(self, first, last=None): """Clear the selection from FIRST to LAST (included).""" self.tk.call(self._w, 'selection', 'clear', first, last) select_clear = selection_clear def selection_includes(self, index): """Return True if INDEX is part of the selection.""" return self.tk.getboolean(self.tk.call( self._w, 'selection', 'includes', index)) select_includes = selection_includes def selection_set(self, first, last=None): """Set the selection from FIRST to LAST (included) without changing the currently selected elements.""" self.tk.call(self._w, 'selection', 'set', first, last) select_set = selection_set def size(self): """Return the number of elements in the listbox.""" return self.tk.getint(self.tk.call(self._w, 'size')) def itemcget(self, index, option): """Return the resource value for an ITEM and an OPTION.""" return self.tk.call( (self._w, 'itemcget') + (index, '-'+option)) def itemconfigure(self, index, cnf=None, **kw): """Configure resources of an ITEM. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. Valid resource names: background, bg, foreground, fg, selectbackground, selectforeground.""" return self._configure(('itemconfigure', index), cnf, kw) itemconfig = itemconfigure class Menu(Widget): """Menu widget which allows displaying menu bars, pull-down menus and pop-up menus.""" def __init__(self, master=None, cnf={}, **kw): """Construct menu widget with the parent MASTER. Valid resource names: activebackground, activeborderwidth, activeforeground, background, bd, bg, borderwidth, cursor, disabledforeground, fg, font, foreground, postcommand, relief, selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" Widget.__init__(self, master, 'menu', cnf, kw) def tk_popup(self, x, y, entry=""): """Post the menu at position X,Y with entry ENTRY.""" self.tk.call('tk_popup', self._w, x, y, entry) def activate(self, index): """Activate entry at INDEX.""" self.tk.call(self._w, 'activate', index) def add(self, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'add', itemType) + self._options(cnf, kw)) def add_cascade(self, cnf={}, **kw): """Add hierarchical menu item.""" self.add('cascade', cnf or kw) def add_checkbutton(self, cnf={}, **kw): """Add checkbutton menu item.""" self.add('checkbutton', cnf or kw) def add_command(self, cnf={}, **kw): """Add command menu item.""" self.add('command', cnf or kw) def add_radiobutton(self, cnf={}, **kw): """Addd radio menu item.""" self.add('radiobutton', cnf or kw) def add_separator(self, cnf={}, **kw): """Add separator.""" self.add('separator', cnf or kw) def insert(self, index, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'insert', index, itemType) + self._options(cnf, kw)) def insert_cascade(self, index, cnf={}, **kw): """Add hierarchical menu item at INDEX.""" self.insert(index, 'cascade', cnf or kw) def insert_checkbutton(self, index, cnf={}, **kw): """Add checkbutton menu item at INDEX.""" self.insert(index, 'checkbutton', cnf or kw) def insert_command(self, index, cnf={}, **kw): """Add command menu item at INDEX.""" self.insert(index, 'command', cnf or kw) def insert_radiobutton(self, index, cnf={}, **kw): """Addd radio menu item at INDEX.""" self.insert(index, 'radiobutton', cnf or kw) def insert_separator(self, index, cnf={}, **kw): """Add separator at INDEX.""" self.insert(index, 'separator', cnf or kw) def delete(self, index1, index2=None): """Delete menu items between INDEX1 and INDEX2 (included).""" if index2 is None: index2 = index1 num_index1, num_index2 = self.index(index1), self.index(index2) if (num_index1 is None) or (num_index2 is None): num_index1, num_index2 = 0, -1 for i in range(num_index1, num_index2 + 1): if 'command' in self.entryconfig(i): c = str(self.entrycget(i, 'command')) if c: self.deletecommand(c) self.tk.call(self._w, 'delete', index1, index2) def entrycget(self, index, option): """Return the resource value of a menu item for OPTION at INDEX.""" return self.tk.call(self._w, 'entrycget', index, '-' + option) def entryconfigure(self, index, cnf=None, **kw): """Configure a menu item at INDEX.""" return self._configure(('entryconfigure', index), cnf, kw) entryconfig = entryconfigure def index(self, index): """Return the index of a menu item identified by INDEX.""" i = self.tk.call(self._w, 'index', index) if i == 'none': return None return self.tk.getint(i) def invoke(self, index): """Invoke a menu item identified by INDEX and execute the associated command.""" return self.tk.call(self._w, 'invoke', index) def post(self, x, y): """Display a menu at position X,Y.""" self.tk.call(self._w, 'post', x, y) def type(self, index): """Return the type of the menu item at INDEX.""" return self.tk.call(self._w, 'type', index) def unpost(self): """Unmap a menu.""" self.tk.call(self._w, 'unpost') def xposition(self, index): # new in Tk 8.5 """Return the x-position of the leftmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call(self._w, 'xposition', index)) def yposition(self, index): """Return the y-position of the topmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call( self._w, 'yposition', index)) class Menubutton(Widget): """Menubutton widget, obsolete since Tk8.0.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'menubutton', cnf, kw) class Message(Widget): """Message widget to display multiline text. Obsolete since Label does it too.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'message', cnf, kw) class Radiobutton(Widget): """Radiobutton widget which shows only one of several buttons in on-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a radiobutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, value, variable, width, wraplength.""" Widget.__init__(self, master, 'radiobutton', cnf, kw) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') class Scale(Widget): """Scale widget which can display a numerical scale.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scale widget with the parent MASTER. Valid resource names: activebackground, background, bigincrement, bd, bg, borderwidth, command, cursor, digits, fg, font, foreground, from, highlightbackground, highlightcolor, highlightthickness, label, length, orient, relief, repeatdelay, repeatinterval, resolution, showvalue, sliderlength, sliderrelief, state, takefocus, tickinterval, to, troughcolor, variable, width.""" Widget.__init__(self, master, 'scale', cnf, kw) def get(self): """Get the current value as integer or float.""" value = self.tk.call(self._w, 'get') try: return self.tk.getint(value) except (ValueError, TypeError, TclError): return self.tk.getdouble(value) def set(self, value): """Set the value to VALUE.""" self.tk.call(self._w, 'set', value) def coords(self, value=None): """Return a tuple (X,Y) of the point along the centerline of the trough that corresponds to VALUE or the current value if None is given.""" return self._getints(self.tk.call(self._w, 'coords', value)) def identify(self, x, y): """Return where the point X,Y lies. Valid return values are "slider", "though1" and "though2".""" return self.tk.call(self._w, 'identify', x, y) class Scrollbar(Widget): """Scrollbar widget which displays a slider at a certain position.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scrollbar widget with the parent MASTER. Valid resource names: activebackground, activerelief, background, bd, bg, borderwidth, command, cursor, elementborderwidth, highlightbackground, highlightcolor, highlightthickness, jump, orient, relief, repeatdelay, repeatinterval, takefocus, troughcolor, width.""" Widget.__init__(self, master, 'scrollbar', cnf, kw) def activate(self, index=None): """Marks the element indicated by index as active. The only index values understood by this method are "arrow1", "slider", or "arrow2". If any other value is specified then no element of the scrollbar will be active. If index is not specified, the method returns the name of the element that is currently active, or None if no element is active.""" return self.tk.call(self._w, 'activate', index) or None def delta(self, deltax, deltay): """Return the fractional change of the scrollbar setting if it would be moved by DELTAX or DELTAY pixels.""" return self.tk.getdouble( self.tk.call(self._w, 'delta', deltax, deltay)) def fraction(self, x, y): """Return the fractional value which corresponds to a slider position of X,Y.""" return self.tk.getdouble(self.tk.call(self._w, 'fraction', x, y)) def identify(self, x, y): """Return the element under position X,Y as one of "arrow1","slider","arrow2" or "".""" return self.tk.call(self._w, 'identify', x, y) def get(self): """Return the current fractional values (upper and lower end) of the slider position.""" return self._getdoubles(self.tk.call(self._w, 'get')) def set(self, first, last): """Set the fractional values of the slider position (upper and lower ends as value between 0 and 1).""" self.tk.call(self._w, 'set', first, last) class Text(Widget, XView, YView): """Text widget which can display text in various forms.""" def __init__(self, master=None, cnf={}, **kw): """Construct a text widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, padx, pady, relief, selectbackground, selectborderwidth, selectforeground, setgrid, takefocus, xscrollcommand, yscrollcommand, WIDGET-SPECIFIC OPTIONS autoseparators, height, maxundo, spacing1, spacing2, spacing3, state, tabs, undo, width, wrap, """ Widget.__init__(self, master, 'text', cnf, kw) def bbox(self, index): """Return a tuple of (x,y,width,height) which gives the bounding box of the visible part of the character at the given index.""" return self._getints( self.tk.call(self._w, 'bbox', index)) or None def compare(self, index1, op, index2): """Return whether between index INDEX1 and index INDEX2 the relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" return self.tk.getboolean(self.tk.call( self._w, 'compare', index1, op, index2)) def count(self, index1, index2, *args): # new in Tk 8.5 """Counts the number of relevant things between the two indices. If index1 is after index2, the result will be a negative number (and this holds for each of the possible options). The actual items which are counted depends on the options given by args. The result is a list of integers, one for the result of each counting option given. Valid counting options are "chars", "displaychars", "displayindices", "displaylines", "indices", "lines", "xpixels" and "ypixels". There is an additional possible option "update", which if given then all subsequent options ensure that any possible out of date information is recalculated.""" args = ['-%s' % arg for arg in args if not arg.startswith('-')] args += [index1, index2] res = self.tk.call(self._w, 'count', *args) or None if res is not None and len(args) <= 3: return (res, ) else: return res def debug(self, boolean=None): """Turn on the internal consistency checks of the B-Tree inside the text widget according to BOOLEAN.""" if boolean is None: return self.tk.getboolean(self.tk.call(self._w, 'debug')) self.tk.call(self._w, 'debug', boolean) def delete(self, index1, index2=None): """Delete the characters between INDEX1 and INDEX2 (not included).""" self.tk.call(self._w, 'delete', index1, index2) def dlineinfo(self, index): """Return tuple (x,y,width,height,baseline) giving the bounding box and baseline position of the visible part of the line containing the character at INDEX.""" return self._getints(self.tk.call(self._w, 'dlineinfo', index)) def dump(self, index1, index2=None, command=None, **kw): """Return the contents of the widget between index1 and index2. The type of contents returned in filtered based on the keyword parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are given and true, then the corresponding items are returned. The result is a list of triples of the form (key, value, index). If none of the keywords are true then 'all' is used by default. If the 'command' argument is given, it is called once for each element of the list of triples, with the values of each triple serving as the arguments to the function. In this case the list is not returned.""" args = [] func_name = None result = None if not command: # Never call the dump command without the -command flag, since the # output could involve Tcl quoting and would be a pain to parse # right. Instead just set the command to build a list of triples # as if we had done the parsing. result = [] def append_triple(key, value, index, result=result): result.append((key, value, index)) command = append_triple try: if not isinstance(command, str): func_name = command = self._register(command) args += ["-command", command] for key in kw: if kw[key]: args.append("-" + key) args.append(index1) if index2: args.append(index2) self.tk.call(self._w, "dump", *args) return result finally: if func_name: self.deletecommand(func_name) ## new in tk8.4 def edit(self, *args): """Internal method This method controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the command are currently supported: edit_modified, edit_redo, edit_reset, edit_separator and edit_undo """ return self.tk.call(self._w, 'edit', *args) def edit_modified(self, arg=None): """Get or Set the modified flag If arg is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to arg. """ return self.edit("modified", arg) def edit_redo(self): """Redo the last undone edit When the undo option is true, reapplies the last undone edits provided no other edits were done since then. Generates an error when the redo stack is empty. Does nothing when the undo option is false. """ return self.edit("redo") def edit_reset(self): """Clears the undo and redo stacks """ return self.edit("reset") def edit_separator(self): """Inserts a separator (boundary) on the undo stack. Does nothing when the undo option is false """ return self.edit("separator") def edit_undo(self): """Undoes the last edit action If the undo option is true. An edit action is defined as all the insert and delete commands that are recorded on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the undo option is false """ return self.edit("undo") def get(self, index1, index2=None): """Return the text from INDEX1 to INDEX2 (not included).""" return self.tk.call(self._w, 'get', index1, index2) # (Image commands are new in 8.0) def image_cget(self, index, option): """Return the value of OPTION of an embedded image at INDEX.""" if option[:1] != "-": option = "-" + option if option[-1:] == "_": option = option[:-1] return self.tk.call(self._w, "image", "cget", index, option) def image_configure(self, index, cnf=None, **kw): """Configure an embedded image at INDEX.""" return self._configure(('image', 'configure', index), cnf, kw) def image_create(self, index, cnf={}, **kw): """Create an embedded image at INDEX.""" return self.tk.call( self._w, "image", "create", index, *self._options(cnf, kw)) def image_names(self): """Return all names of embedded images in this widget.""" return self.tk.call(self._w, "image", "names") def index(self, index): """Return the index in the form line.char for INDEX.""" return str(self.tk.call(self._w, 'index', index)) def insert(self, index, chars, *args): """Insert CHARS before the characters at INDEX. An additional tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" self.tk.call((self._w, 'insert', index, chars) + args) def mark_gravity(self, markName, direction=None): """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). Return the current value if None is given for DIRECTION.""" return self.tk.call( (self._w, 'mark', 'gravity', markName, direction)) def mark_names(self): """Return all mark names.""" return self.tk.splitlist(self.tk.call( self._w, 'mark', 'names')) def mark_set(self, markName, index): """Set mark MARKNAME before the character at INDEX.""" self.tk.call(self._w, 'mark', 'set', markName, index) def mark_unset(self, *markNames): """Delete all marks in MARKNAMES.""" self.tk.call((self._w, 'mark', 'unset') + markNames) def mark_next(self, index): """Return the name of the next mark after INDEX.""" return self.tk.call(self._w, 'mark', 'next', index) or None def mark_previous(self, index): """Return the name of the previous mark before INDEX.""" return self.tk.call(self._w, 'mark', 'previous', index) or None def peer_create(self, newPathName, cnf={}, **kw): # new in Tk 8.5 """Creates a peer text widget with the given newPathName, and any optional standard configuration options. By default the peer will have the same start and end line as the parent widget, but these can be overridden with the standard configuration options.""" self.tk.call(self._w, 'peer', 'create', newPathName, *self._options(cnf, kw)) def peer_names(self): # new in Tk 8.5 """Returns a list of peers of this widget (this does not include the widget itself).""" return self.tk.splitlist(self.tk.call(self._w, 'peer', 'names')) def replace(self, index1, index2, chars, *args): # new in Tk 8.5 """Replaces the range of characters between index1 and index2 with the given characters and tags specified by args. See the method insert for some more information about args, and the method delete for information about the indices.""" self.tk.call(self._w, 'replace', index1, index2, chars, *args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the text to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def search(self, pattern, index, stopindex=None, forwards=None, backwards=None, exact=None, regexp=None, nocase=None, count=None, elide=None): """Search PATTERN beginning from INDEX until STOPINDEX. Return the index of the first character of a match or an empty string.""" args = [self._w, 'search'] if forwards: args.append('-forwards') if backwards: args.append('-backwards') if exact: args.append('-exact') if regexp: args.append('-regexp') if nocase: args.append('-nocase') if elide: args.append('-elide') if count: args.append('-count'); args.append(count) if pattern and pattern[0] == '-': args.append('--') args.append(pattern) args.append(index) if stopindex: args.append(stopindex) return str(self.tk.call(tuple(args))) def see(self, index): """Scroll such that the character at INDEX is visible.""" self.tk.call(self._w, 'see', index) def tag_add(self, tagName, index1, *args): """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. Additional pairs of indices may follow in ARGS.""" self.tk.call( (self._w, 'tag', 'add', tagName, index1) + args) def tag_unbind(self, tagName, sequence, funcid=None): """Unbind for all characters with TAGNAME for event SEQUENCE the function identified with FUNCID.""" self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '') if funcid: self.deletecommand(funcid) def tag_bind(self, tagName, sequence, func, add=None): """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'tag', 'bind', tagName), sequence, func, add) def tag_cget(self, tagName, option): """Return the value of OPTION for tag TAGNAME.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'tag', 'cget', tagName, option) def tag_configure(self, tagName, cnf=None, **kw): """Configure a tag TAGNAME.""" return self._configure(('tag', 'configure', tagName), cnf, kw) tag_config = tag_configure def tag_delete(self, *tagNames): """Delete all tags in TAGNAMES.""" self.tk.call((self._w, 'tag', 'delete') + tagNames) def tag_lower(self, tagName, belowThis=None): """Change the priority of tag TAGNAME such that it is lower than the priority of BELOWTHIS.""" self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) def tag_names(self, index=None): """Return a list of all tag names.""" return self.tk.splitlist( self.tk.call(self._w, 'tag', 'names', index)) def tag_nextrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched forward from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'nextrange', tagName, index1, index2)) def tag_prevrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched backwards from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'prevrange', tagName, index1, index2)) def tag_raise(self, tagName, aboveThis=None): """Change the priority of tag TAGNAME such that it is higher than the priority of ABOVETHIS.""" self.tk.call( self._w, 'tag', 'raise', tagName, aboveThis) def tag_ranges(self, tagName): """Return a list of ranges of text which have tag TAGNAME.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'ranges', tagName)) def tag_remove(self, tagName, index1, index2=None): """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" self.tk.call( self._w, 'tag', 'remove', tagName, index1, index2) def window_cget(self, index, option): """Return the value of OPTION of an embedded window at INDEX.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'window', 'cget', index, option) def window_configure(self, index, cnf=None, **kw): """Configure an embedded window at INDEX.""" return self._configure(('window', 'configure', index), cnf, kw) window_config = window_configure def window_create(self, index, cnf={}, **kw): """Create a window at INDEX.""" self.tk.call( (self._w, 'window', 'create', index) + self._options(cnf, kw)) def window_names(self): """Return all names of embedded windows in this widget.""" return self.tk.splitlist( self.tk.call(self._w, 'window', 'names')) def yview_pickplace(self, *what): """Obsolete function, use see.""" self.tk.call((self._w, 'yview', '-pickplace') + what) class _setit: """Internal class. It wraps the command in the widget OptionMenu.""" def __init__(self, var, value, callback=None): self.__value = value self.__var = var self.__callback = callback def __call__(self, *args): self.__var.set(self.__value) if self.__callback: self.__callback(self.__value, *args) class OptionMenu(Menubutton): """OptionMenu which allows the user to select a value from a menu.""" def __init__(self, master, variable, value, *values, **kwargs): """Construct an optionmenu widget with the parent MASTER, with the resource textvariable set to VARIABLE, the initially selected value VALUE, the other menu values VALUES and an additional keyword argument command.""" kw = {"borderwidth": 2, "textvariable": variable, "indicatoron": 1, "relief": RAISED, "anchor": "c", "highlightthickness": 2} Widget.__init__(self, master, "menubutton", kw) self.widgetName = 'tk_optionMenu' menu = self.__menu = Menu(self, name="menu", tearoff=0) self.menuname = menu._w # 'command' is the only supported keyword callback = kwargs.get('command') if 'command' in kwargs: del kwargs['command'] if kwargs: raise TclError('unknown option -'+next(iter(kwargs))) menu.add_command(label=value, command=_setit(variable, value, callback)) for v in values: menu.add_command(label=v, command=_setit(variable, v, callback)) self["menu"] = menu def __getitem__(self, name): if name == 'menu': return self.__menu return Widget.__getitem__(self, name) def destroy(self): """Destroy this widget and the associated menu.""" Menubutton.destroy(self) self.__menu = None class Image: """Base class for images.""" _last_id = 0 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): self.name = None if not master: master = _get_default_root('create image') self.tk = getattr(master, 'tk', master) if not name: Image._last_id += 1 name = "pyimage%r" % (Image._last_id,) # tk itself would use image if kw and cnf: cnf = _cnfmerge((cnf, kw)) elif kw: cnf = kw options = () for k, v in cnf.items(): if callable(v): v = self._register(v) options = options + ('-'+k, v) self.tk.call(('image', 'create', imgtype, name,) + options) self.name = name def __str__(self): return self.name def __del__(self): if self.name: try: self.tk.call('image', 'delete', self.name) except TclError: # May happen if the root was destroyed pass def __setitem__(self, key, value): self.tk.call(self.name, 'configure', '-'+key, value) def __getitem__(self, key): return self.tk.call(self.name, 'configure', '-'+key) def configure(self, **kw): """Configure the image.""" res = () for k, v in _cnfmerge(kw).items(): if v is not None: if k[-1] == '_': k = k[:-1] if callable(v): v = self._register(v) res = res + ('-'+k, v) self.tk.call((self.name, 'config') + res) config = configure def height(self): """Return the height of the image.""" return self.tk.getint( self.tk.call('image', 'height', self.name)) def type(self): """Return the type of the image, e.g. "photo" or "bitmap".""" return self.tk.call('image', 'type', self.name) def width(self): """Return the width of the image.""" return self.tk.getint( self.tk.call('image', 'width', self.name)) class PhotoImage(Image): """Widget which can display images in PGM, PPM, GIF, PNG format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create an image with NAME. Valid resource names: data, format, file, gamma, height, palette, width.""" Image.__init__(self, 'photo', name, cnf, master, **kw) def blank(self): """Display a transparent image.""" self.tk.call(self.name, 'blank') def cget(self, option): """Return the value of OPTION.""" return self.tk.call(self.name, 'cget', '-' + option) # XXX config def __getitem__(self, key): return self.tk.call(self.name, 'cget', '-' + key) # XXX copy -from, -to, ...? def copy(self): """Return a new PhotoImage with the same image as this widget.""" destImage = PhotoImage(master=self.tk) self.tk.call(destImage, 'copy', self.name) return destImage def zoom(self, x, y=''): """Return a new PhotoImage with the same image as this widget but zoom it with a factor of x in the X direction and y in the Y direction. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) return destImage def subsample(self, x, y=''): """Return a new PhotoImage based on the same image as this widget but use only every Xth or Yth pixel. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) return destImage def get(self, x, y): """Return the color (red, green, blue) of the pixel at X,Y.""" return self.tk.call(self.name, 'get', x, y) def put(self, data, to=None): """Put row formatted colors to image starting from position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" args = (self.name, 'put', data) if to: if to[0] == '-to': to = to[1:] args = args + ('-to',) + tuple(to) self.tk.call(args) # XXX read def write(self, filename, format=None, from_coords=None): """Write image to file FILENAME in FORMAT starting from position FROM_COORDS.""" args = (self.name, 'write', filename) if format: args = args + ('-format', format) if from_coords: args = args + ('-from',) + tuple(from_coords) self.tk.call(args) def transparency_get(self, x, y): """Return True if the pixel at x,y is transparent.""" return self.tk.getboolean(self.tk.call( self.name, 'transparency', 'get', x, y)) def transparency_set(self, x, y, boolean): """Set the transparency of the pixel at x,y.""" self.tk.call(self.name, 'transparency', 'set', x, y, boolean) class BitmapImage(Image): """Widget which can display images in XBM format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create a bitmap with NAME. Valid resource names: background, data, file, foreground, maskdata, maskfile.""" Image.__init__(self, 'bitmap', name, cnf, master, **kw) def image_names(): tk = _get_default_root('use image_names()').tk return tk.splitlist(tk.call('image', 'names')) def image_types(): tk = _get_default_root('use image_types()').tk return tk.splitlist(tk.call('image', 'types')) class Spinbox(Widget, XView): """spinbox widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a spinbox widget with the parent MASTER. STANDARD OPTIONS activebackground, background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, justify, relief, repeatdelay, repeatinterval, selectbackground, selectborderwidth selectforeground, takefocus, textvariable xscrollcommand. WIDGET-SPECIFIC OPTIONS buttonbackground, buttoncursor, buttondownrelief, buttonuprelief, command, disabledbackground, disabledforeground, format, from, invalidcommand, increment, readonlybackground, state, to, validate, validatecommand values, width, wrap, """ Widget.__init__(self, master, 'spinbox', cnf, kw) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the character given by index. The first two elements of the list give the x and y coordinates of the upper-left corner of the screen area covered by the character (in pixels relative to the widget) and the last two elements give the width and height of the character, in pixels. The bounding box may refer to a region outside the visible area of the window. """ return self._getints(self.tk.call(self._w, 'bbox', index)) or None def delete(self, first, last=None): """Delete one or more elements of the spinbox. First is the index of the first character to delete, and last is the index of the character just after the last one to delete. If last isn't specified it defaults to first+1, i.e. a single character is deleted. This command returns an empty string. """ return self.tk.call(self._w, 'delete', first, last) def get(self): """Returns the spinbox's string""" return self.tk.call(self._w, 'get') def icursor(self, index): """Alter the position of the insertion cursor. The insertion cursor will be displayed just before the character given by index. Returns an empty string """ return self.tk.call(self._w, 'icursor', index) def identify(self, x, y): """Returns the name of the widget at position x, y Return value is one of: none, buttondown, buttonup, entry """ return self.tk.call(self._w, 'identify', x, y) def index(self, index): """Returns the numerical index corresponding to index """ return self.tk.call(self._w, 'index', index) def insert(self, index, s): """Insert string s at index Returns an empty string. """ return self.tk.call(self._w, 'insert', index, s) def invoke(self, element): """Causes the specified element to be invoked The element could be buttondown or buttonup triggering the action associated with it. """ return self.tk.call(self._w, 'invoke', element) def scan(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'scan') + args)) or () def scan_mark(self, x): """Records x and the current view in the spinbox window; used in conjunction with later scan dragto commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. """ return self.scan("mark", x) def scan_dragto(self, x): """Compute the difference between the given x argument and the x argument to the last scan mark command It then adjusts the view left or right by 10 times the difference in x-coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the spinbox at high speed through the window. The return value is an empty string. """ return self.scan("dragto", x) def selection(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'selection') + args)) or () def selection_adjust(self, index): """Locate the end of the selection nearest to the character given by index, Then adjust that end of the selection to be at index (i.e including but not going beyond index). The other end of the selection is made the anchor point for future select to commands. If the selection isn't currently in the spinbox, then a new selection is created to include the characters between index and the most recent selection anchor point, inclusive. """ return self.selection("adjust", index) def selection_clear(self): """Clear the selection If the selection isn't in this widget then the command has no effect. """ return self.selection("clear") def selection_element(self, element=None): """Sets or gets the currently selected element. If a spinbutton element is specified, it will be displayed depressed. """ return self.tk.call(self._w, 'selection', 'element', element) def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.selection('from', index) def selection_present(self): """Return True if there are characters selected in the spinbox, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.selection('range', start, end) def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.selection('to', index) ########################################################################### class LabelFrame(Widget): """labelframe widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a labelframe widget with the parent MASTER. STANDARD OPTIONS borderwidth, cursor, font, foreground, highlightbackground, highlightcolor, highlightthickness, padx, pady, relief, takefocus, text WIDGET-SPECIFIC OPTIONS background, class, colormap, container, height, labelanchor, labelwidget, visual, width """ Widget.__init__(self, master, 'labelframe', cnf, kw) ######################################################################## class PanedWindow(Widget): """panedwindow widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a panedwindow widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, height, orient, relief, width WIDGET-SPECIFIC OPTIONS handlepad, handlesize, opaqueresize, sashcursor, sashpad, sashrelief, sashwidth, showhandle, """ Widget.__init__(self, master, 'panedwindow', cnf, kw) def add(self, child, **kw): """Add a child widget to the panedwindow in a new pane. The child argument is the name of the child widget followed by pairs of arguments that specify how to manage the windows. The possible options and values are the ones accepted by the paneconfigure method. """ self.tk.call((self._w, 'add', child) + self._options(kw)) def remove(self, child): """Remove the pane containing child from the panedwindow All geometry management options for child will be forgotten. """ self.tk.call(self._w, 'forget', child) forget = remove def identify(self, x, y): """Identify the panedwindow component at point x, y If the point is over a sash or a sash handle, the result is a two element list containing the index of the sash or handle, and a word indicating whether it is over a sash or a handle, such as {0 sash} or {2 handle}. If the point is over any other part of the panedwindow, the result is an empty list. """ return self.tk.call(self._w, 'identify', x, y) def proxy(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'proxy') + args)) or () def proxy_coord(self): """Return the x and y pair of the most recent proxy location """ return self.proxy("coord") def proxy_forget(self): """Remove the proxy from the display. """ return self.proxy("forget") def proxy_place(self, x, y): """Place the proxy at the given x and y coordinates. """ return self.proxy("place", x, y) def sash(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'sash') + args)) or () def sash_coord(self, index): """Return the current x and y pair for the sash given by index. Index must be an integer between 0 and 1 less than the number of panes in the panedwindow. The coordinates given are those of the top left corner of the region containing the sash. pathName sash dragto index x y This command computes the difference between the given coordinates and the coordinates given to the last sash coord command for the given sash. It then moves that sash the computed difference. The return value is the empty string. """ return self.sash("coord", index) def sash_mark(self, index): """Records x and y for the sash given by index; Used in conjunction with later dragto commands to move the sash. """ return self.sash("mark", index) def sash_place(self, index, x, y): """Place the sash given by index at the given coordinates """ return self.sash("place", index, x, y) def panecget(self, child, option): """Query a management option for window. Option may be any value allowed by the paneconfigure subcommand """ return self.tk.call( (self._w, 'panecget') + (child, '-'+option)) def paneconfigure(self, tagOrId, cnf=None, **kw): """Query or modify the management options for window. If no option is specified, returns a list describing all of the available options for pathName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. The following options are supported: after window Insert the window after the window specified. window should be the name of a window already managed by pathName. before window Insert the window before the window specified. window should be the name of a window already managed by pathName. height size Specify a height for the window. The height will be the outer dimension of the window including its border, if any. If size is an empty string, or if -height is not specified, then the height requested internally by the window will be used initially; the height may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. minsize n Specifies that the size of the window cannot be made less than n. This constraint only affects the size of the widget in the paned dimension -- the x dimension for horizontal panedwindows, the y dimension for vertical panedwindows. May be any value accepted by Tk_GetPixels. padx n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the X-direction. The value may have any of the forms accepted by Tk_GetPixels. pady n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the Y-direction. The value may have any of the forms accepted by Tk_GetPixels. sticky style If a window's pane is larger than the requested dimensions of the window, this option may be used to position (or stretch) the window within its pane. Style is a string that contains zero or more of the characters n, s, e or w. The string can optionally contains spaces or commas, but they are ignored. Each letter refers to a side (north, south, east, or west) that the window will "stick" to. If both n and s (or e and w) are specified, the window will be stretched to fill the entire height (or width) of its cavity. width size Specify a width for the window. The width will be the outer dimension of the window including its border, if any. If size is an empty string, or if -width is not specified, then the width requested internally by the window will be used initially; the width may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. """ if cnf is None and not kw: return self._getconfigure(self._w, 'paneconfigure', tagOrId) if isinstance(cnf, str) and not kw: return self._getconfigure1( self._w, 'paneconfigure', tagOrId, '-'+cnf) self.tk.call((self._w, 'paneconfigure', tagOrId) + self._options(cnf, kw)) paneconfig = paneconfigure def panes(self): """Returns an ordered list of the child panes.""" return self.tk.splitlist(self.tk.call(self._w, 'panes')) # Test: def _test(): root = Tk() text = "This is Tcl/Tk version %s" % TclVersion text += "\nThis should be a cedilla: \xe7" label = Label(root, text=text) label.pack() test = Button(root, text="Click me!", command=lambda root=root: root.test.configure( text="[%s]" % root.test['text'])) test.pack() root.test = test quit = Button(root, text="QUIT", command=root.destroy) quit.pack() # The following three commands are needed so the window pops # up on top on Windows... root.iconify() root.update() root.deiconify() root.mainloop() if __name__ == '__main__': _test() usr/lib/python3.6/site-packages/dateutil/tz/__init__.py000064400000000317152347522040017001 0ustar00from .tz import * __all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz", "enfold", "datetime_ambiguous", "datetime_exists"] usr/lib64/python2.7/idlelib/__init__.py000064400000000440152347523000013561 0ustar00"""The idlelib package implements the Idle application. Idle includes an interactive shell and editor. Use the files named idle.* to start Idle. The other files are private implementations. Their details are subject to change. See PEP 434 for more. Import them at your own risk. """ usr/lib64/python2.7/sqlite3/__init__.py000064400000001762152347523150013557 0ustar00# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Haering # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. from dbapi2 import * usr/lib/python3.6/site-packages/dns/__init__.py000064400000002457152347542120015325 0ustar00# Copyright (C) 2003-2007, 2009, 2011 Nominum, Inc. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose with or without fee is hereby granted, # provided that the above copyright notice and this permission notice # appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """dnspython DNS toolkit""" __all__ = [ 'dnssec', 'e164', 'edns', 'entropy', 'exception', 'flags', 'hash', 'inet', 'ipv4', 'ipv6', 'message', 'name', 'namedict', 'node', 'opcode', 'query', 'rcode', 'rdata', 'rdataclass', 'rdataset', 'rdatatype', 'renderer', 'resolver', 'reversename', 'rrset', 'set', 'tokenizer', 'tsig', 'tsigkeyring', 'ttl', 'rdtypes', 'update', 'version', 'wiredata', 'zone', ] usr/lib64/python3.12/json/__init__.py000064400000033304152347562530013223 0ustar00r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is derived from a version of the externally maintained simplejson library. Encoding basic Python object hierarchies:: >>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print(json.dumps("\"foo\bar")) "\"foo\bar" >>> print(json.dumps('\u1234')) "\u1234" >>> print(json.dumps('\\')) "\\" >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) {"a": 0, "b": 0, "c": 0} >>> from io import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]' Compact encoding:: >>> import json >>> mydict = {'4': 5, '6': 7} >>> json.dumps([1,2,3,mydict], separators=(',', ':')) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: >>> import json >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)) { "4": 5, "6": 7 } Decoding JSON:: >>> import json >>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}] >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj True >>> json.loads('"\\"foo\\bar"') == '"foo\x08ar' True >>> from io import StringIO >>> io = StringIO('["streaming API"]') >>> json.load(io)[0] == 'streaming API' True Specializing JSON object decoding:: >>> import json >>> def as_complex(dct): ... if '__complex__' in dct: ... return complex(dct['real'], dct['imag']) ... return dct ... >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', ... object_hook=as_complex) (1+2j) >>> from decimal import Decimal >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') True Specializing JSON object encoding:: >>> import json >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... raise TypeError(f'Object of type {obj.__class__.__name__} ' ... f'is not JSON serializable') ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) '[2.0, 1.0]' >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) '[2.0, 1.0]' Using json.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } $ echo '{ 1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] __author__ = 'Bob Ippolito ' from .decoder import JSONDecoder, JSONDecodeError from .encoder import JSONEncoder import codecs _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, default=None, ) def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the strings written to ``fp`` can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``RecursionError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): iterable = _default_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the return value can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``RecursionError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): return _default_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).encode(obj) _default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None) def detect_encoding(b): bstartswith = b.startswith if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)): return 'utf-32' if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)): return 'utf-16' if bstartswith(codecs.BOM_UTF8): return 'utf-8-sig' if len(b) >= 4: if not b[0]: # 00 00 -- -- - utf-32-be # 00 XX -- -- - utf-16-be return 'utf-16-be' if b[1] else 'utf-32-be' if not b[1]: # XX 00 00 00 - utf-32-le # XX 00 00 XX - utf-16-le # XX 00 XX -- - utf-16-le return 'utf-16-le' if b[2] or b[3] else 'utf-32-le' elif len(b) == 2: if not b[0]: # 00 XX - utf-16-be return 'utf-16-be' if not b[1]: # XX 00 - utf-16-le return 'utf-16-le' # default return 'utf-8' def load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders. If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ return loads(fp.read(), cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) def loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders. If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. ``parse_float``, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal). ``parse_int``, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float). ``parse_constant``, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ if isinstance(s, str): if s.startswith('\ufeff'): raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0) else: if not isinstance(s, (bytes, bytearray)): raise TypeError(f'the JSON object must be str, bytes or bytearray, ' f'not {s.__class__.__name__}') s = s.decode(detect_encoding(s), 'surrogatepass') if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s) usr/lib64/python3.6/lib2to3/fixes/__init__.py000064400000000057152347565400014567 0ustar00# Dummy file to make this directory a package. usr/lib64/python3.6/distutils/__init__.py000064400000000354152347612250014213 0ustar00"""distutils The main package for the Python Module Distribution Utilities. Normally used from a setup script as from distutils.core import setup setup (...) """ import sys __version__ = sys.version[:sys.version.index(' ')] usr/lib64/python3.8/turtledemo/__init__.py000064400000000472152347614340014360 0ustar00""" -------------------------------------- About this viewer -------------------------------------- Tiny demo viewer to view turtle graphics example scripts. Quickly and dirtyly assembled by Gregor Lingl. June, 2006 For more information see: turtledemo - Help Have fun! """ usr/lib64/python2.7/multiprocessing/dummy/__init__.py000064400000010601152347637510016553 0ustar00# # Support for the API of the multiprocessing package using threads # # multiprocessing/dummy/__init__.py # # Copyright (c) 2006-2008, R Oudkerk # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. Neither the name of author nor the names of any contributors may be # used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # __all__ = [ 'Process', 'current_process', 'active_children', 'freeze_support', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event', 'Queue', 'Manager', 'Pipe', 'Pool', 'JoinableQueue' ] # # Imports # import threading import sys import weakref import array import itertools from multiprocessing import TimeoutError, cpu_count from multiprocessing.dummy.connection import Pipe from threading import Lock, RLock, Semaphore, BoundedSemaphore from threading import Event from Queue import Queue # # # class DummyProcess(threading.Thread): def __init__(self, group=None, target=None, name=None, args=(), kwargs={}): threading.Thread.__init__(self, group, target, name, args, kwargs) self._pid = None self._children = weakref.WeakKeyDictionary() self._start_called = False self._parent = current_process() def start(self): assert self._parent is current_process() self._start_called = True if hasattr(self._parent, '_children'): self._parent._children[self] = None threading.Thread.start(self) @property def exitcode(self): if self._start_called and not self.is_alive(): return 0 else: return None # # # class Condition(threading._Condition): notify_all = threading._Condition.notify_all.im_func # # # Process = DummyProcess current_process = threading.current_thread current_process()._children = weakref.WeakKeyDictionary() def active_children(): children = current_process()._children for p in list(children): if not p.is_alive(): children.pop(p, None) return list(children) def freeze_support(): pass # # # class Namespace(object): def __init__(self, **kwds): self.__dict__.update(kwds) def __repr__(self): items = self.__dict__.items() temp = [] for name, value in items: if not name.startswith('_'): temp.append('%s=%r' % (name, value)) temp.sort() return 'Namespace(%s)' % str.join(', ', temp) dict = dict list = list def Array(typecode, sequence, lock=True): return array.array(typecode, sequence) class Value(object): def __init__(self, typecode, value, lock=True): self._typecode = typecode self._value = value def _get(self): return self._value def _set(self, value): self._value = value value = property(_get, _set) def __repr__(self): return '<%s(%r, %r)>'%(type(self).__name__,self._typecode,self._value) def Manager(): return sys.modules[__name__] def shutdown(): pass def Pool(processes=None, initializer=None, initargs=()): from multiprocessing.pool import ThreadPool return ThreadPool(processes, initializer, initargs) JoinableQueue = Queue lib64/python3.8/ensurepip/__init__.py000064400000016542152347641540013404 0ustar00import distutils.version import glob import os import os.path import sys import runpy import tempfile import subprocess __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('setuptools', 'pip') _WHEEL_DIR = "/usr/share/python38-wheels/" _wheels = {} def _get_most_recent_wheel_version(pkg): prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg)) _wheels[pkg] = {} for suffix in "-py2.py3-none-any.whl", "-py3-none-any.whl": pattern = "{}*{}".format(prefix, suffix) for path in glob.glob(pattern): version_str = path[len(prefix):-len(suffix)] _wheels[pkg][version_str] = os.path.basename(path) return str(max(_wheels[pkg], key=distutils.version.LooseVersion)) _SETUPTOOLS_VERSION = _get_most_recent_wheel_version("setuptools") _PIP_VERSION = _get_most_recent_wheel_version("pip") _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), ] def _run_pip(args, additional_paths=None): # Run the bootstraping in a subprocess to avoid leaking any state that happens # after pip has executed. Particulary, this avoids the case when pip holds onto # the files in *additional_paths*, preventing us to remove them at the end of the # invocation. code = f""" import runpy import sys sys.path = {additional_paths or []} + sys.path sys.argv[1:] = {args} runpy.run_module("pip", run_name="__main__", alter_sys=True) """ cmd = [sys.executable, '-c', code] if sys.flags.isolated: # run code in isolated mode if currently running isolated cmd.insert(1, '-I') return subprocess.run(cmd, check=True).returncode def version(): """ Returns a string specifying the bundled version of pip. """ return _PIP_VERSION def _disable_pip_configuration_settings(): # We deliberately ignore all pip environment variables # when invoking pip # See http://bugs.python.org/issue19734 for details keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] for k in keys_to_remove: del os.environ[k] # We also ignore the settings in the default pip configuration file # See http://bugs.python.org/issue20053 for details os.environ['PIP_CONFIG_FILE'] = os.devnull def bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Note that calling this function will alter both sys.path and os.environ. """ # Discard the return value _bootstrap(root=root, upgrade=upgrade, user=user, altinstall=altinstall, default_pip=default_pip, verbosity=verbosity) def _bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Returns pip command status code. Note that calling this function will alter both sys.path and os.environ. """ if altinstall and default_pip: raise ValueError("Cannot use altinstall and default_pip together") sys.audit("ensurepip.bootstrap", root) _disable_pip_configuration_settings() # By default, installing pip and setuptools installs all of the # following scripts (X.Y == running Python version): # # pip, pipX, pipX.Y, easy_install, easy_install-X.Y # # pip 1.5+ allows ensurepip to request that some of those be left out if altinstall: # omit pip, pipX and easy_install os.environ["ENSUREPIP_OPTIONS"] = "altinstall" elif not default_pip: # omit pip and easy_install os.environ["ENSUREPIP_OPTIONS"] = "install" with tempfile.TemporaryDirectory() as tmpdir: # Put our bundled wheels into a temporary directory and construct the # additional paths that need added to sys.path additional_paths = [] for project, version, py_tag in _PROJECTS: wheel_name = _wheels[project][version] with open(os.path.join(_WHEEL_DIR, wheel_name), "rb") as sfp: with open(os.path.join(tmpdir, wheel_name), "wb") as fp: fp.write(sfp.read()) additional_paths.append(os.path.join(tmpdir, wheel_name)) # Construct the arguments to be passed to the pip command args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir] if root: args += ["--root", root] if upgrade: args += ["--upgrade"] if user: args += ["--user"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) def _uninstall_helper(*, verbosity=0): """Helper to support a clean default uninstall process on Windows Note that calling this function may alter os.environ. """ # Nothing to do if pip was never installed, or has been removed try: import pip except ImportError: return # If the pip version doesn't match the bundled one, leave it alone if pip.__version__ != _PIP_VERSION: msg = ("ensurepip will only uninstall a matching version " "({!r} installed, {!r} bundled)") print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) return _disable_pip_configuration_settings() # Construct the arguments to be passed to the pip command args = ["uninstall", "-y", "--disable-pip-version-check"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) def _main(argv=None): import argparse parser = argparse.ArgumentParser(prog="python -m ensurepip") parser.add_argument( "--version", action="version", version="pip {}".format(version()), help="Show the version of pip that is bundled with this Python.", ) parser.add_argument( "-v", "--verbose", action="count", default=0, dest="verbosity", help=("Give more output. Option is additive, and can be used up to 3 " "times."), ) parser.add_argument( "-U", "--upgrade", action="store_true", default=False, help="Upgrade pip and dependencies, even if already installed.", ) parser.add_argument( "--user", action="store_true", default=False, help="Install using the user scheme.", ) parser.add_argument( "--root", default=None, help="Install everything relative to this alternate root directory.", ) parser.add_argument( "--altinstall", action="store_true", default=False, help=("Make an alternate install, installing only the X.Y versioned " "scripts (Default: pipX, pipX.Y, easy_install-X.Y)."), ) parser.add_argument( "--default-pip", action="store_true", default=False, help=("Make a default pip install, installing the unqualified pip " "and easy_install in addition to the versioned scripts."), ) args = parser.parse_args(argv) return _bootstrap( root=args.root, upgrade=args.upgrade, user=args.user, verbosity=args.verbosity, altinstall=args.altinstall, default_pip=args.default_pip, ) usr/lib64/python3.6/pydoc_data/__init__.py000064400000000000152347642370014270 0ustar00lib64/python2.7/ctypes/macholib/__init__.py000064400000000232152347643600014441 0ustar00""" Enough Mach-O to make your head spin. See the relevant header files in /usr/include/mach-o And also Apple's documentation. """ __version__ = '1.0' usr/lib64/python3.6/site-packages/yaml/__init__.py000064400000022607152347653370015666 0ustar00 from .error import * from .tokens import * from .events import * from .nodes import * from .loader import * from .dumper import * __version__ = '3.12' try: from .cyaml import * __with_libyaml__ = True except ImportError: __with_libyaml__ = False import io def scan(stream, Loader=Loader): """ Scan a YAML stream and produce scanning tokens. """ loader = Loader(stream) try: while loader.check_token(): yield loader.get_token() finally: loader.dispose() def parse(stream, Loader=Loader): """ Parse a YAML stream and produce parsing events. """ loader = Loader(stream) try: while loader.check_event(): yield loader.get_event() finally: loader.dispose() def compose(stream, Loader=Loader): """ Parse the first YAML document in a stream and produce the corresponding representation tree. """ loader = Loader(stream) try: return loader.get_single_node() finally: loader.dispose() def compose_all(stream, Loader=Loader): """ Parse all YAML documents in a stream and produce corresponding representation trees. """ loader = Loader(stream) try: while loader.check_node(): yield loader.get_node() finally: loader.dispose() def load(stream, Loader=Loader): """ Parse the first YAML document in a stream and produce the corresponding Python object. """ loader = Loader(stream) try: return loader.get_single_data() finally: loader.dispose() def load_all(stream, Loader=Loader): """ Parse all YAML documents in a stream and produce corresponding Python objects. """ loader = Loader(stream) try: while loader.check_data(): yield loader.get_data() finally: loader.dispose() def safe_load(stream): """ Parse the first YAML document in a stream and produce the corresponding Python object. Resolve only basic YAML tags. """ return load(stream, SafeLoader) def safe_load_all(stream): """ Parse all YAML documents in a stream and produce corresponding Python objects. Resolve only basic YAML tags. """ return load_all(stream, SafeLoader) def emit(events, stream=None, Dumper=Dumper, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None): """ Emit YAML parsing events into a stream. If stream is None, return the produced string instead. """ getvalue = None if stream is None: stream = io.StringIO() getvalue = stream.getvalue dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break) try: for event in events: dumper.emit(event) finally: dumper.dispose() if getvalue: return getvalue() def serialize_all(nodes, stream=None, Dumper=Dumper, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, version=None, tags=None): """ Serialize a sequence of representation trees into a YAML stream. If stream is None, return the produced string instead. """ getvalue = None if stream is None: if encoding is None: stream = io.StringIO() else: stream = io.BytesIO() getvalue = stream.getvalue dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break, encoding=encoding, version=version, tags=tags, explicit_start=explicit_start, explicit_end=explicit_end) try: dumper.open() for node in nodes: dumper.serialize(node) dumper.close() finally: dumper.dispose() if getvalue: return getvalue() def serialize(node, stream=None, Dumper=Dumper, **kwds): """ Serialize a representation tree into a YAML stream. If stream is None, return the produced string instead. """ return serialize_all([node], stream, Dumper=Dumper, **kwds) def dump_all(documents, stream=None, Dumper=Dumper, default_style=None, default_flow_style=None, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, version=None, tags=None): """ Serialize a sequence of Python objects into a YAML stream. If stream is None, return the produced string instead. """ getvalue = None if stream is None: if encoding is None: stream = io.StringIO() else: stream = io.BytesIO() getvalue = stream.getvalue dumper = Dumper(stream, default_style=default_style, default_flow_style=default_flow_style, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break, encoding=encoding, version=version, tags=tags, explicit_start=explicit_start, explicit_end=explicit_end) try: dumper.open() for data in documents: dumper.represent(data) dumper.close() finally: dumper.dispose() if getvalue: return getvalue() def dump(data, stream=None, Dumper=Dumper, **kwds): """ Serialize a Python object into a YAML stream. If stream is None, return the produced string instead. """ return dump_all([data], stream, Dumper=Dumper, **kwds) def safe_dump_all(documents, stream=None, **kwds): """ Serialize a sequence of Python objects into a YAML stream. Produce only basic YAML tags. If stream is None, return the produced string instead. """ return dump_all(documents, stream, Dumper=SafeDumper, **kwds) def safe_dump(data, stream=None, **kwds): """ Serialize a Python object into a YAML stream. Produce only basic YAML tags. If stream is None, return the produced string instead. """ return dump_all([data], stream, Dumper=SafeDumper, **kwds) def add_implicit_resolver(tag, regexp, first=None, Loader=Loader, Dumper=Dumper): """ Add an implicit scalar detector. If an implicit scalar value matches the given regexp, the corresponding tag is assigned to the scalar. first is a sequence of possible initial characters or None. """ Loader.add_implicit_resolver(tag, regexp, first) Dumper.add_implicit_resolver(tag, regexp, first) def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper): """ Add a path based resolver for the given tag. A path is a list of keys that forms a path to a node in the representation tree. Keys can be string values, integers, or None. """ Loader.add_path_resolver(tag, path, kind) Dumper.add_path_resolver(tag, path, kind) def add_constructor(tag, constructor, Loader=Loader): """ Add a constructor for the given tag. Constructor is a function that accepts a Loader instance and a node object and produces the corresponding Python object. """ Loader.add_constructor(tag, constructor) def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader): """ Add a multi-constructor for the given tag prefix. Multi-constructor is called for a node if its tag starts with tag_prefix. Multi-constructor accepts a Loader instance, a tag suffix, and a node object and produces the corresponding Python object. """ Loader.add_multi_constructor(tag_prefix, multi_constructor) def add_representer(data_type, representer, Dumper=Dumper): """ Add a representer for the given type. Representer is a function accepting a Dumper instance and an instance of the given data type and producing the corresponding representation node. """ Dumper.add_representer(data_type, representer) def add_multi_representer(data_type, multi_representer, Dumper=Dumper): """ Add a representer for the given type. Multi-representer is a function accepting a Dumper instance and an instance of the given data type or subtype and producing the corresponding representation node. """ Dumper.add_multi_representer(data_type, multi_representer) class YAMLObjectMetaclass(type): """ The metaclass for YAMLObject. """ def __init__(cls, name, bases, kwds): super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds) if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None: cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml) cls.yaml_dumper.add_representer(cls, cls.to_yaml) class YAMLObject(metaclass=YAMLObjectMetaclass): """ An object that can dump itself to a YAML stream and load itself from a YAML stream. """ __slots__ = () # no direct instantiation, so allow immutable subclasses yaml_loader = Loader yaml_dumper = Dumper yaml_tag = None yaml_flow_style = None @classmethod def from_yaml(cls, loader, node): """ Convert a representation node to a Python object. """ return loader.construct_yaml_object(node, cls) @classmethod def to_yaml(cls, dumper, data): """ Convert a Python object to a representation node. """ return dumper.represent_yaml_object(cls.yaml_tag, data, cls, flow_style=cls.yaml_flow_style) lib64/python3.12/html/__init__.py000064400000011247152347672370012413 0ustar00""" General functions for HTML manipulation. """ import re as _re from html.entities import html5 as _html5 __all__ = ['escape', 'unescape'] def escape(s, quote=True): """ Replace special characters "&", "<" and ">" to HTML-safe sequences. If the optional flag quote is true (the default), the quotation mark characters, both double quote (") and single quote (') characters are also translated. """ s = s.replace("&", "&") # Must be done first! s = s.replace("<", "<") s = s.replace(">", ">") if quote: s = s.replace('"', """) s = s.replace('\'', "'") return s # see https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state _invalid_charrefs = { 0x00: '\ufffd', # REPLACEMENT CHARACTER 0x0d: '\r', # CARRIAGE RETURN 0x80: '\u20ac', # EURO SIGN 0x81: '\x81', # 0x82: '\u201a', # SINGLE LOW-9 QUOTATION MARK 0x83: '\u0192', # LATIN SMALL LETTER F WITH HOOK 0x84: '\u201e', # DOUBLE LOW-9 QUOTATION MARK 0x85: '\u2026', # HORIZONTAL ELLIPSIS 0x86: '\u2020', # DAGGER 0x87: '\u2021', # DOUBLE DAGGER 0x88: '\u02c6', # MODIFIER LETTER CIRCUMFLEX ACCENT 0x89: '\u2030', # PER MILLE SIGN 0x8a: '\u0160', # LATIN CAPITAL LETTER S WITH CARON 0x8b: '\u2039', # SINGLE LEFT-POINTING ANGLE QUOTATION MARK 0x8c: '\u0152', # LATIN CAPITAL LIGATURE OE 0x8d: '\x8d', # 0x8e: '\u017d', # LATIN CAPITAL LETTER Z WITH CARON 0x8f: '\x8f', # 0x90: '\x90', # 0x91: '\u2018', # LEFT SINGLE QUOTATION MARK 0x92: '\u2019', # RIGHT SINGLE QUOTATION MARK 0x93: '\u201c', # LEFT DOUBLE QUOTATION MARK 0x94: '\u201d', # RIGHT DOUBLE QUOTATION MARK 0x95: '\u2022', # BULLET 0x96: '\u2013', # EN DASH 0x97: '\u2014', # EM DASH 0x98: '\u02dc', # SMALL TILDE 0x99: '\u2122', # TRADE MARK SIGN 0x9a: '\u0161', # LATIN SMALL LETTER S WITH CARON 0x9b: '\u203a', # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 0x9c: '\u0153', # LATIN SMALL LIGATURE OE 0x9d: '\x9d', # 0x9e: '\u017e', # LATIN SMALL LETTER Z WITH CARON 0x9f: '\u0178', # LATIN CAPITAL LETTER Y WITH DIAERESIS } _invalid_codepoints = { # 0x0001 to 0x0008 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, # 0x000E to 0x001F 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, # 0x007F to 0x009F 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, # 0xFDD0 to 0xFDEF 0xfdd0, 0xfdd1, 0xfdd2, 0xfdd3, 0xfdd4, 0xfdd5, 0xfdd6, 0xfdd7, 0xfdd8, 0xfdd9, 0xfdda, 0xfddb, 0xfddc, 0xfddd, 0xfdde, 0xfddf, 0xfde0, 0xfde1, 0xfde2, 0xfde3, 0xfde4, 0xfde5, 0xfde6, 0xfde7, 0xfde8, 0xfde9, 0xfdea, 0xfdeb, 0xfdec, 0xfded, 0xfdee, 0xfdef, # others 0xb, 0xfffe, 0xffff, 0x1fffe, 0x1ffff, 0x2fffe, 0x2ffff, 0x3fffe, 0x3ffff, 0x4fffe, 0x4ffff, 0x5fffe, 0x5ffff, 0x6fffe, 0x6ffff, 0x7fffe, 0x7ffff, 0x8fffe, 0x8ffff, 0x9fffe, 0x9ffff, 0xafffe, 0xaffff, 0xbfffe, 0xbffff, 0xcfffe, 0xcffff, 0xdfffe, 0xdffff, 0xefffe, 0xeffff, 0xffffe, 0xfffff, 0x10fffe, 0x10ffff } def _replace_charref(s): s = s.group(1) if s[0] == '#': # numeric charref if s[1] in 'xX': num = int(s[2:].rstrip(';'), 16) else: num = int(s[1:].rstrip(';')) if num in _invalid_charrefs: return _invalid_charrefs[num] if 0xD800 <= num <= 0xDFFF or num > 0x10FFFF: return '\uFFFD' if num in _invalid_codepoints: return '' return chr(num) else: # named charref if s in _html5: return _html5[s] # find the longest matching name (as defined by the standard) for x in range(len(s)-1, 1, -1): if s[:x] in _html5: return _html5[s[:x]] + s[x:] else: return '&' + s _charref = _re.compile(r'&(#[0-9]+;?' r'|#[xX][0-9a-fA-F]+;?' r'|[^\t\n\f <&#;]{1,32};?)') def unescape(s): """ Convert all named and numeric character references (e.g. >, >, &x3e;) in the string s to the corresponding unicode characters. This function uses the rules defined by the HTML 5 standard for both valid and invalid character references, and the list of HTML 5 named character references defined in html.entities.html5. """ if '&' not in s: return s return _charref.sub(_replace_charref, s) lib64/python3.12/sqlite3/__init__.py000064400000004705152347705070013026 0ustar00# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. """ The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compliant interface to the SQLite library, and requires SQLite 3.7.15 or newer. To use the module, start by creating a database Connection object: import sqlite3 cx = sqlite3.connect("test.db") # test.db will be created or opened The special path name ":memory:" can be provided to connect to a transient in-memory database: cx = sqlite3.connect(":memory:") # connect to a database in RAM Once a connection has been established, create a Cursor object and call its execute() method to perform SQL queries: cu = cx.cursor() # create a table cu.execute("create table lang(name, first_appeared)") # insert values into a table cu.execute("insert into lang values (?, ?)", ("C", 1972)) # execute a query and iterate over the result for row in cu.execute("select * from lang"): print(row) cx.close() The sqlite3 module is written by Gerhard Häring . """ from sqlite3.dbapi2 import * from sqlite3.dbapi2 import (_deprecated_names, _deprecated_version_info, _deprecated_version) def __getattr__(name): if name in _deprecated_names: from warnings import warn warn(f"{name} is deprecated and will be removed in Python 3.14", DeprecationWarning, stacklevel=2) return globals()[f"_deprecated_{name}"] raise AttributeError(f"module {__name__!r} has no attribute {name!r}") lib64/python3.12/tkinter/__init__.py000064400000522160152347707750013131 0ustar00"""Wrapper functions for Tcl/Tk. Tkinter provides classes which allow the display, positioning and control of widgets. Toplevel widgets are Tk and Toplevel. Other widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox LabelFrame and PanedWindow. Properties of the widgets are specified with keyword arguments. Keyword arguments have the same name as the corresponding resource under Tk. Widgets are positioned with one of the geometry managers Place, Pack or Grid. These managers can be called with methods place, pack, grid available in every Widget. Actions are bound to events by resources (e.g. keyword argument command) or with the method bind. Example (Hello, World): import tkinter from tkinter.constants import * tk = tkinter.Tk() frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2) frame.pack(fill=BOTH,expand=1) label = tkinter.Label(frame, text="Hello, World") label.pack(fill=X, expand=1) button = tkinter.Button(frame,text="Exit",command=tk.destroy) button.pack(side=BOTTOM) tk.mainloop() """ import collections import enum import sys import types import _tkinter # If this fails your Python may not be configured for Tk TclError = _tkinter.TclError from tkinter.constants import * import re wantobjects = 1 _debug = False # set to True to print executed Tcl/Tk commands TkVersion = float(_tkinter.TK_VERSION) TclVersion = float(_tkinter.TCL_VERSION) READABLE = _tkinter.READABLE WRITABLE = _tkinter.WRITABLE EXCEPTION = _tkinter.EXCEPTION _magic_re = re.compile(r'([\\{}])') _space_re = re.compile(r'([\s])', re.ASCII) def _join(value): """Internal function.""" return ' '.join(map(_stringify, value)) def _stringify(value): """Internal function.""" if isinstance(value, (list, tuple)): if len(value) == 1: value = _stringify(value[0]) if _magic_re.search(value): value = '{%s}' % value else: value = '{%s}' % _join(value) else: if isinstance(value, bytes): value = str(value, 'latin1') else: value = str(value) if not value: value = '{}' elif _magic_re.search(value): # add '\' before special characters and spaces value = _magic_re.sub(r'\\\1', value) value = value.replace('\n', r'\n') value = _space_re.sub(r'\\\1', value) if value[0] == '"': value = '\\' + value elif value[0] == '"' or _space_re.search(value): value = '{%s}' % value return value def _flatten(seq): """Internal function.""" res = () for item in seq: if isinstance(item, (tuple, list)): res = res + _flatten(item) elif item is not None: res = res + (item,) return res try: _flatten = _tkinter._flatten except AttributeError: pass def _cnfmerge(cnfs): """Internal function.""" if isinstance(cnfs, dict): return cnfs elif isinstance(cnfs, (type(None), str)): return cnfs else: cnf = {} for c in _flatten(cnfs): try: cnf.update(c) except (AttributeError, TypeError) as msg: print("_cnfmerge: fallback due to:", msg) for k, v in c.items(): cnf[k] = v return cnf try: _cnfmerge = _tkinter._cnfmerge except AttributeError: pass def _splitdict(tk, v, cut_minus=True, conv=None): """Return a properly formatted dict built from Tcl list pairs. If cut_minus is True, the supposed '-' prefix will be removed from keys. If conv is specified, it is used to convert values. Tcl list is expected to contain an even number of elements. """ t = tk.splitlist(v) if len(t) % 2: raise RuntimeError('Tcl list representing a dict is expected ' 'to contain an even number of elements') it = iter(t) dict = {} for key, value in zip(it, it): key = str(key) if cut_minus and key[0] == '-': key = key[1:] if conv: value = conv(value) dict[key] = value return dict class _VersionInfoType(collections.namedtuple('_VersionInfoType', ('major', 'minor', 'micro', 'releaselevel', 'serial'))): def __str__(self): if self.releaselevel == 'final': return f'{self.major}.{self.minor}.{self.micro}' else: return f'{self.major}.{self.minor}{self.releaselevel[0]}{self.serial}' def _parse_version(version): import re m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', version) major, minor, releaselevel, serial = m.groups() major, minor, serial = int(major), int(minor), int(serial) if releaselevel == '.': micro = serial serial = 0 releaselevel = 'final' else: micro = 0 releaselevel = {'a': 'alpha', 'b': 'beta'}[releaselevel] return _VersionInfoType(major, minor, micro, releaselevel, serial) @enum._simple_enum(enum.StrEnum) class EventType: KeyPress = '2' Key = KeyPress KeyRelease = '3' ButtonPress = '4' Button = ButtonPress ButtonRelease = '5' Motion = '6' Enter = '7' Leave = '8' FocusIn = '9' FocusOut = '10' Keymap = '11' # undocumented Expose = '12' GraphicsExpose = '13' # undocumented NoExpose = '14' # undocumented Visibility = '15' Create = '16' Destroy = '17' Unmap = '18' Map = '19' MapRequest = '20' Reparent = '21' Configure = '22' ConfigureRequest = '23' Gravity = '24' ResizeRequest = '25' Circulate = '26' CirculateRequest = '27' Property = '28' SelectionClear = '29' # undocumented SelectionRequest = '30' # undocumented Selection = '31' # undocumented Colormap = '32' ClientMessage = '33' # undocumented Mapping = '34' # undocumented VirtualEvent = '35' # undocumented Activate = '36' Deactivate = '37' MouseWheel = '38' class Event: """Container for the properties of an event. Instances of this type are generated if one of the following events occurs: KeyPress, KeyRelease - for keyboard events ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, Colormap, Gravity, Reparent, Property, Destroy, Activate, Deactivate - for window events. If a callback function for one of these events is registered using bind, bind_all, bind_class, or tag_bind, the callback is called with an Event as first argument. It will have the following attributes (in braces are the event types for which the attribute is valid): serial - serial number of event num - mouse button pressed (ButtonPress, ButtonRelease) focus - whether the window has the focus (Enter, Leave) height - height of the exposed window (Configure, Expose) width - width of the exposed window (Configure, Expose) keycode - keycode of the pressed key (KeyPress, KeyRelease) state - state of the event as a number (ButtonPress, ButtonRelease, Enter, KeyPress, KeyRelease, Leave, Motion) state - state as a string (Visibility) time - when the event occurred x - x-position of the mouse y - y-position of the mouse x_root - x-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) y_root - y-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) char - pressed character (KeyPress, KeyRelease) send_event - see X/Windows documentation keysym - keysym of the event as a string (KeyPress, KeyRelease) keysym_num - keysym of the event as a number (KeyPress, KeyRelease) type - type of the event as a number widget - widget in which the event occurred delta - delta of wheel movement (MouseWheel) """ def __repr__(self): attrs = {k: v for k, v in self.__dict__.items() if v != '??'} if not self.char: del attrs['char'] elif self.char != '??': attrs['char'] = repr(self.char) if not getattr(self, 'send_event', True): del attrs['send_event'] if self.state == 0: del attrs['state'] elif isinstance(self.state, int): state = self.state mods = ('Shift', 'Lock', 'Control', 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Button1', 'Button2', 'Button3', 'Button4', 'Button5') s = [] for i, n in enumerate(mods): if state & (1 << i): s.append(n) state = state & ~((1<< len(mods)) - 1) if state or not s: s.append(hex(state)) attrs['state'] = '|'.join(s) if self.delta == 0: del attrs['delta'] # widget usually is known # serial and time are not very interesting # keysym_num duplicates keysym # x_root and y_root mostly duplicate x and y keys = ('send_event', 'state', 'keysym', 'keycode', 'char', 'num', 'delta', 'focus', 'x', 'y', 'width', 'height') return '<%s event%s>' % ( getattr(self.type, 'name', self.type), ''.join(' %s=%s' % (k, attrs[k]) for k in keys if k in attrs) ) _support_default_root = True _default_root = None def NoDefaultRoot(): """Inhibit setting of default root window. Call this function to inhibit that the first instance of Tk is used for windows without an explicit parent window. """ global _support_default_root, _default_root _support_default_root = False # Delete, so any use of _default_root will immediately raise an exception. # Rebind before deletion, so repeated calls will not fail. _default_root = None del _default_root def _get_default_root(what=None): if not _support_default_root: raise RuntimeError("No master specified and tkinter is " "configured to not support default root") if _default_root is None: if what: raise RuntimeError(f"Too early to {what}: no default root window") root = Tk() assert _default_root is root return _default_root def _get_temp_root(): global _support_default_root if not _support_default_root: raise RuntimeError("No master specified and tkinter is " "configured to not support default root") root = _default_root if root is None: assert _support_default_root _support_default_root = False root = Tk() _support_default_root = True assert _default_root is None root.withdraw() root._temporary = True return root def _destroy_temp_root(master): if getattr(master, '_temporary', False): try: master.destroy() except TclError: pass def _tkerror(err): """Internal function.""" pass def _exit(code=0): """Internal function. Calling it will raise the exception SystemExit.""" try: code = int(code) except ValueError: pass raise SystemExit(code) _varnum = 0 class Variable: """Class to define value holders for e.g. buttons. Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations that constrain the type of the value returned from get().""" _default = "" _tk = None _tclCommands = None def __init__(self, master=None, value=None, name=None): """Construct a variable MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ # check for type of NAME parameter to override weird error message # raised from Modules/_tkinter.c:SetVar like: # TypeError: setvar() takes exactly 3 arguments (2 given) if name is not None and not isinstance(name, str): raise TypeError("name must be a string") global _varnum if master is None: master = _get_default_root('create variable') self._root = master._root() self._tk = master.tk if name: self._name = name else: self._name = 'PY_VAR' + repr(_varnum) _varnum += 1 if value is not None: self.initialize(value) elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)): self.initialize(self._default) def __del__(self): """Unset the variable in Tcl.""" if self._tk is None: return if self._tk.getboolean(self._tk.call("info", "exists", self._name)): self._tk.globalunsetvar(self._name) if self._tclCommands is not None: for name in self._tclCommands: self._tk.deletecommand(name) self._tclCommands = None def __str__(self): """Return the name of the variable in Tcl.""" return self._name def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, value) initialize = set def get(self): """Return value of variable.""" return self._tk.globalgetvar(self._name) def _register(self, callback): f = CallWrapper(callback, None, self._root).__call__ cbname = repr(id(f)) try: callback = callback.__func__ except AttributeError: pass try: cbname = cbname + callback.__name__ except AttributeError: pass self._tk.createcommand(cbname, f) if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(cbname) return cbname def trace_add(self, mode, callback): """Define a trace callback for the variable. Mode is one of "read", "write", "unset", or a list or tuple of such strings. Callback must be a function which is called when the variable is read, written or unset. Return the name of the callback. """ cbname = self._register(callback) self._tk.call('trace', 'add', 'variable', self._name, mode, (cbname,)) return cbname def trace_remove(self, mode, cbname): """Delete the trace callback for a variable. Mode is one of "read", "write", "unset" or a list or tuple of such strings. Must be same as were specified in trace_add(). cbname is the name of the callback returned from trace_add(). """ self._tk.call('trace', 'remove', 'variable', self._name, mode, cbname) for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_info(self): """Return all trace callback information.""" splitlist = self._tk.splitlist return [(splitlist(k), v) for k, v in map(splitlist, splitlist(self._tk.call('trace', 'info', 'variable', self._name)))] def trace_variable(self, mode, callback): """Define a trace callback for the variable. MODE is one of "r", "w", "u" for read, write, undefine. CALLBACK must be a function which is called when the variable is read, written or undefined. Return the name of the callback. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_add() instead. """ # TODO: Add deprecation warning cbname = self._register(callback) self._tk.call("trace", "variable", self._name, mode, cbname) return cbname trace = trace_variable def trace_vdelete(self, mode, cbname): """Delete the trace callback for a variable. MODE is one of "r", "w", "u" for read, write, undefine. CBNAME is the name of the callback returned from trace_variable or trace. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_remove() instead. """ # TODO: Add deprecation warning self._tk.call("trace", "vdelete", self._name, mode, cbname) cbname = self._tk.splitlist(cbname)[0] for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_vinfo(self): """Return all trace callback information. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_info() instead. """ # TODO: Add deprecation warning return [self._tk.splitlist(x) for x in self._tk.splitlist( self._tk.call("trace", "vinfo", self._name))] def __eq__(self, other): if not isinstance(other, Variable): return NotImplemented return (self._name == other._name and self.__class__.__name__ == other.__class__.__name__ and self._tk == other._tk) class StringVar(Variable): """Value holder for strings variables.""" _default = "" def __init__(self, master=None, value=None, name=None): """Construct a string variable. MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return value of variable as string.""" value = self._tk.globalgetvar(self._name) if isinstance(value, str): return value return str(value) class IntVar(Variable): """Value holder for integer variables.""" _default = 0 def __init__(self, master=None, value=None, name=None): """Construct an integer variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as an integer.""" value = self._tk.globalgetvar(self._name) try: return self._tk.getint(value) except (TypeError, TclError): return int(self._tk.getdouble(value)) class DoubleVar(Variable): """Value holder for float variables.""" _default = 0.0 def __init__(self, master=None, value=None, name=None): """Construct a float variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0.0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as a float.""" return self._tk.getdouble(self._tk.globalgetvar(self._name)) class BooleanVar(Variable): """Value holder for boolean variables.""" _default = False def __init__(self, master=None, value=None, name=None): """Construct a boolean variable. MASTER can be given as master widget. VALUE is an optional value (defaults to False) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, self._tk.getboolean(value)) initialize = set def get(self): """Return the value of the variable as a bool.""" try: return self._tk.getboolean(self._tk.globalgetvar(self._name)) except TclError: raise ValueError("invalid literal for getboolean()") def mainloop(n=0): """Run the main loop of Tcl.""" _get_default_root('run the main loop').tk.mainloop(n) getint = int getdouble = float def getboolean(s): """Convert Tcl object to True or False.""" try: return _get_default_root('use getboolean()').tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") # Methods defined on both toplevel and interior widgets class Misc: """Internal class. Base class which defines methods common for interior widgets.""" # used for generating child widget names _last_child_ids = None # XXX font command? _tclCommands = None def destroy(self): """Internal function. Delete all Tcl commands created for this widget in the Tcl interpreter.""" if self._tclCommands is not None: for name in self._tclCommands: self.tk.deletecommand(name) self._tclCommands = None def deletecommand(self, name): """Internal function. Delete the Tcl command provided in NAME.""" self.tk.deletecommand(name) try: self._tclCommands.remove(name) except ValueError: pass def tk_strictMotif(self, boolean=None): """Set Tcl internal variable, whether the look and feel should adhere to Motif. A parameter of 1 means adhere to Motif (e.g. no color change if mouse passes over slider). Returns the set value.""" return self.tk.getboolean(self.tk.call( 'set', 'tk_strictMotif', boolean)) def tk_bisque(self): """Change the color scheme to light brown as used in Tk 3.6 and before.""" self.tk.call('tk_bisque') def tk_setPalette(self, *args, **kw): """Set a new color scheme for all widget elements. A single color as argument will cause that all colors of Tk widget elements are derived from this. Alternatively several keyword parameters and its associated colors can be given. The following keywords are valid: activeBackground, foreground, selectColor, activeForeground, highlightBackground, selectBackground, background, highlightColor, selectForeground, disabledForeground, insertBackground, troughColor.""" self.tk.call(('tk_setPalette',) + _flatten(args) + _flatten(list(kw.items()))) def wait_variable(self, name='PY_VAR'): """Wait until the variable is modified. A parameter of type IntVar, StringVar, DoubleVar or BooleanVar must be given.""" self.tk.call('tkwait', 'variable', name) waitvar = wait_variable # XXX b/w compat def wait_window(self, window=None): """Wait until a WIDGET is destroyed. If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'window', window._w) def wait_visibility(self, window=None): """Wait until the visibility of a WIDGET changes (e.g. it appears). If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'visibility', window._w) def setvar(self, name='PY_VAR', value='1'): """Set Tcl variable NAME to VALUE.""" self.tk.setvar(name, value) def getvar(self, name='PY_VAR'): """Return value of Tcl variable NAME.""" return self.tk.getvar(name) def getint(self, s): try: return self.tk.getint(s) except TclError as exc: raise ValueError(str(exc)) def getdouble(self, s): try: return self.tk.getdouble(s) except TclError as exc: raise ValueError(str(exc)) def getboolean(self, s): """Return a boolean value for Tcl boolean values true and false given as parameter.""" try: return self.tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") def focus_set(self): """Direct input focus to this widget. If the application currently does not have the focus this widget will get the focus if the application gets the focus through the window manager.""" self.tk.call('focus', self._w) focus = focus_set # XXX b/w compat? def focus_force(self): """Direct input focus to this widget even if the application does not have the focus. Use with caution!""" self.tk.call('focus', '-force', self._w) def focus_get(self): """Return the widget which has currently the focus in the application. Use focus_displayof to allow working with several displays. Return None if application does not have the focus.""" name = self.tk.call('focus') if name == 'none' or not name: return None return self._nametowidget(name) def focus_displayof(self): """Return the widget which has currently the focus on the display where this widget is located. Return None if the application does not have the focus.""" name = self.tk.call('focus', '-displayof', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def focus_lastfor(self): """Return the widget which would have the focus if top level for this widget gets the focus from the window manager.""" name = self.tk.call('focus', '-lastfor', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def tk_focusFollowsMouse(self): """The widget under mouse will get automatically focus. Can not be disabled easily.""" self.tk.call('tk_focusFollowsMouse') def tk_focusNext(self): """Return the next widget in the focus order which follows widget which has currently the focus. The focus order first goes to the next child, then to the children of the child recursively and then to the next sibling which is higher in the stacking order. A widget is omitted if it has the takefocus resource set to 0.""" name = self.tk.call('tk_focusNext', self._w) if not name: return None return self._nametowidget(name) def tk_focusPrev(self): """Return previous widget in the focus order. See tk_focusNext for details.""" name = self.tk.call('tk_focusPrev', self._w) if not name: return None return self._nametowidget(name) def after(self, ms, func=None, *args): """Call function once after given time. MS specifies the time in milliseconds. FUNC gives the function which shall be called. Additional parameters are given as parameters to the function call. Return identifier to cancel scheduling with after_cancel.""" if func is None: # I'd rather use time.sleep(ms*0.001) self.tk.call('after', ms) return None else: def callit(): try: func(*args) finally: try: self.deletecommand(name) except TclError: pass try: callit.__name__ = func.__name__ except AttributeError: # Required for callable classes (bpo-44404) callit.__name__ = type(func).__name__ name = self._register(callit) return self.tk.call('after', ms, name) def after_idle(self, func, *args): """Call FUNC once if the Tcl main loop has no event to process. Return an identifier to cancel the scheduling with after_cancel.""" return self.after('idle', func, *args) def after_cancel(self, id): """Cancel scheduling of function identified with ID. Identifier returned by after or after_idle must be given as first parameter. """ if not id: raise ValueError('id must be a valid identifier returned from ' 'after or after_idle') try: data = self.tk.call('after', 'info', id) script = self.tk.splitlist(data)[0] self.deletecommand(script) except TclError: pass self.tk.call('after', 'cancel', id) def bell(self, displayof=0): """Ring a display's bell.""" self.tk.call(('bell',) + self._displayof(displayof)) # Clipboard handling: def clipboard_get(self, **kw): """Retrieve data from the clipboard on window's display. The window keyword defaults to the root window of the Tkinter application. The type keyword specifies the form in which the data is to be returned and should be an atom name such as STRING or FILE_NAME. Type defaults to STRING, except on X11, where the default is to try UTF8_STRING and fall back to STRING. This command is equivalent to: selection_get(CLIPBOARD) """ if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('clipboard', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('clipboard', 'get') + self._options(kw)) def clipboard_clear(self, **kw): """Clear the data in the Tk clipboard. A widget specified for the optional displayof keyword argument specifies the target display.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'clear') + self._options(kw)) def clipboard_append(self, string, **kw): """Append STRING to the Tk clipboard. A widget specified at the optional displayof keyword argument specifies the target display. The clipboard can be retrieved with selection_get.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'append') + self._options(kw) + ('--', string)) # XXX grab current w/o window argument def grab_current(self): """Return widget which has currently the grab in this application or None.""" name = self.tk.call('grab', 'current', self._w) if not name: return None return self._nametowidget(name) def grab_release(self): """Release grab for this widget if currently set.""" self.tk.call('grab', 'release', self._w) def grab_set(self): """Set grab for this widget. A grab directs all events to this and descendant widgets in the application.""" self.tk.call('grab', 'set', self._w) def grab_set_global(self): """Set global grab for this widget. A global grab directs all events to this and descendant widgets on the display. Use with caution - other applications do not get events anymore.""" self.tk.call('grab', 'set', '-global', self._w) def grab_status(self): """Return None, "local" or "global" if this widget has no, a local or a global grab.""" status = self.tk.call('grab', 'status', self._w) if status == 'none': status = None return status def option_add(self, pattern, value, priority = None): """Set a VALUE (second parameter) for an option PATTERN (first parameter). An optional third parameter gives the numeric priority (defaults to 80).""" self.tk.call('option', 'add', pattern, value, priority) def option_clear(self): """Clear the option database. It will be reloaded if option_add is called.""" self.tk.call('option', 'clear') def option_get(self, name, className): """Return the value for an option NAME for this widget with CLASSNAME. Values with higher priority override lower values.""" return self.tk.call('option', 'get', self._w, name, className) def option_readfile(self, fileName, priority = None): """Read file FILENAME into the option database. An optional second parameter gives the numeric priority.""" self.tk.call('option', 'readfile', fileName, priority) def selection_clear(self, **kw): """Clear the current X selection.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('selection', 'clear') + self._options(kw)) def selection_get(self, **kw): """Return the contents of the current X selection. A keyword parameter selection specifies the name of the selection and defaults to PRIMARY. A keyword parameter displayof specifies a widget on the display to use. A keyword parameter type specifies the form of data to be fetched, defaulting to STRING except on X11, where UTF8_STRING is tried before STRING.""" if 'displayof' not in kw: kw['displayof'] = self._w if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('selection', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('selection', 'get') + self._options(kw)) def selection_handle(self, command, **kw): """Specify a function COMMAND to call if the X selection owned by this widget is queried by another application. This function must return the contents of the selection. The function will be called with the arguments OFFSET and LENGTH which allows the chunking of very long selections. The following keyword parameters can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" name = self._register(command) self.tk.call(('selection', 'handle') + self._options(kw) + (self._w, name)) def selection_own(self, **kw): """Become owner of X selection. A keyword parameter selection specifies the name of the selection (default PRIMARY).""" self.tk.call(('selection', 'own') + self._options(kw) + (self._w,)) def selection_own_get(self, **kw): """Return owner of X selection. The following keyword parameter can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" if 'displayof' not in kw: kw['displayof'] = self._w name = self.tk.call(('selection', 'own') + self._options(kw)) if not name: return None return self._nametowidget(name) def send(self, interp, cmd, *args): """Send Tcl command CMD to different interpreter INTERP to be executed.""" return self.tk.call(('send', interp, cmd) + args) def lower(self, belowThis=None): """Lower this widget in the stacking order.""" self.tk.call('lower', self._w, belowThis) def tkraise(self, aboveThis=None): """Raise this widget in the stacking order.""" self.tk.call('raise', self._w, aboveThis) lift = tkraise def info_patchlevel(self): """Returns the exact version of the Tcl library.""" patchlevel = self.tk.call('info', 'patchlevel') return _parse_version(patchlevel) def winfo_atom(self, name, displayof=0): """Return integer which represents atom NAME.""" args = ('winfo', 'atom') + self._displayof(displayof) + (name,) return self.tk.getint(self.tk.call(args)) def winfo_atomname(self, id, displayof=0): """Return name of atom with identifier ID.""" args = ('winfo', 'atomname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_cells(self): """Return number of cells in the colormap for this widget.""" return self.tk.getint( self.tk.call('winfo', 'cells', self._w)) def winfo_children(self): """Return a list of all widgets which are children of this widget.""" result = [] for child in self.tk.splitlist( self.tk.call('winfo', 'children', self._w)): try: # Tcl sometimes returns extra windows, e.g. for # menus; those need to be skipped result.append(self._nametowidget(child)) except KeyError: pass return result def winfo_class(self): """Return window class name of this widget.""" return self.tk.call('winfo', 'class', self._w) def winfo_colormapfull(self): """Return True if at the last color request the colormap was full.""" return self.tk.getboolean( self.tk.call('winfo', 'colormapfull', self._w)) def winfo_containing(self, rootX, rootY, displayof=0): """Return the widget which is at the root coordinates ROOTX, ROOTY.""" args = ('winfo', 'containing') \ + self._displayof(displayof) + (rootX, rootY) name = self.tk.call(args) if not name: return None return self._nametowidget(name) def winfo_depth(self): """Return the number of bits per pixel.""" return self.tk.getint(self.tk.call('winfo', 'depth', self._w)) def winfo_exists(self): """Return true if this widget exists.""" return self.tk.getint( self.tk.call('winfo', 'exists', self._w)) def winfo_fpixels(self, number): """Return the number of pixels for the given distance NUMBER (e.g. "3c") as float.""" return self.tk.getdouble(self.tk.call( 'winfo', 'fpixels', self._w, number)) def winfo_geometry(self): """Return geometry string for this widget in the form "widthxheight+X+Y".""" return self.tk.call('winfo', 'geometry', self._w) def winfo_height(self): """Return height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'height', self._w)) def winfo_id(self): """Return identifier ID for this widget.""" return int(self.tk.call('winfo', 'id', self._w), 0) def winfo_interps(self, displayof=0): """Return the name of all Tcl interpreters for this display.""" args = ('winfo', 'interps') + self._displayof(displayof) return self.tk.splitlist(self.tk.call(args)) def winfo_ismapped(self): """Return true if this widget is mapped.""" return self.tk.getint( self.tk.call('winfo', 'ismapped', self._w)) def winfo_manager(self): """Return the window manager name for this widget.""" return self.tk.call('winfo', 'manager', self._w) def winfo_name(self): """Return the name of this widget.""" return self.tk.call('winfo', 'name', self._w) def winfo_parent(self): """Return the name of the parent of this widget.""" return self.tk.call('winfo', 'parent', self._w) def winfo_pathname(self, id, displayof=0): """Return the pathname of the widget given by ID.""" if isinstance(id, int): id = hex(id) args = ('winfo', 'pathname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_pixels(self, number): """Rounded integer value of winfo_fpixels.""" return self.tk.getint( self.tk.call('winfo', 'pixels', self._w, number)) def winfo_pointerx(self): """Return the x coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointerx', self._w)) def winfo_pointerxy(self): """Return a tuple of x and y coordinates of the pointer on the root window.""" return self._getints( self.tk.call('winfo', 'pointerxy', self._w)) def winfo_pointery(self): """Return the y coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointery', self._w)) def winfo_reqheight(self): """Return requested height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqheight', self._w)) def winfo_reqwidth(self): """Return requested width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqwidth', self._w)) def winfo_rgb(self, color): """Return a tuple of integer RGB values in range(65536) for color in this widget.""" return self._getints( self.tk.call('winfo', 'rgb', self._w, color)) def winfo_rootx(self): """Return x coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rootx', self._w)) def winfo_rooty(self): """Return y coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rooty', self._w)) def winfo_screen(self): """Return the screen name of this widget.""" return self.tk.call('winfo', 'screen', self._w) def winfo_screencells(self): """Return the number of the cells in the colormap of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screencells', self._w)) def winfo_screendepth(self): """Return the number of bits per pixel of the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screendepth', self._w)) def winfo_screenheight(self): """Return the number of pixels of the height of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenheight', self._w)) def winfo_screenmmheight(self): """Return the number of pixels of the height of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmheight', self._w)) def winfo_screenmmwidth(self): """Return the number of pixels of the width of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmwidth', self._w)) def winfo_screenvisual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the default colormodel of this screen.""" return self.tk.call('winfo', 'screenvisual', self._w) def winfo_screenwidth(self): """Return the number of pixels of the width of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenwidth', self._w)) def winfo_server(self): """Return information of the X-Server of the screen of this widget in the form "XmajorRminor vendor vendorVersion".""" return self.tk.call('winfo', 'server', self._w) def winfo_toplevel(self): """Return the toplevel widget of this widget.""" return self._nametowidget(self.tk.call( 'winfo', 'toplevel', self._w)) def winfo_viewable(self): """Return true if the widget and all its higher ancestors are mapped.""" return self.tk.getint( self.tk.call('winfo', 'viewable', self._w)) def winfo_visual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the colormodel of this widget.""" return self.tk.call('winfo', 'visual', self._w) def winfo_visualid(self): """Return the X identifier for the visual for this widget.""" return self.tk.call('winfo', 'visualid', self._w) def winfo_visualsavailable(self, includeids=False): """Return a list of all visuals available for the screen of this widget. Each item in the list consists of a visual name (see winfo_visual), a depth and if includeids is true is given also the X identifier.""" data = self.tk.call('winfo', 'visualsavailable', self._w, 'includeids' if includeids else None) data = [self.tk.splitlist(x) for x in self.tk.splitlist(data)] return [self.__winfo_parseitem(x) for x in data] def __winfo_parseitem(self, t): """Internal function.""" return t[:1] + tuple(map(self.__winfo_getint, t[1:])) def __winfo_getint(self, x): """Internal function.""" return int(x, 0) def winfo_vrootheight(self): """Return the height of the virtual root window associated with this widget in pixels. If there is no virtual root window return the height of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootheight', self._w)) def winfo_vrootwidth(self): """Return the width of the virtual root window associated with this widget in pixel. If there is no virtual root window return the width of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootwidth', self._w)) def winfo_vrootx(self): """Return the x offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrootx', self._w)) def winfo_vrooty(self): """Return the y offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrooty', self._w)) def winfo_width(self): """Return the width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'width', self._w)) def winfo_x(self): """Return the x coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'x', self._w)) def winfo_y(self): """Return the y coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'y', self._w)) def update(self): """Enter event loop until all pending events have been processed by Tcl.""" self.tk.call('update') def update_idletasks(self): """Enter event loop until all idle callbacks have been called. This will update the display of windows but not process events caused by the user.""" self.tk.call('update', 'idletasks') def bindtags(self, tagList=None): """Set or get the list of bindtags for this widget. With no argument return the list of all bindtags associated with this widget. With a list of strings as argument the bindtags are set to this list. The bindtags determine in which order events are processed (see bind).""" if tagList is None: return self.tk.splitlist( self.tk.call('bindtags', self._w)) else: self.tk.call('bindtags', self._w, tagList) def _bind(self, what, sequence, func, add, needcleanup=1): """Internal function.""" if isinstance(func, str): self.tk.call(what + (sequence, func)) elif func: funcid = self._register(func, self._substitute, needcleanup) cmd = ('%sif {"[%s %s]" == "break"} break\n' % (add and '+' or '', funcid, self._subst_format_str)) self.tk.call(what + (sequence, cmd)) return funcid elif sequence: return self.tk.call(what + (sequence,)) else: return self.tk.splitlist(self.tk.call(what)) def bind(self, sequence=None, func=None, add=None): """Bind to this widget at event SEQUENCE a call to function FUNC. SEQUENCE is a string of concatenated event patterns. An event pattern is of the form where MODIFIER is one of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, B3, Alt, Button4, B4, Double, Button5, B5 Triple, Mod1, M1. TYPE is one of Activate, Enter, Map, ButtonPress, Button, Expose, Motion, ButtonRelease FocusIn, MouseWheel, Circulate, FocusOut, Property, Colormap, Gravity Reparent, Configure, KeyPress, Key, Unmap, Deactivate, KeyRelease Visibility, Destroy, Leave and DETAIL is the button number for ButtonPress, ButtonRelease and DETAIL is the Keysym for KeyPress and KeyRelease. Examples are for pressing Control and mouse button 1 or for pressing A and the Alt key (KeyPress can be omitted). An event pattern can also be a virtual event of the form <> where AString can be arbitrary. This event can be generated by event_generate. If events are concatenated they must appear shortly after each other. FUNC will be called if the event sequence occurs with an instance of Event as argument. If the return value of FUNC is "break" no further bound function is invoked. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. Bind will return an identifier to allow deletion of the bound function with unbind without memory leak. If FUNC or SEQUENCE is omitted the bound function or list of bound events are returned.""" return self._bind(('bind', self._w), sequence, func, add) def unbind(self, sequence, funcid=None): """Unbind for this widget the event SEQUENCE. If FUNCID is given, only unbind the function identified with FUNCID and also delete the corresponding Tcl command. Otherwise destroy the current binding for SEQUENCE, leaving SEQUENCE unbound. """ self._unbind(('bind', self._w, sequence), funcid) def _unbind(self, what, funcid=None): if funcid is None: self.tk.call(*what, '') else: lines = self.tk.call(what).split('\n') prefix = f'if {{"[{funcid} ' keep = '\n'.join(line for line in lines if not line.startswith(prefix)) if not keep.strip(): keep = '' self.tk.call(*what, keep) self.deletecommand(funcid) def bind_all(self, sequence=None, func=None, add=None): """Bind to all widgets at an event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._root()._bind(('bind', 'all'), sequence, func, add, True) def unbind_all(self, sequence): """Unbind for all widgets for event SEQUENCE all functions.""" self._root()._unbind(('bind', 'all', sequence)) def bind_class(self, className, sequence=None, func=None, add=None): """Bind to widgets with bindtag CLASSNAME at event SEQUENCE a call of function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._root()._bind(('bind', className), sequence, func, add, True) def unbind_class(self, className, sequence): """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self._root()._unbind(('bind', className, sequence)) def mainloop(self, n=0): """Call the mainloop of Tk.""" self.tk.mainloop(n) def quit(self): """Quit the Tcl interpreter. All widgets will be destroyed.""" self.tk.quit() def _getints(self, string): """Internal function.""" if string: return tuple(map(self.tk.getint, self.tk.splitlist(string))) def _getdoubles(self, string): """Internal function.""" if string: return tuple(map(self.tk.getdouble, self.tk.splitlist(string))) def _getboolean(self, string): """Internal function.""" if string: return self.tk.getboolean(string) def _displayof(self, displayof): """Internal function.""" if displayof: return ('-displayof', displayof) if displayof is None: return ('-displayof', self._w) return () @property def _windowingsystem(self): """Internal function.""" try: return self._root()._windowingsystem_cached except AttributeError: ws = self._root()._windowingsystem_cached = \ self.tk.call('tk', 'windowingsystem') return ws def _options(self, cnf, kw = None): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) else: cnf = _cnfmerge(cnf) res = () for k, v in cnf.items(): if v is not None: if k[-1] == '_': k = k[:-1] if callable(v): v = self._register(v) elif isinstance(v, (tuple, list)): nv = [] for item in v: if isinstance(item, int): nv.append(str(item)) elif isinstance(item, str): nv.append(_stringify(item)) else: break else: v = ' '.join(nv) res = res + ('-'+k, v) return res def nametowidget(self, name): """Return the Tkinter instance of a widget identified by its Tcl name NAME.""" name = str(name).split('.') w = self if not name[0]: w = w._root() name = name[1:] for n in name: if not n: break w = w.children[n] return w _nametowidget = nametowidget def _register(self, func, subst=None, needcleanup=1): """Return a newly created Tcl function. If this function is called, the Python function FUNC will be executed. An optional function SUBST can be given which will be executed before FUNC.""" f = CallWrapper(func, subst, self).__call__ name = repr(id(f)) try: func = func.__func__ except AttributeError: pass try: name = name + func.__name__ except AttributeError: pass self.tk.createcommand(name, f) if needcleanup: if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(name) return name register = _register def _root(self): """Internal function.""" w = self while w.master is not None: w = w.master return w _subst_format = ('%#', '%b', '%f', '%h', '%k', '%s', '%t', '%w', '%x', '%y', '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') _subst_format_str = " ".join(_subst_format) def _substitute(self, *args): """Internal function.""" if len(args) != len(self._subst_format): return args getboolean = self.tk.getboolean getint = self.tk.getint def getint_event(s): """Tk changed behavior in 8.4.2, returning "??" rather more often.""" try: return getint(s) except (ValueError, TclError): return s nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args # Missing: (a, c, d, m, o, v, B, R) e = Event() # serial field: valid for all events # number of button: ButtonPress and ButtonRelease events only # height field: Configure, ConfigureRequest, Create, # ResizeRequest, and Expose events only # keycode field: KeyPress and KeyRelease events only # time field: "valid for events that contain a time field" # width field: Configure, ConfigureRequest, Create, ResizeRequest, # and Expose events only # x field: "valid for events that contain an x field" # y field: "valid for events that contain a y field" # keysym as decimal: KeyPress and KeyRelease events only # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, # KeyRelease, and Motion events e.serial = getint(nsign) e.num = getint_event(b) try: e.focus = getboolean(f) except TclError: pass e.height = getint_event(h) e.keycode = getint_event(k) e.state = getint_event(s) e.time = getint_event(t) e.width = getint_event(w) e.x = getint_event(x) e.y = getint_event(y) e.char = A try: e.send_event = getboolean(E) except TclError: pass e.keysym = K e.keysym_num = getint_event(N) try: e.type = EventType(T) except ValueError: e.type = T try: e.widget = self._nametowidget(W) except KeyError: e.widget = W e.x_root = getint_event(X) e.y_root = getint_event(Y) try: e.delta = getint(D) except (ValueError, TclError): e.delta = 0 return (e,) def _report_exception(self): """Internal function.""" exc, val, tb = sys.exc_info() root = self._root() root.report_callback_exception(exc, val, tb) def _getconfigure(self, *args): """Call Tcl configure command and return the result as a dict.""" cnf = {} for x in self.tk.splitlist(self.tk.call(*args)): x = self.tk.splitlist(x) cnf[x[0][1:]] = (x[0][1:],) + x[1:] return cnf def _getconfigure1(self, *args): x = self.tk.splitlist(self.tk.call(*args)) return (x[0][1:],) + x[1:] def _configure(self, cmd, cnf, kw): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) elif cnf: cnf = _cnfmerge(cnf) if cnf is None: return self._getconfigure(_flatten((self._w, cmd))) if isinstance(cnf, str): return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) # These used to be defined in Widget: def configure(self, cnf=None, **kw): """Configure resources of a widget. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method keys. """ return self._configure('configure', cnf, kw) config = configure def cget(self, key): """Return the resource value for a KEY given as string.""" return self.tk.call(self._w, 'cget', '-' + key) __getitem__ = cget def __setitem__(self, key, value): self.configure({key: value}) def keys(self): """Return a list of all resource names of this widget.""" splitlist = self.tk.splitlist return [splitlist(x)[0][1:] for x in splitlist(self.tk.call(self._w, 'configure'))] def __str__(self): """Return the window path name of this widget.""" return self._w def __repr__(self): return '<%s.%s object %s>' % ( self.__class__.__module__, self.__class__.__qualname__, self._w) # Pack methods that apply to the master _noarg_ = ['_noarg_'] def pack_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'pack', 'propagate', self._w)) else: self.tk.call('pack', 'propagate', self._w, flag) propagate = pack_propagate def pack_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call('pack', 'slaves', self._w))] slaves = pack_slaves # Place method that applies to the master def place_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call( 'place', 'slaves', self._w))] # Grid methods that apply to the master def grid_anchor(self, anchor=None): # new in Tk 8.5 """The anchor value controls how to place the grid within the master when no row/column has any weight. The default anchor is nw.""" self.tk.call('grid', 'anchor', self._w, anchor) anchor = grid_anchor def grid_bbox(self, column=None, row=None, col2=None, row2=None): """Return a tuple of integer coordinates for the bounding box of this widget controlled by the geometry manager grid. If COLUMN, ROW is given the bounding box applies from the cell with row and column 0 to the specified cell. If COL2 and ROW2 are given the bounding box starts at that cell. The returned integers specify the offset of the upper left corner in the master widget and the width and height. """ args = ('grid', 'bbox', self._w) if column is not None and row is not None: args = args + (column, row) if col2 is not None and row2 is not None: args = args + (col2, row2) return self._getints(self.tk.call(*args)) or None bbox = grid_bbox def _gridconvvalue(self, value): if isinstance(value, (str, _tkinter.Tcl_Obj)): try: svalue = str(value) if not svalue: return None elif '.' in svalue: return self.tk.getdouble(svalue) else: return self.tk.getint(svalue) except (ValueError, TclError): pass return value def _grid_configure(self, command, index, cnf, kw): """Internal function.""" if isinstance(cnf, str) and not kw: if cnf[-1:] == '_': cnf = cnf[:-1] if cnf[:1] != '-': cnf = '-'+cnf options = (cnf,) else: options = self._options(cnf, kw) if not options: return _splitdict( self.tk, self.tk.call('grid', command, self._w, index), conv=self._gridconvvalue) res = self.tk.call( ('grid', command, self._w, index) + options) if len(options) == 1: return self._gridconvvalue(res) def grid_columnconfigure(self, index, cnf={}, **kw): """Configure column INDEX of a grid. Valid resources are minsize (minimum size of the column), weight (how much does additional space propagate to this column) and pad (how much space to let additionally).""" return self._grid_configure('columnconfigure', index, cnf, kw) columnconfigure = grid_columnconfigure def grid_location(self, x, y): """Return a tuple of column and row which identify the cell at which the pixel at position X and Y inside the master widget is located.""" return self._getints( self.tk.call( 'grid', 'location', self._w, x, y)) or None def grid_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given, the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'grid', 'propagate', self._w)) else: self.tk.call('grid', 'propagate', self._w, flag) def grid_rowconfigure(self, index, cnf={}, **kw): """Configure row INDEX of a grid. Valid resources are minsize (minimum size of the row), weight (how much does additional space propagate to this row) and pad (how much space to let additionally).""" return self._grid_configure('rowconfigure', index, cnf, kw) rowconfigure = grid_rowconfigure def grid_size(self): """Return a tuple of the number of column and rows in the grid.""" return self._getints( self.tk.call('grid', 'size', self._w)) or None size = grid_size def grid_slaves(self, row=None, column=None): """Return a list of all slaves of this widget in its packing order.""" args = () if row is not None: args = args + ('-row', row) if column is not None: args = args + ('-column', column) return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call( ('grid', 'slaves', self._w) + args))] # Support for the "event" command, new in Tk 4.2. # By Case Roole. def event_add(self, virtual, *sequences): """Bind a virtual event VIRTUAL (of the form <>) to an event SEQUENCE such that the virtual event is triggered whenever SEQUENCE occurs.""" args = ('event', 'add', virtual) + sequences self.tk.call(args) def event_delete(self, virtual, *sequences): """Unbind a virtual event VIRTUAL from SEQUENCE.""" args = ('event', 'delete', virtual) + sequences self.tk.call(args) def event_generate(self, sequence, **kw): """Generate an event SEQUENCE. Additional keyword arguments specify parameter of the event (e.g. x, y, rootx, rooty).""" args = ('event', 'generate', self._w, sequence) for k, v in kw.items(): args = args + ('-%s' % k, str(v)) self.tk.call(args) def event_info(self, virtual=None): """Return a list of all virtual events or the information about the SEQUENCE bound to the virtual event VIRTUAL.""" return self.tk.splitlist( self.tk.call('event', 'info', virtual)) # Image related commands def image_names(self): """Return a list of all existing image names.""" return self.tk.splitlist(self.tk.call('image', 'names')) def image_types(self): """Return a list of all available image types (e.g. photo bitmap).""" return self.tk.splitlist(self.tk.call('image', 'types')) class CallWrapper: """Internal class. Stores function to call when some user defined Tcl function is called e.g. after an event occurred.""" def __init__(self, func, subst, widget): """Store FUNC, SUBST and WIDGET as members.""" self.func = func self.subst = subst self.widget = widget def __call__(self, *args): """Apply first function SUBST to arguments, than FUNC.""" try: if self.subst: args = self.subst(*args) return self.func(*args) except SystemExit: raise except: self.widget._report_exception() class XView: """Mix-in class for querying and changing the horizontal position of a widget's window.""" def xview(self, *args): """Query and change the horizontal position of the view.""" res = self.tk.call(self._w, 'xview', *args) if not args: return self._getdoubles(res) def xview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total width of the canvas is off-screen to the left.""" self.tk.call(self._w, 'xview', 'moveto', fraction) def xview_scroll(self, number, what): """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'xview', 'scroll', number, what) class YView: """Mix-in class for querying and changing the vertical position of a widget's window.""" def yview(self, *args): """Query and change the vertical position of the view.""" res = self.tk.call(self._w, 'yview', *args) if not args: return self._getdoubles(res) def yview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total height of the canvas is off-screen to the top.""" self.tk.call(self._w, 'yview', 'moveto', fraction) def yview_scroll(self, number, what): """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'yview', 'scroll', number, what) class Wm: """Provides functions for the communication with the window manager.""" def wm_aspect(self, minNumer=None, minDenom=None, maxNumer=None, maxDenom=None): """Instruct the window manager to set the aspect ratio (width/height) of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple of the actual values if no argument is given.""" return self._getints( self.tk.call('wm', 'aspect', self._w, minNumer, minDenom, maxNumer, maxDenom)) aspect = wm_aspect def wm_attributes(self, *args): """This subcommand returns or sets platform specific attributes The first form returns a list of the platform specific flags and their values. The second form returns the value for the specific option. The third form sets one or more of the values. The values are as follows: On Windows, -disabled gets or sets whether the window is in a disabled state. -toolwindow gets or sets the style of the window to toolwindow (as defined in the MSDN). -topmost gets or sets whether this is a topmost window (displays above all other windows). On Macintosh, XXXXX On Unix, there are currently no special attribute values. """ args = ('wm', 'attributes', self._w) + args return self.tk.call(args) attributes = wm_attributes def wm_client(self, name=None): """Store NAME in WM_CLIENT_MACHINE property of this widget. Return current value.""" return self.tk.call('wm', 'client', self._w, name) client = wm_client def wm_colormapwindows(self, *wlist): """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property of this widget. This list contains windows whose colormaps differ from their parents. Return current list of widgets if WLIST is empty.""" if len(wlist) > 1: wlist = (wlist,) # Tk needs a list of windows here args = ('wm', 'colormapwindows', self._w) + wlist if wlist: self.tk.call(args) else: return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call(args))] colormapwindows = wm_colormapwindows def wm_command(self, value=None): """Store VALUE in WM_COMMAND property. It is the command which shall be used to invoke the application. Return current command if VALUE is None.""" return self.tk.call('wm', 'command', self._w, value) command = wm_command def wm_deiconify(self): """Deiconify this widget. If it was never mapped it will not be mapped. On Windows it will raise this widget and give it the focus.""" return self.tk.call('wm', 'deiconify', self._w) deiconify = wm_deiconify def wm_focusmodel(self, model=None): """Set focus model to MODEL. "active" means that this widget will claim the focus itself, "passive" means that the window manager shall give the focus. Return current focus model if MODEL is None.""" return self.tk.call('wm', 'focusmodel', self._w, model) focusmodel = wm_focusmodel def wm_forget(self, window): # new in Tk 8.5 """The window will be unmapped from the screen and will no longer be managed by wm. toplevel windows will be treated like frame windows once they are no longer managed by wm, however, the menu option configuration will be remembered and the menus will return once the widget is managed again.""" self.tk.call('wm', 'forget', window) forget = wm_forget def wm_frame(self): """Return identifier for decorative frame of this widget if present.""" return self.tk.call('wm', 'frame', self._w) frame = wm_frame def wm_geometry(self, newGeometry=None): """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return current value if None is given.""" return self.tk.call('wm', 'geometry', self._w, newGeometry) geometry = wm_geometry def wm_grid(self, baseWidth=None, baseHeight=None, widthInc=None, heightInc=None): """Instruct the window manager that this widget shall only be resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the number of grid units requested in Tk_GeometryRequest.""" return self._getints(self.tk.call( 'wm', 'grid', self._w, baseWidth, baseHeight, widthInc, heightInc)) grid = wm_grid def wm_group(self, pathName=None): """Set the group leader widgets for related widgets to PATHNAME. Return the group leader of this widget if None is given.""" return self.tk.call('wm', 'group', self._w, pathName) group = wm_group def wm_iconbitmap(self, bitmap=None, default=None): """Set bitmap for the iconified widget to BITMAP. Return the bitmap if None is given. Under Windows, the DEFAULT parameter can be used to set the icon for the widget and any descendants that don't have an icon set explicitly. DEFAULT can be the relative path to a .ico file (example: root.iconbitmap(default='myicon.ico') ). See Tk documentation for more information.""" if default is not None: return self.tk.call('wm', 'iconbitmap', self._w, '-default', default) else: return self.tk.call('wm', 'iconbitmap', self._w, bitmap) iconbitmap = wm_iconbitmap def wm_iconify(self): """Display widget as icon.""" return self.tk.call('wm', 'iconify', self._w) iconify = wm_iconify def wm_iconmask(self, bitmap=None): """Set mask for the icon bitmap of this widget. Return the mask if None is given.""" return self.tk.call('wm', 'iconmask', self._w, bitmap) iconmask = wm_iconmask def wm_iconname(self, newName=None): """Set the name of the icon for this widget. Return the name if None is given.""" return self.tk.call('wm', 'iconname', self._w, newName) iconname = wm_iconname def wm_iconphoto(self, default=False, *args): # new in Tk 8.5 """Sets the titlebar icon for this window based on the named photo images passed through args. If default is True, this is applied to all future created toplevels as well. The data in the images is taken as a snapshot at the time of invocation. If the images are later changed, this is not reflected to the titlebar icons. Multiple images are accepted to allow different images sizes to be provided. The window manager may scale provided icons to an appropriate size. On Windows, the images are packed into a Windows icon structure. This will override an icon specified to wm_iconbitmap, and vice versa. On X, the images are arranged into the _NET_WM_ICON X property, which most modern window managers support. An icon specified by wm_iconbitmap may exist simultaneously. On Macintosh, this currently does nothing.""" if default: self.tk.call('wm', 'iconphoto', self._w, "-default", *args) else: self.tk.call('wm', 'iconphoto', self._w, *args) iconphoto = wm_iconphoto def wm_iconposition(self, x=None, y=None): """Set the position of the icon of this widget to X and Y. Return a tuple of the current values of X and X if None is given.""" return self._getints(self.tk.call( 'wm', 'iconposition', self._w, x, y)) iconposition = wm_iconposition def wm_iconwindow(self, pathName=None): """Set widget PATHNAME to be displayed instead of icon. Return the current value if None is given.""" return self.tk.call('wm', 'iconwindow', self._w, pathName) iconwindow = wm_iconwindow def wm_manage(self, widget): # new in Tk 8.5 """The widget specified will become a stand alone top-level window. The window will be decorated with the window managers title bar, etc.""" self.tk.call('wm', 'manage', widget) manage = wm_manage def wm_maxsize(self, width=None, height=None): """Set max WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'maxsize', self._w, width, height)) maxsize = wm_maxsize def wm_minsize(self, width=None, height=None): """Set min WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'minsize', self._w, width, height)) minsize = wm_minsize def wm_overrideredirect(self, boolean=None): """Instruct the window manager to ignore this widget if BOOLEAN is given with 1. Return the current value if None is given.""" return self._getboolean(self.tk.call( 'wm', 'overrideredirect', self._w, boolean)) overrideredirect = wm_overrideredirect def wm_positionfrom(self, who=None): """Instruct the window manager that the position of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'positionfrom', self._w, who) positionfrom = wm_positionfrom def wm_protocol(self, name=None, func=None): """Bind function FUNC to command NAME for this widget. Return the function bound to NAME if None is given. NAME could be e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" if callable(func): command = self._register(func) else: command = func return self.tk.call( 'wm', 'protocol', self._w, name, command) protocol = wm_protocol def wm_resizable(self, width=None, height=None): """Instruct the window manager whether this width can be resized in WIDTH or HEIGHT. Both values are boolean values.""" return self.tk.call('wm', 'resizable', self._w, width, height) resizable = wm_resizable def wm_sizefrom(self, who=None): """Instruct the window manager that the size of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'sizefrom', self._w, who) sizefrom = wm_sizefrom def wm_state(self, newstate=None): """Query or set the state of this widget as one of normal, icon, iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" return self.tk.call('wm', 'state', self._w, newstate) state = wm_state def wm_title(self, string=None): """Set the title of this widget.""" return self.tk.call('wm', 'title', self._w, string) title = wm_title def wm_transient(self, master=None): """Instruct the window manager that this widget is transient with regard to widget MASTER.""" return self.tk.call('wm', 'transient', self._w, master) transient = wm_transient def wm_withdraw(self): """Withdraw this widget from the screen such that it is unmapped and forgotten by the window manager. Re-draw it with wm_deiconify.""" return self.tk.call('wm', 'withdraw', self._w) withdraw = wm_withdraw class Tk(Misc, Wm): """Toplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.""" _w = '.' def __init__(self, screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None): """Return a new top level widget on screen SCREENNAME. A new Tcl interpreter will be created. BASENAME will be used for the identification of the profile file (see readprofile). It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME is the name of the widget class.""" self.master = None self.children = {} self._tkloaded = False # to avoid recursions in the getattr code in case of failure, we # ensure that self.tk is always _something_. self.tk = None if baseName is None: import os baseName = os.path.basename(sys.argv[0]) baseName, ext = os.path.splitext(baseName) if ext not in ('.py', '.pyc'): baseName = baseName + ext interactive = False self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) if _debug: self.tk.settrace(_print_command) if useTk: self._loadtk() if not sys.flags.ignore_environment: # Issue #16248: Honor the -E flag to avoid code injection. self.readprofile(baseName, className) def loadtk(self): if not self._tkloaded: self.tk.loadtk() self._loadtk() def _loadtk(self): self._tkloaded = True global _default_root # Version sanity checks tk_version = self.tk.getvar('tk_version') if tk_version != _tkinter.TK_VERSION: raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)" % (_tkinter.TK_VERSION, tk_version)) # Under unknown circumstances, tcl_version gets coerced to float tcl_version = str(self.tk.getvar('tcl_version')) if tcl_version != _tkinter.TCL_VERSION: raise RuntimeError("tcl.h version (%s) doesn't match libtcl.a version (%s)" \ % (_tkinter.TCL_VERSION, tcl_version)) # Create and register the tkerror and exit commands # We need to inline parts of _register here, _ register # would register differently-named commands. if self._tclCommands is None: self._tclCommands = [] self.tk.createcommand('tkerror', _tkerror) self.tk.createcommand('exit', _exit) self._tclCommands.append('tkerror') self._tclCommands.append('exit') if _support_default_root and _default_root is None: _default_root = self self.protocol("WM_DELETE_WINDOW", self.destroy) def destroy(self): """Destroy this and all descendants widgets. This will end the application of this Tcl interpreter.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) Misc.destroy(self) global _default_root if _support_default_root and _default_root is self: _default_root = None def readprofile(self, baseName, className): """Internal function. It reads .BASENAME.tcl and .CLASSNAME.tcl into the Tcl Interpreter and calls exec on the contents of .BASENAME.py and .CLASSNAME.py if such a file exists in the home directory.""" import os if 'HOME' in os.environ: home = os.environ['HOME'] else: home = os.curdir class_tcl = os.path.join(home, '.%s.tcl' % className) class_py = os.path.join(home, '.%s.py' % className) base_tcl = os.path.join(home, '.%s.tcl' % baseName) base_py = os.path.join(home, '.%s.py' % baseName) dir = {'self': self} exec('from tkinter import *', dir) if os.path.isfile(class_tcl): self.tk.call('source', class_tcl) if os.path.isfile(class_py): exec(open(class_py).read(), dir) if os.path.isfile(base_tcl): self.tk.call('source', base_tcl) if os.path.isfile(base_py): exec(open(base_py).read(), dir) def report_callback_exception(self, exc, val, tb): """Report callback exception on sys.stderr. Applications may want to override this internal function, and should when sys.stderr is None.""" import traceback print("Exception in Tkinter callback", file=sys.stderr) sys.last_exc = val sys.last_type = exc sys.last_value = val sys.last_traceback = tb traceback.print_exception(exc, val, tb) def __getattr__(self, attr): "Delegate attribute access to the interpreter object" return getattr(self.tk, attr) def _print_command(cmd, *, file=sys.stderr): # Print executed Tcl/Tk commands. assert isinstance(cmd, tuple) cmd = _join(cmd) print(cmd, file=file) # Ideally, the classes Pack, Place and Grid disappear, the # pack/place/grid methods are defined on the Widget class, and # everybody uses w.pack_whatever(...) instead of Pack.whatever(w, # ...), with pack(), place() and grid() being short for # pack_configure(), place_configure() and grid_columnconfigure(), and # forget() being short for pack_forget(). As a practical matter, I'm # afraid that there is too much code out there that may be using the # Pack, Place or Grid class, so I leave them intact -- but only as # backwards compatibility features. Also note that those methods that # take a master as argument (e.g. pack_propagate) have been moved to # the Misc class (which now incorporates all methods common between # toplevel and interior widgets). Again, for compatibility, these are # copied into the Pack, Place or Grid class. def Tcl(screenName=None, baseName=None, className='Tk', useTk=False): return Tk(screenName, baseName, className, useTk) class Pack: """Geometry manager Pack. Base class to use the methods pack_* in every widget.""" def pack_configure(self, cnf={}, **kw): """Pack a widget in the parent widget. Use as options: after=widget - pack it after you have packed widget anchor=NSEW (or subset) - position widget according to given direction before=widget - pack it before you will pack widget expand=bool - expand widget if parent size grows fill=NONE or X or Y or BOTH - fill widget if widget grows in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. """ self.tk.call( ('pack', 'configure', self._w) + self._options(cnf, kw)) pack = configure = config = pack_configure def pack_forget(self): """Unmap this widget and do not use it for the packing order.""" self.tk.call('pack', 'forget', self._w) forget = pack_forget def pack_info(self): """Return information about the packing options for this widget.""" d = _splitdict(self.tk, self.tk.call('pack', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = pack_info propagate = pack_propagate = Misc.pack_propagate slaves = pack_slaves = Misc.pack_slaves class Place: """Geometry manager Place. Base class to use the methods place_* in every widget.""" def place_configure(self, cnf={}, **kw): """Place a widget in the parent widget. Use as options: in=master - master relative to which the widget is placed in_=master - see 'in' option description x=amount - locate anchor of this widget at position x of master y=amount - locate anchor of this widget at position y of master relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge) rely=amount - locate anchor of this widget between 0.0 and 1.0 relative to height of master (1.0 is bottom edge) anchor=NSEW (or subset) - position anchor according to given direction width=amount - width of this widget in pixel height=amount - height of this widget in pixel relwidth=amount - width of this widget between 0.0 and 1.0 relative to width of master (1.0 is the same width as the master) relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master) bordermode="inside" or "outside" - whether to take border width of master widget into account """ self.tk.call( ('place', 'configure', self._w) + self._options(cnf, kw)) place = configure = config = place_configure def place_forget(self): """Unmap this widget.""" self.tk.call('place', 'forget', self._w) forget = place_forget def place_info(self): """Return information about the placing options for this widget.""" d = _splitdict(self.tk, self.tk.call('place', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = place_info slaves = place_slaves = Misc.place_slaves class Grid: """Geometry manager Grid. Base class to use the methods grid_* in every widget.""" # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) def grid_configure(self, cnf={}, **kw): """Position a widget in the parent widget in a grid. Use as options: column=number - use cell identified with given column (starting with 0) columnspan=number - this widget will span several columns in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction row=number - use cell identified with given row (starting with 0) rowspan=number - this widget will span several rows sticky=NSEW - if cell is larger on which sides will this widget stick to the cell boundary """ self.tk.call( ('grid', 'configure', self._w) + self._options(cnf, kw)) grid = configure = config = grid_configure bbox = grid_bbox = Misc.grid_bbox columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure def grid_forget(self): """Unmap this widget.""" self.tk.call('grid', 'forget', self._w) forget = grid_forget def grid_remove(self): """Unmap this widget but remember the grid options.""" self.tk.call('grid', 'remove', self._w) def grid_info(self): """Return information about the options for positioning this widget in a grid.""" d = _splitdict(self.tk, self.tk.call('grid', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = grid_info location = grid_location = Misc.grid_location propagate = grid_propagate = Misc.grid_propagate rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure size = grid_size = Misc.grid_size slaves = grid_slaves = Misc.grid_slaves class BaseWidget(Misc): """Internal class.""" def _setup(self, master, cnf): """Internal function. Sets up information about children.""" if master is None: master = _get_default_root() self.master = master self.tk = master.tk name = None if 'name' in cnf: name = cnf['name'] del cnf['name'] if not name: name = self.__class__.__name__.lower() if name[-1].isdigit(): name += "!" # Avoid duplication when calculating names below if master._last_child_ids is None: master._last_child_ids = {} count = master._last_child_ids.get(name, 0) + 1 master._last_child_ids[name] = count if count == 1: name = '!%s' % (name,) else: name = '!%s%d' % (name, count) self._name = name if master._w=='.': self._w = '.' + name else: self._w = master._w + '.' + name self.children = {} if self._name in self.master.children: self.master.children[self._name].destroy() self.master.children[self._name] = self def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): """Construct a widget with the parent widget MASTER, a name WIDGETNAME and appropriate options.""" if kw: cnf = _cnfmerge((cnf, kw)) self.widgetName = widgetName self._setup(master, cnf) if self._tclCommands is None: self._tclCommands = [] classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)] for k, v in classes: del cnf[k] self.tk.call( (widgetName, self._w) + extra + self._options(cnf)) for k, v in classes: k.configure(self, v) def destroy(self): """Destroy this and all descendants widgets.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) if self._name in self.master.children: del self.master.children[self._name] Misc.destroy(self) def _do(self, name, args=()): # XXX Obsolete -- better use self.tk.call directly! return self.tk.call((self._w, name) + args) class Widget(BaseWidget, Pack, Place, Grid): """Internal class. Base class for a widget which can be positioned with the geometry managers Pack, Place or Grid.""" pass class Toplevel(BaseWidget, Wm): """Toplevel widget, e.g. for dialogs.""" def __init__(self, master=None, cnf={}, **kw): """Construct a toplevel widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, menu, relief, screen, takefocus, use, visual, width.""" if kw: cnf = _cnfmerge((cnf, kw)) extra = () for wmkey in ['screen', 'class_', 'class', 'visual', 'colormap']: if wmkey in cnf: val = cnf[wmkey] # TBD: a hack needed because some keys # are not valid as keyword arguments if wmkey[-1] == '_': opt = '-'+wmkey[:-1] else: opt = '-'+wmkey extra = extra + (opt, val) del cnf[wmkey] BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) root = self._root() self.iconname(root.iconname()) self.title(root.title()) self.protocol("WM_DELETE_WINDOW", self.destroy) class Button(Widget): """Button widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a button widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, repeatdelay, repeatinterval, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS command, compound, default, height, overrelief, state, width """ Widget.__init__(self, master, 'button', cnf, kw) def flash(self): """Flash the button. This is accomplished by redisplaying the button several times, alternating between active and normal colors. At the end of the flash the button is left in the same normal/active state as when the command was invoked. This command is ignored if the button's state is disabled. """ self.tk.call(self._w, 'flash') def invoke(self): """Invoke the command associated with the button. The return value is the return value from the command, or an empty string if there is no command associated with the button. This command is ignored if the button's state is disabled. """ return self.tk.call(self._w, 'invoke') class Canvas(Widget, XView, YView): """Canvas widget to display graphical elements like lines or text.""" def __init__(self, master=None, cnf={}, **kw): """Construct a canvas widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, closeenough, confine, cursor, height, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, offset, relief, scrollregion, selectbackground, selectborderwidth, selectforeground, state, takefocus, width, xscrollcommand, xscrollincrement, yscrollcommand, yscrollincrement.""" Widget.__init__(self, master, 'canvas', cnf, kw) def addtag(self, *args): """Internal function.""" self.tk.call((self._w, 'addtag') + args) def addtag_above(self, newtag, tagOrId): """Add tag NEWTAG to all items above TAGORID.""" self.addtag(newtag, 'above', tagOrId) def addtag_all(self, newtag): """Add tag NEWTAG to all items.""" self.addtag(newtag, 'all') def addtag_below(self, newtag, tagOrId): """Add tag NEWTAG to all items below TAGORID.""" self.addtag(newtag, 'below', tagOrId) def addtag_closest(self, newtag, x, y, halo=None, start=None): """Add tag NEWTAG to item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.""" self.addtag(newtag, 'closest', x, y, halo, start) def addtag_enclosed(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items in the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'enclosed', x1, y1, x2, y2) def addtag_overlapping(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'overlapping', x1, y1, x2, y2) def addtag_withtag(self, newtag, tagOrId): """Add tag NEWTAG to all items with TAGORID.""" self.addtag(newtag, 'withtag', tagOrId) def bbox(self, *args): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses all items with tags specified as arguments.""" return self._getints( self.tk.call((self._w, 'bbox') + args)) or None def tag_unbind(self, tagOrId, sequence, funcid=None): """Unbind for all items with TAGORID for event SEQUENCE the function identified with FUNCID.""" self._unbind((self._w, 'bind', tagOrId, sequence), funcid) def tag_bind(self, tagOrId, sequence=None, func=None, add=None): """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'bind', tagOrId), sequence, func, add) def canvasx(self, screenx, gridspacing=None): """Return the canvas x coordinate of pixel position SCREENX rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasx', screenx, gridspacing)) def canvasy(self, screeny, gridspacing=None): """Return the canvas y coordinate of pixel position SCREENY rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasy', screeny, gridspacing)) def coords(self, *args): """Return a list of coordinates for the item given in ARGS.""" args = _flatten(args) return [self.tk.getdouble(x) for x in self.tk.splitlist( self.tk.call((self._w, 'coords') + args))] def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) """Internal function.""" args = _flatten(args) cnf = args[-1] if isinstance(cnf, (dict, tuple)): args = args[:-1] else: cnf = {} return self.tk.getint(self.tk.call( self._w, 'create', itemType, *(args + self._options(cnf, kw)))) def create_arc(self, *args, **kw): """Create arc shaped region with coordinates x1,y1,x2,y2.""" return self._create('arc', args, kw) def create_bitmap(self, *args, **kw): """Create bitmap with coordinates x1,y1.""" return self._create('bitmap', args, kw) def create_image(self, *args, **kw): """Create image item with coordinates x1,y1.""" return self._create('image', args, kw) def create_line(self, *args, **kw): """Create line with coordinates x1,y1,...,xn,yn.""" return self._create('line', args, kw) def create_oval(self, *args, **kw): """Create oval with coordinates x1,y1,x2,y2.""" return self._create('oval', args, kw) def create_polygon(self, *args, **kw): """Create polygon with coordinates x1,y1,...,xn,yn.""" return self._create('polygon', args, kw) def create_rectangle(self, *args, **kw): """Create rectangle with coordinates x1,y1,x2,y2.""" return self._create('rectangle', args, kw) def create_text(self, *args, **kw): """Create text with coordinates x1,y1.""" return self._create('text', args, kw) def create_window(self, *args, **kw): """Create window with coordinates x1,y1,x2,y2.""" return self._create('window', args, kw) def dchars(self, *args): """Delete characters of text items identified by tag or id in ARGS (possibly several times) from FIRST to LAST character (including).""" self.tk.call((self._w, 'dchars') + args) def delete(self, *args): """Delete items identified by all tag or ids contained in ARGS.""" self.tk.call((self._w, 'delete') + args) def dtag(self, *args): """Delete tag or id given as last arguments in ARGS from items identified by first argument in ARGS.""" self.tk.call((self._w, 'dtag') + args) def find(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'find') + args)) or () def find_above(self, tagOrId): """Return items above TAGORID.""" return self.find('above', tagOrId) def find_all(self): """Return all items.""" return self.find('all') def find_below(self, tagOrId): """Return all items below TAGORID.""" return self.find('below', tagOrId) def find_closest(self, x, y, halo=None, start=None): """Return item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.""" return self.find('closest', x, y, halo, start) def find_enclosed(self, x1, y1, x2, y2): """Return all items in rectangle defined by X1,Y1,X2,Y2.""" return self.find('enclosed', x1, y1, x2, y2) def find_overlapping(self, x1, y1, x2, y2): """Return all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" return self.find('overlapping', x1, y1, x2, y2) def find_withtag(self, tagOrId): """Return all items with TAGORID.""" return self.find('withtag', tagOrId) def focus(self, *args): """Set focus to the first item specified in ARGS.""" return self.tk.call((self._w, 'focus') + args) def gettags(self, *args): """Return tags associated with the first item specified in ARGS.""" return self.tk.splitlist( self.tk.call((self._w, 'gettags') + args)) def icursor(self, *args): """Set cursor at position POS in the item identified by TAGORID. In ARGS TAGORID must be first.""" self.tk.call((self._w, 'icursor') + args) def index(self, *args): """Return position of cursor as integer in item specified in ARGS.""" return self.tk.getint(self.tk.call((self._w, 'index') + args)) def insert(self, *args): """Insert TEXT in item TAGORID at position POS. ARGS must be TAGORID POS TEXT.""" self.tk.call((self._w, 'insert') + args) def itemcget(self, tagOrId, option): """Return the resource value for an OPTION for item TAGORID.""" return self.tk.call( (self._w, 'itemcget') + (tagOrId, '-'+option)) def itemconfigure(self, tagOrId, cnf=None, **kw): """Configure resources of an item TAGORID. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. """ return self._configure(('itemconfigure', tagOrId), cnf, kw) itemconfig = itemconfigure # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, # so the preferred name for them is tag_lower, tag_raise # (similar to tag_bind, and similar to the Text widget); # unfortunately can't delete the old ones yet (maybe in 1.6) def tag_lower(self, *args): """Lower an item TAGORID given in ARGS (optional below another item).""" self.tk.call((self._w, 'lower') + args) lower = tag_lower def move(self, *args): """Move an item TAGORID given in ARGS.""" self.tk.call((self._w, 'move') + args) def moveto(self, tagOrId, x='', y=''): """Move the items given by TAGORID in the canvas coordinate space so that the first coordinate pair of the bottommost item with tag TAGORID is located at position (X,Y). X and Y may be the empty string, in which case the corresponding coordinate will be unchanged. All items matching TAGORID remain in the same positions relative to each other.""" self.tk.call(self._w, 'moveto', tagOrId, x, y) def postscript(self, cnf={}, **kw): """Print the contents of the canvas to a postscript file. Valid options: colormap, colormode, file, fontmap, height, pageanchor, pageheight, pagewidth, pagex, pagey, rotate, width, x, y.""" return self.tk.call((self._w, 'postscript') + self._options(cnf, kw)) def tag_raise(self, *args): """Raise an item TAGORID given in ARGS (optional above another item).""" self.tk.call((self._w, 'raise') + args) lift = tkraise = tag_raise def scale(self, *args): """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" self.tk.call((self._w, 'scale') + args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y, gain=10): """Adjust the view of the canvas to GAIN times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y, gain) def select_adjust(self, tagOrId, index): """Adjust the end of the selection near the cursor of an item TAGORID to index.""" self.tk.call(self._w, 'select', 'adjust', tagOrId, index) def select_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'select', 'clear') def select_from(self, tagOrId, index): """Set the fixed end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'from', tagOrId, index) def select_item(self): """Return the item which has the selection.""" return self.tk.call(self._w, 'select', 'item') or None def select_to(self, tagOrId, index): """Set the variable end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'to', tagOrId, index) def type(self, tagOrId): """Return the type of the item TAGORID.""" return self.tk.call(self._w, 'type', tagOrId) or None _checkbutton_count = 0 class Checkbutton(Widget): """Checkbutton widget which is either in on- or off-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a checkbutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, offvalue, onvalue, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, variable, width, wraplength.""" Widget.__init__(self, master, 'checkbutton', cnf, kw) def _setup(self, master, cnf): # Because Checkbutton defaults to a variable with the same name as # the widget, Checkbutton default names must be globally unique, # not just unique within the parent widget. if not cnf.get('name'): global _checkbutton_count name = self.__class__.__name__.lower() _checkbutton_count += 1 # To avoid collisions with ttk.Checkbutton, use the different # name template. cnf['name'] = f'!{name}-{_checkbutton_count}' super()._setup(master, cnf) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') def toggle(self): """Toggle the button.""" self.tk.call(self._w, 'toggle') class Entry(Widget, XView): """Entry widget which allows displaying simple text.""" def __init__(self, master=None, cnf={}, **kw): """Construct an entry widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, invalidcommand, invcmd, justify, relief, selectbackground, selectborderwidth, selectforeground, show, state, takefocus, textvariable, validate, validatecommand, vcmd, width, xscrollcommand.""" Widget.__init__(self, master, 'entry', cnf, kw) def delete(self, first, last=None): """Delete text from FIRST to LAST (not included).""" self.tk.call(self._w, 'delete', first, last) def get(self): """Return the text.""" return self.tk.call(self._w, 'get') def icursor(self, index): """Insert cursor at INDEX.""" self.tk.call(self._w, 'icursor', index) def index(self, index): """Return position of cursor.""" return self.tk.getint(self.tk.call( self._w, 'index', index)) def insert(self, index, string): """Insert STRING at INDEX.""" self.tk.call(self._w, 'insert', index, string) def scan_mark(self, x): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x) def scan_dragto(self, x): """Adjust the view of the canvas to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x) def selection_adjust(self, index): """Adjust the end of the selection near the cursor to INDEX.""" self.tk.call(self._w, 'selection', 'adjust', index) select_adjust = selection_adjust def selection_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'selection', 'clear') select_clear = selection_clear def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'from', index) select_from = selection_from def selection_present(self): """Return True if there are characters selected in the entry, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) select_present = selection_present def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.tk.call(self._w, 'selection', 'range', start, end) select_range = selection_range def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'to', index) select_to = selection_to class Frame(Widget): """Frame widget which may contain other widgets and can have a 3D border.""" def __init__(self, master=None, cnf={}, **kw): """Construct a frame widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.""" cnf = _cnfmerge((cnf, kw)) extra = () if 'class_' in cnf: extra = ('-class', cnf['class_']) del cnf['class_'] elif 'class' in cnf: extra = ('-class', cnf['class']) del cnf['class'] Widget.__init__(self, master, 'frame', cnf, {}, extra) class Label(Widget): """Label widget which can display text and bitmaps.""" def __init__(self, master=None, cnf={}, **kw): """Construct a label widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground, highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS height, state, width """ Widget.__init__(self, master, 'label', cnf, kw) class Listbox(Widget, XView, YView): """Listbox widget which can display a list of strings.""" def __init__(self, master=None, cnf={}, **kw): """Construct a listbox widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, relief, selectbackground, selectborderwidth, selectforeground, selectmode, setgrid, takefocus, width, xscrollcommand, yscrollcommand, listvariable.""" Widget.__init__(self, master, 'listbox', cnf, kw) def activate(self, index): """Activate item identified by INDEX.""" self.tk.call(self._w, 'activate', index) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the item identified by the given index.""" return self._getints(self.tk.call(self._w, 'bbox', index)) or None def curselection(self): """Return the indices of currently selected item.""" return self._getints(self.tk.call(self._w, 'curselection')) or () def delete(self, first, last=None): """Delete items from FIRST to LAST (included).""" self.tk.call(self._w, 'delete', first, last) def get(self, first, last=None): """Get list of items from FIRST to LAST (included).""" if last is not None: return self.tk.splitlist(self.tk.call( self._w, 'get', first, last)) else: return self.tk.call(self._w, 'get', first) def index(self, index): """Return index of item identified with INDEX.""" i = self.tk.call(self._w, 'index', index) if i == 'none': return None return self.tk.getint(i) def insert(self, index, *elements): """Insert ELEMENTS at INDEX.""" self.tk.call((self._w, 'insert', index) + elements) def nearest(self, y): """Get index of item which is nearest to y coordinate Y.""" return self.tk.getint(self.tk.call( self._w, 'nearest', y)) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the listbox to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def see(self, index): """Scroll such that INDEX is visible.""" self.tk.call(self._w, 'see', index) def selection_anchor(self, index): """Set the fixed end oft the selection to INDEX.""" self.tk.call(self._w, 'selection', 'anchor', index) select_anchor = selection_anchor def selection_clear(self, first, last=None): """Clear the selection from FIRST to LAST (included).""" self.tk.call(self._w, 'selection', 'clear', first, last) select_clear = selection_clear def selection_includes(self, index): """Return True if INDEX is part of the selection.""" return self.tk.getboolean(self.tk.call( self._w, 'selection', 'includes', index)) select_includes = selection_includes def selection_set(self, first, last=None): """Set the selection from FIRST to LAST (included) without changing the currently selected elements.""" self.tk.call(self._w, 'selection', 'set', first, last) select_set = selection_set def size(self): """Return the number of elements in the listbox.""" return self.tk.getint(self.tk.call(self._w, 'size')) def itemcget(self, index, option): """Return the resource value for an ITEM and an OPTION.""" return self.tk.call( (self._w, 'itemcget') + (index, '-'+option)) def itemconfigure(self, index, cnf=None, **kw): """Configure resources of an ITEM. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. Valid resource names: background, bg, foreground, fg, selectbackground, selectforeground.""" return self._configure(('itemconfigure', index), cnf, kw) itemconfig = itemconfigure class Menu(Widget): """Menu widget which allows displaying menu bars, pull-down menus and pop-up menus.""" def __init__(self, master=None, cnf={}, **kw): """Construct menu widget with the parent MASTER. Valid resource names: activebackground, activeborderwidth, activeforeground, background, bd, bg, borderwidth, cursor, disabledforeground, fg, font, foreground, postcommand, relief, selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" Widget.__init__(self, master, 'menu', cnf, kw) def tk_popup(self, x, y, entry=""): """Post the menu at position X,Y with entry ENTRY.""" self.tk.call('tk_popup', self._w, x, y, entry) def activate(self, index): """Activate entry at INDEX.""" self.tk.call(self._w, 'activate', index) def add(self, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'add', itemType) + self._options(cnf, kw)) def add_cascade(self, cnf={}, **kw): """Add hierarchical menu item.""" self.add('cascade', cnf or kw) def add_checkbutton(self, cnf={}, **kw): """Add checkbutton menu item.""" self.add('checkbutton', cnf or kw) def add_command(self, cnf={}, **kw): """Add command menu item.""" self.add('command', cnf or kw) def add_radiobutton(self, cnf={}, **kw): """Add radio menu item.""" self.add('radiobutton', cnf or kw) def add_separator(self, cnf={}, **kw): """Add separator.""" self.add('separator', cnf or kw) def insert(self, index, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'insert', index, itemType) + self._options(cnf, kw)) def insert_cascade(self, index, cnf={}, **kw): """Add hierarchical menu item at INDEX.""" self.insert(index, 'cascade', cnf or kw) def insert_checkbutton(self, index, cnf={}, **kw): """Add checkbutton menu item at INDEX.""" self.insert(index, 'checkbutton', cnf or kw) def insert_command(self, index, cnf={}, **kw): """Add command menu item at INDEX.""" self.insert(index, 'command', cnf or kw) def insert_radiobutton(self, index, cnf={}, **kw): """Add radio menu item at INDEX.""" self.insert(index, 'radiobutton', cnf or kw) def insert_separator(self, index, cnf={}, **kw): """Add separator at INDEX.""" self.insert(index, 'separator', cnf or kw) def delete(self, index1, index2=None): """Delete menu items between INDEX1 and INDEX2 (included).""" if index2 is None: index2 = index1 num_index1, num_index2 = self.index(index1), self.index(index2) if (num_index1 is None) or (num_index2 is None): num_index1, num_index2 = 0, -1 for i in range(num_index1, num_index2 + 1): if 'command' in self.entryconfig(i): c = str(self.entrycget(i, 'command')) if c: self.deletecommand(c) self.tk.call(self._w, 'delete', index1, index2) def entrycget(self, index, option): """Return the resource value of a menu item for OPTION at INDEX.""" return self.tk.call(self._w, 'entrycget', index, '-' + option) def entryconfigure(self, index, cnf=None, **kw): """Configure a menu item at INDEX.""" return self._configure(('entryconfigure', index), cnf, kw) entryconfig = entryconfigure def index(self, index): """Return the index of a menu item identified by INDEX.""" i = self.tk.call(self._w, 'index', index) return None if i in ('', 'none') else self.tk.getint(i) # GH-103685. def invoke(self, index): """Invoke a menu item identified by INDEX and execute the associated command.""" return self.tk.call(self._w, 'invoke', index) def post(self, x, y): """Display a menu at position X,Y.""" self.tk.call(self._w, 'post', x, y) def type(self, index): """Return the type of the menu item at INDEX.""" return self.tk.call(self._w, 'type', index) def unpost(self): """Unmap a menu.""" self.tk.call(self._w, 'unpost') def xposition(self, index): # new in Tk 8.5 """Return the x-position of the leftmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call(self._w, 'xposition', index)) def yposition(self, index): """Return the y-position of the topmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call( self._w, 'yposition', index)) class Menubutton(Widget): """Menubutton widget, obsolete since Tk8.0.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'menubutton', cnf, kw) class Message(Widget): """Message widget to display multiline text. Obsolete since Label does it too.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'message', cnf, kw) class Radiobutton(Widget): """Radiobutton widget which shows only one of several buttons in on-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a radiobutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, value, variable, width, wraplength.""" Widget.__init__(self, master, 'radiobutton', cnf, kw) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') class Scale(Widget): """Scale widget which can display a numerical scale.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scale widget with the parent MASTER. Valid resource names: activebackground, background, bigincrement, bd, bg, borderwidth, command, cursor, digits, fg, font, foreground, from, highlightbackground, highlightcolor, highlightthickness, label, length, orient, relief, repeatdelay, repeatinterval, resolution, showvalue, sliderlength, sliderrelief, state, takefocus, tickinterval, to, troughcolor, variable, width.""" Widget.__init__(self, master, 'scale', cnf, kw) def get(self): """Get the current value as integer or float.""" value = self.tk.call(self._w, 'get') try: return self.tk.getint(value) except (ValueError, TypeError, TclError): return self.tk.getdouble(value) def set(self, value): """Set the value to VALUE.""" self.tk.call(self._w, 'set', value) def coords(self, value=None): """Return a tuple (X,Y) of the point along the centerline of the trough that corresponds to VALUE or the current value if None is given.""" return self._getints(self.tk.call(self._w, 'coords', value)) def identify(self, x, y): """Return where the point X,Y lies. Valid return values are "slider", "though1" and "though2".""" return self.tk.call(self._w, 'identify', x, y) class Scrollbar(Widget): """Scrollbar widget which displays a slider at a certain position.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scrollbar widget with the parent MASTER. Valid resource names: activebackground, activerelief, background, bd, bg, borderwidth, command, cursor, elementborderwidth, highlightbackground, highlightcolor, highlightthickness, jump, orient, relief, repeatdelay, repeatinterval, takefocus, troughcolor, width.""" Widget.__init__(self, master, 'scrollbar', cnf, kw) def activate(self, index=None): """Marks the element indicated by index as active. The only index values understood by this method are "arrow1", "slider", or "arrow2". If any other value is specified then no element of the scrollbar will be active. If index is not specified, the method returns the name of the element that is currently active, or None if no element is active.""" return self.tk.call(self._w, 'activate', index) or None def delta(self, deltax, deltay): """Return the fractional change of the scrollbar setting if it would be moved by DELTAX or DELTAY pixels.""" return self.tk.getdouble( self.tk.call(self._w, 'delta', deltax, deltay)) def fraction(self, x, y): """Return the fractional value which corresponds to a slider position of X,Y.""" return self.tk.getdouble(self.tk.call(self._w, 'fraction', x, y)) def identify(self, x, y): """Return the element under position X,Y as one of "arrow1","slider","arrow2" or "".""" return self.tk.call(self._w, 'identify', x, y) def get(self): """Return the current fractional values (upper and lower end) of the slider position.""" return self._getdoubles(self.tk.call(self._w, 'get')) def set(self, first, last): """Set the fractional values of the slider position (upper and lower ends as value between 0 and 1).""" self.tk.call(self._w, 'set', first, last) class Text(Widget, XView, YView): """Text widget which can display text in various forms.""" def __init__(self, master=None, cnf={}, **kw): """Construct a text widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, padx, pady, relief, selectbackground, selectborderwidth, selectforeground, setgrid, takefocus, xscrollcommand, yscrollcommand, WIDGET-SPECIFIC OPTIONS autoseparators, height, maxundo, spacing1, spacing2, spacing3, state, tabs, undo, width, wrap, """ Widget.__init__(self, master, 'text', cnf, kw) def bbox(self, index): """Return a tuple of (x,y,width,height) which gives the bounding box of the visible part of the character at the given index.""" return self._getints( self.tk.call(self._w, 'bbox', index)) or None def compare(self, index1, op, index2): """Return whether between index INDEX1 and index INDEX2 the relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" return self.tk.getboolean(self.tk.call( self._w, 'compare', index1, op, index2)) def count(self, index1, index2, *args): # new in Tk 8.5 """Counts the number of relevant things between the two indices. If index1 is after index2, the result will be a negative number (and this holds for each of the possible options). The actual items which are counted depends on the options given by args. The result is a list of integers, one for the result of each counting option given. Valid counting options are "chars", "displaychars", "displayindices", "displaylines", "indices", "lines", "xpixels" and "ypixels". There is an additional possible option "update", which if given then all subsequent options ensure that any possible out of date information is recalculated.""" args = ['-%s' % arg for arg in args] args += [index1, index2] res = self.tk.call(self._w, 'count', *args) or None if res is not None and len(args) <= 3: return (res, ) else: return res def debug(self, boolean=None): """Turn on the internal consistency checks of the B-Tree inside the text widget according to BOOLEAN.""" if boolean is None: return self.tk.getboolean(self.tk.call(self._w, 'debug')) self.tk.call(self._w, 'debug', boolean) def delete(self, index1, index2=None): """Delete the characters between INDEX1 and INDEX2 (not included).""" self.tk.call(self._w, 'delete', index1, index2) def dlineinfo(self, index): """Return tuple (x,y,width,height,baseline) giving the bounding box and baseline position of the visible part of the line containing the character at INDEX.""" return self._getints(self.tk.call(self._w, 'dlineinfo', index)) def dump(self, index1, index2=None, command=None, **kw): """Return the contents of the widget between index1 and index2. The type of contents returned in filtered based on the keyword parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are given and true, then the corresponding items are returned. The result is a list of triples of the form (key, value, index). If none of the keywords are true then 'all' is used by default. If the 'command' argument is given, it is called once for each element of the list of triples, with the values of each triple serving as the arguments to the function. In this case the list is not returned.""" args = [] func_name = None result = None if not command: # Never call the dump command without the -command flag, since the # output could involve Tcl quoting and would be a pain to parse # right. Instead just set the command to build a list of triples # as if we had done the parsing. result = [] def append_triple(key, value, index, result=result): result.append((key, value, index)) command = append_triple try: if not isinstance(command, str): func_name = command = self._register(command) args += ["-command", command] for key in kw: if kw[key]: args.append("-" + key) args.append(index1) if index2: args.append(index2) self.tk.call(self._w, "dump", *args) return result finally: if func_name: self.deletecommand(func_name) ## new in tk8.4 def edit(self, *args): """Internal method This method controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the command are currently supported: edit_modified, edit_redo, edit_reset, edit_separator and edit_undo """ return self.tk.call(self._w, 'edit', *args) def edit_modified(self, arg=None): """Get or Set the modified flag If arg is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to arg. """ return self.edit("modified", arg) def edit_redo(self): """Redo the last undone edit When the undo option is true, reapplies the last undone edits provided no other edits were done since then. Generates an error when the redo stack is empty. Does nothing when the undo option is false. """ return self.edit("redo") def edit_reset(self): """Clears the undo and redo stacks """ return self.edit("reset") def edit_separator(self): """Inserts a separator (boundary) on the undo stack. Does nothing when the undo option is false """ return self.edit("separator") def edit_undo(self): """Undoes the last edit action If the undo option is true. An edit action is defined as all the insert and delete commands that are recorded on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the undo option is false """ return self.edit("undo") def get(self, index1, index2=None): """Return the text from INDEX1 to INDEX2 (not included).""" return self.tk.call(self._w, 'get', index1, index2) # (Image commands are new in 8.0) def image_cget(self, index, option): """Return the value of OPTION of an embedded image at INDEX.""" if option[:1] != "-": option = "-" + option if option[-1:] == "_": option = option[:-1] return self.tk.call(self._w, "image", "cget", index, option) def image_configure(self, index, cnf=None, **kw): """Configure an embedded image at INDEX.""" return self._configure(('image', 'configure', index), cnf, kw) def image_create(self, index, cnf={}, **kw): """Create an embedded image at INDEX.""" return self.tk.call( self._w, "image", "create", index, *self._options(cnf, kw)) def image_names(self): """Return all names of embedded images in this widget.""" return self.tk.call(self._w, "image", "names") def index(self, index): """Return the index in the form line.char for INDEX.""" return str(self.tk.call(self._w, 'index', index)) def insert(self, index, chars, *args): """Insert CHARS before the characters at INDEX. An additional tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" self.tk.call((self._w, 'insert', index, chars) + args) def mark_gravity(self, markName, direction=None): """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). Return the current value if None is given for DIRECTION.""" return self.tk.call( (self._w, 'mark', 'gravity', markName, direction)) def mark_names(self): """Return all mark names.""" return self.tk.splitlist(self.tk.call( self._w, 'mark', 'names')) def mark_set(self, markName, index): """Set mark MARKNAME before the character at INDEX.""" self.tk.call(self._w, 'mark', 'set', markName, index) def mark_unset(self, *markNames): """Delete all marks in MARKNAMES.""" self.tk.call((self._w, 'mark', 'unset') + markNames) def mark_next(self, index): """Return the name of the next mark after INDEX.""" return self.tk.call(self._w, 'mark', 'next', index) or None def mark_previous(self, index): """Return the name of the previous mark before INDEX.""" return self.tk.call(self._w, 'mark', 'previous', index) or None def peer_create(self, newPathName, cnf={}, **kw): # new in Tk 8.5 """Creates a peer text widget with the given newPathName, and any optional standard configuration options. By default the peer will have the same start and end line as the parent widget, but these can be overridden with the standard configuration options.""" self.tk.call(self._w, 'peer', 'create', newPathName, *self._options(cnf, kw)) def peer_names(self): # new in Tk 8.5 """Returns a list of peers of this widget (this does not include the widget itself).""" return self.tk.splitlist(self.tk.call(self._w, 'peer', 'names')) def replace(self, index1, index2, chars, *args): # new in Tk 8.5 """Replaces the range of characters between index1 and index2 with the given characters and tags specified by args. See the method insert for some more information about args, and the method delete for information about the indices.""" self.tk.call(self._w, 'replace', index1, index2, chars, *args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the text to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def search(self, pattern, index, stopindex=None, forwards=None, backwards=None, exact=None, regexp=None, nocase=None, count=None, elide=None): """Search PATTERN beginning from INDEX until STOPINDEX. Return the index of the first character of a match or an empty string.""" args = [self._w, 'search'] if forwards: args.append('-forwards') if backwards: args.append('-backwards') if exact: args.append('-exact') if regexp: args.append('-regexp') if nocase: args.append('-nocase') if elide: args.append('-elide') if count: args.append('-count'); args.append(count) if pattern and pattern[0] == '-': args.append('--') args.append(pattern) args.append(index) if stopindex: args.append(stopindex) return str(self.tk.call(tuple(args))) def see(self, index): """Scroll such that the character at INDEX is visible.""" self.tk.call(self._w, 'see', index) def tag_add(self, tagName, index1, *args): """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. Additional pairs of indices may follow in ARGS.""" self.tk.call( (self._w, 'tag', 'add', tagName, index1) + args) def tag_unbind(self, tagName, sequence, funcid=None): """Unbind for all characters with TAGNAME for event SEQUENCE the function identified with FUNCID.""" return self._unbind((self._w, 'tag', 'bind', tagName, sequence), funcid) def tag_bind(self, tagName, sequence, func, add=None): """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'tag', 'bind', tagName), sequence, func, add) def _tag_bind(self, tagName, sequence=None, func=None, add=None): # For tests only return self._bind((self._w, 'tag', 'bind', tagName), sequence, func, add) def tag_cget(self, tagName, option): """Return the value of OPTION for tag TAGNAME.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'tag', 'cget', tagName, option) def tag_configure(self, tagName, cnf=None, **kw): """Configure a tag TAGNAME.""" return self._configure(('tag', 'configure', tagName), cnf, kw) tag_config = tag_configure def tag_delete(self, *tagNames): """Delete all tags in TAGNAMES.""" self.tk.call((self._w, 'tag', 'delete') + tagNames) def tag_lower(self, tagName, belowThis=None): """Change the priority of tag TAGNAME such that it is lower than the priority of BELOWTHIS.""" self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) def tag_names(self, index=None): """Return a list of all tag names.""" return self.tk.splitlist( self.tk.call(self._w, 'tag', 'names', index)) def tag_nextrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched forward from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'nextrange', tagName, index1, index2)) def tag_prevrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched backwards from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'prevrange', tagName, index1, index2)) def tag_raise(self, tagName, aboveThis=None): """Change the priority of tag TAGNAME such that it is higher than the priority of ABOVETHIS.""" self.tk.call( self._w, 'tag', 'raise', tagName, aboveThis) def tag_ranges(self, tagName): """Return a list of ranges of text which have tag TAGNAME.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'ranges', tagName)) def tag_remove(self, tagName, index1, index2=None): """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" self.tk.call( self._w, 'tag', 'remove', tagName, index1, index2) def window_cget(self, index, option): """Return the value of OPTION of an embedded window at INDEX.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'window', 'cget', index, option) def window_configure(self, index, cnf=None, **kw): """Configure an embedded window at INDEX.""" return self._configure(('window', 'configure', index), cnf, kw) window_config = window_configure def window_create(self, index, cnf={}, **kw): """Create a window at INDEX.""" self.tk.call( (self._w, 'window', 'create', index) + self._options(cnf, kw)) def window_names(self): """Return all names of embedded windows in this widget.""" return self.tk.splitlist( self.tk.call(self._w, 'window', 'names')) def yview_pickplace(self, *what): """Obsolete function, use see.""" self.tk.call((self._w, 'yview', '-pickplace') + what) class _setit: """Internal class. It wraps the command in the widget OptionMenu.""" def __init__(self, var, value, callback=None): self.__value = value self.__var = var self.__callback = callback def __call__(self, *args): self.__var.set(self.__value) if self.__callback is not None: self.__callback(self.__value, *args) class OptionMenu(Menubutton): """OptionMenu which allows the user to select a value from a menu.""" def __init__(self, master, variable, value, *values, **kwargs): """Construct an optionmenu widget with the parent MASTER, with the resource textvariable set to VARIABLE, the initially selected value VALUE, the other menu values VALUES and an additional keyword argument command.""" kw = {"borderwidth": 2, "textvariable": variable, "indicatoron": 1, "relief": RAISED, "anchor": "c", "highlightthickness": 2} Widget.__init__(self, master, "menubutton", kw) self.widgetName = 'tk_optionMenu' menu = self.__menu = Menu(self, name="menu", tearoff=0) self.menuname = menu._w # 'command' is the only supported keyword callback = kwargs.get('command') if 'command' in kwargs: del kwargs['command'] if kwargs: raise TclError('unknown option -'+next(iter(kwargs))) menu.add_command(label=value, command=_setit(variable, value, callback)) for v in values: menu.add_command(label=v, command=_setit(variable, v, callback)) self["menu"] = menu def __getitem__(self, name): if name == 'menu': return self.__menu return Widget.__getitem__(self, name) def destroy(self): """Destroy this widget and the associated menu.""" Menubutton.destroy(self) self.__menu = None class Image: """Base class for images.""" _last_id = 0 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): self.name = None if master is None: master = _get_default_root('create image') self.tk = getattr(master, 'tk', master) if not name: Image._last_id += 1 name = "pyimage%r" % (Image._last_id,) # tk itself would use image if kw and cnf: cnf = _cnfmerge((cnf, kw)) elif kw: cnf = kw options = () for k, v in cnf.items(): options = options + ('-'+k, v) self.tk.call(('image', 'create', imgtype, name,) + options) self.name = name def __str__(self): return self.name def __del__(self): if self.name: try: self.tk.call('image', 'delete', self.name) except TclError: # May happen if the root was destroyed pass def __setitem__(self, key, value): self.tk.call(self.name, 'configure', '-'+key, value) def __getitem__(self, key): return self.tk.call(self.name, 'configure', '-'+key) def configure(self, **kw): """Configure the image.""" res = () for k, v in _cnfmerge(kw).items(): if v is not None: if k[-1] == '_': k = k[:-1] res = res + ('-'+k, v) self.tk.call((self.name, 'config') + res) config = configure def height(self): """Return the height of the image.""" return self.tk.getint( self.tk.call('image', 'height', self.name)) def type(self): """Return the type of the image, e.g. "photo" or "bitmap".""" return self.tk.call('image', 'type', self.name) def width(self): """Return the width of the image.""" return self.tk.getint( self.tk.call('image', 'width', self.name)) class PhotoImage(Image): """Widget which can display images in PGM, PPM, GIF, PNG format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create an image with NAME. Valid resource names: data, format, file, gamma, height, palette, width.""" Image.__init__(self, 'photo', name, cnf, master, **kw) def blank(self): """Display a transparent image.""" self.tk.call(self.name, 'blank') def cget(self, option): """Return the value of OPTION.""" return self.tk.call(self.name, 'cget', '-' + option) # XXX config def __getitem__(self, key): return self.tk.call(self.name, 'cget', '-' + key) # XXX copy -from, -to, ...? def copy(self): """Return a new PhotoImage with the same image as this widget.""" destImage = PhotoImage(master=self.tk) self.tk.call(destImage, 'copy', self.name) return destImage def zoom(self, x, y=''): """Return a new PhotoImage with the same image as this widget but zoom it with a factor of x in the X direction and y in the Y direction. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) return destImage def subsample(self, x, y=''): """Return a new PhotoImage based on the same image as this widget but use only every Xth or Yth pixel. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) return destImage def get(self, x, y): """Return the color (red, green, blue) of the pixel at X,Y.""" return self.tk.call(self.name, 'get', x, y) def put(self, data, to=None): """Put row formatted colors to image starting from position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" args = (self.name, 'put', data) if to: if to[0] == '-to': to = to[1:] args = args + ('-to',) + tuple(to) self.tk.call(args) # XXX read def write(self, filename, format=None, from_coords=None): """Write image to file FILENAME in FORMAT starting from position FROM_COORDS.""" args = (self.name, 'write', filename) if format: args = args + ('-format', format) if from_coords: args = args + ('-from',) + tuple(from_coords) self.tk.call(args) def transparency_get(self, x, y): """Return True if the pixel at x,y is transparent.""" return self.tk.getboolean(self.tk.call( self.name, 'transparency', 'get', x, y)) def transparency_set(self, x, y, boolean): """Set the transparency of the pixel at x,y.""" self.tk.call(self.name, 'transparency', 'set', x, y, boolean) class BitmapImage(Image): """Widget which can display images in XBM format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create a bitmap with NAME. Valid resource names: background, data, file, foreground, maskdata, maskfile.""" Image.__init__(self, 'bitmap', name, cnf, master, **kw) def image_names(): tk = _get_default_root('use image_names()').tk return tk.splitlist(tk.call('image', 'names')) def image_types(): tk = _get_default_root('use image_types()').tk return tk.splitlist(tk.call('image', 'types')) class Spinbox(Widget, XView): """spinbox widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a spinbox widget with the parent MASTER. STANDARD OPTIONS activebackground, background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, justify, relief, repeatdelay, repeatinterval, selectbackground, selectborderwidth selectforeground, takefocus, textvariable xscrollcommand. WIDGET-SPECIFIC OPTIONS buttonbackground, buttoncursor, buttondownrelief, buttonuprelief, command, disabledbackground, disabledforeground, format, from, invalidcommand, increment, readonlybackground, state, to, validate, validatecommand values, width, wrap, """ Widget.__init__(self, master, 'spinbox', cnf, kw) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the character given by index. The first two elements of the list give the x and y coordinates of the upper-left corner of the screen area covered by the character (in pixels relative to the widget) and the last two elements give the width and height of the character, in pixels. The bounding box may refer to a region outside the visible area of the window. """ return self._getints(self.tk.call(self._w, 'bbox', index)) or None def delete(self, first, last=None): """Delete one or more elements of the spinbox. First is the index of the first character to delete, and last is the index of the character just after the last one to delete. If last isn't specified it defaults to first+1, i.e. a single character is deleted. This command returns an empty string. """ return self.tk.call(self._w, 'delete', first, last) def get(self): """Returns the spinbox's string""" return self.tk.call(self._w, 'get') def icursor(self, index): """Alter the position of the insertion cursor. The insertion cursor will be displayed just before the character given by index. Returns an empty string """ return self.tk.call(self._w, 'icursor', index) def identify(self, x, y): """Returns the name of the widget at position x, y Return value is one of: none, buttondown, buttonup, entry """ return self.tk.call(self._w, 'identify', x, y) def index(self, index): """Returns the numerical index corresponding to index """ return self.tk.call(self._w, 'index', index) def insert(self, index, s): """Insert string s at index Returns an empty string. """ return self.tk.call(self._w, 'insert', index, s) def invoke(self, element): """Causes the specified element to be invoked The element could be buttondown or buttonup triggering the action associated with it. """ return self.tk.call(self._w, 'invoke', element) def scan(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'scan') + args)) or () def scan_mark(self, x): """Records x and the current view in the spinbox window; used in conjunction with later scan dragto commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. """ return self.scan("mark", x) def scan_dragto(self, x): """Compute the difference between the given x argument and the x argument to the last scan mark command It then adjusts the view left or right by 10 times the difference in x-coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the spinbox at high speed through the window. The return value is an empty string. """ return self.scan("dragto", x) def selection(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'selection') + args)) or () def selection_adjust(self, index): """Locate the end of the selection nearest to the character given by index, Then adjust that end of the selection to be at index (i.e including but not going beyond index). The other end of the selection is made the anchor point for future select to commands. If the selection isn't currently in the spinbox, then a new selection is created to include the characters between index and the most recent selection anchor point, inclusive. """ return self.selection("adjust", index) def selection_clear(self): """Clear the selection If the selection isn't in this widget then the command has no effect. """ return self.selection("clear") def selection_element(self, element=None): """Sets or gets the currently selected element. If a spinbutton element is specified, it will be displayed depressed. """ return self.tk.call(self._w, 'selection', 'element', element) def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.selection('from', index) def selection_present(self): """Return True if there are characters selected in the spinbox, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.selection('range', start, end) def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.selection('to', index) ########################################################################### class LabelFrame(Widget): """labelframe widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a labelframe widget with the parent MASTER. STANDARD OPTIONS borderwidth, cursor, font, foreground, highlightbackground, highlightcolor, highlightthickness, padx, pady, relief, takefocus, text WIDGET-SPECIFIC OPTIONS background, class, colormap, container, height, labelanchor, labelwidget, visual, width """ Widget.__init__(self, master, 'labelframe', cnf, kw) ######################################################################## class PanedWindow(Widget): """panedwindow widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a panedwindow widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, height, orient, relief, width WIDGET-SPECIFIC OPTIONS handlepad, handlesize, opaqueresize, sashcursor, sashpad, sashrelief, sashwidth, showhandle, """ Widget.__init__(self, master, 'panedwindow', cnf, kw) def add(self, child, **kw): """Add a child widget to the panedwindow in a new pane. The child argument is the name of the child widget followed by pairs of arguments that specify how to manage the windows. The possible options and values are the ones accepted by the paneconfigure method. """ self.tk.call((self._w, 'add', child) + self._options(kw)) def remove(self, child): """Remove the pane containing child from the panedwindow All geometry management options for child will be forgotten. """ self.tk.call(self._w, 'forget', child) forget = remove def identify(self, x, y): """Identify the panedwindow component at point x, y If the point is over a sash or a sash handle, the result is a two element list containing the index of the sash or handle, and a word indicating whether it is over a sash or a handle, such as {0 sash} or {2 handle}. If the point is over any other part of the panedwindow, the result is an empty list. """ return self.tk.call(self._w, 'identify', x, y) def proxy(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'proxy') + args)) or () def proxy_coord(self): """Return the x and y pair of the most recent proxy location """ return self.proxy("coord") def proxy_forget(self): """Remove the proxy from the display. """ return self.proxy("forget") def proxy_place(self, x, y): """Place the proxy at the given x and y coordinates. """ return self.proxy("place", x, y) def sash(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'sash') + args)) or () def sash_coord(self, index): """Return the current x and y pair for the sash given by index. Index must be an integer between 0 and 1 less than the number of panes in the panedwindow. The coordinates given are those of the top left corner of the region containing the sash. pathName sash dragto index x y This command computes the difference between the given coordinates and the coordinates given to the last sash coord command for the given sash. It then moves that sash the computed difference. The return value is the empty string. """ return self.sash("coord", index) def sash_mark(self, index): """Records x and y for the sash given by index; Used in conjunction with later dragto commands to move the sash. """ return self.sash("mark", index) def sash_place(self, index, x, y): """Place the sash given by index at the given coordinates """ return self.sash("place", index, x, y) def panecget(self, child, option): """Query a management option for window. Option may be any value allowed by the paneconfigure subcommand """ return self.tk.call( (self._w, 'panecget') + (child, '-'+option)) def paneconfigure(self, tagOrId, cnf=None, **kw): """Query or modify the management options for window. If no option is specified, returns a list describing all of the available options for pathName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. The following options are supported: after window Insert the window after the window specified. window should be the name of a window already managed by pathName. before window Insert the window before the window specified. window should be the name of a window already managed by pathName. height size Specify a height for the window. The height will be the outer dimension of the window including its border, if any. If size is an empty string, or if -height is not specified, then the height requested internally by the window will be used initially; the height may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. minsize n Specifies that the size of the window cannot be made less than n. This constraint only affects the size of the widget in the paned dimension -- the x dimension for horizontal panedwindows, the y dimension for vertical panedwindows. May be any value accepted by Tk_GetPixels. padx n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the X-direction. The value may have any of the forms accepted by Tk_GetPixels. pady n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the Y-direction. The value may have any of the forms accepted by Tk_GetPixels. sticky style If a window's pane is larger than the requested dimensions of the window, this option may be used to position (or stretch) the window within its pane. Style is a string that contains zero or more of the characters n, s, e or w. The string can optionally contains spaces or commas, but they are ignored. Each letter refers to a side (north, south, east, or west) that the window will "stick" to. If both n and s (or e and w) are specified, the window will be stretched to fill the entire height (or width) of its cavity. width size Specify a width for the window. The width will be the outer dimension of the window including its border, if any. If size is an empty string, or if -width is not specified, then the width requested internally by the window will be used initially; the width may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. """ if cnf is None and not kw: return self._getconfigure(self._w, 'paneconfigure', tagOrId) if isinstance(cnf, str) and not kw: return self._getconfigure1( self._w, 'paneconfigure', tagOrId, '-'+cnf) self.tk.call((self._w, 'paneconfigure', tagOrId) + self._options(cnf, kw)) paneconfig = paneconfigure def panes(self): """Returns an ordered list of the child panes.""" return self.tk.splitlist(self.tk.call(self._w, 'panes')) # Test: def _test(): root = Tk() text = "This is Tcl/Tk %s" % root.globalgetvar('tk_patchLevel') text += "\nThis should be a cedilla: \xe7" label = Label(root, text=text) label.pack() test = Button(root, text="Click me!", command=lambda root=root: root.test.configure( text="[%s]" % root.test['text'])) test.pack() root.test = test quit = Button(root, text="QUIT", command=root.destroy) quit.pack() # The following three commands are needed so the window pops # up on top on Windows... root.iconify() root.update() root.deiconify() root.mainloop() __all__ = [name for name, obj in globals().items() if not name.startswith('_') and not isinstance(obj, types.ModuleType) and name not in {'wantobjects'}] if __name__ == '__main__': _test() usr/lib64/python3.6/ctypes/macholib/__init__.py000064400000000232152347726340015255 0ustar00""" Enough Mach-O to make your head spin. See the relevant header files in /usr/include/mach-o And also Apple's documentation. """ __version__ = '1.0' lib64/python2.7/curses/__init__.py000064400000003431152347742540012667 0ustar00"""curses The main package for curses support for Python. Normally used by importing the package, and perhaps a particular module inside it. import curses from curses import textpad curses.initscr() ... """ __revision__ = "$Id$" from _curses import * from curses.wrapper import wrapper import os as _os import sys as _sys # Some constants, most notably the ACS_* ones, are only added to the C # _curses module's dictionary after initscr() is called. (Some # versions of SGI's curses don't define values for those constants # until initscr() has been called.) This wrapper function calls the # underlying C initscr(), and then copies the constants from the # _curses module to the curses package's dictionary. Don't do 'from # curses import *' if you'll be needing the ACS_* constants. def initscr(): import _curses, curses # we call setupterm() here because it raises an error # instead of calling exit() in error cases. setupterm(term=_os.environ.get("TERM", "unknown"), fd=_sys.__stdout__.fileno()) stdscr = _curses.initscr() for key, value in _curses.__dict__.items(): if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): setattr(curses, key, value) return stdscr # This is a similar wrapper for start_color(), which adds the COLORS and # COLOR_PAIRS variables which are only available after start_color() is # called. def start_color(): import _curses, curses retval = _curses.start_color() if hasattr(_curses, 'COLORS'): curses.COLORS = _curses.COLORS if hasattr(_curses, 'COLOR_PAIRS'): curses.COLOR_PAIRS = _curses.COLOR_PAIRS return retval # Import Python has_key() implementation if _curses doesn't contain has_key() try: has_key except NameError: from has_key import has_key lib64/python2.7/sqlite3/__init__.py000064400000001762152350015030012731 0ustar00# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Haering # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. from dbapi2 import * usr/lib64/python3.12/xml/dom/__init__.py000064400000007663152350030350013622 0ustar00"""W3C Document Object Model implementation for Python. The Python mapping of the Document Object Model is documented in the Python Library Reference in the section on the xml.dom package. This package contains the following modules: minidom -- A simple implementation of the Level 1 DOM with namespace support added (based on the Level 2 specification) and other minor Level 2 functionality. pulldom -- DOM builder supporting on-demand tree-building for selected subtrees of the document. """ class Node: """Class giving the NodeType constants.""" __slots__ = () # DOM implementations may use this as a base class for their own # Node implementations. If they don't, the constants defined here # should still be used as the canonical definitions as they match # the values given in the W3C recommendation. Client code can # safely refer to these values in all tests of Node.nodeType # values. ELEMENT_NODE = 1 ATTRIBUTE_NODE = 2 TEXT_NODE = 3 CDATA_SECTION_NODE = 4 ENTITY_REFERENCE_NODE = 5 ENTITY_NODE = 6 PROCESSING_INSTRUCTION_NODE = 7 COMMENT_NODE = 8 DOCUMENT_NODE = 9 DOCUMENT_TYPE_NODE = 10 DOCUMENT_FRAGMENT_NODE = 11 NOTATION_NODE = 12 #ExceptionCode INDEX_SIZE_ERR = 1 DOMSTRING_SIZE_ERR = 2 HIERARCHY_REQUEST_ERR = 3 WRONG_DOCUMENT_ERR = 4 INVALID_CHARACTER_ERR = 5 NO_DATA_ALLOWED_ERR = 6 NO_MODIFICATION_ALLOWED_ERR = 7 NOT_FOUND_ERR = 8 NOT_SUPPORTED_ERR = 9 INUSE_ATTRIBUTE_ERR = 10 INVALID_STATE_ERR = 11 SYNTAX_ERR = 12 INVALID_MODIFICATION_ERR = 13 NAMESPACE_ERR = 14 INVALID_ACCESS_ERR = 15 VALIDATION_ERR = 16 class DOMException(Exception): """Abstract base class for DOM exceptions. Exceptions with specific codes are specializations of this class.""" def __init__(self, *args, **kw): if self.__class__ is DOMException: raise RuntimeError( "DOMException should not be instantiated directly") Exception.__init__(self, *args, **kw) def _get_code(self): return self.code class IndexSizeErr(DOMException): code = INDEX_SIZE_ERR class DomstringSizeErr(DOMException): code = DOMSTRING_SIZE_ERR class HierarchyRequestErr(DOMException): code = HIERARCHY_REQUEST_ERR class WrongDocumentErr(DOMException): code = WRONG_DOCUMENT_ERR class InvalidCharacterErr(DOMException): code = INVALID_CHARACTER_ERR class NoDataAllowedErr(DOMException): code = NO_DATA_ALLOWED_ERR class NoModificationAllowedErr(DOMException): code = NO_MODIFICATION_ALLOWED_ERR class NotFoundErr(DOMException): code = NOT_FOUND_ERR class NotSupportedErr(DOMException): code = NOT_SUPPORTED_ERR class InuseAttributeErr(DOMException): code = INUSE_ATTRIBUTE_ERR class InvalidStateErr(DOMException): code = INVALID_STATE_ERR class SyntaxErr(DOMException): code = SYNTAX_ERR class InvalidModificationErr(DOMException): code = INVALID_MODIFICATION_ERR class NamespaceErr(DOMException): code = NAMESPACE_ERR class InvalidAccessErr(DOMException): code = INVALID_ACCESS_ERR class ValidationErr(DOMException): code = VALIDATION_ERR class UserDataHandler: """Class giving the operation constants for UserDataHandler.handle().""" # Based on DOM Level 3 (WD 9 April 2002) NODE_CLONED = 1 NODE_IMPORTED = 2 NODE_DELETED = 3 NODE_RENAMED = 4 XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml" EMPTY_NAMESPACE = None EMPTY_PREFIX = None from .domreg import getDOMImplementation, registerDOMImplementation usr/lib/python3.6/site-packages/pycriu/__init__.py000064400000000527152350034510016041 0ustar00from . import rpc_pb2 as rpc from . import images from .criu import criu, CRIUExceptionExternal, CRIUException from .criu import CR_DEFAULT_SERVICE_ADDRESS from .version import __version__ __all__ = ( "rpc", "images", "criu", "CRIUExceptionExternal", "CRIUException", "CR_DEFAULT_SERVICE_ADDRESS", "__version__", )usr/lib64/python3.12/xml/parsers/__init__.py000064400000000247152350035460014520 0ustar00"""Python interfaces to XML parsers. This package contains one module: expat -- Python wrapper for James Clark's Expat parser, with namespace support. """ usr/lib64/python3.6/ctypes/__init__.py000064400000040061152350120160013461 0ustar00"""create and manipulate C data types in Python""" import os as _os, sys as _sys __version__ = "1.1.0" from _ctypes import Union, Structure, Array from _ctypes import _Pointer from _ctypes import CFuncPtr as _CFuncPtr from _ctypes import __version__ as _ctypes_version from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import ArgumentError from struct import calcsize as _calcsize if __version__ != _ctypes_version: raise Exception("Version number mismatch", __version__, _ctypes_version) if _os.name == "nt": from _ctypes import FormatError DEFAULT_MODE = RTLD_LOCAL if _os.name == "posix" and _sys.platform == "darwin": # On OS X 10.3, we use RTLD_GLOBAL as default mode # because RTLD_LOCAL does not work at least on some # libraries. OS X 10.3 is Darwin 7, so we check for # that. if int(_os.uname().release.split('.')[0]) < 8: DEFAULT_MODE = RTLD_GLOBAL from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \ FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \ FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR # WINOLEAPI -> HRESULT # WINOLEAPI_(type) # # STDMETHODCALLTYPE # # STDMETHOD(name) # STDMETHOD_(type, name) # # STDAPICALLTYPE def create_string_buffer(init, size=None): """create_string_buffer(aBytes) -> character array create_string_buffer(anInteger) -> character array create_string_buffer(aBytes, anInteger) -> character array """ if isinstance(init, bytes): if size is None: size = len(init)+1 buftype = c_char * size buf = buftype() buf.value = init return buf elif isinstance(init, int): buftype = c_char * init buf = buftype() return buf raise TypeError(init) def c_buffer(init, size=None): ## "deprecated, use create_string_buffer instead" ## import warnings ## warnings.warn("c_buffer is deprecated, use create_string_buffer instead", ## DeprecationWarning, stacklevel=2) return create_string_buffer(init, size) _c_functype_cache = {} def CFUNCTYPE(restype, *argtypes, **kw): """CFUNCTYPE(restype, *argtypes, use_errno=False, use_last_error=False) -> function prototype. restype: the result type argtypes: a sequence specifying the argument types The function prototype can be called in different ways to create a callable object: prototype(integer address) -> foreign function prototype(callable) -> create and return a C callable function from callable prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal prototype((function name, dll object)[, paramflags]) -> foreign function exported by name """ flags = _FUNCFLAG_CDECL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _c_functype_cache[(restype, argtypes, flags)] except KeyError: class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _c_functype_cache[(restype, argtypes, flags)] = CFunctionType return CFunctionType if _os.name == "nt": from _ctypes import LoadLibrary as _dlopen from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL _win_functype_cache = {} def WINFUNCTYPE(restype, *argtypes, **kw): # docstring set later (very similar to CFUNCTYPE.__doc__) flags = _FUNCFLAG_STDCALL if kw.pop("use_errno", False): flags |= _FUNCFLAG_USE_ERRNO if kw.pop("use_last_error", False): flags |= _FUNCFLAG_USE_LASTERROR if kw: raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) try: return _win_functype_cache[(restype, argtypes, flags)] except KeyError: class WinFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = flags _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType return WinFunctionType if WINFUNCTYPE.__doc__: WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE") elif _os.name == "posix": from _ctypes import dlopen as _dlopen from _ctypes import sizeof, byref, addressof, alignment, resize from _ctypes import get_errno, set_errno from _ctypes import _SimpleCData def _check_size(typ, typecode=None): # Check if sizeof(ctypes_type) against struct.calcsize. This # should protect somewhat against a misconfigured libffi. from struct import calcsize if typecode is None: # Most _type_ codes are the same as used in struct typecode = typ._type_ actual, required = sizeof(typ), calcsize(typecode) if actual != required: raise SystemError("sizeof(%s) wrong: %d instead of %d" % \ (typ, actual, required)) class py_object(_SimpleCData): _type_ = "O" def __repr__(self): try: return super().__repr__() except ValueError: return "%s()" % type(self).__name__ _check_size(py_object, "P") class c_short(_SimpleCData): _type_ = "h" _check_size(c_short) class c_ushort(_SimpleCData): _type_ = "H" _check_size(c_ushort) class c_long(_SimpleCData): _type_ = "l" _check_size(c_long) class c_ulong(_SimpleCData): _type_ = "L" _check_size(c_ulong) if _calcsize("i") == _calcsize("l"): # if int and long have the same size, make c_int an alias for c_long c_int = c_long c_uint = c_ulong else: class c_int(_SimpleCData): _type_ = "i" _check_size(c_int) class c_uint(_SimpleCData): _type_ = "I" _check_size(c_uint) class c_float(_SimpleCData): _type_ = "f" _check_size(c_float) class c_double(_SimpleCData): _type_ = "d" _check_size(c_double) class c_longdouble(_SimpleCData): _type_ = "g" if sizeof(c_longdouble) == sizeof(c_double): c_longdouble = c_double if _calcsize("l") == _calcsize("q"): # if long and long long have the same size, make c_longlong an alias for c_long c_longlong = c_long c_ulonglong = c_ulong else: class c_longlong(_SimpleCData): _type_ = "q" _check_size(c_longlong) class c_ulonglong(_SimpleCData): _type_ = "Q" ## def from_param(cls, val): ## return ('d', float(val), val) ## from_param = classmethod(from_param) _check_size(c_ulonglong) class c_ubyte(_SimpleCData): _type_ = "B" c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte # backward compatibility: ##c_uchar = c_ubyte _check_size(c_ubyte) class c_byte(_SimpleCData): _type_ = "b" c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte _check_size(c_byte) class c_char(_SimpleCData): _type_ = "c" c_char.__ctype_le__ = c_char.__ctype_be__ = c_char _check_size(c_char) class c_char_p(_SimpleCData): _type_ = "z" def __repr__(self): return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) _check_size(c_char_p, "P") class c_void_p(_SimpleCData): _type_ = "P" c_voidp = c_void_p # backwards compatibility (to a bug) _check_size(c_void_p) class c_bool(_SimpleCData): _type_ = "?" from _ctypes import POINTER, pointer, _pointer_type_cache class c_wchar_p(_SimpleCData): _type_ = "Z" def __repr__(self): return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) class c_wchar(_SimpleCData): _type_ = "u" def _reset_cache(): _pointer_type_cache.clear() _c_functype_cache.clear() if _os.name == "nt": _win_functype_cache.clear() # _SimpleCData.c_wchar_p_from_param POINTER(c_wchar).from_param = c_wchar_p.from_param # _SimpleCData.c_char_p_from_param POINTER(c_char).from_param = c_char_p.from_param _pointer_type_cache[None] = c_void_p def create_unicode_buffer(init, size=None): """create_unicode_buffer(aString) -> character array create_unicode_buffer(anInteger) -> character array create_unicode_buffer(aString, anInteger) -> character array """ if isinstance(init, str): if size is None: size = len(init)+1 buftype = c_wchar * size buf = buftype() buf.value = init return buf elif isinstance(init, int): buftype = c_wchar * init buf = buftype() return buf raise TypeError(init) # XXX Deprecated def SetPointerType(pointer, cls): if _pointer_type_cache.get(cls, None) is not None: raise RuntimeError("This type already exists in the cache") if id(pointer) not in _pointer_type_cache: raise RuntimeError("What's this???") pointer.set_type(cls) _pointer_type_cache[cls] = pointer del _pointer_type_cache[id(pointer)] # XXX Deprecated def ARRAY(typ, len): return typ * len ################################################################ class CDLL(object): """An instance of this class represents a loaded dll/shared library, exporting functions using the standard C calling convention (named 'cdecl' on Windows). The exported functions can be accessed as attributes, or by indexing with the function name. Examples: .qsort -> callable object ['qsort'] -> callable object Calling the functions releases the Python GIL during the call and reacquires it afterwards. """ _func_flags_ = _FUNCFLAG_CDECL _func_restype_ = c_int # default values for repr _name = '' _handle = 0 _FuncPtr = None def __init__(self, name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False): self._name = name flags = self._func_flags_ if use_errno: flags |= _FUNCFLAG_USE_ERRNO if use_last_error: flags |= _FUNCFLAG_USE_LASTERROR class _FuncPtr(_CFuncPtr): _flags_ = flags _restype_ = self._func_restype_ self._FuncPtr = _FuncPtr if handle is None: self._handle = _dlopen(self._name, mode) else: self._handle = handle def __repr__(self): return "<%s '%s', handle %x at %#x>" % \ (self.__class__.__name__, self._name, (self._handle & (_sys.maxsize*2 + 1)), id(self) & (_sys.maxsize*2 + 1)) def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): raise AttributeError(name) func = self.__getitem__(name) setattr(self, name, func) return func def __getitem__(self, name_or_ordinal): func = self._FuncPtr((name_or_ordinal, self)) if not isinstance(name_or_ordinal, int): func.__name__ = name_or_ordinal return func class PyDLL(CDLL): """This class represents the Python library itself. It allows accessing Python API functions. The GIL is not released, and Python exceptions are handled correctly. """ _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI if _os.name == "nt": class WinDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention. """ _func_flags_ = _FUNCFLAG_STDCALL # XXX Hm, what about HRESULT as normal parameter? # Mustn't it derive from c_long then? from _ctypes import _check_HRESULT, _SimpleCData class HRESULT(_SimpleCData): _type_ = "l" # _check_retval_ is called with the function's result when it # is used as restype. It checks for the FAILED bit, and # raises an OSError if it is set. # # The _check_retval_ method is implemented in C, so that the # method definition itself is not included in the traceback # when it raises an error - that is what we want (and Python # doesn't have a way to raise an exception in the caller's # frame). _check_retval_ = _check_HRESULT class OleDLL(CDLL): """This class represents a dll exporting functions using the Windows stdcall calling convention, and returning HRESULT. HRESULT error values are automatically raised as OSError exceptions. """ _func_flags_ = _FUNCFLAG_STDCALL _func_restype_ = HRESULT class LibraryLoader(object): def __init__(self, dlltype): self._dlltype = dlltype def __getattr__(self, name): if name[0] == '_': raise AttributeError(name) dll = self._dlltype(name) setattr(self, name, dll) return dll def __getitem__(self, name): return getattr(self, name) def LoadLibrary(self, name): return self._dlltype(name) cdll = LibraryLoader(CDLL) pydll = LibraryLoader(PyDLL) if _os.name == "nt": pythonapi = PyDLL("python dll", None, _sys.dllhandle) elif _sys.platform == "cygwin": pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) else: pythonapi = PyDLL(None) if _os.name == "nt": windll = LibraryLoader(WinDLL) oledll = LibraryLoader(OleDLL) if _os.name == "nt": GetLastError = windll.kernel32.GetLastError else: GetLastError = windll.coredll.GetLastError from _ctypes import get_last_error, set_last_error def WinError(code=None, descr=None): if code is None: code = GetLastError() if descr is None: descr = FormatError(code).strip() return OSError(None, descr, None, code) if sizeof(c_uint) == sizeof(c_void_p): c_size_t = c_uint c_ssize_t = c_int elif sizeof(c_ulong) == sizeof(c_void_p): c_size_t = c_ulong c_ssize_t = c_long elif sizeof(c_ulonglong) == sizeof(c_void_p): c_size_t = c_ulonglong c_ssize_t = c_longlong # functions from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr ## void *memmove(void *, const void *, size_t); memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) ## void *memset(void *, int, size_t) memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) def PYFUNCTYPE(restype, *argtypes): class CFunctionType(_CFuncPtr): _argtypes_ = argtypes _restype_ = restype _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI return CFunctionType _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) def cast(obj, typ): return _cast(obj, obj, typ) _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) def string_at(ptr, size=-1): """string_at(addr[, size]) -> string Return the string at addr.""" return _string_at(ptr, size) try: from _ctypes import _wstring_at_addr except ImportError: pass else: _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) def wstring_at(ptr, size=-1): """wstring_at(addr[, size]) -> string Return the string at addr.""" return _wstring_at(ptr, size) if _os.name == "nt": # COM stuff def DllGetClassObject(rclsid, riid, ppv): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return -2147221231 # CLASS_E_CLASSNOTAVAILABLE else: return ccom.DllGetClassObject(rclsid, riid, ppv) def DllCanUnloadNow(): try: ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) except ImportError: return 0 # S_OK return ccom.DllCanUnloadNow() from ctypes._endian import BigEndianStructure, LittleEndianStructure # Fill in specifically-sized types c_int8 = c_byte c_uint8 = c_ubyte for kind in [c_short, c_int, c_long, c_longlong]: if sizeof(kind) == 2: c_int16 = kind elif sizeof(kind) == 4: c_int32 = kind elif sizeof(kind) == 8: c_int64 = kind for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]: if sizeof(kind) == 2: c_uint16 = kind elif sizeof(kind) == 4: c_uint32 = kind elif sizeof(kind) == 8: c_uint64 = kind del(kind) _reset_cache() usr/lib64/python3.8/ctypes/macholib/__init__.py000064400000000232152350146140015243 0ustar00""" Enough Mach-O to make your head spin. See the relevant header files in /usr/include/mach-o And also Apple's documentation. """ __version__ = '1.0' lib64/python3.12/xml/__init__.py000064400000001055152350166000012221 0ustar00"""Core XML support for Python. This package contains four sub-packages: dom -- The W3C Document Object Model. This supports DOM Level 1 + Namespaces. parsers -- Python wrappers for XML parsers (currently only supports Expat). sax -- The Simple API for XML, developed by XML-Dev, led by David Megginson and ported to Python by Lars Marius Garshol. This supports the SAX 2 API. etree -- The ElementTree XML library. This is a subset of the full ElementTree XML release. """ __all__ = ["dom", "parsers", "sax", "etree"] lib64/python3.6/xml/sax/__init__.py000064400000007056152350171570012756 0ustar00"""Simple API for XML (SAX) implementation for Python. This module provides an implementation of the SAX 2 interface; information about the Java version of the interface can be found at http://www.megginson.com/SAX/. The Python version of the interface is documented at <...>. This package contains the following modules: handler -- Base classes and constants which define the SAX 2 API for the 'client-side' of SAX for Python. saxutils -- Implementation of the convenience classes commonly used to work with SAX. xmlreader -- Base classes and constants which define the SAX 2 API for the parsers used with SAX for Python. expatreader -- Driver that allows use of the Expat parser with SAX. """ from .xmlreader import InputSource from .handler import ContentHandler, ErrorHandler from ._exceptions import SAXException, SAXNotRecognizedException, \ SAXParseException, SAXNotSupportedException, \ SAXReaderNotAvailable def parse(source, handler, errorHandler=ErrorHandler()): parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) parser.parse(source) def parseString(string, handler, errorHandler=ErrorHandler()): import io if errorHandler is None: errorHandler = ErrorHandler() parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) inpsrc = InputSource() if isinstance(string, str): inpsrc.setCharacterStream(io.StringIO(string)) else: inpsrc.setByteStream(io.BytesIO(string)) parser.parse(inpsrc) # this is the parser list used by the make_parser function if no # alternatives are given as parameters to the function default_parser_list = ["xml.sax.expatreader"] # tell modulefinder that importing sax potentially imports expatreader _false = 0 if _false: import xml.sax.expatreader import os, sys if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ: default_parser_list = os.environ["PY_SAX_PARSER"].split(",") del os _key = "python.xml.sax.parser" if sys.platform[:4] == "java" and sys.registry.containsKey(_key): default_parser_list = sys.registry.getProperty(_key).split(",") def make_parser(parser_list = []): """Creates and returns a SAX parser. Creates the first parser it is able to instantiate of the ones given in the list created by doing parser_list + default_parser_list. The lists must contain the names of Python modules containing both a SAX parser and a create_parser function.""" for parser_name in parser_list + default_parser_list: try: return _create_parser(parser_name) except ImportError as e: import sys if parser_name in sys.modules: # The parser module was found, but importing it # failed unexpectedly, pass this exception through raise except SAXReaderNotAvailable: # The parser module detected that it won't work properly, # so try the next one pass raise SAXReaderNotAvailable("No parsers found", None) # --- Internal utility methods used by make_parser if sys.platform[ : 4] == "java": def _create_parser(parser_name): from org.python.core import imp drv_module = imp.importName(parser_name, 0, globals()) return drv_module.create_parser() else: def _create_parser(parser_name): drv_module = __import__(parser_name,{},{},['create_parser']) return drv_module.create_parser() del sys lib64/python3.8/concurrent/__init__.py000064400000000046152350221730013531 0ustar00# This directory is a Python package. usr/lib64/python3.12/ensurepip/__init__.py000064400000022345152350262100014247 0ustar00import collections import os import os.path import subprocess import sys import sysconfig import tempfile from importlib import resources __all__ = ["version", "bootstrap"] _PACKAGE_NAMES = ('pip',) _PIP_VERSION = "25.0.1" _PROJECTS = [ ("pip", _PIP_VERSION, "py3"), ] # Packages bundled in ensurepip._bundled have wheel_name set. # Packages from WHEEL_PKG_DIR have wheel_path set. _Package = collections.namedtuple('Package', ('version', 'wheel_name', 'wheel_path')) # Directory of system wheel packages. Some Linux distribution packaging # policies recommend against bundling dependencies. For example, Fedora # installs wheel packages in the /usr/share/python-wheels/ directory and don't # install the ensurepip._bundled package. _WHEEL_PKG_DIR = sysconfig.get_config_var('WHEEL_PKG_DIR') def _find_packages(path): packages = {} try: filenames = os.listdir(path) except OSError: # Ignore: path doesn't exist or permission error filenames = () # Make the code deterministic if a directory contains multiple wheel files # of the same package, but don't attempt to implement correct version # comparison since this case should not happen. filenames = sorted(filenames) for filename in filenames: # filename is like 'pip-21.2.4-py3-none-any.whl' if not filename.endswith(".whl"): continue for name in _PACKAGE_NAMES: prefix = name + '-' if filename.startswith(prefix): break else: continue # Extract '21.2.4' from 'pip-21.2.4-py3-none-any.whl' version = filename.removeprefix(prefix).partition('-')[0] wheel_path = os.path.join(path, filename) packages[name] = _Package(version, None, wheel_path) return packages def _get_packages(): global _PACKAGES, _WHEEL_PKG_DIR if _PACKAGES is not None: return _PACKAGES packages = {} for name, version, py_tag in _PROJECTS: wheel_name = f"{name}-{version}-{py_tag}-none-any.whl" packages[name] = _Package(version, wheel_name, None) if _WHEEL_PKG_DIR: dir_packages = _find_packages(_WHEEL_PKG_DIR) # only used the wheel package directory if all packages are found there if all(name in dir_packages for name in _PACKAGE_NAMES): packages = dir_packages _PACKAGES = packages return packages _PACKAGES = None def _run_pip(args, additional_paths=None): # Run the bootstrapping in a subprocess to avoid leaking any state that happens # after pip has executed. Particularly, this avoids the case when pip holds onto # the files in *additional_paths*, preventing us to remove them at the end of the # invocation. code = f""" import runpy import sys sys.path = {additional_paths or []} + sys.path sys.argv[1:] = {args} runpy.run_module("pip", run_name="__main__", alter_sys=True) """ cmd = [ sys.executable, '-W', 'ignore::DeprecationWarning', '-c', code, ] if sys.flags.isolated: # run code in isolated mode if currently running isolated cmd.insert(1, '-I') return subprocess.run(cmd, check=True).returncode def version(): """ Returns a string specifying the bundled version of pip. """ return _get_packages()['pip'].version def _disable_pip_configuration_settings(): # We deliberately ignore all pip environment variables # when invoking pip # See http://bugs.python.org/issue19734 for details keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] for k in keys_to_remove: del os.environ[k] # We also ignore the settings in the default pip configuration file # See http://bugs.python.org/issue20053 for details os.environ['PIP_CONFIG_FILE'] = os.devnull def bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Note that calling this function will alter both sys.path and os.environ. """ # Discard the return value _bootstrap(root=root, upgrade=upgrade, user=user, altinstall=altinstall, default_pip=default_pip, verbosity=verbosity) def _bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, verbosity=0): """ Bootstrap pip into the current Python installation (or the given root directory). Returns pip command status code. Note that calling this function will alter both sys.path and os.environ. """ if altinstall and default_pip: raise ValueError("Cannot use altinstall and default_pip together") sys.audit("ensurepip.bootstrap", root) _disable_pip_configuration_settings() # By default, installing pip installs all of the # following scripts (X.Y == running Python version): # # pip, pipX, pipX.Y # # pip 1.5+ allows ensurepip to request that some of those be left out if altinstall: # omit pip, pipX os.environ["ENSUREPIP_OPTIONS"] = "altinstall" elif not default_pip: # omit pip os.environ["ENSUREPIP_OPTIONS"] = "install" with tempfile.TemporaryDirectory() as tmpdir: # Put our bundled wheels into a temporary directory and construct the # additional paths that need added to sys.path additional_paths = [] for name, package in _get_packages().items(): if package.wheel_name: # Use bundled wheel package wheel_name = package.wheel_name wheel_path = resources.files("ensurepip") / "_bundled" / wheel_name whl = wheel_path.read_bytes() else: # Use the wheel package directory with open(package.wheel_path, "rb") as fp: whl = fp.read() wheel_name = os.path.basename(package.wheel_path) filename = os.path.join(tmpdir, wheel_name) with open(filename, "wb") as fp: fp.write(whl) additional_paths.append(filename) # Construct the arguments to be passed to the pip command args = ["install", "--no-cache-dir", "--no-index", "--find-links", tmpdir] if root: args += ["--root", root] if upgrade: args += ["--upgrade"] if user: args += ["--user"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip([*args, *_PACKAGE_NAMES], additional_paths) def _uninstall_helper(*, verbosity=0): """Helper to support a clean default uninstall process on Windows Note that calling this function may alter os.environ. """ # Nothing to do if pip was never installed, or has been removed try: import pip except ImportError: return # If the installed pip version doesn't match the available one, # leave it alone available_version = version() if pip.__version__ != available_version: print(f"ensurepip will only uninstall a matching version " f"({pip.__version__!r} installed, " f"{available_version!r} available)", file=sys.stderr) return _disable_pip_configuration_settings() # Construct the arguments to be passed to the pip command args = ["uninstall", "-y", "--disable-pip-version-check"] if verbosity: args += ["-" + "v" * verbosity] return _run_pip([*args, *reversed(_PACKAGE_NAMES)]) def _main(argv=None): import argparse parser = argparse.ArgumentParser(prog="python -m ensurepip") parser.add_argument( "--version", action="version", version="pip {}".format(version()), help="Show the version of pip that is bundled with this Python.", ) parser.add_argument( "-v", "--verbose", action="count", default=0, dest="verbosity", help=("Give more output. Option is additive, and can be used up to 3 " "times."), ) parser.add_argument( "-U", "--upgrade", action="store_true", default=False, help="Upgrade pip and dependencies, even if already installed.", ) parser.add_argument( "--user", action="store_true", default=False, help="Install using the user scheme.", ) parser.add_argument( "--root", default=None, help="Install everything relative to this alternate root directory.", ) parser.add_argument( "--altinstall", action="store_true", default=False, help=("Make an alternate install, installing only the X.Y versioned " "scripts (Default: pipX, pipX.Y)."), ) parser.add_argument( "--default-pip", action="store_true", default=False, help=("Make a default pip install, installing the unqualified pip " "in addition to the versioned scripts."), ) args = parser.parse_args(argv) return _bootstrap( root=args.root, upgrade=args.upgrade, user=args.user, verbosity=args.verbosity, altinstall=args.altinstall, default_pip=args.default_pip, ) lib64/python2.7/xml/dom/__init__.py000064400000007636152350272130012740 0ustar00"""W3C Document Object Model implementation for Python. The Python mapping of the Document Object Model is documented in the Python Library Reference in the section on the xml.dom package. This package contains the following modules: minidom -- A simple implementation of the Level 1 DOM with namespace support added (based on the Level 2 specification) and other minor Level 2 functionality. pulldom -- DOM builder supporting on-demand tree-building for selected subtrees of the document. """ class Node: """Class giving the NodeType constants.""" # DOM implementations may use this as a base class for their own # Node implementations. If they don't, the constants defined here # should still be used as the canonical definitions as they match # the values given in the W3C recommendation. Client code can # safely refer to these values in all tests of Node.nodeType # values. ELEMENT_NODE = 1 ATTRIBUTE_NODE = 2 TEXT_NODE = 3 CDATA_SECTION_NODE = 4 ENTITY_REFERENCE_NODE = 5 ENTITY_NODE = 6 PROCESSING_INSTRUCTION_NODE = 7 COMMENT_NODE = 8 DOCUMENT_NODE = 9 DOCUMENT_TYPE_NODE = 10 DOCUMENT_FRAGMENT_NODE = 11 NOTATION_NODE = 12 #ExceptionCode INDEX_SIZE_ERR = 1 DOMSTRING_SIZE_ERR = 2 HIERARCHY_REQUEST_ERR = 3 WRONG_DOCUMENT_ERR = 4 INVALID_CHARACTER_ERR = 5 NO_DATA_ALLOWED_ERR = 6 NO_MODIFICATION_ALLOWED_ERR = 7 NOT_FOUND_ERR = 8 NOT_SUPPORTED_ERR = 9 INUSE_ATTRIBUTE_ERR = 10 INVALID_STATE_ERR = 11 SYNTAX_ERR = 12 INVALID_MODIFICATION_ERR = 13 NAMESPACE_ERR = 14 INVALID_ACCESS_ERR = 15 VALIDATION_ERR = 16 class DOMException(Exception): """Abstract base class for DOM exceptions. Exceptions with specific codes are specializations of this class.""" def __init__(self, *args, **kw): if self.__class__ is DOMException: raise RuntimeError( "DOMException should not be instantiated directly") Exception.__init__(self, *args, **kw) def _get_code(self): return self.code class IndexSizeErr(DOMException): code = INDEX_SIZE_ERR class DomstringSizeErr(DOMException): code = DOMSTRING_SIZE_ERR class HierarchyRequestErr(DOMException): code = HIERARCHY_REQUEST_ERR class WrongDocumentErr(DOMException): code = WRONG_DOCUMENT_ERR class InvalidCharacterErr(DOMException): code = INVALID_CHARACTER_ERR class NoDataAllowedErr(DOMException): code = NO_DATA_ALLOWED_ERR class NoModificationAllowedErr(DOMException): code = NO_MODIFICATION_ALLOWED_ERR class NotFoundErr(DOMException): code = NOT_FOUND_ERR class NotSupportedErr(DOMException): code = NOT_SUPPORTED_ERR class InuseAttributeErr(DOMException): code = INUSE_ATTRIBUTE_ERR class InvalidStateErr(DOMException): code = INVALID_STATE_ERR class SyntaxErr(DOMException): code = SYNTAX_ERR class InvalidModificationErr(DOMException): code = INVALID_MODIFICATION_ERR class NamespaceErr(DOMException): code = NAMESPACE_ERR class InvalidAccessErr(DOMException): code = INVALID_ACCESS_ERR class ValidationErr(DOMException): code = VALIDATION_ERR class UserDataHandler: """Class giving the operation constants for UserDataHandler.handle().""" # Based on DOM Level 3 (WD 9 April 2002) NODE_CLONED = 1 NODE_IMPORTED = 2 NODE_DELETED = 3 NODE_RENAMED = 4 XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml" EMPTY_NAMESPACE = None EMPTY_PREFIX = None from domreg import getDOMImplementation,registerDOMImplementation lib64/python3.8/xml/parsers/__init__.py000064400000000247152350315540013634 0ustar00"""Python interfaces to XML parsers. This package contains one module: expat -- Python wrapper for James Clark's Expat parser, with namespace support. """ lib64/python2.7/test/__init__.py000064400000000057152350316160012330 0ustar00# Dummy file to make this directory a package. lib64/python3.6/importlib/__init__.py000064400000013356152350317510013360 0ustar00"""A pure Python implementation of import.""" __all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload'] # Bootstrap help ##################################################### # Until bootstrapping is complete, DO NOT import any modules that attempt # to import importlib._bootstrap (directly or indirectly). Since this # partially initialised package would be present in sys.modules, those # modules would get an uninitialised copy of the source version, instead # of a fully initialised version (either the frozen one or the one # initialised below if the frozen one is not available). import _imp # Just the builtin component, NOT the full Python module import sys try: import _frozen_importlib as _bootstrap except ImportError: from . import _bootstrap _bootstrap._setup(sys, _imp) else: # importlib._bootstrap is the built-in import, ensure we don't create # a second copy of the module. _bootstrap.__name__ = 'importlib._bootstrap' _bootstrap.__package__ = 'importlib' try: _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap'] = _bootstrap try: import _frozen_importlib_external as _bootstrap_external except ImportError: from . import _bootstrap_external _bootstrap_external._setup(_bootstrap) _bootstrap._bootstrap_external = _bootstrap_external else: _bootstrap_external.__name__ = 'importlib._bootstrap_external' _bootstrap_external.__package__ = 'importlib' try: _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap_external'] = _bootstrap_external # To simplify imports in test code _w_long = _bootstrap_external._w_long _r_long = _bootstrap_external._r_long # Fully bootstrapped at this point, import whatever you like, circular # dependencies and startup overhead minimisation permitting :) import types import warnings # Public API ######################################################### from ._bootstrap import __import__ def invalidate_caches(): """Call the invalidate_caches() method on all meta path finders stored in sys.meta_path (where implemented).""" for finder in sys.meta_path: if hasattr(finder, 'invalidate_caches'): finder.invalidate_caches() def find_loader(name, path=None): """Return the loader for the specified module. This is a backward-compatible wrapper around find_spec(). This function is deprecated in favor of importlib.util.find_spec(). """ warnings.warn('Use importlib.util.find_spec() instead.', DeprecationWarning, stacklevel=2) try: loader = sys.modules[name].__loader__ if loader is None: raise ValueError('{}.__loader__ is None'.format(name)) else: return loader except KeyError: pass except AttributeError: raise ValueError('{}.__loader__ is not set'.format(name)) from None spec = _bootstrap._find_spec(name, path) # We won't worry about malformed specs (missing attributes). if spec is None: return None if spec.loader is None: if spec.submodule_search_locations is None: raise ImportError('spec for {} missing loader'.format(name), name=name) raise ImportError('namespace packages do not have loaders', name=name) return spec.loader def import_module(name, package=None): """Import a module. The 'package' argument is required when performing a relative import. It specifies the package to use as the anchor point from which to resolve the relative import to an absolute import. """ level = 0 if name.startswith('.'): if not package: msg = ("the 'package' argument is required to perform a relative " "import for {!r}") raise TypeError(msg.format(name)) for character in name: if character != '.': break level += 1 return _bootstrap._gcd_import(name[level:], package, level) _RELOADING = {} def reload(module): """Reload the module and return it. The module must have been successfully imported before. """ if not module or not isinstance(module, types.ModuleType): raise TypeError("reload() argument must be a module") try: name = module.__spec__.name except AttributeError: name = module.__name__ if sys.modules.get(name) is not module: msg = "module {} not in sys.modules" raise ImportError(msg.format(name), name=name) if name in _RELOADING: return _RELOADING[name] _RELOADING[name] = module try: parent_name = name.rpartition('.')[0] if parent_name: try: parent = sys.modules[parent_name] except KeyError: msg = "parent {!r} not in sys.modules" raise ImportError(msg.format(parent_name), name=parent_name) from None else: pkgpath = parent.__path__ else: pkgpath = None target = module spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) _bootstrap._exec(spec, module) # The module may have replaced itself in sys.modules! return sys.modules[name] finally: try: del _RELOADING[name] except KeyError: pass lib64/python3.8/xml/dom/__init__.py000064400000007663152350424260012745 0ustar00"""W3C Document Object Model implementation for Python. The Python mapping of the Document Object Model is documented in the Python Library Reference in the section on the xml.dom package. This package contains the following modules: minidom -- A simple implementation of the Level 1 DOM with namespace support added (based on the Level 2 specification) and other minor Level 2 functionality. pulldom -- DOM builder supporting on-demand tree-building for selected subtrees of the document. """ class Node: """Class giving the NodeType constants.""" __slots__ = () # DOM implementations may use this as a base class for their own # Node implementations. If they don't, the constants defined here # should still be used as the canonical definitions as they match # the values given in the W3C recommendation. Client code can # safely refer to these values in all tests of Node.nodeType # values. ELEMENT_NODE = 1 ATTRIBUTE_NODE = 2 TEXT_NODE = 3 CDATA_SECTION_NODE = 4 ENTITY_REFERENCE_NODE = 5 ENTITY_NODE = 6 PROCESSING_INSTRUCTION_NODE = 7 COMMENT_NODE = 8 DOCUMENT_NODE = 9 DOCUMENT_TYPE_NODE = 10 DOCUMENT_FRAGMENT_NODE = 11 NOTATION_NODE = 12 #ExceptionCode INDEX_SIZE_ERR = 1 DOMSTRING_SIZE_ERR = 2 HIERARCHY_REQUEST_ERR = 3 WRONG_DOCUMENT_ERR = 4 INVALID_CHARACTER_ERR = 5 NO_DATA_ALLOWED_ERR = 6 NO_MODIFICATION_ALLOWED_ERR = 7 NOT_FOUND_ERR = 8 NOT_SUPPORTED_ERR = 9 INUSE_ATTRIBUTE_ERR = 10 INVALID_STATE_ERR = 11 SYNTAX_ERR = 12 INVALID_MODIFICATION_ERR = 13 NAMESPACE_ERR = 14 INVALID_ACCESS_ERR = 15 VALIDATION_ERR = 16 class DOMException(Exception): """Abstract base class for DOM exceptions. Exceptions with specific codes are specializations of this class.""" def __init__(self, *args, **kw): if self.__class__ is DOMException: raise RuntimeError( "DOMException should not be instantiated directly") Exception.__init__(self, *args, **kw) def _get_code(self): return self.code class IndexSizeErr(DOMException): code = INDEX_SIZE_ERR class DomstringSizeErr(DOMException): code = DOMSTRING_SIZE_ERR class HierarchyRequestErr(DOMException): code = HIERARCHY_REQUEST_ERR class WrongDocumentErr(DOMException): code = WRONG_DOCUMENT_ERR class InvalidCharacterErr(DOMException): code = INVALID_CHARACTER_ERR class NoDataAllowedErr(DOMException): code = NO_DATA_ALLOWED_ERR class NoModificationAllowedErr(DOMException): code = NO_MODIFICATION_ALLOWED_ERR class NotFoundErr(DOMException): code = NOT_FOUND_ERR class NotSupportedErr(DOMException): code = NOT_SUPPORTED_ERR class InuseAttributeErr(DOMException): code = INUSE_ATTRIBUTE_ERR class InvalidStateErr(DOMException): code = INVALID_STATE_ERR class SyntaxErr(DOMException): code = SYNTAX_ERR class InvalidModificationErr(DOMException): code = INVALID_MODIFICATION_ERR class NamespaceErr(DOMException): code = NAMESPACE_ERR class InvalidAccessErr(DOMException): code = INVALID_ACCESS_ERR class ValidationErr(DOMException): code = VALIDATION_ERR class UserDataHandler: """Class giving the operation constants for UserDataHandler.handle().""" # Based on DOM Level 3 (WD 9 April 2002) NODE_CLONED = 1 NODE_IMPORTED = 2 NODE_DELETED = 3 NODE_RENAMED = 4 XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml" EMPTY_NAMESPACE = None EMPTY_PREFIX = None from .domreg import getDOMImplementation, registerDOMImplementation lib64/python3.6/sqlite3/__init__.py000064400000001772152350425540012745 0ustar00# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. from sqlite3.dbapi2 import * usr/lib/python3.6/site-packages/slip/__init__.py000064400000000000152350475250015471 0ustar00lib64/python3.12/xml/sax/__init__.py000064400000006246152350536200013026 0ustar00"""Simple API for XML (SAX) implementation for Python. This module provides an implementation of the SAX 2 interface; information about the Java version of the interface can be found at http://www.megginson.com/SAX/. The Python version of the interface is documented at <...>. This package contains the following modules: handler -- Base classes and constants which define the SAX 2 API for the 'client-side' of SAX for Python. saxutils -- Implementation of the convenience classes commonly used to work with SAX. xmlreader -- Base classes and constants which define the SAX 2 API for the parsers used with SAX for Python. expatreader -- Driver that allows use of the Expat parser with SAX. """ from .xmlreader import InputSource from .handler import ContentHandler, ErrorHandler from ._exceptions import SAXException, SAXNotRecognizedException, \ SAXParseException, SAXNotSupportedException, \ SAXReaderNotAvailable def parse(source, handler, errorHandler=ErrorHandler()): parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) parser.parse(source) def parseString(string, handler, errorHandler=ErrorHandler()): import io if errorHandler is None: errorHandler = ErrorHandler() parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) inpsrc = InputSource() if isinstance(string, str): inpsrc.setCharacterStream(io.StringIO(string)) else: inpsrc.setByteStream(io.BytesIO(string)) parser.parse(inpsrc) # this is the parser list used by the make_parser function if no # alternatives are given as parameters to the function default_parser_list = ["xml.sax.expatreader"] # tell modulefinder that importing sax potentially imports expatreader _false = 0 if _false: import xml.sax.expatreader import os, sys if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ: default_parser_list = os.environ["PY_SAX_PARSER"].split(",") del os, sys def make_parser(parser_list=()): """Creates and returns a SAX parser. Creates the first parser it is able to instantiate of the ones given in the iterable created by chaining parser_list and default_parser_list. The iterables must contain the names of Python modules containing both a SAX parser and a create_parser function.""" for parser_name in list(parser_list) + default_parser_list: try: return _create_parser(parser_name) except ImportError: import sys if parser_name in sys.modules: # The parser module was found, but importing it # failed unexpectedly, pass this exception through raise except SAXReaderNotAvailable: # The parser module detected that it won't work properly, # so try the next one pass raise SAXReaderNotAvailable("No parsers found", None) # --- Internal utility methods used by make_parser def _create_parser(parser_name): drv_module = __import__(parser_name,{},{},['create_parser']) return drv_module.create_parser() usr/lib64/python3.8/curses/__init__.py000064400000007330152350540720013472 0ustar00"""curses The main package for curses support for Python. Normally used by importing the package, and perhaps a particular module inside it. import curses from curses import textpad curses.initscr() ... """ from _curses import * import os as _os import sys as _sys # Some constants, most notably the ACS_* ones, are only added to the C # _curses module's dictionary after initscr() is called. (Some # versions of SGI's curses don't define values for those constants # until initscr() has been called.) This wrapper function calls the # underlying C initscr(), and then copies the constants from the # _curses module to the curses package's dictionary. Don't do 'from # curses import *' if you'll be needing the ACS_* constants. def initscr(): import _curses, curses # we call setupterm() here because it raises an error # instead of calling exit() in error cases. setupterm(term=_os.environ.get("TERM", "unknown"), fd=_sys.__stdout__.fileno()) stdscr = _curses.initscr() for key, value in _curses.__dict__.items(): if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): setattr(curses, key, value) return stdscr # This is a similar wrapper for start_color(), which adds the COLORS and # COLOR_PAIRS variables which are only available after start_color() is # called. def start_color(): import _curses, curses retval = _curses.start_color() if hasattr(_curses, 'COLORS'): curses.COLORS = _curses.COLORS if hasattr(_curses, 'COLOR_PAIRS'): curses.COLOR_PAIRS = _curses.COLOR_PAIRS return retval # Import Python has_key() implementation if _curses doesn't contain has_key() try: has_key except NameError: from .has_key import has_key # Wrapper for the entire curses-based application. Runs a function which # should be the rest of your curses-based application. If the application # raises an exception, wrapper() will restore the terminal to a sane state so # you can read the resulting traceback. def wrapper(*args, **kwds): """Wrapper function that initializes curses and calls another function, restoring normal keyboard/screen behavior on error. The callable object 'func' is then passed the main window 'stdscr' as its first argument, followed by any other arguments passed to wrapper(). """ if args: func, *args = args elif 'func' in kwds: func = kwds.pop('func') import warnings warnings.warn("Passing 'func' as keyword argument is deprecated", DeprecationWarning, stacklevel=2) else: raise TypeError('wrapper expected at least 1 positional argument, ' 'got %d' % len(args)) try: # Initialize curses stdscr = initscr() # Turn off echoing of keys, and enter cbreak mode, # where no buffering is performed on keyboard input noecho() cbreak() # In keypad mode, escape sequences for special keys # (like the cursor keys) will be interpreted and # a special value like curses.KEY_LEFT will be returned stdscr.keypad(1) # Start color, too. Harmless if the terminal doesn't have # color; user can test with has_color() later on. The try/catch # works around a minor bit of over-conscientiousness in the curses # module -- the error return from C start_color() is ignorable. try: start_color() except: pass return func(stdscr, *args, **kwds) finally: # Set everything back to normal if 'stdscr' in locals(): stdscr.keypad(0) echo() nocbreak() endwin() wrapper.__text_signature__ = '(func, /, *args, **kwds)' lib64/python3.12/xml/parsers/__init__.py000064400000000247152350566340013715 0ustar00"""Python interfaces to XML parsers. This package contains one module: expat -- Python wrapper for James Clark's Expat parser, with namespace support. """ usr/lib64/python3.6/collections/__init__.py000064400000131364152350753030014507 0ustar00'''This module implements specialized container datatypes providing alternatives to Python's general purpose built-in containers, dict, list, set, and tuple. * namedtuple factory function for creating tuple subclasses with named fields * deque list-like container with fast appends and pops on either end * ChainMap dict-like class for creating a single view of multiple mappings * Counter dict subclass for counting hashable objects * OrderedDict dict subclass that remembers the order entries were added * defaultdict dict subclass that calls a factory function to supply missing values * UserDict wrapper around dictionary objects for easier dict subclassing * UserList wrapper around list objects for easier list subclassing * UserString wrapper around string objects for easier string subclassing ''' __all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 'UserString', 'Counter', 'OrderedDict', 'ChainMap'] # For backwards compatibility, continue to make the collections ABCs # available through the collections module. from _collections_abc import * import _collections_abc __all__ += _collections_abc.__all__ from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq from _weakref import proxy as _proxy from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from reprlib import recursive_repr as _recursive_repr try: from _collections import deque except ImportError: pass else: MutableSequence.register(deque) try: from _collections import defaultdict except ImportError: pass ################################################################################ ### OrderedDict ################################################################################ class _OrderedDictKeysView(KeysView): def __reversed__(self): yield from reversed(self._mapping) class _OrderedDictItemsView(ItemsView): def __reversed__(self): for key in reversed(self._mapping): yield (key, self._mapping[key]) class _OrderedDictValuesView(ValuesView): def __reversed__(self): for key in reversed(self._mapping): yield self._mapping[key] class _Link(object): __slots__ = 'prev', 'next', 'key', '__weakref__' class OrderedDict(dict): 'Dictionary that remembers insertion order' # An inherited dict maps keys to values. # The inherited dict provides __getitem__, __len__, __contains__, and get. # The remaining methods are order-aware. # Big-O running times for all methods are the same as regular dictionaries. # The internal self.__map dict maps keys to links in a doubly linked list. # The circular doubly linked list starts and ends with a sentinel element. # The sentinel element never gets deleted (this simplifies the algorithm). # The sentinel is in self.__hardroot with a weakref proxy in self.__root. # The prev links are weakref proxies (to prevent circular references). # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. def __init__(*args, **kwds): '''Initialize an ordered dictionary. The signature is the same as regular dictionaries. Keyword argument order is preserved. ''' if not args: raise TypeError("descriptor '__init__' of 'OrderedDict' object " "needs an argument") self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: self.__root except AttributeError: self.__hardroot = _Link() self.__root = root = _proxy(self.__hardroot) root.prev = root.next = root self.__map = {} self.__update(*args, **kwds) def __setitem__(self, key, value, dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link): 'od.__setitem__(i, y) <==> od[i]=y' # Setting a new item creates a new link at the end of the linked list, # and the inherited dictionary is updated with the new key/value pair. if key not in self: self.__map[key] = link = Link() root = self.__root last = root.prev link.prev, link.next, link.key = last, root, key last.next = link root.prev = proxy(link) dict_setitem(self, key, value) def __delitem__(self, key, dict_delitem=dict.__delitem__): 'od.__delitem__(y) <==> del od[y]' # Deleting an existing item uses self.__map to find the link which gets # removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link = self.__map.pop(key) link_prev = link.prev link_next = link.next link_prev.next = link_next link_next.prev = link_prev link.prev = None link.next = None def __iter__(self): 'od.__iter__() <==> iter(od)' # Traverse the linked list in order. root = self.__root curr = root.next while curr is not root: yield curr.key curr = curr.next def __reversed__(self): 'od.__reversed__() <==> reversed(od)' # Traverse the linked list in reverse order. root = self.__root curr = root.prev while curr is not root: yield curr.key curr = curr.prev def clear(self): 'od.clear() -> None. Remove all items from od.' root = self.__root root.prev = root.next = root self.__map.clear() dict.clear(self) def popitem(self, last=True): '''Remove and return a (key, value) pair from the dictionary. Pairs are returned in LIFO order if last is true or FIFO order if false. ''' if not self: raise KeyError('dictionary is empty') root = self.__root if last: link = root.prev link_prev = link.prev link_prev.next = root root.prev = link_prev else: link = root.next link_next = link.next root.next = link_next link_next.prev = root key = link.key del self.__map[key] value = dict.pop(self, key) return key, value def move_to_end(self, key, last=True): '''Move an existing element to the end (or beginning if last==False). Raises KeyError if the element does not exist. When last=True, acts like a fast version of self[key]=self.pop(key). ''' link = self.__map[key] link_prev = link.prev link_next = link.next soft_link = link_next.prev link_prev.next = link_next link_next.prev = link_prev root = self.__root if last: last = root.prev link.prev = last link.next = root root.prev = soft_link last.next = link else: first = root.next link.prev = root link.next = first first.prev = soft_link root.next = link def __sizeof__(self): sizeof = _sys.getsizeof n = len(self) + 1 # number of links including root size = sizeof(self.__dict__) # instance dictionary size += sizeof(self.__map) * 2 # internal dict and inherited dict size += sizeof(self.__hardroot) * n # link objects size += sizeof(self.__root) * n # proxy objects return size update = __update = MutableMapping.update def keys(self): "D.keys() -> a set-like object providing a view on D's keys" return _OrderedDictKeysView(self) def items(self): "D.items() -> a set-like object providing a view on D's items" return _OrderedDictItemsView(self) def values(self): "D.values() -> an object providing a view on D's values" return _OrderedDictValuesView(self) __ne__ = MutableMapping.__ne__ __marker = object() def pop(self, key, default=__marker): '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised. ''' if key in self: result = self[key] del self[key] return result if default is self.__marker: raise KeyError(key) return default def setdefault(self, key, default=None): 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' if key in self: return self[key] self[key] = default return default @_recursive_repr() def __repr__(self): 'od.__repr__() <==> repr(od)' if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, list(self.items())) def __reduce__(self): 'Return state information for pickling' inst_dict = vars(self).copy() for k in vars(OrderedDict()): inst_dict.pop(k, None) return self.__class__, (), inst_dict or None, None, iter(self.items()) def copy(self): 'od.copy() -> a shallow copy of od' return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S. If not specified, the value defaults to None. ''' self = cls() for key in iterable: self[key] = value return self def __eq__(self, other): '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive while comparison to a regular mapping is order-insensitive. ''' if isinstance(other, OrderedDict): return dict.__eq__(self, other) and all(map(_eq, self, other)) return dict.__eq__(self, other) try: from _collections import OrderedDict except ImportError: # Leave the pure Python version in place. pass ################################################################################ ### namedtuple ################################################################################ _class_template = """\ from builtins import property as _property, tuple as _tuple from operator import itemgetter as _itemgetter from collections import OrderedDict class {typename}(tuple): '{typename}({arg_list})' __slots__ = () _fields = {field_names!r} def __new__(_cls, {arg_list}): 'Create new instance of {typename}({arg_list})' return _tuple.__new__(_cls, ({arg_list})) @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new {typename} object from a sequence or iterable' result = new(cls, iterable) if len(result) != {num_fields:d}: raise TypeError('Expected {num_fields:d} arguments, got %d' % len(result)) return result def _replace(_self, **kwds): 'Return a new {typename} object replacing specified fields with new values' result = _self._make(map(kwds.pop, {field_names!r}, _self)) if kwds: raise ValueError('Got unexpected field names: %r' % list(kwds)) return result def __repr__(self): 'Return a nicely formatted representation string' return self.__class__.__name__ + '({repr_fmt})' % self def _asdict(self): 'Return a new OrderedDict which maps field names to their values.' return OrderedDict(zip(self._fields, self)) def __getnewargs__(self): 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) {field_defs} """ _repr_template = '{name}=%r' _field_template = '''\ {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}') ''' def namedtuple(typename, field_names, *, verbose=False, rename=False, module=None): """Returns a new subclass of tuple with named fields. >>> Point = namedtuple('Point', ['x', 'y']) >>> Point.__doc__ # docstring for the new class 'Point(x, y)' >>> p = Point(11, y=22) # instantiate with positional args or keywords >>> p[0] + p[1] # indexable like a plain tuple 33 >>> x, y = p # unpack like a regular tuple >>> x, y (11, 22) >>> p.x + p.y # fields also accessible by name 33 >>> d = p._asdict() # convert to a dictionary >>> d['x'] 11 >>> Point(**d) # convert from a dictionary Point(x=11, y=22) >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields Point(x=100, y=22) """ # Validate the field names. At the user's option, either generate an error # message or automatically replace the field name with a valid name. if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() field_names = list(map(str, field_names)) typename = str(typename) if rename: seen = set() for index, name in enumerate(field_names): if (not name.isidentifier() or _iskeyword(name) or name.startswith('_') or name in seen): field_names[index] = '_%d' % index seen.add(name) for name in [typename] + field_names: if type(name) is not str: raise TypeError('Type names and field names must be strings') if not name.isidentifier(): raise ValueError('Type names and field names must be valid ' 'identifiers: %r' % name) if _iskeyword(name): raise ValueError('Type names and field names cannot be a ' 'keyword: %r' % name) seen = set() for name in field_names: if name.startswith('_') and not rename: raise ValueError('Field names cannot start with an underscore: ' '%r' % name) if name in seen: raise ValueError('Encountered duplicate field name: %r' % name) seen.add(name) # Fill-in the class template class_definition = _class_template.format( typename = typename, field_names = tuple(field_names), num_fields = len(field_names), arg_list = repr(tuple(field_names)).replace("'", "")[1:-1], repr_fmt = ', '.join(_repr_template.format(name=name) for name in field_names), field_defs = '\n'.join(_field_template.format(index=index, name=name) for index, name in enumerate(field_names)) ) # Execute the template string in a temporary namespace and support # tracing utilities by setting a value for frame.f_globals['__name__'] namespace = dict(__name__='namedtuple_%s' % typename) exec(class_definition, namespace) result = namespace[typename] result._source = class_definition if verbose: print(result._source) # For pickling to work, the __module__ variable needs to be set to the frame # where the named tuple is created. Bypass this step in environments where # sys._getframe is not defined (Jython for example) or sys._getframe is not # defined for arguments greater than 0 (IronPython), or where the user has # specified a particular module. if module is None: try: module = _sys._getframe(1).f_globals.get('__name__', '__main__') except (AttributeError, ValueError): pass if module is not None: result.__module__ = module return result ######################################################################## ### Counter ######################################################################## def _count_elements(mapping, iterable): 'Tally elements from the iterable.' mapping_get = mapping.get for elem in iterable: mapping[elem] = mapping_get(elem, 0) + 1 try: # Load C helper function if available from _collections import _count_elements except ImportError: pass class Counter(dict): '''Dict subclass for counting hashable items. Sometimes called a bag or multiset. Elements are stored as dictionary keys and their counts are stored as dictionary values. >>> c = Counter('abcdeabcdabcaba') # count elements from a string >>> c.most_common(3) # three most common elements [('a', 5), ('b', 4), ('c', 3)] >>> sorted(c) # list all unique elements ['a', 'b', 'c', 'd', 'e'] >>> ''.join(sorted(c.elements())) # list elements with repetitions 'aaaaabbbbcccdde' >>> sum(c.values()) # total of all counts 15 >>> c['a'] # count of letter 'a' 5 >>> for elem in 'shazam': # update counts from an iterable ... c[elem] += 1 # by adding 1 to each element's count >>> c['a'] # now there are seven 'a' 7 >>> del c['b'] # remove all 'b' >>> c['b'] # now there are zero 'b' 0 >>> d = Counter('simsalabim') # make another counter >>> c.update(d) # add in the second counter >>> c['a'] # now there are nine 'a' 9 >>> c.clear() # empty the counter >>> c Counter() Note: If a count is set to zero or reduced to zero, it will remain in the counter until the entry is deleted or the counter is cleared: >>> c = Counter('aaabbc') >>> c['b'] -= 2 # reduce the count of 'b' by two >>> c.most_common() # 'b' is still in, but its count is zero [('a', 3), ('c', 1), ('b', 0)] ''' # References: # http://en.wikipedia.org/wiki/Multiset # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm # http://code.activestate.com/recipes/259174/ # Knuth, TAOCP Vol. II section 4.6.3 def __init__(*args, **kwds): '''Create a new, empty Counter object. And if given, count elements from an input iterable. Or, initialize the count from another mapping of elements to their counts. >>> c = Counter() # a new, empty counter >>> c = Counter('gallahad') # a new counter from an iterable >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping >>> c = Counter(a=4, b=2) # a new counter from keyword args ''' if not args: raise TypeError("descriptor '__init__' of 'Counter' object " "needs an argument") self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) super(Counter, self).__init__() self.update(*args, **kwds) def __missing__(self, key): 'The count of elements not in the Counter is zero.' # Needed so that self[missing_item] does not raise KeyError return 0 def most_common(self, n=None): '''List the n most common elements and their counts from the most common to the least. If n is None, then list all element counts. >>> Counter('abcdeabcdabcaba').most_common(3) [('a', 5), ('b', 4), ('c', 3)] ''' # Emulate Bag.sortedByCount from Smalltalk if n is None: return sorted(self.items(), key=_itemgetter(1), reverse=True) return _heapq.nlargest(n, self.items(), key=_itemgetter(1)) def elements(self): '''Iterator over elements repeating each as many times as its count. >>> c = Counter('ABCABC') >>> sorted(c.elements()) ['A', 'A', 'B', 'B', 'C', 'C'] # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1 >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) >>> product = 1 >>> for factor in prime_factors.elements(): # loop over factors ... product *= factor # and multiply them >>> product 1836 Note, if an element's count has been set to zero or is a negative number, elements() will ignore it. ''' # Emulate Bag.do from Smalltalk and Multiset.begin from C++. return _chain.from_iterable(_starmap(_repeat, self.items())) # Override dict methods where necessary @classmethod def fromkeys(cls, iterable, v=None): # There is no equivalent method for counters because setting v=1 # means that no element can have a count greater than one. raise NotImplementedError( 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') def update(*args, **kwds): '''Like dict.update() but add counts instead of replacing them. Source can be an iterable, a dictionary, or another Counter instance. >>> c = Counter('which') >>> c.update('witch') # add elements from another iterable >>> d = Counter('watch') >>> c.update(d) # add elements from another counter >>> c['h'] # four 'h' in which, witch, and watch 4 ''' # The regular dict.update() operation makes no sense here because the # replace behavior results in the some of original untouched counts # being mixed-in with all of the other counts for a mismash that # doesn't have a straight-forward interpretation in most counting # contexts. Instead, we implement straight-addition. Both the inputs # and outputs are allowed to contain zero and negative counts. if not args: raise TypeError("descriptor 'update' of 'Counter' object " "needs an argument") self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) iterable = args[0] if args else None if iterable is not None: if isinstance(iterable, Mapping): if self: self_get = self.get for elem, count in iterable.items(): self[elem] = count + self_get(elem, 0) else: super(Counter, self).update(iterable) # fast path when counter is empty else: _count_elements(self, iterable) if kwds: self.update(kwds) def subtract(*args, **kwds): '''Like dict.update() but subtracts counts instead of replacing them. Counts can be reduced below zero. Both the inputs and outputs are allowed to contain zero and negative counts. Source can be an iterable, a dictionary, or another Counter instance. >>> c = Counter('which') >>> c.subtract('witch') # subtract elements from another iterable >>> c.subtract(Counter('watch')) # subtract elements from another counter >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch 0 >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch -1 ''' if not args: raise TypeError("descriptor 'subtract' of 'Counter' object " "needs an argument") self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) iterable = args[0] if args else None if iterable is not None: self_get = self.get if isinstance(iterable, Mapping): for elem, count in iterable.items(): self[elem] = self_get(elem, 0) - count else: for elem in iterable: self[elem] = self_get(elem, 0) - 1 if kwds: self.subtract(kwds) def copy(self): 'Return a shallow copy.' return self.__class__(self) def __reduce__(self): return self.__class__, (dict(self),) def __delitem__(self, elem): 'Like dict.__delitem__() but does not raise KeyError for missing values.' if elem in self: super().__delitem__(elem) def __repr__(self): if not self: return '%s()' % self.__class__.__name__ try: items = ', '.join(map('%r: %r'.__mod__, self.most_common())) return '%s({%s})' % (self.__class__.__name__, items) except TypeError: # handle case where values are not orderable return '{0}({1!r})'.format(self.__class__.__name__, dict(self)) # Multiset-style mathematical operations discussed in: # Knuth TAOCP Volume II section 4.6.3 exercise 19 # and at http://en.wikipedia.org/wiki/Multiset # # Outputs guaranteed to only include positive counts. # # To strip negative and zero counts, add-in an empty counter: # c += Counter() def __add__(self, other): '''Add counts from two counters. >>> Counter('abbb') + Counter('bcc') Counter({'b': 4, 'c': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): newcount = count + other[elem] if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count > 0: result[elem] = count return result def __sub__(self, other): ''' Subtract count, but keep only results with positive counts. >>> Counter('abbbc') - Counter('bccd') Counter({'b': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): newcount = count - other[elem] if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count < 0: result[elem] = 0 - count return result def __or__(self, other): '''Union is the maximum of value in either of the input counters. >>> Counter('abbb') | Counter('bcc') Counter({'b': 3, 'c': 2, 'a': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): other_count = other[elem] newcount = other_count if count < other_count else count if newcount > 0: result[elem] = newcount for elem, count in other.items(): if elem not in self and count > 0: result[elem] = count return result def __and__(self, other): ''' Intersection is the minimum of corresponding counts. >>> Counter('abbb') & Counter('bcc') Counter({'b': 1}) ''' if not isinstance(other, Counter): return NotImplemented result = Counter() for elem, count in self.items(): other_count = other[elem] newcount = count if count < other_count else other_count if newcount > 0: result[elem] = newcount return result def __pos__(self): 'Adds an empty counter, effectively stripping negative and zero counts' result = Counter() for elem, count in self.items(): if count > 0: result[elem] = count return result def __neg__(self): '''Subtracts from an empty counter. Strips positive and zero counts, and flips the sign on negative counts. ''' result = Counter() for elem, count in self.items(): if count < 0: result[elem] = 0 - count return result def _keep_positive(self): '''Internal method to strip elements with a negative or zero count''' nonpositive = [elem for elem, count in self.items() if not count > 0] for elem in nonpositive: del self[elem] return self def __iadd__(self, other): '''Inplace add from another counter, keeping only positive counts. >>> c = Counter('abbb') >>> c += Counter('bcc') >>> c Counter({'b': 4, 'c': 2, 'a': 1}) ''' for elem, count in other.items(): self[elem] += count return self._keep_positive() def __isub__(self, other): '''Inplace subtract counter, but keep only results with positive counts. >>> c = Counter('abbbc') >>> c -= Counter('bccd') >>> c Counter({'b': 2, 'a': 1}) ''' for elem, count in other.items(): self[elem] -= count return self._keep_positive() def __ior__(self, other): '''Inplace union is the maximum of value from either counter. >>> c = Counter('abbb') >>> c |= Counter('bcc') >>> c Counter({'b': 3, 'c': 2, 'a': 1}) ''' for elem, other_count in other.items(): count = self[elem] if other_count > count: self[elem] = other_count return self._keep_positive() def __iand__(self, other): '''Inplace intersection is the minimum of corresponding counts. >>> c = Counter('abbb') >>> c &= Counter('bcc') >>> c Counter({'b': 1}) ''' for elem, count in self.items(): other_count = other[elem] if other_count < count: self[elem] = other_count return self._keep_positive() ######################################################################## ### ChainMap ######################################################################## class ChainMap(MutableMapping): ''' A ChainMap groups multiple dicts (or other mappings) together to create a single, updateable view. The underlying mappings are stored in a list. That list is public and can be accessed or updated using the *maps* attribute. There is no other state. Lookups search the underlying mappings successively until a key is found. In contrast, writes, updates, and deletions only operate on the first mapping. ''' def __init__(self, *maps): '''Initialize a ChainMap by setting *maps* to the given mappings. If no mappings are provided, a single empty dictionary is used. ''' self.maps = list(maps) or [{}] # always at least one map def __missing__(self, key): raise KeyError(key) def __getitem__(self, key): for mapping in self.maps: try: return mapping[key] # can't use 'key in mapping' with defaultdict except KeyError: pass return self.__missing__(key) # support subclasses that define __missing__ def get(self, key, default=None): return self[key] if key in self else default def __len__(self): return len(set().union(*self.maps)) # reuses stored hash values if possible def __iter__(self): return iter(set().union(*self.maps)) def __contains__(self, key): return any(key in m for m in self.maps) def __bool__(self): return any(self.maps) @_recursive_repr() def __repr__(self): return '{0.__class__.__name__}({1})'.format( self, ', '.join(map(repr, self.maps))) @classmethod def fromkeys(cls, iterable, *args): 'Create a ChainMap with a single dict created from the iterable.' return cls(dict.fromkeys(iterable, *args)) def copy(self): 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' return self.__class__(self.maps[0].copy(), *self.maps[1:]) __copy__ = copy def new_child(self, m=None): # like Django's Context.push() '''New ChainMap with a new map followed by all previous maps. If no map is provided, an empty dict is used. ''' if m is None: m = {} return self.__class__(m, *self.maps) @property def parents(self): # like Django's Context.pop() 'New ChainMap from maps[1:].' return self.__class__(*self.maps[1:]) def __setitem__(self, key, value): self.maps[0][key] = value def __delitem__(self, key): try: del self.maps[0][key] except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def popitem(self): 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' try: return self.maps[0].popitem() except KeyError: raise KeyError('No keys found in the first mapping.') def pop(self, key, *args): 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' try: return self.maps[0].pop(key, *args) except KeyError: raise KeyError('Key not found in the first mapping: {!r}'.format(key)) def clear(self): 'Clear maps[0], leaving maps[1:] intact.' self.maps[0].clear() ################################################################################ ### UserDict ################################################################################ class UserDict(MutableMapping): # Start by filling-out the abstract methods def __init__(*args, **kwargs): if not args: raise TypeError("descriptor '__init__' of 'UserDict' object " "needs an argument") self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) if args: dict = args[0] elif 'dict' in kwargs: dict = kwargs.pop('dict') import warnings warnings.warn("Passing 'dict' as keyword argument is deprecated", DeprecationWarning, stacklevel=2) else: dict = None self.data = {} if dict is not None: self.update(dict) if len(kwargs): self.update(kwargs) def __len__(self): return len(self.data) def __getitem__(self, key): if key in self.data: return self.data[key] if hasattr(self.__class__, "__missing__"): return self.__class__.__missing__(self, key) raise KeyError(key) def __setitem__(self, key, item): self.data[key] = item def __delitem__(self, key): del self.data[key] def __iter__(self): return iter(self.data) # Modify __contains__ to work correctly when __missing__ is present def __contains__(self, key): return key in self.data # Now, add the methods in dicts but not in MutableMapping def __repr__(self): return repr(self.data) def copy(self): if self.__class__ is UserDict: return UserDict(self.data.copy()) import copy data = self.data try: self.data = {} c = copy.copy(self) finally: self.data = data c.update(self) return c @classmethod def fromkeys(cls, iterable, value=None): d = cls() for key in iterable: d[key] = value return d ################################################################################ ### UserList ################################################################################ class UserList(MutableSequence): """A more or less complete user-defined wrapper around list objects.""" def __init__(self, initlist=None): self.data = [] if initlist is not None: # XXX should this accept an arbitrary sequence? if type(initlist) == type(self.data): self.data[:] = initlist elif isinstance(initlist, UserList): self.data[:] = initlist.data[:] else: self.data = list(initlist) def __repr__(self): return repr(self.data) def __lt__(self, other): return self.data < self.__cast(other) def __le__(self, other): return self.data <= self.__cast(other) def __eq__(self, other): return self.data == self.__cast(other) def __gt__(self, other): return self.data > self.__cast(other) def __ge__(self, other): return self.data >= self.__cast(other) def __cast(self, other): return other.data if isinstance(other, UserList) else other def __contains__(self, item): return item in self.data def __len__(self): return len(self.data) def __getitem__(self, i): return self.data[i] def __setitem__(self, i, item): self.data[i] = item def __delitem__(self, i): del self.data[i] def __add__(self, other): if isinstance(other, UserList): return self.__class__(self.data + other.data) elif isinstance(other, type(self.data)): return self.__class__(self.data + other) return self.__class__(self.data + list(other)) def __radd__(self, other): if isinstance(other, UserList): return self.__class__(other.data + self.data) elif isinstance(other, type(self.data)): return self.__class__(other + self.data) return self.__class__(list(other) + self.data) def __iadd__(self, other): if isinstance(other, UserList): self.data += other.data elif isinstance(other, type(self.data)): self.data += other else: self.data += list(other) return self def __mul__(self, n): return self.__class__(self.data*n) __rmul__ = __mul__ def __imul__(self, n): self.data *= n return self def append(self, item): self.data.append(item) def insert(self, i, item): self.data.insert(i, item) def pop(self, i=-1): return self.data.pop(i) def remove(self, item): self.data.remove(item) def clear(self): self.data.clear() def copy(self): return self.__class__(self) def count(self, item): return self.data.count(item) def index(self, item, *args): return self.data.index(item, *args) def reverse(self): self.data.reverse() def sort(self, *args, **kwds): self.data.sort(*args, **kwds) def extend(self, other): if isinstance(other, UserList): self.data.extend(other.data) else: self.data.extend(other) ################################################################################ ### UserString ################################################################################ class UserString(Sequence): def __init__(self, seq): if isinstance(seq, str): self.data = seq elif isinstance(seq, UserString): self.data = seq.data[:] else: self.data = str(seq) def __str__(self): return str(self.data) def __repr__(self): return repr(self.data) def __int__(self): return int(self.data) def __float__(self): return float(self.data) def __complex__(self): return complex(self.data) def __hash__(self): return hash(self.data) def __getnewargs__(self): return (self.data[:],) def __eq__(self, string): if isinstance(string, UserString): return self.data == string.data return self.data == string def __lt__(self, string): if isinstance(string, UserString): return self.data < string.data return self.data < string def __le__(self, string): if isinstance(string, UserString): return self.data <= string.data return self.data <= string def __gt__(self, string): if isinstance(string, UserString): return self.data > string.data return self.data > string def __ge__(self, string): if isinstance(string, UserString): return self.data >= string.data return self.data >= string def __contains__(self, char): if isinstance(char, UserString): char = char.data return char in self.data def __len__(self): return len(self.data) def __getitem__(self, index): return self.__class__(self.data[index]) def __add__(self, other): if isinstance(other, UserString): return self.__class__(self.data + other.data) elif isinstance(other, str): return self.__class__(self.data + other) return self.__class__(self.data + str(other)) def __radd__(self, other): if isinstance(other, str): return self.__class__(other + self.data) return self.__class__(str(other) + self.data) def __mul__(self, n): return self.__class__(self.data*n) __rmul__ = __mul__ def __mod__(self, args): return self.__class__(self.data % args) def __rmod__(self, format): return self.__class__(format % args) # the following methods are defined in alphabetical order: def capitalize(self): return self.__class__(self.data.capitalize()) def casefold(self): return self.__class__(self.data.casefold()) def center(self, width, *args): return self.__class__(self.data.center(width, *args)) def count(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.count(sub, start, end) def encode(self, encoding=None, errors=None): # XXX improve this? if encoding: if errors: return self.__class__(self.data.encode(encoding, errors)) return self.__class__(self.data.encode(encoding)) return self.__class__(self.data.encode()) def endswith(self, suffix, start=0, end=_sys.maxsize): return self.data.endswith(suffix, start, end) def expandtabs(self, tabsize=8): return self.__class__(self.data.expandtabs(tabsize)) def find(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.find(sub, start, end) def format(self, *args, **kwds): return self.data.format(*args, **kwds) def format_map(self, mapping): return self.data.format_map(mapping) def index(self, sub, start=0, end=_sys.maxsize): return self.data.index(sub, start, end) def isalpha(self): return self.data.isalpha() def isalnum(self): return self.data.isalnum() def isdecimal(self): return self.data.isdecimal() def isdigit(self): return self.data.isdigit() def isidentifier(self): return self.data.isidentifier() def islower(self): return self.data.islower() def isnumeric(self): return self.data.isnumeric() def isprintable(self): return self.data.isprintable() def isspace(self): return self.data.isspace() def istitle(self): return self.data.istitle() def isupper(self): return self.data.isupper() def join(self, seq): return self.data.join(seq) def ljust(self, width, *args): return self.__class__(self.data.ljust(width, *args)) def lower(self): return self.__class__(self.data.lower()) def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars)) maketrans = str.maketrans def partition(self, sep): return self.data.partition(sep) def replace(self, old, new, maxsplit=-1): if isinstance(old, UserString): old = old.data if isinstance(new, UserString): new = new.data return self.__class__(self.data.replace(old, new, maxsplit)) def rfind(self, sub, start=0, end=_sys.maxsize): if isinstance(sub, UserString): sub = sub.data return self.data.rfind(sub, start, end) def rindex(self, sub, start=0, end=_sys.maxsize): return self.data.rindex(sub, start, end) def rjust(self, width, *args): return self.__class__(self.data.rjust(width, *args)) def rpartition(self, sep): return self.data.rpartition(sep) def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars)) def split(self, sep=None, maxsplit=-1): return self.data.split(sep, maxsplit) def rsplit(self, sep=None, maxsplit=-1): return self.data.rsplit(sep, maxsplit) def splitlines(self, keepends=False): return self.data.splitlines(keepends) def startswith(self, prefix, start=0, end=_sys.maxsize): return self.data.startswith(prefix, start, end) def strip(self, chars=None): return self.__class__(self.data.strip(chars)) def swapcase(self): return self.__class__(self.data.swapcase()) def title(self): return self.__class__(self.data.title()) def translate(self, *args): return self.__class__(self.data.translate(*args)) def upper(self): return self.__class__(self.data.upper()) def zfill(self, width): return self.__class__(self.data.zfill(width)) opt/alt/python37/lib64/python3.7/site-packages/lxml/__init__.py000064400000001047152351005750020124 0ustar00# this is a package def get_include(): """ Returns a list of header include paths (for lxml itself, libxml2 and libxslt) needed to compile C code against lxml if it was built with statically linked libraries. """ import os lxml_path = __path__[0] include_path = os.path.join(lxml_path, 'includes') includes = [include_path, lxml_path] for name in os.listdir(include_path): path = os.path.join(include_path, name) if os.path.isdir(path): includes.append(path) return includes usr/lib/python3.6/site-packages/dnfpluginscore/__init__.py000064400000002340152351067360017555 0ustar00# Copyright (C) 2014 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU General Public License v.2, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY expressed or implied, including the implied warranties of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. You should have received a copy of the # GNU General Public License along with this program; if not, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # """ Common code for dnf-plugins-core""" from __future__ import absolute_import from __future__ import unicode_literals import dnf.exceptions import logging _, P_ = dnf.i18n.translation('dnf-plugins-core') logger = logging.getLogger('dnf.plugin') rpm_logger = logging.getLogger('dnf.rpm') usr/lib/python3.6/site-packages/dateutil/__init__.py000064400000000105152351153600016334 0ustar00# -*- coding: utf-8 -*- from ._version import VERSION as __version__ opt/alt/python38/lib/python3.8/site-packages/aiodns/__init__.py000064400000011731152351250100020245 0ustar00 import asyncio import functools import pycares import socket from typing import ( Any, List, Optional, Set ) from . import error __version__ = '3.0.0' __all__ = ('DNSResolver', 'error') READ = 1 WRITE = 2 query_type_map = {'A' : pycares.QUERY_TYPE_A, 'AAAA' : pycares.QUERY_TYPE_AAAA, 'ANY' : pycares.QUERY_TYPE_ANY, 'CAA' : pycares.QUERY_TYPE_CAA, 'CNAME' : pycares.QUERY_TYPE_CNAME, 'MX' : pycares.QUERY_TYPE_MX, 'NAPTR' : pycares.QUERY_TYPE_NAPTR, 'NS' : pycares.QUERY_TYPE_NS, 'PTR' : pycares.QUERY_TYPE_PTR, 'SOA' : pycares.QUERY_TYPE_SOA, 'SRV' : pycares.QUERY_TYPE_SRV, 'TXT' : pycares.QUERY_TYPE_TXT } query_class_map = {'IN' : pycares.QUERY_CLASS_IN, 'CHAOS' : pycares.QUERY_CLASS_CHAOS, 'HS' : pycares.QUERY_CLASS_HS, 'NONE' : pycares.QUERY_CLASS_NONE, 'ANY' : pycares.QUERY_CLASS_ANY } class DNSResolver: def __init__(self, nameservers: Optional[List[str]] = None, loop: Optional[asyncio.AbstractEventLoop] = None, **kwargs: Any) -> None: self.loop = loop or asyncio.get_event_loop() assert self.loop is not None kwargs.pop('sock_state_cb', None) self._channel = pycares.Channel(sock_state_cb=self._sock_state_cb, **kwargs) if nameservers: self.nameservers = nameservers self._read_fds = set() # type: Set[int] self._write_fds = set() # type: Set[int] self._timer = None # type: Optional[asyncio.TimerHandle] @property def nameservers(self) -> pycares.Channel: return self._channel.servers @nameservers.setter def nameservers(self, value: List[str]) -> None: self._channel.servers = value @staticmethod def _callback(fut: asyncio.Future, result: Any, errorno: int) -> None: if fut.cancelled(): return if errorno is not None: fut.set_exception(error.DNSError(errorno, pycares.errno.strerror(errorno))) else: fut.set_result(result) def query(self, host: str, qtype: str, qclass: str=None) -> asyncio.Future: try: qtype = query_type_map[qtype] except KeyError: raise ValueError('invalid query type: {}'.format(qtype)) if qclass is not None: try: qclass = query_class_map[qclass] except KeyError: raise ValueError('invalid query class: {}'.format(qclass)) fut = asyncio.Future(loop=self.loop) # type: asyncio.Future cb = functools.partial(self._callback, fut) self._channel.query(host, qtype, cb, query_class=qclass) return fut def gethostbyname(self, host: str, family: socket.AddressFamily) -> asyncio.Future: fut = asyncio.Future(loop=self.loop) # type: asyncio.Future cb = functools.partial(self._callback, fut) self._channel.gethostbyname(host, family, cb) return fut def gethostbyaddr(self, name: str) -> asyncio.Future: fut = asyncio.Future(loop=self.loop) # type: asyncio.Future cb = functools.partial(self._callback, fut) self._channel.gethostbyaddr(name, cb) return fut def cancel(self) -> None: self._channel.cancel() def _sock_state_cb(self, fd: int, readable: bool, writable: bool) -> None: if readable or writable: if readable: self.loop.add_reader(fd, self._handle_event, fd, READ) self._read_fds.add(fd) if writable: self.loop.add_writer(fd, self._handle_event, fd, WRITE) self._write_fds.add(fd) if self._timer is None: self._timer = self.loop.call_later(1.0, self._timer_cb) else: # socket is now closed if fd in self._read_fds: self._read_fds.discard(fd) self.loop.remove_reader(fd) if fd in self._write_fds: self._write_fds.discard(fd) self.loop.remove_writer(fd) if not self._read_fds and not self._write_fds and self._timer is not None: self._timer.cancel() self._timer = None def _handle_event(self, fd: int, event: Any) -> None: read_fd = pycares.ARES_SOCKET_BAD write_fd = pycares.ARES_SOCKET_BAD if event == READ: read_fd = fd elif event == WRITE: write_fd = fd self._channel.process_fd(read_fd, write_fd) def _timer_cb(self) -> None: if self._read_fds or self._write_fds: self._channel.process_fd(pycares.ARES_SOCKET_BAD, pycares.ARES_SOCKET_BAD) self._timer = self.loop.call_later(1.0, self._timer_cb) else: self._timer = None lib/python3.6/site-packages/up2date_client/__init__.py000064400000000000152351331130016600 0ustar00usr/lib64/python3.6/site-packages/systemd/__init__.py000064400000001367152351343500016376 0ustar00# -*- Mode: python; indent-tabs-mode: nil -*- */ # # # Copyright 2012 David Strauss # # python-systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # # python-systemd is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with python-systemd; If not, see . usr/lib/python3.6/site-packages/dateutil/zoneinfo/__init__.py000064400000015133152351535640020202 0ustar00# -*- coding: utf-8 -*- import warnings import json from tarfile import TarFile from pkgutil import get_data from io import BytesIO from contextlib import closing from dateutil.tz import tzfile __all__ = ["get_zonefile_instance", "gettz", "gettz_db_metadata", "rebuild"] ZONEFILENAME = "dateutil-zoneinfo.tar.gz" METADATA_FN = 'METADATA' # python2.6 compatability. Note that TarFile.__exit__ != TarFile.close, but # it's close enough for python2.6 tar_open = TarFile.open if not hasattr(TarFile, '__exit__'): def tar_open(*args, **kwargs): return closing(TarFile.open(*args, **kwargs)) class tzfile(tzfile): def __reduce__(self): return (gettz, (self._filename,)) def getzoneinfofile_stream(): try: return BytesIO(get_data(__name__, ZONEFILENAME)) except IOError as e: # TODO switch to FileNotFoundError? warnings.warn("I/O error({0}): {1}".format(e.errno, e.strerror)) return None class ZoneInfoFile(object): def __init__(self, zonefile_stream=None): if zonefile_stream is not None: with tar_open(fileobj=zonefile_stream, mode='r') as tf: # dict comprehension does not work on python2.6 # TODO: get back to the nicer syntax when we ditch python2.6 # self.zones = {zf.name: tzfile(tf.extractfile(zf), # filename = zf.name) # for zf in tf.getmembers() if zf.isfile()} self.zones = dict((zf.name, tzfile(tf.extractfile(zf), filename=zf.name)) for zf in tf.getmembers() if zf.isfile() and zf.name != METADATA_FN) # deal with links: They'll point to their parent object. Less # waste of memory # links = {zl.name: self.zones[zl.linkname] # for zl in tf.getmembers() if zl.islnk() or zl.issym()} links = dict((zl.name, self.zones[zl.linkname]) for zl in tf.getmembers() if zl.islnk() or zl.issym()) self.zones.update(links) try: metadata_json = tf.extractfile(tf.getmember(METADATA_FN)) metadata_str = metadata_json.read().decode('UTF-8') self.metadata = json.loads(metadata_str) except KeyError: # no metadata in tar file self.metadata = None else: self.zones = dict() self.metadata = None def get(self, name, default=None): """ Wrapper for :func:`ZoneInfoFile.zones.get`. This is a convenience method for retrieving zones from the zone dictionary. :param name: The name of the zone to retrieve. (Generally IANA zone names) :param default: The value to return in the event of a missing key. .. versionadded:: 2.6.0 """ return self.zones.get(name, default) # The current API has gettz as a module function, although in fact it taps into # a stateful class. So as a workaround for now, without changing the API, we # will create a new "global" class instance the first time a user requests a # timezone. Ugly, but adheres to the api. # # TODO: Remove after deprecation period. _CLASS_ZONE_INSTANCE = list() def get_zonefile_instance(new_instance=False): """ This is a convenience function which provides a :class:`ZoneInfoFile` instance using the data provided by the ``dateutil`` package. By default, it caches a single instance of the ZoneInfoFile object and returns that. :param new_instance: If ``True``, a new instance of :class:`ZoneInfoFile` is instantiated and used as the cached instance for the next call. Otherwise, new instances are created only as necessary. :return: Returns a :class:`ZoneInfoFile` object. .. versionadded:: 2.6 """ if new_instance: zif = None else: zif = getattr(get_zonefile_instance, '_cached_instance', None) if zif is None: zif = ZoneInfoFile(getzoneinfofile_stream()) get_zonefile_instance._cached_instance = zif return zif def gettz(name): """ This retrieves a time zone from the local zoneinfo tarball that is packaged with dateutil. :param name: An IANA-style time zone name, as found in the zoneinfo file. :return: Returns a :class:`dateutil.tz.tzfile` time zone object. .. warning:: It is generally inadvisable to use this function, and it is only provided for API compatibility with earlier versions. This is *not* equivalent to ``dateutil.tz.gettz()``, which selects an appropriate time zone based on the inputs, favoring system zoneinfo. This is ONLY for accessing the dateutil-specific zoneinfo (which may be out of date compared to the system zoneinfo). .. deprecated:: 2.6 If you need to use a specific zoneinfofile over the system zoneinfo, instantiate a :class:`dateutil.zoneinfo.ZoneInfoFile` object and call :func:`dateutil.zoneinfo.ZoneInfoFile.get(name)` instead. Use :func:`get_zonefile_instance` to retrieve an instance of the dateutil-provided zoneinfo. """ warnings.warn("zoneinfo.gettz() will be removed in future versions, " "to use the dateutil-provided zoneinfo files, instantiate a " "ZoneInfoFile object and use ZoneInfoFile.zones.get() " "instead. See the documentation for details.", DeprecationWarning) if len(_CLASS_ZONE_INSTANCE) == 0: _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream())) return _CLASS_ZONE_INSTANCE[0].zones.get(name) def gettz_db_metadata(): """ Get the zonefile metadata See `zonefile_metadata`_ :returns: A dictionary with the database metadata .. deprecated:: 2.6 See deprecation warning in :func:`zoneinfo.gettz`. To get metadata, query the attribute ``zoneinfo.ZoneInfoFile.metadata``. """ warnings.warn("zoneinfo.gettz_db_metadata() will be removed in future " "versions, to use the dateutil-provided zoneinfo files, " "ZoneInfoFile object and query the 'metadata' attribute " "instead. See the documentation for details.", DeprecationWarning) if len(_CLASS_ZONE_INSTANCE) == 0: _CLASS_ZONE_INSTANCE.append(ZoneInfoFile(getzoneinfofile_stream())) return _CLASS_ZONE_INSTANCE[0].metadata usr/lib64/python2.7/xml/parsers/__init__.py000064400000000247152351717060014447 0ustar00"""Python interfaces to XML parsers. This package contains one module: expat -- Python wrapper for James Clark's Expat parser, with namespace support. """ opt/alt/python38/lib/python3.8/site-packages/attr/__init__.py000064400000002210152352422100017734 0ustar00from __future__ import absolute_import, division, print_function from functools import partial from . import converters, exceptions, filters, validators from ._config import get_run_validators, set_run_validators from ._funcs import asdict, assoc, astuple, evolve, has from ._make import ( NOTHING, Attribute, Factory, attrib, attrs, fields, make_class, validate ) __version__ = "17.4.0" __title__ = "attrs" __description__ = "Classes Without Boilerplate" __uri__ = "http://www.attrs.org/" __doc__ = __description__ + " <" + __uri__ + ">" __author__ = "Hynek Schlawack" __email__ = "hs@ox.cx" __license__ = "MIT" __copyright__ = "Copyright (c) 2015 Hynek Schlawack" s = attributes = attrs ib = attr = attrib dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) __all__ = [ "Attribute", "Factory", "NOTHING", "asdict", "assoc", "astuple", "attr", "attrib", "attributes", "attrs", "converters", "evolve", "exceptions", "fields", "filters", "get_run_validators", "has", "ib", "make_class", "s", "set_run_validators", "validate", "validators", ] opt/alt/python37/lib64/python3.7/site-packages/multidict/__init__.py000064400000001656152352422310021150 0ustar00"""Multidict implementation. HTTP Headers and URL query string require specific data structure: multidict. It behaves mostly like a dict but it can have several values for the same key. """ from ._abc import MultiMapping, MutableMultiMapping from ._compat import USE_CYTHON_EXTENSIONS __all__ = ( "MultiMapping", "MutableMultiMapping", "MultiDictProxy", "CIMultiDictProxy", "MultiDict", "CIMultiDict", "upstr", "istr", "getversion", ) __version__ = "5.1.0" try: if not USE_CYTHON_EXTENSIONS: raise ImportError from ._multidict import ( CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy, getversion, istr, ) except ImportError: # pragma: no cover from ._multidict_py import ( CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy, getversion, istr, ) upstr = istr opt/alt/python38/lib/python3.8/site-packages/setuptools/__init__.py000064400000016766152352712640021243 0ustar00"""Extensions to the 'distutils' for large or complex distributions""" from fnmatch import fnmatchcase import functools import os import re import warnings import _distutils_hack.override # noqa: F401 import distutils.core from distutils.errors import DistutilsOptionError from distutils.util import convert_path from ._deprecation_warning import SetuptoolsDeprecationWarning import setuptools.version from setuptools.extension import Extension from setuptools.dist import Distribution from setuptools.depends import Require from . import monkey __all__ = [ 'setup', 'Distribution', 'Command', 'Extension', 'Require', 'SetuptoolsDeprecationWarning', 'find_packages', 'find_namespace_packages', ] __version__ = setuptools.version.__version__ bootstrap_install_from = None class PackageFinder: """ Generate a list of all Python packages found within a directory """ @classmethod def find(cls, where='.', exclude=(), include=('*',)): """Return a list all Python packages found within directory 'where' 'where' is the root directory which will be searched for packages. It should be supplied as a "cross-platform" (i.e. URL-style) path; it will be converted to the appropriate local path syntax. 'exclude' is a sequence of package names to exclude; '*' can be used as a wildcard in the names, such that 'foo.*' will exclude all subpackages of 'foo' (but not 'foo' itself). 'include' is a sequence of package names to include. If it's specified, only the named packages will be included. If it's not specified, all found packages will be included. 'include' can contain shell style wildcard patterns just like 'exclude'. """ return list( cls._find_packages_iter( convert_path(where), cls._build_filter('ez_setup', '*__pycache__', *exclude), cls._build_filter(*include), ) ) @classmethod def _find_packages_iter(cls, where, exclude, include): """ All the packages found in 'where' that pass the 'include' filter, but not the 'exclude' filter. """ for root, dirs, files in os.walk(where, followlinks=True): # Copy dirs to iterate over it, then empty dirs. all_dirs = dirs[:] dirs[:] = [] for dir in all_dirs: full_path = os.path.join(root, dir) rel_path = os.path.relpath(full_path, where) package = rel_path.replace(os.path.sep, '.') # Skip directory trees that are not valid packages if '.' in dir or not cls._looks_like_package(full_path): continue # Should this package be included? if include(package) and not exclude(package): yield package # Keep searching subdirectories, as there may be more packages # down there, even if the parent was excluded. dirs.append(dir) @staticmethod def _looks_like_package(path): """Does a directory look like a package?""" return os.path.isfile(os.path.join(path, '__init__.py')) @staticmethod def _build_filter(*patterns): """ Given a list of patterns, return a callable that will be true only if the input matches at least one of the patterns. """ return lambda name: any(fnmatchcase(name, pat=pat) for pat in patterns) class PEP420PackageFinder(PackageFinder): @staticmethod def _looks_like_package(path): return True find_packages = PackageFinder.find find_namespace_packages = PEP420PackageFinder.find def _install_setup_requires(attrs): # Note: do not use `setuptools.Distribution` directly, as # our PEP 517 backend patch `distutils.core.Distribution`. class MinimalDistribution(distutils.core.Distribution): """ A minimal version of a distribution for supporting the fetch_build_eggs interface. """ def __init__(self, attrs): _incl = 'dependency_links', 'setup_requires' filtered = {k: attrs[k] for k in set(_incl) & set(attrs)} distutils.core.Distribution.__init__(self, filtered) def finalize_options(self): """ Disable finalize_options to avoid building the working set. Ref #2158. """ dist = MinimalDistribution(attrs) # Honor setup.cfg's options. dist.parse_config_files(ignore_option_errors=True) if dist.setup_requires: warnings.warn( "setup_requires is deprecated. Supply build " "dependencies using PEP 517 pyproject.toml build-requires.", SetuptoolsDeprecationWarning, ) dist.fetch_build_eggs(dist.setup_requires) def setup(**attrs): # Make sure we have any requirements needed to interpret 'attrs'. _install_setup_requires(attrs) return distutils.core.setup(**attrs) setup.__doc__ = distutils.core.setup.__doc__ _Command = monkey.get_unpatched(distutils.core.Command) class Command(_Command): __doc__ = _Command.__doc__ command_consumes_arguments = False def __init__(self, dist, **kw): """ Construct the command for dist, updating vars(self) with any keyword parameters. """ _Command.__init__(self, dist) vars(self).update(kw) def _ensure_stringlike(self, option, what, default=None): val = getattr(self, option) if val is None: setattr(self, option, default) return default elif not isinstance(val, str): raise DistutilsOptionError( "'%s' must be a %s (got `%s`)" % (option, what, val) ) return val def ensure_string_list(self, option): r"""Ensure that 'option' is a list of strings. If 'option' is currently a string, we split it either on /,\s*/ or /\s+/, so "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become ["foo", "bar", "baz"]. """ val = getattr(self, option) if val is None: return elif isinstance(val, str): setattr(self, option, re.split(r',\s*|\s+', val)) else: if isinstance(val, list): ok = all(isinstance(v, str) for v in val) else: ok = False if not ok: raise DistutilsOptionError( "'%s' must be a list of strings (got %r)" % (option, val) ) def reinitialize_command(self, command, reinit_subcommands=0, **kw): cmd = _Command.reinitialize_command(self, command, reinit_subcommands) vars(cmd).update(kw) return cmd def _find_all_simple(path): """ Find all files under 'path' """ results = ( os.path.join(base, file) for base, dirs, files in os.walk(path, followlinks=True) for file in files ) return filter(os.path.isfile, results) def findall(dir=os.curdir): """ Find all files under 'dir' and return the list of full filenames. Unless dir is '.', return full filenames with dir prepended. """ files = _find_all_simple(dir) if dir == os.curdir: make_rel = functools.partial(os.path.relpath, start=dir) files = map(make_rel, files) return list(files) class sic(str): """Treat this string as-is (https://en.wikipedia.org/wiki/Sic)""" # Apply monkey patches monkey.patch_all() opt/alt/python37/lib/python3.7/site-packages/svgwrite/__init__.py000064400000004527152353107460020661 0ustar00#coding:utf-8 # Author: mozman # Purpose: package definition file # Created: 08.09.2010 # License: MIT License # Copyright (c) 2010-2018 Manfred Moitzi """ A Python library to create SVG drawings. SVG is a language for describing two-dimensional graphics in XML. SVG allows for three types of graphic objects: vector graphic shapes (e.g., paths consisting of straight lines and curves), images and text. Graphical objects can be grouped, styled, transformed and composed into previously rendered objects. The feature set includes nested transformations, clipping paths, alpha masks, filter effects and template objects. SVG drawings can be interactive and dynamic. Animations can be defined and triggered either declarative (i.e., by embedding SVG animation elements in SVG content) or via scripting. .. seealso:: http://www.w3.org/TR/SVG11/intro.html#AboutSVG a simple example:: import svgwrite dwg = svgwrite.Drawing('test.svg', profile='tiny') dwg.add(dwg.line((0, 0), (10, 0), stroke=svgwrite.rgb(10, 10, 16, '%'))) dwg.add(dwg.text('Test', insert=(0, 0.2))) dwg.save() SVG Version ----------- You can only create two types of SVG drawings: * *SVG 1.2 Tiny Profile*, use Drawing(profile= ``'tiny'``) * *SVG 1.1 Full Profile*, use Drawing(profile= ``'full'``) """ from .version import __version__, version VERSION = __version__ __author__ = "mozman " AUTHOR_NAME = 'Manfred Moitzi' AUTHOR_EMAIL = 'me@mozman.at' CYEAR = '2014-2019' from svgwrite.drawing import Drawing from svgwrite.utils import rgb class Unit(object): """ Add units to values. """ def __init__(self, unit='cm'): """ Unit constructor :param str unit: specify the unit string """ self._unit = unit def __rmul__(self, other): """ add unit-string to 'other'. (e.g. 5*cm => '5cm') """ return "%s%s" % (other, self._unit) def __call__(self, *args): """ Add unit-strings to all arguments. :param args: list of values e.g.: cm(1,2,3) => '1cm,2cm,3cm' """ return ','.join(["%s%s" % (arg, self._unit) for arg in args]) cm = Unit('cm') mm = Unit('mm') em = Unit('em') ex = Unit('ex') px = Unit('px') inch = Unit('in') pc = Unit('pc') pt = Unit('pt') percent = Unit('%') deg = Unit('deg') grad = Unit('grad') rad = Unit('rad') Hz = Unit('Hz') kHz = Unit('kHz') opt/alt/python37/lib64/python3.7/site-packages/numpy/lib/__init__.py000064400000002440152353113410021057 0ustar00from __future__ import division, absolute_import, print_function import math from .info import __doc__ from numpy.version import version as __version__ from .type_check import * from .index_tricks import * from .function_base import * from .mixins import * from .nanfunctions import * from .shape_base import * from .stride_tricks import * from .twodim_base import * from .ufunclike import * from . import scimath as emath from .polynomial import * #import convertcode from .utils import * from .arraysetops import * from .npyio import * from .financial import * from .arrayterator import Arrayterator from .arraypad import * from ._version import * from numpy.core.multiarray import tracemalloc_domain __all__ = ['emath', 'math', 'tracemalloc_domain'] __all__ += type_check.__all__ __all__ += index_tricks.__all__ __all__ += function_base.__all__ __all__ += mixins.__all__ __all__ += shape_base.__all__ __all__ += stride_tricks.__all__ __all__ += twodim_base.__all__ __all__ += ufunclike.__all__ __all__ += arraypad.__all__ __all__ += polynomial.__all__ __all__ += utils.__all__ __all__ += arraysetops.__all__ __all__ += npyio.__all__ __all__ += financial.__all__ __all__ += nanfunctions.__all__ from numpy.testing.nosetester import _numpy_tester test = _numpy_tester().test bench = _numpy_tester().bench opt/alt/python37/lib64/python3.7/urllib/__init__.py000064400000000000152353155000015701 0ustar00opt/alt/python27/lib/python2.7/site-packages/pip/_vendor/__init__.py000064400000010754152353234060021225 0ustar00""" pip._vendor is for vendoring dependencies of pip to prevent needing pip to depend on something external. Files inside of pip._vendor should be considered immutable and should only be updated to versions from upstream. """ from __future__ import absolute_import import glob import os.path import sys # Downstream redistributors which have debundled our dependencies should also # patch this value to be true. This will trigger the additional patching # to cause things like "six" to be available as pip. DEBUNDLED = False # By default, look in this directory for a bunch of .whl files which we will # add to the beginning of sys.path before attempting to import anything. This # is done to support downstream re-distributors like Debian and Fedora who # wish to create their own Wheels for our dependencies to aid in debundling. WHEEL_DIR = os.path.abspath(os.path.dirname(__file__)) # Define a small helper function to alias our vendored modules to the real ones # if the vendored ones do not exist. This idea of this was taken from # https://github.com/kennethreitz/requests/pull/2567. def vendored(modulename): vendored_name = "{0}.{1}".format(__name__, modulename) try: __import__(modulename, globals(), locals(), level=0) except ImportError: # This error used to be silenced in earlier variants of this file, to instead # raise the error when pip actually tries to use the missing module. # Based on inputs in #5354, this was changed to explicitly raise the error. # Re-raising the exception without modifying it is an intentional choice. raise else: sys.modules[vendored_name] = sys.modules[modulename] base, head = vendored_name.rsplit(".", 1) setattr(sys.modules[base], head, sys.modules[modulename]) # If we're operating in a debundled setup, then we want to go ahead and trigger # the aliasing of our vendored libraries as well as looking for wheels to add # to our sys.path. This will cause all of this code to be a no-op typically # however downstream redistributors can enable it in a consistent way across # all platforms. if DEBUNDLED: # Actually look inside of WHEEL_DIR to find .whl files and add them to the # front of our sys.path. sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path # Actually alias all of our vendored dependencies. vendored("appdirs") vendored("cachecontrol") vendored("certifi") vendored("colorama") vendored("contextlib2") vendored("distlib") vendored("distro") vendored("html5lib") vendored("six") vendored("six.moves") vendored("six.moves.urllib") vendored("six.moves.urllib.parse") vendored("packaging") vendored("packaging.version") vendored("packaging.specifiers") vendored("pep517") vendored("pkg_resources") vendored("progress") vendored("retrying") vendored("requests") vendored("requests.exceptions") vendored("requests.packages") vendored("requests.packages.urllib3") vendored("requests.packages.urllib3._collections") vendored("requests.packages.urllib3.connection") vendored("requests.packages.urllib3.connectionpool") vendored("requests.packages.urllib3.contrib") vendored("requests.packages.urllib3.contrib.ntlmpool") vendored("requests.packages.urllib3.contrib.pyopenssl") vendored("requests.packages.urllib3.exceptions") vendored("requests.packages.urllib3.fields") vendored("requests.packages.urllib3.filepost") vendored("requests.packages.urllib3.packages") vendored("requests.packages.urllib3.packages.ordered_dict") vendored("requests.packages.urllib3.packages.six") vendored("requests.packages.urllib3.packages.ssl_match_hostname") vendored("requests.packages.urllib3.packages.ssl_match_hostname." "_implementation") vendored("requests.packages.urllib3.poolmanager") vendored("requests.packages.urllib3.request") vendored("requests.packages.urllib3.response") vendored("requests.packages.urllib3.util") vendored("requests.packages.urllib3.util.connection") vendored("requests.packages.urllib3.util.request") vendored("requests.packages.urllib3.util.response") vendored("requests.packages.urllib3.util.retry") vendored("requests.packages.urllib3.util.ssl_") vendored("requests.packages.urllib3.util.timeout") vendored("requests.packages.urllib3.util.url") vendored("resolvelib") vendored("toml") vendored("toml.encoder") vendored("toml.decoder") vendored("urllib3") opt/alt/python37/lib64/python3.7/site-packages/yaml/__init__.py000064400000031562152353322570020123 0ustar00 from .error import * from .tokens import * from .events import * from .nodes import * from .loader import * from .dumper import * __version__ = '5.4.1' try: from .cyaml import * __with_libyaml__ = True except ImportError: __with_libyaml__ = False import io #------------------------------------------------------------------------------ # Warnings control #------------------------------------------------------------------------------ # 'Global' warnings state: _warnings_enabled = { 'YAMLLoadWarning': True, } # Get or set global warnings' state def warnings(settings=None): if settings is None: return _warnings_enabled if type(settings) is dict: for key in settings: if key in _warnings_enabled: _warnings_enabled[key] = settings[key] # Warn when load() is called without Loader=... class YAMLLoadWarning(RuntimeWarning): pass def load_warning(method): if _warnings_enabled['YAMLLoadWarning'] is False: return import warnings message = ( "calling yaml.%s() without Loader=... is deprecated, as the " "default Loader is unsafe. Please read " "https://msg.pyyaml.org/load for full details." ) % method warnings.warn(message, YAMLLoadWarning, stacklevel=3) #------------------------------------------------------------------------------ def scan(stream, Loader=Loader): """ Scan a YAML stream and produce scanning tokens. """ loader = Loader(stream) try: while loader.check_token(): yield loader.get_token() finally: loader.dispose() def parse(stream, Loader=Loader): """ Parse a YAML stream and produce parsing events. """ loader = Loader(stream) try: while loader.check_event(): yield loader.get_event() finally: loader.dispose() def compose(stream, Loader=Loader): """ Parse the first YAML document in a stream and produce the corresponding representation tree. """ loader = Loader(stream) try: return loader.get_single_node() finally: loader.dispose() def compose_all(stream, Loader=Loader): """ Parse all YAML documents in a stream and produce corresponding representation trees. """ loader = Loader(stream) try: while loader.check_node(): yield loader.get_node() finally: loader.dispose() def load(stream, Loader=None): """ Parse the first YAML document in a stream and produce the corresponding Python object. """ if Loader is None: load_warning('load') Loader = FullLoader loader = Loader(stream) try: return loader.get_single_data() finally: loader.dispose() def load_all(stream, Loader=None): """ Parse all YAML documents in a stream and produce corresponding Python objects. """ if Loader is None: load_warning('load_all') Loader = FullLoader loader = Loader(stream) try: while loader.check_data(): yield loader.get_data() finally: loader.dispose() def full_load(stream): """ Parse the first YAML document in a stream and produce the corresponding Python object. Resolve all tags except those known to be unsafe on untrusted input. """ return load(stream, FullLoader) def full_load_all(stream): """ Parse all YAML documents in a stream and produce corresponding Python objects. Resolve all tags except those known to be unsafe on untrusted input. """ return load_all(stream, FullLoader) def safe_load(stream): """ Parse the first YAML document in a stream and produce the corresponding Python object. Resolve only basic YAML tags. This is known to be safe for untrusted input. """ return load(stream, SafeLoader) def safe_load_all(stream): """ Parse all YAML documents in a stream and produce corresponding Python objects. Resolve only basic YAML tags. This is known to be safe for untrusted input. """ return load_all(stream, SafeLoader) def unsafe_load(stream): """ Parse the first YAML document in a stream and produce the corresponding Python object. Resolve all tags, even those known to be unsafe on untrusted input. """ return load(stream, UnsafeLoader) def unsafe_load_all(stream): """ Parse all YAML documents in a stream and produce corresponding Python objects. Resolve all tags, even those known to be unsafe on untrusted input. """ return load_all(stream, UnsafeLoader) def emit(events, stream=None, Dumper=Dumper, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None): """ Emit YAML parsing events into a stream. If stream is None, return the produced string instead. """ getvalue = None if stream is None: stream = io.StringIO() getvalue = stream.getvalue dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break) try: for event in events: dumper.emit(event) finally: dumper.dispose() if getvalue: return getvalue() def serialize_all(nodes, stream=None, Dumper=Dumper, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, version=None, tags=None): """ Serialize a sequence of representation trees into a YAML stream. If stream is None, return the produced string instead. """ getvalue = None if stream is None: if encoding is None: stream = io.StringIO() else: stream = io.BytesIO() getvalue = stream.getvalue dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break, encoding=encoding, version=version, tags=tags, explicit_start=explicit_start, explicit_end=explicit_end) try: dumper.open() for node in nodes: dumper.serialize(node) dumper.close() finally: dumper.dispose() if getvalue: return getvalue() def serialize(node, stream=None, Dumper=Dumper, **kwds): """ Serialize a representation tree into a YAML stream. If stream is None, return the produced string instead. """ return serialize_all([node], stream, Dumper=Dumper, **kwds) def dump_all(documents, stream=None, Dumper=Dumper, default_style=None, default_flow_style=False, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, version=None, tags=None, sort_keys=True): """ Serialize a sequence of Python objects into a YAML stream. If stream is None, return the produced string instead. """ getvalue = None if stream is None: if encoding is None: stream = io.StringIO() else: stream = io.BytesIO() getvalue = stream.getvalue dumper = Dumper(stream, default_style=default_style, default_flow_style=default_flow_style, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break, encoding=encoding, version=version, tags=tags, explicit_start=explicit_start, explicit_end=explicit_end, sort_keys=sort_keys) try: dumper.open() for data in documents: dumper.represent(data) dumper.close() finally: dumper.dispose() if getvalue: return getvalue() def dump(data, stream=None, Dumper=Dumper, **kwds): """ Serialize a Python object into a YAML stream. If stream is None, return the produced string instead. """ return dump_all([data], stream, Dumper=Dumper, **kwds) def safe_dump_all(documents, stream=None, **kwds): """ Serialize a sequence of Python objects into a YAML stream. Produce only basic YAML tags. If stream is None, return the produced string instead. """ return dump_all(documents, stream, Dumper=SafeDumper, **kwds) def safe_dump(data, stream=None, **kwds): """ Serialize a Python object into a YAML stream. Produce only basic YAML tags. If stream is None, return the produced string instead. """ return dump_all([data], stream, Dumper=SafeDumper, **kwds) def add_implicit_resolver(tag, regexp, first=None, Loader=None, Dumper=Dumper): """ Add an implicit scalar detector. If an implicit scalar value matches the given regexp, the corresponding tag is assigned to the scalar. first is a sequence of possible initial characters or None. """ if Loader is None: loader.Loader.add_implicit_resolver(tag, regexp, first) loader.FullLoader.add_implicit_resolver(tag, regexp, first) loader.UnsafeLoader.add_implicit_resolver(tag, regexp, first) else: Loader.add_implicit_resolver(tag, regexp, first) Dumper.add_implicit_resolver(tag, regexp, first) def add_path_resolver(tag, path, kind=None, Loader=None, Dumper=Dumper): """ Add a path based resolver for the given tag. A path is a list of keys that forms a path to a node in the representation tree. Keys can be string values, integers, or None. """ if Loader is None: loader.Loader.add_path_resolver(tag, path, kind) loader.FullLoader.add_path_resolver(tag, path, kind) loader.UnsafeLoader.add_path_resolver(tag, path, kind) else: Loader.add_path_resolver(tag, path, kind) Dumper.add_path_resolver(tag, path, kind) def add_constructor(tag, constructor, Loader=None): """ Add a constructor for the given tag. Constructor is a function that accepts a Loader instance and a node object and produces the corresponding Python object. """ if Loader is None: loader.Loader.add_constructor(tag, constructor) loader.FullLoader.add_constructor(tag, constructor) loader.UnsafeLoader.add_constructor(tag, constructor) else: Loader.add_constructor(tag, constructor) def add_multi_constructor(tag_prefix, multi_constructor, Loader=None): """ Add a multi-constructor for the given tag prefix. Multi-constructor is called for a node if its tag starts with tag_prefix. Multi-constructor accepts a Loader instance, a tag suffix, and a node object and produces the corresponding Python object. """ if Loader is None: loader.Loader.add_multi_constructor(tag_prefix, multi_constructor) loader.FullLoader.add_multi_constructor(tag_prefix, multi_constructor) loader.UnsafeLoader.add_multi_constructor(tag_prefix, multi_constructor) else: Loader.add_multi_constructor(tag_prefix, multi_constructor) def add_representer(data_type, representer, Dumper=Dumper): """ Add a representer for the given type. Representer is a function accepting a Dumper instance and an instance of the given data type and producing the corresponding representation node. """ Dumper.add_representer(data_type, representer) def add_multi_representer(data_type, multi_representer, Dumper=Dumper): """ Add a representer for the given type. Multi-representer is a function accepting a Dumper instance and an instance of the given data type or subtype and producing the corresponding representation node. """ Dumper.add_multi_representer(data_type, multi_representer) class YAMLObjectMetaclass(type): """ The metaclass for YAMLObject. """ def __init__(cls, name, bases, kwds): super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds) if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None: if isinstance(cls.yaml_loader, list): for loader in cls.yaml_loader: loader.add_constructor(cls.yaml_tag, cls.from_yaml) else: cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml) cls.yaml_dumper.add_representer(cls, cls.to_yaml) class YAMLObject(metaclass=YAMLObjectMetaclass): """ An object that can dump itself to a YAML stream and load itself from a YAML stream. """ __slots__ = () # no direct instantiation, so allow immutable subclasses yaml_loader = [Loader, FullLoader, UnsafeLoader] yaml_dumper = Dumper yaml_tag = None yaml_flow_style = None @classmethod def from_yaml(cls, loader, node): """ Convert a representation node to a Python object. """ return loader.construct_yaml_object(node, cls) @classmethod def to_yaml(cls, dumper, data): """ Convert a Python object to a representation node. """ return dumper.represent_yaml_object(cls.yaml_tag, data, cls, flow_style=cls.yaml_flow_style) opt/alt/python37/lib64/python3.7/site-packages/simplejson/__init__.py000064400000056260152353327020021341 0ustar00r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. :mod:`simplejson` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is the externally maintained version of the :mod:`json` library contained in Python 2.6, but maintains compatibility back to Python 2.5 and (currently) has significant performance advantages, even without using the optional C extension for speedups. Encoding basic Python object hierarchies:: >>> import simplejson as json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print(json.dumps("\"foo\bar")) "\"foo\bar" >>> print(json.dumps(u'\u1234')) "\u1234" >>> print(json.dumps('\\')) "\\" >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) {"a": 0, "b": 0, "c": 0} >>> from simplejson.compat import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]' Compact encoding:: >>> import simplejson as json >>> obj = [1,2,3,{'4': 5, '6': 7}] >>> json.dumps(obj, separators=(',',':'), sort_keys=True) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: >>> import simplejson as json >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=' ')) { "4": 5, "6": 7 } Decoding JSON:: >>> import simplejson as json >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}] >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj True >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar' True >>> from simplejson.compat import StringIO >>> io = StringIO('["streaming API"]') >>> json.load(io)[0] == 'streaming API' True Specializing JSON object decoding:: >>> import simplejson as json >>> def as_complex(dct): ... if '__complex__' in dct: ... return complex(dct['real'], dct['imag']) ... return dct ... >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', ... object_hook=as_complex) (1+2j) >>> from decimal import Decimal >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') True Specializing JSON object encoding:: >>> import simplejson as json >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... raise TypeError(repr(o) + " is not JSON serializable") ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) '[2.0, 1.0]' >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) '[2.0, 1.0]' Using simplejson.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m simplejson.tool { "json": "obj" } $ echo '{ 1.2:3.4}' | python -m simplejson.tool Expecting property name: line 1 column 3 (char 2) """ from __future__ import absolute_import __version__ = '3.12.0' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', 'OrderedDict', 'simple_first', 'RawJSON' ] __author__ = 'Bob Ippolito ' from decimal import Decimal from .errors import JSONDecodeError from .raw_json import RawJSON from .decoder import JSONDecoder from .encoder import JSONEncoder, JSONEncoderForHTML def _import_OrderedDict(): import collections try: return collections.OrderedDict except AttributeError: from . import ordered_dict return ordered_dict.OrderedDict OrderedDict = _import_OrderedDict() def _import_c_make_encoder(): try: from ._speedups import make_encoder return make_encoder except ImportError: return None _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, iterable_as_array=False, bigint_as_string=False, item_sort_key=None, for_json=False, ignore_nan=False, int_as_string_bitcount=None, ) def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, ignore_nan=False, int_as_string_bitcount=None, iterable_as_array=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). If *skipkeys* is true then ``dict`` keys that are not basic types (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If *ensure_ascii* is false, then the some chunks written to ``fp`` may be ``unicode`` instances, subject to normal Python ``str`` to ``unicode`` coercion rules. Unless ``fp.write()`` explicitly understands ``unicode`` (as in ``codecs.getwriter()``) this is likely to cause an error. If *check_circular* is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If *allow_nan* is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the original JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). See *ignore_nan* for ECMA-262 compliant behavior. If *indent* is a string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. ``None`` (the default) selects the most compact representation without any newlines. For backwards compatibility with versions of simplejson earlier than 2.1.0, an integer is also accepted and is converted to a string with that many spaces. If specified, *separators* should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. *encoding* is the character encoding for str instances, default is UTF-8. *default(obj)* is a function that should return a serializable version of obj or raise ``TypeError``. The default simply raises ``TypeError``. If *use_decimal* is true (default: ``True``) then decimal.Decimal will be natively serialized to JSON with full precision. If *namedtuple_as_object* is true (default: ``True``), :class:`tuple` subclasses with ``_asdict()`` methods will be encoded as JSON objects. If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. If *iterable_as_array* is true (default: ``False``), any object not in the above table that implements ``__iter__()`` will be encoded as a JSON array. If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. Note that this is still a lossy operation that will not round-trip correctly and should be used sparingly. If *int_as_string_bitcount* is a positive number (n), then int of size greater than or equal to 2**n or lower than or equal to -2**n will be encoded as strings. If specified, *item_sort_key* is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precedence over *sort_keys*. If *sort_keys* is true (default: ``False``), the output of dictionaries will be sorted by item. If *for_json* is true (default: ``False``), objects with a ``for_json()`` method will use the return value of that method for encoding as JSON instead of the object. If *ignore_nan* is true (default: ``False``), then out of range :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as ``null`` in compliance with the ECMA-262 specification. If true, this will override *allow_nan*. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead of subclassing whenever possible. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and use_decimal and namedtuple_as_object and tuple_as_array and not iterable_as_array and not bigint_as_string and not sort_keys and not item_sort_key and not for_json and not ignore_nan and int_as_string_bitcount is None and not kw ): iterable = _default_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, encoding=encoding, default=default, use_decimal=use_decimal, namedtuple_as_object=namedtuple_as_object, tuple_as_array=tuple_as_array, iterable_as_array=iterable_as_array, bigint_as_string=bigint_as_string, sort_keys=sort_keys, item_sort_key=item_sort_key, for_json=for_json, ignore_nan=ignore_nan, int_as_string_bitcount=int_as_string_bitcount, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, use_decimal=True, namedtuple_as_object=True, tuple_as_array=True, bigint_as_string=False, sort_keys=False, item_sort_key=None, for_json=False, ignore_nan=False, int_as_string_bitcount=None, iterable_as_array=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is false then ``dict`` keys that are not basic types (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the return value will be a ``unicode`` instance subject to normal Python ``str`` to ``unicode`` coercion rules instead of being escaped to an ASCII ``str``. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a string, then JSON array elements and object members will be pretty-printed with a newline followed by that string repeated for each level of nesting. ``None`` (the default) selects the most compact representation without any newlines. For backwards compatibility with versions of simplejson earlier than 2.1.0, an integer is also accepted and is converted to a string with that many spaces. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``encoding`` is the character encoding for str instances, default is UTF-8. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *use_decimal* is true (default: ``True``) then decimal.Decimal will be natively serialized to JSON with full precision. If *namedtuple_as_object* is true (default: ``True``), :class:`tuple` subclasses with ``_asdict()`` methods will be encoded as JSON objects. If *tuple_as_array* is true (default: ``True``), :class:`tuple` (and subclasses) will be encoded as JSON arrays. If *iterable_as_array* is true (default: ``False``), any object not in the above table that implements ``__iter__()`` will be encoded as a JSON array. If *bigint_as_string* is true (not the default), ints 2**53 and higher or lower than -2**53 will be encoded as strings. This is to avoid the rounding that happens in Javascript otherwise. If *int_as_string_bitcount* is a positive number (n), then int of size greater than or equal to 2**n or lower than or equal to -2**n will be encoded as strings. If specified, *item_sort_key* is a callable used to sort the items in each dictionary. This is useful if you want to sort items other than in alphabetical order by key. This option takes precendence over *sort_keys*. If *sort_keys* is true (default: ``False``), the output of dictionaries will be sorted by item. If *for_json* is true (default: ``False``), objects with a ``for_json()`` method will use the return value of that method for encoding as JSON instead of the object. If *ignore_nan* is true (default: ``False``), then out of range :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as ``null`` in compliance with the ECMA-262 specification. If true, this will override *allow_nan*. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing whenever possible. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and use_decimal and namedtuple_as_object and tuple_as_array and not iterable_as_array and not bigint_as_string and not sort_keys and not item_sort_key and not for_json and not ignore_nan and int_as_string_bitcount is None and not kw ): return _default_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, encoding=encoding, default=default, use_decimal=use_decimal, namedtuple_as_object=namedtuple_as_object, tuple_as_array=tuple_as_array, iterable_as_array=iterable_as_array, bigint_as_string=bigint_as_string, sort_keys=sort_keys, item_sort_key=item_sort_key, for_json=for_json, ignore_nan=ignore_nan, int_as_string_bitcount=int_as_string_bitcount, **kw).encode(obj) _default_decoder = JSONDecoder(encoding=None, object_hook=None, object_pairs_hook=None) def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, use_decimal=False, namedtuple_as_object=True, tuple_as_array=True, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. *encoding* determines the encoding used to interpret any :class:`str` objects decoded by this instance (``'utf-8'`` by default). It has no effect when decoding :class:`unicode` objects. Note that currently only encodings that are a superset of ASCII work, strings of other encodings should be passed in as :class:`unicode`. *object_hook*, if specified, will be called with the result of every JSON object decoded and its return value will be used in place of the given :class:`dict`. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting). *object_pairs_hook* is an optional function that will be called with the result of any object literal decode with an ordered list of pairs. The return value of *object_pairs_hook* will be used instead of the :class:`dict`. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, :func:`collections.OrderedDict` will remember the order of insertion). If *object_hook* is also defined, the *object_pairs_hook* takes priority. *parse_float*, if specified, will be called with the string of every JSON float to be decoded. By default, this is equivalent to ``float(num_str)``. This can be used to use another datatype or parser for JSON floats (e.g. :class:`decimal.Decimal`). *parse_int*, if specified, will be called with the string of every JSON int to be decoded. By default, this is equivalent to ``int(num_str)``. This can be used to use another datatype or parser for JSON integers (e.g. :class:`float`). *parse_constant*, if specified, will be called with one of the following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This can be used to raise an exception if invalid JSON numbers are encountered. If *use_decimal* is true (default: ``False``) then it implies parse_float=decimal.Decimal for parity with ``dump``. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead of subclassing whenever possible. """ return loads(fp.read(), encoding=encoding, cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, use_decimal=use_decimal, **kw) def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, use_decimal=False, **kw): """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON document) to a Python object. *encoding* determines the encoding used to interpret any :class:`str` objects decoded by this instance (``'utf-8'`` by default). It has no effect when decoding :class:`unicode` objects. Note that currently only encodings that are a superset of ASCII work, strings of other encodings should be passed in as :class:`unicode`. *object_hook*, if specified, will be called with the result of every JSON object decoded and its return value will be used in place of the given :class:`dict`. This can be used to provide custom deserializations (e.g. to support JSON-RPC class hinting). *object_pairs_hook* is an optional function that will be called with the result of any object literal decode with an ordered list of pairs. The return value of *object_pairs_hook* will be used instead of the :class:`dict`. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, :func:`collections.OrderedDict` will remember the order of insertion). If *object_hook* is also defined, the *object_pairs_hook* takes priority. *parse_float*, if specified, will be called with the string of every JSON float to be decoded. By default, this is equivalent to ``float(num_str)``. This can be used to use another datatype or parser for JSON floats (e.g. :class:`decimal.Decimal`). *parse_int*, if specified, will be called with the string of every JSON int to be decoded. By default, this is equivalent to ``int(num_str)``. This can be used to use another datatype or parser for JSON integers (e.g. :class:`float`). *parse_constant*, if specified, will be called with one of the following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This can be used to raise an exception if invalid JSON numbers are encountered. If *use_decimal* is true (default: ``False``) then it implies parse_float=decimal.Decimal for parity with ``dump``. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead of subclassing whenever possible. """ if (cls is None and encoding is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not use_decimal and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant if use_decimal: if parse_float is not None: raise TypeError("use_decimal=True implies parse_float=Decimal") kw['parse_float'] = Decimal return cls(encoding=encoding, **kw).decode(s) def _toggle_speedups(enabled): from . import decoder as dec from . import encoder as enc from . import scanner as scan c_make_encoder = _import_c_make_encoder() if enabled: dec.scanstring = dec.c_scanstring or dec.py_scanstring enc.c_make_encoder = c_make_encoder enc.encode_basestring_ascii = (enc.c_encode_basestring_ascii or enc.py_encode_basestring_ascii) scan.make_scanner = scan.c_make_scanner or scan.py_make_scanner else: dec.scanstring = dec.py_scanstring enc.c_make_encoder = None enc.encode_basestring_ascii = enc.py_encode_basestring_ascii scan.make_scanner = scan.py_make_scanner dec.make_scanner = scan.make_scanner global _default_decoder _default_decoder = JSONDecoder( encoding=None, object_hook=None, object_pairs_hook=None, ) global _default_encoder _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, encoding='utf-8', default=None, ) def simple_first(kv): """Helper function to pass to item_sort_key to sort simple elements to the top, then container elements. """ return (isinstance(kv[1], (list, dict, tuple)), kv[0]) opt/alt/python35/lib/python3.5/site-packages/pip/_vendor/__init__.py000064400000010754152353350260021224 0ustar00""" pip._vendor is for vendoring dependencies of pip to prevent needing pip to depend on something external. Files inside of pip._vendor should be considered immutable and should only be updated to versions from upstream. """ from __future__ import absolute_import import glob import os.path import sys # Downstream redistributors which have debundled our dependencies should also # patch this value to be true. This will trigger the additional patching # to cause things like "six" to be available as pip. DEBUNDLED = False # By default, look in this directory for a bunch of .whl files which we will # add to the beginning of sys.path before attempting to import anything. This # is done to support downstream re-distributors like Debian and Fedora who # wish to create their own Wheels for our dependencies to aid in debundling. WHEEL_DIR = os.path.abspath(os.path.dirname(__file__)) # Define a small helper function to alias our vendored modules to the real ones # if the vendored ones do not exist. This idea of this was taken from # https://github.com/kennethreitz/requests/pull/2567. def vendored(modulename): vendored_name = "{0}.{1}".format(__name__, modulename) try: __import__(modulename, globals(), locals(), level=0) except ImportError: # This error used to be silenced in earlier variants of this file, to instead # raise the error when pip actually tries to use the missing module. # Based on inputs in #5354, this was changed to explicitly raise the error. # Re-raising the exception without modifying it is an intentional choice. raise else: sys.modules[vendored_name] = sys.modules[modulename] base, head = vendored_name.rsplit(".", 1) setattr(sys.modules[base], head, sys.modules[modulename]) # If we're operating in a debundled setup, then we want to go ahead and trigger # the aliasing of our vendored libraries as well as looking for wheels to add # to our sys.path. This will cause all of this code to be a no-op typically # however downstream redistributors can enable it in a consistent way across # all platforms. if DEBUNDLED: # Actually look inside of WHEEL_DIR to find .whl files and add them to the # front of our sys.path. sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path # Actually alias all of our vendored dependencies. vendored("appdirs") vendored("cachecontrol") vendored("certifi") vendored("colorama") vendored("contextlib2") vendored("distlib") vendored("distro") vendored("html5lib") vendored("six") vendored("six.moves") vendored("six.moves.urllib") vendored("six.moves.urllib.parse") vendored("packaging") vendored("packaging.version") vendored("packaging.specifiers") vendored("pep517") vendored("pkg_resources") vendored("progress") vendored("retrying") vendored("requests") vendored("requests.exceptions") vendored("requests.packages") vendored("requests.packages.urllib3") vendored("requests.packages.urllib3._collections") vendored("requests.packages.urllib3.connection") vendored("requests.packages.urllib3.connectionpool") vendored("requests.packages.urllib3.contrib") vendored("requests.packages.urllib3.contrib.ntlmpool") vendored("requests.packages.urllib3.contrib.pyopenssl") vendored("requests.packages.urllib3.exceptions") vendored("requests.packages.urllib3.fields") vendored("requests.packages.urllib3.filepost") vendored("requests.packages.urllib3.packages") vendored("requests.packages.urllib3.packages.ordered_dict") vendored("requests.packages.urllib3.packages.six") vendored("requests.packages.urllib3.packages.ssl_match_hostname") vendored("requests.packages.urllib3.packages.ssl_match_hostname." "_implementation") vendored("requests.packages.urllib3.poolmanager") vendored("requests.packages.urllib3.request") vendored("requests.packages.urllib3.response") vendored("requests.packages.urllib3.util") vendored("requests.packages.urllib3.util.connection") vendored("requests.packages.urllib3.util.request") vendored("requests.packages.urllib3.util.response") vendored("requests.packages.urllib3.util.retry") vendored("requests.packages.urllib3.util.ssl_") vendored("requests.packages.urllib3.util.timeout") vendored("requests.packages.urllib3.util.url") vendored("resolvelib") vendored("toml") vendored("toml.encoder") vendored("toml.decoder") vendored("urllib3") opt/alt/python38/lib/python3.8/site-packages/cerberus/__init__.py000064400000001256152353421020020606 0ustar00""" Extensible validation for Python dictionaries. :copyright: 2012-2021 by Nicola Iarocci. :license: ISC, see LICENSE for more details. Full documentation is available at https://python-cerberus.org/ """ from __future__ import absolute_import from importlib.metadata import version from cerberus.schema import rules_set_registry, schema_registry, SchemaError from cerberus.utils import TypeDefinition from cerberus.validator import DocumentError, Validator __version__ = version("Cerberus") __all__ = [ DocumentError.__name__, SchemaError.__name__, TypeDefinition.__name__, Validator.__name__, "schema_registry", "rules_set_registry", ] lib64/python3.8/sqlite3/__init__.py000064400000001772152353652660012757 0ustar00# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. from sqlite3.dbapi2 import * usr/lib64/python3.12/tkinter/__init__.py000064400000522160152353673120013730 0ustar00"""Wrapper functions for Tcl/Tk. Tkinter provides classes which allow the display, positioning and control of widgets. Toplevel widgets are Tk and Toplevel. Other widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox LabelFrame and PanedWindow. Properties of the widgets are specified with keyword arguments. Keyword arguments have the same name as the corresponding resource under Tk. Widgets are positioned with one of the geometry managers Place, Pack or Grid. These managers can be called with methods place, pack, grid available in every Widget. Actions are bound to events by resources (e.g. keyword argument command) or with the method bind. Example (Hello, World): import tkinter from tkinter.constants import * tk = tkinter.Tk() frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2) frame.pack(fill=BOTH,expand=1) label = tkinter.Label(frame, text="Hello, World") label.pack(fill=X, expand=1) button = tkinter.Button(frame,text="Exit",command=tk.destroy) button.pack(side=BOTTOM) tk.mainloop() """ import collections import enum import sys import types import _tkinter # If this fails your Python may not be configured for Tk TclError = _tkinter.TclError from tkinter.constants import * import re wantobjects = 1 _debug = False # set to True to print executed Tcl/Tk commands TkVersion = float(_tkinter.TK_VERSION) TclVersion = float(_tkinter.TCL_VERSION) READABLE = _tkinter.READABLE WRITABLE = _tkinter.WRITABLE EXCEPTION = _tkinter.EXCEPTION _magic_re = re.compile(r'([\\{}])') _space_re = re.compile(r'([\s])', re.ASCII) def _join(value): """Internal function.""" return ' '.join(map(_stringify, value)) def _stringify(value): """Internal function.""" if isinstance(value, (list, tuple)): if len(value) == 1: value = _stringify(value[0]) if _magic_re.search(value): value = '{%s}' % value else: value = '{%s}' % _join(value) else: if isinstance(value, bytes): value = str(value, 'latin1') else: value = str(value) if not value: value = '{}' elif _magic_re.search(value): # add '\' before special characters and spaces value = _magic_re.sub(r'\\\1', value) value = value.replace('\n', r'\n') value = _space_re.sub(r'\\\1', value) if value[0] == '"': value = '\\' + value elif value[0] == '"' or _space_re.search(value): value = '{%s}' % value return value def _flatten(seq): """Internal function.""" res = () for item in seq: if isinstance(item, (tuple, list)): res = res + _flatten(item) elif item is not None: res = res + (item,) return res try: _flatten = _tkinter._flatten except AttributeError: pass def _cnfmerge(cnfs): """Internal function.""" if isinstance(cnfs, dict): return cnfs elif isinstance(cnfs, (type(None), str)): return cnfs else: cnf = {} for c in _flatten(cnfs): try: cnf.update(c) except (AttributeError, TypeError) as msg: print("_cnfmerge: fallback due to:", msg) for k, v in c.items(): cnf[k] = v return cnf try: _cnfmerge = _tkinter._cnfmerge except AttributeError: pass def _splitdict(tk, v, cut_minus=True, conv=None): """Return a properly formatted dict built from Tcl list pairs. If cut_minus is True, the supposed '-' prefix will be removed from keys. If conv is specified, it is used to convert values. Tcl list is expected to contain an even number of elements. """ t = tk.splitlist(v) if len(t) % 2: raise RuntimeError('Tcl list representing a dict is expected ' 'to contain an even number of elements') it = iter(t) dict = {} for key, value in zip(it, it): key = str(key) if cut_minus and key[0] == '-': key = key[1:] if conv: value = conv(value) dict[key] = value return dict class _VersionInfoType(collections.namedtuple('_VersionInfoType', ('major', 'minor', 'micro', 'releaselevel', 'serial'))): def __str__(self): if self.releaselevel == 'final': return f'{self.major}.{self.minor}.{self.micro}' else: return f'{self.major}.{self.minor}{self.releaselevel[0]}{self.serial}' def _parse_version(version): import re m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', version) major, minor, releaselevel, serial = m.groups() major, minor, serial = int(major), int(minor), int(serial) if releaselevel == '.': micro = serial serial = 0 releaselevel = 'final' else: micro = 0 releaselevel = {'a': 'alpha', 'b': 'beta'}[releaselevel] return _VersionInfoType(major, minor, micro, releaselevel, serial) @enum._simple_enum(enum.StrEnum) class EventType: KeyPress = '2' Key = KeyPress KeyRelease = '3' ButtonPress = '4' Button = ButtonPress ButtonRelease = '5' Motion = '6' Enter = '7' Leave = '8' FocusIn = '9' FocusOut = '10' Keymap = '11' # undocumented Expose = '12' GraphicsExpose = '13' # undocumented NoExpose = '14' # undocumented Visibility = '15' Create = '16' Destroy = '17' Unmap = '18' Map = '19' MapRequest = '20' Reparent = '21' Configure = '22' ConfigureRequest = '23' Gravity = '24' ResizeRequest = '25' Circulate = '26' CirculateRequest = '27' Property = '28' SelectionClear = '29' # undocumented SelectionRequest = '30' # undocumented Selection = '31' # undocumented Colormap = '32' ClientMessage = '33' # undocumented Mapping = '34' # undocumented VirtualEvent = '35' # undocumented Activate = '36' Deactivate = '37' MouseWheel = '38' class Event: """Container for the properties of an event. Instances of this type are generated if one of the following events occurs: KeyPress, KeyRelease - for keyboard events ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, Colormap, Gravity, Reparent, Property, Destroy, Activate, Deactivate - for window events. If a callback function for one of these events is registered using bind, bind_all, bind_class, or tag_bind, the callback is called with an Event as first argument. It will have the following attributes (in braces are the event types for which the attribute is valid): serial - serial number of event num - mouse button pressed (ButtonPress, ButtonRelease) focus - whether the window has the focus (Enter, Leave) height - height of the exposed window (Configure, Expose) width - width of the exposed window (Configure, Expose) keycode - keycode of the pressed key (KeyPress, KeyRelease) state - state of the event as a number (ButtonPress, ButtonRelease, Enter, KeyPress, KeyRelease, Leave, Motion) state - state as a string (Visibility) time - when the event occurred x - x-position of the mouse y - y-position of the mouse x_root - x-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) y_root - y-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) char - pressed character (KeyPress, KeyRelease) send_event - see X/Windows documentation keysym - keysym of the event as a string (KeyPress, KeyRelease) keysym_num - keysym of the event as a number (KeyPress, KeyRelease) type - type of the event as a number widget - widget in which the event occurred delta - delta of wheel movement (MouseWheel) """ def __repr__(self): attrs = {k: v for k, v in self.__dict__.items() if v != '??'} if not self.char: del attrs['char'] elif self.char != '??': attrs['char'] = repr(self.char) if not getattr(self, 'send_event', True): del attrs['send_event'] if self.state == 0: del attrs['state'] elif isinstance(self.state, int): state = self.state mods = ('Shift', 'Lock', 'Control', 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Button1', 'Button2', 'Button3', 'Button4', 'Button5') s = [] for i, n in enumerate(mods): if state & (1 << i): s.append(n) state = state & ~((1<< len(mods)) - 1) if state or not s: s.append(hex(state)) attrs['state'] = '|'.join(s) if self.delta == 0: del attrs['delta'] # widget usually is known # serial and time are not very interesting # keysym_num duplicates keysym # x_root and y_root mostly duplicate x and y keys = ('send_event', 'state', 'keysym', 'keycode', 'char', 'num', 'delta', 'focus', 'x', 'y', 'width', 'height') return '<%s event%s>' % ( getattr(self.type, 'name', self.type), ''.join(' %s=%s' % (k, attrs[k]) for k in keys if k in attrs) ) _support_default_root = True _default_root = None def NoDefaultRoot(): """Inhibit setting of default root window. Call this function to inhibit that the first instance of Tk is used for windows without an explicit parent window. """ global _support_default_root, _default_root _support_default_root = False # Delete, so any use of _default_root will immediately raise an exception. # Rebind before deletion, so repeated calls will not fail. _default_root = None del _default_root def _get_default_root(what=None): if not _support_default_root: raise RuntimeError("No master specified and tkinter is " "configured to not support default root") if _default_root is None: if what: raise RuntimeError(f"Too early to {what}: no default root window") root = Tk() assert _default_root is root return _default_root def _get_temp_root(): global _support_default_root if not _support_default_root: raise RuntimeError("No master specified and tkinter is " "configured to not support default root") root = _default_root if root is None: assert _support_default_root _support_default_root = False root = Tk() _support_default_root = True assert _default_root is None root.withdraw() root._temporary = True return root def _destroy_temp_root(master): if getattr(master, '_temporary', False): try: master.destroy() except TclError: pass def _tkerror(err): """Internal function.""" pass def _exit(code=0): """Internal function. Calling it will raise the exception SystemExit.""" try: code = int(code) except ValueError: pass raise SystemExit(code) _varnum = 0 class Variable: """Class to define value holders for e.g. buttons. Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations that constrain the type of the value returned from get().""" _default = "" _tk = None _tclCommands = None def __init__(self, master=None, value=None, name=None): """Construct a variable MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ # check for type of NAME parameter to override weird error message # raised from Modules/_tkinter.c:SetVar like: # TypeError: setvar() takes exactly 3 arguments (2 given) if name is not None and not isinstance(name, str): raise TypeError("name must be a string") global _varnum if master is None: master = _get_default_root('create variable') self._root = master._root() self._tk = master.tk if name: self._name = name else: self._name = 'PY_VAR' + repr(_varnum) _varnum += 1 if value is not None: self.initialize(value) elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)): self.initialize(self._default) def __del__(self): """Unset the variable in Tcl.""" if self._tk is None: return if self._tk.getboolean(self._tk.call("info", "exists", self._name)): self._tk.globalunsetvar(self._name) if self._tclCommands is not None: for name in self._tclCommands: self._tk.deletecommand(name) self._tclCommands = None def __str__(self): """Return the name of the variable in Tcl.""" return self._name def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, value) initialize = set def get(self): """Return value of variable.""" return self._tk.globalgetvar(self._name) def _register(self, callback): f = CallWrapper(callback, None, self._root).__call__ cbname = repr(id(f)) try: callback = callback.__func__ except AttributeError: pass try: cbname = cbname + callback.__name__ except AttributeError: pass self._tk.createcommand(cbname, f) if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(cbname) return cbname def trace_add(self, mode, callback): """Define a trace callback for the variable. Mode is one of "read", "write", "unset", or a list or tuple of such strings. Callback must be a function which is called when the variable is read, written or unset. Return the name of the callback. """ cbname = self._register(callback) self._tk.call('trace', 'add', 'variable', self._name, mode, (cbname,)) return cbname def trace_remove(self, mode, cbname): """Delete the trace callback for a variable. Mode is one of "read", "write", "unset" or a list or tuple of such strings. Must be same as were specified in trace_add(). cbname is the name of the callback returned from trace_add(). """ self._tk.call('trace', 'remove', 'variable', self._name, mode, cbname) for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_info(self): """Return all trace callback information.""" splitlist = self._tk.splitlist return [(splitlist(k), v) for k, v in map(splitlist, splitlist(self._tk.call('trace', 'info', 'variable', self._name)))] def trace_variable(self, mode, callback): """Define a trace callback for the variable. MODE is one of "r", "w", "u" for read, write, undefine. CALLBACK must be a function which is called when the variable is read, written or undefined. Return the name of the callback. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_add() instead. """ # TODO: Add deprecation warning cbname = self._register(callback) self._tk.call("trace", "variable", self._name, mode, cbname) return cbname trace = trace_variable def trace_vdelete(self, mode, cbname): """Delete the trace callback for a variable. MODE is one of "r", "w", "u" for read, write, undefine. CBNAME is the name of the callback returned from trace_variable or trace. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_remove() instead. """ # TODO: Add deprecation warning self._tk.call("trace", "vdelete", self._name, mode, cbname) cbname = self._tk.splitlist(cbname)[0] for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_vinfo(self): """Return all trace callback information. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_info() instead. """ # TODO: Add deprecation warning return [self._tk.splitlist(x) for x in self._tk.splitlist( self._tk.call("trace", "vinfo", self._name))] def __eq__(self, other): if not isinstance(other, Variable): return NotImplemented return (self._name == other._name and self.__class__.__name__ == other.__class__.__name__ and self._tk == other._tk) class StringVar(Variable): """Value holder for strings variables.""" _default = "" def __init__(self, master=None, value=None, name=None): """Construct a string variable. MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return value of variable as string.""" value = self._tk.globalgetvar(self._name) if isinstance(value, str): return value return str(value) class IntVar(Variable): """Value holder for integer variables.""" _default = 0 def __init__(self, master=None, value=None, name=None): """Construct an integer variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as an integer.""" value = self._tk.globalgetvar(self._name) try: return self._tk.getint(value) except (TypeError, TclError): return int(self._tk.getdouble(value)) class DoubleVar(Variable): """Value holder for float variables.""" _default = 0.0 def __init__(self, master=None, value=None, name=None): """Construct a float variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0.0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as a float.""" return self._tk.getdouble(self._tk.globalgetvar(self._name)) class BooleanVar(Variable): """Value holder for boolean variables.""" _default = False def __init__(self, master=None, value=None, name=None): """Construct a boolean variable. MASTER can be given as master widget. VALUE is an optional value (defaults to False) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, self._tk.getboolean(value)) initialize = set def get(self): """Return the value of the variable as a bool.""" try: return self._tk.getboolean(self._tk.globalgetvar(self._name)) except TclError: raise ValueError("invalid literal for getboolean()") def mainloop(n=0): """Run the main loop of Tcl.""" _get_default_root('run the main loop').tk.mainloop(n) getint = int getdouble = float def getboolean(s): """Convert Tcl object to True or False.""" try: return _get_default_root('use getboolean()').tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") # Methods defined on both toplevel and interior widgets class Misc: """Internal class. Base class which defines methods common for interior widgets.""" # used for generating child widget names _last_child_ids = None # XXX font command? _tclCommands = None def destroy(self): """Internal function. Delete all Tcl commands created for this widget in the Tcl interpreter.""" if self._tclCommands is not None: for name in self._tclCommands: self.tk.deletecommand(name) self._tclCommands = None def deletecommand(self, name): """Internal function. Delete the Tcl command provided in NAME.""" self.tk.deletecommand(name) try: self._tclCommands.remove(name) except ValueError: pass def tk_strictMotif(self, boolean=None): """Set Tcl internal variable, whether the look and feel should adhere to Motif. A parameter of 1 means adhere to Motif (e.g. no color change if mouse passes over slider). Returns the set value.""" return self.tk.getboolean(self.tk.call( 'set', 'tk_strictMotif', boolean)) def tk_bisque(self): """Change the color scheme to light brown as used in Tk 3.6 and before.""" self.tk.call('tk_bisque') def tk_setPalette(self, *args, **kw): """Set a new color scheme for all widget elements. A single color as argument will cause that all colors of Tk widget elements are derived from this. Alternatively several keyword parameters and its associated colors can be given. The following keywords are valid: activeBackground, foreground, selectColor, activeForeground, highlightBackground, selectBackground, background, highlightColor, selectForeground, disabledForeground, insertBackground, troughColor.""" self.tk.call(('tk_setPalette',) + _flatten(args) + _flatten(list(kw.items()))) def wait_variable(self, name='PY_VAR'): """Wait until the variable is modified. A parameter of type IntVar, StringVar, DoubleVar or BooleanVar must be given.""" self.tk.call('tkwait', 'variable', name) waitvar = wait_variable # XXX b/w compat def wait_window(self, window=None): """Wait until a WIDGET is destroyed. If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'window', window._w) def wait_visibility(self, window=None): """Wait until the visibility of a WIDGET changes (e.g. it appears). If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'visibility', window._w) def setvar(self, name='PY_VAR', value='1'): """Set Tcl variable NAME to VALUE.""" self.tk.setvar(name, value) def getvar(self, name='PY_VAR'): """Return value of Tcl variable NAME.""" return self.tk.getvar(name) def getint(self, s): try: return self.tk.getint(s) except TclError as exc: raise ValueError(str(exc)) def getdouble(self, s): try: return self.tk.getdouble(s) except TclError as exc: raise ValueError(str(exc)) def getboolean(self, s): """Return a boolean value for Tcl boolean values true and false given as parameter.""" try: return self.tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") def focus_set(self): """Direct input focus to this widget. If the application currently does not have the focus this widget will get the focus if the application gets the focus through the window manager.""" self.tk.call('focus', self._w) focus = focus_set # XXX b/w compat? def focus_force(self): """Direct input focus to this widget even if the application does not have the focus. Use with caution!""" self.tk.call('focus', '-force', self._w) def focus_get(self): """Return the widget which has currently the focus in the application. Use focus_displayof to allow working with several displays. Return None if application does not have the focus.""" name = self.tk.call('focus') if name == 'none' or not name: return None return self._nametowidget(name) def focus_displayof(self): """Return the widget which has currently the focus on the display where this widget is located. Return None if the application does not have the focus.""" name = self.tk.call('focus', '-displayof', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def focus_lastfor(self): """Return the widget which would have the focus if top level for this widget gets the focus from the window manager.""" name = self.tk.call('focus', '-lastfor', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def tk_focusFollowsMouse(self): """The widget under mouse will get automatically focus. Can not be disabled easily.""" self.tk.call('tk_focusFollowsMouse') def tk_focusNext(self): """Return the next widget in the focus order which follows widget which has currently the focus. The focus order first goes to the next child, then to the children of the child recursively and then to the next sibling which is higher in the stacking order. A widget is omitted if it has the takefocus resource set to 0.""" name = self.tk.call('tk_focusNext', self._w) if not name: return None return self._nametowidget(name) def tk_focusPrev(self): """Return previous widget in the focus order. See tk_focusNext for details.""" name = self.tk.call('tk_focusPrev', self._w) if not name: return None return self._nametowidget(name) def after(self, ms, func=None, *args): """Call function once after given time. MS specifies the time in milliseconds. FUNC gives the function which shall be called. Additional parameters are given as parameters to the function call. Return identifier to cancel scheduling with after_cancel.""" if func is None: # I'd rather use time.sleep(ms*0.001) self.tk.call('after', ms) return None else: def callit(): try: func(*args) finally: try: self.deletecommand(name) except TclError: pass try: callit.__name__ = func.__name__ except AttributeError: # Required for callable classes (bpo-44404) callit.__name__ = type(func).__name__ name = self._register(callit) return self.tk.call('after', ms, name) def after_idle(self, func, *args): """Call FUNC once if the Tcl main loop has no event to process. Return an identifier to cancel the scheduling with after_cancel.""" return self.after('idle', func, *args) def after_cancel(self, id): """Cancel scheduling of function identified with ID. Identifier returned by after or after_idle must be given as first parameter. """ if not id: raise ValueError('id must be a valid identifier returned from ' 'after or after_idle') try: data = self.tk.call('after', 'info', id) script = self.tk.splitlist(data)[0] self.deletecommand(script) except TclError: pass self.tk.call('after', 'cancel', id) def bell(self, displayof=0): """Ring a display's bell.""" self.tk.call(('bell',) + self._displayof(displayof)) # Clipboard handling: def clipboard_get(self, **kw): """Retrieve data from the clipboard on window's display. The window keyword defaults to the root window of the Tkinter application. The type keyword specifies the form in which the data is to be returned and should be an atom name such as STRING or FILE_NAME. Type defaults to STRING, except on X11, where the default is to try UTF8_STRING and fall back to STRING. This command is equivalent to: selection_get(CLIPBOARD) """ if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('clipboard', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('clipboard', 'get') + self._options(kw)) def clipboard_clear(self, **kw): """Clear the data in the Tk clipboard. A widget specified for the optional displayof keyword argument specifies the target display.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'clear') + self._options(kw)) def clipboard_append(self, string, **kw): """Append STRING to the Tk clipboard. A widget specified at the optional displayof keyword argument specifies the target display. The clipboard can be retrieved with selection_get.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'append') + self._options(kw) + ('--', string)) # XXX grab current w/o window argument def grab_current(self): """Return widget which has currently the grab in this application or None.""" name = self.tk.call('grab', 'current', self._w) if not name: return None return self._nametowidget(name) def grab_release(self): """Release grab for this widget if currently set.""" self.tk.call('grab', 'release', self._w) def grab_set(self): """Set grab for this widget. A grab directs all events to this and descendant widgets in the application.""" self.tk.call('grab', 'set', self._w) def grab_set_global(self): """Set global grab for this widget. A global grab directs all events to this and descendant widgets on the display. Use with caution - other applications do not get events anymore.""" self.tk.call('grab', 'set', '-global', self._w) def grab_status(self): """Return None, "local" or "global" if this widget has no, a local or a global grab.""" status = self.tk.call('grab', 'status', self._w) if status == 'none': status = None return status def option_add(self, pattern, value, priority = None): """Set a VALUE (second parameter) for an option PATTERN (first parameter). An optional third parameter gives the numeric priority (defaults to 80).""" self.tk.call('option', 'add', pattern, value, priority) def option_clear(self): """Clear the option database. It will be reloaded if option_add is called.""" self.tk.call('option', 'clear') def option_get(self, name, className): """Return the value for an option NAME for this widget with CLASSNAME. Values with higher priority override lower values.""" return self.tk.call('option', 'get', self._w, name, className) def option_readfile(self, fileName, priority = None): """Read file FILENAME into the option database. An optional second parameter gives the numeric priority.""" self.tk.call('option', 'readfile', fileName, priority) def selection_clear(self, **kw): """Clear the current X selection.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('selection', 'clear') + self._options(kw)) def selection_get(self, **kw): """Return the contents of the current X selection. A keyword parameter selection specifies the name of the selection and defaults to PRIMARY. A keyword parameter displayof specifies a widget on the display to use. A keyword parameter type specifies the form of data to be fetched, defaulting to STRING except on X11, where UTF8_STRING is tried before STRING.""" if 'displayof' not in kw: kw['displayof'] = self._w if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('selection', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('selection', 'get') + self._options(kw)) def selection_handle(self, command, **kw): """Specify a function COMMAND to call if the X selection owned by this widget is queried by another application. This function must return the contents of the selection. The function will be called with the arguments OFFSET and LENGTH which allows the chunking of very long selections. The following keyword parameters can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" name = self._register(command) self.tk.call(('selection', 'handle') + self._options(kw) + (self._w, name)) def selection_own(self, **kw): """Become owner of X selection. A keyword parameter selection specifies the name of the selection (default PRIMARY).""" self.tk.call(('selection', 'own') + self._options(kw) + (self._w,)) def selection_own_get(self, **kw): """Return owner of X selection. The following keyword parameter can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" if 'displayof' not in kw: kw['displayof'] = self._w name = self.tk.call(('selection', 'own') + self._options(kw)) if not name: return None return self._nametowidget(name) def send(self, interp, cmd, *args): """Send Tcl command CMD to different interpreter INTERP to be executed.""" return self.tk.call(('send', interp, cmd) + args) def lower(self, belowThis=None): """Lower this widget in the stacking order.""" self.tk.call('lower', self._w, belowThis) def tkraise(self, aboveThis=None): """Raise this widget in the stacking order.""" self.tk.call('raise', self._w, aboveThis) lift = tkraise def info_patchlevel(self): """Returns the exact version of the Tcl library.""" patchlevel = self.tk.call('info', 'patchlevel') return _parse_version(patchlevel) def winfo_atom(self, name, displayof=0): """Return integer which represents atom NAME.""" args = ('winfo', 'atom') + self._displayof(displayof) + (name,) return self.tk.getint(self.tk.call(args)) def winfo_atomname(self, id, displayof=0): """Return name of atom with identifier ID.""" args = ('winfo', 'atomname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_cells(self): """Return number of cells in the colormap for this widget.""" return self.tk.getint( self.tk.call('winfo', 'cells', self._w)) def winfo_children(self): """Return a list of all widgets which are children of this widget.""" result = [] for child in self.tk.splitlist( self.tk.call('winfo', 'children', self._w)): try: # Tcl sometimes returns extra windows, e.g. for # menus; those need to be skipped result.append(self._nametowidget(child)) except KeyError: pass return result def winfo_class(self): """Return window class name of this widget.""" return self.tk.call('winfo', 'class', self._w) def winfo_colormapfull(self): """Return True if at the last color request the colormap was full.""" return self.tk.getboolean( self.tk.call('winfo', 'colormapfull', self._w)) def winfo_containing(self, rootX, rootY, displayof=0): """Return the widget which is at the root coordinates ROOTX, ROOTY.""" args = ('winfo', 'containing') \ + self._displayof(displayof) + (rootX, rootY) name = self.tk.call(args) if not name: return None return self._nametowidget(name) def winfo_depth(self): """Return the number of bits per pixel.""" return self.tk.getint(self.tk.call('winfo', 'depth', self._w)) def winfo_exists(self): """Return true if this widget exists.""" return self.tk.getint( self.tk.call('winfo', 'exists', self._w)) def winfo_fpixels(self, number): """Return the number of pixels for the given distance NUMBER (e.g. "3c") as float.""" return self.tk.getdouble(self.tk.call( 'winfo', 'fpixels', self._w, number)) def winfo_geometry(self): """Return geometry string for this widget in the form "widthxheight+X+Y".""" return self.tk.call('winfo', 'geometry', self._w) def winfo_height(self): """Return height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'height', self._w)) def winfo_id(self): """Return identifier ID for this widget.""" return int(self.tk.call('winfo', 'id', self._w), 0) def winfo_interps(self, displayof=0): """Return the name of all Tcl interpreters for this display.""" args = ('winfo', 'interps') + self._displayof(displayof) return self.tk.splitlist(self.tk.call(args)) def winfo_ismapped(self): """Return true if this widget is mapped.""" return self.tk.getint( self.tk.call('winfo', 'ismapped', self._w)) def winfo_manager(self): """Return the window manager name for this widget.""" return self.tk.call('winfo', 'manager', self._w) def winfo_name(self): """Return the name of this widget.""" return self.tk.call('winfo', 'name', self._w) def winfo_parent(self): """Return the name of the parent of this widget.""" return self.tk.call('winfo', 'parent', self._w) def winfo_pathname(self, id, displayof=0): """Return the pathname of the widget given by ID.""" if isinstance(id, int): id = hex(id) args = ('winfo', 'pathname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_pixels(self, number): """Rounded integer value of winfo_fpixels.""" return self.tk.getint( self.tk.call('winfo', 'pixels', self._w, number)) def winfo_pointerx(self): """Return the x coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointerx', self._w)) def winfo_pointerxy(self): """Return a tuple of x and y coordinates of the pointer on the root window.""" return self._getints( self.tk.call('winfo', 'pointerxy', self._w)) def winfo_pointery(self): """Return the y coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointery', self._w)) def winfo_reqheight(self): """Return requested height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqheight', self._w)) def winfo_reqwidth(self): """Return requested width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqwidth', self._w)) def winfo_rgb(self, color): """Return a tuple of integer RGB values in range(65536) for color in this widget.""" return self._getints( self.tk.call('winfo', 'rgb', self._w, color)) def winfo_rootx(self): """Return x coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rootx', self._w)) def winfo_rooty(self): """Return y coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rooty', self._w)) def winfo_screen(self): """Return the screen name of this widget.""" return self.tk.call('winfo', 'screen', self._w) def winfo_screencells(self): """Return the number of the cells in the colormap of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screencells', self._w)) def winfo_screendepth(self): """Return the number of bits per pixel of the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screendepth', self._w)) def winfo_screenheight(self): """Return the number of pixels of the height of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenheight', self._w)) def winfo_screenmmheight(self): """Return the number of pixels of the height of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmheight', self._w)) def winfo_screenmmwidth(self): """Return the number of pixels of the width of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmwidth', self._w)) def winfo_screenvisual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the default colormodel of this screen.""" return self.tk.call('winfo', 'screenvisual', self._w) def winfo_screenwidth(self): """Return the number of pixels of the width of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenwidth', self._w)) def winfo_server(self): """Return information of the X-Server of the screen of this widget in the form "XmajorRminor vendor vendorVersion".""" return self.tk.call('winfo', 'server', self._w) def winfo_toplevel(self): """Return the toplevel widget of this widget.""" return self._nametowidget(self.tk.call( 'winfo', 'toplevel', self._w)) def winfo_viewable(self): """Return true if the widget and all its higher ancestors are mapped.""" return self.tk.getint( self.tk.call('winfo', 'viewable', self._w)) def winfo_visual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the colormodel of this widget.""" return self.tk.call('winfo', 'visual', self._w) def winfo_visualid(self): """Return the X identifier for the visual for this widget.""" return self.tk.call('winfo', 'visualid', self._w) def winfo_visualsavailable(self, includeids=False): """Return a list of all visuals available for the screen of this widget. Each item in the list consists of a visual name (see winfo_visual), a depth and if includeids is true is given also the X identifier.""" data = self.tk.call('winfo', 'visualsavailable', self._w, 'includeids' if includeids else None) data = [self.tk.splitlist(x) for x in self.tk.splitlist(data)] return [self.__winfo_parseitem(x) for x in data] def __winfo_parseitem(self, t): """Internal function.""" return t[:1] + tuple(map(self.__winfo_getint, t[1:])) def __winfo_getint(self, x): """Internal function.""" return int(x, 0) def winfo_vrootheight(self): """Return the height of the virtual root window associated with this widget in pixels. If there is no virtual root window return the height of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootheight', self._w)) def winfo_vrootwidth(self): """Return the width of the virtual root window associated with this widget in pixel. If there is no virtual root window return the width of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootwidth', self._w)) def winfo_vrootx(self): """Return the x offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrootx', self._w)) def winfo_vrooty(self): """Return the y offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrooty', self._w)) def winfo_width(self): """Return the width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'width', self._w)) def winfo_x(self): """Return the x coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'x', self._w)) def winfo_y(self): """Return the y coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'y', self._w)) def update(self): """Enter event loop until all pending events have been processed by Tcl.""" self.tk.call('update') def update_idletasks(self): """Enter event loop until all idle callbacks have been called. This will update the display of windows but not process events caused by the user.""" self.tk.call('update', 'idletasks') def bindtags(self, tagList=None): """Set or get the list of bindtags for this widget. With no argument return the list of all bindtags associated with this widget. With a list of strings as argument the bindtags are set to this list. The bindtags determine in which order events are processed (see bind).""" if tagList is None: return self.tk.splitlist( self.tk.call('bindtags', self._w)) else: self.tk.call('bindtags', self._w, tagList) def _bind(self, what, sequence, func, add, needcleanup=1): """Internal function.""" if isinstance(func, str): self.tk.call(what + (sequence, func)) elif func: funcid = self._register(func, self._substitute, needcleanup) cmd = ('%sif {"[%s %s]" == "break"} break\n' % (add and '+' or '', funcid, self._subst_format_str)) self.tk.call(what + (sequence, cmd)) return funcid elif sequence: return self.tk.call(what + (sequence,)) else: return self.tk.splitlist(self.tk.call(what)) def bind(self, sequence=None, func=None, add=None): """Bind to this widget at event SEQUENCE a call to function FUNC. SEQUENCE is a string of concatenated event patterns. An event pattern is of the form where MODIFIER is one of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, B3, Alt, Button4, B4, Double, Button5, B5 Triple, Mod1, M1. TYPE is one of Activate, Enter, Map, ButtonPress, Button, Expose, Motion, ButtonRelease FocusIn, MouseWheel, Circulate, FocusOut, Property, Colormap, Gravity Reparent, Configure, KeyPress, Key, Unmap, Deactivate, KeyRelease Visibility, Destroy, Leave and DETAIL is the button number for ButtonPress, ButtonRelease and DETAIL is the Keysym for KeyPress and KeyRelease. Examples are for pressing Control and mouse button 1 or for pressing A and the Alt key (KeyPress can be omitted). An event pattern can also be a virtual event of the form <> where AString can be arbitrary. This event can be generated by event_generate. If events are concatenated they must appear shortly after each other. FUNC will be called if the event sequence occurs with an instance of Event as argument. If the return value of FUNC is "break" no further bound function is invoked. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. Bind will return an identifier to allow deletion of the bound function with unbind without memory leak. If FUNC or SEQUENCE is omitted the bound function or list of bound events are returned.""" return self._bind(('bind', self._w), sequence, func, add) def unbind(self, sequence, funcid=None): """Unbind for this widget the event SEQUENCE. If FUNCID is given, only unbind the function identified with FUNCID and also delete the corresponding Tcl command. Otherwise destroy the current binding for SEQUENCE, leaving SEQUENCE unbound. """ self._unbind(('bind', self._w, sequence), funcid) def _unbind(self, what, funcid=None): if funcid is None: self.tk.call(*what, '') else: lines = self.tk.call(what).split('\n') prefix = f'if {{"[{funcid} ' keep = '\n'.join(line for line in lines if not line.startswith(prefix)) if not keep.strip(): keep = '' self.tk.call(*what, keep) self.deletecommand(funcid) def bind_all(self, sequence=None, func=None, add=None): """Bind to all widgets at an event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._root()._bind(('bind', 'all'), sequence, func, add, True) def unbind_all(self, sequence): """Unbind for all widgets for event SEQUENCE all functions.""" self._root()._unbind(('bind', 'all', sequence)) def bind_class(self, className, sequence=None, func=None, add=None): """Bind to widgets with bindtag CLASSNAME at event SEQUENCE a call of function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._root()._bind(('bind', className), sequence, func, add, True) def unbind_class(self, className, sequence): """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self._root()._unbind(('bind', className, sequence)) def mainloop(self, n=0): """Call the mainloop of Tk.""" self.tk.mainloop(n) def quit(self): """Quit the Tcl interpreter. All widgets will be destroyed.""" self.tk.quit() def _getints(self, string): """Internal function.""" if string: return tuple(map(self.tk.getint, self.tk.splitlist(string))) def _getdoubles(self, string): """Internal function.""" if string: return tuple(map(self.tk.getdouble, self.tk.splitlist(string))) def _getboolean(self, string): """Internal function.""" if string: return self.tk.getboolean(string) def _displayof(self, displayof): """Internal function.""" if displayof: return ('-displayof', displayof) if displayof is None: return ('-displayof', self._w) return () @property def _windowingsystem(self): """Internal function.""" try: return self._root()._windowingsystem_cached except AttributeError: ws = self._root()._windowingsystem_cached = \ self.tk.call('tk', 'windowingsystem') return ws def _options(self, cnf, kw = None): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) else: cnf = _cnfmerge(cnf) res = () for k, v in cnf.items(): if v is not None: if k[-1] == '_': k = k[:-1] if callable(v): v = self._register(v) elif isinstance(v, (tuple, list)): nv = [] for item in v: if isinstance(item, int): nv.append(str(item)) elif isinstance(item, str): nv.append(_stringify(item)) else: break else: v = ' '.join(nv) res = res + ('-'+k, v) return res def nametowidget(self, name): """Return the Tkinter instance of a widget identified by its Tcl name NAME.""" name = str(name).split('.') w = self if not name[0]: w = w._root() name = name[1:] for n in name: if not n: break w = w.children[n] return w _nametowidget = nametowidget def _register(self, func, subst=None, needcleanup=1): """Return a newly created Tcl function. If this function is called, the Python function FUNC will be executed. An optional function SUBST can be given which will be executed before FUNC.""" f = CallWrapper(func, subst, self).__call__ name = repr(id(f)) try: func = func.__func__ except AttributeError: pass try: name = name + func.__name__ except AttributeError: pass self.tk.createcommand(name, f) if needcleanup: if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(name) return name register = _register def _root(self): """Internal function.""" w = self while w.master is not None: w = w.master return w _subst_format = ('%#', '%b', '%f', '%h', '%k', '%s', '%t', '%w', '%x', '%y', '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') _subst_format_str = " ".join(_subst_format) def _substitute(self, *args): """Internal function.""" if len(args) != len(self._subst_format): return args getboolean = self.tk.getboolean getint = self.tk.getint def getint_event(s): """Tk changed behavior in 8.4.2, returning "??" rather more often.""" try: return getint(s) except (ValueError, TclError): return s nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args # Missing: (a, c, d, m, o, v, B, R) e = Event() # serial field: valid for all events # number of button: ButtonPress and ButtonRelease events only # height field: Configure, ConfigureRequest, Create, # ResizeRequest, and Expose events only # keycode field: KeyPress and KeyRelease events only # time field: "valid for events that contain a time field" # width field: Configure, ConfigureRequest, Create, ResizeRequest, # and Expose events only # x field: "valid for events that contain an x field" # y field: "valid for events that contain a y field" # keysym as decimal: KeyPress and KeyRelease events only # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, # KeyRelease, and Motion events e.serial = getint(nsign) e.num = getint_event(b) try: e.focus = getboolean(f) except TclError: pass e.height = getint_event(h) e.keycode = getint_event(k) e.state = getint_event(s) e.time = getint_event(t) e.width = getint_event(w) e.x = getint_event(x) e.y = getint_event(y) e.char = A try: e.send_event = getboolean(E) except TclError: pass e.keysym = K e.keysym_num = getint_event(N) try: e.type = EventType(T) except ValueError: e.type = T try: e.widget = self._nametowidget(W) except KeyError: e.widget = W e.x_root = getint_event(X) e.y_root = getint_event(Y) try: e.delta = getint(D) except (ValueError, TclError): e.delta = 0 return (e,) def _report_exception(self): """Internal function.""" exc, val, tb = sys.exc_info() root = self._root() root.report_callback_exception(exc, val, tb) def _getconfigure(self, *args): """Call Tcl configure command and return the result as a dict.""" cnf = {} for x in self.tk.splitlist(self.tk.call(*args)): x = self.tk.splitlist(x) cnf[x[0][1:]] = (x[0][1:],) + x[1:] return cnf def _getconfigure1(self, *args): x = self.tk.splitlist(self.tk.call(*args)) return (x[0][1:],) + x[1:] def _configure(self, cmd, cnf, kw): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) elif cnf: cnf = _cnfmerge(cnf) if cnf is None: return self._getconfigure(_flatten((self._w, cmd))) if isinstance(cnf, str): return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) # These used to be defined in Widget: def configure(self, cnf=None, **kw): """Configure resources of a widget. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method keys. """ return self._configure('configure', cnf, kw) config = configure def cget(self, key): """Return the resource value for a KEY given as string.""" return self.tk.call(self._w, 'cget', '-' + key) __getitem__ = cget def __setitem__(self, key, value): self.configure({key: value}) def keys(self): """Return a list of all resource names of this widget.""" splitlist = self.tk.splitlist return [splitlist(x)[0][1:] for x in splitlist(self.tk.call(self._w, 'configure'))] def __str__(self): """Return the window path name of this widget.""" return self._w def __repr__(self): return '<%s.%s object %s>' % ( self.__class__.__module__, self.__class__.__qualname__, self._w) # Pack methods that apply to the master _noarg_ = ['_noarg_'] def pack_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'pack', 'propagate', self._w)) else: self.tk.call('pack', 'propagate', self._w, flag) propagate = pack_propagate def pack_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call('pack', 'slaves', self._w))] slaves = pack_slaves # Place method that applies to the master def place_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call( 'place', 'slaves', self._w))] # Grid methods that apply to the master def grid_anchor(self, anchor=None): # new in Tk 8.5 """The anchor value controls how to place the grid within the master when no row/column has any weight. The default anchor is nw.""" self.tk.call('grid', 'anchor', self._w, anchor) anchor = grid_anchor def grid_bbox(self, column=None, row=None, col2=None, row2=None): """Return a tuple of integer coordinates for the bounding box of this widget controlled by the geometry manager grid. If COLUMN, ROW is given the bounding box applies from the cell with row and column 0 to the specified cell. If COL2 and ROW2 are given the bounding box starts at that cell. The returned integers specify the offset of the upper left corner in the master widget and the width and height. """ args = ('grid', 'bbox', self._w) if column is not None and row is not None: args = args + (column, row) if col2 is not None and row2 is not None: args = args + (col2, row2) return self._getints(self.tk.call(*args)) or None bbox = grid_bbox def _gridconvvalue(self, value): if isinstance(value, (str, _tkinter.Tcl_Obj)): try: svalue = str(value) if not svalue: return None elif '.' in svalue: return self.tk.getdouble(svalue) else: return self.tk.getint(svalue) except (ValueError, TclError): pass return value def _grid_configure(self, command, index, cnf, kw): """Internal function.""" if isinstance(cnf, str) and not kw: if cnf[-1:] == '_': cnf = cnf[:-1] if cnf[:1] != '-': cnf = '-'+cnf options = (cnf,) else: options = self._options(cnf, kw) if not options: return _splitdict( self.tk, self.tk.call('grid', command, self._w, index), conv=self._gridconvvalue) res = self.tk.call( ('grid', command, self._w, index) + options) if len(options) == 1: return self._gridconvvalue(res) def grid_columnconfigure(self, index, cnf={}, **kw): """Configure column INDEX of a grid. Valid resources are minsize (minimum size of the column), weight (how much does additional space propagate to this column) and pad (how much space to let additionally).""" return self._grid_configure('columnconfigure', index, cnf, kw) columnconfigure = grid_columnconfigure def grid_location(self, x, y): """Return a tuple of column and row which identify the cell at which the pixel at position X and Y inside the master widget is located.""" return self._getints( self.tk.call( 'grid', 'location', self._w, x, y)) or None def grid_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given, the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'grid', 'propagate', self._w)) else: self.tk.call('grid', 'propagate', self._w, flag) def grid_rowconfigure(self, index, cnf={}, **kw): """Configure row INDEX of a grid. Valid resources are minsize (minimum size of the row), weight (how much does additional space propagate to this row) and pad (how much space to let additionally).""" return self._grid_configure('rowconfigure', index, cnf, kw) rowconfigure = grid_rowconfigure def grid_size(self): """Return a tuple of the number of column and rows in the grid.""" return self._getints( self.tk.call('grid', 'size', self._w)) or None size = grid_size def grid_slaves(self, row=None, column=None): """Return a list of all slaves of this widget in its packing order.""" args = () if row is not None: args = args + ('-row', row) if column is not None: args = args + ('-column', column) return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call( ('grid', 'slaves', self._w) + args))] # Support for the "event" command, new in Tk 4.2. # By Case Roole. def event_add(self, virtual, *sequences): """Bind a virtual event VIRTUAL (of the form <>) to an event SEQUENCE such that the virtual event is triggered whenever SEQUENCE occurs.""" args = ('event', 'add', virtual) + sequences self.tk.call(args) def event_delete(self, virtual, *sequences): """Unbind a virtual event VIRTUAL from SEQUENCE.""" args = ('event', 'delete', virtual) + sequences self.tk.call(args) def event_generate(self, sequence, **kw): """Generate an event SEQUENCE. Additional keyword arguments specify parameter of the event (e.g. x, y, rootx, rooty).""" args = ('event', 'generate', self._w, sequence) for k, v in kw.items(): args = args + ('-%s' % k, str(v)) self.tk.call(args) def event_info(self, virtual=None): """Return a list of all virtual events or the information about the SEQUENCE bound to the virtual event VIRTUAL.""" return self.tk.splitlist( self.tk.call('event', 'info', virtual)) # Image related commands def image_names(self): """Return a list of all existing image names.""" return self.tk.splitlist(self.tk.call('image', 'names')) def image_types(self): """Return a list of all available image types (e.g. photo bitmap).""" return self.tk.splitlist(self.tk.call('image', 'types')) class CallWrapper: """Internal class. Stores function to call when some user defined Tcl function is called e.g. after an event occurred.""" def __init__(self, func, subst, widget): """Store FUNC, SUBST and WIDGET as members.""" self.func = func self.subst = subst self.widget = widget def __call__(self, *args): """Apply first function SUBST to arguments, than FUNC.""" try: if self.subst: args = self.subst(*args) return self.func(*args) except SystemExit: raise except: self.widget._report_exception() class XView: """Mix-in class for querying and changing the horizontal position of a widget's window.""" def xview(self, *args): """Query and change the horizontal position of the view.""" res = self.tk.call(self._w, 'xview', *args) if not args: return self._getdoubles(res) def xview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total width of the canvas is off-screen to the left.""" self.tk.call(self._w, 'xview', 'moveto', fraction) def xview_scroll(self, number, what): """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'xview', 'scroll', number, what) class YView: """Mix-in class for querying and changing the vertical position of a widget's window.""" def yview(self, *args): """Query and change the vertical position of the view.""" res = self.tk.call(self._w, 'yview', *args) if not args: return self._getdoubles(res) def yview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total height of the canvas is off-screen to the top.""" self.tk.call(self._w, 'yview', 'moveto', fraction) def yview_scroll(self, number, what): """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'yview', 'scroll', number, what) class Wm: """Provides functions for the communication with the window manager.""" def wm_aspect(self, minNumer=None, minDenom=None, maxNumer=None, maxDenom=None): """Instruct the window manager to set the aspect ratio (width/height) of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple of the actual values if no argument is given.""" return self._getints( self.tk.call('wm', 'aspect', self._w, minNumer, minDenom, maxNumer, maxDenom)) aspect = wm_aspect def wm_attributes(self, *args): """This subcommand returns or sets platform specific attributes The first form returns a list of the platform specific flags and their values. The second form returns the value for the specific option. The third form sets one or more of the values. The values are as follows: On Windows, -disabled gets or sets whether the window is in a disabled state. -toolwindow gets or sets the style of the window to toolwindow (as defined in the MSDN). -topmost gets or sets whether this is a topmost window (displays above all other windows). On Macintosh, XXXXX On Unix, there are currently no special attribute values. """ args = ('wm', 'attributes', self._w) + args return self.tk.call(args) attributes = wm_attributes def wm_client(self, name=None): """Store NAME in WM_CLIENT_MACHINE property of this widget. Return current value.""" return self.tk.call('wm', 'client', self._w, name) client = wm_client def wm_colormapwindows(self, *wlist): """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property of this widget. This list contains windows whose colormaps differ from their parents. Return current list of widgets if WLIST is empty.""" if len(wlist) > 1: wlist = (wlist,) # Tk needs a list of windows here args = ('wm', 'colormapwindows', self._w) + wlist if wlist: self.tk.call(args) else: return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call(args))] colormapwindows = wm_colormapwindows def wm_command(self, value=None): """Store VALUE in WM_COMMAND property. It is the command which shall be used to invoke the application. Return current command if VALUE is None.""" return self.tk.call('wm', 'command', self._w, value) command = wm_command def wm_deiconify(self): """Deiconify this widget. If it was never mapped it will not be mapped. On Windows it will raise this widget and give it the focus.""" return self.tk.call('wm', 'deiconify', self._w) deiconify = wm_deiconify def wm_focusmodel(self, model=None): """Set focus model to MODEL. "active" means that this widget will claim the focus itself, "passive" means that the window manager shall give the focus. Return current focus model if MODEL is None.""" return self.tk.call('wm', 'focusmodel', self._w, model) focusmodel = wm_focusmodel def wm_forget(self, window): # new in Tk 8.5 """The window will be unmapped from the screen and will no longer be managed by wm. toplevel windows will be treated like frame windows once they are no longer managed by wm, however, the menu option configuration will be remembered and the menus will return once the widget is managed again.""" self.tk.call('wm', 'forget', window) forget = wm_forget def wm_frame(self): """Return identifier for decorative frame of this widget if present.""" return self.tk.call('wm', 'frame', self._w) frame = wm_frame def wm_geometry(self, newGeometry=None): """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return current value if None is given.""" return self.tk.call('wm', 'geometry', self._w, newGeometry) geometry = wm_geometry def wm_grid(self, baseWidth=None, baseHeight=None, widthInc=None, heightInc=None): """Instruct the window manager that this widget shall only be resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the number of grid units requested in Tk_GeometryRequest.""" return self._getints(self.tk.call( 'wm', 'grid', self._w, baseWidth, baseHeight, widthInc, heightInc)) grid = wm_grid def wm_group(self, pathName=None): """Set the group leader widgets for related widgets to PATHNAME. Return the group leader of this widget if None is given.""" return self.tk.call('wm', 'group', self._w, pathName) group = wm_group def wm_iconbitmap(self, bitmap=None, default=None): """Set bitmap for the iconified widget to BITMAP. Return the bitmap if None is given. Under Windows, the DEFAULT parameter can be used to set the icon for the widget and any descendants that don't have an icon set explicitly. DEFAULT can be the relative path to a .ico file (example: root.iconbitmap(default='myicon.ico') ). See Tk documentation for more information.""" if default is not None: return self.tk.call('wm', 'iconbitmap', self._w, '-default', default) else: return self.tk.call('wm', 'iconbitmap', self._w, bitmap) iconbitmap = wm_iconbitmap def wm_iconify(self): """Display widget as icon.""" return self.tk.call('wm', 'iconify', self._w) iconify = wm_iconify def wm_iconmask(self, bitmap=None): """Set mask for the icon bitmap of this widget. Return the mask if None is given.""" return self.tk.call('wm', 'iconmask', self._w, bitmap) iconmask = wm_iconmask def wm_iconname(self, newName=None): """Set the name of the icon for this widget. Return the name if None is given.""" return self.tk.call('wm', 'iconname', self._w, newName) iconname = wm_iconname def wm_iconphoto(self, default=False, *args): # new in Tk 8.5 """Sets the titlebar icon for this window based on the named photo images passed through args. If default is True, this is applied to all future created toplevels as well. The data in the images is taken as a snapshot at the time of invocation. If the images are later changed, this is not reflected to the titlebar icons. Multiple images are accepted to allow different images sizes to be provided. The window manager may scale provided icons to an appropriate size. On Windows, the images are packed into a Windows icon structure. This will override an icon specified to wm_iconbitmap, and vice versa. On X, the images are arranged into the _NET_WM_ICON X property, which most modern window managers support. An icon specified by wm_iconbitmap may exist simultaneously. On Macintosh, this currently does nothing.""" if default: self.tk.call('wm', 'iconphoto', self._w, "-default", *args) else: self.tk.call('wm', 'iconphoto', self._w, *args) iconphoto = wm_iconphoto def wm_iconposition(self, x=None, y=None): """Set the position of the icon of this widget to X and Y. Return a tuple of the current values of X and X if None is given.""" return self._getints(self.tk.call( 'wm', 'iconposition', self._w, x, y)) iconposition = wm_iconposition def wm_iconwindow(self, pathName=None): """Set widget PATHNAME to be displayed instead of icon. Return the current value if None is given.""" return self.tk.call('wm', 'iconwindow', self._w, pathName) iconwindow = wm_iconwindow def wm_manage(self, widget): # new in Tk 8.5 """The widget specified will become a stand alone top-level window. The window will be decorated with the window managers title bar, etc.""" self.tk.call('wm', 'manage', widget) manage = wm_manage def wm_maxsize(self, width=None, height=None): """Set max WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'maxsize', self._w, width, height)) maxsize = wm_maxsize def wm_minsize(self, width=None, height=None): """Set min WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'minsize', self._w, width, height)) minsize = wm_minsize def wm_overrideredirect(self, boolean=None): """Instruct the window manager to ignore this widget if BOOLEAN is given with 1. Return the current value if None is given.""" return self._getboolean(self.tk.call( 'wm', 'overrideredirect', self._w, boolean)) overrideredirect = wm_overrideredirect def wm_positionfrom(self, who=None): """Instruct the window manager that the position of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'positionfrom', self._w, who) positionfrom = wm_positionfrom def wm_protocol(self, name=None, func=None): """Bind function FUNC to command NAME for this widget. Return the function bound to NAME if None is given. NAME could be e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" if callable(func): command = self._register(func) else: command = func return self.tk.call( 'wm', 'protocol', self._w, name, command) protocol = wm_protocol def wm_resizable(self, width=None, height=None): """Instruct the window manager whether this width can be resized in WIDTH or HEIGHT. Both values are boolean values.""" return self.tk.call('wm', 'resizable', self._w, width, height) resizable = wm_resizable def wm_sizefrom(self, who=None): """Instruct the window manager that the size of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'sizefrom', self._w, who) sizefrom = wm_sizefrom def wm_state(self, newstate=None): """Query or set the state of this widget as one of normal, icon, iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" return self.tk.call('wm', 'state', self._w, newstate) state = wm_state def wm_title(self, string=None): """Set the title of this widget.""" return self.tk.call('wm', 'title', self._w, string) title = wm_title def wm_transient(self, master=None): """Instruct the window manager that this widget is transient with regard to widget MASTER.""" return self.tk.call('wm', 'transient', self._w, master) transient = wm_transient def wm_withdraw(self): """Withdraw this widget from the screen such that it is unmapped and forgotten by the window manager. Re-draw it with wm_deiconify.""" return self.tk.call('wm', 'withdraw', self._w) withdraw = wm_withdraw class Tk(Misc, Wm): """Toplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.""" _w = '.' def __init__(self, screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None): """Return a new top level widget on screen SCREENNAME. A new Tcl interpreter will be created. BASENAME will be used for the identification of the profile file (see readprofile). It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME is the name of the widget class.""" self.master = None self.children = {} self._tkloaded = False # to avoid recursions in the getattr code in case of failure, we # ensure that self.tk is always _something_. self.tk = None if baseName is None: import os baseName = os.path.basename(sys.argv[0]) baseName, ext = os.path.splitext(baseName) if ext not in ('.py', '.pyc'): baseName = baseName + ext interactive = False self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) if _debug: self.tk.settrace(_print_command) if useTk: self._loadtk() if not sys.flags.ignore_environment: # Issue #16248: Honor the -E flag to avoid code injection. self.readprofile(baseName, className) def loadtk(self): if not self._tkloaded: self.tk.loadtk() self._loadtk() def _loadtk(self): self._tkloaded = True global _default_root # Version sanity checks tk_version = self.tk.getvar('tk_version') if tk_version != _tkinter.TK_VERSION: raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)" % (_tkinter.TK_VERSION, tk_version)) # Under unknown circumstances, tcl_version gets coerced to float tcl_version = str(self.tk.getvar('tcl_version')) if tcl_version != _tkinter.TCL_VERSION: raise RuntimeError("tcl.h version (%s) doesn't match libtcl.a version (%s)" \ % (_tkinter.TCL_VERSION, tcl_version)) # Create and register the tkerror and exit commands # We need to inline parts of _register here, _ register # would register differently-named commands. if self._tclCommands is None: self._tclCommands = [] self.tk.createcommand('tkerror', _tkerror) self.tk.createcommand('exit', _exit) self._tclCommands.append('tkerror') self._tclCommands.append('exit') if _support_default_root and _default_root is None: _default_root = self self.protocol("WM_DELETE_WINDOW", self.destroy) def destroy(self): """Destroy this and all descendants widgets. This will end the application of this Tcl interpreter.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) Misc.destroy(self) global _default_root if _support_default_root and _default_root is self: _default_root = None def readprofile(self, baseName, className): """Internal function. It reads .BASENAME.tcl and .CLASSNAME.tcl into the Tcl Interpreter and calls exec on the contents of .BASENAME.py and .CLASSNAME.py if such a file exists in the home directory.""" import os if 'HOME' in os.environ: home = os.environ['HOME'] else: home = os.curdir class_tcl = os.path.join(home, '.%s.tcl' % className) class_py = os.path.join(home, '.%s.py' % className) base_tcl = os.path.join(home, '.%s.tcl' % baseName) base_py = os.path.join(home, '.%s.py' % baseName) dir = {'self': self} exec('from tkinter import *', dir) if os.path.isfile(class_tcl): self.tk.call('source', class_tcl) if os.path.isfile(class_py): exec(open(class_py).read(), dir) if os.path.isfile(base_tcl): self.tk.call('source', base_tcl) if os.path.isfile(base_py): exec(open(base_py).read(), dir) def report_callback_exception(self, exc, val, tb): """Report callback exception on sys.stderr. Applications may want to override this internal function, and should when sys.stderr is None.""" import traceback print("Exception in Tkinter callback", file=sys.stderr) sys.last_exc = val sys.last_type = exc sys.last_value = val sys.last_traceback = tb traceback.print_exception(exc, val, tb) def __getattr__(self, attr): "Delegate attribute access to the interpreter object" return getattr(self.tk, attr) def _print_command(cmd, *, file=sys.stderr): # Print executed Tcl/Tk commands. assert isinstance(cmd, tuple) cmd = _join(cmd) print(cmd, file=file) # Ideally, the classes Pack, Place and Grid disappear, the # pack/place/grid methods are defined on the Widget class, and # everybody uses w.pack_whatever(...) instead of Pack.whatever(w, # ...), with pack(), place() and grid() being short for # pack_configure(), place_configure() and grid_columnconfigure(), and # forget() being short for pack_forget(). As a practical matter, I'm # afraid that there is too much code out there that may be using the # Pack, Place or Grid class, so I leave them intact -- but only as # backwards compatibility features. Also note that those methods that # take a master as argument (e.g. pack_propagate) have been moved to # the Misc class (which now incorporates all methods common between # toplevel and interior widgets). Again, for compatibility, these are # copied into the Pack, Place or Grid class. def Tcl(screenName=None, baseName=None, className='Tk', useTk=False): return Tk(screenName, baseName, className, useTk) class Pack: """Geometry manager Pack. Base class to use the methods pack_* in every widget.""" def pack_configure(self, cnf={}, **kw): """Pack a widget in the parent widget. Use as options: after=widget - pack it after you have packed widget anchor=NSEW (or subset) - position widget according to given direction before=widget - pack it before you will pack widget expand=bool - expand widget if parent size grows fill=NONE or X or Y or BOTH - fill widget if widget grows in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. """ self.tk.call( ('pack', 'configure', self._w) + self._options(cnf, kw)) pack = configure = config = pack_configure def pack_forget(self): """Unmap this widget and do not use it for the packing order.""" self.tk.call('pack', 'forget', self._w) forget = pack_forget def pack_info(self): """Return information about the packing options for this widget.""" d = _splitdict(self.tk, self.tk.call('pack', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = pack_info propagate = pack_propagate = Misc.pack_propagate slaves = pack_slaves = Misc.pack_slaves class Place: """Geometry manager Place. Base class to use the methods place_* in every widget.""" def place_configure(self, cnf={}, **kw): """Place a widget in the parent widget. Use as options: in=master - master relative to which the widget is placed in_=master - see 'in' option description x=amount - locate anchor of this widget at position x of master y=amount - locate anchor of this widget at position y of master relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge) rely=amount - locate anchor of this widget between 0.0 and 1.0 relative to height of master (1.0 is bottom edge) anchor=NSEW (or subset) - position anchor according to given direction width=amount - width of this widget in pixel height=amount - height of this widget in pixel relwidth=amount - width of this widget between 0.0 and 1.0 relative to width of master (1.0 is the same width as the master) relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master) bordermode="inside" or "outside" - whether to take border width of master widget into account """ self.tk.call( ('place', 'configure', self._w) + self._options(cnf, kw)) place = configure = config = place_configure def place_forget(self): """Unmap this widget.""" self.tk.call('place', 'forget', self._w) forget = place_forget def place_info(self): """Return information about the placing options for this widget.""" d = _splitdict(self.tk, self.tk.call('place', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = place_info slaves = place_slaves = Misc.place_slaves class Grid: """Geometry manager Grid. Base class to use the methods grid_* in every widget.""" # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) def grid_configure(self, cnf={}, **kw): """Position a widget in the parent widget in a grid. Use as options: column=number - use cell identified with given column (starting with 0) columnspan=number - this widget will span several columns in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction row=number - use cell identified with given row (starting with 0) rowspan=number - this widget will span several rows sticky=NSEW - if cell is larger on which sides will this widget stick to the cell boundary """ self.tk.call( ('grid', 'configure', self._w) + self._options(cnf, kw)) grid = configure = config = grid_configure bbox = grid_bbox = Misc.grid_bbox columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure def grid_forget(self): """Unmap this widget.""" self.tk.call('grid', 'forget', self._w) forget = grid_forget def grid_remove(self): """Unmap this widget but remember the grid options.""" self.tk.call('grid', 'remove', self._w) def grid_info(self): """Return information about the options for positioning this widget in a grid.""" d = _splitdict(self.tk, self.tk.call('grid', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = grid_info location = grid_location = Misc.grid_location propagate = grid_propagate = Misc.grid_propagate rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure size = grid_size = Misc.grid_size slaves = grid_slaves = Misc.grid_slaves class BaseWidget(Misc): """Internal class.""" def _setup(self, master, cnf): """Internal function. Sets up information about children.""" if master is None: master = _get_default_root() self.master = master self.tk = master.tk name = None if 'name' in cnf: name = cnf['name'] del cnf['name'] if not name: name = self.__class__.__name__.lower() if name[-1].isdigit(): name += "!" # Avoid duplication when calculating names below if master._last_child_ids is None: master._last_child_ids = {} count = master._last_child_ids.get(name, 0) + 1 master._last_child_ids[name] = count if count == 1: name = '!%s' % (name,) else: name = '!%s%d' % (name, count) self._name = name if master._w=='.': self._w = '.' + name else: self._w = master._w + '.' + name self.children = {} if self._name in self.master.children: self.master.children[self._name].destroy() self.master.children[self._name] = self def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): """Construct a widget with the parent widget MASTER, a name WIDGETNAME and appropriate options.""" if kw: cnf = _cnfmerge((cnf, kw)) self.widgetName = widgetName self._setup(master, cnf) if self._tclCommands is None: self._tclCommands = [] classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)] for k, v in classes: del cnf[k] self.tk.call( (widgetName, self._w) + extra + self._options(cnf)) for k, v in classes: k.configure(self, v) def destroy(self): """Destroy this and all descendants widgets.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) if self._name in self.master.children: del self.master.children[self._name] Misc.destroy(self) def _do(self, name, args=()): # XXX Obsolete -- better use self.tk.call directly! return self.tk.call((self._w, name) + args) class Widget(BaseWidget, Pack, Place, Grid): """Internal class. Base class for a widget which can be positioned with the geometry managers Pack, Place or Grid.""" pass class Toplevel(BaseWidget, Wm): """Toplevel widget, e.g. for dialogs.""" def __init__(self, master=None, cnf={}, **kw): """Construct a toplevel widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, menu, relief, screen, takefocus, use, visual, width.""" if kw: cnf = _cnfmerge((cnf, kw)) extra = () for wmkey in ['screen', 'class_', 'class', 'visual', 'colormap']: if wmkey in cnf: val = cnf[wmkey] # TBD: a hack needed because some keys # are not valid as keyword arguments if wmkey[-1] == '_': opt = '-'+wmkey[:-1] else: opt = '-'+wmkey extra = extra + (opt, val) del cnf[wmkey] BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) root = self._root() self.iconname(root.iconname()) self.title(root.title()) self.protocol("WM_DELETE_WINDOW", self.destroy) class Button(Widget): """Button widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a button widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, repeatdelay, repeatinterval, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS command, compound, default, height, overrelief, state, width """ Widget.__init__(self, master, 'button', cnf, kw) def flash(self): """Flash the button. This is accomplished by redisplaying the button several times, alternating between active and normal colors. At the end of the flash the button is left in the same normal/active state as when the command was invoked. This command is ignored if the button's state is disabled. """ self.tk.call(self._w, 'flash') def invoke(self): """Invoke the command associated with the button. The return value is the return value from the command, or an empty string if there is no command associated with the button. This command is ignored if the button's state is disabled. """ return self.tk.call(self._w, 'invoke') class Canvas(Widget, XView, YView): """Canvas widget to display graphical elements like lines or text.""" def __init__(self, master=None, cnf={}, **kw): """Construct a canvas widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, closeenough, confine, cursor, height, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, offset, relief, scrollregion, selectbackground, selectborderwidth, selectforeground, state, takefocus, width, xscrollcommand, xscrollincrement, yscrollcommand, yscrollincrement.""" Widget.__init__(self, master, 'canvas', cnf, kw) def addtag(self, *args): """Internal function.""" self.tk.call((self._w, 'addtag') + args) def addtag_above(self, newtag, tagOrId): """Add tag NEWTAG to all items above TAGORID.""" self.addtag(newtag, 'above', tagOrId) def addtag_all(self, newtag): """Add tag NEWTAG to all items.""" self.addtag(newtag, 'all') def addtag_below(self, newtag, tagOrId): """Add tag NEWTAG to all items below TAGORID.""" self.addtag(newtag, 'below', tagOrId) def addtag_closest(self, newtag, x, y, halo=None, start=None): """Add tag NEWTAG to item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.""" self.addtag(newtag, 'closest', x, y, halo, start) def addtag_enclosed(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items in the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'enclosed', x1, y1, x2, y2) def addtag_overlapping(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'overlapping', x1, y1, x2, y2) def addtag_withtag(self, newtag, tagOrId): """Add tag NEWTAG to all items with TAGORID.""" self.addtag(newtag, 'withtag', tagOrId) def bbox(self, *args): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses all items with tags specified as arguments.""" return self._getints( self.tk.call((self._w, 'bbox') + args)) or None def tag_unbind(self, tagOrId, sequence, funcid=None): """Unbind for all items with TAGORID for event SEQUENCE the function identified with FUNCID.""" self._unbind((self._w, 'bind', tagOrId, sequence), funcid) def tag_bind(self, tagOrId, sequence=None, func=None, add=None): """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'bind', tagOrId), sequence, func, add) def canvasx(self, screenx, gridspacing=None): """Return the canvas x coordinate of pixel position SCREENX rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasx', screenx, gridspacing)) def canvasy(self, screeny, gridspacing=None): """Return the canvas y coordinate of pixel position SCREENY rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasy', screeny, gridspacing)) def coords(self, *args): """Return a list of coordinates for the item given in ARGS.""" args = _flatten(args) return [self.tk.getdouble(x) for x in self.tk.splitlist( self.tk.call((self._w, 'coords') + args))] def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) """Internal function.""" args = _flatten(args) cnf = args[-1] if isinstance(cnf, (dict, tuple)): args = args[:-1] else: cnf = {} return self.tk.getint(self.tk.call( self._w, 'create', itemType, *(args + self._options(cnf, kw)))) def create_arc(self, *args, **kw): """Create arc shaped region with coordinates x1,y1,x2,y2.""" return self._create('arc', args, kw) def create_bitmap(self, *args, **kw): """Create bitmap with coordinates x1,y1.""" return self._create('bitmap', args, kw) def create_image(self, *args, **kw): """Create image item with coordinates x1,y1.""" return self._create('image', args, kw) def create_line(self, *args, **kw): """Create line with coordinates x1,y1,...,xn,yn.""" return self._create('line', args, kw) def create_oval(self, *args, **kw): """Create oval with coordinates x1,y1,x2,y2.""" return self._create('oval', args, kw) def create_polygon(self, *args, **kw): """Create polygon with coordinates x1,y1,...,xn,yn.""" return self._create('polygon', args, kw) def create_rectangle(self, *args, **kw): """Create rectangle with coordinates x1,y1,x2,y2.""" return self._create('rectangle', args, kw) def create_text(self, *args, **kw): """Create text with coordinates x1,y1.""" return self._create('text', args, kw) def create_window(self, *args, **kw): """Create window with coordinates x1,y1,x2,y2.""" return self._create('window', args, kw) def dchars(self, *args): """Delete characters of text items identified by tag or id in ARGS (possibly several times) from FIRST to LAST character (including).""" self.tk.call((self._w, 'dchars') + args) def delete(self, *args): """Delete items identified by all tag or ids contained in ARGS.""" self.tk.call((self._w, 'delete') + args) def dtag(self, *args): """Delete tag or id given as last arguments in ARGS from items identified by first argument in ARGS.""" self.tk.call((self._w, 'dtag') + args) def find(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'find') + args)) or () def find_above(self, tagOrId): """Return items above TAGORID.""" return self.find('above', tagOrId) def find_all(self): """Return all items.""" return self.find('all') def find_below(self, tagOrId): """Return all items below TAGORID.""" return self.find('below', tagOrId) def find_closest(self, x, y, halo=None, start=None): """Return item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.""" return self.find('closest', x, y, halo, start) def find_enclosed(self, x1, y1, x2, y2): """Return all items in rectangle defined by X1,Y1,X2,Y2.""" return self.find('enclosed', x1, y1, x2, y2) def find_overlapping(self, x1, y1, x2, y2): """Return all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" return self.find('overlapping', x1, y1, x2, y2) def find_withtag(self, tagOrId): """Return all items with TAGORID.""" return self.find('withtag', tagOrId) def focus(self, *args): """Set focus to the first item specified in ARGS.""" return self.tk.call((self._w, 'focus') + args) def gettags(self, *args): """Return tags associated with the first item specified in ARGS.""" return self.tk.splitlist( self.tk.call((self._w, 'gettags') + args)) def icursor(self, *args): """Set cursor at position POS in the item identified by TAGORID. In ARGS TAGORID must be first.""" self.tk.call((self._w, 'icursor') + args) def index(self, *args): """Return position of cursor as integer in item specified in ARGS.""" return self.tk.getint(self.tk.call((self._w, 'index') + args)) def insert(self, *args): """Insert TEXT in item TAGORID at position POS. ARGS must be TAGORID POS TEXT.""" self.tk.call((self._w, 'insert') + args) def itemcget(self, tagOrId, option): """Return the resource value for an OPTION for item TAGORID.""" return self.tk.call( (self._w, 'itemcget') + (tagOrId, '-'+option)) def itemconfigure(self, tagOrId, cnf=None, **kw): """Configure resources of an item TAGORID. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. """ return self._configure(('itemconfigure', tagOrId), cnf, kw) itemconfig = itemconfigure # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, # so the preferred name for them is tag_lower, tag_raise # (similar to tag_bind, and similar to the Text widget); # unfortunately can't delete the old ones yet (maybe in 1.6) def tag_lower(self, *args): """Lower an item TAGORID given in ARGS (optional below another item).""" self.tk.call((self._w, 'lower') + args) lower = tag_lower def move(self, *args): """Move an item TAGORID given in ARGS.""" self.tk.call((self._w, 'move') + args) def moveto(self, tagOrId, x='', y=''): """Move the items given by TAGORID in the canvas coordinate space so that the first coordinate pair of the bottommost item with tag TAGORID is located at position (X,Y). X and Y may be the empty string, in which case the corresponding coordinate will be unchanged. All items matching TAGORID remain in the same positions relative to each other.""" self.tk.call(self._w, 'moveto', tagOrId, x, y) def postscript(self, cnf={}, **kw): """Print the contents of the canvas to a postscript file. Valid options: colormap, colormode, file, fontmap, height, pageanchor, pageheight, pagewidth, pagex, pagey, rotate, width, x, y.""" return self.tk.call((self._w, 'postscript') + self._options(cnf, kw)) def tag_raise(self, *args): """Raise an item TAGORID given in ARGS (optional above another item).""" self.tk.call((self._w, 'raise') + args) lift = tkraise = tag_raise def scale(self, *args): """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" self.tk.call((self._w, 'scale') + args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y, gain=10): """Adjust the view of the canvas to GAIN times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y, gain) def select_adjust(self, tagOrId, index): """Adjust the end of the selection near the cursor of an item TAGORID to index.""" self.tk.call(self._w, 'select', 'adjust', tagOrId, index) def select_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'select', 'clear') def select_from(self, tagOrId, index): """Set the fixed end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'from', tagOrId, index) def select_item(self): """Return the item which has the selection.""" return self.tk.call(self._w, 'select', 'item') or None def select_to(self, tagOrId, index): """Set the variable end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'to', tagOrId, index) def type(self, tagOrId): """Return the type of the item TAGORID.""" return self.tk.call(self._w, 'type', tagOrId) or None _checkbutton_count = 0 class Checkbutton(Widget): """Checkbutton widget which is either in on- or off-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a checkbutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, offvalue, onvalue, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, variable, width, wraplength.""" Widget.__init__(self, master, 'checkbutton', cnf, kw) def _setup(self, master, cnf): # Because Checkbutton defaults to a variable with the same name as # the widget, Checkbutton default names must be globally unique, # not just unique within the parent widget. if not cnf.get('name'): global _checkbutton_count name = self.__class__.__name__.lower() _checkbutton_count += 1 # To avoid collisions with ttk.Checkbutton, use the different # name template. cnf['name'] = f'!{name}-{_checkbutton_count}' super()._setup(master, cnf) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') def toggle(self): """Toggle the button.""" self.tk.call(self._w, 'toggle') class Entry(Widget, XView): """Entry widget which allows displaying simple text.""" def __init__(self, master=None, cnf={}, **kw): """Construct an entry widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, invalidcommand, invcmd, justify, relief, selectbackground, selectborderwidth, selectforeground, show, state, takefocus, textvariable, validate, validatecommand, vcmd, width, xscrollcommand.""" Widget.__init__(self, master, 'entry', cnf, kw) def delete(self, first, last=None): """Delete text from FIRST to LAST (not included).""" self.tk.call(self._w, 'delete', first, last) def get(self): """Return the text.""" return self.tk.call(self._w, 'get') def icursor(self, index): """Insert cursor at INDEX.""" self.tk.call(self._w, 'icursor', index) def index(self, index): """Return position of cursor.""" return self.tk.getint(self.tk.call( self._w, 'index', index)) def insert(self, index, string): """Insert STRING at INDEX.""" self.tk.call(self._w, 'insert', index, string) def scan_mark(self, x): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x) def scan_dragto(self, x): """Adjust the view of the canvas to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x) def selection_adjust(self, index): """Adjust the end of the selection near the cursor to INDEX.""" self.tk.call(self._w, 'selection', 'adjust', index) select_adjust = selection_adjust def selection_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'selection', 'clear') select_clear = selection_clear def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'from', index) select_from = selection_from def selection_present(self): """Return True if there are characters selected in the entry, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) select_present = selection_present def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.tk.call(self._w, 'selection', 'range', start, end) select_range = selection_range def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'to', index) select_to = selection_to class Frame(Widget): """Frame widget which may contain other widgets and can have a 3D border.""" def __init__(self, master=None, cnf={}, **kw): """Construct a frame widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.""" cnf = _cnfmerge((cnf, kw)) extra = () if 'class_' in cnf: extra = ('-class', cnf['class_']) del cnf['class_'] elif 'class' in cnf: extra = ('-class', cnf['class']) del cnf['class'] Widget.__init__(self, master, 'frame', cnf, {}, extra) class Label(Widget): """Label widget which can display text and bitmaps.""" def __init__(self, master=None, cnf={}, **kw): """Construct a label widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground, highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS height, state, width """ Widget.__init__(self, master, 'label', cnf, kw) class Listbox(Widget, XView, YView): """Listbox widget which can display a list of strings.""" def __init__(self, master=None, cnf={}, **kw): """Construct a listbox widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, relief, selectbackground, selectborderwidth, selectforeground, selectmode, setgrid, takefocus, width, xscrollcommand, yscrollcommand, listvariable.""" Widget.__init__(self, master, 'listbox', cnf, kw) def activate(self, index): """Activate item identified by INDEX.""" self.tk.call(self._w, 'activate', index) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the item identified by the given index.""" return self._getints(self.tk.call(self._w, 'bbox', index)) or None def curselection(self): """Return the indices of currently selected item.""" return self._getints(self.tk.call(self._w, 'curselection')) or () def delete(self, first, last=None): """Delete items from FIRST to LAST (included).""" self.tk.call(self._w, 'delete', first, last) def get(self, first, last=None): """Get list of items from FIRST to LAST (included).""" if last is not None: return self.tk.splitlist(self.tk.call( self._w, 'get', first, last)) else: return self.tk.call(self._w, 'get', first) def index(self, index): """Return index of item identified with INDEX.""" i = self.tk.call(self._w, 'index', index) if i == 'none': return None return self.tk.getint(i) def insert(self, index, *elements): """Insert ELEMENTS at INDEX.""" self.tk.call((self._w, 'insert', index) + elements) def nearest(self, y): """Get index of item which is nearest to y coordinate Y.""" return self.tk.getint(self.tk.call( self._w, 'nearest', y)) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the listbox to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def see(self, index): """Scroll such that INDEX is visible.""" self.tk.call(self._w, 'see', index) def selection_anchor(self, index): """Set the fixed end oft the selection to INDEX.""" self.tk.call(self._w, 'selection', 'anchor', index) select_anchor = selection_anchor def selection_clear(self, first, last=None): """Clear the selection from FIRST to LAST (included).""" self.tk.call(self._w, 'selection', 'clear', first, last) select_clear = selection_clear def selection_includes(self, index): """Return True if INDEX is part of the selection.""" return self.tk.getboolean(self.tk.call( self._w, 'selection', 'includes', index)) select_includes = selection_includes def selection_set(self, first, last=None): """Set the selection from FIRST to LAST (included) without changing the currently selected elements.""" self.tk.call(self._w, 'selection', 'set', first, last) select_set = selection_set def size(self): """Return the number of elements in the listbox.""" return self.tk.getint(self.tk.call(self._w, 'size')) def itemcget(self, index, option): """Return the resource value for an ITEM and an OPTION.""" return self.tk.call( (self._w, 'itemcget') + (index, '-'+option)) def itemconfigure(self, index, cnf=None, **kw): """Configure resources of an ITEM. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. Valid resource names: background, bg, foreground, fg, selectbackground, selectforeground.""" return self._configure(('itemconfigure', index), cnf, kw) itemconfig = itemconfigure class Menu(Widget): """Menu widget which allows displaying menu bars, pull-down menus and pop-up menus.""" def __init__(self, master=None, cnf={}, **kw): """Construct menu widget with the parent MASTER. Valid resource names: activebackground, activeborderwidth, activeforeground, background, bd, bg, borderwidth, cursor, disabledforeground, fg, font, foreground, postcommand, relief, selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" Widget.__init__(self, master, 'menu', cnf, kw) def tk_popup(self, x, y, entry=""): """Post the menu at position X,Y with entry ENTRY.""" self.tk.call('tk_popup', self._w, x, y, entry) def activate(self, index): """Activate entry at INDEX.""" self.tk.call(self._w, 'activate', index) def add(self, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'add', itemType) + self._options(cnf, kw)) def add_cascade(self, cnf={}, **kw): """Add hierarchical menu item.""" self.add('cascade', cnf or kw) def add_checkbutton(self, cnf={}, **kw): """Add checkbutton menu item.""" self.add('checkbutton', cnf or kw) def add_command(self, cnf={}, **kw): """Add command menu item.""" self.add('command', cnf or kw) def add_radiobutton(self, cnf={}, **kw): """Add radio menu item.""" self.add('radiobutton', cnf or kw) def add_separator(self, cnf={}, **kw): """Add separator.""" self.add('separator', cnf or kw) def insert(self, index, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'insert', index, itemType) + self._options(cnf, kw)) def insert_cascade(self, index, cnf={}, **kw): """Add hierarchical menu item at INDEX.""" self.insert(index, 'cascade', cnf or kw) def insert_checkbutton(self, index, cnf={}, **kw): """Add checkbutton menu item at INDEX.""" self.insert(index, 'checkbutton', cnf or kw) def insert_command(self, index, cnf={}, **kw): """Add command menu item at INDEX.""" self.insert(index, 'command', cnf or kw) def insert_radiobutton(self, index, cnf={}, **kw): """Add radio menu item at INDEX.""" self.insert(index, 'radiobutton', cnf or kw) def insert_separator(self, index, cnf={}, **kw): """Add separator at INDEX.""" self.insert(index, 'separator', cnf or kw) def delete(self, index1, index2=None): """Delete menu items between INDEX1 and INDEX2 (included).""" if index2 is None: index2 = index1 num_index1, num_index2 = self.index(index1), self.index(index2) if (num_index1 is None) or (num_index2 is None): num_index1, num_index2 = 0, -1 for i in range(num_index1, num_index2 + 1): if 'command' in self.entryconfig(i): c = str(self.entrycget(i, 'command')) if c: self.deletecommand(c) self.tk.call(self._w, 'delete', index1, index2) def entrycget(self, index, option): """Return the resource value of a menu item for OPTION at INDEX.""" return self.tk.call(self._w, 'entrycget', index, '-' + option) def entryconfigure(self, index, cnf=None, **kw): """Configure a menu item at INDEX.""" return self._configure(('entryconfigure', index), cnf, kw) entryconfig = entryconfigure def index(self, index): """Return the index of a menu item identified by INDEX.""" i = self.tk.call(self._w, 'index', index) return None if i in ('', 'none') else self.tk.getint(i) # GH-103685. def invoke(self, index): """Invoke a menu item identified by INDEX and execute the associated command.""" return self.tk.call(self._w, 'invoke', index) def post(self, x, y): """Display a menu at position X,Y.""" self.tk.call(self._w, 'post', x, y) def type(self, index): """Return the type of the menu item at INDEX.""" return self.tk.call(self._w, 'type', index) def unpost(self): """Unmap a menu.""" self.tk.call(self._w, 'unpost') def xposition(self, index): # new in Tk 8.5 """Return the x-position of the leftmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call(self._w, 'xposition', index)) def yposition(self, index): """Return the y-position of the topmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call( self._w, 'yposition', index)) class Menubutton(Widget): """Menubutton widget, obsolete since Tk8.0.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'menubutton', cnf, kw) class Message(Widget): """Message widget to display multiline text. Obsolete since Label does it too.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'message', cnf, kw) class Radiobutton(Widget): """Radiobutton widget which shows only one of several buttons in on-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a radiobutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, value, variable, width, wraplength.""" Widget.__init__(self, master, 'radiobutton', cnf, kw) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') class Scale(Widget): """Scale widget which can display a numerical scale.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scale widget with the parent MASTER. Valid resource names: activebackground, background, bigincrement, bd, bg, borderwidth, command, cursor, digits, fg, font, foreground, from, highlightbackground, highlightcolor, highlightthickness, label, length, orient, relief, repeatdelay, repeatinterval, resolution, showvalue, sliderlength, sliderrelief, state, takefocus, tickinterval, to, troughcolor, variable, width.""" Widget.__init__(self, master, 'scale', cnf, kw) def get(self): """Get the current value as integer or float.""" value = self.tk.call(self._w, 'get') try: return self.tk.getint(value) except (ValueError, TypeError, TclError): return self.tk.getdouble(value) def set(self, value): """Set the value to VALUE.""" self.tk.call(self._w, 'set', value) def coords(self, value=None): """Return a tuple (X,Y) of the point along the centerline of the trough that corresponds to VALUE or the current value if None is given.""" return self._getints(self.tk.call(self._w, 'coords', value)) def identify(self, x, y): """Return where the point X,Y lies. Valid return values are "slider", "though1" and "though2".""" return self.tk.call(self._w, 'identify', x, y) class Scrollbar(Widget): """Scrollbar widget which displays a slider at a certain position.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scrollbar widget with the parent MASTER. Valid resource names: activebackground, activerelief, background, bd, bg, borderwidth, command, cursor, elementborderwidth, highlightbackground, highlightcolor, highlightthickness, jump, orient, relief, repeatdelay, repeatinterval, takefocus, troughcolor, width.""" Widget.__init__(self, master, 'scrollbar', cnf, kw) def activate(self, index=None): """Marks the element indicated by index as active. The only index values understood by this method are "arrow1", "slider", or "arrow2". If any other value is specified then no element of the scrollbar will be active. If index is not specified, the method returns the name of the element that is currently active, or None if no element is active.""" return self.tk.call(self._w, 'activate', index) or None def delta(self, deltax, deltay): """Return the fractional change of the scrollbar setting if it would be moved by DELTAX or DELTAY pixels.""" return self.tk.getdouble( self.tk.call(self._w, 'delta', deltax, deltay)) def fraction(self, x, y): """Return the fractional value which corresponds to a slider position of X,Y.""" return self.tk.getdouble(self.tk.call(self._w, 'fraction', x, y)) def identify(self, x, y): """Return the element under position X,Y as one of "arrow1","slider","arrow2" or "".""" return self.tk.call(self._w, 'identify', x, y) def get(self): """Return the current fractional values (upper and lower end) of the slider position.""" return self._getdoubles(self.tk.call(self._w, 'get')) def set(self, first, last): """Set the fractional values of the slider position (upper and lower ends as value between 0 and 1).""" self.tk.call(self._w, 'set', first, last) class Text(Widget, XView, YView): """Text widget which can display text in various forms.""" def __init__(self, master=None, cnf={}, **kw): """Construct a text widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, padx, pady, relief, selectbackground, selectborderwidth, selectforeground, setgrid, takefocus, xscrollcommand, yscrollcommand, WIDGET-SPECIFIC OPTIONS autoseparators, height, maxundo, spacing1, spacing2, spacing3, state, tabs, undo, width, wrap, """ Widget.__init__(self, master, 'text', cnf, kw) def bbox(self, index): """Return a tuple of (x,y,width,height) which gives the bounding box of the visible part of the character at the given index.""" return self._getints( self.tk.call(self._w, 'bbox', index)) or None def compare(self, index1, op, index2): """Return whether between index INDEX1 and index INDEX2 the relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" return self.tk.getboolean(self.tk.call( self._w, 'compare', index1, op, index2)) def count(self, index1, index2, *args): # new in Tk 8.5 """Counts the number of relevant things between the two indices. If index1 is after index2, the result will be a negative number (and this holds for each of the possible options). The actual items which are counted depends on the options given by args. The result is a list of integers, one for the result of each counting option given. Valid counting options are "chars", "displaychars", "displayindices", "displaylines", "indices", "lines", "xpixels" and "ypixels". There is an additional possible option "update", which if given then all subsequent options ensure that any possible out of date information is recalculated.""" args = ['-%s' % arg for arg in args] args += [index1, index2] res = self.tk.call(self._w, 'count', *args) or None if res is not None and len(args) <= 3: return (res, ) else: return res def debug(self, boolean=None): """Turn on the internal consistency checks of the B-Tree inside the text widget according to BOOLEAN.""" if boolean is None: return self.tk.getboolean(self.tk.call(self._w, 'debug')) self.tk.call(self._w, 'debug', boolean) def delete(self, index1, index2=None): """Delete the characters between INDEX1 and INDEX2 (not included).""" self.tk.call(self._w, 'delete', index1, index2) def dlineinfo(self, index): """Return tuple (x,y,width,height,baseline) giving the bounding box and baseline position of the visible part of the line containing the character at INDEX.""" return self._getints(self.tk.call(self._w, 'dlineinfo', index)) def dump(self, index1, index2=None, command=None, **kw): """Return the contents of the widget between index1 and index2. The type of contents returned in filtered based on the keyword parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are given and true, then the corresponding items are returned. The result is a list of triples of the form (key, value, index). If none of the keywords are true then 'all' is used by default. If the 'command' argument is given, it is called once for each element of the list of triples, with the values of each triple serving as the arguments to the function. In this case the list is not returned.""" args = [] func_name = None result = None if not command: # Never call the dump command without the -command flag, since the # output could involve Tcl quoting and would be a pain to parse # right. Instead just set the command to build a list of triples # as if we had done the parsing. result = [] def append_triple(key, value, index, result=result): result.append((key, value, index)) command = append_triple try: if not isinstance(command, str): func_name = command = self._register(command) args += ["-command", command] for key in kw: if kw[key]: args.append("-" + key) args.append(index1) if index2: args.append(index2) self.tk.call(self._w, "dump", *args) return result finally: if func_name: self.deletecommand(func_name) ## new in tk8.4 def edit(self, *args): """Internal method This method controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the command are currently supported: edit_modified, edit_redo, edit_reset, edit_separator and edit_undo """ return self.tk.call(self._w, 'edit', *args) def edit_modified(self, arg=None): """Get or Set the modified flag If arg is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to arg. """ return self.edit("modified", arg) def edit_redo(self): """Redo the last undone edit When the undo option is true, reapplies the last undone edits provided no other edits were done since then. Generates an error when the redo stack is empty. Does nothing when the undo option is false. """ return self.edit("redo") def edit_reset(self): """Clears the undo and redo stacks """ return self.edit("reset") def edit_separator(self): """Inserts a separator (boundary) on the undo stack. Does nothing when the undo option is false """ return self.edit("separator") def edit_undo(self): """Undoes the last edit action If the undo option is true. An edit action is defined as all the insert and delete commands that are recorded on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the undo option is false """ return self.edit("undo") def get(self, index1, index2=None): """Return the text from INDEX1 to INDEX2 (not included).""" return self.tk.call(self._w, 'get', index1, index2) # (Image commands are new in 8.0) def image_cget(self, index, option): """Return the value of OPTION of an embedded image at INDEX.""" if option[:1] != "-": option = "-" + option if option[-1:] == "_": option = option[:-1] return self.tk.call(self._w, "image", "cget", index, option) def image_configure(self, index, cnf=None, **kw): """Configure an embedded image at INDEX.""" return self._configure(('image', 'configure', index), cnf, kw) def image_create(self, index, cnf={}, **kw): """Create an embedded image at INDEX.""" return self.tk.call( self._w, "image", "create", index, *self._options(cnf, kw)) def image_names(self): """Return all names of embedded images in this widget.""" return self.tk.call(self._w, "image", "names") def index(self, index): """Return the index in the form line.char for INDEX.""" return str(self.tk.call(self._w, 'index', index)) def insert(self, index, chars, *args): """Insert CHARS before the characters at INDEX. An additional tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" self.tk.call((self._w, 'insert', index, chars) + args) def mark_gravity(self, markName, direction=None): """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). Return the current value if None is given for DIRECTION.""" return self.tk.call( (self._w, 'mark', 'gravity', markName, direction)) def mark_names(self): """Return all mark names.""" return self.tk.splitlist(self.tk.call( self._w, 'mark', 'names')) def mark_set(self, markName, index): """Set mark MARKNAME before the character at INDEX.""" self.tk.call(self._w, 'mark', 'set', markName, index) def mark_unset(self, *markNames): """Delete all marks in MARKNAMES.""" self.tk.call((self._w, 'mark', 'unset') + markNames) def mark_next(self, index): """Return the name of the next mark after INDEX.""" return self.tk.call(self._w, 'mark', 'next', index) or None def mark_previous(self, index): """Return the name of the previous mark before INDEX.""" return self.tk.call(self._w, 'mark', 'previous', index) or None def peer_create(self, newPathName, cnf={}, **kw): # new in Tk 8.5 """Creates a peer text widget with the given newPathName, and any optional standard configuration options. By default the peer will have the same start and end line as the parent widget, but these can be overridden with the standard configuration options.""" self.tk.call(self._w, 'peer', 'create', newPathName, *self._options(cnf, kw)) def peer_names(self): # new in Tk 8.5 """Returns a list of peers of this widget (this does not include the widget itself).""" return self.tk.splitlist(self.tk.call(self._w, 'peer', 'names')) def replace(self, index1, index2, chars, *args): # new in Tk 8.5 """Replaces the range of characters between index1 and index2 with the given characters and tags specified by args. See the method insert for some more information about args, and the method delete for information about the indices.""" self.tk.call(self._w, 'replace', index1, index2, chars, *args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the text to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def search(self, pattern, index, stopindex=None, forwards=None, backwards=None, exact=None, regexp=None, nocase=None, count=None, elide=None): """Search PATTERN beginning from INDEX until STOPINDEX. Return the index of the first character of a match or an empty string.""" args = [self._w, 'search'] if forwards: args.append('-forwards') if backwards: args.append('-backwards') if exact: args.append('-exact') if regexp: args.append('-regexp') if nocase: args.append('-nocase') if elide: args.append('-elide') if count: args.append('-count'); args.append(count) if pattern and pattern[0] == '-': args.append('--') args.append(pattern) args.append(index) if stopindex: args.append(stopindex) return str(self.tk.call(tuple(args))) def see(self, index): """Scroll such that the character at INDEX is visible.""" self.tk.call(self._w, 'see', index) def tag_add(self, tagName, index1, *args): """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. Additional pairs of indices may follow in ARGS.""" self.tk.call( (self._w, 'tag', 'add', tagName, index1) + args) def tag_unbind(self, tagName, sequence, funcid=None): """Unbind for all characters with TAGNAME for event SEQUENCE the function identified with FUNCID.""" return self._unbind((self._w, 'tag', 'bind', tagName, sequence), funcid) def tag_bind(self, tagName, sequence, func, add=None): """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'tag', 'bind', tagName), sequence, func, add) def _tag_bind(self, tagName, sequence=None, func=None, add=None): # For tests only return self._bind((self._w, 'tag', 'bind', tagName), sequence, func, add) def tag_cget(self, tagName, option): """Return the value of OPTION for tag TAGNAME.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'tag', 'cget', tagName, option) def tag_configure(self, tagName, cnf=None, **kw): """Configure a tag TAGNAME.""" return self._configure(('tag', 'configure', tagName), cnf, kw) tag_config = tag_configure def tag_delete(self, *tagNames): """Delete all tags in TAGNAMES.""" self.tk.call((self._w, 'tag', 'delete') + tagNames) def tag_lower(self, tagName, belowThis=None): """Change the priority of tag TAGNAME such that it is lower than the priority of BELOWTHIS.""" self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) def tag_names(self, index=None): """Return a list of all tag names.""" return self.tk.splitlist( self.tk.call(self._w, 'tag', 'names', index)) def tag_nextrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched forward from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'nextrange', tagName, index1, index2)) def tag_prevrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched backwards from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'prevrange', tagName, index1, index2)) def tag_raise(self, tagName, aboveThis=None): """Change the priority of tag TAGNAME such that it is higher than the priority of ABOVETHIS.""" self.tk.call( self._w, 'tag', 'raise', tagName, aboveThis) def tag_ranges(self, tagName): """Return a list of ranges of text which have tag TAGNAME.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'ranges', tagName)) def tag_remove(self, tagName, index1, index2=None): """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" self.tk.call( self._w, 'tag', 'remove', tagName, index1, index2) def window_cget(self, index, option): """Return the value of OPTION of an embedded window at INDEX.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'window', 'cget', index, option) def window_configure(self, index, cnf=None, **kw): """Configure an embedded window at INDEX.""" return self._configure(('window', 'configure', index), cnf, kw) window_config = window_configure def window_create(self, index, cnf={}, **kw): """Create a window at INDEX.""" self.tk.call( (self._w, 'window', 'create', index) + self._options(cnf, kw)) def window_names(self): """Return all names of embedded windows in this widget.""" return self.tk.splitlist( self.tk.call(self._w, 'window', 'names')) def yview_pickplace(self, *what): """Obsolete function, use see.""" self.tk.call((self._w, 'yview', '-pickplace') + what) class _setit: """Internal class. It wraps the command in the widget OptionMenu.""" def __init__(self, var, value, callback=None): self.__value = value self.__var = var self.__callback = callback def __call__(self, *args): self.__var.set(self.__value) if self.__callback is not None: self.__callback(self.__value, *args) class OptionMenu(Menubutton): """OptionMenu which allows the user to select a value from a menu.""" def __init__(self, master, variable, value, *values, **kwargs): """Construct an optionmenu widget with the parent MASTER, with the resource textvariable set to VARIABLE, the initially selected value VALUE, the other menu values VALUES and an additional keyword argument command.""" kw = {"borderwidth": 2, "textvariable": variable, "indicatoron": 1, "relief": RAISED, "anchor": "c", "highlightthickness": 2} Widget.__init__(self, master, "menubutton", kw) self.widgetName = 'tk_optionMenu' menu = self.__menu = Menu(self, name="menu", tearoff=0) self.menuname = menu._w # 'command' is the only supported keyword callback = kwargs.get('command') if 'command' in kwargs: del kwargs['command'] if kwargs: raise TclError('unknown option -'+next(iter(kwargs))) menu.add_command(label=value, command=_setit(variable, value, callback)) for v in values: menu.add_command(label=v, command=_setit(variable, v, callback)) self["menu"] = menu def __getitem__(self, name): if name == 'menu': return self.__menu return Widget.__getitem__(self, name) def destroy(self): """Destroy this widget and the associated menu.""" Menubutton.destroy(self) self.__menu = None class Image: """Base class for images.""" _last_id = 0 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): self.name = None if master is None: master = _get_default_root('create image') self.tk = getattr(master, 'tk', master) if not name: Image._last_id += 1 name = "pyimage%r" % (Image._last_id,) # tk itself would use image if kw and cnf: cnf = _cnfmerge((cnf, kw)) elif kw: cnf = kw options = () for k, v in cnf.items(): options = options + ('-'+k, v) self.tk.call(('image', 'create', imgtype, name,) + options) self.name = name def __str__(self): return self.name def __del__(self): if self.name: try: self.tk.call('image', 'delete', self.name) except TclError: # May happen if the root was destroyed pass def __setitem__(self, key, value): self.tk.call(self.name, 'configure', '-'+key, value) def __getitem__(self, key): return self.tk.call(self.name, 'configure', '-'+key) def configure(self, **kw): """Configure the image.""" res = () for k, v in _cnfmerge(kw).items(): if v is not None: if k[-1] == '_': k = k[:-1] res = res + ('-'+k, v) self.tk.call((self.name, 'config') + res) config = configure def height(self): """Return the height of the image.""" return self.tk.getint( self.tk.call('image', 'height', self.name)) def type(self): """Return the type of the image, e.g. "photo" or "bitmap".""" return self.tk.call('image', 'type', self.name) def width(self): """Return the width of the image.""" return self.tk.getint( self.tk.call('image', 'width', self.name)) class PhotoImage(Image): """Widget which can display images in PGM, PPM, GIF, PNG format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create an image with NAME. Valid resource names: data, format, file, gamma, height, palette, width.""" Image.__init__(self, 'photo', name, cnf, master, **kw) def blank(self): """Display a transparent image.""" self.tk.call(self.name, 'blank') def cget(self, option): """Return the value of OPTION.""" return self.tk.call(self.name, 'cget', '-' + option) # XXX config def __getitem__(self, key): return self.tk.call(self.name, 'cget', '-' + key) # XXX copy -from, -to, ...? def copy(self): """Return a new PhotoImage with the same image as this widget.""" destImage = PhotoImage(master=self.tk) self.tk.call(destImage, 'copy', self.name) return destImage def zoom(self, x, y=''): """Return a new PhotoImage with the same image as this widget but zoom it with a factor of x in the X direction and y in the Y direction. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) return destImage def subsample(self, x, y=''): """Return a new PhotoImage based on the same image as this widget but use only every Xth or Yth pixel. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) return destImage def get(self, x, y): """Return the color (red, green, blue) of the pixel at X,Y.""" return self.tk.call(self.name, 'get', x, y) def put(self, data, to=None): """Put row formatted colors to image starting from position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" args = (self.name, 'put', data) if to: if to[0] == '-to': to = to[1:] args = args + ('-to',) + tuple(to) self.tk.call(args) # XXX read def write(self, filename, format=None, from_coords=None): """Write image to file FILENAME in FORMAT starting from position FROM_COORDS.""" args = (self.name, 'write', filename) if format: args = args + ('-format', format) if from_coords: args = args + ('-from',) + tuple(from_coords) self.tk.call(args) def transparency_get(self, x, y): """Return True if the pixel at x,y is transparent.""" return self.tk.getboolean(self.tk.call( self.name, 'transparency', 'get', x, y)) def transparency_set(self, x, y, boolean): """Set the transparency of the pixel at x,y.""" self.tk.call(self.name, 'transparency', 'set', x, y, boolean) class BitmapImage(Image): """Widget which can display images in XBM format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create a bitmap with NAME. Valid resource names: background, data, file, foreground, maskdata, maskfile.""" Image.__init__(self, 'bitmap', name, cnf, master, **kw) def image_names(): tk = _get_default_root('use image_names()').tk return tk.splitlist(tk.call('image', 'names')) def image_types(): tk = _get_default_root('use image_types()').tk return tk.splitlist(tk.call('image', 'types')) class Spinbox(Widget, XView): """spinbox widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a spinbox widget with the parent MASTER. STANDARD OPTIONS activebackground, background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, justify, relief, repeatdelay, repeatinterval, selectbackground, selectborderwidth selectforeground, takefocus, textvariable xscrollcommand. WIDGET-SPECIFIC OPTIONS buttonbackground, buttoncursor, buttondownrelief, buttonuprelief, command, disabledbackground, disabledforeground, format, from, invalidcommand, increment, readonlybackground, state, to, validate, validatecommand values, width, wrap, """ Widget.__init__(self, master, 'spinbox', cnf, kw) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the character given by index. The first two elements of the list give the x and y coordinates of the upper-left corner of the screen area covered by the character (in pixels relative to the widget) and the last two elements give the width and height of the character, in pixels. The bounding box may refer to a region outside the visible area of the window. """ return self._getints(self.tk.call(self._w, 'bbox', index)) or None def delete(self, first, last=None): """Delete one or more elements of the spinbox. First is the index of the first character to delete, and last is the index of the character just after the last one to delete. If last isn't specified it defaults to first+1, i.e. a single character is deleted. This command returns an empty string. """ return self.tk.call(self._w, 'delete', first, last) def get(self): """Returns the spinbox's string""" return self.tk.call(self._w, 'get') def icursor(self, index): """Alter the position of the insertion cursor. The insertion cursor will be displayed just before the character given by index. Returns an empty string """ return self.tk.call(self._w, 'icursor', index) def identify(self, x, y): """Returns the name of the widget at position x, y Return value is one of: none, buttondown, buttonup, entry """ return self.tk.call(self._w, 'identify', x, y) def index(self, index): """Returns the numerical index corresponding to index """ return self.tk.call(self._w, 'index', index) def insert(self, index, s): """Insert string s at index Returns an empty string. """ return self.tk.call(self._w, 'insert', index, s) def invoke(self, element): """Causes the specified element to be invoked The element could be buttondown or buttonup triggering the action associated with it. """ return self.tk.call(self._w, 'invoke', element) def scan(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'scan') + args)) or () def scan_mark(self, x): """Records x and the current view in the spinbox window; used in conjunction with later scan dragto commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. """ return self.scan("mark", x) def scan_dragto(self, x): """Compute the difference between the given x argument and the x argument to the last scan mark command It then adjusts the view left or right by 10 times the difference in x-coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the spinbox at high speed through the window. The return value is an empty string. """ return self.scan("dragto", x) def selection(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'selection') + args)) or () def selection_adjust(self, index): """Locate the end of the selection nearest to the character given by index, Then adjust that end of the selection to be at index (i.e including but not going beyond index). The other end of the selection is made the anchor point for future select to commands. If the selection isn't currently in the spinbox, then a new selection is created to include the characters between index and the most recent selection anchor point, inclusive. """ return self.selection("adjust", index) def selection_clear(self): """Clear the selection If the selection isn't in this widget then the command has no effect. """ return self.selection("clear") def selection_element(self, element=None): """Sets or gets the currently selected element. If a spinbutton element is specified, it will be displayed depressed. """ return self.tk.call(self._w, 'selection', 'element', element) def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.selection('from', index) def selection_present(self): """Return True if there are characters selected in the spinbox, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.selection('range', start, end) def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.selection('to', index) ########################################################################### class LabelFrame(Widget): """labelframe widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a labelframe widget with the parent MASTER. STANDARD OPTIONS borderwidth, cursor, font, foreground, highlightbackground, highlightcolor, highlightthickness, padx, pady, relief, takefocus, text WIDGET-SPECIFIC OPTIONS background, class, colormap, container, height, labelanchor, labelwidget, visual, width """ Widget.__init__(self, master, 'labelframe', cnf, kw) ######################################################################## class PanedWindow(Widget): """panedwindow widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a panedwindow widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, height, orient, relief, width WIDGET-SPECIFIC OPTIONS handlepad, handlesize, opaqueresize, sashcursor, sashpad, sashrelief, sashwidth, showhandle, """ Widget.__init__(self, master, 'panedwindow', cnf, kw) def add(self, child, **kw): """Add a child widget to the panedwindow in a new pane. The child argument is the name of the child widget followed by pairs of arguments that specify how to manage the windows. The possible options and values are the ones accepted by the paneconfigure method. """ self.tk.call((self._w, 'add', child) + self._options(kw)) def remove(self, child): """Remove the pane containing child from the panedwindow All geometry management options for child will be forgotten. """ self.tk.call(self._w, 'forget', child) forget = remove def identify(self, x, y): """Identify the panedwindow component at point x, y If the point is over a sash or a sash handle, the result is a two element list containing the index of the sash or handle, and a word indicating whether it is over a sash or a handle, such as {0 sash} or {2 handle}. If the point is over any other part of the panedwindow, the result is an empty list. """ return self.tk.call(self._w, 'identify', x, y) def proxy(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'proxy') + args)) or () def proxy_coord(self): """Return the x and y pair of the most recent proxy location """ return self.proxy("coord") def proxy_forget(self): """Remove the proxy from the display. """ return self.proxy("forget") def proxy_place(self, x, y): """Place the proxy at the given x and y coordinates. """ return self.proxy("place", x, y) def sash(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'sash') + args)) or () def sash_coord(self, index): """Return the current x and y pair for the sash given by index. Index must be an integer between 0 and 1 less than the number of panes in the panedwindow. The coordinates given are those of the top left corner of the region containing the sash. pathName sash dragto index x y This command computes the difference between the given coordinates and the coordinates given to the last sash coord command for the given sash. It then moves that sash the computed difference. The return value is the empty string. """ return self.sash("coord", index) def sash_mark(self, index): """Records x and y for the sash given by index; Used in conjunction with later dragto commands to move the sash. """ return self.sash("mark", index) def sash_place(self, index, x, y): """Place the sash given by index at the given coordinates """ return self.sash("place", index, x, y) def panecget(self, child, option): """Query a management option for window. Option may be any value allowed by the paneconfigure subcommand """ return self.tk.call( (self._w, 'panecget') + (child, '-'+option)) def paneconfigure(self, tagOrId, cnf=None, **kw): """Query or modify the management options for window. If no option is specified, returns a list describing all of the available options for pathName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. The following options are supported: after window Insert the window after the window specified. window should be the name of a window already managed by pathName. before window Insert the window before the window specified. window should be the name of a window already managed by pathName. height size Specify a height for the window. The height will be the outer dimension of the window including its border, if any. If size is an empty string, or if -height is not specified, then the height requested internally by the window will be used initially; the height may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. minsize n Specifies that the size of the window cannot be made less than n. This constraint only affects the size of the widget in the paned dimension -- the x dimension for horizontal panedwindows, the y dimension for vertical panedwindows. May be any value accepted by Tk_GetPixels. padx n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the X-direction. The value may have any of the forms accepted by Tk_GetPixels. pady n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the Y-direction. The value may have any of the forms accepted by Tk_GetPixels. sticky style If a window's pane is larger than the requested dimensions of the window, this option may be used to position (or stretch) the window within its pane. Style is a string that contains zero or more of the characters n, s, e or w. The string can optionally contains spaces or commas, but they are ignored. Each letter refers to a side (north, south, east, or west) that the window will "stick" to. If both n and s (or e and w) are specified, the window will be stretched to fill the entire height (or width) of its cavity. width size Specify a width for the window. The width will be the outer dimension of the window including its border, if any. If size is an empty string, or if -width is not specified, then the width requested internally by the window will be used initially; the width may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. """ if cnf is None and not kw: return self._getconfigure(self._w, 'paneconfigure', tagOrId) if isinstance(cnf, str) and not kw: return self._getconfigure1( self._w, 'paneconfigure', tagOrId, '-'+cnf) self.tk.call((self._w, 'paneconfigure', tagOrId) + self._options(cnf, kw)) paneconfig = paneconfigure def panes(self): """Returns an ordered list of the child panes.""" return self.tk.splitlist(self.tk.call(self._w, 'panes')) # Test: def _test(): root = Tk() text = "This is Tcl/Tk %s" % root.globalgetvar('tk_patchLevel') text += "\nThis should be a cedilla: \xe7" label = Label(root, text=text) label.pack() test = Button(root, text="Click me!", command=lambda root=root: root.test.configure( text="[%s]" % root.test['text'])) test.pack() root.test = test quit = Button(root, text="QUIT", command=root.destroy) quit.pack() # The following three commands are needed so the window pops # up on top on Windows... root.iconify() root.update() root.deiconify() root.mainloop() __all__ = [name for name, obj in globals().items() if not name.startswith('_') and not isinstance(obj, types.ModuleType) and name not in {'wantobjects'}] if __name__ == '__main__': _test() lib64/python3.8/xml/sax/__init__.py000064400000007077152353763060012767 0ustar00"""Simple API for XML (SAX) implementation for Python. This module provides an implementation of the SAX 2 interface; information about the Java version of the interface can be found at http://www.megginson.com/SAX/. The Python version of the interface is documented at <...>. This package contains the following modules: handler -- Base classes and constants which define the SAX 2 API for the 'client-side' of SAX for Python. saxutils -- Implementation of the convenience classes commonly used to work with SAX. xmlreader -- Base classes and constants which define the SAX 2 API for the parsers used with SAX for Python. expatreader -- Driver that allows use of the Expat parser with SAX. """ from .xmlreader import InputSource from .handler import ContentHandler, ErrorHandler from ._exceptions import SAXException, SAXNotRecognizedException, \ SAXParseException, SAXNotSupportedException, \ SAXReaderNotAvailable def parse(source, handler, errorHandler=ErrorHandler()): parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) parser.parse(source) def parseString(string, handler, errorHandler=ErrorHandler()): import io if errorHandler is None: errorHandler = ErrorHandler() parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) inpsrc = InputSource() if isinstance(string, str): inpsrc.setCharacterStream(io.StringIO(string)) else: inpsrc.setByteStream(io.BytesIO(string)) parser.parse(inpsrc) # this is the parser list used by the make_parser function if no # alternatives are given as parameters to the function default_parser_list = ["xml.sax.expatreader"] # tell modulefinder that importing sax potentially imports expatreader _false = 0 if _false: import xml.sax.expatreader import os, sys if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ: default_parser_list = os.environ["PY_SAX_PARSER"].split(",") del os _key = "python.xml.sax.parser" if sys.platform[:4] == "java" and sys.registry.containsKey(_key): default_parser_list = sys.registry.getProperty(_key).split(",") def make_parser(parser_list=()): """Creates and returns a SAX parser. Creates the first parser it is able to instantiate of the ones given in the iterable created by chaining parser_list and default_parser_list. The iterables must contain the names of Python modules containing both a SAX parser and a create_parser function.""" for parser_name in list(parser_list) + default_parser_list: try: return _create_parser(parser_name) except ImportError as e: import sys if parser_name in sys.modules: # The parser module was found, but importing it # failed unexpectedly, pass this exception through raise except SAXReaderNotAvailable: # The parser module detected that it won't work properly, # so try the next one pass raise SAXReaderNotAvailable("No parsers found", None) # --- Internal utility methods used by make_parser if sys.platform[ : 4] == "java": def _create_parser(parser_name): from org.python.core import imp drv_module = imp.importName(parser_name, 0, globals()) return drv_module.create_parser() else: def _create_parser(parser_name): drv_module = __import__(parser_name,{},{},['create_parser']) return drv_module.create_parser() del sys lib64/python3.12/xml/dom/__init__.py000064400000007663152353764030013025 0ustar00"""W3C Document Object Model implementation for Python. The Python mapping of the Document Object Model is documented in the Python Library Reference in the section on the xml.dom package. This package contains the following modules: minidom -- A simple implementation of the Level 1 DOM with namespace support added (based on the Level 2 specification) and other minor Level 2 functionality. pulldom -- DOM builder supporting on-demand tree-building for selected subtrees of the document. """ class Node: """Class giving the NodeType constants.""" __slots__ = () # DOM implementations may use this as a base class for their own # Node implementations. If they don't, the constants defined here # should still be used as the canonical definitions as they match # the values given in the W3C recommendation. Client code can # safely refer to these values in all tests of Node.nodeType # values. ELEMENT_NODE = 1 ATTRIBUTE_NODE = 2 TEXT_NODE = 3 CDATA_SECTION_NODE = 4 ENTITY_REFERENCE_NODE = 5 ENTITY_NODE = 6 PROCESSING_INSTRUCTION_NODE = 7 COMMENT_NODE = 8 DOCUMENT_NODE = 9 DOCUMENT_TYPE_NODE = 10 DOCUMENT_FRAGMENT_NODE = 11 NOTATION_NODE = 12 #ExceptionCode INDEX_SIZE_ERR = 1 DOMSTRING_SIZE_ERR = 2 HIERARCHY_REQUEST_ERR = 3 WRONG_DOCUMENT_ERR = 4 INVALID_CHARACTER_ERR = 5 NO_DATA_ALLOWED_ERR = 6 NO_MODIFICATION_ALLOWED_ERR = 7 NOT_FOUND_ERR = 8 NOT_SUPPORTED_ERR = 9 INUSE_ATTRIBUTE_ERR = 10 INVALID_STATE_ERR = 11 SYNTAX_ERR = 12 INVALID_MODIFICATION_ERR = 13 NAMESPACE_ERR = 14 INVALID_ACCESS_ERR = 15 VALIDATION_ERR = 16 class DOMException(Exception): """Abstract base class for DOM exceptions. Exceptions with specific codes are specializations of this class.""" def __init__(self, *args, **kw): if self.__class__ is DOMException: raise RuntimeError( "DOMException should not be instantiated directly") Exception.__init__(self, *args, **kw) def _get_code(self): return self.code class IndexSizeErr(DOMException): code = INDEX_SIZE_ERR class DomstringSizeErr(DOMException): code = DOMSTRING_SIZE_ERR class HierarchyRequestErr(DOMException): code = HIERARCHY_REQUEST_ERR class WrongDocumentErr(DOMException): code = WRONG_DOCUMENT_ERR class InvalidCharacterErr(DOMException): code = INVALID_CHARACTER_ERR class NoDataAllowedErr(DOMException): code = NO_DATA_ALLOWED_ERR class NoModificationAllowedErr(DOMException): code = NO_MODIFICATION_ALLOWED_ERR class NotFoundErr(DOMException): code = NOT_FOUND_ERR class NotSupportedErr(DOMException): code = NOT_SUPPORTED_ERR class InuseAttributeErr(DOMException): code = INUSE_ATTRIBUTE_ERR class InvalidStateErr(DOMException): code = INVALID_STATE_ERR class SyntaxErr(DOMException): code = SYNTAX_ERR class InvalidModificationErr(DOMException): code = INVALID_MODIFICATION_ERR class NamespaceErr(DOMException): code = NAMESPACE_ERR class InvalidAccessErr(DOMException): code = INVALID_ACCESS_ERR class ValidationErr(DOMException): code = VALIDATION_ERR class UserDataHandler: """Class giving the operation constants for UserDataHandler.handle().""" # Based on DOM Level 3 (WD 9 April 2002) NODE_CLONED = 1 NODE_IMPORTED = 2 NODE_DELETED = 3 NODE_RENAMED = 4 XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml" EMPTY_NAMESPACE = None EMPTY_PREFIX = None from .domreg import getDOMImplementation, registerDOMImplementation lib64/python3.8/xml/__init__.py000064400000001055152354007630012155 0ustar00"""Core XML support for Python. This package contains four sub-packages: dom -- The W3C Document Object Model. This supports DOM Level 1 + Namespaces. parsers -- Python wrappers for XML parsers (currently only supports Expat). sax -- The Simple API for XML, developed by XML-Dev, led by David Megginson and ported to Python by Lars Marius Garshol. This supports the SAX 2 API. etree -- The ElementTree XML library. This is a subset of the full ElementTree XML release. """ __all__ = ["dom", "parsers", "sax", "etree"] lib64/python2.7/xml/sax/__init__.py000064400000007042152354117540012752 0ustar00"""Simple API for XML (SAX) implementation for Python. This module provides an implementation of the SAX 2 interface; information about the Java version of the interface can be found at http://www.megginson.com/SAX/. The Python version of the interface is documented at <...>. This package contains the following modules: handler -- Base classes and constants which define the SAX 2 API for the 'client-side' of SAX for Python. saxutils -- Implementation of the convenience classes commonly used to work with SAX. xmlreader -- Base classes and constants which define the SAX 2 API for the parsers used with SAX for Python. expatreader -- Driver that allows use of the Expat parser with SAX. """ from xmlreader import InputSource from handler import ContentHandler, ErrorHandler from _exceptions import SAXException, SAXNotRecognizedException, \ SAXParseException, SAXNotSupportedException, \ SAXReaderNotAvailable def parse(source, handler, errorHandler=ErrorHandler()): parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) parser.parse(source) def parseString(string, handler, errorHandler=ErrorHandler()): try: from cStringIO import StringIO except ImportError: from StringIO import StringIO if errorHandler is None: errorHandler = ErrorHandler() parser = make_parser() parser.setContentHandler(handler) parser.setErrorHandler(errorHandler) inpsrc = InputSource() inpsrc.setByteStream(StringIO(string)) parser.parse(inpsrc) # this is the parser list used by the make_parser function if no # alternatives are given as parameters to the function default_parser_list = ["xml.sax.expatreader"] # tell modulefinder that importing sax potentially imports expatreader _false = 0 if _false: import xml.sax.expatreader import os, sys if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ: default_parser_list = os.environ["PY_SAX_PARSER"].split(",") del os _key = "python.xml.sax.parser" if sys.platform[:4] == "java" and sys.registry.containsKey(_key): default_parser_list = sys.registry.getProperty(_key).split(",") def make_parser(parser_list = []): """Creates and returns a SAX parser. Creates the first parser it is able to instantiate of the ones given in the list created by doing parser_list + default_parser_list. The lists must contain the names of Python modules containing both a SAX parser and a create_parser function.""" for parser_name in parser_list + default_parser_list: try: return _create_parser(parser_name) except ImportError,e: import sys if parser_name in sys.modules: # The parser module was found, but importing it # failed unexpectedly, pass this exception through raise except SAXReaderNotAvailable: # The parser module detected that it won't work properly, # so try the next one pass raise SAXReaderNotAvailable("No parsers found", None) # --- Internal utility methods used by make_parser if sys.platform[ : 4] == "java": def _create_parser(parser_name): from org.python.core import imp drv_module = imp.importName(parser_name, 0, globals()) return drv_module.create_parser() else: def _create_parser(parser_name): drv_module = __import__(parser_name,{},{},['create_parser']) return drv_module.create_parser() del sys lib64/python3.6/html/__init__.py000064400000011224152356705230012321 0ustar00""" General functions for HTML manipulation. """ import re as _re from html.entities import html5 as _html5 __all__ = ['escape', 'unescape'] def escape(s, quote=True): """ Replace special characters "&", "<" and ">" to HTML-safe sequences. If the optional flag quote is true (the default), the quotation mark characters, both double quote (") and single quote (') characters are also translated. """ s = s.replace("&", "&") # Must be done first! s = s.replace("<", "<") s = s.replace(">", ">") if quote: s = s.replace('"', """) s = s.replace('\'', "'") return s # see http://www.w3.org/TR/html5/syntax.html#tokenizing-character-references _invalid_charrefs = { 0x00: '\ufffd', # REPLACEMENT CHARACTER 0x0d: '\r', # CARRIAGE RETURN 0x80: '\u20ac', # EURO SIGN 0x81: '\x81', # 0x82: '\u201a', # SINGLE LOW-9 QUOTATION MARK 0x83: '\u0192', # LATIN SMALL LETTER F WITH HOOK 0x84: '\u201e', # DOUBLE LOW-9 QUOTATION MARK 0x85: '\u2026', # HORIZONTAL ELLIPSIS 0x86: '\u2020', # DAGGER 0x87: '\u2021', # DOUBLE DAGGER 0x88: '\u02c6', # MODIFIER LETTER CIRCUMFLEX ACCENT 0x89: '\u2030', # PER MILLE SIGN 0x8a: '\u0160', # LATIN CAPITAL LETTER S WITH CARON 0x8b: '\u2039', # SINGLE LEFT-POINTING ANGLE QUOTATION MARK 0x8c: '\u0152', # LATIN CAPITAL LIGATURE OE 0x8d: '\x8d', # 0x8e: '\u017d', # LATIN CAPITAL LETTER Z WITH CARON 0x8f: '\x8f', # 0x90: '\x90', # 0x91: '\u2018', # LEFT SINGLE QUOTATION MARK 0x92: '\u2019', # RIGHT SINGLE QUOTATION MARK 0x93: '\u201c', # LEFT DOUBLE QUOTATION MARK 0x94: '\u201d', # RIGHT DOUBLE QUOTATION MARK 0x95: '\u2022', # BULLET 0x96: '\u2013', # EN DASH 0x97: '\u2014', # EM DASH 0x98: '\u02dc', # SMALL TILDE 0x99: '\u2122', # TRADE MARK SIGN 0x9a: '\u0161', # LATIN SMALL LETTER S WITH CARON 0x9b: '\u203a', # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK 0x9c: '\u0153', # LATIN SMALL LIGATURE OE 0x9d: '\x9d', # 0x9e: '\u017e', # LATIN SMALL LETTER Z WITH CARON 0x9f: '\u0178', # LATIN CAPITAL LETTER Y WITH DIAERESIS } _invalid_codepoints = { # 0x0001 to 0x0008 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, # 0x000E to 0x001F 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, # 0x007F to 0x009F 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, # 0xFDD0 to 0xFDEF 0xfdd0, 0xfdd1, 0xfdd2, 0xfdd3, 0xfdd4, 0xfdd5, 0xfdd6, 0xfdd7, 0xfdd8, 0xfdd9, 0xfdda, 0xfddb, 0xfddc, 0xfddd, 0xfdde, 0xfddf, 0xfde0, 0xfde1, 0xfde2, 0xfde3, 0xfde4, 0xfde5, 0xfde6, 0xfde7, 0xfde8, 0xfde9, 0xfdea, 0xfdeb, 0xfdec, 0xfded, 0xfdee, 0xfdef, # others 0xb, 0xfffe, 0xffff, 0x1fffe, 0x1ffff, 0x2fffe, 0x2ffff, 0x3fffe, 0x3ffff, 0x4fffe, 0x4ffff, 0x5fffe, 0x5ffff, 0x6fffe, 0x6ffff, 0x7fffe, 0x7ffff, 0x8fffe, 0x8ffff, 0x9fffe, 0x9ffff, 0xafffe, 0xaffff, 0xbfffe, 0xbffff, 0xcfffe, 0xcffff, 0xdfffe, 0xdffff, 0xefffe, 0xeffff, 0xffffe, 0xfffff, 0x10fffe, 0x10ffff } def _replace_charref(s): s = s.group(1) if s[0] == '#': # numeric charref if s[1] in 'xX': num = int(s[2:].rstrip(';'), 16) else: num = int(s[1:].rstrip(';')) if num in _invalid_charrefs: return _invalid_charrefs[num] if 0xD800 <= num <= 0xDFFF or num > 0x10FFFF: return '\uFFFD' if num in _invalid_codepoints: return '' return chr(num) else: # named charref if s in _html5: return _html5[s] # find the longest matching name (as defined by the standard) for x in range(len(s)-1, 1, -1): if s[:x] in _html5: return _html5[s[:x]] + s[x:] else: return '&' + s _charref = _re.compile(r'&(#[0-9]+;?' r'|#[xX][0-9a-fA-F]+;?' r'|[^\t\n\f <&#;]{1,32};?)') def unescape(s): """ Convert all named and numeric character references (e.g. >, >, &x3e;) in the string s to the corresponding unicode characters. This function uses the rules defined by the HTML 5 standard for both valid and invalid character references, and the list of HTML 5 named character references defined in html.entities.html5. """ if '&' not in s: return s return _charref.sub(_replace_charref, s) lib64/python3.8/json/__init__.py000064400000034011152357201370012324 0ustar00r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is derived from a version of the externally maintained simplejson library. Encoding basic Python object hierarchies:: >>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print(json.dumps("\"foo\bar")) "\"foo\bar" >>> print(json.dumps('\u1234')) "\u1234" >>> print(json.dumps('\\')) "\\" >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)) {"a": 0, "b": 0, "c": 0} >>> from io import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]' Compact encoding:: >>> import json >>> mydict = {'4': 5, '6': 7} >>> json.dumps([1,2,3,mydict], separators=(',', ':')) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: >>> import json >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4)) { "4": 5, "6": 7 } Decoding JSON:: >>> import json >>> obj = ['foo', {'bar': ['baz', None, 1.0, 2]}] >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj True >>> json.loads('"\\"foo\\bar"') == '"foo\x08ar' True >>> from io import StringIO >>> io = StringIO('["streaming API"]') >>> json.load(io)[0] == 'streaming API' True Specializing JSON object decoding:: >>> import json >>> def as_complex(dct): ... if '__complex__' in dct: ... return complex(dct['real'], dct['imag']) ... return dct ... >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', ... object_hook=as_complex) (1+2j) >>> from decimal import Decimal >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') True Specializing JSON object encoding:: >>> import json >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... raise TypeError(f'Object of type {obj.__class__.__name__} ' ... f'is not JSON serializable') ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) '[2.0, 1.0]' >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) '[2.0, 1.0]' Using json.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } $ echo '{ 1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] __author__ = 'Bob Ippolito ' from .decoder import JSONDecoder, JSONDecodeError from .encoder import JSONEncoder import codecs _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, default=None, ) def dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the strings written to ``fp`` can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): iterable = _default_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, then the return value can contain non-ASCII characters if they appear in strings contained in ``obj``. Otherwise, all such characters are escaped in JSON strings. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. If specified, ``separators`` should be an ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most compact JSON representation, you should specify ``(',', ':')`` to eliminate whitespace. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and default is None and not sort_keys and not kw): return _default_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, default=default, sort_keys=sort_keys, **kw).encode(obj) _default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None) def detect_encoding(b): bstartswith = b.startswith if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)): return 'utf-32' if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)): return 'utf-16' if bstartswith(codecs.BOM_UTF8): return 'utf-8-sig' if len(b) >= 4: if not b[0]: # 00 00 -- -- - utf-32-be # 00 XX -- -- - utf-16-be return 'utf-16-be' if b[1] else 'utf-32-be' if not b[1]: # XX 00 00 00 - utf-32-le # XX 00 00 XX - utf-16-le # XX 00 XX -- - utf-16-le return 'utf-16-le' if b[2] or b[3] else 'utf-32-le' elif len(b) == 2: if not b[0]: # 00 XX - utf-16-be return 'utf-16-be' if not b[1]: # XX 00 - utf-16-le return 'utf-16-le' # default return 'utf-8' def load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders. If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ return loads(fp.read(), cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) def loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance containing a JSON document) to a Python object. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders. If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. ``parse_float``, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal). ``parse_int``, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float). ``parse_constant``, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. The ``encoding`` argument is ignored and deprecated since Python 3.1. """ if isinstance(s, str): if s.startswith('\ufeff'): raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", s, 0) else: if not isinstance(s, (bytes, bytearray)): raise TypeError(f'the JSON object must be str, bytes or bytearray, ' f'not {s.__class__.__name__}') s = s.decode(detect_encoding(s), 'surrogatepass') if "encoding" in kw: import warnings warnings.warn( "'encoding' is ignored and deprecated. It will be removed in Python 3.9", DeprecationWarning, stacklevel=2 ) del kw['encoding'] if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(**kw).decode(s) lib64/python2.7/json/__init__.py000064400000034601152357257110012332 0ustar00r"""JSON (JavaScript Object Notation) is a subset of JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data interchange format. :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. It is the externally maintained version of the :mod:`json` library contained in Python 2.6, but maintains compatibility with Python 2.4 and Python 2.5 and (currently) has significant performance advantages, even without using the optional C extension for speedups. Encoding basic Python object hierarchies:: >>> import json >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) '["foo", {"bar": ["baz", null, 1.0, 2]}]' >>> print json.dumps("\"foo\bar") "\"foo\bar" >>> print json.dumps(u'\u1234') "\u1234" >>> print json.dumps('\\') "\\" >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True) {"a": 0, "b": 0, "c": 0} >>> from StringIO import StringIO >>> io = StringIO() >>> json.dump(['streaming API'], io) >>> io.getvalue() '["streaming API"]' Compact encoding:: >>> import json >>> json.dumps([1,2,3,{'4': 5, '6': 7}], sort_keys=True, separators=(',',':')) '[1,2,3,{"4":5,"6":7}]' Pretty printing:: >>> import json >>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, ... indent=4, separators=(',', ': ')) { "4": 5, "6": 7 } Decoding JSON:: >>> import json >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}] >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj True >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar' True >>> from StringIO import StringIO >>> io = StringIO('["streaming API"]') >>> json.load(io)[0] == 'streaming API' True Specializing JSON object decoding:: >>> import json >>> def as_complex(dct): ... if '__complex__' in dct: ... return complex(dct['real'], dct['imag']) ... return dct ... >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', ... object_hook=as_complex) (1+2j) >>> from decimal import Decimal >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') True Specializing JSON object encoding:: >>> import json >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] ... raise TypeError(repr(obj) + " is not JSON serializable") ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) '[2.0, 1.0]' >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) '[2.0, 1.0]' Using json.tool from the shell to validate and pretty-print:: $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } $ echo '{ 1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', 'JSONDecoder', 'JSONEncoder', ] __author__ = 'Bob Ippolito ' from .decoder import JSONDecoder from .encoder import JSONEncoder _default_encoder = JSONEncoder( skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, indent=None, separators=None, encoding='utf-8', default=None, ) def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, sort_keys=False, **kw): """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a ``.write()``-supporting file-like object). If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is true (the default), all non-ASCII characters in the output are escaped with ``\uXXXX`` sequences, and the result is a ``str`` instance consisting of ASCII characters only. If ``ensure_ascii`` is false, some chunks written to ``fp`` may be ``unicode`` instances. This usually happens because the input contains unicode strings or the ``encoding`` parameter is used. Unless ``fp.write()`` explicitly understands ``unicode`` (as in ``codecs.getwriter``) this is likely to cause an error. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. Since the default item separator is ``', '``, the output might include trailing whitespace when ``indent`` is specified. You can use ``separators=(',', ': ')`` to avoid this. If ``separators`` is an ``(item_separator, dict_separator)`` tuple then it will be used instead of the default ``(', ', ': ')`` separators. ``(',', ':')`` is the most compact JSON representation. ``encoding`` is the character encoding for str instances, default is UTF-8. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and not sort_keys and not kw): iterable = _default_encoder.iterencode(obj) else: if cls is None: cls = JSONEncoder iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, encoding=encoding, default=default, sort_keys=sort_keys, **kw).iterencode(obj) # could accelerate with writelines in some versions of Python, at # a debuggability cost for chunk in iterable: fp.write(chunk) def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, encoding='utf-8', default=None, sort_keys=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. If ``ensure_ascii`` is false, all non-ASCII characters are not escaped, and the return value may be a ``unicode`` instance. See ``dump`` for details. If ``check_circular`` is false, then the circular reference check for container types will be skipped and a circular reference will result in an ``OverflowError`` (or worse). If ``allow_nan`` is false, then it will be a ``ValueError`` to serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). If ``indent`` is a non-negative integer, then JSON array elements and object members will be pretty-printed with that indent level. An indent level of 0 will only insert newlines. ``None`` is the most compact representation. Since the default item separator is ``', '``, the output might include trailing whitespace when ``indent`` is specified. You can use ``separators=(',', ': ')`` to avoid this. If ``separators`` is an ``(item_separator, dict_separator)`` tuple then it will be used instead of the default ``(', ', ': ')`` separators. ``(',', ':')`` is the most compact JSON representation. ``encoding`` is the character encoding for str instances, default is UTF-8. ``default(obj)`` is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError. If *sort_keys* is true (default: ``False``), then the output of dictionaries will be sorted by key. To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the ``.default()`` method to serialize additional types), specify it with the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. """ # cached encoder if (not skipkeys and ensure_ascii and check_circular and allow_nan and cls is None and indent is None and separators is None and encoding == 'utf-8' and default is None and not sort_keys and not kw): return _default_encoder.encode(obj) if cls is None: cls = JSONEncoder return cls( skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, indent=indent, separators=separators, encoding=encoding, default=default, sort_keys=sort_keys, **kw).encode(obj) _default_decoder = JSONDecoder(encoding=None, object_hook=None, object_pairs_hook=None) def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing a JSON document) to a Python object. If the contents of ``fp`` is encoded with an ASCII based encoding other than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed, and should be wrapped with ``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode`` object and passed to ``loads()`` ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict will remember the order of insertion). If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ return loads(fp.read(), encoding=encoding, cls=cls, object_hook=object_hook, parse_float=parse_float, parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON document) to a Python object. If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name must be specified. Encodings that are not ASCII based (such as UCS-2) are not allowed and should be decoded to ``unicode`` first. ``object_hook`` is an optional function that will be called with the result of any object literal decode (a ``dict``). The return value of ``object_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders (e.g. JSON-RPC class hinting). ``object_pairs_hook`` is an optional function that will be called with the result of any object literal decoded with an ordered list of pairs. The return value of ``object_pairs_hook`` will be used instead of the ``dict``. This feature can be used to implement custom decoders that rely on the order that the key and value pairs are decoded (for example, collections.OrderedDict will remember the order of insertion). If ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. ``parse_float``, if specified, will be called with the string of every JSON float to be decoded. By default this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal). ``parse_int``, if specified, will be called with the string of every JSON int to be decoded. By default this is equivalent to int(num_str). This can be used to use another datatype or parser for JSON integers (e.g. float). ``parse_constant``, if specified, will be called with one of the following strings: -Infinity, Infinity, NaN. This can be used to raise an exception if invalid JSON numbers are encountered. To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` kwarg; otherwise ``JSONDecoder`` is used. """ if (cls is None and encoding is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): return _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: kw['object_hook'] = object_hook if object_pairs_hook is not None: kw['object_pairs_hook'] = object_pairs_hook if parse_float is not None: kw['parse_float'] = parse_float if parse_int is not None: kw['parse_int'] = parse_int if parse_constant is not None: kw['parse_constant'] = parse_constant return cls(encoding=encoding, **kw).decode(s) lib64/python3.6/concurrent/__init__.py000064400000000046152357371720013543 0ustar00# This directory is a Python package. lib64/python3.12/xml/etree/__init__.py000064400000003105152357373430013341 0ustar00# $Id: __init__.py 3375 2008-02-13 08:05:08Z fredrik $ # elementtree package # -------------------------------------------------------------------- # The ElementTree toolkit is # # Copyright (c) 1999-2008 by Fredrik Lundh # # By obtaining, using, and/or copying this software and/or its # associated documentation, you agree that you have read, understood, # and will comply with the following terms and conditions: # # Permission to use, copy, modify, and distribute this software and # its associated documentation for any purpose and without fee is # hereby granted, provided that the above copyright notice appears in # all copies, and that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of # Secret Labs AB or the author not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # OF THIS SOFTWARE. # -------------------------------------------------------------------- # Licensed to PSF under a Contributor Agreement. # See https://www.python.org/psf/license for licensing details. lib64/python3.8/xml/etree/__init__.py000064400000003104152357475310013265 0ustar00# $Id: __init__.py 3375 2008-02-13 08:05:08Z fredrik $ # elementtree package # -------------------------------------------------------------------- # The ElementTree toolkit is # # Copyright (c) 1999-2008 by Fredrik Lundh # # By obtaining, using, and/or copying this software and/or its # associated documentation, you agree that you have read, understood, # and will comply with the following terms and conditions: # # Permission to use, copy, modify, and distribute this software and # its associated documentation for any purpose and without fee is # hereby granted, provided that the above copyright notice appears in # all copies, and that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of # Secret Labs AB or the author not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # OF THIS SOFTWARE. # -------------------------------------------------------------------- # Licensed to PSF under a Contributor Agreement. # See http://www.python.org/psf/license for licensing details. usr/lib64/python3.12/xmlrpc/__init__.py000064400000000046152357523050013547 0ustar00# This directory is a Python package. lib64/python3.6/site-packages/libcomps/__init__.py000064400000000034152357525130015702 0ustar00from ._libpycomps import * usr/lib64/python3.12/sqlite3/__init__.py000064400000004705152357622740013642 0ustar00# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Häring # # This file is part of pysqlite. # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages # arising from the use of this software. # # Permission is granted to anyone to use this software for any purpose, # including commercial applications, and to alter it and redistribute it # freely, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment in the product documentation would be # appreciated but is not required. # 2. Altered source versions must be plainly marked as such, and must not be # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. """ The sqlite3 extension module provides a DB-API 2.0 (PEP 249) compliant interface to the SQLite library, and requires SQLite 3.7.15 or newer. To use the module, start by creating a database Connection object: import sqlite3 cx = sqlite3.connect("test.db") # test.db will be created or opened The special path name ":memory:" can be provided to connect to a transient in-memory database: cx = sqlite3.connect(":memory:") # connect to a database in RAM Once a connection has been established, create a Cursor object and call its execute() method to perform SQL queries: cu = cx.cursor() # create a table cu.execute("create table lang(name, first_appeared)") # insert values into a table cu.execute("insert into lang values (?, ?)", ("C", 1972)) # execute a query and iterate over the result for row in cu.execute("select * from lang"): print(row) cx.close() The sqlite3 module is written by Gerhard Häring . """ from sqlite3.dbapi2 import * from sqlite3.dbapi2 import (_deprecated_names, _deprecated_version_info, _deprecated_version) def __getattr__(name): if name in _deprecated_names: from warnings import warn warn(f"{name} is deprecated and will be removed in Python 3.14", DeprecationWarning, stacklevel=2) return globals()[f"_deprecated_{name}"] raise AttributeError(f"module {__name__!r} has no attribute {name!r}") usr/lib64/python3.8/xml/parsers/__init__.py000064400000000247152357743420014456 0ustar00"""Python interfaces to XML parsers. This package contains one module: expat -- Python wrapper for James Clark's Expat parser, with namespace support. """ lib64/python2.7/test/support/__init__.py000064400000227217152357763270014074 0ustar00"""Supporting definitions for the Python regression tests.""" if __name__ != 'test.support': raise ImportError('test.support must be imported from the test package') import contextlib import errno import fnmatch import functools import gc import socket import stat import sys import os import platform import shutil import warnings import unittest import importlib import UserDict import re import time import struct import sysconfig import types try: import thread except ImportError: thread = None __all__ = ["Error", "TestFailed", "TestDidNotRun", "ResourceDenied", "import_module", "verbose", "use_resources", "max_memuse", "record_original_stdout", "get_original_stdout", "unload", "unlink", "rmtree", "forget", "is_resource_enabled", "requires", "requires_mac_ver", "find_unused_port", "bind_port", "fcmp", "have_unicode", "is_jython", "TESTFN", "HOST", "FUZZ", "SAVEDCWD", "temp_cwd", "findfile", "sortdict", "check_syntax_error", "open_urlresource", "check_warnings", "check_py3k_warnings", "CleanImport", "EnvironmentVarGuard", "captured_output", "captured_stdout", "TransientResource", "transient_internet", "run_with_locale", "set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner", "run_unittest", "run_doctest", "threading_setup", "threading_cleanup", "reap_threads", "start_threads", "cpython_only", "check_impl_detail", "get_attribute", "py3k_bytes", "import_fresh_module", "threading_cleanup", "reap_children", "strip_python_stderr", "IPV6_ENABLED", "run_with_tz", "SuppressCrashReport"] SHORT_TIMEOUT = 30.0 # Added to make backporting from 3.x easier class Error(Exception): """Base class for regression test exceptions.""" class TestFailed(Error): """Test failed.""" class TestDidNotRun(Error): """Test did not run any subtests.""" class ResourceDenied(unittest.SkipTest): """Test skipped because it requested a disallowed resource. This is raised when a test calls requires() for a resource that has not been enabled. It is used to distinguish between expected and unexpected skips. """ @contextlib.contextmanager def _ignore_deprecated_imports(ignore=True): """Context manager to suppress package and module deprecation warnings when importing them. If ignore is False, this context manager has no effect.""" if ignore: with warnings.catch_warnings(): warnings.filterwarnings("ignore", ".+ (module|package)", DeprecationWarning) yield else: yield def import_module(name, deprecated=False): """Import and return the module to be tested, raising SkipTest if it is not available. If deprecated is True, any module or package deprecation messages will be suppressed.""" with _ignore_deprecated_imports(deprecated): try: return importlib.import_module(name) except ImportError, msg: raise unittest.SkipTest(str(msg)) def _save_and_remove_module(name, orig_modules): """Helper function to save and remove a module from sys.modules Raise ImportError if the module can't be imported.""" # try to import the module and raise an error if it can't be imported if name not in sys.modules: __import__(name) del sys.modules[name] for modname in list(sys.modules): if modname == name or modname.startswith(name + '.'): orig_modules[modname] = sys.modules[modname] del sys.modules[modname] def _save_and_block_module(name, orig_modules): """Helper function to save and block a module in sys.modules Return True if the module was in sys.modules, False otherwise.""" saved = True try: orig_modules[name] = sys.modules[name] except KeyError: saved = False sys.modules[name] = None return saved def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): """Imports and returns a module, deliberately bypassing the sys.modules cache and importing a fresh copy of the module. Once the import is complete, the sys.modules cache is restored to its original state. Modules named in fresh are also imported anew if needed by the import. If one of these modules can't be imported, None is returned. Importing of modules named in blocked is prevented while the fresh import takes place. If deprecated is True, any module or package deprecation messages will be suppressed.""" # NOTE: test_heapq, test_json, and test_warnings include extra sanity # checks to make sure that this utility function is working as expected with _ignore_deprecated_imports(deprecated): # Keep track of modules saved for later restoration as well # as those which just need a blocking entry removed orig_modules = {} names_to_remove = [] _save_and_remove_module(name, orig_modules) try: for fresh_name in fresh: _save_and_remove_module(fresh_name, orig_modules) for blocked_name in blocked: if not _save_and_block_module(blocked_name, orig_modules): names_to_remove.append(blocked_name) fresh_module = importlib.import_module(name) except ImportError: fresh_module = None finally: for orig_name, module in orig_modules.items(): sys.modules[orig_name] = module for name_to_remove in names_to_remove: del sys.modules[name_to_remove] return fresh_module def get_attribute(obj, name): """Get an attribute, raising SkipTest if AttributeError is raised.""" try: attribute = getattr(obj, name) except AttributeError: if isinstance(obj, types.ModuleType): msg = "module %r has no attribute %r" % (obj.__name__, name) elif isinstance(obj, types.ClassType): msg = "class %s has no attribute %r" % (obj.__name__, name) elif isinstance(obj, types.InstanceType): msg = "%s instance has no attribute %r" % (obj.__class__.__name__, name) elif isinstance(obj, type): msg = "type object %r has no attribute %r" % (obj.__name__, name) else: msg = "%r object has no attribute %r" % (type(obj).__name__, name) raise unittest.SkipTest(msg) else: return attribute verbose = 1 # Flag set to 0 by regrtest.py use_resources = None # Flag set to [] by regrtest.py max_memuse = 0 # Disable bigmem tests (they will still be run with # small sizes, to make sure they work.) real_max_memuse = 0 failfast = False # _original_stdout is meant to hold stdout at the time regrtest began. # This may be "the real" stdout, or IDLE's emulation of stdout, or whatever. # The point is to have some flavor of stdout the user can actually see. _original_stdout = None def record_original_stdout(stdout): global _original_stdout _original_stdout = stdout def get_original_stdout(): return _original_stdout or sys.stdout def unload(name): try: del sys.modules[name] except KeyError: pass def _force_run(path, func, *args): try: return func(*args) except EnvironmentError as err: if verbose >= 2: print('%s: %s' % (err.__class__.__name__, err)) print('re-run %s%r' % (func.__name__, args)) os.chmod(path, stat.S_IRWXU) return func(*args) if sys.platform.startswith("win"): def _waitfor(func, pathname, waitall=False): # Perform the operation func(pathname) # Now setup the wait loop if waitall: dirname = pathname else: dirname, name = os.path.split(pathname) dirname = dirname or '.' # Check for `pathname` to be removed from the filesystem. # The exponential backoff of the timeout amounts to a total # of ~1 second after which the deletion is probably an error # anyway. # Testing on an i7@4.3GHz shows that usually only 1 iteration is # required when contention occurs. timeout = 0.001 while timeout < 1.0: # Note we are only testing for the existence of the file(s) in # the contents of the directory regardless of any security or # access rights. If we have made it this far, we have sufficient # permissions to do that much using Python's equivalent of the # Windows API FindFirstFile. # Other Windows APIs can fail or give incorrect results when # dealing with files that are pending deletion. L = os.listdir(dirname) if not (L if waitall else name in L): return # Increase the timeout and try again time.sleep(timeout) timeout *= 2 warnings.warn('tests may fail, delete still pending for ' + pathname, RuntimeWarning, stacklevel=4) def _unlink(filename): _waitfor(os.unlink, filename) def _rmdir(dirname): _waitfor(os.rmdir, dirname) def _rmtree(path): def _rmtree_inner(path): for name in _force_run(path, os.listdir, path): fullname = os.path.join(path, name) if os.path.isdir(fullname): _waitfor(_rmtree_inner, fullname, waitall=True) _force_run(fullname, os.rmdir, fullname) else: _force_run(fullname, os.unlink, fullname) _waitfor(_rmtree_inner, path, waitall=True) _waitfor(lambda p: _force_run(p, os.rmdir, p), path) else: _unlink = os.unlink _rmdir = os.rmdir def _rmtree(path): try: shutil.rmtree(path) return except EnvironmentError: pass def _rmtree_inner(path): for name in _force_run(path, os.listdir, path): fullname = os.path.join(path, name) try: mode = os.lstat(fullname).st_mode except EnvironmentError: mode = 0 if stat.S_ISDIR(mode): _rmtree_inner(fullname) _force_run(path, os.rmdir, fullname) else: _force_run(path, os.unlink, fullname) _rmtree_inner(path) os.rmdir(path) def unlink(filename): try: _unlink(filename) except OSError as exc: if exc.errno not in (errno.ENOENT, errno.ENOTDIR): raise def rmdir(dirname): try: _rmdir(dirname) except OSError as error: # The directory need not exist. if error.errno != errno.ENOENT: raise def rmtree(path): try: _rmtree(path) except OSError, e: # Unix returns ENOENT, Windows returns ESRCH. if e.errno not in (errno.ENOENT, errno.ESRCH): raise def forget(modname): '''"Forget" a module was ever imported by removing it from sys.modules and deleting any .pyc and .pyo files.''' unload(modname) for dirname in sys.path: unlink(os.path.join(dirname, modname + os.extsep + 'pyc')) # Deleting the .pyo file cannot be within the 'try' for the .pyc since # the chance exists that there is no .pyc (and thus the 'try' statement # is exited) but there is a .pyo file. unlink(os.path.join(dirname, modname + os.extsep + 'pyo')) # Check whether a gui is actually available def _is_gui_available(): if hasattr(_is_gui_available, 'result'): return _is_gui_available.result reason = None if sys.platform.startswith('win'): # if Python is running as a service (such as the buildbot service), # gui interaction may be disallowed import ctypes import ctypes.wintypes UOI_FLAGS = 1 WSF_VISIBLE = 0x0001 class USEROBJECTFLAGS(ctypes.Structure): _fields_ = [("fInherit", ctypes.wintypes.BOOL), ("fReserved", ctypes.wintypes.BOOL), ("dwFlags", ctypes.wintypes.DWORD)] dll = ctypes.windll.user32 h = dll.GetProcessWindowStation() if not h: raise ctypes.WinError() uof = USEROBJECTFLAGS() needed = ctypes.wintypes.DWORD() res = dll.GetUserObjectInformationW(h, UOI_FLAGS, ctypes.byref(uof), ctypes.sizeof(uof), ctypes.byref(needed)) if not res: raise ctypes.WinError() if not bool(uof.dwFlags & WSF_VISIBLE): reason = "gui not available (WSF_VISIBLE flag not set)" elif sys.platform == 'darwin': # The Aqua Tk implementations on OS X can abort the process if # being called in an environment where a window server connection # cannot be made, for instance when invoked by a buildbot or ssh # process not running under the same user id as the current console # user. To avoid that, raise an exception if the window manager # connection is not available. from ctypes import cdll, c_int, pointer, Structure from ctypes.util import find_library app_services = cdll.LoadLibrary(find_library("ApplicationServices")) if app_services.CGMainDisplayID() == 0: reason = "gui tests cannot run without OS X window manager" else: class ProcessSerialNumber(Structure): _fields_ = [("highLongOfPSN", c_int), ("lowLongOfPSN", c_int)] psn = ProcessSerialNumber() psn_p = pointer(psn) if ( (app_services.GetCurrentProcess(psn_p) < 0) or (app_services.SetFrontProcess(psn_p) < 0) ): reason = "cannot run without OS X gui process" # check on every platform whether tkinter can actually do anything if not reason: try: from Tkinter import Tk root = Tk() root.withdraw() root.update() root.destroy() except Exception as e: err_string = str(e) if len(err_string) > 50: err_string = err_string[:50] + ' [...]' reason = 'Tk unavailable due to {}: {}'.format(type(e).__name__, err_string) _is_gui_available.reason = reason _is_gui_available.result = not reason return _is_gui_available.result def is_resource_enabled(resource): """Test whether a resource is enabled. Known resources are set by regrtest.py. If not running under regrtest.py, all resources are assumed enabled unless use_resources has been set. """ return use_resources is None or resource in use_resources def requires(resource, msg=None): """Raise ResourceDenied if the specified resource is not available.""" if not is_resource_enabled(resource): if msg is None: msg = "Use of the `%s' resource not enabled" % resource raise ResourceDenied(msg) if resource == 'gui' and not _is_gui_available(): raise ResourceDenied(_is_gui_available.reason) def requires_mac_ver(*min_version): """Decorator raising SkipTest if the OS is Mac OS X and the OS X version if less than min_version. For example, @requires_mac_ver(10, 5) raises SkipTest if the OS X version is lesser than 10.5. """ def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): if sys.platform == 'darwin': version_txt = platform.mac_ver()[0] try: version = tuple(map(int, version_txt.split('.'))) except ValueError: pass else: if version < min_version: min_version_txt = '.'.join(map(str, min_version)) raise unittest.SkipTest( "Mac OS X %s or higher required, not %s" % (min_version_txt, version_txt)) return func(*args, **kw) wrapper.min_version = min_version return wrapper return decorator # Don't use "localhost", since resolving it uses the DNS under recent # Windows versions (see issue #18792). HOST = "127.0.0.1" HOSTv6 = "::1" def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM): """Returns an unused port that should be suitable for binding. This is achieved by creating a temporary socket with the same family and type as the 'sock' parameter (default is AF_INET, SOCK_STREAM), and binding it to the specified host address (defaults to 0.0.0.0) with the port set to 0, eliciting an unused ephemeral port from the OS. The temporary socket is then closed and deleted, and the ephemeral port is returned. Either this method or bind_port() should be used for any tests where a server socket needs to be bound to a particular port for the duration of the test. Which one to use depends on whether the calling code is creating a python socket, or if an unused port needs to be provided in a constructor or passed to an external program (i.e. the -accept argument to openssl's s_server mode). Always prefer bind_port() over find_unused_port() where possible. Hard coded ports should *NEVER* be used. As soon as a server socket is bound to a hard coded port, the ability to run multiple instances of the test simultaneously on the same host is compromised, which makes the test a ticking time bomb in a buildbot environment. On Unix buildbots, this may simply manifest as a failed test, which can be recovered from without intervention in most cases, but on Windows, the entire python process can completely and utterly wedge, requiring someone to log in to the buildbot and manually kill the affected process. (This is easy to reproduce on Windows, unfortunately, and can be traced to the SO_REUSEADDR socket option having different semantics on Windows versus Unix/Linux. On Unix, you can't have two AF_INET SOCK_STREAM sockets bind, listen and then accept connections on identical host/ports. An EADDRINUSE socket.error will be raised at some point (depending on the platform and the order bind and listen were called on each socket). However, on Windows, if SO_REUSEADDR is set on the sockets, no EADDRINUSE will ever be raised when attempting to bind two identical host/ports. When accept() is called on each socket, the second caller's process will steal the port from the first caller, leaving them both in an awkwardly wedged state where they'll no longer respond to any signals or graceful kills, and must be forcibly killed via OpenProcess()/TerminateProcess(). The solution on Windows is to use the SO_EXCLUSIVEADDRUSE socket option instead of SO_REUSEADDR, which effectively affords the same semantics as SO_REUSEADDR on Unix. Given the propensity of Unix developers in the Open Source world compared to Windows ones, this is a common mistake. A quick look over OpenSSL's 0.9.8g source shows that they use SO_REUSEADDR when openssl.exe is called with the 's_server' option, for example. See http://bugs.python.org/issue2550 for more info. The following site also has a very thorough description about the implications of both REUSEADDR and EXCLUSIVEADDRUSE on Windows: http://msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx) XXX: although this approach is a vast improvement on previous attempts to elicit unused ports, it rests heavily on the assumption that the ephemeral port returned to us by the OS won't immediately be dished back out to some other process when we close and delete our temporary socket but before our calling code has a chance to bind the returned port. We can deal with this issue if/when we come across it.""" tempsock = socket.socket(family, socktype) port = bind_port(tempsock) tempsock.close() del tempsock return port def bind_port(sock, host=HOST): """Bind the socket to a free port and return the port number. Relies on ephemeral ports in order to ensure we are using an unbound port. This is important as many tests may be running simultaneously, especially in a buildbot environment. This method raises an exception if the sock.family is AF_INET and sock.type is SOCK_STREAM, *and* the socket has SO_REUSEADDR or SO_REUSEPORT set on it. Tests should *never* set these socket options for TCP/IP sockets. The only case for setting these options is testing multicasting via multiple UDP sockets. Additionally, if the SO_EXCLUSIVEADDRUSE socket option is available (i.e. on Windows), it will be set on the socket. This will prevent anyone else from bind()'ing to our host/port for the duration of the test. """ if sock.family == socket.AF_INET and sock.type == socket.SOCK_STREAM: if hasattr(socket, 'SO_REUSEADDR'): if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 1: raise TestFailed("tests should never set the SO_REUSEADDR " \ "socket option on TCP/IP sockets!") if hasattr(socket, 'SO_REUSEPORT'): try: if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 1: raise TestFailed("tests should never set the SO_REUSEPORT " \ "socket option on TCP/IP sockets!") except EnvironmentError: # Python's socket module was compiled using modern headers # thus defining SO_REUSEPORT but this process is running # under an older kernel that does not support SO_REUSEPORT. pass if hasattr(socket, 'SO_EXCLUSIVEADDRUSE'): sock.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1) sock.bind((host, 0)) port = sock.getsockname()[1] return port def _is_ipv6_enabled(): """Check whether IPv6 is enabled on this host.""" if socket.has_ipv6: sock = None try: sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) sock.bind((HOSTv6, 0)) return True except socket.error: pass finally: if sock: sock.close() return False IPV6_ENABLED = _is_ipv6_enabled() def system_must_validate_cert(f): """Skip the test on TLS certificate validation failures.""" @functools.wraps(f) def dec(*args, **kwargs): try: f(*args, **kwargs) except IOError as e: if "CERTIFICATE_VERIFY_FAILED" in str(e): raise unittest.SkipTest("system does not contain " "necessary certificates") raise return dec FUZZ = 1e-6 def fcmp(x, y): # fuzzy comparison function if isinstance(x, float) or isinstance(y, float): try: fuzz = (abs(x) + abs(y)) * FUZZ if abs(x-y) <= fuzz: return 0 except: pass elif type(x) == type(y) and isinstance(x, (tuple, list)): for i in range(min(len(x), len(y))): outcome = fcmp(x[i], y[i]) if outcome != 0: return outcome return (len(x) > len(y)) - (len(x) < len(y)) return (x > y) - (x < y) # A constant likely larger than the underlying OS pipe buffer size, to # make writes blocking. # Windows limit seems to be around 512 B, and many Unix kernels have a # 64 KiB pipe buffer size or 16 * PAGE_SIZE: take a few megs to be sure. # (see issue #17835 for a discussion of this number). PIPE_MAX_SIZE = 4 * 1024 * 1024 + 1 # A constant likely larger than the underlying OS socket buffer size, to make # writes blocking. # The socket buffer sizes can usually be tuned system-wide (e.g. through sysctl # on Linux), or on a per-socket basis (SO_SNDBUF/SO_RCVBUF). See issue #18643 # for a discussion of this number). SOCK_MAX_SIZE = 16 * 1024 * 1024 + 1 is_jython = sys.platform.startswith('java') try: unicode have_unicode = True except NameError: have_unicode = False requires_unicode = unittest.skipUnless(have_unicode, 'no unicode support') def u(s): return unicode(s, 'unicode-escape') # FS_NONASCII: non-ASCII Unicode character encodable by # sys.getfilesystemencoding(), or None if there is no such character. FS_NONASCII = None if have_unicode: for character in ( # First try printable and common characters to have a readable filename. # For each character, the encoding list are just example of encodings able # to encode the character (the list is not exhaustive). # U+00E6 (Latin Small Letter Ae): cp1252, iso-8859-1 unichr(0x00E6), # U+0130 (Latin Capital Letter I With Dot Above): cp1254, iso8859_3 unichr(0x0130), # U+0141 (Latin Capital Letter L With Stroke): cp1250, cp1257 unichr(0x0141), # U+03C6 (Greek Small Letter Phi): cp1253 unichr(0x03C6), # U+041A (Cyrillic Capital Letter Ka): cp1251 unichr(0x041A), # U+05D0 (Hebrew Letter Alef): Encodable to cp424 unichr(0x05D0), # U+060C (Arabic Comma): cp864, cp1006, iso8859_6, mac_arabic unichr(0x060C), # U+062A (Arabic Letter Teh): cp720 unichr(0x062A), # U+0E01 (Thai Character Ko Kai): cp874 unichr(0x0E01), # Then try more "special" characters. "special" because they may be # interpreted or displayed differently depending on the exact locale # encoding and the font. # U+00A0 (No-Break Space) unichr(0x00A0), # U+20AC (Euro Sign) unichr(0x20AC), ): try: # In Windows, 'mbcs' is used, and encode() returns '?' # for characters missing in the ANSI codepage if character.encode(sys.getfilesystemencoding())\ .decode(sys.getfilesystemencoding())\ != character: raise UnicodeError except UnicodeError: pass else: FS_NONASCII = character break # Filename used for testing if os.name == 'java': # Jython disallows @ in module names TESTFN = '$test' elif os.name == 'riscos': TESTFN = 'testfile' else: TESTFN = '@test' # Unicode name only used if TEST_FN_ENCODING exists for the platform. if have_unicode: # Assuming sys.getfilesystemencoding()!=sys.getdefaultencoding() # TESTFN_UNICODE is a filename that can be encoded using the # file system encoding, but *not* with the default (ascii) encoding if isinstance('', unicode): # python -U # XXX perhaps unicode() should accept Unicode strings? TESTFN_UNICODE = "@test-\xe0\xf2" else: # 2 latin characters. TESTFN_UNICODE = unicode("@test-\xe0\xf2", "latin-1") TESTFN_ENCODING = sys.getfilesystemencoding() # TESTFN_UNENCODABLE is a filename that should *not* be # able to be encoded by *either* the default or filesystem encoding. # This test really only makes sense on Windows NT platforms # which have special Unicode support in posixmodule. if (not hasattr(sys, "getwindowsversion") or sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME TESTFN_UNENCODABLE = None else: # Japanese characters (I think - from bug 846133) TESTFN_UNENCODABLE = eval('u"@test-\u5171\u6709\u3055\u308c\u308b"') try: # XXX - Note - should be using TESTFN_ENCODING here - but for # Windows, "mbcs" currently always operates as if in # errors=ignore' mode - hence we get '?' characters rather than # the exception. 'Latin1' operates as we expect - ie, fails. # See [ 850997 ] mbcs encoding ignores errors TESTFN_UNENCODABLE.encode("Latin1") except UnicodeEncodeError: pass else: print \ 'WARNING: The filename %r CAN be encoded by the filesystem. ' \ 'Unicode filename tests may not be effective' \ % TESTFN_UNENCODABLE # Disambiguate TESTFN for parallel testing, while letting it remain a valid # module name. TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid()) # Define the URL of a dedicated HTTP server for the network tests. # The URL must use clear-text HTTP: no redirection to encrypted HTTPS. TEST_HTTP_URL = "http://www.pythontest.net" # Save the initial cwd SAVEDCWD = os.getcwd() @contextlib.contextmanager def temp_dir(path=None, quiet=False): """Return a context manager that creates a temporary directory. Arguments: path: the directory to create temporarily. If omitted or None, defaults to creating a temporary directory using tempfile.mkdtemp. quiet: if False (the default), the context manager raises an exception on error. Otherwise, if the path is specified and cannot be created, only a warning is issued. """ dir_created = False if path is None: import tempfile path = tempfile.mkdtemp() dir_created = True path = os.path.realpath(path) else: if (have_unicode and isinstance(path, unicode) and not os.path.supports_unicode_filenames): try: path = path.encode(sys.getfilesystemencoding() or 'ascii') except UnicodeEncodeError: if not quiet: raise unittest.SkipTest('unable to encode the cwd name with ' 'the filesystem encoding.') try: os.mkdir(path) dir_created = True except OSError: if not quiet: raise warnings.warn('tests may fail, unable to create temp dir: ' + path, RuntimeWarning, stacklevel=3) if dir_created: pid = os.getpid() try: yield path finally: # In case the process forks, let only the parent remove the # directory. The child has a diffent process id. (bpo-30028) if dir_created and pid == os.getpid(): rmtree(path) @contextlib.contextmanager def change_cwd(path, quiet=False): """Return a context manager that changes the current working directory. Arguments: path: the directory to use as the temporary current working directory. quiet: if False (the default), the context manager raises an exception on error. Otherwise, it issues only a warning and keeps the current working directory the same. """ saved_dir = os.getcwd() try: os.chdir(path) except OSError: if not quiet: raise warnings.warn('tests may fail, unable to change CWD to: ' + path, RuntimeWarning, stacklevel=3) try: yield os.getcwd() finally: os.chdir(saved_dir) @contextlib.contextmanager def temp_cwd(name='tempcwd', quiet=False): """ Context manager that temporarily creates and changes the CWD. The function temporarily changes the current working directory after creating a temporary directory in the current directory with name *name*. If *name* is None, the temporary directory is created using tempfile.mkdtemp. If *quiet* is False (default) and it is not possible to create or change the CWD, an error is raised. If *quiet* is True, only a warning is raised and the original CWD is used. """ with temp_dir(path=name, quiet=quiet) as temp_path: with change_cwd(temp_path, quiet=quiet) as cwd_dir: yield cwd_dir # TEST_HOME_DIR refers to the top level directory of the "test" package # that contains Python's regression test suite TEST_SUPPORT_DIR = os.path.dirname(os.path.abspath(__file__)) TEST_HOME_DIR = os.path.dirname(TEST_SUPPORT_DIR) # TEST_DATA_DIR is used as a target download location for remote resources TEST_DATA_DIR = os.path.join(TEST_HOME_DIR, "data") def findfile(file, subdir=None): """Try to find a file on sys.path and the working directory. If it is not found the argument passed to the function is returned (this does not necessarily signal failure; could still be the legitimate path).""" if os.path.isabs(file): return file if subdir is not None: file = os.path.join(subdir, file) path = [TEST_HOME_DIR] + sys.path for dn in path: fn = os.path.join(dn, file) if os.path.exists(fn): return fn return file def sortdict(dict): "Like repr(dict), but in sorted order." items = dict.items() items.sort() reprpairs = ["%r: %r" % pair for pair in items] withcommas = ", ".join(reprpairs) return "{%s}" % withcommas def make_bad_fd(): """ Create an invalid file descriptor by opening and closing a file and return its fd. """ file = open(TESTFN, "wb") try: return file.fileno() finally: file.close() unlink(TESTFN) def check_syntax_error(testcase, statement, errtext='', lineno=None, offset=None): with testcase.assertRaisesRegexp(SyntaxError, errtext) as cm: compile(statement, '', 'exec') err = cm.exception if lineno is not None: testcase.assertEqual(err.lineno, lineno) if offset is not None: testcase.assertEqual(err.offset, offset) def open_urlresource(url, check=None): import urlparse, urllib2 filename = urlparse.urlparse(url)[2].split('/')[-1] # '/': it's URL! fn = os.path.join(TEST_DATA_DIR, filename) def check_valid_file(fn): f = open(fn) if check is None: return f elif check(f): f.seek(0) return f f.close() if os.path.exists(fn): f = check_valid_file(fn) if f is not None: return f unlink(fn) # Verify the requirement before downloading the file requires('urlfetch') print >> get_original_stdout(), '\tfetching %s ...' % url f = urllib2.urlopen(url, timeout=15) try: with open(fn, "wb") as out: s = f.read() while s: out.write(s) s = f.read() finally: f.close() f = check_valid_file(fn) if f is not None: return f raise TestFailed('invalid resource "%s"' % fn) class WarningsRecorder(object): """Convenience wrapper for the warnings list returned on entry to the warnings.catch_warnings() context manager. """ def __init__(self, warnings_list): self._warnings = warnings_list self._last = 0 def __getattr__(self, attr): if len(self._warnings) > self._last: return getattr(self._warnings[-1], attr) elif attr in warnings.WarningMessage._WARNING_DETAILS: return None raise AttributeError("%r has no attribute %r" % (self, attr)) @property def warnings(self): return self._warnings[self._last:] def reset(self): self._last = len(self._warnings) def _filterwarnings(filters, quiet=False): """Catch the warnings, then check if all the expected warnings have been raised and re-raise unexpected warnings. If 'quiet' is True, only re-raise the unexpected warnings. """ # Clear the warning registry of the calling module # in order to re-raise the warnings. frame = sys._getframe(2) registry = frame.f_globals.get('__warningregistry__') if registry: registry.clear() with warnings.catch_warnings(record=True) as w: # Set filter "always" to record all warnings. Because # test_warnings swap the module, we need to look up in # the sys.modules dictionary. sys.modules['warnings'].simplefilter("always") yield WarningsRecorder(w) # Filter the recorded warnings reraise = [warning.message for warning in w] missing = [] for msg, cat in filters: seen = False for exc in reraise[:]: message = str(exc) # Filter out the matching messages if (re.match(msg, message, re.I) and issubclass(exc.__class__, cat)): seen = True reraise.remove(exc) if not seen and not quiet: # This filter caught nothing missing.append((msg, cat.__name__)) if reraise: raise AssertionError("unhandled warning %r" % reraise[0]) if missing: raise AssertionError("filter (%r, %s) did not catch any warning" % missing[0]) @contextlib.contextmanager def check_warnings(*filters, **kwargs): """Context manager to silence warnings. Accept 2-tuples as positional arguments: ("message regexp", WarningCategory) Optional argument: - if 'quiet' is True, it does not fail if a filter catches nothing (default True without argument, default False if some filters are defined) Without argument, it defaults to: check_warnings(("", Warning), quiet=True) """ quiet = kwargs.get('quiet') if not filters: filters = (("", Warning),) # Preserve backward compatibility if quiet is None: quiet = True return _filterwarnings(filters, quiet) @contextlib.contextmanager def check_py3k_warnings(*filters, **kwargs): """Context manager to silence py3k warnings. Accept 2-tuples as positional arguments: ("message regexp", WarningCategory) Optional argument: - if 'quiet' is True, it does not fail if a filter catches nothing (default False) Without argument, it defaults to: check_py3k_warnings(("", DeprecationWarning), quiet=False) """ if sys.py3kwarning: if not filters: filters = (("", DeprecationWarning),) else: # It should not raise any py3k warning filters = () return _filterwarnings(filters, kwargs.get('quiet')) class CleanImport(object): """Context manager to force import to return a new module reference. This is useful for testing module-level behaviours, such as the emission of a DeprecationWarning on import. Use like this: with CleanImport("foo"): importlib.import_module("foo") # new reference """ def __init__(self, *module_names): self.original_modules = sys.modules.copy() for module_name in module_names: if module_name in sys.modules: module = sys.modules[module_name] # It is possible that module_name is just an alias for # another module (e.g. stub for modules renamed in 3.x). # In that case, we also need delete the real module to clear # the import cache. if module.__name__ != module_name: del sys.modules[module.__name__] del sys.modules[module_name] def __enter__(self): return self def __exit__(self, *ignore_exc): sys.modules.update(self.original_modules) class EnvironmentVarGuard(UserDict.DictMixin): """Class to help protect the environment variable properly. Can be used as a context manager.""" def __init__(self): self._environ = os.environ self._changed = {} def __getitem__(self, envvar): return self._environ[envvar] def __setitem__(self, envvar, value): # Remember the initial value on the first access if envvar not in self._changed: self._changed[envvar] = self._environ.get(envvar) self._environ[envvar] = value def __delitem__(self, envvar): # Remember the initial value on the first access if envvar not in self._changed: self._changed[envvar] = self._environ.get(envvar) if envvar in self._environ: del self._environ[envvar] def keys(self): return self._environ.keys() def set(self, envvar, value): self[envvar] = value def unset(self, envvar): del self[envvar] def __enter__(self): return self def __exit__(self, *ignore_exc): for (k, v) in self._changed.items(): if v is None: if k in self._environ: del self._environ[k] else: self._environ[k] = v os.environ = self._environ class DirsOnSysPath(object): """Context manager to temporarily add directories to sys.path. This makes a copy of sys.path, appends any directories given as positional arguments, then reverts sys.path to the copied settings when the context ends. Note that *all* sys.path modifications in the body of the context manager, including replacement of the object, will be reverted at the end of the block. """ def __init__(self, *paths): self.original_value = sys.path[:] self.original_object = sys.path sys.path.extend(paths) def __enter__(self): return self def __exit__(self, *ignore_exc): sys.path = self.original_object sys.path[:] = self.original_value class TransientResource(object): """Raise ResourceDenied if an exception is raised while the context manager is in effect that matches the specified exception and attributes.""" def __init__(self, exc, **kwargs): self.exc = exc self.attrs = kwargs def __enter__(self): return self def __exit__(self, type_=None, value=None, traceback=None): """If type_ is a subclass of self.exc and value has attributes matching self.attrs, raise ResourceDenied. Otherwise let the exception propagate (if any).""" if type_ is not None and issubclass(self.exc, type_): for attr, attr_value in self.attrs.iteritems(): if not hasattr(value, attr): break if getattr(value, attr) != attr_value: break else: raise ResourceDenied("an optional resource is not available") @contextlib.contextmanager def transient_internet(resource_name, timeout=30.0, errnos=()): """Return a context manager that raises ResourceDenied when various issues with the Internet connection manifest themselves as exceptions.""" default_errnos = [ ('ECONNREFUSED', 111), ('ECONNRESET', 104), ('EHOSTUNREACH', 113), ('ENETUNREACH', 101), ('ETIMEDOUT', 110), # socket.create_connection() fails randomly with # EADDRNOTAVAIL on Travis CI. ('EADDRNOTAVAIL', 99), ] default_gai_errnos = [ ('EAI_AGAIN', -3), ('EAI_FAIL', -4), ('EAI_NONAME', -2), ('EAI_NODATA', -5), # Windows defines EAI_NODATA as 11001 but idiotic getaddrinfo() # implementation actually returns WSANO_DATA i.e. 11004. ('WSANO_DATA', 11004), ] denied = ResourceDenied("Resource '%s' is not available" % resource_name) captured_errnos = errnos gai_errnos = [] if not captured_errnos: captured_errnos = [getattr(errno, name, num) for (name, num) in default_errnos] gai_errnos = [getattr(socket, name, num) for (name, num) in default_gai_errnos] def filter_error(err): n = getattr(err, 'errno', None) if (isinstance(err, socket.timeout) or (isinstance(err, socket.gaierror) and n in gai_errnos) or n in captured_errnos): if not verbose: sys.stderr.write(denied.args[0] + "\n") raise denied old_timeout = socket.getdefaulttimeout() try: if timeout is not None: socket.setdefaulttimeout(timeout) yield except IOError as err: # urllib can wrap original socket errors multiple times (!), we must # unwrap to get at the original error. while True: a = err.args if len(a) >= 1 and isinstance(a[0], IOError): err = a[0] # The error can also be wrapped as args[1]: # except socket.error as msg: # raise IOError('socket error', msg).with_traceback(sys.exc_info()[2]) elif len(a) >= 2 and isinstance(a[1], IOError): err = a[1] else: break filter_error(err) raise # XXX should we catch generic exceptions and look for their # __cause__ or __context__? finally: socket.setdefaulttimeout(old_timeout) @contextlib.contextmanager def captured_output(stream_name): """Return a context manager used by captured_stdout and captured_stdin that temporarily replaces the sys stream *stream_name* with a StringIO.""" import StringIO orig_stdout = getattr(sys, stream_name) setattr(sys, stream_name, StringIO.StringIO()) try: yield getattr(sys, stream_name) finally: setattr(sys, stream_name, orig_stdout) def captured_stdout(): """Capture the output of sys.stdout: with captured_stdout() as s: print "hello" self.assertEqual(s.getvalue(), "hello") """ return captured_output("stdout") def captured_stderr(): return captured_output("stderr") def captured_stdin(): return captured_output("stdin") def gc_collect(): """Force as many objects as possible to be collected. In non-CPython implementations of Python, this is needed because timely deallocation is not guaranteed by the garbage collector. (Even in CPython this can be the case in case of reference cycles.) This means that __del__ methods may be called later than expected and weakrefs may remain alive for longer than expected. This function tries its best to force all garbage objects to disappear. """ gc.collect() if is_jython: time.sleep(0.1) gc.collect() gc.collect() _header = '2P' if hasattr(sys, "gettotalrefcount"): _header = '2P' + _header _vheader = _header + 'P' def calcobjsize(fmt): return struct.calcsize(_header + fmt + '0P') def calcvobjsize(fmt): return struct.calcsize(_vheader + fmt + '0P') _TPFLAGS_HAVE_GC = 1<<14 _TPFLAGS_HEAPTYPE = 1<<9 def check_sizeof(test, o, size): import _testcapi result = sys.getsizeof(o) # add GC header size if ((type(o) == type) and (o.__flags__ & _TPFLAGS_HEAPTYPE) or\ ((type(o) != type) and (type(o).__flags__ & _TPFLAGS_HAVE_GC))): size += _testcapi.SIZEOF_PYGC_HEAD msg = 'wrong size for %s: got %d, expected %d' \ % (type(o), result, size) test.assertEqual(result, size, msg) #======================================================================= # Decorator for running a function in a different locale, correctly resetting # it afterwards. def run_with_locale(catstr, *locales): def decorator(func): def inner(*args, **kwds): try: import locale category = getattr(locale, catstr) orig_locale = locale.setlocale(category) except AttributeError: # if the test author gives us an invalid category string raise except: # cannot retrieve original locale, so do nothing locale = orig_locale = None else: for loc in locales: try: locale.setlocale(category, loc) break except: pass # now run the function, resetting the locale on exceptions try: return func(*args, **kwds) finally: if locale and orig_locale: locale.setlocale(category, orig_locale) inner.func_name = func.func_name inner.__doc__ = func.__doc__ return inner return decorator #======================================================================= # Decorator for running a function in a specific timezone, correctly # resetting it afterwards. def run_with_tz(tz): def decorator(func): def inner(*args, **kwds): try: tzset = time.tzset except AttributeError: raise unittest.SkipTest("tzset required") if 'TZ' in os.environ: orig_tz = os.environ['TZ'] else: orig_tz = None os.environ['TZ'] = tz tzset() # now run the function, resetting the tz on exceptions try: return func(*args, **kwds) finally: if orig_tz is None: del os.environ['TZ'] else: os.environ['TZ'] = orig_tz time.tzset() inner.__name__ = func.__name__ inner.__doc__ = func.__doc__ return inner return decorator #======================================================================= # Big-memory-test support. Separate from 'resources' because memory use should be configurable. # Some handy shorthands. Note that these are used for byte-limits as well # as size-limits, in the various bigmem tests _1M = 1024*1024 _1G = 1024 * _1M _2G = 2 * _1G _4G = 4 * _1G MAX_Py_ssize_t = sys.maxsize def set_memlimit(limit): global max_memuse global real_max_memuse sizes = { 'k': 1024, 'm': _1M, 'g': _1G, 't': 1024*_1G, } m = re.match(r'(\d+(\.\d+)?) (K|M|G|T)b?$', limit, re.IGNORECASE | re.VERBOSE) if m is None: raise ValueError('Invalid memory limit %r' % (limit,)) memlimit = int(float(m.group(1)) * sizes[m.group(3).lower()]) real_max_memuse = memlimit if memlimit > MAX_Py_ssize_t: memlimit = MAX_Py_ssize_t if memlimit < _2G - 1: raise ValueError('Memory limit %r too low to be useful' % (limit,)) max_memuse = memlimit def bigmemtest(minsize, memuse, overhead=5*_1M): """Decorator for bigmem tests. 'minsize' is the minimum useful size for the test (in arbitrary, test-interpreted units.) 'memuse' is the number of 'bytes per size' for the test, or a good estimate of it. 'overhead' specifies fixed overhead, independent of the testsize, and defaults to 5Mb. The decorator tries to guess a good value for 'size' and passes it to the decorated test function. If minsize * memuse is more than the allowed memory use (as defined by max_memuse), the test is skipped. Otherwise, minsize is adjusted upward to use up to max_memuse. """ def decorator(f): def wrapper(self): if not max_memuse: # If max_memuse is 0 (the default), # we still want to run the tests with size set to a few kb, # to make sure they work. We still want to avoid using # too much memory, though, but we do that noisily. maxsize = 5147 self.assertFalse(maxsize * memuse + overhead > 20 * _1M) else: maxsize = int((max_memuse - overhead) / memuse) if maxsize < minsize: # Really ought to print 'test skipped' or something if verbose: sys.stderr.write("Skipping %s because of memory " "constraint\n" % (f.__name__,)) return # Try to keep some breathing room in memory use maxsize = max(maxsize - 50 * _1M, minsize) return f(self, maxsize) wrapper.minsize = minsize wrapper.memuse = memuse wrapper.overhead = overhead return wrapper return decorator def precisionbigmemtest(size, memuse, overhead=5*_1M, dry_run=True): def decorator(f): def wrapper(self): if not real_max_memuse: maxsize = 5147 else: maxsize = size if ((real_max_memuse or not dry_run) and real_max_memuse < maxsize * memuse): if verbose: sys.stderr.write("Skipping %s because of memory " "constraint\n" % (f.__name__,)) return return f(self, maxsize) wrapper.size = size wrapper.memuse = memuse wrapper.overhead = overhead return wrapper return decorator def bigaddrspacetest(f): """Decorator for tests that fill the address space.""" def wrapper(self): if max_memuse < MAX_Py_ssize_t: if verbose: sys.stderr.write("Skipping %s because of memory " "constraint\n" % (f.__name__,)) else: return f(self) return wrapper #======================================================================= # unittest integration. class BasicTestRunner: def run(self, test): result = unittest.TestResult() test(result) return result def _id(obj): return obj def requires_resource(resource): if resource == 'gui' and not _is_gui_available(): return unittest.skip(_is_gui_available.reason) if is_resource_enabled(resource): return _id else: return unittest.skip("resource {0!r} is not enabled".format(resource)) def cpython_only(test): """ Decorator for tests only applicable on CPython. """ return impl_detail(cpython=True)(test) def impl_detail(msg=None, **guards): if check_impl_detail(**guards): return _id if msg is None: guardnames, default = _parse_guards(guards) if default: msg = "implementation detail not available on {0}" else: msg = "implementation detail specific to {0}" guardnames = sorted(guardnames.keys()) msg = msg.format(' or '.join(guardnames)) return unittest.skip(msg) def _parse_guards(guards): # Returns a tuple ({platform_name: run_me}, default_value) if not guards: return ({'cpython': True}, False) is_true = guards.values()[0] assert guards.values() == [is_true] * len(guards) # all True or all False return (guards, not is_true) # Use the following check to guard CPython's implementation-specific tests -- # or to run them only on the implementation(s) guarded by the arguments. def check_impl_detail(**guards): """This function returns True or False depending on the host platform. Examples: if check_impl_detail(): # only on CPython (default) if check_impl_detail(jython=True): # only on Jython if check_impl_detail(cpython=False): # everywhere except on CPython """ guards, default = _parse_guards(guards) return guards.get(platform.python_implementation().lower(), default) def _filter_suite(suite, pred): """Recursively filter test cases in a suite based on a predicate.""" newtests = [] for test in suite._tests: if isinstance(test, unittest.TestSuite): _filter_suite(test, pred) newtests.append(test) else: if pred(test): newtests.append(test) suite._tests = newtests def _run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" if verbose: runner = unittest.TextTestRunner(sys.stdout, verbosity=2, failfast=failfast) else: runner = BasicTestRunner() result = runner.run(suite) if not result.testsRun and not result.skipped: raise TestDidNotRun if not result.wasSuccessful(): if len(result.errors) == 1 and not result.failures: err = result.errors[0][1] elif len(result.failures) == 1 and not result.errors: err = result.failures[0][1] else: err = "multiple errors occurred" if not verbose: err += "; run in verbose mode for details" raise TestFailed(err) # By default, don't filter tests _match_test_func = None _match_test_patterns = None def match_test(test): # Function used by support.run_unittest() and regrtest --list-cases if _match_test_func is None: return True else: return _match_test_func(test.id()) def _is_full_match_test(pattern): # If a pattern contains at least one dot, it's considered # as a full test identifier. # Example: 'test.test_os.FileTests.test_access'. # # Reject patterns which contain fnmatch patterns: '*', '?', '[...]' # or '[!...]'. For example, reject 'test_access*'. return ('.' in pattern) and (not re.search(r'[?*\[\]]', pattern)) def set_match_tests(patterns): global _match_test_func, _match_test_patterns if patterns == _match_test_patterns: # No change: no need to recompile patterns. return if not patterns: func = None # set_match_tests(None) behaves as set_match_tests(()) patterns = () elif all(map(_is_full_match_test, patterns)): # Simple case: all patterns are full test identifier. # The test.bisect utility only uses such full test identifiers. func = set(patterns).__contains__ else: regex = '|'.join(map(fnmatch.translate, patterns)) # The search *is* case sensitive on purpose: # don't use flags=re.IGNORECASE regex_match = re.compile(regex).match def match_test_regex(test_id): if regex_match(test_id): # The regex matchs the whole identifier like # 'test.test_os.FileTests.test_access' return True else: # Try to match parts of the test identifier. # For example, split 'test.test_os.FileTests.test_access' # into: 'test', 'test_os', 'FileTests' and 'test_access'. return any(map(regex_match, test_id.split("."))) func = match_test_regex # Create a copy since patterns can be mutable and so modified later _match_test_patterns = tuple(patterns) _match_test_func = func def run_unittest(*classes): """Run tests from unittest.TestCase-derived classes.""" valid_types = (unittest.TestSuite, unittest.TestCase) suite = unittest.TestSuite() for cls in classes: if isinstance(cls, str): if cls in sys.modules: suite.addTest(unittest.findTestCases(sys.modules[cls])) else: raise ValueError("str arguments must be keys in sys.modules") elif isinstance(cls, valid_types): suite.addTest(cls) else: suite.addTest(unittest.makeSuite(cls)) _filter_suite(suite, match_test) _run_suite(suite) #======================================================================= # Check for the presence of docstrings. HAVE_DOCSTRINGS = (check_impl_detail(cpython=False) or sys.platform == 'win32' or sysconfig.get_config_var('WITH_DOC_STRINGS')) requires_docstrings = unittest.skipUnless(HAVE_DOCSTRINGS, "test requires docstrings") #======================================================================= # doctest driver. def run_doctest(module, verbosity=None): """Run doctest on the given module. Return (#failures, #tests). If optional argument verbosity is not specified (or is None), pass test.support's belief about verbosity on to doctest. Else doctest's usual behavior is used (it searches sys.argv for -v). """ import doctest if verbosity is None: verbosity = verbose else: verbosity = None # Direct doctest output (normally just errors) to real stdout; doctest # output shouldn't be compared by regrtest. save_stdout = sys.stdout sys.stdout = get_original_stdout() try: f, t = doctest.testmod(module, verbose=verbosity) if f: raise TestFailed("%d of %d doctests failed" % (f, t)) finally: sys.stdout = save_stdout if verbose: print 'doctest (%s) ... %d tests with zero failures' % (module.__name__, t) return f, t #======================================================================= # Threading support to prevent reporting refleaks when running regrtest.py -R # Flag used by saved_test_environment of test.libregrtest.save_env, # to check if a test modified the environment. The flag should be set to False # before running a new test. # # For example, threading_cleanup() sets the flag is the function fails # to cleanup threads. environment_altered = False # NOTE: we use thread._count() rather than threading.enumerate() (or the # moral equivalent thereof) because a threading.Thread object is still alive # until its __bootstrap() method has returned, even after it has been # unregistered from the threading module. # thread._count(), on the other hand, only gets decremented *after* the # __bootstrap() method has returned, which gives us reliable reference counts # at the end of a test run. def threading_setup(): if thread: return thread._count(), else: return 1, def threading_cleanup(nb_threads): if not thread: return _MAX_COUNT = 10 for count in range(_MAX_COUNT): n = thread._count() if n == nb_threads: break time.sleep(0.1) # XXX print a warning in case of failure? def reap_threads(func): """Use this function when threads are being used. This will ensure that the threads are cleaned up even when the test fails. If threading is unavailable this function does nothing. """ if not thread: return func @functools.wraps(func) def decorator(*args): key = threading_setup() try: return func(*args) finally: threading_cleanup(*key) return decorator @contextlib.contextmanager def wait_threads_exit(timeout=60.0): """ bpo-31234: Context manager to wait until all threads created in the with statement exit. Use thread.count() to check if threads exited. Indirectly, wait until threads exit the internal t_bootstrap() C function of the thread module. threading_setup() and threading_cleanup() are designed to emit a warning if a test leaves running threads in the background. This context manager is designed to cleanup threads started by the thread.start_new_thread() which doesn't allow to wait for thread exit, whereas thread.Thread has a join() method. """ old_count = thread._count() try: yield finally: start_time = time.time() deadline = start_time + timeout while True: count = thread._count() if count <= old_count: break if time.time() > deadline: dt = time.time() - start_time msg = ("wait_threads() failed to cleanup %s " "threads after %.1f seconds " "(count: %s, old count: %s)" % (count - old_count, dt, count, old_count)) raise AssertionError(msg) time.sleep(0.010) gc_collect() def reap_children(): """Use this function at the end of test_main() whenever sub-processes are started. This will help ensure that no extra children (zombies) stick around to hog resources and create problems when looking for refleaks. """ # Reap all our dead child processes so we don't leave zombies around. # These hog resources and might be causing some of the buildbots to die. if hasattr(os, 'waitpid'): any_process = -1 while True: try: # This will raise an exception on Windows. That's ok. pid, status = os.waitpid(any_process, os.WNOHANG) if pid == 0: break except: break @contextlib.contextmanager def start_threads(threads, unlock=None): threads = list(threads) started = [] try: try: for t in threads: t.start() started.append(t) except: if verbose: print("Can't start %d threads, only %d threads started" % (len(threads), len(started))) raise yield finally: if unlock: unlock() endtime = starttime = time.time() for timeout in range(1, 16): endtime += 60 for t in started: t.join(max(endtime - time.time(), 0.01)) started = [t for t in started if t.isAlive()] if not started: break if verbose: print('Unable to join %d threads during a period of ' '%d minutes' % (len(started), timeout)) started = [t for t in started if t.isAlive()] if started: raise AssertionError('Unable to join %d threads' % len(started)) @contextlib.contextmanager def swap_attr(obj, attr, new_val): """Temporary swap out an attribute with a new object. Usage: with swap_attr(obj, "attr", 5): ... This will set obj.attr to 5 for the duration of the with: block, restoring the old value at the end of the block. If `attr` doesn't exist on `obj`, it will be created and then deleted at the end of the block. The old value (or None if it doesn't exist) will be assigned to the target of the "as" clause, if there is one. """ if hasattr(obj, attr): real_val = getattr(obj, attr) setattr(obj, attr, new_val) try: yield real_val finally: setattr(obj, attr, real_val) else: setattr(obj, attr, new_val) try: yield finally: if hasattr(obj, attr): delattr(obj, attr) @contextlib.contextmanager def swap_item(obj, item, new_val): """Temporary swap out an item with a new object. Usage: with swap_item(obj, "item", 5): ... This will set obj["item"] to 5 for the duration of the with: block, restoring the old value at the end of the block. If `item` doesn't exist on `obj`, it will be created and then deleted at the end of the block. The old value (or None if it doesn't exist) will be assigned to the target of the "as" clause, if there is one. """ if item in obj: real_val = obj[item] obj[item] = new_val try: yield real_val finally: obj[item] = real_val else: obj[item] = new_val try: yield finally: if item in obj: del obj[item] def py3k_bytes(b): """Emulate the py3k bytes() constructor. NOTE: This is only a best effort function. """ try: # memoryview? return b.tobytes() except AttributeError: try: # iterable of ints? return b"".join(chr(x) for x in b) except TypeError: return bytes(b) requires_type_collecting = unittest.skipIf(hasattr(sys, 'getcounts'), 'types are immortal if COUNT_ALLOCS is defined') def args_from_interpreter_flags(): """Return a list of command-line arguments reproducing the current settings in sys.flags.""" import subprocess return subprocess._args_from_interpreter_flags() def strip_python_stderr(stderr): """Strip the stderr of a Python process from potential debug output emitted by the interpreter. This will typically be run on the result of the communicate() method of a subprocess.Popen object. """ stderr = re.sub(br"\[\d+ refs\]\r?\n?$", b"", stderr).strip() return stderr def check_free_after_iterating(test, iter, cls, args=()): class A(cls): def __del__(self): done[0] = True try: next(it) except StopIteration: pass done = [False] it = iter(A(*args)) # Issue 26494: Shouldn't crash test.assertRaises(StopIteration, next, it) # The sequence should be deallocated just after the end of iterating gc_collect() test.assertTrue(done[0]) @contextlib.contextmanager def disable_gc(): have_gc = gc.isenabled() gc.disable() try: yield finally: if have_gc: gc.enable() def python_is_optimized(): """Find if Python was built with optimizations.""" cflags = sysconfig.get_config_var('PY_CFLAGS') or '' final_opt = "" for opt in cflags.split(): if opt.startswith('-O'): final_opt = opt return final_opt not in ('', '-O0', '-Og') class SuppressCrashReport: """Try to prevent a crash report from popping up. On Windows, don't display the Windows Error Reporting dialog. On UNIX, disable the creation of coredump file. """ old_value = None old_modes = None def __enter__(self): """On Windows, disable Windows Error Reporting dialogs using SetErrorMode. On UNIX, try to save the previous core file size limit, then set soft limit to 0. """ if sys.platform.startswith('win'): # see http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx # GetErrorMode is not available on Windows XP and Windows Server 2003, # but SetErrorMode returns the previous value, so we can use that import ctypes self._k32 = ctypes.windll.kernel32 SEM_NOGPFAULTERRORBOX = 0x02 self.old_value = self._k32.SetErrorMode(SEM_NOGPFAULTERRORBOX) self._k32.SetErrorMode(self.old_value | SEM_NOGPFAULTERRORBOX) # Suppress assert dialogs in debug builds # (see http://bugs.python.org/issue23314) try: import _testcapi _testcapi.CrtSetReportMode except (AttributeError, ImportError): # no _testcapi or a release build pass else: self.old_modes = {} for report_type in [_testcapi.CRT_WARN, _testcapi.CRT_ERROR, _testcapi.CRT_ASSERT]: old_mode = _testcapi.CrtSetReportMode(report_type, _testcapi.CRTDBG_MODE_FILE) old_file = _testcapi.CrtSetReportFile(report_type, _testcapi.CRTDBG_FILE_STDERR) self.old_modes[report_type] = old_mode, old_file else: try: import resource except ImportError: resource = None if resource is not None: try: self.old_value = resource.getrlimit(resource.RLIMIT_CORE) resource.setrlimit(resource.RLIMIT_CORE, (0, self.old_value[1])) except (ValueError, OSError): pass if sys.platform == 'darwin': # Check if the 'Crash Reporter' on OSX was configured # in 'Developer' mode and warn that it will get triggered # when it is. # # This assumes that this context manager is used in tests # that might trigger the next manager. import subprocess cmd = ['/usr/bin/defaults', 'read', 'com.apple.CrashReporter', 'DialogType'] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = proc.communicate()[0] if stdout.strip() == b'developer': sys.stdout.write("this test triggers the Crash Reporter, " "that is intentional") sys.stdout.flush() return self def __exit__(self, *ignore_exc): """Restore Windows ErrorMode or core file behavior to initial value.""" if self.old_value is None: return if sys.platform.startswith('win'): self._k32.SetErrorMode(self.old_value) if self.old_modes: import _testcapi for report_type, (old_mode, old_file) in self.old_modes.items(): _testcapi.CrtSetReportMode(report_type, old_mode) _testcapi.CrtSetReportFile(report_type, old_file) else: import resource try: resource.setrlimit(resource.RLIMIT_CORE, self.old_value) except (ValueError, OSError): pass def _crash_python(): """Deliberate crash of Python. Python can be killed by a segmentation fault (SIGSEGV), a bus error (SIGBUS), or a different error depending on the platform. Use SuppressCrashReport() to prevent a crash report from popping up. """ import _testcapi with SuppressCrashReport(): _testcapi._read_null() def fd_count(): """Count the number of open file descriptors. """ if sys.platform.startswith(('linux', 'freebsd')): try: names = os.listdir("/proc/self/fd") # Substract one because listdir() opens internally a file # descriptor to list the content of the /proc/self/fd/ directory. return len(names) - 1 except OSError as exc: if exc.errno != errno.ENOENT: raise MAXFD = 256 if hasattr(os, 'sysconf'): try: MAXFD = os.sysconf("SC_OPEN_MAX") except OSError: pass old_modes = None if sys.platform == 'win32': # bpo-25306, bpo-31009: Call CrtSetReportMode() to not kill the process # on invalid file descriptor if Python is compiled in debug mode try: import msvcrt msvcrt.CrtSetReportMode except (AttributeError, ImportError): # no msvcrt or a release build pass else: old_modes = {} for report_type in (msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT): old_modes[report_type] = msvcrt.CrtSetReportMode(report_type, 0) try: count = 0 for fd in range(MAXFD): try: # Prefer dup() over fstat(). fstat() can require input/output # whereas dup() doesn't. fd2 = os.dup(fd) except OSError as e: if e.errno != errno.EBADF: raise else: os.close(fd2) count += 1 finally: if old_modes is not None: for report_type in (msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT): msvcrt.CrtSetReportMode(report_type, old_modes[report_type]) return count class SaveSignals: """ Save an restore signal handlers. This class is only able to save/restore signal handlers registered by the Python signal module: see bpo-13285 for "external" signal handlers. """ def __init__(self): import signal self.signal = signal self.signals = list(range(1, signal.NSIG)) # SIGKILL and SIGSTOP signals cannot be ignored nor catched for signame in ('SIGKILL', 'SIGSTOP'): try: signum = getattr(signal, signame) except AttributeError: continue self.signals.remove(signum) self.handlers = {} def save(self): for signum in self.signals: handler = self.signal.getsignal(signum) if handler is None: # getsignal() returns None if a signal handler was not # registered by the Python signal module, # and the handler is not SIG_DFL nor SIG_IGN. # # Ignore the signal: we cannot restore the handler. continue self.handlers[signum] = handler def restore(self): for signum, handler in self.handlers.items(): self.signal.signal(signum, handler) lib64/python3.6/xml/dom/__init__.py000064400000007663152360234600012741 0ustar00"""W3C Document Object Model implementation for Python. The Python mapping of the Document Object Model is documented in the Python Library Reference in the section on the xml.dom package. This package contains the following modules: minidom -- A simple implementation of the Level 1 DOM with namespace support added (based on the Level 2 specification) and other minor Level 2 functionality. pulldom -- DOM builder supporting on-demand tree-building for selected subtrees of the document. """ class Node: """Class giving the NodeType constants.""" __slots__ = () # DOM implementations may use this as a base class for their own # Node implementations. If they don't, the constants defined here # should still be used as the canonical definitions as they match # the values given in the W3C recommendation. Client code can # safely refer to these values in all tests of Node.nodeType # values. ELEMENT_NODE = 1 ATTRIBUTE_NODE = 2 TEXT_NODE = 3 CDATA_SECTION_NODE = 4 ENTITY_REFERENCE_NODE = 5 ENTITY_NODE = 6 PROCESSING_INSTRUCTION_NODE = 7 COMMENT_NODE = 8 DOCUMENT_NODE = 9 DOCUMENT_TYPE_NODE = 10 DOCUMENT_FRAGMENT_NODE = 11 NOTATION_NODE = 12 #ExceptionCode INDEX_SIZE_ERR = 1 DOMSTRING_SIZE_ERR = 2 HIERARCHY_REQUEST_ERR = 3 WRONG_DOCUMENT_ERR = 4 INVALID_CHARACTER_ERR = 5 NO_DATA_ALLOWED_ERR = 6 NO_MODIFICATION_ALLOWED_ERR = 7 NOT_FOUND_ERR = 8 NOT_SUPPORTED_ERR = 9 INUSE_ATTRIBUTE_ERR = 10 INVALID_STATE_ERR = 11 SYNTAX_ERR = 12 INVALID_MODIFICATION_ERR = 13 NAMESPACE_ERR = 14 INVALID_ACCESS_ERR = 15 VALIDATION_ERR = 16 class DOMException(Exception): """Abstract base class for DOM exceptions. Exceptions with specific codes are specializations of this class.""" def __init__(self, *args, **kw): if self.__class__ is DOMException: raise RuntimeError( "DOMException should not be instantiated directly") Exception.__init__(self, *args, **kw) def _get_code(self): return self.code class IndexSizeErr(DOMException): code = INDEX_SIZE_ERR class DomstringSizeErr(DOMException): code = DOMSTRING_SIZE_ERR class HierarchyRequestErr(DOMException): code = HIERARCHY_REQUEST_ERR class WrongDocumentErr(DOMException): code = WRONG_DOCUMENT_ERR class InvalidCharacterErr(DOMException): code = INVALID_CHARACTER_ERR class NoDataAllowedErr(DOMException): code = NO_DATA_ALLOWED_ERR class NoModificationAllowedErr(DOMException): code = NO_MODIFICATION_ALLOWED_ERR class NotFoundErr(DOMException): code = NOT_FOUND_ERR class NotSupportedErr(DOMException): code = NOT_SUPPORTED_ERR class InuseAttributeErr(DOMException): code = INUSE_ATTRIBUTE_ERR class InvalidStateErr(DOMException): code = INVALID_STATE_ERR class SyntaxErr(DOMException): code = SYNTAX_ERR class InvalidModificationErr(DOMException): code = INVALID_MODIFICATION_ERR class NamespaceErr(DOMException): code = NAMESPACE_ERR class InvalidAccessErr(DOMException): code = INVALID_ACCESS_ERR class ValidationErr(DOMException): code = VALIDATION_ERR class UserDataHandler: """Class giving the operation constants for UserDataHandler.handle().""" # Based on DOM Level 3 (WD 9 April 2002) NODE_CLONED = 1 NODE_IMPORTED = 2 NODE_DELETED = 3 NODE_RENAMED = 4 XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml" EMPTY_NAMESPACE = None EMPTY_PREFIX = None from .domreg import getDOMImplementation, registerDOMImplementation usr/lib64/python3.8/xmlrpc/__init__.py000064400000000046152360257620013475 0ustar00# This directory is a Python package. lib64/python3.6/concurrent/futures/__init__.py000064400000001440152360302420015220 0ustar00# Copyright 2009 Brian Quinlan. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """Execute computations asynchronously using threads or processes.""" __author__ = 'Brian Quinlan (brian@sweetapp.com)' from concurrent.futures._base import (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED, CancelledError, TimeoutError, Future, Executor, wait, as_completed) from concurrent.futures.process import ProcessPoolExecutor from concurrent.futures.thread import ThreadPoolExecutor lib64/python3.8/concurrent/futures/__init__.py000064400000003022152360350050015222 0ustar00# Copyright 2009 Brian Quinlan. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """Execute computations asynchronously using threads or processes.""" __author__ = 'Brian Quinlan (brian@sweetapp.com)' from concurrent.futures._base import (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED, CancelledError, TimeoutError, InvalidStateError, BrokenExecutor, Future, Executor, wait, as_completed) __all__ = ( 'FIRST_COMPLETED', 'FIRST_EXCEPTION', 'ALL_COMPLETED', 'CancelledError', 'TimeoutError', 'BrokenExecutor', 'Future', 'Executor', 'wait', 'as_completed', 'ProcessPoolExecutor', 'ThreadPoolExecutor', ) def __dir__(): return __all__ + ('__author__', '__doc__') def __getattr__(name): global ProcessPoolExecutor, ThreadPoolExecutor if name == 'ProcessPoolExecutor': from .process import ProcessPoolExecutor as pe ProcessPoolExecutor = pe return pe if name == 'ThreadPoolExecutor': from .thread import ThreadPoolExecutor as te ThreadPoolExecutor = te return te raise AttributeError(f"module {__name__} has no attribute {name}") lib64/python3.6/xml/__init__.py000064400000001055152360440470012153 0ustar00"""Core XML support for Python. This package contains four sub-packages: dom -- The W3C Document Object Model. This supports DOM Level 1 + Namespaces. parsers -- Python wrappers for XML parsers (currently only supports Expat). sax -- The Simple API for XML, developed by XML-Dev, led by David Megginson and ported to Python by Lars Marius Garshol. This supports the SAX 2 API. etree -- The ElementTree XML library. This is a subset of the full ElementTree XML release. """ __all__ = ["dom", "parsers", "sax", "etree"] usr/lib64/python3.12/lib2to3/__init__.py000064400000000234152360500010013500 0ustar00import warnings warnings.warn( "lib2to3 package is deprecated and may not be able to parse Python 3.10+", DeprecationWarning, stacklevel=2, ) usr/lib/python3.6/site-packages/netaddr/__init__.py000064400000003453152360500120016144 0ustar00#----------------------------------------------------------------------------- # Copyright (c) 2008 by David P. D. Moss. All rights reserved. # # Released under the BSD license. See the LICENSE file for details. #----------------------------------------------------------------------------- """A Python library for manipulating IP and EUI network addresses.""" #: Version info (major, minor, maintenance, status) VERSION = (0, 7, 19) STATUS = '' __version__ = '%d.%d.%d' % VERSION[0:3] + STATUS import sys as _sys if _sys.version_info[0:2] < (2, 4): raise RuntimeError('Python 2.4.x or higher is required!') from netaddr.core import (AddrConversionError, AddrFormatError, NotRegisteredError, ZEROFILL, Z, INET_PTON, P, NOHOST, N) from netaddr.ip import (IPAddress, IPNetwork, IPRange, all_matching_cidrs, cidr_abbrev_to_verbose, cidr_exclude, cidr_merge, iprange_to_cidrs, iter_iprange, iter_unique_ips, largest_matching_cidr, smallest_matching_cidr, spanning_cidr) from netaddr.ip.sets import IPSet from netaddr.ip.glob import (IPGlob, cidr_to_glob, glob_to_cidrs, glob_to_iprange, glob_to_iptuple, iprange_to_globs, valid_glob) from netaddr.ip.nmap import valid_nmap_range, iter_nmap_range from netaddr.ip.rfc1924 import base85_to_ipv6, ipv6_to_base85 from netaddr.eui import EUI, IAB, OUI from netaddr.strategy.ipv4 import valid_str as valid_ipv4 from netaddr.strategy.ipv6 import (valid_str as valid_ipv6, ipv6_compact, ipv6_full, ipv6_verbose) from netaddr.strategy.eui48 import (mac_eui48, mac_unix, mac_unix_expanded, mac_cisco, mac_bare, mac_pgsql, valid_str as valid_mac) from netaddr.strategy.eui64 import (eui64_base, eui64_unix, eui64_unix_expanded, eui64_cisco, eui64_bare, valid_str as valid_eui64) from netaddr.contrib.subnet_splitter import SubnetSplitter lib64/python3.8/importlib/__init__.py000064400000013655152360516410013365 0ustar00"""A pure Python implementation of import.""" __all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload'] # Bootstrap help ##################################################### # Until bootstrapping is complete, DO NOT import any modules that attempt # to import importlib._bootstrap (directly or indirectly). Since this # partially initialised package would be present in sys.modules, those # modules would get an uninitialised copy of the source version, instead # of a fully initialised version (either the frozen one or the one # initialised below if the frozen one is not available). import _imp # Just the builtin component, NOT the full Python module import sys try: import _frozen_importlib as _bootstrap except ImportError: from . import _bootstrap _bootstrap._setup(sys, _imp) else: # importlib._bootstrap is the built-in import, ensure we don't create # a second copy of the module. _bootstrap.__name__ = 'importlib._bootstrap' _bootstrap.__package__ = 'importlib' try: _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap'] = _bootstrap try: import _frozen_importlib_external as _bootstrap_external except ImportError: from . import _bootstrap_external _bootstrap_external._setup(_bootstrap) _bootstrap._bootstrap_external = _bootstrap_external else: _bootstrap_external.__name__ = 'importlib._bootstrap_external' _bootstrap_external.__package__ = 'importlib' try: _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap_external'] = _bootstrap_external # To simplify imports in test code _pack_uint32 = _bootstrap_external._pack_uint32 _unpack_uint32 = _bootstrap_external._unpack_uint32 # Fully bootstrapped at this point, import whatever you like, circular # dependencies and startup overhead minimisation permitting :) import types import warnings # Public API ######################################################### from ._bootstrap import __import__ def invalidate_caches(): """Call the invalidate_caches() method on all meta path finders stored in sys.meta_path (where implemented).""" for finder in sys.meta_path: if hasattr(finder, 'invalidate_caches'): finder.invalidate_caches() def find_loader(name, path=None): """Return the loader for the specified module. This is a backward-compatible wrapper around find_spec(). This function is deprecated in favor of importlib.util.find_spec(). """ warnings.warn('Deprecated since Python 3.4. ' 'Use importlib.util.find_spec() instead.', DeprecationWarning, stacklevel=2) try: loader = sys.modules[name].__loader__ if loader is None: raise ValueError('{}.__loader__ is None'.format(name)) else: return loader except KeyError: pass except AttributeError: raise ValueError('{}.__loader__ is not set'.format(name)) from None spec = _bootstrap._find_spec(name, path) # We won't worry about malformed specs (missing attributes). if spec is None: return None if spec.loader is None: if spec.submodule_search_locations is None: raise ImportError('spec for {} missing loader'.format(name), name=name) raise ImportError('namespace packages do not have loaders', name=name) return spec.loader def import_module(name, package=None): """Import a module. The 'package' argument is required when performing a relative import. It specifies the package to use as the anchor point from which to resolve the relative import to an absolute import. """ level = 0 if name.startswith('.'): if not package: msg = ("the 'package' argument is required to perform a relative " "import for {!r}") raise TypeError(msg.format(name)) for character in name: if character != '.': break level += 1 return _bootstrap._gcd_import(name[level:], package, level) _RELOADING = {} def reload(module): """Reload the module and return it. The module must have been successfully imported before. """ if not module or not isinstance(module, types.ModuleType): raise TypeError("reload() argument must be a module") try: name = module.__spec__.name except AttributeError: name = module.__name__ if sys.modules.get(name) is not module: msg = "module {} not in sys.modules" raise ImportError(msg.format(name), name=name) if name in _RELOADING: return _RELOADING[name] _RELOADING[name] = module try: parent_name = name.rpartition('.')[0] if parent_name: try: parent = sys.modules[parent_name] except KeyError: msg = "parent {!r} not in sys.modules" raise ImportError(msg.format(parent_name), name=parent_name) from None else: pkgpath = parent.__path__ else: pkgpath = None target = module spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) if spec is None: raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name) _bootstrap._exec(spec, module) # The module may have replaced itself in sys.modules! return sys.modules[name] finally: try: del _RELOADING[name] except KeyError: pass usr/lib64/python3.6/unittest/__init__.py000064400000006153152360561320014045 0ustar00""" Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's Smalltalk testing framework (used with permission). This module contains the core framework classes that form the basis of specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results (TextTestRunner). Simple usage: import unittest class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): # test method names begin with 'test' self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main() Further information is available in the bundled documentation, and from http://docs.python.org/library/unittest.html Copyright (c) 1999-2003 Steve Purcell Copyright (c) 2003-2010 Python Software Foundation This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __all__ = ['TestResult', 'TestCase', 'TestSuite', 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', 'expectedFailure', 'TextTestResult', 'installHandler', 'registerResult', 'removeResult', 'removeHandler'] # Expose obsolete functions for backwards compatibility __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) __unittest = True from .result import TestResult from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf, skipUnless, expectedFailure, _skipInRpmBuild) from .suite import BaseTestSuite, TestSuite from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, findTestCases) from .main import TestProgram, main from .runner import TextTestRunner, TextTestResult from .signals import installHandler, registerResult, removeResult, removeHandler # deprecated _TextTestResult = TextTestResult # There are no tests here, so don't try to run anything discovered from # introspecting the symbols (e.g. FunctionTestCase). Instead, all our # tests come from within unittest.test. def load_tests(loader, tests, pattern): import os.path # top level directory cached on loader instance this_dir = os.path.dirname(__file__) return loader.discover(start_dir=this_dir, pattern=pattern) lib64/python2.7/xml/parsers/__init__.py000064400000000247152360575470013645 0ustar00"""Python interfaces to XML parsers. This package contains one module: expat -- Python wrapper for James Clark's Expat parser, with namespace support. """ usr/lib64/python3.8/importlib/__init__.py000064400000013655152360636630014205 0ustar00"""A pure Python implementation of import.""" __all__ = ['__import__', 'import_module', 'invalidate_caches', 'reload'] # Bootstrap help ##################################################### # Until bootstrapping is complete, DO NOT import any modules that attempt # to import importlib._bootstrap (directly or indirectly). Since this # partially initialised package would be present in sys.modules, those # modules would get an uninitialised copy of the source version, instead # of a fully initialised version (either the frozen one or the one # initialised below if the frozen one is not available). import _imp # Just the builtin component, NOT the full Python module import sys try: import _frozen_importlib as _bootstrap except ImportError: from . import _bootstrap _bootstrap._setup(sys, _imp) else: # importlib._bootstrap is the built-in import, ensure we don't create # a second copy of the module. _bootstrap.__name__ = 'importlib._bootstrap' _bootstrap.__package__ = 'importlib' try: _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap'] = _bootstrap try: import _frozen_importlib_external as _bootstrap_external except ImportError: from . import _bootstrap_external _bootstrap_external._setup(_bootstrap) _bootstrap._bootstrap_external = _bootstrap_external else: _bootstrap_external.__name__ = 'importlib._bootstrap_external' _bootstrap_external.__package__ = 'importlib' try: _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') except NameError: # __file__ is not guaranteed to be defined, e.g. if this code gets # frozen by a tool like cx_Freeze. pass sys.modules['importlib._bootstrap_external'] = _bootstrap_external # To simplify imports in test code _pack_uint32 = _bootstrap_external._pack_uint32 _unpack_uint32 = _bootstrap_external._unpack_uint32 # Fully bootstrapped at this point, import whatever you like, circular # dependencies and startup overhead minimisation permitting :) import types import warnings # Public API ######################################################### from ._bootstrap import __import__ def invalidate_caches(): """Call the invalidate_caches() method on all meta path finders stored in sys.meta_path (where implemented).""" for finder in sys.meta_path: if hasattr(finder, 'invalidate_caches'): finder.invalidate_caches() def find_loader(name, path=None): """Return the loader for the specified module. This is a backward-compatible wrapper around find_spec(). This function is deprecated in favor of importlib.util.find_spec(). """ warnings.warn('Deprecated since Python 3.4. ' 'Use importlib.util.find_spec() instead.', DeprecationWarning, stacklevel=2) try: loader = sys.modules[name].__loader__ if loader is None: raise ValueError('{}.__loader__ is None'.format(name)) else: return loader except KeyError: pass except AttributeError: raise ValueError('{}.__loader__ is not set'.format(name)) from None spec = _bootstrap._find_spec(name, path) # We won't worry about malformed specs (missing attributes). if spec is None: return None if spec.loader is None: if spec.submodule_search_locations is None: raise ImportError('spec for {} missing loader'.format(name), name=name) raise ImportError('namespace packages do not have loaders', name=name) return spec.loader def import_module(name, package=None): """Import a module. The 'package' argument is required when performing a relative import. It specifies the package to use as the anchor point from which to resolve the relative import to an absolute import. """ level = 0 if name.startswith('.'): if not package: msg = ("the 'package' argument is required to perform a relative " "import for {!r}") raise TypeError(msg.format(name)) for character in name: if character != '.': break level += 1 return _bootstrap._gcd_import(name[level:], package, level) _RELOADING = {} def reload(module): """Reload the module and return it. The module must have been successfully imported before. """ if not module or not isinstance(module, types.ModuleType): raise TypeError("reload() argument must be a module") try: name = module.__spec__.name except AttributeError: name = module.__name__ if sys.modules.get(name) is not module: msg = "module {} not in sys.modules" raise ImportError(msg.format(name), name=name) if name in _RELOADING: return _RELOADING[name] _RELOADING[name] = module try: parent_name = name.rpartition('.')[0] if parent_name: try: parent = sys.modules[parent_name] except KeyError: msg = "parent {!r} not in sys.modules" raise ImportError(msg.format(parent_name), name=parent_name) from None else: pkgpath = parent.__path__ else: pkgpath = None target = module spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) if spec is None: raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name) _bootstrap._exec(spec, module) # The module may have replaced itself in sys.modules! return sys.modules[name] finally: try: del _RELOADING[name] except KeyError: pass opt/alt/python38/lib/python3.8/site-packages/pip/__init__.py000064400000000545152360637530017601 0ustar00from typing import List, Optional __version__ = "22.2.1" def main(args: Optional[List[str]] = None) -> int: """This is an internal API only meant for use by pip's own console scripts. For additional details, see https://github.com/pypa/pip/issues/7498. """ from pip._internal.utils.entrypoints import _wrapper return _wrapper(args) lib64/python2.7/xml/etree/__init__.py000064400000003104152360725100013250 0ustar00# $Id: __init__.py 3375 2008-02-13 08:05:08Z fredrik $ # elementtree package # -------------------------------------------------------------------- # The ElementTree toolkit is # # Copyright (c) 1999-2008 by Fredrik Lundh # # By obtaining, using, and/or copying this software and/or its # associated documentation, you agree that you have read, understood, # and will comply with the following terms and conditions: # # Permission to use, copy, modify, and distribute this software and # its associated documentation for any purpose and without fee is # hereby granted, provided that the above copyright notice appears in # all copies, and that both that copyright notice and this permission # notice appear in supporting documentation, and that the name of # Secret Labs AB or the author not be used in advertising or publicity # pertaining to distribution of the software without specific, written # prior permission. # # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # OF THIS SOFTWARE. # -------------------------------------------------------------------- # Licensed to PSF under a Contributor Agreement. # See http://www.python.org/psf/license for licensing details. usr/lib64/python3.8/email/__init__.py000064400000003346152360736610013266 0ustar00# Copyright (C) 2001-2007 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org """A package for parsing, handling, and generating email messages.""" __all__ = [ 'base64mime', 'charset', 'encoders', 'errors', 'feedparser', 'generator', 'header', 'iterators', 'message', 'message_from_file', 'message_from_binary_file', 'message_from_string', 'message_from_bytes', 'mime', 'parser', 'quoprimime', 'utils', ] # Some convenience routines. Don't import Parser and Message as side-effects # of importing email since those cascadingly import most of the rest of the # email package. def message_from_string(s, *args, **kws): """Parse a string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parsestr(s) def message_from_bytes(s, *args, **kws): """Parse a bytes string into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parsebytes(s) def message_from_file(fp, *args, **kws): """Read a file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import Parser return Parser(*args, **kws).parse(fp) def message_from_binary_file(fp, *args, **kws): """Read a binary file and parse its contents into a Message object model. Optional _class and strict are passed to the Parser constructor. """ from email.parser import BytesParser return BytesParser(*args, **kws).parse(fp) usr/lib64/python3.8/distutils/__init__.py000064400000000354152360752470014221 0ustar00"""distutils The main package for the Python Module Distribution Utilities. Normally used from a setup script as from distutils.core import setup setup (...) """ import sys __version__ = sys.version[:sys.version.index(' ')] usr/lib/python3.6/site-packages/dns/rdtypes/__init__.py000064400000001577152361252320017015 0ustar00# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose with or without fee is hereby granted, # provided that the above copyright notice and this permission notice # appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """DNS rdata type classes""" __all__ = [ 'ANY', 'IN', 'euibase', 'mxbase', 'nsbase', ] usr/lib64/python2.7/distutils/command/__init__.py000064400000001466152361343100015625 0ustar00"""distutils.command Package containing implementation of all the standard Distutils commands.""" __revision__ = "$Id$" __all__ = ['build', 'build_py', 'build_ext', 'build_clib', 'build_scripts', 'clean', 'install', 'install_lib', 'install_headers', 'install_scripts', 'install_data', 'sdist', 'register', 'bdist', 'bdist_dumb', 'bdist_rpm', 'bdist_wininst', 'upload', 'check', # These two are reserved for future use: #'bdist_sdux', #'bdist_pkgtool', # Note: # bdist_packager is not included because it only provides # an abstract base class ] opt/alt/python36/lib/python3.6/site-packages/pip/__init__.py000064400000000707152361520300017560 0ustar00from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: from typing import List, Optional __version__ = "20.2.4" def main(args=None): # type: (Optional[List[str]]) -> int """This is an internal API only meant for use by pip's own console scripts. For additional details, see https://github.com/pypa/pip/issues/7498. """ from pip._internal.utils.entrypoints import _wrapper return _wrapper(args) usr/lib64/python3.8/asyncio/__init__.py000064400000002313152361776160013642 0ustar00"""The asyncio package, tracking PEP 3156.""" # flake8: noqa import sys # This relies on each of the submodules having an __all__ variable. from .base_events import * from .coroutines import * from .events import * from .exceptions import * from .futures import * from .locks import * from .protocols import * from .runners import * from .queues import * from .streams import * from .subprocess import * from .tasks import * from .transports import * # Exposed for _asynciomodule.c to implement now deprecated # Task.all_tasks() method. This function will be removed in 3.9. from .tasks import _all_tasks_compat # NoQA __all__ = (base_events.__all__ + coroutines.__all__ + events.__all__ + exceptions.__all__ + futures.__all__ + locks.__all__ + protocols.__all__ + runners.__all__ + queues.__all__ + streams.__all__ + subprocess.__all__ + tasks.__all__ + transports.__all__) if sys.platform == 'win32': # pragma: no cover from .windows_events import * __all__ += windows_events.__all__ else: from .unix_events import * # pragma: no cover __all__ += unix_events.__all__ opt/alt/python33/lib/python3.3/site-packages/pip/__init__.py000064400000022324152362231520017555 0ustar00import os import optparse import sys import re from pip.exceptions import InstallationError, CommandError, PipError from pip.log import logger from pip.util import get_installed_distributions, get_prog from pip.vcs import git, mercurial, subversion, bazaar # noqa from pip.baseparser import ConfigOptionParser, UpdatingDefaultsHelpFormatter from pip.commands import commands, get_summaries, get_similar_commands # This fixes a peculiarity when importing via __import__ - as we are # initialising the pip module, "from pip import cmdoptions" is recursive # and appears not to work properly in that situation. import pip.cmdoptions cmdoptions = pip.cmdoptions # The version as used in the setup.py and the docs conf.py __version__ = "1.5.6" def autocomplete(): """Command and option completion for the main option parser (and options) and its subcommands (and options). Enable by sourcing one of the completion shell scripts (bash or zsh). """ # Don't complete if user hasn't sourced bash_completion file. if 'PIP_AUTO_COMPLETE' not in os.environ: return cwords = os.environ['COMP_WORDS'].split()[1:] cword = int(os.environ['COMP_CWORD']) try: current = cwords[cword - 1] except IndexError: current = '' subcommands = [cmd for cmd, summary in get_summaries()] options = [] # subcommand try: subcommand_name = [w for w in cwords if w in subcommands][0] except IndexError: subcommand_name = None parser = create_main_parser() # subcommand options if subcommand_name: # special case: 'help' subcommand has no options if subcommand_name == 'help': sys.exit(1) # special case: list locally installed dists for uninstall command if subcommand_name == 'uninstall' and not current.startswith('-'): installed = [] lc = current.lower() for dist in get_installed_distributions(local_only=True): if dist.key.startswith(lc) and dist.key not in cwords[1:]: installed.append(dist.key) # if there are no dists installed, fall back to option completion if installed: for dist in installed: print(dist) sys.exit(1) subcommand = commands[subcommand_name]() options += [(opt.get_opt_string(), opt.nargs) for opt in subcommand.parser.option_list_all if opt.help != optparse.SUPPRESS_HELP] # filter out previously specified options from available options prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] options = [(x, v) for (x, v) in options if x not in prev_opts] # filter options by current input options = [(k, v) for k, v in options if k.startswith(current)] for option in options: opt_label = option[0] # append '=' to options which require args if option[1]: opt_label += '=' print(opt_label) else: # show main parser options only when necessary if current.startswith('-') or current.startswith('--'): opts = [i.option_list for i in parser.option_groups] opts.append(parser.option_list) opts = (o for it in opts for o in it) subcommands += [i.get_opt_string() for i in opts if i.help != optparse.SUPPRESS_HELP] print(' '.join([x for x in subcommands if x.startswith(current)])) sys.exit(1) def create_main_parser(): parser_kw = { 'usage': '\n%prog [options]', 'add_help_option': False, 'formatter': UpdatingDefaultsHelpFormatter(), 'name': 'global', 'prog': get_prog(), } parser = ConfigOptionParser(**parser_kw) parser.disable_interspersed_args() pip_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) parser.version = 'pip %s from %s (python %s)' % ( __version__, pip_pkg_dir, sys.version[:3]) # add the general options gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) parser.add_option_group(gen_opts) parser.main = True # so the help formatter knows # create command listing for description command_summaries = get_summaries() description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] parser.description = '\n'.join(description) return parser def parseopts(args): parser = create_main_parser() # Note: parser calls disable_interspersed_args(), so the result of this call # is to split the initial args into the general options before the # subcommand and everything else. # For example: # args: ['--timeout=5', 'install', '--user', 'INITools'] # general_options: ['--timeout==5'] # args_else: ['install', '--user', 'INITools'] general_options, args_else = parser.parse_args(args) # --version if general_options.version: sys.stdout.write(parser.version) sys.stdout.write(os.linesep) sys.exit() # pip || pip help -> print_help() if not args_else or (args_else[0] == 'help' and len(args_else) == 1): parser.print_help() sys.exit() # the subcommand name cmd_name = args_else[0].lower() #all the args without the subcommand cmd_args = args[:] cmd_args.remove(args_else[0].lower()) if cmd_name not in commands: guess = get_similar_commands(cmd_name) msg = ['unknown command "%s"' % cmd_name] if guess: msg.append('maybe you meant "%s"' % guess) raise CommandError(' - '.join(msg)) return cmd_name, cmd_args def main(initial_args=None): if initial_args is None: initial_args = sys.argv[1:] autocomplete() try: cmd_name, cmd_args = parseopts(initial_args) except PipError: e = sys.exc_info()[1] sys.stderr.write("ERROR: %s" % e) sys.stderr.write(os.linesep) sys.exit(1) command = commands[cmd_name]() return command.main(cmd_args) def bootstrap(): """ Bootstrapping function to be called from install-pip.py script. """ pkgs = ['pip'] try: import setuptools except ImportError: pkgs.append('setuptools') return main(['install', '--upgrade'] + pkgs + sys.argv[1:]) ############################################################ ## Writing freeze files class FrozenRequirement(object): def __init__(self, name, req, editable, comments=()): self.name = name self.req = req self.editable = editable self.comments = comments _rev_re = re.compile(r'-r(\d+)$') _date_re = re.compile(r'-(20\d\d\d\d\d\d)$') @classmethod def from_dist(cls, dist, dependency_links, find_tags=False): location = os.path.normcase(os.path.abspath(dist.location)) comments = [] from pip.vcs import vcs, get_src_requirement if vcs.get_backend_name(location): editable = True try: req = get_src_requirement(dist, location, find_tags) except InstallationError: ex = sys.exc_info()[1] logger.warn("Error when trying to get requirement for VCS system %s, falling back to uneditable format" % ex) req = None if req is None: logger.warn('Could not determine repository location of %s' % location) comments.append('## !! Could not determine repository location') req = dist.as_requirement() editable = False else: editable = False req = dist.as_requirement() specs = req.specs assert len(specs) == 1 and specs[0][0] == '==' version = specs[0][1] ver_match = cls._rev_re.search(version) date_match = cls._date_re.search(version) if ver_match or date_match: svn_backend = vcs.get_backend('svn') if svn_backend: svn_location = svn_backend( ).get_location(dist, dependency_links) if not svn_location: logger.warn( 'Warning: cannot find svn location for %s' % req) comments.append('## FIXME: could not find svn URL in dependency_links for this package:') else: comments.append('# Installing as editable to satisfy requirement %s:' % req) if ver_match: rev = ver_match.group(1) else: rev = '{%s}' % date_match.group(1) editable = True req = '%s@%s#egg=%s' % (svn_location, rev, cls.egg_name(dist)) return cls(dist.project_name, req, editable, comments) @staticmethod def egg_name(dist): name = dist.egg_name() match = re.search(r'-py\d\.\d$', name) if match: name = name[:match.start()] return name def __str__(self): req = self.req if self.editable: req = '-e %s' % req return '\n'.join(list(self.comments) + [str(req)]) + '\n' if __name__ == '__main__': exit = main() if exit: sys.exit(exit) usr/lib64/python3.6/site-packages/dbus/__init__.py000064400000007364152362662310015653 0ustar00"""\ Implements the public API for a D-Bus client. See the dbus.service module to export objects or claim well-known names. .. for epydoc's benefit :NewField SupportedUsage: Supported usage :NewField Constructor: Constructor """ # Copyright (C) 2003, 2004, 2005, 2006 Red Hat Inc. # Copyright (C) 2003 David Zeuthen # Copyright (C) 2004 Rob Taylor # Copyright (C) 2005, 2006 Collabora Ltd. # # Permission is hereby granted, free of charge, to any person # obtaining a copy of this software and associated documentation # files (the "Software"), to deal in the Software without # restriction, including without limitation the rights to use, copy, # modify, merge, publish, distribute, sublicense, and/or sell copies # of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. __all__ = [ # from _dbus 'Bus', 'SystemBus', 'SessionBus', 'StarterBus', # from proxies 'Interface', # from _dbus_bindings 'get_default_main_loop', 'set_default_main_loop', 'validate_interface_name', 'validate_member_name', 'validate_bus_name', 'validate_object_path', 'validate_error_name', 'BUS_DAEMON_NAME', 'BUS_DAEMON_PATH', 'BUS_DAEMON_IFACE', 'LOCAL_PATH', 'LOCAL_IFACE', 'PEER_IFACE', 'INTROSPECTABLE_IFACE', 'PROPERTIES_IFACE', 'ObjectPath', 'ByteArray', 'Signature', 'Byte', 'Boolean', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64', 'Double', 'String', 'Array', 'Struct', 'Dictionary', # from exceptions 'DBusException', 'MissingErrorHandlerException', 'MissingReplyHandlerException', 'ValidationException', 'IntrospectionParserException', 'UnknownMethodException', 'NameExistsException', # submodules 'service', 'mainloop', 'lowlevel' ] from dbus._compat import is_py2 if is_py2: __all__.append('UTF8String') __docformat__ = 'restructuredtext' # OLPC Sugar compatibility import dbus.exceptions as exceptions import dbus.types as types from _dbus_bindings import __version__ version = tuple(map(int, __version__.split('.'))) from _dbus_bindings import ( get_default_main_loop, set_default_main_loop, validate_bus_name, validate_error_name, validate_interface_name, validate_member_name, validate_object_path) from _dbus_bindings import ( BUS_DAEMON_IFACE, BUS_DAEMON_NAME, BUS_DAEMON_PATH, INTROSPECTABLE_IFACE, LOCAL_IFACE, LOCAL_PATH, PEER_IFACE, PROPERTIES_IFACE) from dbus.exceptions import ( DBusException, IntrospectionParserException, MissingErrorHandlerException, MissingReplyHandlerException, NameExistsException, UnknownMethodException, ValidationException) from _dbus_bindings import ( Array, Boolean, Byte, ByteArray, Dictionary, Double, Int16, Int32, Int64, ObjectPath, Signature, String, Struct, UInt16, UInt32, UInt64) if is_py2: from _dbus_bindings import UTF8String from dbus._dbus import Bus, SystemBus, SessionBus, StarterBus from dbus.proxies import Interface opt/alt/python39/lib/python3.9/site-packages/pip/__init__.py000064400000000545152362725750017607 0ustar00from typing import List, Optional __version__ = "21.3.1" def main(args: Optional[List[str]] = None) -> int: """This is an internal API only meant for use by pip's own console scripts. For additional details, see https://github.com/pypa/pip/issues/7498. """ from pip._internal.utils.entrypoints import _wrapper return _wrapper(args) usr/lib64/python3.12/concurrent/__init__.py000064400000000046152363053110014414 0ustar00# This directory is a Python package. opt/alt/python38/lib/python3.8/site-packages/ply/__init__.py000064400000000146152363301730017603 0ustar00# PLY package # Author: David Beazley (dave@dabeaz.com) __version__ = '3.7' __all__ = ['lex','yacc'] lib64/python3.6/site-packages/hawkey/__init__.py000064400000030735152363334760015401 0ustar00# # Copyright (C) 2012-2019 Red Hat, Inc. # # Licensed under the GNU Lesser General Public License Version 2.1 # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # from __future__ import absolute_import from sys import version_info as python_version import collections import functools import logging import operator import time import warnings import libdnf.transaction from . import _hawkey __all__ = [ # version info 'VERSION', 'VERSION_MAJOR', 'VERSION_MINOR', 'VERSION_PATCH', # submodules 'test', # constants 'CHKSUM_MD5', 'CHKSUM_SHA1', 'CHKSUM_SHA256', 'CHKSUM_SHA384', 'CHKSUM_SHA512', 'ICASE', 'CMDLINE_REPO_NAME', 'MODULE_FAIL_SAFE_REPO_NAME', 'SYSTEM_REPO_NAME', 'REASON_DEP', 'REASON_USER', 'REASON_CLEAN', 'REASON_WEAKDEP', 'FORM_NEVRA', 'FORM_NEVR', 'FORM_NEV', 'FORM_NA', 'FORM_NAME', 'FORM_ALL', 'MODULE_FORM_NSVCAP', 'MODULE_FORM_NSVCA', 'MODULE_FORM_NSVAP', 'MODULE_FORM_NSVA', 'MODULE_FORM_NSAP', 'MODULE_FORM_NSA', 'MODULE_FORM_NSVCP', 'MODULE_FORM_NSVP', 'MODULE_FORM_NSVC', 'MODULE_FORM_NSV', 'MODULE_FORM_NSP', 'MODULE_FORM_NS', 'MODULE_FORM_NAP', 'MODULE_FORM_NA', 'MODULE_FORM_NP', 'MODULE_FORM_N' # exceptions 'ArchException', 'Exception', 'QueryException', 'RuntimeException', 'ValueException', # functions 'chksum_name', 'chksum_type', 'split_nevra', 'convert_hawkey_reason', # classes 'Goal', 'NEVRA', 'NSVCAP', 'Package', 'Query', 'Repo', 'Sack', 'Selector', 'Subject'] NEVRA = _hawkey.NEVRA Query = _hawkey.Query Selector = _hawkey.Selector VERSION_MAJOR = _hawkey.VERSION_MAJOR VERSION_MINOR = _hawkey.VERSION_MINOR VERSION_PATCH = _hawkey.VERSION_PATCH VERSION = u"%d.%d.%d" % (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH) SYSTEM_REPO_NAME = _hawkey.SYSTEM_REPO_NAME CMDLINE_REPO_NAME = _hawkey.CMDLINE_REPO_NAME MODULE_FAIL_SAFE_REPO_NAME = _hawkey.MODULE_FAIL_SAFE_REPO_NAME FORM_NEVRA = _hawkey.FORM_NEVRA FORM_NEVR = _hawkey.FORM_NEVR FORM_NEV = _hawkey.FORM_NEV FORM_NA = _hawkey.FORM_NA FORM_NAME = _hawkey.FORM_NAME MODULE_FORM_NSVCAP = _hawkey.MODULE_FORM_NSVCAP MODULE_FORM_NSVCA = _hawkey.MODULE_FORM_NSVCA MODULE_FORM_NSVAP = _hawkey.MODULE_FORM_NSVAP MODULE_FORM_NSVA = _hawkey.MODULE_FORM_NSVA MODULE_FORM_NSAP = _hawkey.MODULE_FORM_NSAP MODULE_FORM_NSA = _hawkey.MODULE_FORM_NSA MODULE_FORM_NSVCP = _hawkey.MODULE_FORM_NSVCP MODULE_FORM_NSVP = _hawkey.MODULE_FORM_NSVP MODULE_FORM_NSVC = _hawkey.MODULE_FORM_NSVC MODULE_FORM_NSV = _hawkey.MODULE_FORM_NSV MODULE_FORM_NSP = _hawkey.MODULE_FORM_NSP MODULE_FORM_NS = _hawkey.MODULE_FORM_NS MODULE_FORM_NAP = _hawkey.MODULE_FORM_NAP MODULE_FORM_NA = _hawkey.MODULE_FORM_NA MODULE_FORM_NP = _hawkey.MODULE_FORM_NP MODULE_FORM_N = _hawkey.MODULE_FORM_N ICASE = _hawkey.ICASE EQ = _hawkey.EQ LT = _hawkey.LT GT = _hawkey.GT APPLY_EXCLUDES = _hawkey.APPLY_EXCLUDES IGNORE_MODULAR_EXCLUDES = _hawkey.IGNORE_MODULAR_EXCLUDES IGNORE_REGULAR_EXCLUDES = _hawkey.IGNORE_REGULAR_EXCLUDES IGNORE_EXCLUDES = _hawkey.IGNORE_EXCLUDES CHKSUM_MD5 = _hawkey.CHKSUM_MD5 CHKSUM_SHA1 = _hawkey.CHKSUM_SHA1 CHKSUM_SHA256 = _hawkey.CHKSUM_SHA256 CHKSUM_SHA384 = _hawkey.CHKSUM_SHA384 CHKSUM_SHA512 = _hawkey.CHKSUM_SHA512 REASON_DEP = _hawkey.REASON_DEP REASON_USER = _hawkey.REASON_USER REASON_CLEAN = _hawkey.REASON_CLEAN REASON_WEAKDEP = _hawkey.REASON_WEAKDEP def convert_hawkey_reason(hawkey_reason): if hawkey_reason == REASON_USER: return libdnf.transaction.TransactionItemReason_USER if hawkey_reason == REASON_DEP: return libdnf.transaction.TransactionItemReason_DEPENDENCY if hawkey_reason == REASON_CLEAN: return libdnf.transaction.TransactionItemReason_CLEAN if hawkey_reason == REASON_WEAKDEP: return libdnf.transaction.TransactionItemReason_WEAK_DEPENDENCY return libdnf.transaction.TransactionItemReason_UNKNOWN ADVISORY_UNKNOWN = _hawkey.ADVISORY_UNKNOWN ADVISORY_SECURITY = _hawkey.ADVISORY_SECURITY ADVISORY_BUGFIX = _hawkey.ADVISORY_BUGFIX ADVISORY_ENHANCEMENT = _hawkey.ADVISORY_ENHANCEMENT ADVISORY_NEWPACKAGE = _hawkey.ADVISORY_NEWPACKAGE REFERENCE_UNKNOWN = _hawkey.REFERENCE_UNKNOWN REFERENCE_BUGZILLA = _hawkey.REFERENCE_BUGZILLA REFERENCE_CVE = _hawkey.REFERENCE_CVE REFERENCE_VENDOR = _hawkey.REFERENCE_VENDOR Package = _hawkey.Package Reldep = _hawkey.Reldep Sack = _hawkey.Sack Exception = _hawkey.Exception QueryException = _hawkey.QueryException ValueException = _hawkey.ValueException ArchException = _hawkey.ArchException RuntimeException = _hawkey.RuntimeException chksum_name = _hawkey.chksum_name chksum_type = _hawkey.chksum_type detect_arch = _hawkey.detect_arch ERASE = _hawkey.ERASE DISTUPGRADE = _hawkey.DISTUPGRADE DISTUPGRADE_ALL = _hawkey.DISTUPGRADE_ALL DOWNGRADE = _hawkey.DOWNGRADE INSTALL = _hawkey.INSTALL UPGRADE = _hawkey.UPGRADE UPGRADE_ALL = _hawkey.UPGRADE_ALL ALLOW_UNINSTALL = _hawkey.ALLOW_UNINSTALL FORCE_BEST = _hawkey.FORCE_BEST VERIFY = _hawkey.VERIFY IGNORE_WEAK_DEPS = _hawkey.IGNORE_WEAK_DEPS PY3 = python_version.major >= 3 logger = logging.getLogger('dnf') def split_nevra(s): t = _hawkey.split_nevra(s) return NEVRA(*t) class NSVCAP(_hawkey.NSVCAP): NSVCAP_FIELDS = ["name", "stream", "version", "context", "arch", "profile"] def _has_just_name(self): return self.name and not self.stream and not self.version and \ not self.arch and not self.profile def __repr__(self): values = [getattr(self, i) for i in self.NSVCAP_FIELDS] items = [(field, value) for field, value in zip(self.NSVCAP_FIELDS, values) if value is not None] items_str = ", ".join(["{}={}".format(field, value) for field, value in items]) return "".format(items_str) def __eq__(self, other): result = True for field in self.NSVCAP_FIELDS: value_self = getattr(self, field) value_other = getattr(other, field) result &= value_self == value_other return result class Goal(_hawkey.Goal): _goal_actions = { ERASE, DISTUPGRADE, DISTUPGRADE_ALL, DOWNGRADE, INSTALL, UPGRADE, UPGRADE_ALL } def __init__(self, sack): super(Goal, self).__init__(sack) self.group_members = set() def get_reason(self, pkg): code = super(Goal, self).get_reason(pkg) if code == REASON_USER and pkg.name in self.group_members: return libdnf.transaction.TransactionItemReason_GROUP return convert_hawkey_reason(code) def group_reason(self, pkg, current_reason): if current_reason == libdnf.transaction.TransactionItemReason_UNKNOWN and pkg.name in self.group_members: return libdnf.transaction.TransactionItemReason_GROUP return current_reason def push_userinstalled(self, query, history): msg = '--> Finding unneeded leftover dependencies' # translate logger.debug(msg) # get only user installed packages user_installed = query.userinstalled(history.swdb) self.userinstalled(user_installed) def _encode(obj): """ Identity, except when obj is unicode then return a UTF-8 string. This assumes UTF-8 is good enough for libsolv and always will be. Else we'll have to deal with some encoding configuration. Since we use this to match string queries, we have to enforce 'strict' and potentially face exceptions rather than bizarre results. (Except that as long as we stick to UTF-8 it never fails.) """ if not PY3 and isinstance(obj, unicode): return obj.encode('utf8', 'strict') return obj def is_glob_pattern(pattern): if (not PY3 and isinstance(pattern, basestring)) or \ (PY3 and isinstance(pattern, str)): pattern = [pattern] return (isinstance(pattern, list) and any(set(p) & set("*[?") for p in pattern)) class Subject(_hawkey.Subject): def __init__(self, pkg_spec, ignore_case=False): super(Subject, self).__init__(pkg_spec, ignore_case=ignore_case) def nsvcap_possibilities(self, *args, **kwargs): poss = super(Subject, self).nsvcap_possibilities(*args, **kwargs) for nsvcap in poss: yield NSVCAP(nsvcap=nsvcap) @property def _filename_pattern(self): return self.pattern.startswith('/') or self.pattern.startswith('*/') def _is_arch_specified(self, solution): if solution['nevra'] and solution['nevra'].arch: return is_glob_pattern(solution['nevra'].arch) return False def nevra_possibilities(self, form=None): warnings.simplefilter('always', DeprecationWarning) msg = "The function 'nevra_possibilities' is deprecated. " \ "Please use 'get_nevra_possibilities' instead. The function will be removed on " \ "2018-01-01" warnings.warn(msg, DeprecationWarning) for nevra in super(Subject, self).get_nevra_possibilities(forms=form): yield NEVRA(nevra=nevra) def _get_best_selectors(self, base, forms=None, obsoletes=True, reponame=None, reports=False, solution=None): if solution is None: solution = self.get_best_solution(base.sack, forms=forms, with_src=False) q = solution['query'] if len(q) == 0: return [] q = self._apply_security_filters(q, base) if not q: # we don't report the exact reason why any selector returned - reasons can be only src # found, no package or not in requested repository. We should improve it in libdnf # after movement of base.install() or base.distro_sync() return [] if not self._filename_pattern and is_glob_pattern(self.pattern) \ or solution['nevra'] and solution['nevra'].name is None: with_obsoletes = False if obsoletes and solution['nevra'] and solution['nevra'].has_just_name(): with_obsoletes = True installed_query = q.installed() if reponame: q = q.filter(reponame=reponame) available_query = q.available() installed_relevant_query = installed_query.filter( name=[pkg.name for pkg in available_query]) if reports: base._report_already_installed(installed_relevant_query) q = available_query.union(installed_relevant_query) sltrs = [] for name, pkgs_list in q._name_dict().items(): if with_obsoletes: pkgs_list = pkgs_list + base.sack.query().filter( obsoletes=pkgs_list).run() sltrs.append(self._list_or_query_to_selector(base.sack, pkgs_list)) return sltrs else: if obsoletes and solution['nevra'] and solution['nevra'].has_just_name(): q = q.union(base.sack.query().filter(obsoletes=q)) installed_query = q.installed() if reports: base._report_already_installed(installed_query) if reponame: q = q.filter(reponame=reponame).union(installed_query) if not q: return [] return [self._list_or_query_to_selector(base.sack, q)] def _apply_security_filters(self, query, base): query = base._merge_update_filters(query, warning=False) if not query: logger.warning('No security updates for argument "{}"'.format(self.pattern)) # translate return query @staticmethod def _list_or_query_to_selector(sack, list_or_query): sltr = Selector(sack) return sltr.set(pkg=list_or_query) class Repo(_hawkey.Repo): def __init__(self, name): warnings.simplefilter('always', DeprecationWarning) msg = "The class hawkey.Repo is deprecated. " \ "Please use dnf.repo.Repo instead. The class will be removed on 2019-12-31." warnings.warn(msg, DeprecationWarning) super(Repo, self).__init__(name) usr/lib/python3.6/site-packages/urllib3/packages/__init__.py000064400000000155152363354770017676 0ustar00from __future__ import absolute_import from . import ssl_match_hostname __all__ = ('ssl_match_hostname', ) lib64/python3.6/site-packages/yaml/__init__.py000064400000022607152363654750015056 0ustar00 from .error import * from .tokens import * from .events import * from .nodes import * from .loader import * from .dumper import * __version__ = '3.12' try: from .cyaml import * __with_libyaml__ = True except ImportError: __with_libyaml__ = False import io def scan(stream, Loader=Loader): """ Scan a YAML stream and produce scanning tokens. """ loader = Loader(stream) try: while loader.check_token(): yield loader.get_token() finally: loader.dispose() def parse(stream, Loader=Loader): """ Parse a YAML stream and produce parsing events. """ loader = Loader(stream) try: while loader.check_event(): yield loader.get_event() finally: loader.dispose() def compose(stream, Loader=Loader): """ Parse the first YAML document in a stream and produce the corresponding representation tree. """ loader = Loader(stream) try: return loader.get_single_node() finally: loader.dispose() def compose_all(stream, Loader=Loader): """ Parse all YAML documents in a stream and produce corresponding representation trees. """ loader = Loader(stream) try: while loader.check_node(): yield loader.get_node() finally: loader.dispose() def load(stream, Loader=Loader): """ Parse the first YAML document in a stream and produce the corresponding Python object. """ loader = Loader(stream) try: return loader.get_single_data() finally: loader.dispose() def load_all(stream, Loader=Loader): """ Parse all YAML documents in a stream and produce corresponding Python objects. """ loader = Loader(stream) try: while loader.check_data(): yield loader.get_data() finally: loader.dispose() def safe_load(stream): """ Parse the first YAML document in a stream and produce the corresponding Python object. Resolve only basic YAML tags. """ return load(stream, SafeLoader) def safe_load_all(stream): """ Parse all YAML documents in a stream and produce corresponding Python objects. Resolve only basic YAML tags. """ return load_all(stream, SafeLoader) def emit(events, stream=None, Dumper=Dumper, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None): """ Emit YAML parsing events into a stream. If stream is None, return the produced string instead. """ getvalue = None if stream is None: stream = io.StringIO() getvalue = stream.getvalue dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break) try: for event in events: dumper.emit(event) finally: dumper.dispose() if getvalue: return getvalue() def serialize_all(nodes, stream=None, Dumper=Dumper, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, version=None, tags=None): """ Serialize a sequence of representation trees into a YAML stream. If stream is None, return the produced string instead. """ getvalue = None if stream is None: if encoding is None: stream = io.StringIO() else: stream = io.BytesIO() getvalue = stream.getvalue dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break, encoding=encoding, version=version, tags=tags, explicit_start=explicit_start, explicit_end=explicit_end) try: dumper.open() for node in nodes: dumper.serialize(node) dumper.close() finally: dumper.dispose() if getvalue: return getvalue() def serialize(node, stream=None, Dumper=Dumper, **kwds): """ Serialize a representation tree into a YAML stream. If stream is None, return the produced string instead. """ return serialize_all([node], stream, Dumper=Dumper, **kwds) def dump_all(documents, stream=None, Dumper=Dumper, default_style=None, default_flow_style=None, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding=None, explicit_start=None, explicit_end=None, version=None, tags=None): """ Serialize a sequence of Python objects into a YAML stream. If stream is None, return the produced string instead. """ getvalue = None if stream is None: if encoding is None: stream = io.StringIO() else: stream = io.BytesIO() getvalue = stream.getvalue dumper = Dumper(stream, default_style=default_style, default_flow_style=default_flow_style, canonical=canonical, indent=indent, width=width, allow_unicode=allow_unicode, line_break=line_break, encoding=encoding, version=version, tags=tags, explicit_start=explicit_start, explicit_end=explicit_end) try: dumper.open() for data in documents: dumper.represent(data) dumper.close() finally: dumper.dispose() if getvalue: return getvalue() def dump(data, stream=None, Dumper=Dumper, **kwds): """ Serialize a Python object into a YAML stream. If stream is None, return the produced string instead. """ return dump_all([data], stream, Dumper=Dumper, **kwds) def safe_dump_all(documents, stream=None, **kwds): """ Serialize a sequence of Python objects into a YAML stream. Produce only basic YAML tags. If stream is None, return the produced string instead. """ return dump_all(documents, stream, Dumper=SafeDumper, **kwds) def safe_dump(data, stream=None, **kwds): """ Serialize a Python object into a YAML stream. Produce only basic YAML tags. If stream is None, return the produced string instead. """ return dump_all([data], stream, Dumper=SafeDumper, **kwds) def add_implicit_resolver(tag, regexp, first=None, Loader=Loader, Dumper=Dumper): """ Add an implicit scalar detector. If an implicit scalar value matches the given regexp, the corresponding tag is assigned to the scalar. first is a sequence of possible initial characters or None. """ Loader.add_implicit_resolver(tag, regexp, first) Dumper.add_implicit_resolver(tag, regexp, first) def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper): """ Add a path based resolver for the given tag. A path is a list of keys that forms a path to a node in the representation tree. Keys can be string values, integers, or None. """ Loader.add_path_resolver(tag, path, kind) Dumper.add_path_resolver(tag, path, kind) def add_constructor(tag, constructor, Loader=Loader): """ Add a constructor for the given tag. Constructor is a function that accepts a Loader instance and a node object and produces the corresponding Python object. """ Loader.add_constructor(tag, constructor) def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader): """ Add a multi-constructor for the given tag prefix. Multi-constructor is called for a node if its tag starts with tag_prefix. Multi-constructor accepts a Loader instance, a tag suffix, and a node object and produces the corresponding Python object. """ Loader.add_multi_constructor(tag_prefix, multi_constructor) def add_representer(data_type, representer, Dumper=Dumper): """ Add a representer for the given type. Representer is a function accepting a Dumper instance and an instance of the given data type and producing the corresponding representation node. """ Dumper.add_representer(data_type, representer) def add_multi_representer(data_type, multi_representer, Dumper=Dumper): """ Add a representer for the given type. Multi-representer is a function accepting a Dumper instance and an instance of the given data type or subtype and producing the corresponding representation node. """ Dumper.add_multi_representer(data_type, multi_representer) class YAMLObjectMetaclass(type): """ The metaclass for YAMLObject. """ def __init__(cls, name, bases, kwds): super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds) if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None: cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml) cls.yaml_dumper.add_representer(cls, cls.to_yaml) class YAMLObject(metaclass=YAMLObjectMetaclass): """ An object that can dump itself to a YAML stream and load itself from a YAML stream. """ __slots__ = () # no direct instantiation, so allow immutable subclasses yaml_loader = Loader yaml_dumper = Dumper yaml_tag = None yaml_flow_style = None @classmethod def from_yaml(cls, loader, node): """ Convert a representation node to a Python object. """ return loader.construct_yaml_object(node, cls) @classmethod def to_yaml(cls, dumper, data): """ Convert a Python object to a representation node. """ return dumper.represent_yaml_object(cls.yaml_tag, data, cls, flow_style=cls.yaml_flow_style) usr/lib64/python2.7/idlelib/idle_test/__init__.py000064400000001212152364554710015546 0ustar00'''idlelib.idle_test is a private implementation of test.test_idle, which tests the IDLE application as part of the stdlib test suite. Run IDLE tests alone with "python -m test.test_idle". This package and its contained modules are subject to change and any direct use is at your own risk. ''' from os.path import dirname def load_tests(loader, standard_tests, pattern): this_dir = dirname(__file__) top_dir = dirname(dirname(this_dir)) package_tests = loader.discover(start_dir=this_dir, pattern='test*.py', top_level_dir=top_dir) standard_tests.addTests(package_tests) return standard_tests opt/alt/python37/lib64/python3.7/dbm/__init__.py000064400000013227152364621410015176 0ustar00"""Generic interface to all dbm clones. Use import dbm d = dbm.open(file, 'w', 0o666) The returned object is a dbm.gnu, dbm.ndbm or dbm.dumb object, dependent on the type of database being opened (determined by the whichdb function) in the case of an existing dbm. If the dbm does not exist and the create or new flag ('c' or 'n') was specified, the dbm type will be determined by the availability of the modules (tested in the above order). It has the following interface (key and data are strings): d[key] = data # store data at key (may override data at # existing key) data = d[key] # retrieve data at key (raise KeyError if no # such key) del d[key] # delete data stored at key (raises KeyError # if no such key) flag = key in d # true if the key exists list = d.keys() # return a list of all existing keys (slow!) Future versions may change the order in which implementations are tested for existence, and add interfaces to other dbm-like implementations. """ __all__ = ['open', 'whichdb', 'error'] import io import os import struct import sys class error(Exception): pass _names = ['dbm.gnu', 'dbm.ndbm', 'dbm.dumb'] _defaultmod = None _modules = {} error = (error, OSError) try: from dbm import ndbm except ImportError: ndbm = None def open(file, flag='r', mode=0o666): """Open or create database at path given by *file*. Optional argument *flag* can be 'r' (default) for read-only access, 'w' for read-write access of an existing database, 'c' for read-write access to a new or existing database, and 'n' for read-write access to a new database. Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it only if it doesn't exist; and 'n' always creates a new database. """ global _defaultmod if _defaultmod is None: for name in _names: try: mod = __import__(name, fromlist=['open']) except ImportError: continue if not _defaultmod: _defaultmod = mod _modules[name] = mod if not _defaultmod: raise ImportError("no dbm clone found; tried %s" % _names) # guess the type of an existing database, if not creating a new one result = whichdb(file) if 'n' not in flag else None if result is None: # db doesn't exist or 'n' flag was specified to create a new db if 'c' in flag or 'n' in flag: # file doesn't exist and the new flag was used so use default type mod = _defaultmod else: raise error[0]("need 'c' or 'n' flag to open new db") elif result == "": # db type cannot be determined raise error[0]("db type could not be determined") elif result not in _modules: raise error[0]("db type is {0}, but the module is not " "available".format(result)) else: mod = _modules[result] return mod.open(file, flag, mode) def whichdb(filename): """Guess which db package to use to open a db file. Return values: - None if the database file can't be read; - empty string if the file can be read but can't be recognized - the name of the dbm submodule (e.g. "ndbm" or "gnu") if recognized. Importing the given module may still fail, and opening the database using that module may still fail. """ # Check for ndbm first -- this has a .pag and a .dir file try: f = io.open(filename + ".pag", "rb") f.close() f = io.open(filename + ".dir", "rb") f.close() return "dbm.ndbm" except OSError: # some dbm emulations based on Berkeley DB generate a .db file # some do not, but they should be caught by the bsd checks try: f = io.open(filename + ".db", "rb") f.close() # guarantee we can actually open the file using dbm # kind of overkill, but since we are dealing with emulations # it seems like a prudent step if ndbm is not None: d = ndbm.open(filename) d.close() return "dbm.ndbm" except OSError: pass # Check for dumbdbm next -- this has a .dir and a .dat file try: # First check for presence of files os.stat(filename + ".dat") size = os.stat(filename + ".dir").st_size # dumbdbm files with no keys are empty if size == 0: return "dbm.dumb" f = io.open(filename + ".dir", "rb") try: if f.read(1) in (b"'", b'"'): return "dbm.dumb" finally: f.close() except OSError: pass # See if the file exists, return None if not try: f = io.open(filename, "rb") except OSError: return None with f: # Read the start of the file -- the magic number s16 = f.read(16) s = s16[0:4] # Return "" if not at least 4 bytes if len(s) != 4: return "" # Convert to 4-byte int in native byte order -- return "" if impossible try: (magic,) = struct.unpack("=l", s) except struct.error: return "" # Check for GNU dbm if magic in (0x13579ace, 0x13579acd, 0x13579acf): return "dbm.gnu" # Later versions of Berkeley db hash file have a 12-byte pad in # front of the file type try: (magic,) = struct.unpack("=l", s16[-4:]) except struct.error: return "" # Unknown return "" if __name__ == "__main__": for filename in sys.argv[1:]: print(whichdb(filename) or "UNKNOWN", filename) opt/alt/python27/lib/python2.7/site-packages/pip/__init__.py000064400000000707152365075240017574 0ustar00from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: from typing import List, Optional __version__ = "20.2.4" def main(args=None): # type: (Optional[List[str]]) -> int """This is an internal API only meant for use by pip's own console scripts. For additional details, see https://github.com/pypa/pip/issues/7498. """ from pip._internal.utils.entrypoints import _wrapper return _wrapper(args) opt/alt/python38/lib/python3.8/site-packages/humanize/__init__.py000064400000001644152365373670020641 0ustar00"""Main package for humanize.""" from humanize.filesize import naturalsize from humanize.i18n import activate, deactivate, thousands_separator from humanize.number import ( apnumber, clamp, fractional, intcomma, intword, ordinal, scientific, ) from humanize.time import ( naturaldate, naturalday, naturaldelta, naturaltime, precisedelta, ) try: # Python 3.8+ import importlib.metadata as importlib_metadata except ImportError: # " __author__ = "José Padilla" __email__ = "hello@jpadilla.com" __license__ = "MIT" __copyright__ = "Copyright 2015-2020 José Padilla" __all__ = [ "PyJWS", "PyJWT", "PyJWKClient", "PyJWK", "PyJWKSet", "decode", "encode", "get_unverified_header", "register_algorithm", "unregister_algorithm", # Exceptions "DecodeError", "ExpiredSignatureError", "ImmatureSignatureError", "InvalidAlgorithmError", "InvalidAudienceError", "InvalidIssuedAtError", "InvalidIssuerError", "InvalidKeyError", "InvalidSignatureError", "InvalidTokenError", "MissingRequiredClaimError", "PyJWKClientError", "PyJWKError", "PyJWKSetError", "PyJWTError", ] opt/alt/python37/lib64/python3.7/distutils/__init__.py000064400000000354152367526500016464 0ustar00"""distutils The main package for the Python Module Distribution Utilities. Normally used from a setup script as from distutils.core import setup setup (...) """ import sys __version__ = sys.version[:sys.version.index(' ')]