�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!usr/lib64/python2.7/hotshot/__init__.py000064400000005156152526356760013676 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) usr/lib64/python2.7/xml/dom/__init__.py000064400000007636152526412270013557 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 usr/lib64/python2.7/encodings/__init__.py000064400000013102152526417550014140 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/lib64/python3.6/logging/__init__.py000064400000213145152526446470013631 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/lib64/python3.12/re/__init__.py000064400000037673152526475550012701 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.12/dbm/__init__.py000064400000013372152526571600013014 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) usr/lib64/python3.6/http/__init__.py000064400000013501152526603030013137 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/python3.6/test/__init__.py000064400000000057152526604570013153 0ustar00# Dummy file to make this directory a package. usr/lib64/python3.12/ensurepip/__init__.py000064400000022345152527044450014263 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, ) usr/lib/python2.7/site-packages/bs4/__init__.py000064400000054560152527055060015235 0ustar00"""Beautiful Soup Elixir and Tonic "The Screen-Scraper's Friend" http://www.crummy.com/software/BeautifulSoup/ Beautiful Soup uses a pluggable XML or HTML parser to parse a (possibly invalid) document into a tree representation. Beautiful Soup provides methods and Pythonic idioms that make it easy to navigate, search, and modify the parse tree. Beautiful Soup works with Python 2.7 and up. It works better if lxml and/or html5lib is installed. For more than you ever wanted to know about Beautiful Soup, see the documentation: http://www.crummy.com/software/BeautifulSoup/bs4/doc/ """ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. __author__ = "Leonard Richardson (leonardr@segfault.org)" __version__ = "4.6.3" __copyright__ = "Copyright (c) 2004-2018 Leonard Richardson" __license__ = "MIT" __all__ = ['BeautifulSoup'] import os import re import sys import traceback import warnings from .builder import builder_registry, ParserRejectedMarkup from .dammit import UnicodeDammit from .element import ( CData, Comment, DEFAULT_OUTPUT_ENCODING, Declaration, Doctype, NavigableString, PageElement, ProcessingInstruction, ResultSet, SoupStrainer, Tag, ) # The very first thing we do is give a useful error if someone is # running this code under Python 3 without converting it. 'You are trying to run the Python 2 version of Beautiful Soup under Python 3. This will not work.'<>'You need to convert the code, either by installing it (`python setup.py install`) or by running 2to3 (`2to3 -w bs4`).' class BeautifulSoup(Tag): """ This class defines the basic interface called by the tree builders. These methods will be called by the parser: reset() feed(markup) The tree builder may call these methods from its feed() implementation: handle_starttag(name, attrs) # See note about return value handle_endtag(name) handle_data(data) # Appends to the current data node endData(containerClass=NavigableString) # Ends the current data node No matter how complicated the underlying parser is, you should be able to build a tree using 'start tag' events, 'end tag' events, 'data' events, and "done with data" events. If you encounter an empty-element tag (aka a self-closing tag, like HTML's
tag), call handle_starttag and then handle_endtag. """ ROOT_TAG_NAME = u'[document]' # If the end-user gives no indication which tree builder they # want, look for one with these features. DEFAULT_BUILDER_FEATURES = ['html', 'fast'] ASCII_SPACES = '\x20\x0a\x09\x0c\x0d' NO_PARSER_SPECIFIED_WARNING = "No parser was explicitly specified, so I'm using the best available %(markup_type)s parser for this system (\"%(parser)s\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n\nThe code that caused this warning is on line %(line_number)s of the file %(filename)s. To get rid of this warning, pass the additional argument 'features=\"%(parser)s\"' to the BeautifulSoup constructor.\n" def __init__(self, markup="", features=None, builder=None, parse_only=None, from_encoding=None, exclude_encodings=None, **kwargs): """Constructor. :param markup: A string or a file-like object representing markup to be parsed. :param features: Desirable features of the parser to be used. This may be the name of a specific parser ("lxml", "lxml-xml", "html.parser", or "html5lib") or it may be the type of markup to be used ("html", "html5", "xml"). It's recommended that you name a specific parser, so that Beautiful Soup gives you the same results across platforms and virtual environments. :param builder: A specific TreeBuilder to use instead of looking one up based on `features`. You shouldn't need to use this. :param parse_only: A SoupStrainer. Only parts of the document matching the SoupStrainer will be considered. This is useful when parsing part of a document that would otherwise be too large to fit into memory. :param from_encoding: A string indicating the encoding of the document to be parsed. Pass this in if Beautiful Soup is guessing wrongly about the document's encoding. :param exclude_encodings: A list of strings indicating encodings known to be wrong. Pass this in if you don't know the document's encoding but you know Beautiful Soup's guess is wrong. :param kwargs: For backwards compatibility purposes, the constructor accepts certain keyword arguments used in Beautiful Soup 3. None of these arguments do anything in Beautiful Soup 4 and there's no need to actually pass keyword arguments into the constructor. """ if 'convertEntities' in kwargs: warnings.warn( "BS4 does not respect the convertEntities argument to the " "BeautifulSoup constructor. Entities are always converted " "to Unicode characters.") if 'markupMassage' in kwargs: del kwargs['markupMassage'] warnings.warn( "BS4 does not respect the markupMassage argument to the " "BeautifulSoup constructor. The tree builder is responsible " "for any necessary markup massage.") if 'smartQuotesTo' in kwargs: del kwargs['smartQuotesTo'] warnings.warn( "BS4 does not respect the smartQuotesTo argument to the " "BeautifulSoup constructor. Smart quotes are always converted " "to Unicode characters.") if 'selfClosingTags' in kwargs: del kwargs['selfClosingTags'] warnings.warn( "BS4 does not respect the selfClosingTags argument to the " "BeautifulSoup constructor. The tree builder is responsible " "for understanding self-closing tags.") if 'isHTML' in kwargs: del kwargs['isHTML'] warnings.warn( "BS4 does not respect the isHTML argument to the " "BeautifulSoup constructor. Suggest you use " "features='lxml' for HTML and features='lxml-xml' for " "XML.") def deprecated_argument(old_name, new_name): if old_name in kwargs: warnings.warn( 'The "%s" argument to the BeautifulSoup constructor ' 'has been renamed to "%s."' % (old_name, new_name)) value = kwargs[old_name] del kwargs[old_name] return value return None parse_only = parse_only or deprecated_argument( "parseOnlyThese", "parse_only") from_encoding = from_encoding or deprecated_argument( "fromEncoding", "from_encoding") if from_encoding and isinstance(markup, unicode): warnings.warn("You provided Unicode markup but also provided a value for from_encoding. Your from_encoding will be ignored.") from_encoding = None if len(kwargs) > 0: arg = kwargs.keys().pop() raise TypeError( "__init__() got an unexpected keyword argument '%s'" % arg) if builder is None: original_features = features if isinstance(features, basestring): features = [features] if features is None or len(features) == 0: features = self.DEFAULT_BUILDER_FEATURES builder_class = builder_registry.lookup(*features) if builder_class is None: raise FeatureNotFound( "Couldn't find a tree builder with the features you " "requested: %s. Do you need to install a parser library?" % ",".join(features)) builder = builder_class() if not (original_features == builder.NAME or original_features in builder.ALTERNATE_NAMES): if builder.is_xml: markup_type = "XML" else: markup_type = "HTML" # This code adapted from warnings.py so that we get the same line # of code as our warnings.warn() call gets, even if the answer is wrong # (as it may be in a multithreading situation). caller = None try: caller = sys._getframe(1) except ValueError: pass if caller: globals = caller.f_globals line_number = caller.f_lineno else: globals = sys.__dict__ line_number= 1 filename = globals.get('__file__') if filename: fnl = filename.lower() if fnl.endswith((".pyc", ".pyo")): filename = filename[:-1] if filename: # If there is no filename at all, the user is most likely in a REPL, # and the warning is not necessary. values = dict( filename=filename, line_number=line_number, parser=builder.NAME, markup_type=markup_type ) warnings.warn(self.NO_PARSER_SPECIFIED_WARNING % values, stacklevel=2) self.builder = builder self.is_xml = builder.is_xml self.known_xml = self.is_xml self.builder.soup = self self.parse_only = parse_only if hasattr(markup, 'read'): # It's a file-type object. markup = markup.read() elif len(markup) <= 256 and ( (isinstance(markup, bytes) and not b'<' in markup) or (isinstance(markup, unicode) and not u'<' in markup) ): # Print out warnings for a couple beginner problems # involving passing non-markup to Beautiful Soup. # Beautiful Soup will still parse the input as markup, # just in case that's what the user really wants. if (isinstance(markup, unicode) and not os.path.supports_unicode_filenames): possible_filename = markup.encode("utf8") else: possible_filename = markup is_file = False try: is_file = os.path.exists(possible_filename) except Exception, e: # This is almost certainly a problem involving # characters not valid in filenames on this # system. Just let it go. pass if is_file: if isinstance(markup, unicode): markup = markup.encode("utf8") warnings.warn( '"%s" looks like a filename, not markup. You should' ' probably open this file and pass the filehandle into' ' Beautiful Soup.' % markup) self._check_markup_is_url(markup) for (self.markup, self.original_encoding, self.declared_html_encoding, self.contains_replacement_characters) in ( self.builder.prepare_markup( markup, from_encoding, exclude_encodings=exclude_encodings)): self.reset() try: self._feed() break except ParserRejectedMarkup: pass # Clear out the markup and remove the builder's circular # reference to this object. self.markup = None self.builder.soup = None def __copy__(self): copy = type(self)( self.encode('utf-8'), builder=self.builder, from_encoding='utf-8' ) # Although we encoded the tree to UTF-8, that may not have # been the encoding of the original markup. Set the copy's # .original_encoding to reflect the original object's # .original_encoding. copy.original_encoding = self.original_encoding return copy def __getstate__(self): # Frequently a tree builder can't be pickled. d = dict(self.__dict__) if 'builder' in d and not self.builder.picklable: d['builder'] = None return d @staticmethod def _check_markup_is_url(markup): """ Check if markup looks like it's actually a url and raise a warning if so. Markup can be unicode or str (py2) / bytes (py3). """ if isinstance(markup, bytes): space = b' ' cant_start_with = (b"http:", b"https:") elif isinstance(markup, unicode): space = u' ' cant_start_with = (u"http:", u"https:") else: return if any(markup.startswith(prefix) for prefix in cant_start_with): if not space in markup: if isinstance(markup, bytes): decoded_markup = markup.decode('utf-8', 'replace') else: decoded_markup = markup warnings.warn( '"%s" looks like a URL. Beautiful Soup is not an' ' HTTP client. You should probably use an HTTP client like' ' requests to get the document behind the URL, and feed' ' that document to Beautiful Soup.' % decoded_markup ) def _feed(self): # Convert the document to Unicode. self.builder.reset() self.builder.feed(self.markup) # Close out any unfinished strings and close all the open tags. self.endData() while self.currentTag.name != self.ROOT_TAG_NAME: self.popTag() def reset(self): Tag.__init__(self, self, self.builder, self.ROOT_TAG_NAME) self.hidden = 1 self.builder.reset() self.current_data = [] self.currentTag = None self.tagStack = [] self.preserve_whitespace_tag_stack = [] self.pushTag(self) def new_tag(self, name, namespace=None, nsprefix=None, attrs={}, **kwattrs): """Create a new tag associated with this soup.""" kwattrs.update(attrs) return Tag(None, self.builder, name, namespace, nsprefix, kwattrs) def new_string(self, s, subclass=NavigableString): """Create a new NavigableString associated with this soup.""" return subclass(s) def insert_before(self, successor): raise NotImplementedError("BeautifulSoup objects don't support insert_before().") def insert_after(self, successor): raise NotImplementedError("BeautifulSoup objects don't support insert_after().") def popTag(self): tag = self.tagStack.pop() if self.preserve_whitespace_tag_stack and tag == self.preserve_whitespace_tag_stack[-1]: self.preserve_whitespace_tag_stack.pop() #print "Pop", tag.name if self.tagStack: self.currentTag = self.tagStack[-1] return self.currentTag def pushTag(self, tag): #print "Push", tag.name if self.currentTag: self.currentTag.contents.append(tag) self.tagStack.append(tag) self.currentTag = self.tagStack[-1] if tag.name in self.builder.preserve_whitespace_tags: self.preserve_whitespace_tag_stack.append(tag) def endData(self, containerClass=NavigableString): if self.current_data: current_data = u''.join(self.current_data) # If whitespace is not preserved, and this string contains # nothing but ASCII spaces, replace it with a single space # or newline. if not self.preserve_whitespace_tag_stack: strippable = True for i in current_data: if i not in self.ASCII_SPACES: strippable = False break if strippable: if '\n' in current_data: current_data = '\n' else: current_data = ' ' # Reset the data collector. self.current_data = [] # Should we add this string to the tree at all? if self.parse_only and len(self.tagStack) <= 1 and \ (not self.parse_only.text or \ not self.parse_only.search(current_data)): return o = containerClass(current_data) self.object_was_parsed(o) def object_was_parsed(self, o, parent=None, most_recent_element=None): """Add an object to the parse tree.""" parent = parent or self.currentTag previous_element = most_recent_element or self._most_recent_element next_element = previous_sibling = next_sibling = None if isinstance(o, Tag): next_element = o.next_element next_sibling = o.next_sibling previous_sibling = o.previous_sibling if not previous_element: previous_element = o.previous_element o.setup(parent, previous_element, next_element, previous_sibling, next_sibling) self._most_recent_element = o parent.contents.append(o) if parent.next_sibling: # This node is being inserted into an element that has # already been parsed. Deal with any dangling references. index = len(parent.contents)-1 while index >= 0: if parent.contents[index] is o: break index -= 1 else: raise ValueError( "Error building tree: supposedly %r was inserted " "into %r after the fact, but I don't see it!" % ( o, parent ) ) if index == 0: previous_element = parent previous_sibling = None else: previous_element = previous_sibling = parent.contents[index-1] if index == len(parent.contents)-1: next_element = parent.next_sibling next_sibling = None else: next_element = next_sibling = parent.contents[index+1] o.previous_element = previous_element if previous_element: previous_element.next_element = o o.next_element = next_element if next_element: next_element.previous_element = o o.next_sibling = next_sibling if next_sibling: next_sibling.previous_sibling = o o.previous_sibling = previous_sibling if previous_sibling: previous_sibling.next_sibling = o def _popToTag(self, name, nsprefix=None, inclusivePop=True): """Pops the tag stack up to and including the most recent instance of the given tag. If inclusivePop is false, pops the tag stack up to but *not* including the most recent instqance of the given tag.""" #print "Popping to %s" % name if name == self.ROOT_TAG_NAME: # The BeautifulSoup object itself can never be popped. return most_recently_popped = None stack_size = len(self.tagStack) for i in range(stack_size - 1, 0, -1): t = self.tagStack[i] if (name == t.name and nsprefix == t.prefix): if inclusivePop: most_recently_popped = self.popTag() break most_recently_popped = self.popTag() return most_recently_popped def handle_starttag(self, name, namespace, nsprefix, attrs): """Push a start tag on to the stack. If this method returns None, the tag was rejected by the SoupStrainer. You should proceed as if the tag had not occurred in the document. For instance, if this was a self-closing tag, don't call handle_endtag. """ # print "Start tag %s: %s" % (name, attrs) self.endData() if (self.parse_only and len(self.tagStack) <= 1 and (self.parse_only.text or not self.parse_only.search_tag(name, attrs))): return None tag = Tag(self, self.builder, name, namespace, nsprefix, attrs, self.currentTag, self._most_recent_element) if tag is None: return tag if self._most_recent_element: self._most_recent_element.next_element = tag self._most_recent_element = tag self.pushTag(tag) return tag def handle_endtag(self, name, nsprefix=None): #print "End tag: " + name self.endData() self._popToTag(name, nsprefix) def handle_data(self, data): self.current_data.append(data) def decode(self, pretty_print=False, eventual_encoding=DEFAULT_OUTPUT_ENCODING, formatter="minimal"): """Returns a string or Unicode representation of this document. To get Unicode, pass None for encoding.""" if self.is_xml: # Print the XML declaration encoding_part = '' if eventual_encoding != None: encoding_part = ' encoding="%s"' % eventual_encoding prefix = u'\n' % encoding_part else: prefix = u'' if not pretty_print: indent_level = None else: indent_level = 0 return prefix + super(BeautifulSoup, self).decode( indent_level, eventual_encoding, formatter) # Alias to make it easier to type import: 'from bs4 import _soup' _s = BeautifulSoup _soup = BeautifulSoup class BeautifulStoneSoup(BeautifulSoup): """Deprecated interface to an XML parser.""" def __init__(self, *args, **kwargs): kwargs['features'] = 'xml' warnings.warn( 'The BeautifulStoneSoup class is deprecated. Instead of using ' 'it, pass features="xml" into the BeautifulSoup constructor.') super(BeautifulStoneSoup, self).__init__(*args, **kwargs) class StopParsing(Exception): pass class FeatureNotFound(ValueError): pass #By default, act as an HTML pretty-printer. if __name__ == '__main__': import sys soup = BeautifulSoup(sys.stdin) print soup.prettify() usr/lib64/python3.6/xml/__init__.py000064400000001055152527140200012755 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/logging/__init__.py000064400000170342152527146450013626 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.12/xml/etree/__init__.py000064400000003105152527410030014135 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/python2.7/curses/__init__.py000064400000003431152527410300013462 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 opt/alt/python311/lib64/python3.11/xml/dom/__init__.py000064400000007663152527423220016150 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.6/lib2to3/fixes/__init__.py000064400000000057152527631610014564 0ustar00# Dummy file to make this directory a package. usr/lib64/python2.7/email/__init__.py000064400000005450152527633760013271 0ustar00# Copyright (C) 2001-2006 Python Software Foundation # Author: Barry Warsaw # Contact: email-sig@python.org """A package for parsing, handling, and generating email messages.""" __version__ = '4.0.3' __all__ = [ # Old names 'base64MIME', 'Charset', 'Encoders', 'Errors', 'Generator', 'Header', 'Iterators', 'Message', 'MIMEAudio', 'MIMEBase', 'MIMEImage', 'MIMEMessage', 'MIMEMultipart', 'MIMENonMultipart', 'MIMEText', 'Parser', 'quopriMIME', 'Utils', 'message_from_string', 'message_from_file', # new names 'base64mime', 'charset', 'encoders', 'errors', 'generator', 'header', 'iterators', 'message', '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_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) # Lazy loading to provide name mapping from new-style names (PEP 8 compatible # email 4.0 module names), to old-style names (email 3.0 module names). import sys class LazyImporter(object): def __init__(self, module_name): self.__name__ = 'email.' + module_name def __getattr__(self, name): __import__(self.__name__) mod = sys.modules[self.__name__] self.__dict__.update(mod.__dict__) return getattr(mod, name) _LOWERNAMES = [ # email. -> email. 'Charset', 'Encoders', 'Errors', 'FeedParser', 'Generator', 'Header', 'Iterators', 'Message', 'Parser', 'Utils', 'base64MIME', 'quopriMIME', ] _MIMENAMES = [ # email.MIME -> email.mime. 'Audio', 'Base', 'Image', 'Message', 'Multipart', 'NonMultipart', 'Text', ] for _name in _LOWERNAMES: importer = LazyImporter(_name.lower()) sys.modules['email.' + _name] = importer setattr(sys.modules['email'], _name, importer) import email.mime for _name in _MIMENAMES: importer = LazyImporter('mime.' + _name.lower()) sys.modules['email.MIME' + _name] = importer setattr(sys.modules['email'], 'MIME' + _name, importer) setattr(sys.modules['email.mime'], _name, importer) usr/lib/python2.7/site-packages/pip/models/__init__.py000064400000000107152527654460016615 0ustar00from pip.models.index import Index, PyPI __all__ = ["Index", "PyPI"] usr/lib64/python3.6/json/__init__.py000064400000034074152527763570013162 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) usr/lib64/python3.12/multiprocessing/__init__.py000064400000001624152530004250015461 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/bsddb/__init__.py000064400000037164152530011630013243 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 #---------------------------------------------------------------------- usr/lib64/python3.6/sqlite3/__init__.py000064400000001772152530066470013561 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/ctypes/__init__.py000064400000040061152530070330013464 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.12/xml/dom/__init__.py000064400000007663152530077540013636 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/pip/__init__.py000064400000027236152530077760015342 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.12/xmlrpc/__init__.py000064400000000046152530136420013541 0ustar00# This directory is a Python package. usr/lib64/python3.12/xml/__init__.py000064400000001055152530205050013031 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/logging/__init__.py000064400000242755152530337740013711 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/python2.7/idlelib/__init__.py000064400000000440152530411350013557 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.6/html/__init__.py000064400000011224152530412100013113 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/json/__init__.py000064400000034601152530475760013151 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) usr/lib64/python3.6/dbm/__init__.py000064400000013227152530552560012735 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) usr/lib64/python2.7/unittest/__init__.py000064400000005336152530614570014054 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__.py000064400000015520152530617020014174 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/lib/python3.6/site-packages/firewall/__init__.py000064400000000000152530630720016322 0ustar00usr/lib64/python3.6/xml/etree/__init__.py000064400000003104152530722110014056 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/python2.7/test/__init__.py000064400000000057152530764140013146 0ustar00# Dummy file to make this directory a package. usr/lib64/python3.6/xml/dom/__init__.py000064400000007663152530771000013551 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.12/tomllib/__init__.py000064400000000464152530777760013724 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/lib/python3.6/site-packages/slip/dbus/__init__.py000064400000000336152531050000016421 0ustar00# -*- coding: utf-8 -*- from __future__ import absolute_import from . import bus from .bus import SessionBus, SystemBus, StarterBus from . import proxies from . import service from . import polkit from . import mainloop usr/lib64/python2.7/sqlite3/__init__.py000064400000001762152531213010013541 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/python2.7/compiler/__init__.py000064400000001777152531221360014004 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 usr/lib/python3.6/site-packages/nftables/__init__.py000064400000000030152531275710016323 0ustar00from .nftables import * usr/lib64/python3.12/ctypes/__init__.py000064400000043442152531313250013551 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() usr/lib64/python2.7/ctypes/__init__.py000064400000041366152531313630013501 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/lib64/python3.6/lib2to3/__init__.py000064400000000007152531402220013425 0ustar00#empty usr/lib64/python3.6/xml/sax/__init__.py000064400000007056152531404450013564 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/lib/python3.6/site-packages/bs4/__init__.py000064400000054530152531422070015224 0ustar00"""Beautiful Soup Elixir and Tonic "The Screen-Scraper's Friend" http://www.crummy.com/software/BeautifulSoup/ Beautiful Soup uses a pluggable XML or HTML parser to parse a (possibly invalid) document into a tree representation. Beautiful Soup provides methods and Pythonic idioms that make it easy to navigate, search, and modify the parse tree. Beautiful Soup works with Python 2.7 and up. It works better if lxml and/or html5lib is installed. For more than you ever wanted to know about Beautiful Soup, see the documentation: http://www.crummy.com/software/BeautifulSoup/bs4/doc/ """ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. __author__ = "Leonard Richardson (leonardr@segfault.org)" __version__ = "4.6.3" __copyright__ = "Copyright (c) 2004-2018 Leonard Richardson" __license__ = "MIT" __all__ = ['BeautifulSoup'] import os import re import sys import traceback import warnings from .builder import builder_registry, ParserRejectedMarkup from .dammit import UnicodeDammit from .element import ( CData, Comment, DEFAULT_OUTPUT_ENCODING, Declaration, Doctype, NavigableString, PageElement, ProcessingInstruction, ResultSet, SoupStrainer, Tag, ) # The very first thing we do is give a useful error if someone is # running this code under Python 3 without converting it. 'You are trying to run the Python 2 version of Beautiful Soup under Python 3. This will not work.'!='You need to convert the code, either by installing it (`python setup.py install`) or by running 2to3 (`2to3 -w bs4`).' class BeautifulSoup(Tag): """ This class defines the basic interface called by the tree builders. These methods will be called by the parser: reset() feed(markup) The tree builder may call these methods from its feed() implementation: handle_starttag(name, attrs) # See note about return value handle_endtag(name) handle_data(data) # Appends to the current data node endData(containerClass=NavigableString) # Ends the current data node No matter how complicated the underlying parser is, you should be able to build a tree using 'start tag' events, 'end tag' events, 'data' events, and "done with data" events. If you encounter an empty-element tag (aka a self-closing tag, like HTML's
tag), call handle_starttag and then handle_endtag. """ ROOT_TAG_NAME = '[document]' # If the end-user gives no indication which tree builder they # want, look for one with these features. DEFAULT_BUILDER_FEATURES = ['html', 'fast'] ASCII_SPACES = '\x20\x0a\x09\x0c\x0d' NO_PARSER_SPECIFIED_WARNING = "No parser was explicitly specified, so I'm using the best available %(markup_type)s parser for this system (\"%(parser)s\"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.\n\nThe code that caused this warning is on line %(line_number)s of the file %(filename)s. To get rid of this warning, pass the additional argument 'features=\"%(parser)s\"' to the BeautifulSoup constructor.\n" def __init__(self, markup="", features=None, builder=None, parse_only=None, from_encoding=None, exclude_encodings=None, **kwargs): """Constructor. :param markup: A string or a file-like object representing markup to be parsed. :param features: Desirable features of the parser to be used. This may be the name of a specific parser ("lxml", "lxml-xml", "html.parser", or "html5lib") or it may be the type of markup to be used ("html", "html5", "xml"). It's recommended that you name a specific parser, so that Beautiful Soup gives you the same results across platforms and virtual environments. :param builder: A specific TreeBuilder to use instead of looking one up based on `features`. You shouldn't need to use this. :param parse_only: A SoupStrainer. Only parts of the document matching the SoupStrainer will be considered. This is useful when parsing part of a document that would otherwise be too large to fit into memory. :param from_encoding: A string indicating the encoding of the document to be parsed. Pass this in if Beautiful Soup is guessing wrongly about the document's encoding. :param exclude_encodings: A list of strings indicating encodings known to be wrong. Pass this in if you don't know the document's encoding but you know Beautiful Soup's guess is wrong. :param kwargs: For backwards compatibility purposes, the constructor accepts certain keyword arguments used in Beautiful Soup 3. None of these arguments do anything in Beautiful Soup 4 and there's no need to actually pass keyword arguments into the constructor. """ if 'convertEntities' in kwargs: warnings.warn( "BS4 does not respect the convertEntities argument to the " "BeautifulSoup constructor. Entities are always converted " "to Unicode characters.") if 'markupMassage' in kwargs: del kwargs['markupMassage'] warnings.warn( "BS4 does not respect the markupMassage argument to the " "BeautifulSoup constructor. The tree builder is responsible " "for any necessary markup massage.") if 'smartQuotesTo' in kwargs: del kwargs['smartQuotesTo'] warnings.warn( "BS4 does not respect the smartQuotesTo argument to the " "BeautifulSoup constructor. Smart quotes are always converted " "to Unicode characters.") if 'selfClosingTags' in kwargs: del kwargs['selfClosingTags'] warnings.warn( "BS4 does not respect the selfClosingTags argument to the " "BeautifulSoup constructor. The tree builder is responsible " "for understanding self-closing tags.") if 'isHTML' in kwargs: del kwargs['isHTML'] warnings.warn( "BS4 does not respect the isHTML argument to the " "BeautifulSoup constructor. Suggest you use " "features='lxml' for HTML and features='lxml-xml' for " "XML.") def deprecated_argument(old_name, new_name): if old_name in kwargs: warnings.warn( 'The "%s" argument to the BeautifulSoup constructor ' 'has been renamed to "%s."' % (old_name, new_name)) value = kwargs[old_name] del kwargs[old_name] return value return None parse_only = parse_only or deprecated_argument( "parseOnlyThese", "parse_only") from_encoding = from_encoding or deprecated_argument( "fromEncoding", "from_encoding") if from_encoding and isinstance(markup, str): warnings.warn("You provided Unicode markup but also provided a value for from_encoding. Your from_encoding will be ignored.") from_encoding = None if len(kwargs) > 0: arg = list(kwargs.keys()).pop() raise TypeError( "__init__() got an unexpected keyword argument '%s'" % arg) if builder is None: original_features = features if isinstance(features, str): features = [features] if features is None or len(features) == 0: features = self.DEFAULT_BUILDER_FEATURES builder_class = builder_registry.lookup(*features) if builder_class is None: raise FeatureNotFound( "Couldn't find a tree builder with the features you " "requested: %s. Do you need to install a parser library?" % ",".join(features)) builder = builder_class() if not (original_features == builder.NAME or original_features in builder.ALTERNATE_NAMES): if builder.is_xml: markup_type = "XML" else: markup_type = "HTML" # This code adapted from warnings.py so that we get the same line # of code as our warnings.warn() call gets, even if the answer is wrong # (as it may be in a multithreading situation). caller = None try: caller = sys._getframe(1) except ValueError: pass if caller: globals = caller.f_globals line_number = caller.f_lineno else: globals = sys.__dict__ line_number= 1 filename = globals.get('__file__') if filename: fnl = filename.lower() if fnl.endswith((".pyc", ".pyo")): filename = filename[:-1] if filename: # If there is no filename at all, the user is most likely in a REPL, # and the warning is not necessary. values = dict( filename=filename, line_number=line_number, parser=builder.NAME, markup_type=markup_type ) warnings.warn(self.NO_PARSER_SPECIFIED_WARNING % values, stacklevel=2) self.builder = builder self.is_xml = builder.is_xml self.known_xml = self.is_xml self.builder.soup = self self.parse_only = parse_only if hasattr(markup, 'read'): # It's a file-type object. markup = markup.read() elif len(markup) <= 256 and ( (isinstance(markup, bytes) and not b'<' in markup) or (isinstance(markup, str) and not '<' in markup) ): # Print out warnings for a couple beginner problems # involving passing non-markup to Beautiful Soup. # Beautiful Soup will still parse the input as markup, # just in case that's what the user really wants. if (isinstance(markup, str) and not os.path.supports_unicode_filenames): possible_filename = markup.encode("utf8") else: possible_filename = markup is_file = False try: is_file = os.path.exists(possible_filename) except Exception as e: # This is almost certainly a problem involving # characters not valid in filenames on this # system. Just let it go. pass if is_file: if isinstance(markup, str): markup = markup.encode("utf8") warnings.warn( '"%s" looks like a filename, not markup. You should' ' probably open this file and pass the filehandle into' ' Beautiful Soup.' % markup) self._check_markup_is_url(markup) for (self.markup, self.original_encoding, self.declared_html_encoding, self.contains_replacement_characters) in ( self.builder.prepare_markup( markup, from_encoding, exclude_encodings=exclude_encodings)): self.reset() try: self._feed() break except ParserRejectedMarkup: pass # Clear out the markup and remove the builder's circular # reference to this object. self.markup = None self.builder.soup = None def __copy__(self): copy = type(self)( self.encode('utf-8'), builder=self.builder, from_encoding='utf-8' ) # Although we encoded the tree to UTF-8, that may not have # been the encoding of the original markup. Set the copy's # .original_encoding to reflect the original object's # .original_encoding. copy.original_encoding = self.original_encoding return copy def __getstate__(self): # Frequently a tree builder can't be pickled. d = dict(self.__dict__) if 'builder' in d and not self.builder.picklable: d['builder'] = None return d @staticmethod def _check_markup_is_url(markup): """ Check if markup looks like it's actually a url and raise a warning if so. Markup can be unicode or str (py2) / bytes (py3). """ if isinstance(markup, bytes): space = b' ' cant_start_with = (b"http:", b"https:") elif isinstance(markup, str): space = ' ' cant_start_with = ("http:", "https:") else: return if any(markup.startswith(prefix) for prefix in cant_start_with): if not space in markup: if isinstance(markup, bytes): decoded_markup = markup.decode('utf-8', 'replace') else: decoded_markup = markup warnings.warn( '"%s" looks like a URL. Beautiful Soup is not an' ' HTTP client. You should probably use an HTTP client like' ' requests to get the document behind the URL, and feed' ' that document to Beautiful Soup.' % decoded_markup ) def _feed(self): # Convert the document to Unicode. self.builder.reset() self.builder.feed(self.markup) # Close out any unfinished strings and close all the open tags. self.endData() while self.currentTag.name != self.ROOT_TAG_NAME: self.popTag() def reset(self): Tag.__init__(self, self, self.builder, self.ROOT_TAG_NAME) self.hidden = 1 self.builder.reset() self.current_data = [] self.currentTag = None self.tagStack = [] self.preserve_whitespace_tag_stack = [] self.pushTag(self) def new_tag(self, name, namespace=None, nsprefix=None, attrs={}, **kwattrs): """Create a new tag associated with this soup.""" kwattrs.update(attrs) return Tag(None, self.builder, name, namespace, nsprefix, kwattrs) def new_string(self, s, subclass=NavigableString): """Create a new NavigableString associated with this soup.""" return subclass(s) def insert_before(self, successor): raise NotImplementedError("BeautifulSoup objects don't support insert_before().") def insert_after(self, successor): raise NotImplementedError("BeautifulSoup objects don't support insert_after().") def popTag(self): tag = self.tagStack.pop() if self.preserve_whitespace_tag_stack and tag == self.preserve_whitespace_tag_stack[-1]: self.preserve_whitespace_tag_stack.pop() #print "Pop", tag.name if self.tagStack: self.currentTag = self.tagStack[-1] return self.currentTag def pushTag(self, tag): #print "Push", tag.name if self.currentTag: self.currentTag.contents.append(tag) self.tagStack.append(tag) self.currentTag = self.tagStack[-1] if tag.name in self.builder.preserve_whitespace_tags: self.preserve_whitespace_tag_stack.append(tag) def endData(self, containerClass=NavigableString): if self.current_data: current_data = ''.join(self.current_data) # If whitespace is not preserved, and this string contains # nothing but ASCII spaces, replace it with a single space # or newline. if not self.preserve_whitespace_tag_stack: strippable = True for i in current_data: if i not in self.ASCII_SPACES: strippable = False break if strippable: if '\n' in current_data: current_data = '\n' else: current_data = ' ' # Reset the data collector. self.current_data = [] # Should we add this string to the tree at all? if self.parse_only and len(self.tagStack) <= 1 and \ (not self.parse_only.text or \ not self.parse_only.search(current_data)): return o = containerClass(current_data) self.object_was_parsed(o) def object_was_parsed(self, o, parent=None, most_recent_element=None): """Add an object to the parse tree.""" parent = parent or self.currentTag previous_element = most_recent_element or self._most_recent_element next_element = previous_sibling = next_sibling = None if isinstance(o, Tag): next_element = o.next_element next_sibling = o.next_sibling previous_sibling = o.previous_sibling if not previous_element: previous_element = o.previous_element o.setup(parent, previous_element, next_element, previous_sibling, next_sibling) self._most_recent_element = o parent.contents.append(o) if parent.next_sibling: # This node is being inserted into an element that has # already been parsed. Deal with any dangling references. index = len(parent.contents)-1 while index >= 0: if parent.contents[index] is o: break index -= 1 else: raise ValueError( "Error building tree: supposedly %r was inserted " "into %r after the fact, but I don't see it!" % ( o, parent ) ) if index == 0: previous_element = parent previous_sibling = None else: previous_element = previous_sibling = parent.contents[index-1] if index == len(parent.contents)-1: next_element = parent.next_sibling next_sibling = None else: next_element = next_sibling = parent.contents[index+1] o.previous_element = previous_element if previous_element: previous_element.next_element = o o.next_element = next_element if next_element: next_element.previous_element = o o.next_sibling = next_sibling if next_sibling: next_sibling.previous_sibling = o o.previous_sibling = previous_sibling if previous_sibling: previous_sibling.next_sibling = o def _popToTag(self, name, nsprefix=None, inclusivePop=True): """Pops the tag stack up to and including the most recent instance of the given tag. If inclusivePop is false, pops the tag stack up to but *not* including the most recent instqance of the given tag.""" #print "Popping to %s" % name if name == self.ROOT_TAG_NAME: # The BeautifulSoup object itself can never be popped. return most_recently_popped = None stack_size = len(self.tagStack) for i in range(stack_size - 1, 0, -1): t = self.tagStack[i] if (name == t.name and nsprefix == t.prefix): if inclusivePop: most_recently_popped = self.popTag() break most_recently_popped = self.popTag() return most_recently_popped def handle_starttag(self, name, namespace, nsprefix, attrs): """Push a start tag on to the stack. If this method returns None, the tag was rejected by the SoupStrainer. You should proceed as if the tag had not occurred in the document. For instance, if this was a self-closing tag, don't call handle_endtag. """ # print "Start tag %s: %s" % (name, attrs) self.endData() if (self.parse_only and len(self.tagStack) <= 1 and (self.parse_only.text or not self.parse_only.search_tag(name, attrs))): return None tag = Tag(self, self.builder, name, namespace, nsprefix, attrs, self.currentTag, self._most_recent_element) if tag is None: return tag if self._most_recent_element: self._most_recent_element.next_element = tag self._most_recent_element = tag self.pushTag(tag) return tag def handle_endtag(self, name, nsprefix=None): #print "End tag: " + name self.endData() self._popToTag(name, nsprefix) def handle_data(self, data): self.current_data.append(data) def decode(self, pretty_print=False, eventual_encoding=DEFAULT_OUTPUT_ENCODING, formatter="minimal"): """Returns a string or Unicode representation of this document. To get Unicode, pass None for encoding.""" if self.is_xml: # Print the XML declaration encoding_part = '' if eventual_encoding != None: encoding_part = ' encoding="%s"' % eventual_encoding prefix = '\n' % encoding_part else: prefix = '' if not pretty_print: indent_level = None else: indent_level = 0 return prefix + super(BeautifulSoup, self).decode( indent_level, eventual_encoding, formatter) # Alias to make it easier to type import: 'from bs4 import _soup' _s = BeautifulSoup _soup = BeautifulSoup class BeautifulStoneSoup(BeautifulSoup): """Deprecated interface to an XML parser.""" def __init__(self, *args, **kwargs): kwargs['features'] = 'xml' warnings.warn( 'The BeautifulStoneSoup class is deprecated. Instead of using ' 'it, pass features="xml" into the BeautifulSoup constructor.') super(BeautifulStoneSoup, self).__init__(*args, **kwargs) class StopParsing(Exception): pass class FeatureNotFound(ValueError): pass #By default, act as an HTML pretty-printer. if __name__ == '__main__': import sys soup = BeautifulSoup(sys.stdin) print((soup.prettify())) usr/lib/python2.7/site-packages/pip/compat/__init__.py000064400000011100152531430420016567 0ustar00"""Stuff that differs in different Python versions and platform distributions.""" from __future__ import absolute_import, division import os import sys from pip._vendor.six import text_type try: from logging.config import dictConfig as logging_dictConfig except ImportError: from pip.compat.dictconfig import dictConfig as logging_dictConfig try: from collections import OrderedDict except ImportError: from pip._vendor.ordereddict import OrderedDict try: import ipaddress except ImportError: try: from pip._vendor import ipaddress except ImportError: import ipaddr as ipaddress ipaddress.ip_address = ipaddress.IPAddress ipaddress.ip_network = ipaddress.IPNetwork try: import sysconfig def get_stdlib(): paths = [ sysconfig.get_path("stdlib"), sysconfig.get_path("platstdlib"), ] return set(filter(bool, paths)) except ImportError: from distutils import sysconfig def get_stdlib(): paths = [ sysconfig.get_python_lib(standard_lib=True), sysconfig.get_python_lib(standard_lib=True, plat_specific=True), ] return set(filter(bool, paths)) __all__ = [ "logging_dictConfig", "ipaddress", "uses_pycache", "console_to_str", "native_str", "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "OrderedDict", ] if sys.version_info >= (3, 4): uses_pycache = True from importlib.util import cache_from_source else: import imp uses_pycache = hasattr(imp, 'cache_from_source') if uses_pycache: cache_from_source = imp.cache_from_source else: cache_from_source = None if sys.version_info >= (3,): def console_to_str(s): try: return s.decode(sys.__stdout__.encoding) except UnicodeDecodeError: return s.decode('utf_8') def native_str(s, replace=False): if isinstance(s, bytes): return s.decode('utf-8', 'replace' if replace else 'strict') return s else: def console_to_str(s): return s def native_str(s, replace=False): # Replace is ignored -- unicode to UTF-8 can't fail if isinstance(s, text_type): return s.encode('utf-8') return s def total_seconds(td): if hasattr(td, "total_seconds"): return td.total_seconds() else: val = td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6 return val / 10 ** 6 def get_path_uid(path): """ Return path's uid. Does not follow symlinks: https://github.com/pypa/pip/pull/935#discussion_r5307003 Placed this function in compat due to differences on AIX and Jython, that should eventually go away. :raises OSError: When path is a symlink or can't be read. """ if hasattr(os, 'O_NOFOLLOW'): fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) file_uid = os.fstat(fd).st_uid os.close(fd) else: # AIX and Jython # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW if not os.path.islink(path): # older versions of Jython don't have `os.fstat` file_uid = os.stat(path).st_uid else: # raise OSError for parity with os.O_NOFOLLOW above raise OSError( "%s is a symlink; Will not return uid for symlinks" % path ) return file_uid def expanduser(path): """ Expand ~ and ~user constructions. Includes a workaround for http://bugs.python.org/issue14768 """ expanded = os.path.expanduser(path) if path.startswith('~/') and expanded.startswith('//'): expanded = expanded[1:] return expanded # packages in the stdlib that may have installation metadata, but should not be # considered 'installed'. this theoretically could be determined based on # dist.location (py27:`sysconfig.get_paths()['stdlib']`, # py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may # make this ineffective, so hard-coding stdlib_pkgs = ('python', 'wsgiref') if sys.version_info >= (2, 7): stdlib_pkgs += ('argparse',) # windows detection, covers cpython and ironpython WINDOWS = (sys.platform.startswith("win") or (sys.platform == 'cli' and os.name == 'nt')) def samefile(file1, file2): """Provide an alternative for os.path.samefile on Windows/Python2""" if hasattr(os.path, 'samefile'): return os.path.samefile(file1, file2) else: path1 = os.path.normcase(os.path.abspath(file1)) path2 = os.path.normcase(os.path.abspath(file2)) return path1 == path2 usr/lib/python3.6/site-packages/isc/__init__.py000064400000001651152531445470015317 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.6/xmlrpc/__init__.py000064400000000046152531522410013463 0ustar00# This directory is a Python package. usr/lib/python3.6/site-packages/setuptools/__init__.py000064400000013104152531554170016754 0ustar00"""Extensions to the 'distutils' for large or complex distributions""" import os import functools import distutils.core import distutils.filelist from distutils.util import convert_path from fnmatch import fnmatchcase from setuptools.extern.six.moves import filter, map import setuptools.version from setuptools.extension import Extension from setuptools.dist import Distribution, Feature from setuptools.depends import Require from . import monkey __all__ = [ 'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require', 'find_packages', ] __version__ = setuptools.version.__version__ bootstrap_install_from = None # If we run 2to3 on .py files, should we also convert docstrings? # Default: yes; assume that we can detect doctests reliably run_2to3_on_doctests = True # Standard package names for fixer packages lib2to3_fixer_packages = ['lib2to3.fixes'] class PackageFinder(object): """ 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 def _install_setup_requires(attrs): # Note: do not use `setuptools.Distribution` directly, as # our PEP 517 backend patch `distutils.core.Distribution`. dist = distutils.core.Distribution(dict( (k, v) for k, v in attrs.items() if k in ('dependency_links', 'setup_requires') )) # Honor setup.cfg's options. dist.parse_config_files(ignore_option_errors=True) if dist.setup_requires: 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 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) monkey.patch_all() usr/lib64/python3.6/email/mime/__init__.py000064400000000000152531650210014162 0ustar00usr/lib64/python2.7/xml/__init__.py000064400000001724152531671200012764 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/python2.7/lib2to3/__init__.py000064400000000007152531716400013435 0ustar00#empty usr/lib64/python3.6/venv/__init__.py000064400000046561152531717130013155 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/python2.7/lib2to3/pgen2/__init__.py000064400000000217152531721660014457 0ustar00# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """The pgen2 package.""" usr/lib64/python3.6/pydoc_data/__init__.py000064400000000000152531760420014260 0ustar00usr/lib64/python2.7/xml/etree/__init__.py000064400000003104152532266240014067 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/lib/python3.6/site-packages/dnf/conf/__init__.py000064400000003671152532267230016236 0ustar00# conf.py # dnf configuration classes. # # 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. # """ The configuration classes and routines in yum are splattered over too many places, hard to change and debug. The new structure here will replace that. Its goal is to: * accept configuration options from all three sources (the main config file, repo config files, command line switches) * handle all the logic of storing those and producing related values. * returning configuration values. * optionally: asserting no value is overridden once it has been applied somewhere (e.g. do not let a new repo be initialized with different global cache path than an already existing one). """ from __future__ import absolute_import from __future__ import unicode_literals from dnf.conf.config import PRIO_DEFAULT, PRIO_MAINCONFIG, PRIO_AUTOMATICCONFIG from dnf.conf.config import PRIO_REPOCONFIG, PRIO_PLUGINDEFAULT, PRIO_PLUGINCONFIG from dnf.conf.config import PRIO_COMMANDLINE, PRIO_RUNTIME from dnf.conf.config import BaseConfig, MainConf, RepoConf Conf = MainConf usr/lib64/python3.6/curses/__init__.py000064400000006446152532307410013476 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/python2.7/site-packages/pip/__init__.py000064400000027236152532310070015324 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/lib/python2.7/site-packages/setuptools/__init__.py000064400000013104152532500130016740 0ustar00"""Extensions to the 'distutils' for large or complex distributions""" import os import functools import distutils.core import distutils.filelist from distutils.util import convert_path from fnmatch import fnmatchcase from setuptools.extern.six.moves import filter, map import setuptools.version from setuptools.extension import Extension from setuptools.dist import Distribution, Feature from setuptools.depends import Require from . import monkey __all__ = [ 'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require', 'find_packages', ] __version__ = setuptools.version.__version__ bootstrap_install_from = None # If we run 2to3 on .py files, should we also convert docstrings? # Default: yes; assume that we can detect doctests reliably run_2to3_on_doctests = True # Standard package names for fixer packages lib2to3_fixer_packages = ['lib2to3.fixes'] class PackageFinder(object): """ 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 def _install_setup_requires(attrs): # Note: do not use `setuptools.Distribution` directly, as # our PEP 517 backend patch `distutils.core.Distribution`. dist = distutils.core.Distribution(dict( (k, v) for k, v in attrs.items() if k in ('dependency_links', 'setup_requires') )) # Honor setup.cfg's options. dist.parse_config_files(ignore_option_errors=True) if dist.setup_requires: 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 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) monkey.patch_all() usr/lib64/python3.12/json/__init__.py000064400000033304152532515270013216 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/lib/python2.7/site-packages/pip/vcs/__init__.py000064400000030126152532521030016107 0ustar00"""Handles all VCS (version control) support""" from __future__ import absolute_import import errno import logging import os import shutil import sys from pip._vendor.six.moves.urllib import parse as urllib_parse from pip.exceptions import BadCommand from pip.utils import (display_path, backup_dir, call_subprocess, rmtree, ask_path_exists) __all__ = ['vcs', 'get_src_requirement'] logger = logging.getLogger(__name__) class VcsSupport(object): _registry = {} schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] def __init__(self): # Register more schemes with urlparse for various version control # systems urllib_parse.uses_netloc.extend(self.schemes) # Python >= 2.7.4, 3.3 doesn't have uses_fragment if getattr(urllib_parse, 'uses_fragment', None): urllib_parse.uses_fragment.extend(self.schemes) super(VcsSupport, self).__init__() def __iter__(self): return self._registry.__iter__() @property def backends(self): return list(self._registry.values()) @property def dirnames(self): return [backend.dirname for backend in self.backends] @property def all_schemes(self): schemes = [] for backend in self.backends: schemes.extend(backend.schemes) return schemes def register(self, cls): if not hasattr(cls, 'name'): logger.warning('Cannot register VCS %s', cls.__name__) return if cls.name not in self._registry: self._registry[cls.name] = cls logger.debug('Registered VCS backend: %s', cls.name) def unregister(self, cls=None, name=None): if name in self._registry: del self._registry[name] elif cls in self._registry.values(): del self._registry[cls.name] else: logger.warning('Cannot unregister because no class or name given') def get_backend_name(self, location): """ Return the name of the version control backend if found at given location, e.g. vcs.get_backend_name('/path/to/vcs/checkout') """ for vc_type in self._registry.values(): if vc_type.controls_location(location): logger.debug('Determine that %s uses VCS: %s', location, vc_type.name) return vc_type.name return None def get_backend(self, name): name = name.lower() if name in self._registry: return self._registry[name] def get_backend_from_location(self, location): vc_type = self.get_backend_name(location) if vc_type: return self.get_backend(vc_type) return None vcs = VcsSupport() class VersionControl(object): name = '' dirname = '' # List of supported schemes for this Version Control schemes = () def __init__(self, url=None, *args, **kwargs): self.url = url super(VersionControl, self).__init__(*args, **kwargs) def _is_local_repository(self, repo): """ posix absolute paths start with os.path.sep, win32 ones start with drive (like c:\\folder) """ drive, tail = os.path.splitdrive(repo) return repo.startswith(os.path.sep) or drive # See issue #1083 for why this method was introduced: # https://github.com/pypa/pip/issues/1083 def translate_egg_surname(self, surname): # For example, Django has branches of the form "stable/1.7.x". return surname.replace('/', '_') def export(self, location): """ Export the repository at the url to the destination location i.e. only download the files, without vcs informations """ raise NotImplementedError def get_url_rev(self): """ Returns the correct repository URL and revision by parsing the given repository URL """ error_message = ( "Sorry, '%s' is a malformed VCS url. " "The format is +://, " "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp" ) assert '+' in self.url, error_message % self.url url = self.url.split('+', 1)[1] scheme, netloc, path, query, frag = urllib_parse.urlsplit(url) rev = None if '@' in path: path, rev = path.rsplit('@', 1) url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) return url, rev def get_info(self, location): """ Returns (url, revision), where both are strings """ assert not location.rstrip('/').endswith(self.dirname), \ 'Bad directory: %s' % location return self.get_url(location), self.get_revision(location) def normalize_url(self, url): """ Normalize a URL for comparison by unquoting it and removing any trailing slash. """ return urllib_parse.unquote(url).rstrip('/') def compare_urls(self, url1, url2): """ Compare two repo URLs for identity, ignoring incidental differences. """ return (self.normalize_url(url1) == self.normalize_url(url2)) def obtain(self, dest): """ Called when installing or updating an editable package, takes the source path of the checkout. """ raise NotImplementedError def switch(self, dest, url, rev_options): """ Switch the repo at ``dest`` to point to ``URL``. """ raise NotImplementedError def update(self, dest, rev_options): """ Update an already-existing repo to the given ``rev_options``. """ raise NotImplementedError def check_version(self, dest, rev_options): """ Return True if the version is identical to what exists and doesn't need to be updated. """ raise NotImplementedError def check_destination(self, dest, url, rev_options, rev_display): """ Prepare a location to receive a checkout/clone. Return True if the location is ready for (and requires) a checkout/clone, False otherwise. """ checkout = True prompt = False if os.path.exists(dest): checkout = False if os.path.exists(os.path.join(dest, self.dirname)): existing_url = self.get_url(dest) if self.compare_urls(existing_url, url): logger.debug( '%s in %s exists, and has correct URL (%s)', self.repo_name.title(), display_path(dest), url, ) if not self.check_version(dest, rev_options): logger.info( 'Updating %s %s%s', display_path(dest), self.repo_name, rev_display, ) self.update(dest, rev_options) else: logger.info( 'Skipping because already up-to-date.') else: logger.warning( '%s %s in %s exists with URL %s', self.name, self.repo_name, display_path(dest), existing_url, ) prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', ('s', 'i', 'w', 'b')) else: logger.warning( 'Directory %s already exists, and is not a %s %s.', dest, self.name, self.repo_name, ) prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) if prompt: logger.warning( 'The plan is to install the %s repository %s', self.name, url, ) response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) if response == 's': logger.info( 'Switching %s %s to %s%s', self.repo_name, display_path(dest), url, rev_display, ) self.switch(dest, url, rev_options) elif response == 'i': # do nothing pass elif response == 'w': logger.warning('Deleting %s', display_path(dest)) rmtree(dest) checkout = True elif response == 'b': dest_dir = backup_dir(dest) logger.warning( 'Backing up %s to %s', display_path(dest), dest_dir, ) shutil.move(dest, dest_dir) checkout = True elif response == 'a': sys.exit(-1) return checkout def unpack(self, location): """ Clean up current location and download the url repository (and vcs infos) into location """ if os.path.exists(location): rmtree(location) self.obtain(location) def get_src_requirement(self, dist, location): """ Return a string representing the requirement needed to redownload the files currently present in location, something like: {repository_url}@{revision}#egg={project_name}-{version_identifier} """ raise NotImplementedError def get_url(self, location): """ Return the url used at location Used in get_info or check_destination """ raise NotImplementedError def get_revision(self, location): """ Return the current revision of the files at location Used in get_info """ raise NotImplementedError def run_command(self, cmd, show_stdout=True, cwd=None, on_returncode='raise', command_desc=None, extra_environ=None, spinner=None): """ Run a VCS subcommand This is simply a wrapper around call_subprocess that adds the VCS command name, and checks that the VCS is available """ cmd = [self.name] + cmd try: return call_subprocess(cmd, show_stdout, cwd, on_returncode, command_desc, extra_environ, spinner) except OSError as e: # errno.ENOENT = no such file or directory # In other words, the VCS executable isn't available if e.errno == errno.ENOENT: raise BadCommand('Cannot find command %r' % self.name) else: raise # re-raise exception if a different error occurred @classmethod def controls_location(cls, location): """ Check if a location is controlled by the vcs. It is meant to be overridden to implement smarter detection mechanisms for specific vcs. """ logger.debug('Checking in %s for %s (%s)...', location, cls.dirname, cls.name) path = os.path.join(location, cls.dirname) return os.path.exists(path) def get_src_requirement(dist, location): version_control = vcs.get_backend_from_location(location) if version_control: try: return version_control().get_src_requirement(dist, location) except BadCommand: logger.warning( 'cannot determine version of editable source in %s ' '(%s command not found in path)', location, version_control.name, ) return dist.as_requirement() logger.warning( 'cannot determine version of editable source in %s (is not SVN ' 'checkout, Git clone, Mercurial clone or Bazaar branch)', location, ) return dist.as_requirement() usr/lib64/python3.12/multiprocessing/dummy/__init__.py000064400000005765152532543200016633 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/libexec/kcare/python/kcarectl/__init__.py000064400000235052152532546310015314 0ustar00# Copyright (c) Cloud Linux Software, Inc # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENCE.TXT from __future__ import print_function import base64 import json import logging import os import platform import random import re import shutil import socket import ssl import sys import tempfile import time import traceback import warnings from argparse import ArgumentParser from contextlib import contextmanager from datetime import datetime from . import ( anomaly, auth, capabilities, config, config_handlers, constants, doctor, errors, fetch, http_utils, ipv6_support, kcare, libcare, log_utils, platform_utils, process_utils, selinux, server_info, serverid, update_utils, utils, ) from .errors import KcareError, NotFound, SafeExceptionWrapper from .py23 import HTTPError, URLError, httplib, json_loads_nstr, urlencode CPANEL_GID = 99 EFFECTIVE_LATEST = 'v3' EXPECTED_PREFIX = ('12h', '24h', '48h', 'test') FREEZER_BLACKLIST = '/etc/sysconfig/kcare/freezer.modules.blacklist' KCDOCTOR = '/usr/libexec/kcare/kcdoctor.sh' PATCH_LATEST = ( 'latest.v3', 'latest.v2', ) SYSCTL_CONFIG = '/etc/sysconfig/kcare/sysctl.conf' UNLOAD_RETRY_DELAY = 10 BLACKLIST_RE = re.compile('==BLACKLIST==\n(.*)==END BLACKLIST==\n', re.DOTALL) CONFLICTING_MODULES_RE = re.compile('(kpatch.*|ksplice.*|kpatch_livepatch.*)') if os.path.isdir('/usr/libexec/kcare/python'): # pragma: no cover sys.path.insert(0, '/usr/libexec/kcare/python') warnings.filterwarnings('ignore', category=DeprecationWarning) if False: # pragma: no cover from typing import Any, Dict, Optional, Set, Tuple, Union # noqa: F401 log_utils.kcarelog.setLevel(logging.DEBUG) def get_freezer_blacklist(): result = set() if os.path.isfile(FREEZER_BLACKLIST): f = open(FREEZER_BLACKLIST, 'r') for line in f: result.add(line.rstrip()) f.close() return result def _apply_ptype(ptype, filename): name_parts = filename.split('.') if ptype: filename = '.'.join([name_parts[0], ptype, name_parts[-1]]) else: filename = '.'.join([name_parts[0], name_parts[-1]]) return filename def apply_ptype(ptype): config.PATCH_BIN = _apply_ptype(ptype, config.PATCH_BIN) config.PATCH_INFO = _apply_ptype(ptype, config.PATCH_INFO) config.BLACKLIST_FILE = _apply_ptype(ptype, config.BLACKLIST_FILE) config.FIXUPS_FILE = _apply_ptype(ptype, config.FIXUPS_FILE) config.PATCH_DONE = _apply_ptype(ptype, config.PATCH_DONE) def format_exception_without_details(): etype, value, tb = sys.exc_info() details_sanitized = '' if isinstance(value, OSError) and not isinstance(value, URLError): try: # reconstruct for safety, it may be any IO-related subclass details_sanitized = "[Errno %i] %s: '%s'" % (value.errno, os.strerror(value.errno), value.filename) except (AttributeError, TypeError): pass elif isinstance(value, (KeyError, TypeError, IOError)) and not isinstance(value, URLError): details_sanitized = '%s' % value elif isinstance(value, SafeExceptionWrapper): etype = value.etype or type(value.inner) details_sanitized = value.details or ('%s' % value.inner) distro = platform_utils.get_distro() return { 'agent_version': constants.VERSION, 'python_version': platform_utils.get_python_version(), 'distro': distro[0], 'distro_version': distro[1], 'error': getattr(etype, '__name__', str(etype)), 'details': details_sanitized, 'traceback': ''.join(traceback.format_tb(tb, 100)), 'attempts': getattr(value, 'attempts', 0), } def send_exc(): if config.UPDATE_FROM_LOCAL: # pragma: no cover return trace = json.dumps(format_exception_without_details()) encoded_trace = utils.nstr(base64.urlsafe_b64encode(utils.bstr(trace))) # type: str url = utils.get_patch_server_url('/api/kcarectl-trace') + '?trace=' + encoded_trace request = http_utils.http_request(url, auth.get_http_auth_string()) try: http_utils.urlopen_base(request) except Exception: # import traceback # traceback.print_exc() # we really don't interested in exception pass def nohup_fork(func, sleep=None): # pragma: no cover """ Run func in a fork in an own process group (will stay alive after kcarectl process death). :param func: function to execute :return: """ # TODO move to process_utils.py pid = os.fork() if pid != 0: os.waitpid(pid, 0) return os.setsid() pid = os.fork() if pid != 0: os._exit(0) # close standard files to release TTY os.close(0) # redirect stdout/stdin into log file with open(constants.LOG_FILE, 'a') as fd: os.dup2(fd.fileno(), 1) os.dup2(fd.fileno(), 2) if sleep: time.sleep(sleep) try: func() except Exception: log_utils.kcarelog.exception('Wait exception') os._exit(1) os._exit(0) def touch_anchor(): """Check the fact that there was a failed patching attempt. If anchor file not exists we should create an anchor with timestamp and schedule its deletion at $timeout. If anchor exists and its timestamp more than $timeout from now we should raise an error. """ anchor_filepath = os.path.join(constants.PATCH_CACHE, '.kcareprev.lock') if os.path.isfile(anchor_filepath): with open(anchor_filepath, 'r') as afile: try: timestamp = int(afile.read()) # anchor was created quite recently # that means that something went wrong if timestamp + config.SUCCESS_TIMEOUT > time.time(): raise PreviousPatchFailedException(timestamp, anchor_filepath) except ValueError: pass utils.atomic_write(anchor_filepath, utils.timestamp_str()) # write a new timestamp def commit_update(state_data): """ See touch_anchor() for detailed explanation of anchor mechanics. See KPT-730 for details about action registration. :param state_data: dict with current level, kernel_id etc. """ try: os.remove(os.path.join(constants.PATCH_CACHE, '.kcareprev.lock')) except OSError: pass register_action('done', state_data) # reset module cache, to allow server_info get fresh data kcare.get_loaded_modules.clear() try: get_latest_patch_level(reason='done') except Exception: log_utils.kcarelog.exception('Cannot send update info!') def clear_cache(khash, plevel): utils.clean_directory(os.path.join(constants.PATCH_CACHE, 'patches'), exclude_path=kcare.get_cache_path(khash, plevel, '')) def get_current_level_path(khash, fname): prefix = config.PREFIX or 'none' module_dir = '-'.join([prefix, khash]) result = (constants.PATCH_CACHE, 'modules', module_dir) # type: Tuple[str, ...] if fname: result += (fname,) return os.path.join(*result) def save_cache_latest(khash, patch_level): utils.atomic_write(get_current_level_path(khash, 'latest'), str(patch_level), ensure_dir=True) def get_cache_latest(khash): # type: (str) -> Optional[kcare.LegacyKernelPatchLevel] path_with_latest = get_current_level_path(khash, 'latest') if os.path.isfile(path_with_latest): try: pl = int(open(path_with_latest, 'r').read().strip()) return kcare.LegacyKernelPatchLevel(khash, pl) except (ValueError, TypeError): pass return None class CertificateError(ValueError): pass class UnknownKernelException(KcareError): status = 'unknown kernel' def __init__(self, **kwargs): msg = 'New kernel detected ({0} {1} {2}).\nThere are no updates for this kernel yet.'.format( platform_utils.get_distro()[0], platform.release(), kcare.get_kernel_hash() ) super(UnknownKernelException, self).__init__(msg, **kwargs) class ApplyPatchError(KcareError): status = 'patch apply error' def __init__(self, code, freezer_style, level, patch_file, *args, **kwargs): super(ApplyPatchError, self).__init__(*args, **kwargs) self.code = code self.freezer_style = freezer_style self.level = level self.patch_file = patch_file self.distro = platform_utils.get_distro()[0] self.release = platform.release() def __str__(self): return 'Unable to apply patch ({0} {1} {2} {3} {4}, {5})'.format( self.patch_file, self.level, self.code, self.distro, self.release, ', '.join([str(i) for i in self.freezer_style]), ) # KCARE-509 class PreviousPatchFailedException(KcareError): status = 'previous patch failed' def __init__(self, timestamp, anchor, *args, **kwargs): super(PreviousPatchFailedException, self).__init__(*args, **kwargs) self.timestamp = timestamp self.anchor = anchor def __str__(self): message = ( 'It seems, the latest patch, applying at {0}, crashed, ' 'and further attempts will be suspended. ' 'To force patch applying, remove `{1}` file' ) return message.format(self.timestamp, self.anchor) def set_monitoring_key_for_ip_license(key): url = ipv6_support.get_registration_url() + '/nagios/register_key.plain?key={0}'.format(key) try: response = http_utils.urlopen(url) res = utils.data_as_dict(utils.nstr(response.read())) code = int(res['code']) if code == 0: utils.print_wrapper('Key successfully registered') elif code == 1: utils.print_wrapper('Wrong key format or size') elif code == 2: utils.print_wrapper('No KernelCare license for that IP') else: utils.print_wrapper('Unknown error {0}'.format(code)) return code except HTTPError as e: log_utils.print_cln_http_error(e, url) return -1 @contextmanager def execute_hooks(): if config.BEFORE_UPDATE_COMMAND: process_utils.run_command(config.BEFORE_UPDATE_COMMAND, shell=True) try: yield finally: if config.AFTER_UPDATE_COMMAND: process_utils.run_command(config.AFTER_UPDATE_COMMAND, shell=True) def plugin_info(fmt=None): """ The output will consist of: Ignore output up to the line with "--START--" Line 1: show if update is needed: 0 - updated to latest, 1 - update available, 2 - unknown kernel 3 - kernel doesn't need patches 4 - no license, cannot determine Line 2: licensing message (can be skipped, can be more then one line) Line 3: LICENSE: CODE: 1: license present, 2: trial license present, 0: no license Line 4: Update mode (True - auto-update, False, no auto update) Line 5: Effective kernel version Line 6: Real kernel version Line 7: Patchset Installed # --> If None, no patchset installed Line 8: Uptime (in seconds) If *format* is 'json' return the results in JSON format. Any other output means error retrieving info :return: """ pli = _patch_level_info() update_code = pli.code loaded_pl = pli.applied_lvl license_info_result = auth.license_info() if fmt == 'json': results = { 'updateCode': str(update_code), 'autoUpdate': config.AUTO_UPDATE, 'effectiveKernel': kcare.kcare_uname(), 'realKernel': platform.release(), 'loadedPatchLevel': loaded_pl, 'uptime': int(platform_utils.get_uptime()), 'license': license_info_result, } utils.print_wrapper('--START--') utils.print_wrapper(json.dumps(results)) else: utils.print_wrapper('--START--') utils.print_wrapper(str(update_code)) utils.print_wrapper('LICENSE: ' + str(license_info_result)) utils.print_wrapper(config.AUTO_UPDATE) utils.print_wrapper(kcare.kcare_uname()) utils.print_wrapper(platform.release()) utils.print_wrapper(loaded_pl) utils.print_wrapper(platform_utils.get_uptime()) def get_update_status(): current_level = kcare.loaded_patch_level() try: latest_patch_level = get_latest_patch_level(reason='info') except UnknownKernelException: return 0 if config.IGNORE_UNKNOWN_KERNEL else 3 if current_level is None: return 1 if current_level >= latest_patch_level: return 0 return 2 if update_utils.status_gap_passed() else 0 def edf_fallback_ptype(): distro, version = platform_utils.get_distro()[:2] # From talk with @kolshanov if distro == 'CloudLinux' and version.startswith('7.'): return 'extra' else: return '' # addr -> resolved_peer_addr map CONNECTION_STICKY_MAP = {} # type: Dict[Tuple[str, int], Tuple[Optional[str], int]] def sticky_connect(self): """Function remembers IP address of host connected to and uses it for later connections. Replaces stdlib version of httplib.HTTPConnection.connect """ addr = self.host, self.port resolved_addr = CONNECTION_STICKY_MAP.get(addr, addr) # type: Tuple[Optional[str], int] self.sock = socket.create_connection(resolved_addr, self.timeout) self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if addr not in CONNECTION_STICKY_MAP: CONNECTION_STICKY_MAP[addr] = self.sock.getpeername()[:2] if self._tunnel_host: self._tunnel() httplib.HTTPConnection.connect = sticky_connect # type: ignore[method-assign] # python >= 2.7.9 stdlib (with ssl.HAS_SNI) is able to process https request on its own, # for earlier versions manual checks should be done if not getattr(ssl, 'HAS_SNI', None): # pragma: no cover unit # TODO move to http_utils or py23 try: import distutils.version import OpenSSL.SSL if distutils.version.StrictVersion(OpenSSL.__version__) < distutils.version.StrictVersion('0.13'): # type: ignore[attr-defined] raise ImportError('No pyOpenSSL module with SNI ability.') except ImportError: pass else: def dummy_verify_callback(*args): # OpenSSL.SSL.Context.set_verify() requires callback # where additional checks could be done; # here is a dummy callback and a hostname check is made externally # to provide original exception from match_hostname() return True PureHTTPSConnection = httplib.HTTPSConnection class SSLSock(object): def __init__(self, sock): self._ssl_conn = sock self._makefile_refs = 0 def makefile(self, *args): self._makefile_refs += 1 return socket._fileobject(self._ssl_conn, *args, close=True) # type: ignore[attr-defined] def close(self): if not self._makefile_refs and self._ssl_conn: self._ssl_conn.close() self._ssl_conn = None def sendall(self, *args): return self._ssl_conn.sendall(*args) class PyOpenSSLHTTPSConnection(httplib.HTTPSConnection): def connect(self): httplib.HTTPConnection.connect(self) # workaround to force pyopenssl to use TLSv1.2 ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD) ctx.set_options(OpenSSL.SSL.OP_NO_SSLv2 | OpenSSL.SSL.OP_NO_SSLv3) if config.CHECK_SSL_CERTS: ctx.set_verify(OpenSSL.SSL.VERIFY_PEER, dummy_verify_callback) else: ctx.set_verify(OpenSSL.SSL.VERIFY_NONE, dummy_verify_callback) ctx.set_default_verify_paths() conn = OpenSSL.SSL.Connection(ctx, self.sock) conn.set_connect_state() # self._tunnel_host is an original hostname in case of proxy use server_host = self._tunnel_host or self.host # type: ignore[attr-defined] conn.set_tlsext_host_name(server_host.encode()) conn.do_handshake() if config.CHECK_SSL_CERTS: match_hostname(conn.get_peer_certificate(), server_host) self.sock = SSLSock(conn) httplib.HTTPSConnection = PyOpenSSLHTTPSConnection # type: ignore[misc] def _fetch_patch_level_request(khash, latest, reason, mode): if config.UPDATE_FROM_LOCAL: url = kcare.get_kernel_prefixed_url(khash, latest) return fetch.wrap_with_cache_key(auth.urlopen_auth)(url, check_license=False) b64_encoding = latest not in ['latest.v1', 'latest.v2'] perf_enabled = config.SEND_PERF_METRICS and b64_encoding for secure_boot_info, perf_metrics in [(True, perf_enabled), (False, perf_enabled), (False, False)]: # pragma: no branch sinfo = server_info.server_info(reason, secure_boot_info=secure_boot_info, perf_metrics=perf_metrics) request_param = server_info.encode_checkin_payload(sinfo, b64_encoding=b64_encoding) if b64_encoding: request_param = 'info={0}'.format(request_param) url = kcare.get_kernel_prefixed_url(khash, stickyfy(latest, mode)) + '?' + request_param max_url_length = 7000 # the entire request should fit in 8K if (secure_boot_info or perf_metrics) and len(url) > max_url_length: discard_info = 'secure boot info' if secure_boot_info else 'perf metrics' log_utils.logwarn('Check-in URL param is too large, discarding {0}'.format(discard_info)) continue try: result = fetch.wrap_with_cache_key(auth.urlopen_auth)(url, check_license=False) if config.KERNEL_ANOMALY_REPORT_ENABLE and anomaly.detect_anomaly(sinfo): # possible errors in prepare_kernel_anomaly_report and send_data_package are silently ignored data_package = anomaly.prepare_kernel_anomaly_report(sinfo) upload_name = anomaly.send_data_package(data_package) if upload_name: # will be None in case of errors in send_data_package log_utils.loginfo( 'Automatic kernel anomaly report uploaded successfully: {0}'.format(upload_name), print_msg=False ) else: log_utils.logwarn('Failed to send kernel anomaly report', print_msg=False) if data_package: data_package.remove_archive() return result except HTTPError as ex: if (secure_boot_info or perf_metrics) and (ex.code in (413, 414) or ex.code >= 500): log_utils.logwarn('Check-in request failed with error: {0}, retrying with reduced info'.format(ex)) continue raise def fetch_patch_level(reason, mode=constants.UPDATE_MODE_MANUAL): khash = kcare.get_kernel_hash() if config.PATCH_LEVEL is not None: return kcare.LegacyKernelPatchLevel(khash, int(config.PATCH_LEVEL)) for latest in PATCH_LATEST: try: response = _fetch_patch_level_request(khash, latest, reason, mode) config_handlers.set_feature_flags_from_headers(response.headers) update_all_kmod_params() pl = utils.nstr(response.read()).strip() log_utils.loginfo('fetch patch level, reason: {0}, kernel latest response: {1}'.format(reason, pl), print_msg=False) if pl and pl.startswith('{'): latest_info = json_loads_nstr(pl) required_capabilities = latest_info.get('capabilities', []) if not capabilities.has_kc_capabilities(required_capabilities): raise errors.CapabilitiesMismatch( 'Latest KernelCare patchset is incompatible with the current kernecare package version, please upgrade' ) return kcare.KernelPatchLevel(khash, latest_info['level'], latest_info['baseurl'], latest_info['release']) return kcare.LegacyKernelPatchLevel(khash, int(pl)) except NotFound: # old ePortal version < 2.20 returns 404 for latest.v3 requests pass except HTTPError as ex: # No license - no access if ex.code in (403, 401): raise KcareError('KC licence is required') raise raise UnknownKernelException() def probe_patch(level, ptype): bin_url = level.file_url(_apply_ptype(ptype, config.PATCH_BIN)) log_utils.kcarelog.info('Probing patch URL: {0}'.format(bin_url)) try: auth.urlopen_auth(bin_url, check_license=False, method='HEAD') return True except NotFound: log_utils.kcarelog.info('{0} is not available: 404'.format(bin_url)) return False except Exception as ex: # Fallback to GET in case of any error. log_utils.kcarelog.debug('HEAD request for {0} raised an error, fallback to the GET request: {1}'.format(bin_url, str(ex))) url = level.file_url(_apply_ptype(ptype, config.PATCH_BIN) + constants.SIG) log_utils.kcarelog.info('Probing patch URL: {0}'.format(url)) try: auth.urlopen_auth(url, check_license=False) except NotFound: log_utils.kcarelog.info('{0} is not available: 404'.format(url)) return False except URLError as ex: log_utils.kcarelog.info('{0} is not available: {1}'.format(url, str(ex))) return True def fetch_and_verify_kernel_file(level, name): if name == constants.KMOD_BIN: url = level.kmod_url(constants.KMOD_BIN) else: url = level.file_url(name) dst = level.cache_path(name) return fetch.fetch_url(url, dst, config.USE_SIGNATURE, hash_checker=fetch.get_hash_checker(level)) class PatchFetcher(object): # TODO move to fetch.py def __init__(self, patch_level=None): self.patch_level = patch_level # LegacyKernelPatchLevel or KernelPatchLevel def _fetch(self, name): return fetch_and_verify_kernel_file(self.patch_level, name) def is_patch_fetched(self): patch_done_path = self.patch_level.cache_path(config.PATCH_DONE) patch_bin_path = self.patch_level.cache_path(config.PATCH_BIN) patch_info_path = self.patch_level.cache_path(config.PATCH_INFO) kmod_bin_path = self.patch_level.cache_path(constants.KMOD_BIN) return ( all(os.path.isfile(path) for path in (patch_done_path, patch_bin_path, patch_info_path, kmod_bin_path)) and os.path.getsize(patch_bin_path) > 0 and os.path.getsize(kmod_bin_path) > 0 ) def fetch_patch(self): if self.patch_level is None: raise ValueError("Cannot fetch patch as no patch level is set") if not self.patch_level: # level is 0, do nothing return self.patch_level if self.is_patch_fetched(): log_utils.loginfo('Updates already downloaded') return self.patch_level log_utils.loginfo('Downloading updates') # try to upgrade patch level if isinstance(self.patch_level, kcare.LegacyKernelPatchLevel): try: resp = auth.urlopen_auth(self.patch_level.file_url(config.PATCH_BIN), method='HEAD') except NotFound: pass else: baseurl = resp.headers.get('KC-Base-Url', None) if baseurl: self.patch_level = self.patch_level.upgrade(utils.nstr(baseurl)) try: self._fetch(config.PATCH_BIN) except NotFound: raise KcareError( 'The `{0}` patch level is not found for `{1}` patch type. ' 'Please select valid patch type or patch level'.format(self.patch_level, config.PATCH_TYPE or 'default'), status='patch level not found', ) self._fetch(config.PATCH_INFO) self._fetch(constants.KMOD_BIN) self.extract_blacklist() utils.atomic_write(self.patch_level.cache_path(config.PATCH_DONE), b'', mode='wb') selinux.restore_selinux_context(constants.PATCH_CACHE) return self.patch_level def extract_blacklist(self): buf = open(self.patch_level.cache_path(config.PATCH_INFO), 'r').read() if buf: mo = BLACKLIST_RE.search(buf) if mo: utils.atomic_write(self.patch_level.cache_path(config.BLACKLIST_FILE), mo.group(1)) def fetch_fixups(self, level): """ Download fixup files for defined patch level :param level: download fixups for this patch level (usually it's a level of loaded patch) :return: None """ if level is None: return try: # never use cache for fixup files, must be downloaded from scratch resp = fetch_and_verify_kernel_file(level, config.FIXUPS_FILE) except NotFound: return # Upgrade level to a new format with baseurl to fetch fixup files baseurl = resp.headers.get('KC-Base-Url', None) if baseurl: level = level.upgrade(utils.nstr(baseurl)) fixups_fname = level.cache_path(config.FIXUPS_FILE) with open(fixups_fname, 'r') as f: fixups = set([fixup.strip() for fixup in f.readlines()]) for fixup in fixups: fetch_and_verify_kernel_file(level, fixup) selinux.restore_selinux_context(constants.PATCH_CACHE) def kcare_check(): pli = _patch_level_info() utils.print_wrapper(pli.msg) if pli.code == PLI.PATCH_NEED_UPDATE: sys.exit(0) else: sys.exit(1) def show_generic_info(): pli = _patch_level_info() kcare_info = _kcare_patch_info_json(pli) try: libcare_info = libcare.libcare_patch_info_basic() except KcareError: libcare_info = {} state = kcare.get_state() latest_update = "Unknown" if state is not None: latest_update = datetime.fromtimestamp(state['ts']).strftime('%Y-%m-%d') effective_version = kcare.kcare_uname() # count unique CVEs for accurate vulnerability counts kernel_patches = kcare_info.get('patches', []) kernel_vulnerabilities = len(utils.extract_unique_cves(kernel_patches, cve_field='kpatch-cve')) kernel_patches_count = len(kernel_patches) userspace_patches = [patch for rec in libcare_info for patch in rec.get('patches', [])] userspace_vulnerabilities = len(utils.extract_unique_cves(userspace_patches, cve_field='cve')) userspace_patches_count = sum(len(rec.get('patches', [])) for rec in libcare_info) total_patches_count = kernel_patches_count + userspace_patches_count patch_level = kcare.loaded_patch_level() if not patch_level: utils.print_wrapper("KernelCare live patching is disabled") else: utils.print_wrapper("KernelCare live patching is active") utils.print_wrapper(" - Last updated on {0}".format(latest_update)) utils.print_wrapper(" - Effective kernel version {0}".format(effective_version)) if kernel_vulnerabilities > 0: utils.print_wrapper(" - {0} kernel vulnerabilities live patched".format(kernel_vulnerabilities)) if userspace_vulnerabilities > 0: utils.print_wrapper(" - {0} userspace vulnerabilities live patched".format(userspace_vulnerabilities)) if total_patches_count == 0: utils.print_wrapper(" - This system has no applied patches") utils.print_wrapper("Type kcarectl --patch-info to learn more") def kcare_latest_patch_info(is_json=False): """ Retrieve and output to STDOUT latest patch info, so it is easy to get list of CVEs in use. More info at https://cloudlinux.atlassian.net/browse/KCARE-952 :return: None """ try: latest = get_latest_patch_level(reason='info', policy=constants.POLICY_REMOTE) if not latest: raise UnknownKernelException url = latest.file_url(config.PATCH_INFO) patch_info = utils.nstr(auth.urlopen_auth(url).read()) if is_json: patches, result = [], {} for chunk in patch_info.split('\n\n'): data = utils.data_as_dict(chunk) if data and 'kpatch-name' in data: patches.append(data) else: result.update(data) result['patches'] = patches # type: ignore[assignment] patch_info = json.dumps(result) utils.print_wrapper(patch_info) except HTTPError as e: log_utils.print_cln_http_error(e, e.url) return 1 except UnknownKernelException: utils.print_wrapper('No patches available') return 0 def _kcare_patch_info_json(pli): result = {'message': pli.msg} if pli.applied_lvl is not None: patch_info = _kcare_patch_info(pli) patches = [] for chunk in patch_info.split('\n\n'): data = utils.data_as_dict(chunk) if data and 'kpatch-name' in data: patches.append(data) else: result.update(data) result['patches'] = patches saved_patch_level = kcare.read_dumped_kernel_patch_level() result['release'] = saved_patch_level['release'] if saved_patch_level else 'unknown' return result def _kcare_patch_info(pli): khash = kcare.get_kernel_hash() cache_path = kcare.get_cache_path(khash, pli.applied_lvl, config.PATCH_INFO) if not os.path.isfile(cache_path): raise KcareError( "Can't find information due to the absent patch information file." " Please, run /usr/bin/kcarectl --update and try again.", status='patch info not found', ) info = open(cache_path, 'r').read() if info: info = BLACKLIST_RE.sub('', info) return info def patch_info(is_json=False): pli = _patch_level_info() if not is_json: if pli.code != 0: utils.print_wrapper(pli.msg) if pli.applied_lvl is None: return utils.print_wrapper(_kcare_patch_info(pli)) else: utils.print_wrapper(json.dumps(_kcare_patch_info_json(pli), sort_keys=True)) def is_same_patch(new_patch_file): # mocked: tests/unit args = [constants.KPATCH_CTL, 'file-info', new_patch_file] new_patch_info = process_utils.check_output(args) current_patch_info = kcare._patch_info() build_time_label = 'kpatch-build-time' return kcare.get_patch_value(new_patch_info, build_time_label) == kcare.get_patch_value(current_patch_info, build_time_label) def kcare_need_update(applied_level, new_level): if new_level == 0: return False # ignore down-patching if applied_level and new_level < applied_level: return False if applied_level != new_level: return True new_patch_file = kcare.get_cache_path(kcare.get_kernel_hash(), new_level, config.PATCH_BIN) if not is_same_patch(new_patch_file): return True return False def update_sysctl(): # TODO move to platform_utils.py if config.UPDATE_SYSCTL_CONFIG: if not (os.path.isfile(SYSCTL_CONFIG) and os.access(SYSCTL_CONFIG, os.R_OK)): log_utils.kcarelog.warning('File {0} does not exist or has no read access'.format(SYSCTL_CONFIG)) return code, _, _ = process_utils.run_command(['/sbin/sysctl', '-q', '-p', SYSCTL_CONFIG], catch_stdout=True) if code != 0: log_utils.kcarelog.warning('Unable to load kcare sysctl.conf: {0}'.format(code)) def edit_sysctl_conf(remove, append): """Update SYSCTL_CONFIG accordingly the edits""" # TODO move to platform_utils.py # Create if it does not exist if not os.path.isfile(SYSCTL_CONFIG): open(SYSCTL_CONFIG, 'a').close() # Check kcare sysctl path and read access if not os.access(SYSCTL_CONFIG, os.R_OK): log_utils.kcarelog.warning('File {0} has no read access'.format(SYSCTL_CONFIG)) return with open(SYSCTL_CONFIG, 'r+') as sysctl: lines = sysctl.readlines() sysctl.seek(0) for line in lines: # Do not rewrite lines that should be deleted if not any(line.startswith(r) for r in remove): sysctl.write(line) # Write additional lines for a in append: sysctl.write(a + '\n') sysctl.truncate() def detect_conflicting_modules(modules): for module in modules: if CONFLICTING_MODULES_RE.match(module): raise KcareError( "Detected '{0}' kernel module loaded. Please unload that module first".format(module), status='conflicting kernel module', ) def get_kcare_kmod_link(): return '/lib/modules/{0}/extra/kcare.ko'.format(platform_utils.get_system_uname()) def kmod_is_signed(): level = get_latest_patch_level(reason='info') kmod_file = kcare.get_cache_path(kcare.get_kernel_hash(), level, constants.KMOD_BIN) if not os.path.isfile(kmod_file): return None with open(kmod_file, 'rb') as vfd: return vfd.read()[-28:] == b'~Module signature appended~\n' def kcare_certs_enrolled(): # pragma: no cover system_keys = utils.try_to_read('/proc/keys') if system_keys is None: return None kcare_keys = [ '12ff0613c0f80cfba3b2f8eba71ebc27c5a76170', # CloudLinux key '69a6d9eed3f620d5c2e13a1d211c46510a5ad9f5', # AlmaLinux kpatch signing key ] return any(key in system_keys for key in kcare_keys) def load_kmod(kmod, **kwargs): cmd = ['/sbin/insmod', kmod] for key, value in kwargs.items(): cmd.append('{0}={1}'.format(key, value)) code, _, _ = process_utils.run_command(cmd, catch_stdout=True) if code != 0: raise KcareError( 'Unable to load kmod ({0} {1}). Try to run with `--check-compatibility` flag.'.format(kmod, code), status='kmod load error', ) def check_compatibility(): if platform_utils.is_secure_boot(): if kmod_is_signed() is False: raise KcareError('Secure boot is enabled. Not supported by KernelCare.') if kcare_certs_enrolled() is False: raise KcareError('Secure boot is enabled. No KernelCare certificates enrolled.') if platform_utils.inside_vz_container() or platform_utils.inside_lxc_container() or platform_utils.inside_docker_container(): raise KcareError( 'You are running inside a container. Kernelcare should be executed on host side instead.', status='running in container', ) def check_patch_type_compatibility(ptype): # type: (str) -> None # TODO KPT-4474 patch type autodetection cmd = process_utils.find_cmd('modinfo') has_kmodlve = process_utils.run_command([cmd, 'kmodlve'], catch_stdout=True, catch_stderr=True)[0] == 0 if has_kmodlve and ptype in ('free', 'extra'): # KPT-4269 kcarectl: free/extra patches confict with kmodlve log_utils.logerror('{0} patch type conflicts with kmodlve kernel module'.format(ptype)) sys.exit(1) def get_kmod_available_params(kcare_link): stdout = process_utils.check_output(["/sbin/modinfo", "-F", "parm", kcare_link]) available_params = [] for line in stdout.split('\n'): if line.strip(): param_name, _, _ = line.partition(':') available_params.append(param_name) return available_params def make_kmod_new_params(): return { 'kpatch_debug': 1 if config.KPATCH_DEBUG else 0, 'kmsg_output': 1 if config.KMSG_OUTPUT else 0, 'kcore_output': config.KCORE_OUTPUT_SIZE if config.KCORE_OUTPUT else 0, 'kdumps_dir': config.KDUMPS_DIR if isinstance(config.KDUMPS_DIR, str) else "", 'enable_crashreporter': 1 if config.ENABLE_CRASHREPORTER else 0, } def update_all_kmod_params(): if config.KDUMPS_DIR and not os.path.exists(config.KDUMPS_DIR): os.makedirs(config.KDUMPS_DIR) for param, val in make_kmod_new_params().items(): update_kmod_param(param, val) def update_kmod_param(kmod_param_name, param_value): params_root = '/sys/module/kcare/parameters' param_path = os.path.join(params_root, kmod_param_name) if not os.path.exists(param_path): return try: with open(param_path, 'w') as f: f.write(str(param_value)) except Exception: # pragma: no cover log_utils.kcarelog.error('failed to set %s kmod param to %s', kmod_param_name, param_value) def load_kcare_kmod(khash, level): # To make `kdump` service work. We need to copy # `kcare.ko` into `/lib/modules/$(uname -r)/extra/kcare.ko` # and call `/sbin/depmod` kcare_link = get_kcare_kmod_link() kcare_file = kcare.get_cache_path(khash, level, constants.KMOD_BIN) try: shutil.copy(kcare_file, kcare_link) except Exception: kcare_link = kcare_file if config.KDUMPS_DIR and not os.path.exists(config.KDUMPS_DIR): os.makedirs(config.KDUMPS_DIR) kmod_params = make_kmod_new_params() available_kmod_params = get_kmod_available_params(kcare_link) kmod_params = dict((k, v) for k, v in kmod_params.items() if k in available_kmod_params) load_kmod(kcare_link, **kmod_params) update_depmod() def update_depmod(uname=None): cmd = [ '/sbin/depmod', ] if uname is not None: cmd.extend(['-a', uname]) code, _, stderr = process_utils.run_command(cmd, catch_stdout=True, catch_stderr=True) if code: # We don't want to show the error to the user but want to see it in logs log_utils.logerror('Running of `{0}` failed with {1}: {2}'.format(' '.join(cmd), code, stderr), print_msg=False) def unload_kmod(modname): code, _, _ = process_utils.run_command(['/sbin/rmmod', modname], catch_stdout=True) if code != 0: raise KcareError('Unable to unload {0} kmod {1}'.format(modname, code), status='kmod unload error') def apply_fixups(khash, current_level, modules): loaded = [] for mod in ['vmlinux'] + modules: modpath = kcare.get_cache_path(khash, current_level, 'fixup_{0}.ko'.format(mod)) if os.path.exists(modpath): load_kmod(modpath) loaded.append('fixup_{0}'.format(mod)) return loaded def remove_fixups(fixups): for mod in fixups: try: unload_kmod(mod) except Exception: log_utils.kcarelog.exception('Exception while unloading module %s.' % mod) def get_freezer_style(freezer, modules): if freezer: method = freezer elif config.PATCH_METHOD: method = config.PATCH_METHOD elif get_freezer_blacklist().intersection(modules): # blacklist module found, use smart freezer # xxx: this branch could be safely removed when smart would work by default return 'freeze_conflict', freezer, config.PATCH_METHOD, True else: # user doesn't provide patch method and no conflicting modules loaded return 'default', freezer, config.PATCH_METHOD, False # non default patch method, translate it into form accepted by kpatch_ctl patch_method_map = { 'NONE': 'freeze_none', 'NOFREEZE': 'freeze_none', 'FULL': 'freeze_all', 'FREEZE': 'freeze_all', 'SMART': 'freeze_conflict', } method = method.upper() if method in patch_method_map: method = patch_method_map[method] else: raise KcareError( 'Unable to detect freezer style ({0}, {1}, {2}, {3})'.format(method, freezer, config.PATCH_METHOD, False), status='freezer style detection error', ) return method, freezer, config.PATCH_METHOD, False def kcare_load(khash, level, mode, freezer='', use_anchor=False): state_data = {'khash': khash, 'future': level, 'mode': mode} register_action('start', state_data) current_level = kcare.loaded_patch_level() modules = kcare.get_loaded_modules() detect_conflicting_modules(modules) # get freezer in the beginning to prevent any further job in case of exception freezer_style = get_freezer_style(freezer, modules) patch_file = kcare.get_cache_path(khash, level, config.PATCH_BIN) save_cache_latest(khash, level) description = '{0}-{1}:{2};{3}'.format( level, config.PATCH_TYPE, utils.timestamp_str(), kcare.parse_uname(level) # future server_info['ltimestamp'] ) kmod_loaded = 'kcare' in modules kmod_changed = kmod_loaded and kcare.is_kmod_version_changed(khash, level) patch_loaded = current_level is not None same_patch = patch_loaded and is_same_patch(patch_file) and kcare.kcare_update_effective_version(description) state_data.update({'current': current_level, 'kmod_changed': kmod_changed}) if same_patch: register_action('done', state_data) return if patch_loaded: register_action('fxp', state_data) fixups = apply_fixups(khash, current_level, modules) register_action('unpatch', state_data) kpatch_ctl_unpatch(freezer_style) register_action('unfxp', state_data) remove_fixups(fixups) if kmod_changed: register_action('unload', state_data) unload_kmod('kcare') kmod_loaded = False if not kmod_loaded: register_action('load', state_data) load_kcare_kmod(khash, level) if use_anchor: # KCARE-509 touch_anchor() register_action('patch', state_data) kpatch_ctl_patch(patch_file, khash, level, description, freezer_style) update_sysctl() log_utils.loginfo('Patch level {0} applied. Effective kernel version {1}'.format(level, kcare.kcare_uname())) # Update last status check timestamp update_utils.touch_status_gap_file() # do final actions when update is considered as successful register_action('wait', state_data) nohup_fork(lambda: commit_update(state_data), sleep=config.SUCCESS_TIMEOUT) def kpatch_ctl_patch(patch_file, khash, level, description, freezer_style): args = [constants.KPATCH_CTL] blacklist_file = kcare.get_cache_path(khash, level, config.BLACKLIST_FILE) if os.path.exists(blacklist_file): args.extend(['-b', blacklist_file]) args.extend(['patch', '-d', description]) args.extend(['-m', freezer_style[0]]) args.append(patch_file) code, _, _ = process_utils.run_command(args, catch_stdout=True) if code != 0: raise ApplyPatchError(code, freezer_style, level, patch_file) def kpatch_ctl_unpatch(freezer_style): # TODO KPT-4001 refactoring, extract kpatch_ctl run to a class with patch/unpatch/etc methods with logging and error handling code, stdout, stderr = process_utils.run_command( [constants.KPATCH_CTL, 'unpatch', '-m', freezer_style[0]], catch_stdout=True, catch_stderr=True ) if code != 0: log_utils.logerror('Error unpatching, kpatch_ctl stdout:\n{0}\nstderr:\n{1}'.format(stdout, stderr), print_msg=False) raise KcareError('Error unpatching [{0}] {1}'.format(code, str(freezer_style)), status='unpatch error') def register_action(action, state_data): state_data['action'] = action state_data['ts'] = int(time.time()) utils.atomic_write(os.path.join(constants.PATCH_CACHE, 'kcare.state'), str(state_data)) def update_weak_modules(kmod_link): modules_path = '/usr/lib/modules/' if not os.path.isdir(modules_path): return for entry in os.listdir(modules_path): sym_link_path = os.path.join(modules_path, entry, 'weak-updates', 'kcare.ko') if not os.path.islink(sym_link_path): continue target_path = os.readlink(sym_link_path) if target_path == kmod_link: os.unlink(sym_link_path) update_depmod(entry) @process_utils.log_all_parent_processes def kcare_unload(freezer='', force=False): current_level = kcare.loaded_patch_level() pf = PatchFetcher() try: pf.fetch_fixups(current_level) except Exception as err: if not force: raise KcareError( "Unable to retrieve fixups: '{0}'. The unloading of patches has been " "interrupted. To proceed without fixups, use the --force flag.".format(err), status='fixups retrieval error', ) modules = kcare.get_loaded_modules() freezer_style = get_freezer_style(freezer, modules) with execute_hooks(): if 'kcare' in modules: need_unpatch = current_level is not None if need_unpatch: fixups = apply_fixups(kcare.get_kernel_hash(), current_level, modules) code, stdout, stderr = process_utils.run_command( [constants.KPATCH_CTL, 'unpatch', '-m', freezer_style[0]], catch_stdout=True, catch_stderr=True ) remove_fixups(fixups) if code != 0: log_utils.logerror( 'Error unpatching, kpatch_ctl stdout:\n{0}\nstderr:\n{1}'.format(stdout, stderr), print_msg=False ) raise KcareError('Error unpatching [{0}] {1}'.format(code, str(freezer_style)), status='unpatch error') # Unload kcare module and retry once after 10 seconds if failed # Kernel module could be loaded even if patch is not applyed utils.retry(errors.check_exc(KcareError), count=1, delay=UNLOAD_RETRY_DELAY)(unload_kmod)('kcare') kmod_link = get_kcare_kmod_link() if os.path.isfile(kmod_link): os.unlink(kmod_link) # KPT-3469 fix the case with kernel upgrade where third party modules are linked under # /usr/lib/modules/{uname_r}/weak-updates/kcare.ko so that kdump work good update_weak_modules(kmod_link) def kcare_info(is_json): pli = _patch_level_info() if is_json: return _kcare_info_json(pli) else: if pli.code != 0: return pli.msg if pli.applied_lvl is not None: return kcare._patch_info() def _kcare_info_json(pli): result = {'message': pli.msg} if pli.applied_lvl is not None: result.update(utils.data_as_dict(kcare._patch_info())) result.update(kcare.parse_patch_description(result.get('kpatch-description'))) result['kpatch-state'] = pli.state return json.dumps(result) class PLI: PATCH_LATEST = 0 PATCH_NEED_UPDATE = 1 PATCH_UNAVALIABLE = 2 PATCH_NOT_NEEDED = 3 def __init__(self, code, msg, remote_lvl, applied_lvl, state): self.code = code self.msg = msg self.remote_lvl = remote_lvl self.applied_lvl = applied_lvl self.state = state def _patch_level_info(): current_patch_level = kcare.loaded_patch_level() try: # this line raises UnknownKernel from the bottom of this try new_patch_level = get_latest_patch_level(reason='info') if current_patch_level: if kcare_need_update(current_patch_level, new_patch_level): code, msg, state = ( PLI.PATCH_NEED_UPDATE, "Update available, run 'kcarectl --update'.", 'applied', ) else: code, msg, state = ( PLI.PATCH_LATEST, 'The latest patch is applied.', 'applied', ) else: # no patch applied if new_patch_level == 0: code, msg, state = ( PLI.PATCH_NOT_NEEDED, "This kernel doesn't require any patches.", 'unset', ) else: code, msg, state = ( PLI.PATCH_NEED_UPDATE, "No patches applied, but some are available, run 'kcarectl --update'.", 'unset', ) info = PLI(code, msg, new_patch_level, current_patch_level, state) except UnknownKernelException: code = PLI.PATCH_UNAVALIABLE if config.STICKY_PATCH: msg = ( 'Invalid sticky patch tag {0} for kernel ({1} {2}). ' 'Please check /etc/sysconfig/kcare/kcare.conf ' 'STICKY_PATCH settings'.format(config.STICKY_PATCH, platform_utils.get_distro()[0], platform.release()) ) else: msg = 'New kernel detected ({0} {1} {2}).\nThere are no updates for this kernel yet.'.format( platform_utils.get_distro()[0], platform.release(), kcare.get_kernel_hash() ) info = PLI(code, msg, None, None, 'unavailable') return info def tag_server(tag): """ Request to tag server from ePortal. See KCARE-947 for more info :param tag: String used to tag the server :return: 0 on success, -1 on wrong server id, other values otherwise """ url = None try: # TODO: is it ok to send request in case when no server_id found? (machine is not registered in ePortal) server_id = serverid.get_serverid() query = urlencode([('server_id', server_id), ('tag', tag)]) url = ipv6_support.get_registration_url() + '/tag_server.plain?{0}'.format(query) response = http_utils.urlopen(url) res = utils.data_as_dict(utils.nstr(response.read())) return int(res['code']) except HTTPError as e: log_utils.print_cln_http_error(e, url) return -3 except URLError as ue: log_utils.print_cln_http_error(ue, url) return -4 except Exception as ee: log_utils.logerror('Internal Error {0}'.format(ee)) return -5 def kcdoctor(): doctor_url = utils.get_patch_server_url("doctor.sh") log_utils.logdebug("Requesting doctor script from `{0}`".format(doctor_url)) doctor_filename = KCDOCTOR with tempfile.NamedTemporaryFile() as doctor_dst: try: signature = fetch.fetch_signature(doctor_url, doctor_dst.name) utils.save_to_file(http_utils.urlopen(doctor_url), doctor_dst.name) fetch.check_gpg_signature(doctor_dst.name, signature) doctor_filename = doctor_dst.name except Exception as err: log_utils.logerror('Kcare doctor error: {0}. Fallback to the local one.'.format(err)) code, _, stderr = process_utils.run_command(['bash', doctor_filename, ipv6_support.get_patch_server()], catch_stderr=True) if code: raise KcareError("Script failed with '{0}' {1}".format(stderr, code), status='doctor script failed') def check_new_kc_version(): url = utils.get_patch_server_url('{0}-new-version'.format(EFFECTIVE_LATEST)) try: http_utils.urlopen(url) except URLError: return False log_utils.loginfo( 'A new version of the KernelCare package is available. To continue to get kernel updates, please install the new version' ) return True # mocked: tests/unit/test_patch_level_info.py def get_latest_patch_level(reason, policy=constants.POLICY_REMOTE, mode=constants.UPDATE_MODE_MANUAL): """ Get patch level to apply. :param reason: what was the source of request (update, info etc.) :param policy: REMOTE -- get latest patch_level from patchserver, LOCAL -- use cached latest, LOCAL_FIRST -- if cached level is None get latest from patchserver, use cache otherwise :param mode: constants.UPDATE_MODE_MANUAL, constants.UPDATE_MODE_AUTO or constants.UPDATE_MODE_SMART :return: patch_level string """ khash = kcare.get_kernel_hash() cached_level = get_cache_latest(khash) consider_remote_ex = policy == constants.POLICY_REMOTE or (policy == constants.POLICY_LOCAL_FIRST and cached_level is None) try: remote_level = fetch_patch_level(reason, mode) except errors.CapabilitiesMismatch as e: if cached_level is None: # error will be logged in __main__.py raise log_utils.logwarn(str(e)) log_utils.logwarn('Using previously downloaded patches') # force using already downloaded patches policy = constants.POLICY_LOCAL except Exception as ex: if consider_remote_ex: raise else: log_utils.kcarelog.warning('Unable to send data: {0}'.format(ex)) if policy == constants.POLICY_REMOTE: level = remote_level else: level = cached_level if cached_level is None: if policy == constants.POLICY_LOCAL: level = kcare.LegacyKernelPatchLevel(khash, 0) elif policy == constants.POLICY_LOCAL_FIRST: level = remote_level else: raise KcareError('Unknown policy, choose one of: REMOTE, LOCAL, LOCAL_FIRST') return level def update_patch_type(ptype): if ptype == 'edf': # The only way user can get here if call kcarectl --set-patch-type # we don't support this anyway and can silently ignore return config.PATCH_TYPE = '' if ptype == 'default' else ptype if probe_patch(fetch_patch_level(reason='probe'), config.PATCH_TYPE): config_handlers.update_config(PATCH_TYPE=config.PATCH_TYPE) if config.PATCH_TYPE in ('free', 'extra') and platform_utils.is_cpanel(): gid = config.FORCE_GID or CPANEL_GID edit_sysctl_conf( ('fs.enforce_symlinksifowner', 'fs.symlinkown_gid'), ('fs.enforce_symlinksifowner=1', 'fs.symlinkown_gid={0}'.format(gid)), ) log_utils.loginfo("'{0}' patch type selected".format(ptype)) else: raise KcareError("'{0}' patch type is unavailable for your kernel".format(ptype), status='patch type unavailable') # log_all_parent_processes must be outermost to run first @process_utils.log_all_parent_processes @update_utils.track_update_status('kernel') def do_update(freezer, mode, policy=constants.POLICY_REMOTE): """ :param mode: constants.UPDATE_MODE_MANUAL, constants.UPDATE_MODE_AUTO or constants.UPDATE_MODE_SMART :param policy: REMOTE -- download latest and patches from patchserver, LOCAL -- use cached files, LOCAL_FIRST -- download latest and patches if cached level is None, use cache in other cases :param freezer: freezer mode """ check_patch_type_compatibility(config.PATCH_TYPE) if policy == constants.POLICY_REMOTE: check_new_kc_version() try: level = get_latest_patch_level(reason='update', policy=policy, mode=mode) except UnknownKernelException as e: if mode in (constants.UPDATE_MODE_AUTO, constants.UPDATE_MODE_SMART) and config.IGNORE_UNKNOWN_KERNEL: msg = str(e) log_utils.kcarelog.warning(msg) return raise current_level = kcare.loaded_patch_level() # Cron triggers `kcarectl -q --auto-update` regardless of AUTO_UPDATE. # When AUTO_UPDATE=NO, return before touching the on-disk cache so the # currently-applied patch's cache directory is not rotated out by # subsequent fetches (CACHE_ENTRIES rotation would otherwise evict it # and break --patch-info). if mode == constants.UPDATE_MODE_AUTO and not config.AUTO_UPDATE: return pf = PatchFetcher(level) pf.fetch_patch() if not kcare_need_update(applied_level=current_level, new_level=level): log_utils.loginfo('No updates are needed for this kernel') return # Rotate crash report dumps try: utils.clean_directory(config.KDUMPS_DIR, keep_n=3, pattern="kcore*.dump") utils.clean_directory(config.KDUMPS_DIR, keep_n=3, pattern="kmsg*.log") except Exception: log_utils.kcarelog.exception('Error during crash reporter cleanup') khash = kcare.get_kernel_hash() with execute_hooks(): pf.fetch_fixups(current_level) kcare_load(khash, level, mode, freezer, use_anchor=mode == constants.UPDATE_MODE_SMART) kcare.dump_kernel_patch_level(level) clear_cache(khash, level) """ This is needed to support sticky keys as per https://cloudlinux.atlassian.net/browse/KCARE-953 """ def get_sticky(mode): count = sum( ( bool(config.STICKY_PATCH), bool(config.UPDATE_DELAY or config.AUTO_UPDATE_DELAY), bool(config.STICKY_PATCHSET or config.AUTO_STICKY_PATCHSET), ) ) if count > 1: raise KcareError( 'Invalid configuration: conflicting settings STICKY_PATCH,' ' [AUTO_]UPDATE_DELAY or [AUTO_]STICKY_PATCHSET. There should be only one of them', status='conflicting sticky settings', ) if config.STICKY_PATCH: return config.STICKY_PATCH if mode != constants.UPDATE_MODE_MANUAL: delay = config.AUTO_UPDATE_DELAY or config.UPDATE_DELAY patchset = config.AUTO_STICKY_PATCHSET or config.STICKY_PATCHSET else: delay = config.UPDATE_DELAY patchset = config.STICKY_PATCHSET if delay: return delay if patchset: return 'release-' + patchset def _stickyfy(prefix, fname): return prefix + '.' + fname def stickyfy(file, mode): """ Used to add sticky prefix to satisfy KCARE-953 :param file: name of the file to stickify :return: stickified file. """ s = get_sticky(mode) if not s: return file if s != 'KEY': return _stickyfy(s, file) server_id = serverid.get_serverid() if not server_id: log_utils.kcarelog.info('Patch set to STICKY_PATCH=KEY, but server is not registered with the key') sys.exit(-4) try: response = http_utils.urlopen(ipv6_support.get_registration_url() + '/sticky_patch.plain?server_id={0}'.format(server_id)) except HTTPError as e: log_utils.print_cln_http_error(e, e.url) sys.exit(-5) res = utils.data_as_dict(utils.nstr(response.read())) code = int(res['code']) if code == 0: return _stickyfy(res['prefix'], file) elif code == 1: return file elif code == 2: log_utils.kcarelog.info('Server ID is not recognized. Please check if the server is registered') sys.exit(-1) log_utils.kcarelog.info('Error: ' + res['message']) sys.exit(-3) ################################# # from python 2.7.17 ssl stdlib # ################################# def _dnsname_match(dn, hostname, max_wildcards=1): # pragma: no cover """Matching according to RFC 6125, section 6.4.3 http://tools.ietf.org/html/rfc6125#section-6.4.3 """ pats = [] if not dn: return False pieces = dn.split(r'.') leftmost = pieces[0] remainder = pieces[1:] wildcards = leftmost.count('*') if wildcards > max_wildcards: # Issue #17980: avoid denials of service by refusing more # than one wildcard per fragment. A survery of established # policy among SSL implementations showed it to be a # reasonable choice. raise CertificateError('too many wildcards in certificate DNS name: ' + repr(dn)) # speed up common case w/o wildcards if not wildcards: return dn.lower() == hostname.lower() # RFC 6125, section 6.4.3, subitem 1. # The client SHOULD NOT attempt to match a presented identifier in which # the wildcard character comprises a label other than the left-most label. if leftmost == '*': # When '*' is a fragment by itself, it matches a non-empty dotless # fragment. pats.append('[^.]+') elif leftmost.startswith('xn--') or hostname.startswith('xn--'): # RFC 6125, section 6.4.3, subitem 3. # The client SHOULD NOT attempt to match a presented identifier # where the wildcard character is embedded within an A-label or # U-label of an internationalized domain name. pats.append(re.escape(leftmost)) else: # Otherwise, '*' matches any dotless string, e.g. www* pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) # add the remaining fragments, ignore any wildcards for frag in remainder: pats.append(re.escape(frag)) pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) return pat.match(hostname) # match_hostname tweaked to get dns names from pyopenssl x509 cert object def match_hostname(cert, hostname): # pragma: no cover san = [] for i in range(cert.get_extension_count()): e = cert.get_extension(i) if e.get_short_name() == 'subjectAltName': san = [it.strip().split(':', 1) for it in str(e).split(',')] if not cert: raise ValueError( 'empty or no certificate, match_hostname needs a ' 'SSL socket or SSL context with either ' 'CERT_OPTIONAL or CERT_REQUIRED' ) dnsnames = [] for key, value in san: if key == 'DNS': if _dnsname_match(value, hostname): return dnsnames.append(value) if not dnsnames: # The subject is only checked when there is no dNSName entry # in subjectAltName cn = cert.get_subject().commonName if _dnsname_match(cn, hostname): return dnsnames.append(value) if len(dnsnames) > 1: raise CertificateError("hostname {0} doesn't match either of {1}".format(hostname, ', '.join(map(repr, dnsnames)))) elif len(dnsnames) == 1: raise CertificateError("hostname {0} doesn't match {1}".format(hostname, dnsnames[0])) else: raise CertificateError('no appropriate commonName or subjectAltName fields were found') ##################### # end of ssl stdlib # ##################### def main(): parser = ArgumentParser(prog="kcarectl", description='Manage KernelCare patches for your kernel') parser.add_argument('--debug', help='', action='store_true') parser.add_argument( '-i', '--info', help='Display information about KernelCare. Use with --json parameter to get result in JSON format.', action='store_true', ) parser.add_argument( '--app-info', help='Display information about KernelCare agent. Use with --json parameter to get result in JSON format.', action='store_true', ) parser.add_argument('-u', '--update', help='Download latest patches and apply them to the current kernel', action='store_true') parser.add_argument('--unload', help='Unload patches', action='store_true') parser.add_argument('--smart-update', help='Patch kernel based on UPDATE POLICY settings', action='store_true') parser.add_argument('--auto-update', help='Check if update is available, if so -- update', action='store_true') parser.add_argument( '--local', help='Update from a server local directory; accepts a path where patches are located', metavar='PATH' ) parser.add_argument('--patch-info', help='Return the list of applied patches', action='store_true') parser.add_argument('--freezer', help='Freezer type: full (default), smart, none', metavar='freezer') parser.add_argument('--nofreeze', help="[deprecated] Don't freeze tasks before patching", action='store_true') parser.add_argument('--uname', help='Return safe kernel version', action='store_true') parser.add_argument('--license-info', help='Return current license info', action='store_true') parser.add_argument('--status', help='Return status of updates', action='store_true') parser.add_argument('--register', help='Register using KernelCare Key', metavar='KEY') parser.add_argument( '--register-autoretry', help='Retry registering indefinitely if failed on the first attempt', action='store_true' ) parser.add_argument('--unregister', help='Unregister from KernelCare (for key-based servers only)', action='store_true') parser.add_argument('--check', help='Check if new update available', action='store_true') parser.add_argument( '--latest-patch-info', help='Return patch info for the latest available patch. Use with --json parameter to get result in JSON format.', action='store_true', ) parser.add_argument('--test', help='[deprecated] Use --prefix=test instead', action='store_true') parser.add_argument('--tag', help='Tag server with custom metadata, for ePortal users only', metavar='TAG') parser.add_argument( '--prefix', help='Patch source prefix used to test different builds by downloading builds from different locations based on prefix', metavar='PREFIX', ) parser.add_argument('--nosignature', help='Do not check signature', action='store_true') parser.add_argument( '--set-monitoring-key', help='Set monitoring key for IP based licenses. 16 to 32 characters, alphanumeric only', metavar='KEY' ) parser.add_argument('--doctor', help='Submits a vitals report to CloudLinux for analysis and bug-fixes', action='store_true') parser.add_argument( '--fallback', help='With --doctor, force the legacy kcdoctor.sh flow instead of the v2 upload path', action='store_true', ) parser.add_argument( '--kernel-anomaly-report', help='Submits a kernel anomaly report to CloudLinux for analysis and bug-fixes', action='store_true', ) parser.add_argument('--no-send', help='Skip sending artifacts', action='store_true', dest='save_only') parser.add_argument('--keep-local', help="Don't delete generated kernel anomaly report after sending", action='store_true') parser.add_argument('--enable-auto-update', help='Enable auto updates', action='store_true') parser.add_argument('--disable-auto-update', help='Disable auto updates', action='store_true') parser.add_argument( '--plugin-info', help='Provides the information shown in control panel plugins for KernelCare. ' 'Use with --json parameter to get result in JSON format.', action='store_true', ) parser.add_argument( '--server-info', help='Provides information about the host in JSON format.', action='store_true', ) parser.add_argument( '--json', help="Return '--plugin-info', '--latest-patch-info', '--patch-info', '--app-info' and '--info' results in JSON format", action='store_true', ) parser.add_argument('--version', help='Return the current version of KernelCare', action='store_true') parser.add_argument('--kpatch-debug', help='Enable the debug mode', action='store_true') parser.add_argument('--no-check-cert', help='Disable the patch server SSL certificates checking', action='store_true') parser.add_argument( '--set-patch-level', help='Set patch level to be applied. To select latest patch level set -1', action='store', type=int, default=None, required=False, ) parser.add_argument('--check-compatibility', help='Check compatibility.', action='store_true') parser.add_argument('--clear-cache', help='Clear all cached files', action='store_true') exclusive_group = parser.add_mutually_exclusive_group() exclusive_group.add_argument( '--set-patch-type', help="Set patch type feed. To select default feed use 'default' option", action='store' ) exclusive_group.add_argument('--edf-enabled', help='Enable exploit detection framework', action='store_true') exclusive_group.add_argument('--edf-disabled', help='Disable exploit detection framework', action='store_true') parser.add_argument( '--set-sticky-patch', help='Set patch to stick to date in DDMMYY format, or retrieve it from KEY if set to KEY. Leave empty to unstick', action='store', default=None, required=False, ) parser.add_argument( '-q', '--quiet', help='Suppress messages, provide only errors and warnings to stderr', action='store_true', required=False ) parser.add_argument('--has-flags', help='Check agent features') parser.add_argument('--force', help='Force action and ignore several restristions.', action="store_true") parser.add_argument('--set-config', help='Change configuration option', action='append', metavar='KEY=VALUE') if not config.LIBCARE_DISABLED: parser.add_argument( '--disable-libcare', help='Disable libcare services', dest='enable_libcare', action='store_const', const=False ) parser.add_argument( '--enable-libcare', help='Enable libcare services', dest='enable_libcare', action='store_const', const=True ) parser.add_argument( '--lib-update', help='Download latest patches and apply them to the current userspace libraries', action='store_true' ) parser.add_argument('--lib-unload', '--userspace-unload', help='Unload userspace patches', action='store_true') parser.add_argument('--lib-replugin', '--userspace-replugin', help='Reload libcare-server plugin', action='store_true') parser.add_argument('--lib-auto-update', help='Check if update is available, if so -- update', action='store_true') parser.add_argument('--lib-info', '--userspace-info', help='Display information about KernelCare+.', action='store_true') parser.add_argument( '--lib-patch-info', '--userspace-patch-info', help='Return the list of applied userspace patches', action='store_true' ) parser.add_argument('--lib-version', '--userspace-version', help='Return safe package version', metavar='PACKAGENAME') parser.add_argument( '--userspace-update', metavar='USERSPACE_PATCHES', nargs='?', const="", help='Download latest patches and apply them to the corresponding userspace processes', ) parser.add_argument( '--userspace-auto-update', help='Download latest patches and apply them to the corresponding userspace processes', action='store_true', ) parser.add_argument('--userspace-status', help='Return status of userspace updates', action='store_true') parser.add_argument( '--lib-tag', '--userspace-tag', metavar='TAG', help='Apply userspace patches for a specific tag (DDMMYY, ' 'YYYY-MM-DD, Nd, Nh, release-) into an isolated ' 'cache, leaving the default storage untouched. Use together with ' '--lib-update or --userspace-update.', action='store', default=None, required=False, ) args = parser.parse_args() config_handlers.set_settings_from_config_file() if not config.LIBCARE_DISABLED: config.FLAGS += ['libcare-enabled'] if args.has_flags is not None: if set(filter(None, args.has_flags.split(','))).issubset(config.FLAGS): return 0 else: return 1 # do not remove args.auto_update! # once added to machine, kcare-cron is never changed by package update; # old clients has no -q option in their cron, # so auto_update default silent mode must be saved forever if args.quiet or args.auto_update: if config.SILENCE_ERRORS: config.PRINT_LEVEL = constants.PRINT_CRITICAL else: config.PRINT_LEVEL = constants.PRINT_ERROR elif args.debug: config.PRINT_LEVEL = constants.PRINT_DEBUG if not args.uname: if os.getuid() != 0: print('Please run as root', file=sys.stderr) # noqa: T201 return 1 level = logging.INFO if args.quiet: level = logging.WARNING elif args.debug: level = logging.DEBUG # should be after root role check to create a log file with correct rights log_utils.initialize_logging(level) if not config.IGNORE_FEATURE_FLAGS: # run this after initialize_logging to log settings overrides config_handlers.set_feature_flags_from_cache() if args.clear_cache: utils.clear_all_cache() if args.set_patch_level: if args.set_patch_level >= 0: config.PATCH_LEVEL = str(args.set_patch_level) # type: ignore config_handlers.update_config(PATCH_LEVEL=config.PATCH_LEVEL) else: config.PATCH_LEVEL = None config_handlers.update_config(PATCH_LEVEL='') if args.set_sticky_patch is not None: config_handlers.update_config(STICKY_PATCH=args.set_sticky_patch) config.STICKY_PATCH = args.set_sticky_patch if args.nosignature: config.USE_SIGNATURE = False if args.no_check_cert: config.CHECK_SSL_CERTS = False if args.kpatch_debug: config.KPATCH_DEBUG = True if args.check_compatibility: check_compatibility() # EDF do nothing if args.edf_enabled: warnings.warn('Flag --edf-enabled has been deprecated and will be not available in future releases.', DeprecationWarning) elif args.edf_disabled: if config.PATCH_TYPE == 'edf': args.set_patch_type = ('' if config.PREV_PATCH_TYPE == 'edf' else config.PREV_PATCH_TYPE) or 'default' args.update = True if args.prefix: config.PREFIX = args.prefix if args.test: warnings.warn('Flag --test has been deprecated and will be not available in future releases.', DeprecationWarning) config.PREFIX = 'test' config.PREFIX = config.PREFIX.strip('/') if config.PREFIX and config.PREFIX not in EXPECTED_PREFIX: log_utils.kcarelog.warning('Prefix `{0}` is not in expected one {1}.'.format(config.PREFIX, ' '.join(EXPECTED_PREFIX))) if args.local: config.UPDATE_FROM_LOCAL = True config.PATCH_SERVER = 'file:' + args.local if args.set_patch_type: update_patch_type(args.set_patch_type) if config.PATCH_TYPE == 'edf': config.PATCH_TYPE = edf_fallback_ptype() warnings.warn('edf patches are deprecated. Fallback to {0}'.format(config.PATCH_TYPE or 'default'), DeprecationWarning) if args.app_info: utils.print_wrapper(platform_utils.app_info(is_json=args.json)) return if args.server_info: info = server_info.server_info(reason='debug', secure_boot_info=True, perf_metrics=True) utils.print_wrapper(json.dumps(info)) return apply_ptype(config.PATCH_TYPE) if args.doctor: doctor.send_doctor_report(kcdoctor, force_fallback=args.fallback) return if args.kernel_anomaly_report: data_package = anomaly.prepare_kernel_anomaly_report( server_info.server_info(reason='debug', secure_boot_info=True, perf_metrics=True) ) local_path_message = 'Kernel anomaly report file generated: {0}'.format(data_package.archive_path) if args.save_only: utils.print_wrapper(local_path_message) else: upload_name = anomaly.send_data_package(data_package) if upload_name: log_utils.loginfo('Kernel anomaly report uploaded successfully: {0}'.format(upload_name)) else: # pragma: no cover log_utils.logwarn('Failed to send kernel anomaly report', print_msg=True) if args.keep_local: utils.print_wrapper(local_path_message) elif data_package: # pragma: no branch data_package.remove_archive() if args.plugin_info: if args.json: plugin_info(fmt='json') else: plugin_info() return if args.enable_auto_update: config_handlers.update_config(AUTO_UPDATE='YES') return if args.disable_auto_update: config_handlers.update_config(AUTO_UPDATE='NO') return if args.set_config: config_handlers.update_config_from_args(args.set_config) return if args.set_monitoring_key: return set_monitoring_key_for_ip_license(args.set_monitoring_key) if args.unregister: auth.unregister() if args.register: if config.PATCH_TYPE == 'free': config_handlers.update_config(PATCH_TYPE='extra') return auth.register(args.register, args.register_autoretry) if args.license_info: # license_info returns zero if no valid license found and non-zero otherwise if auth.license_info() != 0: return 0 else: return 1 if args.tag is not None: return tag_server(args.tag) if args.version: utils.print_wrapper(constants.VERSION) if getattr(args, 'enable_libcare', None) is not None: libcare.set_libcare_status(args.enable_libcare) return 0 if not config.LIBCARE_DISABLED: lib_tag_kw = {'tag': args.lib_tag} if args.lib_tag else {} if args.userspace_status: return libcare.get_userspace_update_status() if args.lib_update: if libcare.do_userspace_update(**lib_tag_kw) is not None: log_utils.loginfo('Userspace patches are applied.') if args.lib_auto_update: libcare.do_userspace_update(mode=constants.UPDATE_MODE_AUTO, **lib_tag_kw) elif args.lib_unload: libcare.libcare_unload() log_utils.loginfo('Userspace patches are unloaded.') if args.lib_replugin: # pragma: no cover unit libcare.libcare_replugin() log_utils.loginfo('Libcare plugin reloaded.') if args.lib_info: utils.print_wrapper(libcare.libcare_info()) if args.lib_patch_info: utils.print_wrapper(libcare.libcare_patch_info()) if args.lib_version and libcare.libcare_server_started(): utils.print_wrapper(libcare.libcare_version(args.lib_version)) if args.userspace_update is not None: if args.userspace_update == '': # Get from config or defaults limit = config.USERSPACE_PATCHES or list(libcare.get_userspace_map().keys()) else: limit = [ptch.strip().lower() for ptch in args.userspace_update.split(',')] if libcare.do_userspace_update(limit=sorted(limit), **lib_tag_kw) is not None: log_utils.loginfo('Userspace patches are applied.') if args.userspace_auto_update: libcare.do_userspace_update(mode=constants.UPDATE_MODE_AUTO, limit=None, **lib_tag_kw) if args.info: utils.print_wrapper(kcare_info(is_json=args.json)) freezer = '' if args.nofreeze: warnings.warn('Flag --nofreeze has been deprecated and will be not available in future releases.', DeprecationWarning) freezer = 'none' if args.freezer: freezer = args.freezer if args.smart_update: do_update(freezer, mode=constants.UPDATE_MODE_SMART, policy=config.UPDATE_POLICY) if args.update: do_update(freezer, mode=constants.UPDATE_MODE_MANUAL) log_utils.loginfo('Kernel is safe') if args.uname: utils.print_wrapper(kcare.kcare_uname()) if args.unload: kcare_unload(freezer, force=args.force) log_utils.loginfo('KernelCare protection disabled. Your kernel might not be safe') if args.auto_update: config.CHECK_CLN_LICENSE_STATUS = False # wait to prevent spikes at the beginning of each minute KPT-1874 # bandit warns about using random.uniform for security which is not the case here time.sleep(random.uniform(0, 60)) # nosec B311 do_update(freezer, mode=constants.UPDATE_MODE_AUTO) if args.patch_info: patch_info(is_json=args.json) if args.status: return get_update_status() if args.latest_patch_info: kcare_latest_patch_info(is_json=args.json) if args.check: kcare_check() # No arg were provided if len(sys.argv) == 1: show_generic_info() usr/lib64/python3.12/encodings/__init__.py000064400000013374152532614230014217 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/lib2to3/__init__.py000064400000000234152532614760013523 0ustar00import warnings warnings.warn( "lib2to3 package is deprecated and may not be able to parse Python 3.10+", DeprecationWarning, stacklevel=2, ) usr/lib64/python2.7/ctypes/macholib/__init__.py000064400000000232152532616560015253 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.12/venv/__init__.py000064400000064176152532617340013237 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/lib/python2.7/site-packages/bs4/tests/__init__.py000064400000000033152532620210016350 0ustar00"The beautifulsoup tests." usr/lib64/python2.7/pydoc_data/__init__.py000064400000000000152532637030014261 0ustar00opt/alt/python311/lib64/python3.11/lib2to3/__init__.py000064400000000234152532642520016034 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/cssselect/__init__.py000064400000001177152532705730016533 0ustar00# -*- coding: utf-8 -*- """ CSS Selectors based on XPath ============================ This module supports selecting XML/HTML elements based on CSS selectors. See the `CSSSelector` class for details. :copyright: (c) 2007-2012 Ian Bicking and contributors. See AUTHORS for more details. :license: BSD, see LICENSE for more details. """ from cssselect.parser import (parse, Selector, FunctionalPseudoElement, SelectorError, SelectorSyntaxError) from cssselect.xpath import GenericTranslator, HTMLTranslator, ExpressionError VERSION = '0.9.2' __version__ = VERSION usr/lib64/python2.7/multiprocessing/__init__.py000064400000017175152533050750015425 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'] usr/lib/python3.6/site-packages/sepolicy/__init__.py000064400000111172152533053670016367 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/python3.6/site-packages/pygtkcompat/__init__.py000064400000001043152533067160017246 0ustar00 # pyflakes.ignore from .pygtkcompat import (enable, enable_gtk, enable_vte, enable_poppler, enable_webkit, enable_gudev, enable_gst, enable_goocanvas) __all__ = ['enable', 'enable_gtk', 'enable_vte', 'enable_poppler', 'enable_webkit', 'enable_gudev', 'enable_gst', 'enable_goocanvas'] usr/lib/python2.7/site-packages/pip/utils/__init__.py000064400000065063152533137040016471 0ustar00from __future__ import absolute_import from collections import deque import contextlib import errno import io import locale # we have a submodule named 'logging' which would shadow this if we used the # regular name: import logging as std_logging import re import os import posixpath import shutil import stat import subprocess import sys import tarfile import zipfile from pip.exceptions import InstallationError from pip.compat import console_to_str, expanduser, stdlib_pkgs from pip.locations import ( site_packages, user_site, running_under_virtualenv, virtualenv_no_global, write_delete_marker_file, ) from pip._vendor import pkg_resources from pip._vendor.six.moves import input from pip._vendor.six import PY2 from pip._vendor.retrying import retry if PY2: from io import BytesIO as StringIO else: from io import StringIO __all__ = ['rmtree', 'display_path', 'backup_dir', 'ask', 'splitext', 'format_size', 'is_installable_dir', 'is_svn_page', 'file_contents', 'split_leading_dir', 'has_leading_dir', 'normalize_path', 'renames', 'get_terminal_size', 'get_prog', 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', 'captured_stdout', 'ensure_dir', 'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS', 'get_installed_version'] logger = std_logging.getLogger(__name__) BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') ZIP_EXTENSIONS = ('.zip', '.whl') TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') ARCHIVE_EXTENSIONS = ( ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS) SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS try: import bz2 # noqa SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS except ImportError: logger.debug('bz2 module is not available') try: # Only for Python 3.3+ import lzma # noqa SUPPORTED_EXTENSIONS += XZ_EXTENSIONS except ImportError: logger.debug('lzma module is not available') def import_or_raise(pkg_or_module_string, ExceptionType, *args, **kwargs): try: return __import__(pkg_or_module_string) except ImportError: raise ExceptionType(*args, **kwargs) def ensure_dir(path): """os.path.makedirs without EEXIST.""" try: os.makedirs(path) except OSError as e: if e.errno != errno.EEXIST: raise def get_prog(): try: if os.path.basename(sys.argv[0]) in ('__main__.py', '-c'): return "%s -m pip" % sys.executable except (AttributeError, TypeError, IndexError): pass return 'pip' # Retry every half second for up to 3 seconds @retry(stop_max_delay=3000, wait_fixed=500) def rmtree(dir, ignore_errors=False): shutil.rmtree(dir, ignore_errors=ignore_errors, onerror=rmtree_errorhandler) def rmtree_errorhandler(func, path, exc_info): """On Windows, the files in .svn are read-only, so when rmtree() tries to remove them, an exception is thrown. We catch that here, remove the read-only attribute, and hopefully continue without problems.""" # if file type currently read only if os.stat(path).st_mode & stat.S_IREAD: # convert to read/write os.chmod(path, stat.S_IWRITE) # use the original function to repeat the operation func(path) return else: raise def display_path(path): """Gives the display value for a given path, making it relative to cwd if possible.""" path = os.path.normcase(os.path.abspath(path)) if sys.version_info[0] == 2: path = path.decode(sys.getfilesystemencoding(), 'replace') path = path.encode(sys.getdefaultencoding(), 'replace') if path.startswith(os.getcwd() + os.path.sep): path = '.' + path[len(os.getcwd()):] return path def backup_dir(dir, ext='.bak'): """Figure out the name of a directory to back up the given dir to (adding .bak, .bak2, etc)""" n = 1 extension = ext while os.path.exists(dir + extension): n += 1 extension = ext + str(n) return dir + extension def ask_path_exists(message, options): for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): if action in options: return action return ask(message, options) def ask(message, options): """Ask the message interactively, with the given possible responses""" while 1: if os.environ.get('PIP_NO_INPUT'): raise Exception( 'No input was expected ($PIP_NO_INPUT set); question: %s' % message ) response = input(message) response = response.strip().lower() if response not in options: print( 'Your response (%r) was not one of the expected responses: ' '%s' % (response, ', '.join(options)) ) else: return response def format_size(bytes): if bytes > 1000 * 1000: return '%.1fMB' % (bytes / 1000.0 / 1000) elif bytes > 10 * 1000: return '%ikB' % (bytes / 1000) elif bytes > 1000: return '%.1fkB' % (bytes / 1000.0) else: return '%ibytes' % bytes def is_installable_dir(path): """Return True if `path` is a directory containing a setup.py file.""" if not os.path.isdir(path): return False setup_py = os.path.join(path, 'setup.py') if os.path.isfile(setup_py): return True return False def is_svn_page(html): """ Returns true if the page appears to be the index page of an svn repository """ return (re.search(r'[^<]*Revision \d+:', html) and re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) def file_contents(filename): with open(filename, 'rb') as fp: return fp.read().decode('utf-8') def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): """Yield pieces of data from a file-like object until EOF.""" while True: chunk = file.read(size) if not chunk: break yield chunk def split_leading_dir(path): path = path.lstrip('/').lstrip('\\') if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) or '\\' not in path): return path.split('/', 1) elif '\\' in path: return path.split('\\', 1) else: return path, '' def has_leading_dir(paths): """Returns true if all the paths have the same leading path name (i.e., everything is in one subdirectory in an archive)""" common_prefix = None for path in paths: prefix, rest = split_leading_dir(path) if not prefix: return False elif common_prefix is None: common_prefix = prefix elif prefix != common_prefix: return False return True def normalize_path(path, resolve_symlinks=True): """ Convert a path to its canonical, case-normalized, absolute version. """ path = expanduser(path) if resolve_symlinks: path = os.path.realpath(path) else: path = os.path.abspath(path) return os.path.normcase(path) def splitext(path): """Like os.path.splitext, but take off .tar too""" base, ext = posixpath.splitext(path) if base.lower().endswith('.tar'): ext = base[-4:] + ext base = base[:-4] return base, ext def renames(old, new): """Like os.renames(), but handles renaming across devices.""" # Implementation borrowed from os.renames(). head, tail = os.path.split(new) if head and tail and not os.path.exists(head): os.makedirs(head) shutil.move(old, new) head, tail = os.path.split(old) if head and tail: try: os.removedirs(head) except OSError: pass def is_local(path): """ Return True if path is within sys.prefix, if we're running in a virtualenv. If we're not in a virtualenv, all paths are considered "local." """ if not running_under_virtualenv(): return True return normalize_path(path).startswith(normalize_path(sys.prefix)) def dist_is_local(dist): """ Return True if given Distribution object is installed locally (i.e. within current virtualenv). Always True if we're not in a virtualenv. """ return is_local(dist_location(dist)) def dist_in_usersite(dist): """ Return True if given Distribution is installed in user site. """ norm_path = normalize_path(dist_location(dist)) return norm_path.startswith(normalize_path(user_site)) def dist_in_site_packages(dist): """ Return True if given Distribution is installed in distutils.sysconfig.get_python_lib(). """ return normalize_path( dist_location(dist) ).startswith(normalize_path(site_packages)) def dist_is_editable(dist): """Is distribution an editable install?""" for path_item in sys.path: egg_link = os.path.join(path_item, dist.project_name + '.egg-link') if os.path.isfile(egg_link): return True return False def get_installed_distributions(local_only=True, skip=stdlib_pkgs, include_editables=True, editables_only=False, user_only=False): """ Return a list of installed Distribution objects. If ``local_only`` is True (default), only return installations local to the current virtualenv, if in a virtualenv. ``skip`` argument is an iterable of lower-case project names to ignore; defaults to stdlib_pkgs If ``editables`` is False, don't report editables. If ``editables_only`` is True , only report editables. If ``user_only`` is True , only report installations in the user site directory. """ if local_only: local_test = dist_is_local else: def local_test(d): return True if include_editables: def editable_test(d): return True else: def editable_test(d): return not dist_is_editable(d) if editables_only: def editables_only_test(d): return dist_is_editable(d) else: def editables_only_test(d): return True if user_only: user_test = dist_in_usersite else: def user_test(d): return True return [d for d in pkg_resources.working_set if local_test(d) and d.key not in skip and editable_test(d) and editables_only_test(d) and user_test(d) ] def egg_link_path(dist): """ Return the path for the .egg-link file if it exists, otherwise, None. There's 3 scenarios: 1) not in a virtualenv try to find in site.USER_SITE, then site_packages 2) in a no-global virtualenv try to find in site_packages 3) in a yes-global virtualenv try to find in site_packages, then site.USER_SITE (don't look in global location) For #1 and #3, there could be odd cases, where there's an egg-link in 2 locations. This method will just return the first one found. """ sites = [] if running_under_virtualenv(): if virtualenv_no_global(): sites.append(site_packages) else: sites.append(site_packages) if user_site: sites.append(user_site) else: if user_site: sites.append(user_site) sites.append(site_packages) for site in sites: egglink = os.path.join(site, dist.project_name) + '.egg-link' if os.path.isfile(egglink): return egglink def dist_location(dist): """ Get the site-packages location of this distribution. Generally this is dist.location, except in the case of develop-installed packages, where dist.location is the source code location, and we want to know where the egg-link file is. """ egg_link = egg_link_path(dist) if egg_link: return egg_link return dist.location def get_terminal_size(): """Returns a tuple (x, y) representing the width(x) and the height(x) in characters of the terminal window.""" def ioctl_GWINSZ(fd): try: import fcntl import termios import struct cr = struct.unpack( 'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234') ) except: return None if cr == (0, 0): return None return cr cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) if not cr: try: fd = os.open(os.ctermid(), os.O_RDONLY) cr = ioctl_GWINSZ(fd) os.close(fd) except: pass if not cr: cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) return int(cr[1]), int(cr[0]) def current_umask(): """Get the current umask which involves having to set it temporarily.""" mask = os.umask(0) os.umask(mask) return mask def unzip_file(filename, location, flatten=True): """ Unzip the file (with path `filename`) to the destination `location`. All files are written based on system defaults and umask (i.e. permissions are not preserved), except that regular file members with any execute permissions (user, group, or world) have "chmod +x" applied after being written. Note that for windows, any execute changes using os.chmod are no-ops per the python docs. """ ensure_dir(location) zipfp = open(filename, 'rb') try: zip = zipfile.ZipFile(zipfp, allowZip64=True) leading = has_leading_dir(zip.namelist()) and flatten for info in zip.infolist(): name = info.filename data = zip.read(name) fn = name if leading: fn = split_leading_dir(name)[1] fn = os.path.join(location, fn) dir = os.path.dirname(fn) if fn.endswith('/') or fn.endswith('\\'): # A directory ensure_dir(fn) else: ensure_dir(dir) fp = open(fn, 'wb') try: fp.write(data) finally: fp.close() mode = info.external_attr >> 16 # if mode and regular file and any execute permissions for # user/group/world? if mode and stat.S_ISREG(mode) and mode & 0o111: # make dest file have execute for user/group/world # (chmod +x) no-op on windows per python docs os.chmod(fn, (0o777 - current_umask() | 0o111)) finally: zipfp.close() def untar_file(filename, location): """ Untar the file (with path `filename`) to the destination `location`. All files are written based on system defaults and umask (i.e. permissions are not preserved), except that regular file members with any execute permissions (user, group, or world) have "chmod +x" applied after being written. Note that for windows, any execute changes using os.chmod are no-ops per the python docs. """ ensure_dir(location) if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): mode = 'r:gz' elif filename.lower().endswith(BZ2_EXTENSIONS): mode = 'r:bz2' elif filename.lower().endswith(XZ_EXTENSIONS): mode = 'r:xz' elif filename.lower().endswith('.tar'): mode = 'r' else: logger.warning( 'Cannot determine compression type for file %s', filename, ) mode = 'r:*' tar = tarfile.open(filename, mode) try: # note: python<=2.5 doesn't seem to know about pax headers, filter them leading = has_leading_dir([ member.name for member in tar.getmembers() if member.name != 'pax_global_header' ]) for member in tar.getmembers(): fn = member.name if fn == 'pax_global_header': continue if leading: fn = split_leading_dir(fn)[1] path = os.path.join(location, fn) if member.isdir(): ensure_dir(path) elif member.issym(): try: tar._extract_member(member, path) except Exception as exc: # Some corrupt tar files seem to produce this # (specifically bad symlinks) logger.warning( 'In the tar file %s the member %s is invalid: %s', filename, member.name, exc, ) continue else: try: fp = tar.extractfile(member) except (KeyError, AttributeError) as exc: # Some corrupt tar files seem to produce this # (specifically bad symlinks) logger.warning( 'In the tar file %s the member %s is invalid: %s', filename, member.name, exc, ) continue ensure_dir(os.path.dirname(path)) with open(path, 'wb') as destfp: shutil.copyfileobj(fp, destfp) fp.close() # Update the timestamp (useful for cython compiled files) tar.utime(member, path) # member have any execute permissions for user/group/world? if member.mode & 0o111: # make dest file have execute for user/group/world # no-op on windows per python docs os.chmod(path, (0o777 - current_umask() | 0o111)) finally: tar.close() def unpack_file(filename, location, content_type, link): filename = os.path.realpath(filename) if (content_type == 'application/zip' or filename.lower().endswith(ZIP_EXTENSIONS) or zipfile.is_zipfile(filename)): unzip_file( filename, location, flatten=not filename.endswith('.whl') ) elif (content_type == 'application/x-gzip' or tarfile.is_tarfile(filename) or filename.lower().endswith( TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS)): untar_file(filename, location) elif (content_type and content_type.startswith('text/html') and is_svn_page(file_contents(filename))): # We don't really care about this from pip.vcs.subversion import Subversion Subversion('svn+' + link.url).unpack(location) else: # FIXME: handle? # FIXME: magic signatures? logger.critical( 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' 'cannot detect archive format', filename, location, content_type, ) raise InstallationError( 'Cannot determine archive format of %s' % location ) def call_subprocess(cmd, show_stdout=True, cwd=None, on_returncode='raise', command_desc=None, extra_environ=None, spinner=None): # This function's handling of subprocess output is confusing and I # previously broke it terribly, so as penance I will write a long comment # explaining things. # # The obvious thing that affects output is the show_stdout= # kwarg. show_stdout=True means, let the subprocess write directly to our # stdout. Even though it is nominally the default, it is almost never used # inside pip (and should not be used in new code without a very good # reason); as of 2016-02-22 it is only used in a few places inside the VCS # wrapper code. Ideally we should get rid of it entirely, because it # creates a lot of complexity here for a rarely used feature. # # Most places in pip set show_stdout=False. What this means is: # - We connect the child stdout to a pipe, which we read. # - By default, we hide the output but show a spinner -- unless the # subprocess exits with an error, in which case we show the output. # - If the --verbose option was passed (= loglevel is DEBUG), then we show # the output unconditionally. (But in this case we don't want to show # the output a second time if it turns out that there was an error.) # # stderr is always merged with stdout (even if show_stdout=True). if show_stdout: stdout = None else: stdout = subprocess.PIPE if command_desc is None: cmd_parts = [] for part in cmd: if ' ' in part or '\n' in part or '"' in part or "'" in part: part = '"%s"' % part.replace('"', '\\"') cmd_parts.append(part) command_desc = ' '.join(cmd_parts) logger.debug("Running command %s", command_desc) env = os.environ.copy() if extra_environ: env.update(extra_environ) try: proc = subprocess.Popen( cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, cwd=cwd, env=env) except Exception as exc: logger.critical( "Error %s while executing command %s", exc, command_desc, ) raise if stdout is not None: all_output = [] while True: line = console_to_str(proc.stdout.readline()) if not line: break line = line.rstrip() all_output.append(line + '\n') if logger.getEffectiveLevel() <= std_logging.DEBUG: # Show the line immediately logger.debug(line) else: # Update the spinner if spinner is not None: spinner.spin() proc.wait() if spinner is not None: if proc.returncode: spinner.finish("error") else: spinner.finish("done") if proc.returncode: if on_returncode == 'raise': if (logger.getEffectiveLevel() > std_logging.DEBUG and not show_stdout): logger.info( 'Complete output from command %s:', command_desc, ) logger.info( ''.join(all_output) + '\n----------------------------------------' ) raise InstallationError( 'Command "%s" failed with error code %s in %s' % (command_desc, proc.returncode, cwd)) elif on_returncode == 'warn': logger.warning( 'Command "%s" had error code %s in %s', command_desc, proc.returncode, cwd, ) elif on_returncode == 'ignore': pass else: raise ValueError('Invalid value: on_returncode=%s' % repr(on_returncode)) if not show_stdout: return ''.join(all_output) def read_text_file(filename): """Return the contents of *filename*. Try to decode the file contents with utf-8, the preferred system encoding (e.g., cp1252 on some Windows machines), and latin1, in that order. Decoding a byte string with latin1 will never raise an error. In the worst case, the returned string will contain some garbage characters. """ with open(filename, 'rb') as fp: data = fp.read() encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1'] for enc in encodings: try: data = data.decode(enc) except UnicodeDecodeError: continue break assert type(data) != bytes # Latin1 should have worked. return data def _make_build_dir(build_dir): os.makedirs(build_dir) write_delete_marker_file(build_dir) class FakeFile(object): """Wrap a list of lines in an object with readline() to make ConfigParser happy.""" def __init__(self, lines): self._gen = (l for l in lines) def readline(self): try: try: return next(self._gen) except NameError: return self._gen.next() except StopIteration: return '' def __iter__(self): return self._gen class StreamWrapper(StringIO): @classmethod def from_stream(cls, orig_stream): cls.orig_stream = orig_stream return cls() # compileall.compile_dir() needs stdout.encoding to print to stdout @property def encoding(self): return self.orig_stream.encoding @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. Taken from Lib/support/__init__.py in the CPython repo. """ orig_stdout = getattr(sys, stream_name) setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) 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') Taken from Lib/support/__init__.py in the CPython repo. """ return captured_output('stdout') class cached_property(object): """A property that is only computed once per instance and then replaces itself with an ordinary attribute. Deleting the attribute resets the property. Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175 """ def __init__(self, func): self.__doc__ = getattr(func, '__doc__') self.func = func def __get__(self, obj, cls): if obj is None: # We're being accessed from the class itself, not from an object return self value = obj.__dict__[self.func.__name__] = self.func(obj) return value def get_installed_version(dist_name, lookup_dirs=None): """Get the installed version of dist_name avoiding pkg_resources cache""" # Create a requirement that we'll look for inside of setuptools. req = pkg_resources.Requirement.parse(dist_name) # We want to avoid having this cached, so we need to construct a new # working set each time. if lookup_dirs is None: working_set = pkg_resources.WorkingSet() else: working_set = pkg_resources.WorkingSet(lookup_dirs) # Get the installed distribution from our working set dist = working_set.find(req) # Check to see if we got an installed distribution or not, if we did # we want to return it's version. return dist.version if dist else None def consume(iterator): """Consume an iterable at C speed.""" deque(iterator, maxlen=0) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/tuned/storage/__init__.py�������������������������������������������0000644�����������������00000000215�15253316461�0017313 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from tuned.storage.storage import Storage from tuned.storage.factory import Factory from tuned.storage.pickle_provider import PickleProvider �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.6/multiprocessing/dummy/__init__.py�����������������������������������������������0000644�����������������00000005520�15253320214�0016537 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # 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): 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 # # # 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 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 ..pool import ThreadPool return ThreadPool(processes, initializer, initargs) JoinableQueue = Queue ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/sqlite3/__init__.py����������������������������������������������0000644�����������������00000004750�15253330313�0016141 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Häring <gh@ghaering.de> # # 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 <gh@ghaering.de>. """ from sqlite3.dbapi2 import * # bpo-42264: OptimizedUnicode was deprecated in Python 3.10. It's scheduled # for removal in Python 3.12. def __getattr__(name): if name == "OptimizedUnicode": import warnings msg = (""" OptimizedUnicode is deprecated and will be removed in Python 3.12. Since Python 3.3 it has simply been an alias for 'str'. """) warnings.warn(msg, DeprecationWarning, stacklevel=2) return str raise AttributeError(f"module 'sqlite3' has no attribute '{name}'") ������������������������usr/lib/python3.6/site-packages/firewall/server/__init__.py�����������������������������������������0000644�����������������00000000000�15253330413�0017624 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/venv/__init__.py�������������������������������������������������0000644�����������������00000061075�15253336426�0015551 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������""" 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 CORE_VENV_DEPS = ('pip', 'setuptools') 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) 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) 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 os.path.normcase(real_env_exe) != os.path.normcase(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. """ 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 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): 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.') parser.add_argument('--upgrade-deps', default=False, action='store_true', dest='upgrade_deps', help='Upgrade core dependencies: {} to the latest ' 'version in PyPI'.format( ' '.join(CORE_VENV_DEPS))) 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/lib/python2.7/site-packages/pip/_vendor/cachecontrol/__init__.py��������������������������������0000644�����������������00000000456�15253336521�0021426 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""CacheControl import Interface. Make it easy to import from cachecontrol without long namespaces. """ __author__ = 'Eric Larson' __email__ = 'eric@ionrock.org' __version__ = '0.11.7' from .wrapper import CacheControl from .adapter import CacheControlAdapter from .controller import CacheController ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python2.7/site-packages/bs4/builder/__init__.py���������������������������������������������0000644�����������������00000027707�15253336523�0016666 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. from collections import defaultdict import itertools import sys from bs4.element import ( CharsetMetaAttributeValue, ContentMetaAttributeValue, HTMLAwareEntitySubstitution, whitespace_re ) __all__ = [ 'HTMLTreeBuilder', 'SAXTreeBuilder', 'TreeBuilder', 'TreeBuilderRegistry', ] # Some useful features for a TreeBuilder to have. FAST = 'fast' PERMISSIVE = 'permissive' STRICT = 'strict' XML = 'xml' HTML = 'html' HTML_5 = 'html5' class TreeBuilderRegistry(object): def __init__(self): self.builders_for_feature = defaultdict(list) self.builders = [] def register(self, treebuilder_class): """Register a treebuilder based on its advertised features.""" for feature in treebuilder_class.features: self.builders_for_feature[feature].insert(0, treebuilder_class) self.builders.insert(0, treebuilder_class) def lookup(self, *features): if len(self.builders) == 0: # There are no builders at all. return None if len(features) == 0: # They didn't ask for any features. Give them the most # recently registered builder. return self.builders[0] # Go down the list of features in order, and eliminate any builders # that don't match every feature. features = list(features) features.reverse() candidates = None candidate_set = None while len(features) > 0: feature = features.pop() we_have_the_feature = self.builders_for_feature.get(feature, []) if len(we_have_the_feature) > 0: if candidates is None: candidates = we_have_the_feature candidate_set = set(candidates) else: # Eliminate any candidates that don't have this feature. candidate_set = candidate_set.intersection( set(we_have_the_feature)) # The only valid candidates are the ones in candidate_set. # Go through the original list of candidates and pick the first one # that's in candidate_set. if candidate_set is None: return None for candidate in candidates: if candidate in candidate_set: return candidate return None # The BeautifulSoup class will take feature lists from developers and use them # to look up builders in this registry. builder_registry = TreeBuilderRegistry() class TreeBuilder(object): """Turn a document into a Beautiful Soup object tree.""" NAME = "[Unknown tree builder]" ALTERNATE_NAMES = [] features = [] is_xml = False picklable = False preserve_whitespace_tags = set() empty_element_tags = None # A tag will be considered an empty-element # tag when and only when it has no contents. # A value for these tag/attribute combinations is a space- or # comma-separated list of CDATA, rather than a single CDATA. cdata_list_attributes = {} def __init__(self): self.soup = None def reset(self): pass def can_be_empty_element(self, tag_name): """Might a tag with this name be an empty-element tag? The final markup may or may not actually present this tag as self-closing. For instance: an HTMLBuilder does not consider a <p> tag to be an empty-element tag (it's not in HTMLBuilder.empty_element_tags). This means an empty <p> tag will be presented as "<p></p>", not "<p />". The default implementation has no opinion about which tags are empty-element tags, so a tag will be presented as an empty-element tag if and only if it has no contents. "<foo></foo>" will become "<foo />", and "<foo>bar</foo>" will be left alone. """ if self.empty_element_tags is None: return True return tag_name in self.empty_element_tags def feed(self, markup): raise NotImplementedError() def prepare_markup(self, markup, user_specified_encoding=None, document_declared_encoding=None): return markup, None, None, False def test_fragment_to_document(self, fragment): """Wrap an HTML fragment to make it look like a document. Different parsers do this differently. For instance, lxml introduces an empty <head> tag, and html5lib doesn't. Abstracting this away lets us write simple tests which run HTML fragments through the parser and compare the results against other HTML fragments. This method should not be used outside of tests. """ return fragment def set_up_substitutions(self, tag): return False def _replace_cdata_list_attribute_values(self, tag_name, attrs): """Replaces class="foo bar" with class=["foo", "bar"] Modifies its input in place. """ if not attrs: return attrs if self.cdata_list_attributes: universal = self.cdata_list_attributes.get('*', []) tag_specific = self.cdata_list_attributes.get( tag_name.lower(), None) for attr in attrs.keys(): if attr in universal or (tag_specific and attr in tag_specific): # We have a "class"-type attribute whose string # value is a whitespace-separated list of # values. Split it into a list. value = attrs[attr] if isinstance(value, basestring): values = whitespace_re.split(value) else: # html5lib sometimes calls setAttributes twice # for the same tag when rearranging the parse # tree. On the second call the attribute value # here is already a list. If this happens, # leave the value alone rather than trying to # split it again. values = value attrs[attr] = values return attrs class SAXTreeBuilder(TreeBuilder): """A Beautiful Soup treebuilder that listens for SAX events.""" def feed(self, markup): raise NotImplementedError() def close(self): pass def startElement(self, name, attrs): attrs = dict((key[1], value) for key, value in list(attrs.items())) #print "Start %s, %r" % (name, attrs) self.soup.handle_starttag(name, attrs) def endElement(self, name): #print "End %s" % name self.soup.handle_endtag(name) def startElementNS(self, nsTuple, nodeName, attrs): # Throw away (ns, nodeName) for now. self.startElement(nodeName, attrs) def endElementNS(self, nsTuple, nodeName): # Throw away (ns, nodeName) for now. self.endElement(nodeName) #handler.endElementNS((ns, node.nodeName), node.nodeName) def startPrefixMapping(self, prefix, nodeValue): # Ignore the prefix for now. pass def endPrefixMapping(self, prefix): # Ignore the prefix for now. # handler.endPrefixMapping(prefix) pass def characters(self, content): self.soup.handle_data(content) def startDocument(self): pass def endDocument(self): pass class HTMLTreeBuilder(TreeBuilder): """This TreeBuilder knows facts about HTML. Such as which tags are empty-element tags. """ preserve_whitespace_tags = HTMLAwareEntitySubstitution.preserve_whitespace_tags empty_element_tags = set([ # These are from HTML5. 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr', # These are from earlier versions of HTML and are removed in HTML5. 'basefont', 'bgsound', 'command', 'frame', 'image', 'isindex', 'nextid', 'spacer' ]) # The HTML standard defines these as block-level elements. Beautiful # Soup does not treat these elements differently from other elements, # but it may do so eventually, and this information is available if # you need to use it. block_elements = set(["address", "article", "aside", "blockquote", "canvas", "dd", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hr", "li", "main", "nav", "noscript", "ol", "output", "p", "pre", "section", "table", "tfoot", "ul", "video"]) # The HTML standard defines these attributes as containing a # space-separated list of values, not a single value. That is, # class="foo bar" means that the 'class' attribute has two values, # 'foo' and 'bar', not the single value 'foo bar'. When we # encounter one of these attributes, we will parse its value into # a list of values if possible. Upon output, the list will be # converted back into a string. cdata_list_attributes = { "*" : ['class', 'accesskey', 'dropzone'], "a" : ['rel', 'rev'], "link" : ['rel', 'rev'], "td" : ["headers"], "th" : ["headers"], "td" : ["headers"], "form" : ["accept-charset"], "object" : ["archive"], # These are HTML5 specific, as are *.accesskey and *.dropzone above. "area" : ["rel"], "icon" : ["sizes"], "iframe" : ["sandbox"], "output" : ["for"], } def set_up_substitutions(self, tag): # We are only interested in <meta> tags if tag.name != 'meta': return False http_equiv = tag.get('http-equiv') content = tag.get('content') charset = tag.get('charset') # We are interested in <meta> tags that say what encoding the # document was originally in. This means HTML 5-style <meta> # tags that provide the "charset" attribute. It also means # HTML 4-style <meta> tags that provide the "content" # attribute and have "http-equiv" set to "content-type". # # In both cases we will replace the value of the appropriate # attribute with a standin object that can take on any # encoding. meta_encoding = None if charset is not None: # HTML 5 style: # <meta charset="utf8"> meta_encoding = charset tag['charset'] = CharsetMetaAttributeValue(charset) elif (content is not None and http_equiv is not None and http_equiv.lower() == 'content-type'): # HTML 4 style: # <meta http-equiv="content-type" content="text/html; charset=utf8"> tag['content'] = ContentMetaAttributeValue(content) return (meta_encoding is not None) def register_treebuilders_from(module): """Copy TreeBuilders from the given module into this module.""" # I'm fairly sure this is not the best way to do this. this_module = sys.modules['bs4.builder'] for name in module.__all__: obj = getattr(module, name) if issubclass(obj, TreeBuilder): setattr(this_module, name, obj) this_module.__all__.append(name) # Register the builder while we're at it. this_module.builder_registry.register(obj) class ParserRejectedMarkup(Exception): pass # Builders are registered in reverse order of priority, so that custom # builder registrations will take precedence. In general, we want lxml # to take precedence over html5lib, because it's faster. And we only # want to use HTMLParser as a last result. from . import _htmlparser register_treebuilders_from(_htmlparser) try: from . import _html5lib register_treebuilders_from(_html5lib) except ImportError: # They don't have html5lib installed. pass try: from . import _lxml register_treebuilders_from(_lxml) except ImportError: # They don't have lxml installed. pass ���������������������������������������������������������usr/lib/python3.6/site-packages/firewall/core/io/__init__.py����������������������������������������0000644�����������������00000003074�15253337605�0017705 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # # Copyright (C) 2012 Red Hat, Inc. # # Authors: # Thomas Woerner <twoerner@redhat.com> # # 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, see <http://www.gnu.org/licenses/>. # # fix xmlplus to be compatible with the python xml sax parser and python 3 # by adding __contains__ to xml.sax.xmlreader.AttributesImpl import xml if "_xmlplus" in xml.__file__: from xml.sax.xmlreader import AttributesImpl if not hasattr(AttributesImpl, "__contains__"): # this is missing: def __AttributesImpl__contains__(self, name): return name in getattr(self, "_attrs") # add it using the name __contains__ setattr(AttributesImpl, "__contains__", __AttributesImpl__contains__) from xml.sax.saxutils import XMLGenerator if not hasattr(XMLGenerator, "_write"): # this is missing: def __XMLGenerator_write(self, text): getattr(self, "_out").write(text) # add it using the name _write setattr(XMLGenerator, "_write", __XMLGenerator_write) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python2.7/lib-tk/test/test_tkinter/__init__.py��������������������������������������������0000644�����������������00000000000�15253340033�0017022 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/html2text/__init__.py�����������������������������������������������0000644�����������������00000100004�15253341644�0016461 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""html2text: Turn HTML into equivalent Markdown-structured text.""" import html.entities import html.parser import re import urllib.parse as urlparse from textwrap import wrap from html2text import config from html2text.utils import ( dumb_css_parser, element_style, escape_md, escape_md_section, google_fixed_width_font, google_has_height, google_list_style, google_text_emphasis, hn, list_numbering_start, pad_tables_in_text, skipwrap, unifiable_n, ) __version__ = (2019, 9, 26) # TODO: # Support decoded entities with UNIFIABLE. class HTML2Text(html.parser.HTMLParser): def __init__(self, out=None, baseurl="", bodywidth=config.BODY_WIDTH): """ Input parameters: out: possible custom replacement for self.outtextf (which appends lines of text). baseurl: base URL of the document we process """ super().__init__(convert_charrefs=False) # Config options self.split_next_td = False self.td_count = 0 self.table_start = False self.unicode_snob = config.UNICODE_SNOB # covered in cli self.escape_snob = config.ESCAPE_SNOB # covered in cli self.links_each_paragraph = config.LINKS_EACH_PARAGRAPH self.body_width = bodywidth # covered in cli self.skip_internal_links = config.SKIP_INTERNAL_LINKS # covered in cli self.inline_links = config.INLINE_LINKS # covered in cli self.protect_links = config.PROTECT_LINKS # covered in cli self.google_list_indent = config.GOOGLE_LIST_INDENT # covered in cli self.ignore_links = config.IGNORE_ANCHORS # covered in cli self.ignore_images = config.IGNORE_IMAGES # covered in cli self.images_as_html = config.IMAGES_AS_HTML # covered in cli self.images_to_alt = config.IMAGES_TO_ALT # covered in cli self.images_with_size = config.IMAGES_WITH_SIZE # covered in cli self.ignore_emphasis = config.IGNORE_EMPHASIS # covered in cli self.bypass_tables = config.BYPASS_TABLES # covered in cli self.ignore_tables = config.IGNORE_TABLES # covered in cli self.google_doc = False # covered in cli self.ul_item_mark = "*" # covered in cli self.emphasis_mark = "_" # covered in cli self.strong_mark = "**" self.single_line_break = config.SINGLE_LINE_BREAK # covered in cli self.use_automatic_links = config.USE_AUTOMATIC_LINKS # covered in cli self.hide_strikethrough = False # covered in cli self.mark_code = config.MARK_CODE self.wrap_list_items = config.WRAP_LIST_ITEMS # covered in cli self.wrap_links = config.WRAP_LINKS # covered in cli self.pad_tables = config.PAD_TABLES # covered in cli self.default_image_alt = config.DEFAULT_IMAGE_ALT # covered in cli self.tag_callback = None self.open_quote = config.OPEN_QUOTE # covered in cli self.close_quote = config.CLOSE_QUOTE # covered in cli if out is None: self.out = self.outtextf else: self.out = out # empty list to store output characters before they are "joined" self.outtextlist = [] self.quiet = 0 self.p_p = 0 # number of newline character to print before next output self.outcount = 0 self.start = True self.space = False self.a = [] self.astack = [] self.maybe_automatic_link = None self.empty_link = False self.absolute_url_matcher = re.compile(r"^[a-zA-Z+]+://") self.acount = 0 self.list = [] self.blockquote = 0 self.pre = False self.startpre = False self.code = False self.quote = False self.br_toggle = "" self.lastWasNL = False self.lastWasList = False self.style = 0 self.style_def = {} self.tag_stack = [] self.emphasis = 0 self.drop_white_space = 0 self.inheader = False self.abbr_title = None # current abbreviation definition self.abbr_data = None # last inner HTML (for abbr being defined) self.abbr_list = {} # stack of abbreviations to write later self.baseurl = baseurl self.stressed = False self.preceding_stressed = False self.preceding_data = None self.current_tag = None config.UNIFIABLE["nbsp"] = " _place_holder;" def feed(self, data): data = data.replace("</' + 'script>", "</ignore>") super().feed(data) def handle(self, data): self.feed(data) self.feed("") markdown = self.optwrap(self.close()) if self.pad_tables: return pad_tables_in_text(markdown) else: return markdown def outtextf(self, s): self.outtextlist.append(s) if s: self.lastWasNL = s[-1] == "\n" def close(self): super().close() self.pbr() self.o("", force="end") outtext = "".join(self.outtextlist) if self.unicode_snob: nbsp = html.entities.html5["nbsp;"] else: nbsp = " " outtext = outtext.replace(" _place_holder;", nbsp) # Clear self.outtextlist to avoid memory leak of its content to # the next handling. self.outtextlist = [] return outtext def handle_charref(self, c): self.handle_data(self.charref(c), True) def handle_entityref(self, c): ref = self.entityref(c) # ref may be an empty string (e.g. for ‎/‏ markers that should # not contribute to the final output). # self.handle_data cannot handle a zero-length string right after a # stressed tag or mid-text within a stressed tag (text get split and # self.stressed/self.preceding_stressed gets switched after the first # part of that text). if ref: self.handle_data(ref, True) def handle_starttag(self, tag, attrs): self.handle_tag(tag, attrs, start=True) def handle_endtag(self, tag): self.handle_tag(tag, None, start=False) def previousIndex(self, attrs): """ :type attrs: dict :returns: The index of certain set of attributes (of a link) in the self.a list. If the set of attributes is not found, returns None :rtype: int """ if "href" not in attrs: return None match = False for i, a in enumerate(self.a): if "href" in a and a["href"] == attrs["href"]: if "title" in a or "title" in attrs: if ( "title" in a and "title" in attrs and a["title"] == attrs["title"] ): match = True else: match = True if match: return i return None def handle_emphasis(self, start, tag_style, parent_style): """ Handles various text emphases """ tag_emphasis = google_text_emphasis(tag_style) parent_emphasis = google_text_emphasis(parent_style) # handle Google's text emphasis strikethrough = "line-through" in tag_emphasis and self.hide_strikethrough # google and others may mark a font's weight as `bold` or `700` bold = False for bold_marker in config.BOLD_TEXT_STYLE_VALUES: bold = bold_marker in tag_emphasis and bold_marker not in parent_emphasis if bold: break italic = "italic" in tag_emphasis and "italic" not in parent_emphasis fixed = ( google_fixed_width_font(tag_style) and not google_fixed_width_font(parent_style) and not self.pre ) if start: # crossed-out text must be handled before other attributes # in order not to output qualifiers unnecessarily if bold or italic or fixed: self.emphasis += 1 if strikethrough: self.quiet += 1 if italic: self.o(self.emphasis_mark) self.drop_white_space += 1 if bold: self.o(self.strong_mark) self.drop_white_space += 1 if fixed: self.o("`") self.drop_white_space += 1 self.code = True else: if bold or italic or fixed: # there must not be whitespace before closing emphasis mark self.emphasis -= 1 self.space = False if fixed: if self.drop_white_space: # empty emphasis, drop it self.drop_white_space -= 1 else: self.o("`") self.code = False if bold: if self.drop_white_space: # empty emphasis, drop it self.drop_white_space -= 1 else: self.o(self.strong_mark) if italic: if self.drop_white_space: # empty emphasis, drop it self.drop_white_space -= 1 else: self.o(self.emphasis_mark) # space is only allowed after *all* emphasis marks if (bold or italic) and not self.emphasis: self.o(" ") if strikethrough: self.quiet -= 1 def handle_tag(self, tag, attrs, start): self.current_tag = tag # attrs is None for endtags if attrs is None: attrs = {} else: attrs = dict(attrs) if self.tag_callback is not None: if self.tag_callback(self, tag, attrs, start) is True: return # first thing inside the anchor tag is another tag # that produces some output if ( start and self.maybe_automatic_link is not None and tag not in ["p", "div", "style", "dl", "dt"] and (tag != "img" or self.ignore_images) ): self.o("[") self.maybe_automatic_link = None self.empty_link = False if self.google_doc: # the attrs parameter is empty for a closing tag. in addition, we # need the attributes of the parent nodes in order to get a # complete style description for the current element. we assume # that google docs export well formed html. parent_style = {} if start: if self.tag_stack: parent_style = self.tag_stack[-1][2] tag_style = element_style(attrs, self.style_def, parent_style) self.tag_stack.append((tag, attrs, tag_style)) else: dummy, attrs, tag_style = ( self.tag_stack.pop() if self.tag_stack else (None, {}, {}) ) if self.tag_stack: parent_style = self.tag_stack[-1][2] if hn(tag): self.p() if start: self.inheader = True self.o(hn(tag) * "#" + " ") else: self.inheader = False return # prevent redundant emphasis marks on headers if tag in ["p", "div"]: if self.google_doc: if start and google_has_height(tag_style): self.p() else: self.soft_br() elif self.astack and tag == "div": pass else: self.p() if tag == "br" and start: if self.blockquote > 0: self.o(" \n> ") else: self.o(" \n") if tag == "hr" and start: self.p() self.o("* * *") self.p() if tag in ["head", "style", "script"]: if start: self.quiet += 1 else: self.quiet -= 1 if tag == "style": if start: self.style += 1 else: self.style -= 1 if tag in ["body"]: self.quiet = 0 # sites like 9rules.com never close <head> if tag == "blockquote": if start: self.p() self.o("> ", force=True) self.start = True self.blockquote += 1 else: self.blockquote -= 1 self.p() def no_preceding_space(self): return self.preceding_data and re.match(r"[^\s]", self.preceding_data[-1]) if tag in ["em", "i", "u"] and not self.ignore_emphasis: if start and no_preceding_space(self): emphasis = " " + self.emphasis_mark else: emphasis = self.emphasis_mark self.o(emphasis) if start: self.stressed = True if tag in ["strong", "b"] and not self.ignore_emphasis: if start and no_preceding_space(self): strong = " " + self.strong_mark else: strong = self.strong_mark self.o(strong) if start: self.stressed = True if tag in ["del", "strike", "s"]: if start and no_preceding_space(self): strike = " ~~" else: strike = "~~" self.o(strike) if start: self.stressed = True if self.google_doc: if not self.inheader: # handle some font attributes, but leave headers clean self.handle_emphasis(start, tag_style, parent_style) if tag in ["kbd", "code", "tt"] and not self.pre: self.o("`") # TODO: `` `this` `` self.code = not self.code if tag == "abbr": if start: self.abbr_title = None self.abbr_data = "" if "title" in attrs: self.abbr_title = attrs["title"] else: if self.abbr_title is not None: self.abbr_list[self.abbr_data] = self.abbr_title self.abbr_title = None self.abbr_data = None if tag == "q": if not self.quote: self.o(self.open_quote) else: self.o(self.close_quote) self.quote = not self.quote def link_url(self, link, title=""): url = urlparse.urljoin(self.baseurl, link) title = ' "{}"'.format(title) if title.strip() else "" self.o("]({url}{title})".format(url=escape_md(url), title=title)) if tag == "a" and not self.ignore_links: if start: if ( "href" in attrs and attrs["href"] is not None and not (self.skip_internal_links and attrs["href"].startswith("#")) ): self.astack.append(attrs) self.maybe_automatic_link = attrs["href"] self.empty_link = True if self.protect_links: attrs["href"] = "<" + attrs["href"] + ">" else: self.astack.append(None) else: if self.astack: a = self.astack.pop() if self.maybe_automatic_link and not self.empty_link: self.maybe_automatic_link = None elif a: if self.empty_link: self.o("[") self.empty_link = False self.maybe_automatic_link = None if self.inline_links: try: title = a["title"] if a["title"] else "" title = escape_md(title) except KeyError: link_url(self, a["href"], "") else: link_url(self, a["href"], title) else: i = self.previousIndex(a) if i is not None: a = self.a[i] else: self.acount += 1 a["count"] = self.acount a["outcount"] = self.outcount self.a.append(a) self.o("][" + str(a["count"]) + "]") if tag == "img" and start and not self.ignore_images: if "src" in attrs: if not self.images_to_alt: attrs["href"] = attrs["src"] alt = attrs.get("alt") or self.default_image_alt # If we have images_with_size, write raw html including width, # height, and alt attributes if self.images_as_html or ( self.images_with_size and ("width" in attrs or "height" in attrs) ): self.o("<img src='" + attrs["src"] + "' ") if "width" in attrs: self.o("width='" + attrs["width"] + "' ") if "height" in attrs: self.o("height='" + attrs["height"] + "' ") if alt: self.o("alt='" + alt + "' ") self.o("/>") return # If we have a link to create, output the start if self.maybe_automatic_link is not None: href = self.maybe_automatic_link if ( self.images_to_alt and escape_md(alt) == href and self.absolute_url_matcher.match(href) ): self.o("<" + escape_md(alt) + ">") self.empty_link = False return else: self.o("[") self.maybe_automatic_link = None self.empty_link = False # If we have images_to_alt, we discard the image itself, # considering only the alt text. if self.images_to_alt: self.o(escape_md(alt)) else: self.o("![" + escape_md(alt) + "]") if self.inline_links: href = attrs.get("href") or "" self.o( "(" + escape_md(urlparse.urljoin(self.baseurl, href)) + ")" ) else: i = self.previousIndex(attrs) if i is not None: attrs = self.a[i] else: self.acount += 1 attrs["count"] = self.acount attrs["outcount"] = self.outcount self.a.append(attrs) self.o("[" + str(attrs["count"]) + "]") if tag == "dl" and start: self.p() if tag == "dt" and not start: self.pbr() if tag == "dd" and start: self.o(" ") if tag == "dd" and not start: self.pbr() if tag in ["ol", "ul"]: # Google Docs create sub lists as top level lists if not self.list and not self.lastWasList: self.p() if start: if self.google_doc: list_style = google_list_style(tag_style) else: list_style = tag numbering_start = list_numbering_start(attrs) self.list.append({"name": list_style, "num": numbering_start}) else: if self.list: self.list.pop() if not self.google_doc and not self.list: self.o("\n") self.lastWasList = True else: self.lastWasList = False if tag == "li": self.pbr() if start: if self.list: li = self.list[-1] else: li = {"name": "ul", "num": 0} if self.google_doc: nest_count = self.google_nest_count(tag_style) else: nest_count = len(self.list) # TODO: line up <ol><li>s > 9 correctly. self.o(" " * nest_count) if li["name"] == "ul": self.o(self.ul_item_mark + " ") elif li["name"] == "ol": li["num"] += 1 self.o(str(li["num"]) + ". ") self.start = True if tag in ["table", "tr", "td", "th"]: if self.ignore_tables: if tag == "tr": if start: pass else: self.soft_br() else: pass elif self.bypass_tables: if start: self.soft_br() if tag in ["td", "th"]: if start: self.o("<{}>\n\n".format(tag)) else: self.o("\n</{}>".format(tag)) else: if start: self.o("<{}>".format(tag)) else: self.o("</{}>".format(tag)) else: if tag == "table": if start: self.table_start = True if self.pad_tables: self.o("<" + config.TABLE_MARKER_FOR_PAD + ">") self.o(" \n") else: if self.pad_tables: self.o("</" + config.TABLE_MARKER_FOR_PAD + ">") self.o(" \n") if tag in ["td", "th"] and start: if self.split_next_td: self.o("| ") self.split_next_td = True if tag == "tr" and start: self.td_count = 0 if tag == "tr" and not start: self.split_next_td = False self.soft_br() if tag == "tr" and not start and self.table_start: # Underline table header self.o("|".join(["---"] * self.td_count)) self.soft_br() self.table_start = False if tag in ["td", "th"] and start: self.td_count += 1 if tag == "pre": if start: self.startpre = True self.pre = True else: self.pre = False if self.mark_code: self.out("\n[/code]") self.p() # TODO: Add docstring for these one letter functions def pbr(self): "Pretty print has a line break" if self.p_p == 0: self.p_p = 1 def p(self): "Set pretty print to 1 or 2 lines" self.p_p = 1 if self.single_line_break else 2 def soft_br(self): "Soft breaks" self.pbr() self.br_toggle = " " def o(self, data, puredata=False, force=False): """ Deal with indentation and whitespace """ if self.abbr_data is not None: self.abbr_data += data if not self.quiet: if self.google_doc: # prevent white space immediately after 'begin emphasis' # marks ('**' and '_') lstripped_data = data.lstrip() if self.drop_white_space and not (self.pre or self.code): data = lstripped_data if lstripped_data != "": self.drop_white_space = 0 if puredata and not self.pre: # This is a very dangerous call ... it could mess up # all handling of   when not handled properly # (see entityref) data = re.sub(r"\s+", r" ", data) if data and data[0] == " ": self.space = True data = data[1:] if not data and not force: return if self.startpre: # self.out(" :") #TODO: not output when already one there if not data.startswith("\n") and not data.startswith("\r\n"): # <pre>stuff... data = "\n" + data if self.mark_code: self.out("\n[code]") self.p_p = 0 bq = ">" * self.blockquote if not (force and data and data[0] == ">") and self.blockquote: bq += " " if self.pre: if not self.list: bq += " " # else: list content is already partially indented for i in range(len(self.list)): bq += " " data = data.replace("\n", "\n" + bq) if self.startpre: self.startpre = False if self.list: # use existing initial indentation data = data.lstrip("\n") if self.start: self.space = False self.p_p = 0 self.start = False if force == "end": # It's the end. self.p_p = 0 self.out("\n") self.space = False if self.p_p: self.out((self.br_toggle + "\n" + bq) * self.p_p) self.space = False self.br_toggle = "" if self.space: if not self.lastWasNL: self.out(" ") self.space = False if self.a and ( (self.p_p == 2 and self.links_each_paragraph) or force == "end" ): if force == "end": self.out("\n") newa = [] for link in self.a: if self.outcount > link["outcount"]: self.out( " [" + str(link["count"]) + "]: " + urlparse.urljoin(self.baseurl, link["href"]) ) if "title" in link: self.out(" (" + link["title"] + ")") self.out("\n") else: newa.append(link) # Don't need an extra line when nothing was done. if self.a != newa: self.out("\n") self.a = newa if self.abbr_list and force == "end": for abbr, definition in self.abbr_list.items(): self.out(" *[" + abbr + "]: " + definition + "\n") self.p_p = 0 self.out(data) self.outcount += 1 def handle_data(self, data, entity_char=False): if not data: # Data may be empty for some HTML entities. For example, # LEFT-TO-RIGHT MARK. return if self.stressed: data = data.strip() self.stressed = False self.preceding_stressed = True elif self.preceding_stressed: if ( re.match(r"[^\s.!?]", data[0]) and not hn(self.current_tag) and self.current_tag not in ["a", "code", "pre"] ): # should match a letter or common punctuation data = " " + data self.preceding_stressed = False if self.style: self.style_def.update(dumb_css_parser(data)) if self.maybe_automatic_link is not None: href = self.maybe_automatic_link if ( href == data and self.absolute_url_matcher.match(href) and self.use_automatic_links ): self.o("<" + data + ">") self.empty_link = False return else: self.o("[") self.maybe_automatic_link = None self.empty_link = False if not self.code and not self.pre and not entity_char: data = escape_md_section(data, snob=self.escape_snob) self.preceding_data = data self.o(data, puredata=True) def charref(self, name): if name[0] in ["x", "X"]: c = int(name[1:], 16) else: c = int(name) if not self.unicode_snob and c in unifiable_n: return unifiable_n[c] else: try: return chr(c) except ValueError: # invalid unicode return "" def entityref(self, c): if not self.unicode_snob and c in config.UNIFIABLE: return config.UNIFIABLE[c] try: ch = html.entities.html5[c + ";"] except KeyError: return "&" + c + ";" return config.UNIFIABLE[c] if c == "nbsp" else ch def google_nest_count(self, style): """ Calculate the nesting count of google doc lists :type style: dict :rtype: int """ nest_count = 0 if "margin-left" in style: nest_count = int(style["margin-left"][:-2]) // self.google_list_indent return nest_count def optwrap(self, text): """ Wrap all paragraphs in the provided text. :type text: str :rtype: str """ if not self.body_width: return text result = "" newlines = 0 # I cannot think of a better solution for now. # To avoid the non-wrap behaviour for entire paras # because of the presence of a link in it if not self.wrap_links: self.inline_links = False for para in text.split("\n"): if len(para) > 0: if not skipwrap(para, self.wrap_links, self.wrap_list_items): indent = "" if para.startswith(" " + self.ul_item_mark): # list item continuation: add a double indent to the # new lines indent = " " elif para.startswith("> "): # blockquote continuation: add the greater than symbol # to the new lines indent = "> " wrapped = wrap( para, self.body_width, break_long_words=False, subsequent_indent=indent, ) result += "\n".join(wrapped) if para.endswith(" "): result += " \n" newlines = 1 elif indent: result += "\n" newlines = 1 else: result += "\n\n" newlines = 2 else: # Warning for the tempted!!! # Be aware that obvious replacement of this with # line.isspace() # DOES NOT work! Explanations are welcome. if not config.RE_SPACE.match(para): result += para + "\n" newlines = 1 else: if newlines < 2: result += "\n" newlines += 1 return result def html2text(html, baseurl="", bodywidth=None): if bodywidth is None: bodywidth = config.BODY_WIDTH h = HTML2Text(baseurl=baseurl, bodywidth=bodywidth) return h.handle(html) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/tuned/plugins/__init__.py�������������������������������������������0000644�����������������00000000061�15253341716�0017330 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .repository import * from . import instance �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/ctypes/__init__.py�����������������������������������������������0000644�����������������00000042664�15253342503�0016076 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""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 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(<NULL>)" % 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: <obj>.qsort -> callable object <obj>['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 = '<uninitialized>' _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) __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(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 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) _reset_cache() ����������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/tomllib/__init__.py����������������������������������������������0000644�����������������00000000464�15253342525�0016225 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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__ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/http/__init__.py�������������������������������������������������0000644�����������������00000017351�15253343351�0015543 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from 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 # 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/lib64/python3.6/site-packages/gi/__init__.py����������������������������������������������������0000644�����������������00000013556�15253350274�0015315 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- Mode: Python; py-indent-offset: 4 -*- # vim: tabstop=4 shiftwidth=4 expandtab # # Copyright (C) 2005-2009 Johan Dahlin <johan@gnome.org> # # 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 from __future__ import absolute_import # support overrides in different directories than our gi module from pkgutil import extend_path __path__ = extend_path(__path__, __name__) import sys import os import importlib import types _static_binding_error = ('When using gi.repository you must not import static ' 'modules like "gobject". Please change all occurrences ' 'of "import gobject" to "from gi.repository import GObject". ' 'See: https://bugzilla.gnome.org/show_bug.cgi?id=709183') # we can't have pygobject 2 loaded at the same time we load the internal _gobject if 'gobject' in sys.modules: raise ImportError(_static_binding_error) from . import _gi from ._gi import _API from ._gi import Repository from ._gi import PyGIDeprecationWarning from ._gi import PyGIWarning _API = _API # pyflakes PyGIDeprecationWarning = PyGIDeprecationWarning PyGIWarning = PyGIWarning _versions = {} _overridesdir = os.path.join(os.path.dirname(__file__), 'overrides') # Needed for compatibility with "pygobject.h"/pygobject_init() _gobject = types.ModuleType("gi._gobject") sys.modules[_gobject.__name__] = _gobject _gobject._PyGObject_API = _gi._PyGObject_API _gobject.pygobject_version = _gi.pygobject_version version_info = _gi.pygobject_version[:] __version__ = "{0}.{1}.{2}".format(*version_info) class _DummyStaticModule(types.ModuleType): __path__ = None def __getattr__(self, name): raise AttributeError(_static_binding_error) sys.modules['glib'] = _DummyStaticModule('glib', _static_binding_error) sys.modules['gobject'] = _DummyStaticModule('gobject', _static_binding_error) sys.modules['gio'] = _DummyStaticModule('gio', _static_binding_error) sys.modules['gtk'] = _DummyStaticModule('gtk', _static_binding_error) sys.modules['gtk.gdk'] = _DummyStaticModule('gtk.gdk', _static_binding_error) def check_version(version): if isinstance(version, str): version_list = tuple(map(int, version.split("."))) else: version_list = version if version_list > version_info: raise ValueError(( "pygobject's version %s required, and available version " "%s is not recent enough") % (version, __version__) ) def require_version(namespace, version): """ Ensures the correct versions are loaded when importing `gi` modules. :param namespace: The name of module to require. :type namespace: str :param version: The version of module to require. :type version: str :raises ValueError: If module/version is already loaded, already required, or unavailable. :Example: .. code-block:: python import gi gi.require_version('Gtk', '3.0') """ repository = Repository.get_default() if sys.version_info[0] <= 2: if not isinstance(version, basestring): raise ValueError('Namespace version needs to be a string.') else: if not isinstance(version, str): raise ValueError('Namespace version needs to be a string.') if namespace in repository.get_loaded_namespaces(): loaded_version = repository.get_version(namespace) if loaded_version != version: raise ValueError('Namespace %s is already loaded with version %s' % (namespace, loaded_version)) if namespace in _versions and _versions[namespace] != version: raise ValueError('Namespace %s already requires version %s' % (namespace, _versions[namespace])) available_versions = repository.enumerate_versions(namespace) if not available_versions: raise ValueError('Namespace %s not available' % namespace) if version not in available_versions: raise ValueError('Namespace %s not available for version %s' % (namespace, version)) _versions[namespace] = version def require_versions(requires): """ Utility function for consolidating multiple `gi.require_version()` calls. :param requires: The names and versions of modules to require. :type requires: dict :Example: .. code-block:: python import gi gi.require_versions({'Gtk': '3.0', 'GLib': '2.0', 'Gio': '2.0'}) """ for module_name, module_version in requires.items(): require_version(module_name, module_version) def get_required_version(namespace): return _versions.get(namespace, None) def require_foreign(namespace, symbol=None): """Ensure the given foreign marshaling module is available and loaded. :param str namespace: Introspection namespace of the foreign module (e.g. "cairo") :param symbol: Optional symbol typename to ensure a converter exists. :type symbol: str or None :raises: ImportError :Example: .. code-block:: python import gi import cairo gi.require_foreign('cairo') """ try: _gi.require_foreign(namespace, symbol) except Exception as e: raise ImportError(str(e)) importlib.import_module('gi.repository', namespace) ��������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/pyudev/_ctypeslib/__init__.py���������������������������������������0000644�����������������00000001717�15253353225�0020210 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # Copyright (C) 2015 mulhern <amulhern@redhat.com> # 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._ctypeslib ================= Wrappers for libraries. .. moduleauthor:: mulhern <amulhern@redhat.com> """ from . import libc from . import libudev �������������������������������������������������usr/lib/python2.7/site-packages/pip/_vendor/certifi/__init__.py�������������������������������������0000644�����������������00000000077�15253353464�0020413 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .core import where, old_where __version__ = "2018.01.18" �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/dateutil/__init__.py������������������������������������������������0000644�����������������00000000105�15253353562�0016344 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- from ._version import VERSION as __version__ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.6/collections/__init__.py���������������������������������������������������������0000644�����������������00000131364�15253361471�0014513 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'''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/python311/lib64/python3.11/email/mime/__init__.py�������������������������������������������0000644�����������������00000000000�15253362013�0016555 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/pip/_vendor/idna/__init__.py����������������������������������������0000644�����������������00000000072�15253362527�0017674 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .package_data import __version__ from .core import * ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/pydoc_data/__init__.py�������������������������������������������0000644�����������������00000000000�15253363063�0016654 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/tuned/exports/__init__.py�������������������������������������������0000644�����������������00000003561�15253372367�0017371 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from . import interfaces from . import controller from . import dbus_exporter as dbus from . import dbus_exporter_with_properties as dbus_with_properties from . import unix_socket_exporter as unix_socket def export(*args, **kwargs): """Decorator, use to mark exportable methods.""" def wrapper(method): method.export_params = [ args, kwargs ] return method return wrapper def signal(*args, **kwargs): """Decorator, use to mark exportable signals.""" def wrapper(method): method.signal_params = [ args, kwargs ] return method return wrapper def property_setter(*args, **kwargs): """Decorator, use to mark setters of exportable properties.""" def wrapper(method): method.property_set_params = [ args, kwargs ] return method return wrapper def property_getter(*args, **kwargs): """Decorator, use to mark getters of exportable properties.""" def wrapper(method): method.property_get_params = [ args, kwargs ] return method return wrapper def property_changed(*args, **kwargs): ctl = controller.ExportsController.get_instance() return ctl.property_changed(*args, **kwargs) def register_exporter(instance): if not isinstance(instance, interfaces.ExporterInterface): raise Exception() ctl = controller.ExportsController.get_instance() return ctl.register_exporter(instance) def register_object(instance): if not isinstance(instance, interfaces.ExportableInterface): raise Exception() ctl = controller.ExportsController.get_instance() return ctl.register_object(instance) def send_signal(*args, **kwargs): ctl = controller.ExportsController.get_instance() return ctl.send_signal(*args, **kwargs) def start(): ctl = controller.ExportsController.get_instance() return ctl.start() def stop(): ctl = controller.ExportsController.get_instance() return ctl.stop() def period_check(): ctl = controller.ExportsController.get_instance() return ctl.period_check() �����������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/slip/_wrappers/__init__.py������������������������������������������0000644�����������������00000000000�15253372405�0017471 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/bs4/builder/__init__.py���������������������������������������������0000644�����������������00000027706�15253372451�0016665 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. from collections import defaultdict import itertools import sys from bs4.element import ( CharsetMetaAttributeValue, ContentMetaAttributeValue, HTMLAwareEntitySubstitution, whitespace_re ) __all__ = [ 'HTMLTreeBuilder', 'SAXTreeBuilder', 'TreeBuilder', 'TreeBuilderRegistry', ] # Some useful features for a TreeBuilder to have. FAST = 'fast' PERMISSIVE = 'permissive' STRICT = 'strict' XML = 'xml' HTML = 'html' HTML_5 = 'html5' class TreeBuilderRegistry(object): def __init__(self): self.builders_for_feature = defaultdict(list) self.builders = [] def register(self, treebuilder_class): """Register a treebuilder based on its advertised features.""" for feature in treebuilder_class.features: self.builders_for_feature[feature].insert(0, treebuilder_class) self.builders.insert(0, treebuilder_class) def lookup(self, *features): if len(self.builders) == 0: # There are no builders at all. return None if len(features) == 0: # They didn't ask for any features. Give them the most # recently registered builder. return self.builders[0] # Go down the list of features in order, and eliminate any builders # that don't match every feature. features = list(features) features.reverse() candidates = None candidate_set = None while len(features) > 0: feature = features.pop() we_have_the_feature = self.builders_for_feature.get(feature, []) if len(we_have_the_feature) > 0: if candidates is None: candidates = we_have_the_feature candidate_set = set(candidates) else: # Eliminate any candidates that don't have this feature. candidate_set = candidate_set.intersection( set(we_have_the_feature)) # The only valid candidates are the ones in candidate_set. # Go through the original list of candidates and pick the first one # that's in candidate_set. if candidate_set is None: return None for candidate in candidates: if candidate in candidate_set: return candidate return None # The BeautifulSoup class will take feature lists from developers and use them # to look up builders in this registry. builder_registry = TreeBuilderRegistry() class TreeBuilder(object): """Turn a document into a Beautiful Soup object tree.""" NAME = "[Unknown tree builder]" ALTERNATE_NAMES = [] features = [] is_xml = False picklable = False preserve_whitespace_tags = set() empty_element_tags = None # A tag will be considered an empty-element # tag when and only when it has no contents. # A value for these tag/attribute combinations is a space- or # comma-separated list of CDATA, rather than a single CDATA. cdata_list_attributes = {} def __init__(self): self.soup = None def reset(self): pass def can_be_empty_element(self, tag_name): """Might a tag with this name be an empty-element tag? The final markup may or may not actually present this tag as self-closing. For instance: an HTMLBuilder does not consider a <p> tag to be an empty-element tag (it's not in HTMLBuilder.empty_element_tags). This means an empty <p> tag will be presented as "<p></p>", not "<p />". The default implementation has no opinion about which tags are empty-element tags, so a tag will be presented as an empty-element tag if and only if it has no contents. "<foo></foo>" will become "<foo />", and "<foo>bar</foo>" will be left alone. """ if self.empty_element_tags is None: return True return tag_name in self.empty_element_tags def feed(self, markup): raise NotImplementedError() def prepare_markup(self, markup, user_specified_encoding=None, document_declared_encoding=None): return markup, None, None, False def test_fragment_to_document(self, fragment): """Wrap an HTML fragment to make it look like a document. Different parsers do this differently. For instance, lxml introduces an empty <head> tag, and html5lib doesn't. Abstracting this away lets us write simple tests which run HTML fragments through the parser and compare the results against other HTML fragments. This method should not be used outside of tests. """ return fragment def set_up_substitutions(self, tag): return False def _replace_cdata_list_attribute_values(self, tag_name, attrs): """Replaces class="foo bar" with class=["foo", "bar"] Modifies its input in place. """ if not attrs: return attrs if self.cdata_list_attributes: universal = self.cdata_list_attributes.get('*', []) tag_specific = self.cdata_list_attributes.get( tag_name.lower(), None) for attr in list(attrs.keys()): if attr in universal or (tag_specific and attr in tag_specific): # We have a "class"-type attribute whose string # value is a whitespace-separated list of # values. Split it into a list. value = attrs[attr] if isinstance(value, str): values = whitespace_re.split(value) else: # html5lib sometimes calls setAttributes twice # for the same tag when rearranging the parse # tree. On the second call the attribute value # here is already a list. If this happens, # leave the value alone rather than trying to # split it again. values = value attrs[attr] = values return attrs class SAXTreeBuilder(TreeBuilder): """A Beautiful Soup treebuilder that listens for SAX events.""" def feed(self, markup): raise NotImplementedError() def close(self): pass def startElement(self, name, attrs): attrs = dict((key[1], value) for key, value in list(attrs.items())) #print "Start %s, %r" % (name, attrs) self.soup.handle_starttag(name, attrs) def endElement(self, name): #print "End %s" % name self.soup.handle_endtag(name) def startElementNS(self, nsTuple, nodeName, attrs): # Throw away (ns, nodeName) for now. self.startElement(nodeName, attrs) def endElementNS(self, nsTuple, nodeName): # Throw away (ns, nodeName) for now. self.endElement(nodeName) #handler.endElementNS((ns, node.nodeName), node.nodeName) def startPrefixMapping(self, prefix, nodeValue): # Ignore the prefix for now. pass def endPrefixMapping(self, prefix): # Ignore the prefix for now. # handler.endPrefixMapping(prefix) pass def characters(self, content): self.soup.handle_data(content) def startDocument(self): pass def endDocument(self): pass class HTMLTreeBuilder(TreeBuilder): """This TreeBuilder knows facts about HTML. Such as which tags are empty-element tags. """ preserve_whitespace_tags = HTMLAwareEntitySubstitution.preserve_whitespace_tags empty_element_tags = set([ # These are from HTML5. 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr', # These are from earlier versions of HTML and are removed in HTML5. 'basefont', 'bgsound', 'command', 'frame', 'image', 'isindex', 'nextid', 'spacer' ]) # The HTML standard defines these as block-level elements. Beautiful # Soup does not treat these elements differently from other elements, # but it may do so eventually, and this information is available if # you need to use it. block_elements = set(["address", "article", "aside", "blockquote", "canvas", "dd", "div", "dl", "dt", "fieldset", "figcaption", "figure", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hr", "li", "main", "nav", "noscript", "ol", "output", "p", "pre", "section", "table", "tfoot", "ul", "video"]) # The HTML standard defines these attributes as containing a # space-separated list of values, not a single value. That is, # class="foo bar" means that the 'class' attribute has two values, # 'foo' and 'bar', not the single value 'foo bar'. When we # encounter one of these attributes, we will parse its value into # a list of values if possible. Upon output, the list will be # converted back into a string. cdata_list_attributes = { "*" : ['class', 'accesskey', 'dropzone'], "a" : ['rel', 'rev'], "link" : ['rel', 'rev'], "td" : ["headers"], "th" : ["headers"], "td" : ["headers"], "form" : ["accept-charset"], "object" : ["archive"], # These are HTML5 specific, as are *.accesskey and *.dropzone above. "area" : ["rel"], "icon" : ["sizes"], "iframe" : ["sandbox"], "output" : ["for"], } def set_up_substitutions(self, tag): # We are only interested in <meta> tags if tag.name != 'meta': return False http_equiv = tag.get('http-equiv') content = tag.get('content') charset = tag.get('charset') # We are interested in <meta> tags that say what encoding the # document was originally in. This means HTML 5-style <meta> # tags that provide the "charset" attribute. It also means # HTML 4-style <meta> tags that provide the "content" # attribute and have "http-equiv" set to "content-type". # # In both cases we will replace the value of the appropriate # attribute with a standin object that can take on any # encoding. meta_encoding = None if charset is not None: # HTML 5 style: # <meta charset="utf8"> meta_encoding = charset tag['charset'] = CharsetMetaAttributeValue(charset) elif (content is not None and http_equiv is not None and http_equiv.lower() == 'content-type'): # HTML 4 style: # <meta http-equiv="content-type" content="text/html; charset=utf8"> tag['content'] = ContentMetaAttributeValue(content) return (meta_encoding is not None) def register_treebuilders_from(module): """Copy TreeBuilders from the given module into this module.""" # I'm fairly sure this is not the best way to do this. this_module = sys.modules['bs4.builder'] for name in module.__all__: obj = getattr(module, name) if issubclass(obj, TreeBuilder): setattr(this_module, name, obj) this_module.__all__.append(name) # Register the builder while we're at it. this_module.builder_registry.register(obj) class ParserRejectedMarkup(Exception): pass # Builders are registered in reverse order of priority, so that custom # builder registrations will take precedence. In general, we want lxml # to take precedence over html5lib, because it's faster. And we only # want to use HTMLParser as a last result. from . import _htmlparser register_treebuilders_from(_htmlparser) try: from . import _html5lib register_treebuilders_from(_html5lib) except ImportError: # They don't have html5lib installed. pass try: from . import _lxml register_treebuilders_from(_lxml) except ImportError: # They don't have lxml installed. pass ����������������������������������������������������������usr/lib/python3.6/site-packages/pip/_vendor/chardet/__init__.py�������������������������������������0000644�����������������00000003027�15253372466�0020401 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������######################## 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() ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/json/__init__.py�������������������������������������������������0000644�����������������00000033304�15253374350�0015534 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������r"""JSON (JavaScript Object Notation) <https://json.org> 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 <bob@redivi.com>' 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.12/email/mime/__init__.py���������������������������������������������������������0000644�����������������00000000000�15253374513�0014247 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.6/site-packages/setools/__init__.py�����������������������������������������������0000644�����������������00000005450�15253375714�0016406 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""The SETools SELinux policy analysis library.""" # Copyright 2014-2015, Tresys Technology, LLC # Copyright 2016, Chris PeBenito <pebenito@ieee.org> # # This file is part of SETools. # # SETools 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. # # SETools 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 SETools. If not, see # <http://www.gnu.org/licenses/>. # try: import pkg_resources # pylint: disable=no-member __version__ = pkg_resources.get_distribution("setools").version except ImportError: # pragma: no cover __version__ = "unknown" import logging # Python classes for policy representation from .policyrep import SELinuxPolicy, BoundsRuletype, ConstraintRuletype, DefaultRuletype, \ DefaultRangeValue, DefaultValue, FSUseRuletype, HandleUnknown, IbpkeyconRange, MLSRuletype, \ NodeconIPVersion, PolicyTarget, PortconProtocol, RBACRuletype, TERuletype # Exceptions from . import exception # Component Queries from .boolquery import BoolQuery from .categoryquery import CategoryQuery from .commonquery import CommonQuery from .objclassquery import ObjClassQuery from .polcapquery import PolCapQuery from .rolequery import RoleQuery from .sensitivityquery import SensitivityQuery from .typequery import TypeQuery from .typeattrquery import TypeAttributeQuery from .userquery import UserQuery # Rule Queries from .mlsrulequery import MLSRuleQuery from .rbacrulequery import RBACRuleQuery from .terulequery import TERuleQuery # Constraint queries from .constraintquery import ConstraintQuery # Other queries from .boundsquery import BoundsQuery from .defaultquery import DefaultQuery # In-policy Context Queries from .fsusequery import FSUseQuery from .genfsconquery import GenfsconQuery from .ibendportconquery import IbendportconQuery from .ibpkeyconquery import IbpkeyconQuery from .initsidquery import InitialSIDQuery from .netifconquery import NetifconQuery from .nodeconquery import NodeconQuery from .portconquery import PortconQuery from .ioportconquery import IoportconQuery from .iomemconquery import IomemconQuery from .pirqconquery import PirqconQuery from .pcideviceconquery import PcideviceconQuery from .devicetreeconquery import DevicetreeconQuery # Information Flow Analysis from .permmap import PermissionMap # Policy difference from .diff import PolicyDifference logging.getLogger(__name__).addHandler(logging.NullHandler()) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/sqlite3/__init__.py������������������������������������������������������������0000644�����������������00000004705�15253376220�0013632 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# pysqlite2/__init__.py: the pysqlite2 package. # # Copyright (C) 2005 Gerhard Häring <gh@ghaering.de> # # 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 <gh@ghaering.de>. """ 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/lib/python3.6/site-packages/setuptools/_vendor/__init__.py��������������������������������������0000644�����������������00000000000�15253400021�0020357 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/pip/_vendor/__init__.py���������������������������������������������0000644�����������������00000011076�15253400314�0016752 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������""" 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__(vendored_name, globals(), locals(), level=0) except ImportError: try: __import__(modulename, globals(), locals(), level=0) except ImportError: # We can just silently allow import failures to pass here. If we # got to this point it means that ``import pip._vendor.whatever`` # failed and so did ``import whatever``. Since we're importing this # upfront in an attempt to alias imports, not erroring here will # just mean we get a regular import error whenever pip *actually* # tries to import one of these modules to use it, which actually # gives us a better error message than we would have otherwise # gotten. pass 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("cachecontrol") vendored("colorama") vendored("distlib") vendored("distro") vendored("html5lib") vendored("lockfile") vendored("six") vendored("six.moves") vendored("six.moves.urllib") vendored("packaging") vendored("packaging.version") vendored("packaging.specifiers") vendored("pkg_resources") vendored("progress") vendored("retrying") vendored("requests") 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") ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python2.7/site-packages/pip/_vendor/chardet/__init__.py�������������������������������������0000644�����������������00000003027�15253407214�0020367 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������######################## 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/lib/python3.6/site-packages/firewall/core/__init__.py�������������������������������������������0000644�����������������00000000000�15253414022�0017245 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/lib2to3/pgen2/__init__.py������������������������������������������������������0000644�����������������00000000217�15253414105�0014524 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """The pgen2 package.""" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/pydoc_data/__init__.py���������������������������������������������������������0000644�����������������00000000000�15253415335�0014336 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python2.7/site-packages/pip/_vendor/__init__.py���������������������������������������������0000644�����������������00000011076�15253422272�0016761 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������""" 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__(vendored_name, globals(), locals(), level=0) except ImportError: try: __import__(modulename, globals(), locals(), level=0) except ImportError: # We can just silently allow import failures to pass here. If we # got to this point it means that ``import pip._vendor.whatever`` # failed and so did ``import whatever``. Since we're importing this # upfront in an attempt to alias imports, not erroring here will # just mean we get a regular import error whenever pip *actually* # tries to import one of these modules to use it, which actually # gives us a better error message than we would have otherwise # gotten. pass 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("cachecontrol") vendored("colorama") vendored("distlib") vendored("distro") vendored("html5lib") vendored("lockfile") vendored("six") vendored("six.moves") vendored("six.moves.urllib") vendored("packaging") vendored("packaging.version") vendored("packaging.specifiers") vendored("pkg_resources") vendored("progress") vendored("retrying") vendored("requests") 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") ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/dateutil/tz/__init__.py���������������������������������������������0000644�����������������00000000317�15253423206�0016777 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .tz import * __all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz", "enfold", "datetime_ambiguous", "datetime_exists"] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/tuned/units/__init__.py���������������������������������������������0000644�����������������00000000027�15253423670�0017013 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .manager import * ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/pip/utils/__init__.py�����������������������������������������������0000644�����������������00000066155�15253426102�0016471 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import absolute_import from collections import deque import contextlib import errno import io import locale # we have a submodule named 'logging' which would shadow this if we used the # regular name: import logging as std_logging import re import os import posixpath import shutil import stat import subprocess import sys import tarfile import zipfile from pip.exceptions import InstallationError from pip.compat import console_to_str, expanduser, stdlib_pkgs from pip.locations import ( site_packages, user_site, running_under_virtualenv, virtualenv_no_global, write_delete_marker_file, distutils_scheme, ) from pip._vendor import pkg_resources from pip._vendor.six.moves import input from pip._vendor.six import PY2 from pip._vendor.retrying import retry if PY2: from io import BytesIO as StringIO else: from io import StringIO __all__ = ['rmtree', 'display_path', 'backup_dir', 'ask', 'splitext', 'format_size', 'is_installable_dir', 'is_svn_page', 'file_contents', 'split_leading_dir', 'has_leading_dir', 'normalize_path', 'renames', 'get_terminal_size', 'get_prog', 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', 'captured_stdout', 'ensure_dir', 'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS', 'get_installed_version'] logger = std_logging.getLogger(__name__) BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') ZIP_EXTENSIONS = ('.zip', '.whl') TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') ARCHIVE_EXTENSIONS = ( ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS) SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS try: import bz2 # noqa SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS except ImportError: logger.debug('bz2 module is not available') try: # Only for Python 3.3+ import lzma # noqa SUPPORTED_EXTENSIONS += XZ_EXTENSIONS except ImportError: logger.debug('lzma module is not available') def import_or_raise(pkg_or_module_string, ExceptionType, *args, **kwargs): try: return __import__(pkg_or_module_string) except ImportError: raise ExceptionType(*args, **kwargs) def ensure_dir(path): """os.path.makedirs without EEXIST.""" try: os.makedirs(path) except OSError as e: if e.errno != errno.EEXIST: raise def get_prog(): try: if os.path.basename(sys.argv[0]) in ('__main__.py', '-c'): return "%s -m pip" % sys.executable except (AttributeError, TypeError, IndexError): pass return 'pip' # Retry every half second for up to 3 seconds @retry(stop_max_delay=3000, wait_fixed=500) def rmtree(dir, ignore_errors=False): shutil.rmtree(dir, ignore_errors=ignore_errors, onerror=rmtree_errorhandler) def rmtree_errorhandler(func, path, exc_info): """On Windows, the files in .svn are read-only, so when rmtree() tries to remove them, an exception is thrown. We catch that here, remove the read-only attribute, and hopefully continue without problems.""" # if file type currently read only if os.stat(path).st_mode & stat.S_IREAD: # convert to read/write os.chmod(path, stat.S_IWRITE) # use the original function to repeat the operation func(path) return else: raise def display_path(path): """Gives the display value for a given path, making it relative to cwd if possible.""" path = os.path.normcase(os.path.abspath(path)) if sys.version_info[0] == 2: path = path.decode(sys.getfilesystemencoding(), 'replace') path = path.encode(sys.getdefaultencoding(), 'replace') if path.startswith(os.getcwd() + os.path.sep): path = '.' + path[len(os.getcwd()):] return path def backup_dir(dir, ext='.bak'): """Figure out the name of a directory to back up the given dir to (adding .bak, .bak2, etc)""" n = 1 extension = ext while os.path.exists(dir + extension): n += 1 extension = ext + str(n) return dir + extension def ask_path_exists(message, options): for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): if action in options: return action return ask(message, options) def ask(message, options): """Ask the message interactively, with the given possible responses""" while 1: if os.environ.get('PIP_NO_INPUT'): raise Exception( 'No input was expected ($PIP_NO_INPUT set); question: %s' % message ) response = input(message) response = response.strip().lower() if response not in options: print( 'Your response (%r) was not one of the expected responses: ' '%s' % (response, ', '.join(options)) ) else: return response def format_size(bytes): if bytes > 1000 * 1000: return '%.1fMB' % (bytes / 1000.0 / 1000) elif bytes > 10 * 1000: return '%ikB' % (bytes / 1000) elif bytes > 1000: return '%.1fkB' % (bytes / 1000.0) else: return '%ibytes' % bytes def is_installable_dir(path): """Return True if `path` is a directory containing a setup.py file.""" if not os.path.isdir(path): return False setup_py = os.path.join(path, 'setup.py') if os.path.isfile(setup_py): return True return False def is_svn_page(html): """ Returns true if the page appears to be the index page of an svn repository """ return (re.search(r'<title>[^<]*Revision \d+:', html) and re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) def file_contents(filename): with open(filename, 'rb') as fp: return fp.read().decode('utf-8') def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): """Yield pieces of data from a file-like object until EOF.""" while True: chunk = file.read(size) if not chunk: break yield chunk def split_leading_dir(path): path = path.lstrip('/').lstrip('\\') if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) or '\\' not in path): return path.split('/', 1) elif '\\' in path: return path.split('\\', 1) else: return path, '' def has_leading_dir(paths): """Returns true if all the paths have the same leading path name (i.e., everything is in one subdirectory in an archive)""" common_prefix = None for path in paths: prefix, rest = split_leading_dir(path) if not prefix: return False elif common_prefix is None: common_prefix = prefix elif prefix != common_prefix: return False return True def normalize_path(path, resolve_symlinks=True): """ Convert a path to its canonical, case-normalized, absolute version. """ path = expanduser(path) if resolve_symlinks: path = os.path.realpath(path) else: path = os.path.abspath(path) return os.path.normcase(path) def splitext(path): """Like os.path.splitext, but take off .tar too""" base, ext = posixpath.splitext(path) if base.lower().endswith('.tar'): ext = base[-4:] + ext base = base[:-4] return base, ext def renames(old, new): """Like os.renames(), but handles renaming across devices.""" # Implementation borrowed from os.renames(). head, tail = os.path.split(new) if head and tail and not os.path.exists(head): os.makedirs(head) shutil.move(old, new) head, tail = os.path.split(old) if head and tail: try: os.removedirs(head) except OSError: pass def is_local(path): """ Return True if path is within sys.prefix, if we're running in a virtualenv. If we're not in a virtualenv, all paths are considered "local." """ if not running_under_virtualenv(): return True return normalize_path(path).startswith(normalize_path(sys.prefix)) def dist_is_local(dist): """ Return True if given Distribution object is installed locally (i.e. within current virtualenv). Always True if we're not in a virtualenv. """ return is_local(dist_location(dist)) def dist_in_usersite(dist): """ Return True if given Distribution is installed in user site. """ norm_path = normalize_path(dist_location(dist)) return norm_path.startswith(normalize_path(user_site)) def dist_in_site_packages(dist): """ Return True if given Distribution is installed in distutils.sysconfig.get_python_lib(). """ return normalize_path( dist_location(dist) ).startswith(normalize_path(site_packages)) def dist_in_install_path(dist): """ Return True if given Distribution is installed in path matching distutils_scheme layout. """ norm_path = normalize_path(dist_location(dist)) return norm_path.startswith(normalize_path( distutils_scheme("")['purelib'].split('python')[0])) def dist_is_editable(dist): """Is distribution an editable install?""" for path_item in sys.path: egg_link = os.path.join(path_item, dist.project_name + '.egg-link') if os.path.isfile(egg_link): return True return False def get_installed_distributions(local_only=True, skip=stdlib_pkgs, include_editables=True, editables_only=False, user_only=False): """ Return a list of installed Distribution objects. If ``local_only`` is True (default), only return installations local to the current virtualenv, if in a virtualenv. ``skip`` argument is an iterable of lower-case project names to ignore; defaults to stdlib_pkgs If ``editables`` is False, don't report editables. If ``editables_only`` is True , only report editables. If ``user_only`` is True , only report installations in the user site directory. """ if local_only: local_test = dist_is_local else: def local_test(d): return True if include_editables: def editable_test(d): return True else: def editable_test(d): return not dist_is_editable(d) if editables_only: def editables_only_test(d): return dist_is_editable(d) else: def editables_only_test(d): return True if user_only: user_test = dist_in_usersite else: def user_test(d): return True return [d for d in pkg_resources.working_set if local_test(d) and d.key not in skip and editable_test(d) and editables_only_test(d) and user_test(d) ] def egg_link_path(dist): """ Return the path for the .egg-link file if it exists, otherwise, None. There's 3 scenarios: 1) not in a virtualenv try to find in site.USER_SITE, then site_packages 2) in a no-global virtualenv try to find in site_packages 3) in a yes-global virtualenv try to find in site_packages, then site.USER_SITE (don't look in global location) For #1 and #3, there could be odd cases, where there's an egg-link in 2 locations. This method will just return the first one found. """ sites = [] if running_under_virtualenv(): if virtualenv_no_global(): sites.append(site_packages) else: sites.append(site_packages) if user_site: sites.append(user_site) else: if user_site: sites.append(user_site) sites.append(site_packages) for site in sites: egglink = os.path.join(site, dist.project_name) + '.egg-link' if os.path.isfile(egglink): return egglink def dist_location(dist): """ Get the site-packages location of this distribution. Generally this is dist.location, except in the case of develop-installed packages, where dist.location is the source code location, and we want to know where the egg-link file is. """ egg_link = egg_link_path(dist) if egg_link: return egg_link return dist.location def get_terminal_size(): """Returns a tuple (x, y) representing the width(x) and the height(x) in characters of the terminal window.""" def ioctl_GWINSZ(fd): try: import fcntl import termios import struct cr = struct.unpack( 'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234') ) except: return None if cr == (0, 0): return None return cr cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) if not cr: try: fd = os.open(os.ctermid(), os.O_RDONLY) cr = ioctl_GWINSZ(fd) os.close(fd) except: pass if not cr: cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) return int(cr[1]), int(cr[0]) def current_umask(): """Get the current umask which involves having to set it temporarily.""" mask = os.umask(0) os.umask(mask) return mask def unzip_file(filename, location, flatten=True): """ Unzip the file (with path `filename`) to the destination `location`. All files are written based on system defaults and umask (i.e. permissions are not preserved), except that regular file members with any execute permissions (user, group, or world) have "chmod +x" applied after being written. Note that for windows, any execute changes using os.chmod are no-ops per the python docs. """ ensure_dir(location) zipfp = open(filename, 'rb') try: zip = zipfile.ZipFile(zipfp, allowZip64=True) leading = has_leading_dir(zip.namelist()) and flatten for info in zip.infolist(): name = info.filename data = zip.read(name) fn = name if leading: fn = split_leading_dir(name)[1] fn = os.path.join(location, fn) dir = os.path.dirname(fn) if fn.endswith('/') or fn.endswith('\\'): # A directory ensure_dir(fn) else: ensure_dir(dir) fp = open(fn, 'wb') try: fp.write(data) finally: fp.close() mode = info.external_attr >> 16 # if mode and regular file and any execute permissions for # user/group/world? if mode and stat.S_ISREG(mode) and mode & 0o111: # make dest file have execute for user/group/world # (chmod +x) no-op on windows per python docs os.chmod(fn, (0o777 - current_umask() | 0o111)) finally: zipfp.close() def untar_file(filename, location): """ Untar the file (with path `filename`) to the destination `location`. All files are written based on system defaults and umask (i.e. permissions are not preserved), except that regular file members with any execute permissions (user, group, or world) have "chmod +x" applied after being written. Note that for windows, any execute changes using os.chmod are no-ops per the python docs. """ ensure_dir(location) if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): mode = 'r:gz' elif filename.lower().endswith(BZ2_EXTENSIONS): mode = 'r:bz2' elif filename.lower().endswith(XZ_EXTENSIONS): mode = 'r:xz' elif filename.lower().endswith('.tar'): mode = 'r' else: logger.warning( 'Cannot determine compression type for file %s', filename, ) mode = 'r:*' tar = tarfile.open(filename, mode) try: # note: python<=2.5 doesn't seem to know about pax headers, filter them leading = has_leading_dir([ member.name for member in tar.getmembers() if member.name != 'pax_global_header' ]) for member in tar.getmembers(): fn = member.name if fn == 'pax_global_header': continue if leading: fn = split_leading_dir(fn)[1] path = os.path.join(location, fn) # Call the `data` filter for its side effect (raising exception) try: tarfile.data_filter(member.replace(name=fn), location) except tarfile.LinkOutsideDestinationError: pass if member.isdir(): ensure_dir(path) elif member.issym(): try: tar._extract_member(member, path) except Exception as exc: # Some corrupt tar files seem to produce this # (specifically bad symlinks) logger.warning( 'In the tar file %s the member %s is invalid: %s', filename, member.name, exc, ) continue else: try: fp = tar.extractfile(member) except (KeyError, AttributeError) as exc: # Some corrupt tar files seem to produce this # (specifically bad symlinks) logger.warning( 'In the tar file %s the member %s is invalid: %s', filename, member.name, exc, ) continue ensure_dir(os.path.dirname(path)) with open(path, 'wb') as destfp: shutil.copyfileobj(fp, destfp) fp.close() # Update the timestamp (useful for cython compiled files) tar.utime(member, path) # member have any execute permissions for user/group/world? if member.mode & 0o111: # make dest file have execute for user/group/world # no-op on windows per python docs os.chmod(path, (0o777 - current_umask() | 0o111)) finally: tar.close() def unpack_file(filename, location, content_type, link): filename = os.path.realpath(filename) if (content_type == 'application/zip' or filename.lower().endswith(ZIP_EXTENSIONS) or zipfile.is_zipfile(filename)): unzip_file( filename, location, flatten=not filename.endswith('.whl') ) elif (content_type == 'application/x-gzip' or tarfile.is_tarfile(filename) or filename.lower().endswith( TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS)): untar_file(filename, location) elif (content_type and content_type.startswith('text/html') and is_svn_page(file_contents(filename))): # We don't really care about this from pip.vcs.subversion import Subversion Subversion('svn+' + link.url).unpack(location) else: # FIXME: handle? # FIXME: magic signatures? logger.critical( 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' 'cannot detect archive format', filename, location, content_type, ) raise InstallationError( 'Cannot determine archive format of %s' % location ) def call_subprocess(cmd, show_stdout=True, cwd=None, on_returncode='raise', command_desc=None, extra_environ=None, spinner=None): # This function's handling of subprocess output is confusing and I # previously broke it terribly, so as penance I will write a long comment # explaining things. # # The obvious thing that affects output is the show_stdout= # kwarg. show_stdout=True means, let the subprocess write directly to our # stdout. Even though it is nominally the default, it is almost never used # inside pip (and should not be used in new code without a very good # reason); as of 2016-02-22 it is only used in a few places inside the VCS # wrapper code. Ideally we should get rid of it entirely, because it # creates a lot of complexity here for a rarely used feature. # # Most places in pip set show_stdout=False. What this means is: # - We connect the child stdout to a pipe, which we read. # - By default, we hide the output but show a spinner -- unless the # subprocess exits with an error, in which case we show the output. # - If the --verbose option was passed (= loglevel is DEBUG), then we show # the output unconditionally. (But in this case we don't want to show # the output a second time if it turns out that there was an error.) # # stderr is always merged with stdout (even if show_stdout=True). if show_stdout: stdout = None else: stdout = subprocess.PIPE if command_desc is None: cmd_parts = [] for part in cmd: if ' ' in part or '\n' in part or '"' in part or "'" in part: part = '"%s"' % part.replace('"', '\\"') cmd_parts.append(part) command_desc = ' '.join(cmd_parts) logger.debug("Running command %s", command_desc) env = os.environ.copy() if extra_environ: env.update(extra_environ) try: proc = subprocess.Popen( cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, cwd=cwd, env=env) except Exception as exc: logger.critical( "Error %s while executing command %s", exc, command_desc, ) raise if stdout is not None: all_output = [] while True: line = console_to_str(proc.stdout.readline()) if not line: break line = line.rstrip() all_output.append(line + '\n') if logger.getEffectiveLevel() <= std_logging.DEBUG: # Show the line immediately logger.debug(line) else: # Update the spinner if spinner is not None: spinner.spin() proc.wait() if spinner is not None: if proc.returncode: spinner.finish("error") else: spinner.finish("done") if proc.returncode: if on_returncode == 'raise': if (logger.getEffectiveLevel() > std_logging.DEBUG and not show_stdout): logger.info( 'Complete output from command %s:', command_desc, ) logger.info( ''.join(all_output) + '\n----------------------------------------' ) raise InstallationError( 'Command "%s" failed with error code %s in %s' % (command_desc, proc.returncode, cwd)) elif on_returncode == 'warn': logger.warning( 'Command "%s" had error code %s in %s', command_desc, proc.returncode, cwd, ) elif on_returncode == 'ignore': pass else: raise ValueError('Invalid value: on_returncode=%s' % repr(on_returncode)) if not show_stdout: return ''.join(all_output) def read_text_file(filename): """Return the contents of *filename*. Try to decode the file contents with utf-8, the preferred system encoding (e.g., cp1252 on some Windows machines), and latin1, in that order. Decoding a byte string with latin1 will never raise an error. In the worst case, the returned string will contain some garbage characters. """ with open(filename, 'rb') as fp: data = fp.read() encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1'] for enc in encodings: try: data = data.decode(enc) except UnicodeDecodeError: continue break assert type(data) != bytes # Latin1 should have worked. return data def _make_build_dir(build_dir): os.makedirs(build_dir) write_delete_marker_file(build_dir) class FakeFile(object): """Wrap a list of lines in an object with readline() to make ConfigParser happy.""" def __init__(self, lines): self._gen = (l for l in lines) def readline(self): try: try: return next(self._gen) except NameError: return self._gen.next() except StopIteration: return '' def __iter__(self): return self._gen class StreamWrapper(StringIO): @classmethod def from_stream(cls, orig_stream): cls.orig_stream = orig_stream return cls() # compileall.compile_dir() needs stdout.encoding to print to stdout @property def encoding(self): return self.orig_stream.encoding @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. Taken from Lib/support/__init__.py in the CPython repo. """ orig_stdout = getattr(sys, stream_name) setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) 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') Taken from Lib/support/__init__.py in the CPython repo. """ return captured_output('stdout') class cached_property(object): """A property that is only computed once per instance and then replaces itself with an ordinary attribute. Deleting the attribute resets the property. Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175 """ def __init__(self, func): self.__doc__ = getattr(func, '__doc__') self.func = func def __get__(self, obj, cls): if obj is None: # We're being accessed from the class itself, not from an object return self value = obj.__dict__[self.func.__name__] = self.func(obj) return value def get_installed_version(dist_name, lookup_dirs=None): """Get the installed version of dist_name avoiding pkg_resources cache""" # Create a requirement that we'll look for inside of setuptools. req = pkg_resources.Requirement.parse(dist_name) # We want to avoid having this cached, so we need to construct a new # working set each time. if lookup_dirs is None: working_set = pkg_resources.WorkingSet() else: working_set = pkg_resources.WorkingSet(lookup_dirs) # Get the installed distribution from our working set dist = working_set.find(req) # Check to see if we got an installed distribution or not, if we did # we want to return it's version. return dist.version if dist else None def consume(iterator): """Consume an iterable at C speed.""" deque(iterator, maxlen=0) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python2.7/distutils/command/__init__.py���������������������������������������������������0000644�����������������00000001466�15253443604�0015635 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""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/lib/python3.6/site-packages/tuned/utils/__init__.py���������������������������������������������0000644�����������������00000000000�15253446252�0017001 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python2.7/site-packages/pip/_vendor/colorama/__init__.py������������������������������������0000644�����������������00000000360�15253460176�0020555 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. from .initialise import init, deinit, reinit, colorama_text from .ansi import Fore, Back, Style, Cursor from .ansitowin32 import AnsiToWin32 __version__ = '0.3.7' ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python2.7/site-packages/setuptools/extern/__init__.py���������������������������������������0000644�����������������00000004703�15253464603�0020266 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import sys class VendorImporter: """ A PEP 302 meta path importer for finding optionally-vendored or otherwise naturally-installed packages from root_name. """ def __init__(self, root_name, vendored_names=(), vendor_pkg=None): self.root_name = root_name self.vendored_names = set(vendored_names) self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') @property def search_path(self): """ Search first the vendor package then as a natural package. """ yield self.vendor_pkg + '.' yield '' def find_module(self, fullname, path=None): """ Return self when fullname starts with root_name and the target module is one vendored through this importer. """ root, base, target = fullname.partition(self.root_name + '.') if root: return if not any(map(target.startswith, self.vendored_names)): return return self def load_module(self, fullname): """ Iterate over the search path to locate and load fullname. """ root, base, target = fullname.partition(self.root_name + '.') for prefix in self.search_path: try: extant = prefix + target __import__(extant) mod = sys.modules[extant] sys.modules[fullname] = mod # mysterious hack: # Remove the reference to the extant package/module # on later Python versions to cause relative imports # in the vendor package to resolve the same modules # as those going through this importer. if sys.version_info > (3, 3): del sys.modules[extant] return mod except ImportError: pass else: raise ImportError( "The '{target}' package is required; " "normally this is bundled with this package so if you get " "this warning, consult the packager of your " "distribution.".format(**locals()) ) def install(self): """ Install this importer into sys.meta_path if not already present. """ if self not in sys.meta_path: sys.meta_path.append(self) names = 'six', 'packaging', 'pyparsing', VendorImporter(__name__, names, 'setuptools._vendor').install() �������������������������������������������������������������usr/lib/python3.6/site-packages/pip/_vendor/distlib/__init__.py�������������������������������������0000644�����������������00000001105�15253465532�0020411 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # # Copyright (C) 2012-2016 Vinay Sajip. # Licensed to the Python Software Foundation under a contributor agreement. # See LICENSE.txt and CONTRIBUTORS.txt. # import logging __version__ = '0.2.4' class DistlibException(Exception): pass try: from logging import NullHandler except ImportError: # pragma: no cover class NullHandler(logging.Handler): def handle(self, record): pass def emit(self, record): pass def createLock(self): self.lock = None logger = logging.getLogger(__name__) logger.addHandler(NullHandler()) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/concurrent/__init__.py���������������������������������������������������������0000644�����������������00000000046�15253475441�0014427 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This directory is a Python package. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/html5lib/_trie/__init__.py������������������������������������������0000644�����������������00000000441�15253503471�0017352 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import absolute_import, division, unicode_literals from .py import Trie as PyTrie Trie = PyTrie # pylint:disable=wrong-import-position try: from .datrie import Trie as DATrie except ImportError: pass else: Trie = DATrie # pylint:enable=wrong-import-position �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/dns/rdtypes/ANY/__init__.py�����������������������������������������0000644�����������������00000002305�15253514515�0017437 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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. """Class ANY (generic) rdata type classes.""" __all__ = [ 'AFSDB', 'CDNSKEY', 'CDS', 'CERT', 'CNAME', 'DLV', 'DNAME', 'DNSKEY', 'DS', 'EUI48', 'EUI64', 'GPOS', 'HINFO', 'HIP', 'ISDN', 'LOC', 'MX', 'NS', 'NSEC', 'NSEC3', 'NSEC3PARAM', 'TLSA', 'PTR', 'RP', 'RRSIG', 'RT', 'SOA', 'SPF', 'SSHFP', 'TXT', 'X25', ] ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/dns/rdtypes/__init__.py���������������������������������������������0000644�����������������00000001577�15253515661�0017025 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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/python3.12/importlib/resources/__init__.py������������������������������������������������0000644�����������������00000001024�15253521670�0016251 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Read resources contained within a package.""" from ._common import ( as_file, files, Package, Anchor, ) from ._legacy import ( contents, open_binary, read_binary, open_text, read_text, is_resource, path, Resource, ) from .abc import ResourceReader __all__ = [ 'Package', 'Anchor', 'Resource', 'ResourceReader', 'as_file', 'contents', 'files', 'is_resource', 'open_binary', 'open_text', 'path', 'read_binary', 'read_text', ] ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/dns/rdtypes/IN/__init__.py������������������������������������������0000644�����������������00000001705�15253531010�0017306 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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. """Class IN rdata type classes.""" __all__ = [ 'A', 'AAAA', 'APL', 'DHCID', 'KX', 'NAPTR', 'NSAP', 'NSAP_PTR', 'PX', 'SRV', 'WKS', ] �����������������������������������������������������������usr/lib/python2.7/site-packages/pip/operations/__init__.py������������������������������������������0000644�����������������00000000000�15253531111�0017462 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python2.7/site-packages/pip/_vendor/html5lib/__init__.py������������������������������������0000644�����������������00000001414�15253540444�0020476 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������""" HTML parsing library based on the WHATWG "HTML5" specification. The parser is designed to be compatible with existing HTML found in the wild and implements well-defined error recovery that is largely compatible with modern desktop web browsers. Example usage: import html5lib f = open("my_document.html") tree = html5lib.parse(f) """ from __future__ import absolute_import, division, unicode_literals from .html5parser import HTMLParser, parse, parseFragment from .treebuilders import getTreeBuilder from .treewalkers import getTreeWalker from .serializer import serialize __all__ = ["HTMLParser", "parse", "parseFragment", "getTreeBuilder", "getTreeWalker", "serialize"] # this has to be at the top level, see how setup.py parses this __version__ = "1.0b10" ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python2.7/site-packages/pip/_vendor/webencodings/__init__.py��������������������������������0000644�����������������00000024520�15253556035�0021433 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# coding: utf8 """ webencodings ~~~~~~~~~~~~ This is a Python implementation of the `WHATWG Encoding standard <http://encoding.spec.whatwg.org/>`. See README for details. :copyright: Copyright 2012 by Simon Sapin :license: BSD, see LICENSE for details. """ from __future__ import unicode_literals import codecs from .labels import LABELS VERSION = '0.5' # Some names in Encoding are not valid Python aliases. Remap these. PYTHON_NAMES = { 'iso-8859-8-i': 'iso-8859-8', 'x-mac-cyrillic': 'mac-cyrillic', 'macintosh': 'mac-roman', 'windows-874': 'cp874'} CACHE = {} def ascii_lower(string): r"""Transform (only) ASCII letters to lower case: A-Z is mapped to a-z. :param string: An Unicode string. :returns: A new Unicode string. This is used for `ASCII case-insensitive <http://encoding.spec.whatwg.org/#ascii-case-insensitive>`_ matching of encoding labels. The same matching is also used, among other things, for `CSS keywords <http://dev.w3.org/csswg/css-values/#keywords>`_. This is different from the :meth:`~py:str.lower` method of Unicode strings which also affect non-ASCII characters, sometimes mapping them into the ASCII range: >>> keyword = u'Bac\N{KELVIN SIGN}ground' >>> assert keyword.lower() == u'background' >>> assert ascii_lower(keyword) != keyword.lower() >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground' """ # This turns out to be faster than unicode.translate() return string.encode('utf8').lower().decode('utf8') def lookup(label): """ Look for an encoding by its label. This is the spec’s `get an encoding <http://encoding.spec.whatwg.org/#concept-encoding-get>`_ algorithm. Supported labels are listed there. :param label: A string. :returns: An :class:`Encoding` object, or :obj:`None` for an unknown label. """ # Only strip ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. label = ascii_lower(label.strip('\t\n\f\r ')) name = LABELS.get(label) if name is None: return None encoding = CACHE.get(name) if encoding is None: if name == 'x-user-defined': from .x_user_defined import codec_info else: python_name = PYTHON_NAMES.get(name, name) # Any python_name value that gets to here should be valid. codec_info = codecs.lookup(python_name) encoding = Encoding(name, codec_info) CACHE[name] = encoding return encoding def _get_encoding(encoding_or_label): """ Accept either an encoding object or label. :param encoding: An :class:`Encoding` object or a label string. :returns: An :class:`Encoding` object. :raises: :exc:`~exceptions.LookupError` for an unknown label. """ if hasattr(encoding_or_label, 'codec_info'): return encoding_or_label encoding = lookup(encoding_or_label) if encoding is None: raise LookupError('Unknown encoding label: %r' % encoding_or_label) return encoding class Encoding(object): """Reresents a character encoding such as UTF-8, that can be used for decoding or encoding. .. attribute:: name Canonical name of the encoding .. attribute:: codec_info The actual implementation of the encoding, a stdlib :class:`~codecs.CodecInfo` object. See :func:`codecs.register`. """ def __init__(self, name, codec_info): self.name = name self.codec_info = codec_info def __repr__(self): return '<Encoding %s>' % self.name #: The UTF-8 encoding. Should be used for new content and formats. UTF8 = lookup('utf-8') _UTF16LE = lookup('utf-16le') _UTF16BE = lookup('utf-16be') def decode(input, fallback_encoding, errors='replace'): """ Decode a single string. :param input: A byte string :param fallback_encoding: An :class:`Encoding` object or a label string. The encoding to use if :obj:`input` does note have a BOM. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :return: A ``(output, encoding)`` tuple of an Unicode string and an :obj:`Encoding`. """ # Fail early if `encoding` is an invalid label. fallback_encoding = _get_encoding(fallback_encoding) bom_encoding, input = _detect_bom(input) encoding = bom_encoding or fallback_encoding return encoding.codec_info.decode(input, errors)[0], encoding def _detect_bom(input): """Return (bom_encoding, input), with any BOM removed from the input.""" if input.startswith(b'\xFF\xFE'): return _UTF16LE, input[2:] if input.startswith(b'\xFE\xFF'): return _UTF16BE, input[2:] if input.startswith(b'\xEF\xBB\xBF'): return UTF8, input[3:] return None, input def encode(input, encoding=UTF8, errors='strict'): """ Encode a single string. :param input: An Unicode string. :param encoding: An :class:`Encoding` object or a label string. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :return: A byte string. """ return _get_encoding(encoding).codec_info.encode(input, errors)[0] def iter_decode(input, fallback_encoding, errors='replace'): """ "Pull"-based decoder. :param input: An iterable of byte strings. The input is first consumed just enough to determine the encoding based on the precense of a BOM, then consumed on demand when the return value is. :param fallback_encoding: An :class:`Encoding` object or a label string. The encoding to use if :obj:`input` does note have a BOM. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :returns: An ``(output, encoding)`` tuple. :obj:`output` is an iterable of Unicode strings, :obj:`encoding` is the :obj:`Encoding` that is being used. """ decoder = IncrementalDecoder(fallback_encoding, errors) generator = _iter_decode_generator(input, decoder) encoding = next(generator) return generator, encoding def _iter_decode_generator(input, decoder): """Return a generator that first yields the :obj:`Encoding`, then yields output chukns as Unicode strings. """ decode = decoder.decode input = iter(input) for chunck in input: output = decode(chunck) if output: assert decoder.encoding is not None yield decoder.encoding yield output break else: # Input exhausted without determining the encoding output = decode(b'', final=True) assert decoder.encoding is not None yield decoder.encoding if output: yield output return for chunck in input: output = decode(chunck) if output: yield output output = decode(b'', final=True) if output: yield output def iter_encode(input, encoding=UTF8, errors='strict'): """ “Pull”-based encoder. :param input: An iterable of Unicode strings. :param encoding: An :class:`Encoding` object or a label string. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. :returns: An iterable of byte strings. """ # Fail early if `encoding` is an invalid label. encode = IncrementalEncoder(encoding, errors).encode return _iter_encode_generator(input, encode) def _iter_encode_generator(input, encode): for chunck in input: output = encode(chunck) if output: yield output output = encode('', final=True) if output: yield output class IncrementalDecoder(object): """ “Push”-based decoder. :param fallback_encoding: An :class:`Encoding` object or a label string. The encoding to use if :obj:`input` does note have a BOM. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. """ def __init__(self, fallback_encoding, errors='replace'): # Fail early if `encoding` is an invalid label. self._fallback_encoding = _get_encoding(fallback_encoding) self._errors = errors self._buffer = b'' self._decoder = None #: The actual :class:`Encoding` that is being used, #: or :obj:`None` if that is not determined yet. #: (Ie. if there is not enough input yet to determine #: if there is a BOM.) self.encoding = None # Not known yet. def decode(self, input, final=False): """Decode one chunk of the input. :param input: A byte string. :param final: Indicate that no more input is available. Must be :obj:`True` if this is the last call. :returns: An Unicode string. """ decoder = self._decoder if decoder is not None: return decoder(input, final) input = self._buffer + input encoding, input = _detect_bom(input) if encoding is None: if len(input) < 3 and not final: # Not enough data yet. self._buffer = input return '' else: # No BOM encoding = self._fallback_encoding decoder = encoding.codec_info.incrementaldecoder(self._errors).decode self._decoder = decoder self.encoding = encoding return decoder(input, final) class IncrementalEncoder(object): """ “Push”-based encoder. :param encoding: An :class:`Encoding` object or a label string. :param errors: Type of error handling. See :func:`codecs.register`. :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. .. method:: encode(input, final=False) :param input: An Unicode string. :param final: Indicate that no more input is available. Must be :obj:`True` if this is the last call. :returns: A byte string. """ def __init__(self, encoding=UTF8, errors='strict'): encoding = _get_encoding(encoding) self.encode = encoding.codec_info.incrementalencoder(errors).encode ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/tuned/monitors/__init__.py������������������������������������������0000644�����������������00000000056�15253563047�0017530 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .base import * from .repository import * ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python-internal/lib64/python3.11/tomllib/__init__.py����������������������������������������0000644�����������������00000000464�15253563310�0017607 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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__ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python-internal/lib64/python3.11/xml/etree/__init__.py��������������������������������������0000644�����������������00000003105�15253564207�0020052 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# $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. �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python-internal/lib64/python3.11/xmlrpc/__init__.py�����������������������������������������0000644�����������������00000000046�15253564242�0017453 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This directory is a Python package. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/slip/__init__.py����������������������������������������������������0000644�����������������00000000000�15253571756�0015501 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/urllib/__init__.py�������������������������������������������������������������0000644�����������������00000000000�15253572425�0013524 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python2.7/site-packages/pip/req/__init__.py�������������������������������������������������0000644�����������������00000000424�15253574612�0016115 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import absolute_import from .req_install import InstallRequirement from .req_set import RequirementSet, Requirements from .req_file import parse_requirements __all__ = [ "RequirementSet", "Requirements", "InstallRequirement", "parse_requirements", ] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/pip/req/__init__.py�������������������������������������������������0000644�����������������00000000424�15253575354�0016121 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import absolute_import from .req_install import InstallRequirement from .req_set import RequirementSet, Requirements from .req_file import parse_requirements __all__ = [ "RequirementSet", "Requirements", "InstallRequirement", "parse_requirements", ] ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python2.7/multiprocessing/dummy/__init__.py�����������������������������������������������0000644�����������������00000010601�15253575744�0016557 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # 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 �������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/pip/vcs/__init__.py�������������������������������������������������0000644�����������������00000030126�15253576124�0016123 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""Handles all VCS (version control) support""" from __future__ import absolute_import import errno import logging import os import shutil import sys from pip._vendor.six.moves.urllib import parse as urllib_parse from pip.exceptions import BadCommand from pip.utils import (display_path, backup_dir, call_subprocess, rmtree, ask_path_exists) __all__ = ['vcs', 'get_src_requirement'] logger = logging.getLogger(__name__) class VcsSupport(object): _registry = {} schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] def __init__(self): # Register more schemes with urlparse for various version control # systems urllib_parse.uses_netloc.extend(self.schemes) # Python >= 2.7.4, 3.3 doesn't have uses_fragment if getattr(urllib_parse, 'uses_fragment', None): urllib_parse.uses_fragment.extend(self.schemes) super(VcsSupport, self).__init__() def __iter__(self): return self._registry.__iter__() @property def backends(self): return list(self._registry.values()) @property def dirnames(self): return [backend.dirname for backend in self.backends] @property def all_schemes(self): schemes = [] for backend in self.backends: schemes.extend(backend.schemes) return schemes def register(self, cls): if not hasattr(cls, 'name'): logger.warning('Cannot register VCS %s', cls.__name__) return if cls.name not in self._registry: self._registry[cls.name] = cls logger.debug('Registered VCS backend: %s', cls.name) def unregister(self, cls=None, name=None): if name in self._registry: del self._registry[name] elif cls in self._registry.values(): del self._registry[cls.name] else: logger.warning('Cannot unregister because no class or name given') def get_backend_name(self, location): """ Return the name of the version control backend if found at given location, e.g. vcs.get_backend_name('/path/to/vcs/checkout') """ for vc_type in self._registry.values(): if vc_type.controls_location(location): logger.debug('Determine that %s uses VCS: %s', location, vc_type.name) return vc_type.name return None def get_backend(self, name): name = name.lower() if name in self._registry: return self._registry[name] def get_backend_from_location(self, location): vc_type = self.get_backend_name(location) if vc_type: return self.get_backend(vc_type) return None vcs = VcsSupport() class VersionControl(object): name = '' dirname = '' # List of supported schemes for this Version Control schemes = () def __init__(self, url=None, *args, **kwargs): self.url = url super(VersionControl, self).__init__(*args, **kwargs) def _is_local_repository(self, repo): """ posix absolute paths start with os.path.sep, win32 ones start with drive (like c:\\folder) """ drive, tail = os.path.splitdrive(repo) return repo.startswith(os.path.sep) or drive # See issue #1083 for why this method was introduced: # https://github.com/pypa/pip/issues/1083 def translate_egg_surname(self, surname): # For example, Django has branches of the form "stable/1.7.x". return surname.replace('/', '_') def export(self, location): """ Export the repository at the url to the destination location i.e. only download the files, without vcs informations """ raise NotImplementedError def get_url_rev(self): """ Returns the correct repository URL and revision by parsing the given repository URL """ error_message = ( "Sorry, '%s' is a malformed VCS url. " "The format is <vcs>+<protocol>://<url>, " "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp" ) assert '+' in self.url, error_message % self.url url = self.url.split('+', 1)[1] scheme, netloc, path, query, frag = urllib_parse.urlsplit(url) rev = None if '@' in path: path, rev = path.rsplit('@', 1) url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) return url, rev def get_info(self, location): """ Returns (url, revision), where both are strings """ assert not location.rstrip('/').endswith(self.dirname), \ 'Bad directory: %s' % location return self.get_url(location), self.get_revision(location) def normalize_url(self, url): """ Normalize a URL for comparison by unquoting it and removing any trailing slash. """ return urllib_parse.unquote(url).rstrip('/') def compare_urls(self, url1, url2): """ Compare two repo URLs for identity, ignoring incidental differences. """ return (self.normalize_url(url1) == self.normalize_url(url2)) def obtain(self, dest): """ Called when installing or updating an editable package, takes the source path of the checkout. """ raise NotImplementedError def switch(self, dest, url, rev_options): """ Switch the repo at ``dest`` to point to ``URL``. """ raise NotImplementedError def update(self, dest, rev_options): """ Update an already-existing repo to the given ``rev_options``. """ raise NotImplementedError def check_version(self, dest, rev_options): """ Return True if the version is identical to what exists and doesn't need to be updated. """ raise NotImplementedError def check_destination(self, dest, url, rev_options, rev_display): """ Prepare a location to receive a checkout/clone. Return True if the location is ready for (and requires) a checkout/clone, False otherwise. """ checkout = True prompt = False if os.path.exists(dest): checkout = False if os.path.exists(os.path.join(dest, self.dirname)): existing_url = self.get_url(dest) if self.compare_urls(existing_url, url): logger.debug( '%s in %s exists, and has correct URL (%s)', self.repo_name.title(), display_path(dest), url, ) if not self.check_version(dest, rev_options): logger.info( 'Updating %s %s%s', display_path(dest), self.repo_name, rev_display, ) self.update(dest, rev_options) else: logger.info( 'Skipping because already up-to-date.') else: logger.warning( '%s %s in %s exists with URL %s', self.name, self.repo_name, display_path(dest), existing_url, ) prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', ('s', 'i', 'w', 'b')) else: logger.warning( 'Directory %s already exists, and is not a %s %s.', dest, self.name, self.repo_name, ) prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) if prompt: logger.warning( 'The plan is to install the %s repository %s', self.name, url, ) response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) if response == 's': logger.info( 'Switching %s %s to %s%s', self.repo_name, display_path(dest), url, rev_display, ) self.switch(dest, url, rev_options) elif response == 'i': # do nothing pass elif response == 'w': logger.warning('Deleting %s', display_path(dest)) rmtree(dest) checkout = True elif response == 'b': dest_dir = backup_dir(dest) logger.warning( 'Backing up %s to %s', display_path(dest), dest_dir, ) shutil.move(dest, dest_dir) checkout = True elif response == 'a': sys.exit(-1) return checkout def unpack(self, location): """ Clean up current location and download the url repository (and vcs infos) into location """ if os.path.exists(location): rmtree(location) self.obtain(location) def get_src_requirement(self, dist, location): """ Return a string representing the requirement needed to redownload the files currently present in location, something like: {repository_url}@{revision}#egg={project_name}-{version_identifier} """ raise NotImplementedError def get_url(self, location): """ Return the url used at location Used in get_info or check_destination """ raise NotImplementedError def get_revision(self, location): """ Return the current revision of the files at location Used in get_info """ raise NotImplementedError def run_command(self, cmd, show_stdout=True, cwd=None, on_returncode='raise', command_desc=None, extra_environ=None, spinner=None): """ Run a VCS subcommand This is simply a wrapper around call_subprocess that adds the VCS command name, and checks that the VCS is available """ cmd = [self.name] + cmd try: return call_subprocess(cmd, show_stdout, cwd, on_returncode, command_desc, extra_environ, spinner) except OSError as e: # errno.ENOENT = no such file or directory # In other words, the VCS executable isn't available if e.errno == errno.ENOENT: raise BadCommand('Cannot find command %r' % self.name) else: raise # re-raise exception if a different error occurred @classmethod def controls_location(cls, location): """ Check if a location is controlled by the vcs. It is meant to be overridden to implement smarter detection mechanisms for specific vcs. """ logger.debug('Checking in %s for %s (%s)...', location, cls.dirname, cls.name) path = os.path.join(location, cls.dirname) return os.path.exists(path) def get_src_requirement(dist, location): version_control = vcs.get_backend_from_location(location) if version_control: try: return version_control().get_src_requirement(dist, location) except BadCommand: logger.warning( 'cannot determine version of editable source in %s ' '(%s command not found in path)', location, version_control.name, ) return dist.as_requirement() logger.warning( 'cannot determine version of editable source in %s (is not SVN ' 'checkout, Git clone, Mercurial clone or Bazaar branch)', location, ) return dist.as_requirement() ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/curses/__init__.py�����������������������������������������������0000644�����������������00000006451�15253577670�0016104 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""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.6/email/__init__.py���������������������������������������������������������������0000644�����������������00000003346�15253600114�0013250 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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/pyudev/_os/__init__.py����������������������������������������������0000644�����������������00000001741�15253600211�0016616 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # Copyright (C) 2015 mulhern <amulhern@redhat.com> # 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._os ========== Extras to compensate for deficiencies in python os module. .. moduleauthor:: mulhern <amulhern@redhat.com> """ from . import pipe from . import poll �������������������������������usr/lib64/python3.12/importlib/__init__.py����������������������������������������������������������0000644�����������������00000011260�15253601013�0014230 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""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 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python-internal/lib64/python3.11/email/mime/__init__.py�������������������������������������0000644�����������������00000000000�15253601157�0020147 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/tuned/hardware/__init__.py������������������������������������������0000644�����������������00000000132�15253602023�0017432 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from .inventory import * from .device_matcher import * from .device_matcher_udev import * ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/dnf/yum/__init__.py�������������������������������������������������0000644�����������������00000001750�15253606734�0016123 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# __init__.py # The legacy YUM subpackage. # # Copyright (C) 2013 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. # ������������������������usr/lib64/python2.7/email/mime/__init__.py����������������������������������������������������������0000644�����������������00000000000�15253614641�0014171 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/html/__init__.py���������������������������������������������������������������0000644�����������������00000011247�15253615063�0013212 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������""" 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', # <control> 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', # <control> 0x8e: '\u017d', # LATIN CAPITAL LETTER Z WITH CARON 0x8f: '\x8f', # <control> 0x90: '\x90', # <control> 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', # <control> 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.6/asyncio/__init__.py�������������������������������������������������������������0000644�����������������00000002634�15253615230�0013632 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""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.6/encodings/__init__.py�����������������������������������������������������������0000644�����������������00000013012�15253616667�0014145 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������""" 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/share/gcc-8/python/libstdcxx/v6/__init__.py�����������������������������������������������������0000644�����������������00000002175�15253624000�0015353 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 2014-2025 Free Software Foundation, 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 3 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, see <http://www.gnu.org/licenses/>. # Load the xmethods if GDB supports them. def gdb_has_xmethods(): try: import gdb.xmethod return True except ImportError: return False def register_libstdcxx_printers(obj): # Load the pretty-printers. from .printers import register_libstdcxx_printers register_libstdcxx_printers(obj) if gdb_has_xmethods(): from .xmethods import register_libstdcxx_xmethods register_libstdcxx_xmethods(obj) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/email/__init__.py��������������������������������������������������������������0000644�����������������00000003344�15253633666�0013345 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# 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/share/gcc-8/python/libstdcxx/__init__.py��������������������������������������������������������0000644�����������������00000000001�15253633673�0015022 0����������������������������������������������������������������������������������������������������ustar�00������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/dnf/__init__.py�����������������������������������������������������0000644�����������������00000002555�15253640254�0015310 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# __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/lib/python2.7/site-packages/pip/_vendor/progress/__init__.py������������������������������������0000644�����������������00000005717�15253647025�0020637 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> # # Permission to use, copy, modify, and distribute this software 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 THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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. from __future__ import division from collections import deque from datetime import timedelta from math import ceil from sys import stderr from time import time __version__ = '1.2' class Infinite(object): file = stderr sma_window = 10 def __init__(self, *args, **kwargs): self.index = 0 self.start_ts = time() self._ts = self.start_ts self._dt = deque(maxlen=self.sma_window) for key, val in kwargs.items(): setattr(self, key, val) def __getitem__(self, key): if key.startswith('_'): return None return getattr(self, key, None) @property def avg(self): return sum(self._dt) / len(self._dt) if self._dt else 0 @property def elapsed(self): return int(time() - self.start_ts) @property def elapsed_td(self): return timedelta(seconds=self.elapsed) def update(self): pass def start(self): pass def finish(self): pass def next(self, n=1): if n > 0: now = time() dt = (now - self._ts) / n self._dt.append(dt) self._ts = now self.index = self.index + n self.update() def iter(self, it): for x in it: yield x self.next() self.finish() class Progress(Infinite): def __init__(self, *args, **kwargs): super(Progress, self).__init__(*args, **kwargs) self.max = kwargs.get('max', 100) @property def eta(self): return int(ceil(self.avg * self.remaining)) @property def eta_td(self): return timedelta(seconds=self.eta) @property def percent(self): return self.progress * 100 @property def progress(self): return min(1, self.index / self.max) @property def remaining(self): return max(self.max - self.index, 0) def start(self): self.update() def goto(self, index): incr = index - self.index self.next(incr) def iter(self, it): try: self.max = len(it) except TypeError: pass for x in it: yield x self.next() self.finish() �������������������������������������������������usr/lib64/python3.6/site-packages/lxml/html/__init__.py���������������������������������������������0000644�����������������00000176571�15253647327�0016655 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (c) 2004 Ian Bicking. 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 Ian Bicking 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 THE COPYRIGHT HOLDERS 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 IAN BICKING 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. """The ``lxml.html`` tool set for HTML handling. """ from __future__ import absolute_import __all__ = [ 'document_fromstring', 'fragment_fromstring', 'fragments_fromstring', 'fromstring', 'tostring', 'Element', 'defs', 'open_in_browser', 'submit_form', 'find_rel_links', 'find_class', 'make_links_absolute', 'resolve_base_href', 'iterlinks', 'rewrite_links', 'open_in_browser', 'parse'] import copy import sys import re from functools import partial try: # while unnecessary, importing from 'collections.abc' is the right way to do it from collections.abc import MutableMapping, MutableSet except ImportError: from collections import MutableMapping, MutableSet from .. import etree from . import defs from ._setmixin import SetMixin try: from urlparse import urljoin except ImportError: # Python 3 from urllib.parse import urljoin try: unicode except NameError: # Python 3 unicode = str try: basestring except NameError: # Python 3 basestring = (str, bytes) def __fix_docstring(s): if not s: return s if sys.version_info[0] >= 3: sub = re.compile(r"^(\s*)u'", re.M).sub else: sub = re.compile(r"^(\s*)b'", re.M).sub return sub(r"\1'", s) XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml" _rel_links_xpath = etree.XPath("descendant-or-self::a[@rel]|descendant-or-self::x:a[@rel]", namespaces={'x':XHTML_NAMESPACE}) _options_xpath = etree.XPath("descendant-or-self::option|descendant-or-self::x:option", namespaces={'x':XHTML_NAMESPACE}) _forms_xpath = etree.XPath("descendant-or-self::form|descendant-or-self::x:form", namespaces={'x':XHTML_NAMESPACE}) #_class_xpath = etree.XPath(r"descendant-or-self::*[regexp:match(@class, concat('\b', $class_name, '\b'))]", {'regexp': 'http://exslt.org/regular-expressions'}) _class_xpath = etree.XPath("descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), concat(' ', $class_name, ' '))]") _id_xpath = etree.XPath("descendant-or-self::*[@id=$id]") _collect_string_content = etree.XPath("string()") _iter_css_urls = re.compile(r'url\(('+'["][^"]*["]|'+"['][^']*[']|"+r'[^)]*)\)', re.I).finditer _iter_css_imports = re.compile(r'@import "(.*?)"').finditer _label_xpath = etree.XPath("//label[@for=$id]|//x:label[@for=$id]", namespaces={'x':XHTML_NAMESPACE}) _archive_re = re.compile(r'[^ ]+') _parse_meta_refresh_url = re.compile( r'[^;=]*;\s*(?:url\s*=\s*)?(?P<url>.*)$', re.I).search def _unquote_match(s, pos): if s[:1] == '"' and s[-1:] == '"' or s[:1] == "'" and s[-1:] == "'": return s[1:-1], pos+1 else: return s,pos def _transform_result(typ, result): """Convert the result back into the input type. """ if issubclass(typ, bytes): return tostring(result, encoding='utf-8') elif issubclass(typ, unicode): return tostring(result, encoding='unicode') else: return result def _nons(tag): if isinstance(tag, basestring): if tag[0] == '{' and tag[1:len(XHTML_NAMESPACE)+1] == XHTML_NAMESPACE: return tag.split('}')[-1] return tag class Classes(MutableSet): """Provides access to an element's class attribute as a set-like collection. Usage:: >>> el = fromstring('<p class="hidden large">Text</p>') >>> classes = el.classes # or: classes = Classes(el.attrib) >>> classes |= ['block', 'paragraph'] >>> el.get('class') 'hidden large block paragraph' >>> classes.toggle('hidden') False >>> el.get('class') 'large block paragraph' >>> classes -= ('some', 'classes', 'block') >>> el.get('class') 'large paragraph' """ def __init__(self, attributes): self._attributes = attributes self._get_class_value = partial(attributes.get, 'class', '') def add(self, value): """ Add a class. This has no effect if the class is already present. """ if not value or re.search(r'\s', value): raise ValueError("Invalid class name: %r" % value) classes = self._get_class_value().split() if value in classes: return classes.append(value) self._attributes['class'] = ' '.join(classes) def discard(self, value): """ Remove a class if it is currently present. If the class is not present, do nothing. """ if not value or re.search(r'\s', value): raise ValueError("Invalid class name: %r" % value) classes = [name for name in self._get_class_value().split() if name != value] if classes: self._attributes['class'] = ' '.join(classes) elif 'class' in self._attributes: del self._attributes['class'] def remove(self, value): """ Remove a class; it must currently be present. If the class is not present, raise a KeyError. """ if not value or re.search(r'\s', value): raise ValueError("Invalid class name: %r" % value) super(Classes, self).remove(value) def __contains__(self, name): classes = self._get_class_value() return name in classes and name in classes.split() def __iter__(self): return iter(self._get_class_value().split()) def __len__(self): return len(self._get_class_value().split()) # non-standard methods def update(self, values): """ Add all names from 'values'. """ classes = self._get_class_value().split() extended = False for value in values: if value not in classes: classes.append(value) extended = True if extended: self._attributes['class'] = ' '.join(classes) def toggle(self, value): """ Add a class name if it isn't there yet, or remove it if it exists. Returns true if the class was added (and is now enabled) and false if it was removed (and is now disabled). """ if not value or re.search(r'\s', value): raise ValueError("Invalid class name: %r" % value) classes = self._get_class_value().split() try: classes.remove(value) enabled = False except ValueError: classes.append(value) enabled = True if classes: self._attributes['class'] = ' '.join(classes) else: del self._attributes['class'] return enabled class HtmlMixin(object): def set(self, key, value=None): """set(self, key, value=None) Sets an element attribute. If no value is provided, or if the value is None, creates a 'boolean' attribute without value, e.g. "<form novalidate></form>" for ``form.set('novalidate')``. """ super(HtmlElement, self).set(key, value) @property def classes(self): """ A set-like wrapper around the 'class' attribute. """ return Classes(self.attrib) @classes.setter def classes(self, classes): assert isinstance(classes, Classes) # only allow "el.classes |= ..." etc. value = classes._get_class_value() if value: self.set('class', value) elif self.get('class') is not None: del self.attrib['class'] @property def base_url(self): """ Returns the base URL, given when the page was parsed. Use with ``urlparse.urljoin(el.base_url, href)`` to get absolute URLs. """ return self.getroottree().docinfo.URL @property def forms(self): """ Return a list of all the forms """ return _forms_xpath(self) @property def body(self): """ Return the <body> element. Can be called from a child element to get the document's head. """ return self.xpath('//body|//x:body', namespaces={'x':XHTML_NAMESPACE})[0] @property def head(self): """ Returns the <head> element. Can be called from a child element to get the document's head. """ return self.xpath('//head|//x:head', namespaces={'x':XHTML_NAMESPACE})[0] @property def label(self): """ Get or set any <label> element associated with this element. """ id = self.get('id') if not id: return None result = _label_xpath(self, id=id) if not result: return None else: return result[0] @label.setter def label(self, label): id = self.get('id') if not id: raise TypeError( "You cannot set a label for an element (%r) that has no id" % self) if _nons(label.tag) != 'label': raise TypeError( "You can only assign label to a label element (not %r)" % label) label.set('for', id) @label.deleter def label(self): label = self.label if label is not None: del label.attrib['for'] def drop_tree(self): """ Removes this element from the tree, including its children and text. The tail text is joined to the previous element or parent. """ parent = self.getparent() assert parent is not None if self.tail: previous = self.getprevious() if previous is None: parent.text = (parent.text or '') + self.tail else: previous.tail = (previous.tail or '') + self.tail parent.remove(self) def drop_tag(self): """ Remove the tag, but not its children or text. The children and text are merged into the parent. Example:: >>> h = fragment_fromstring('<div>Hello <b>World!</b></div>') >>> h.find('.//b').drop_tag() >>> print(tostring(h, encoding='unicode')) <div>Hello World!</div> """ parent = self.getparent() assert parent is not None previous = self.getprevious() if self.text and isinstance(self.tag, basestring): # not a Comment, etc. if previous is None: parent.text = (parent.text or '') + self.text else: previous.tail = (previous.tail or '') + self.text if self.tail: if len(self): last = self[-1] last.tail = (last.tail or '') + self.tail elif previous is None: parent.text = (parent.text or '') + self.tail else: previous.tail = (previous.tail or '') + self.tail index = parent.index(self) parent[index:index+1] = self[:] def find_rel_links(self, rel): """ Find any links like ``<a rel="{rel}">...</a>``; returns a list of elements. """ rel = rel.lower() return [el for el in _rel_links_xpath(self) if el.get('rel').lower() == rel] def find_class(self, class_name): """ Find any elements with the given class name. """ return _class_xpath(self, class_name=class_name) def get_element_by_id(self, id, *default): """ Get the first element in a document with the given id. If none is found, return the default argument if provided or raise KeyError otherwise. Note that there can be more than one element with the same id, and this isn't uncommon in HTML documents found in the wild. Browsers return only the first match, and this function does the same. """ try: # FIXME: should this check for multiple matches? # browsers just return the first one return _id_xpath(self, id=id)[0] except IndexError: if default: return default[0] else: raise KeyError(id) def text_content(self): """ Return the text content of the tag (and the text in any children). """ return _collect_string_content(self) def cssselect(self, expr, translator='html'): """ Run the CSS expression on this element and its children, returning a list of the results. Equivalent to lxml.cssselect.CSSSelect(expr, translator='html')(self) -- note that pre-compiling the expression can provide a substantial speedup. """ # Do the import here to make the dependency optional. from lxml.cssselect import CSSSelector return CSSSelector(expr, translator=translator)(self) ######################################## ## Link functions ######################################## def make_links_absolute(self, base_url=None, resolve_base_href=True, handle_failures=None): """ Make all links in the document absolute, given the ``base_url`` for the document (the full URL where the document came from), or if no ``base_url`` is given, then the ``.base_url`` of the document. If ``resolve_base_href`` is true, then any ``<base href>`` tags in the document are used *and* removed from the document. If it is false then any such tag is ignored. If ``handle_failures`` is None (default), a failure to process a URL will abort the processing. If set to 'ignore', errors are ignored. If set to 'discard', failing URLs will be removed. """ if base_url is None: base_url = self.base_url if base_url is None: raise TypeError( "No base_url given, and the document has no base_url") if resolve_base_href: self.resolve_base_href() if handle_failures == 'ignore': def link_repl(href): try: return urljoin(base_url, href) except ValueError: return href elif handle_failures == 'discard': def link_repl(href): try: return urljoin(base_url, href) except ValueError: return None elif handle_failures is None: def link_repl(href): return urljoin(base_url, href) else: raise ValueError( "unexpected value for handle_failures: %r" % handle_failures) self.rewrite_links(link_repl) def resolve_base_href(self, handle_failures=None): """ Find any ``<base href>`` tag in the document, and apply its values to all links found in the document. Also remove the tag once it has been applied. If ``handle_failures`` is None (default), a failure to process a URL will abort the processing. If set to 'ignore', errors are ignored. If set to 'discard', failing URLs will be removed. """ base_href = None basetags = self.xpath('//base[@href]|//x:base[@href]', namespaces={'x': XHTML_NAMESPACE}) for b in basetags: base_href = b.get('href') b.drop_tree() if not base_href: return self.make_links_absolute(base_href, resolve_base_href=False, handle_failures=handle_failures) def iterlinks(self): """ Yield (element, attribute, link, pos), where attribute may be None (indicating the link is in the text). ``pos`` is the position where the link occurs; often 0, but sometimes something else in the case of links in stylesheets or style tags. Note: <base href> is *not* taken into account in any way. The link you get is exactly the link in the document. Note: multiple links inside of a single text string or attribute value are returned in reversed order. This makes it possible to replace or delete them from the text string value based on their reported text positions. Otherwise, a modification at one text position can change the positions of links reported later on. """ link_attrs = defs.link_attrs for el in self.iter(etree.Element): attribs = el.attrib tag = _nons(el.tag) if tag == 'object': codebase = None ## <object> tags have attributes that are relative to ## codebase if 'codebase' in attribs: codebase = el.get('codebase') yield (el, 'codebase', codebase, 0) for attrib in ('classid', 'data'): if attrib in attribs: value = el.get(attrib) if codebase is not None: value = urljoin(codebase, value) yield (el, attrib, value, 0) if 'archive' in attribs: for match in _archive_re.finditer(el.get('archive')): value = match.group(0) if codebase is not None: value = urljoin(codebase, value) yield (el, 'archive', value, match.start()) else: for attrib in link_attrs: if attrib in attribs: yield (el, attrib, attribs[attrib], 0) if tag == 'meta': http_equiv = attribs.get('http-equiv', '').lower() if http_equiv == 'refresh': content = attribs.get('content', '') match = _parse_meta_refresh_url(content) url = (match.group('url') if match else content).strip() # unexpected content means the redirect won't work, but we might # as well be permissive and return the entire string. if url: url, pos = _unquote_match( url, match.start('url') if match else content.find(url)) yield (el, 'content', url, pos) elif tag == 'param': valuetype = el.get('valuetype') or '' if valuetype.lower() == 'ref': ## FIXME: while it's fine we *find* this link, ## according to the spec we aren't supposed to ## actually change the value, including resolving ## it. It can also still be a link, even if it ## doesn't have a valuetype="ref" (which seems to be the norm) ## http://www.w3.org/TR/html401/struct/objects.html#adef-valuetype yield (el, 'value', el.get('value'), 0) elif tag == 'style' and el.text: urls = [ # (start_pos, url) _unquote_match(match.group(1), match.start(1))[::-1] for match in _iter_css_urls(el.text) ] + [ (match.start(1), match.group(1)) for match in _iter_css_imports(el.text) ] if urls: # sort by start pos to bring both match sets back into order # and reverse the list to report correct positions despite # modifications urls.sort(reverse=True) for start, url in urls: yield (el, None, url, start) if 'style' in attribs: urls = list(_iter_css_urls(attribs['style'])) if urls: # return in reversed order to simplify in-place modifications for match in urls[::-1]: url, start = _unquote_match(match.group(1), match.start(1)) yield (el, 'style', url, start) def rewrite_links(self, link_repl_func, resolve_base_href=True, base_href=None): """ Rewrite all the links in the document. For each link ``link_repl_func(link)`` will be called, and the return value will replace the old link. Note that links may not be absolute (unless you first called ``make_links_absolute()``), and may be internal (e.g., ``'#anchor'``). They can also be values like ``'mailto:email'`` or ``'javascript:expr'``. If you give ``base_href`` then all links passed to ``link_repl_func()`` will take that into account. If the ``link_repl_func`` returns None, the attribute or tag text will be removed completely. """ if base_href is not None: # FIXME: this can be done in one pass with a wrapper # around link_repl_func self.make_links_absolute( base_href, resolve_base_href=resolve_base_href) elif resolve_base_href: self.resolve_base_href() for el, attrib, link, pos in self.iterlinks(): new_link = link_repl_func(link.strip()) if new_link == link: continue if new_link is None: # Remove the attribute or element content if attrib is None: el.text = '' else: del el.attrib[attrib] continue if attrib is None: new = el.text[:pos] + new_link + el.text[pos+len(link):] el.text = new else: cur = el.get(attrib) if not pos and len(cur) == len(link): new = new_link # most common case else: new = cur[:pos] + new_link + cur[pos+len(link):] el.set(attrib, new) class _MethodFunc(object): """ An object that represents a method on an element as a function; the function takes either an element or an HTML string. It returns whatever the function normally returns, or if the function works in-place (and so returns None) it returns a serialized form of the resulting document. """ def __init__(self, name, copy=False, source_class=HtmlMixin): self.name = name self.copy = copy self.__doc__ = getattr(source_class, self.name).__doc__ def __call__(self, doc, *args, **kw): result_type = type(doc) if isinstance(doc, basestring): if 'copy' in kw: raise TypeError( "The keyword 'copy' can only be used with element inputs to %s, not a string input" % self.name) doc = fromstring(doc, **kw) else: if 'copy' in kw: make_a_copy = kw.pop('copy') else: make_a_copy = self.copy if make_a_copy: doc = copy.deepcopy(doc) meth = getattr(doc, self.name) result = meth(*args, **kw) # FIXME: this None test is a bit sloppy if result is None: # Then return what we got in return _transform_result(result_type, doc) else: return result find_rel_links = _MethodFunc('find_rel_links', copy=False) find_class = _MethodFunc('find_class', copy=False) make_links_absolute = _MethodFunc('make_links_absolute', copy=True) resolve_base_href = _MethodFunc('resolve_base_href', copy=True) iterlinks = _MethodFunc('iterlinks', copy=False) rewrite_links = _MethodFunc('rewrite_links', copy=True) class HtmlComment(etree.CommentBase, HtmlMixin): pass class HtmlElement(etree.ElementBase, HtmlMixin): # Override etree.ElementBase.cssselect() and set(), despite the MRO (FIXME: change base order?) cssselect = HtmlMixin.cssselect set = HtmlMixin.set class HtmlProcessingInstruction(etree.PIBase, HtmlMixin): pass class HtmlEntity(etree.EntityBase, HtmlMixin): pass class HtmlElementClassLookup(etree.CustomElementClassLookup): """A lookup scheme for HTML Element classes. To create a lookup instance with different Element classes, pass a tag name mapping of Element classes in the ``classes`` keyword argument and/or a tag name mapping of Mixin classes in the ``mixins`` keyword argument. The special key '*' denotes a Mixin class that should be mixed into all Element classes. """ _default_element_classes = {} def __init__(self, classes=None, mixins=None): etree.CustomElementClassLookup.__init__(self) if classes is None: classes = self._default_element_classes.copy() if mixins: mixers = {} for name, value in mixins: if name == '*': for n in classes.keys(): mixers.setdefault(n, []).append(value) else: mixers.setdefault(name, []).append(value) for name, mix_bases in mixers.items(): cur = classes.get(name, HtmlElement) bases = tuple(mix_bases + [cur]) classes[name] = type(cur.__name__, bases, {}) self._element_classes = classes def lookup(self, node_type, document, namespace, name): if node_type == 'element': return self._element_classes.get(name.lower(), HtmlElement) elif node_type == 'comment': return HtmlComment elif node_type == 'PI': return HtmlProcessingInstruction elif node_type == 'entity': return HtmlEntity # Otherwise normal lookup return None ################################################################################ # parsing ################################################################################ _looks_like_full_html_unicode = re.compile( unicode(r'^\s*<(?:html|!doctype)'), re.I).match _looks_like_full_html_bytes = re.compile( r'^\s*<(?:html|!doctype)'.encode('ascii'), re.I).match def document_fromstring(html, parser=None, ensure_head_body=False, **kw): if parser is None: parser = html_parser value = etree.fromstring(html, parser, **kw) if value is None: raise etree.ParserError( "Document is empty") if ensure_head_body and value.find('head') is None: value.insert(0, Element('head')) if ensure_head_body and value.find('body') is None: value.append(Element('body')) return value def fragments_fromstring(html, no_leading_text=False, base_url=None, parser=None, **kw): """Parses several HTML elements, returning a list of elements. The first item in the list may be a string. If no_leading_text is true, then it will be an error if there is leading text, and it will always be a list of only elements. base_url will set the document's base_url attribute (and the tree's docinfo.URL). """ if parser is None: parser = html_parser # FIXME: check what happens when you give html with a body, head, etc. if isinstance(html, bytes): if not _looks_like_full_html_bytes(html): # can't use %-formatting in early Py3 versions html = ('<html><body>'.encode('ascii') + html + '</body></html>'.encode('ascii')) else: if not _looks_like_full_html_unicode(html): html = '<html><body>%s</body></html>' % html doc = document_fromstring(html, parser=parser, base_url=base_url, **kw) assert _nons(doc.tag) == 'html' bodies = [e for e in doc if _nons(e.tag) == 'body'] assert len(bodies) == 1, ("too many bodies: %r in %r" % (bodies, html)) body = bodies[0] elements = [] if no_leading_text and body.text and body.text.strip(): raise etree.ParserError( "There is leading text: %r" % body.text) if body.text and body.text.strip(): elements.append(body.text) elements.extend(body) # FIXME: removing the reference to the parent artificial document # would be nice return elements def fragment_fromstring(html, create_parent=False, base_url=None, parser=None, **kw): """ Parses a single HTML element; it is an error if there is more than one element, or if anything but whitespace precedes or follows the element. If ``create_parent`` is true (or is a tag name) then a parent node will be created to encapsulate the HTML in a single element. In this case, leading or trailing text is also allowed, as are multiple elements as result of the parsing. Passing a ``base_url`` will set the document's ``base_url`` attribute (and the tree's docinfo.URL). """ if parser is None: parser = html_parser accept_leading_text = bool(create_parent) elements = fragments_fromstring( html, parser=parser, no_leading_text=not accept_leading_text, base_url=base_url, **kw) if create_parent: if not isinstance(create_parent, basestring): create_parent = 'div' new_root = Element(create_parent) if elements: if isinstance(elements[0], basestring): new_root.text = elements[0] del elements[0] new_root.extend(elements) return new_root if not elements: raise etree.ParserError('No elements found') if len(elements) > 1: raise etree.ParserError( "Multiple elements found (%s)" % ', '.join([_element_name(e) for e in elements])) el = elements[0] if el.tail and el.tail.strip(): raise etree.ParserError( "Element followed by text: %r" % el.tail) el.tail = None return el def fromstring(html, base_url=None, parser=None, **kw): """ Parse the html, returning a single element/document. This tries to minimally parse the chunk of text, without knowing if it is a fragment or a document. base_url will set the document's base_url attribute (and the tree's docinfo.URL) """ if parser is None: parser = html_parser if isinstance(html, bytes): is_full_html = _looks_like_full_html_bytes(html) else: is_full_html = _looks_like_full_html_unicode(html) doc = document_fromstring(html, parser=parser, base_url=base_url, **kw) if is_full_html: return doc # otherwise, lets parse it out... bodies = doc.findall('body') if not bodies: bodies = doc.findall('{%s}body' % XHTML_NAMESPACE) if bodies: body = bodies[0] if len(bodies) > 1: # Somehow there are multiple bodies, which is bad, but just # smash them into one body for other_body in bodies[1:]: if other_body.text: if len(body): body[-1].tail = (body[-1].tail or '') + other_body.text else: body.text = (body.text or '') + other_body.text body.extend(other_body) # We'll ignore tail # I guess we are ignoring attributes too other_body.drop_tree() else: body = None heads = doc.findall('head') if not heads: heads = doc.findall('{%s}head' % XHTML_NAMESPACE) if heads: # Well, we have some sort of structure, so lets keep it all head = heads[0] if len(heads) > 1: for other_head in heads[1:]: head.extend(other_head) # We don't care about text or tail in a head other_head.drop_tree() return doc if body is None: return doc if (len(body) == 1 and (not body.text or not body.text.strip()) and (not body[-1].tail or not body[-1].tail.strip())): # The body has just one element, so it was probably a single # element passed in return body[0] # Now we have a body which represents a bunch of tags which have the # content that was passed in. We will create a fake container, which # is the body tag, except <body> implies too much structure. if _contains_block_level_tag(body): body.tag = 'div' else: body.tag = 'span' return body def parse(filename_or_url, parser=None, base_url=None, **kw): """ Parse a filename, URL, or file-like object into an HTML document tree. Note: this returns a tree, not an element. Use ``parse(...).getroot()`` to get the document root. You can override the base URL with the ``base_url`` keyword. This is most useful when parsing from a file-like object. """ if parser is None: parser = html_parser return etree.parse(filename_or_url, parser, base_url=base_url, **kw) def _contains_block_level_tag(el): # FIXME: I could do this with XPath, but would that just be # unnecessarily slow? for el in el.iter(etree.Element): if _nons(el.tag) in defs.block_tags: return True return False def _element_name(el): if isinstance(el, etree.CommentBase): return 'comment' elif isinstance(el, basestring): return 'string' else: return _nons(el.tag) ################################################################################ # form handling ################################################################################ class FormElement(HtmlElement): """ Represents a <form> element. """ @property def inputs(self): """ Returns an accessor for all the input elements in the form. See `InputGetter` for more information about the object. """ return InputGetter(self) @property def fields(self): """ Dictionary-like object that represents all the fields in this form. You can set values in this dictionary to effect the form. """ return FieldsDict(self.inputs) @fields.setter def fields(self, value): fields = self.fields prev_keys = fields.keys() for key, value in value.items(): if key in prev_keys: prev_keys.remove(key) fields[key] = value for key in prev_keys: if key is None: # Case of an unnamed input; these aren't really # expressed in form_values() anyway. continue fields[key] = None def _name(self): if self.get('name'): return self.get('name') elif self.get('id'): return '#' + self.get('id') iter_tags = self.body.iter forms = list(iter_tags('form')) if not forms: forms = list(iter_tags('{%s}form' % XHTML_NAMESPACE)) return str(forms.index(self)) def form_values(self): """ Return a list of tuples of the field values for the form. This is suitable to be passed to ``urllib.urlencode()``. """ results = [] for el in self.inputs: name = el.name if not name or 'disabled' in el.attrib: continue tag = _nons(el.tag) if tag == 'textarea': results.append((name, el.value)) elif tag == 'select': value = el.value if el.multiple: for v in value: results.append((name, v)) elif value is not None: results.append((name, el.value)) else: assert tag == 'input', ( "Unexpected tag: %r" % el) if el.checkable and not el.checked: continue if el.type in ('submit', 'image', 'reset', 'file'): continue value = el.value if value is not None: results.append((name, el.value)) return results @property def action(self): """ Get/set the form's ``action`` attribute. """ base_url = self.base_url action = self.get('action') if base_url and action is not None: return urljoin(base_url, action) else: return action @action.setter def action(self, value): self.set('action', value) @action.deleter def action(self): attrib = self.attrib if 'action' in attrib: del attrib['action'] @property def method(self): """ Get/set the form's method. Always returns a capitalized string, and defaults to ``'GET'`` """ return self.get('method', 'GET').upper() @method.setter def method(self, value): self.set('method', value.upper()) HtmlElementClassLookup._default_element_classes['form'] = FormElement def submit_form(form, extra_values=None, open_http=None): """ Helper function to submit a form. Returns a file-like object, as from ``urllib.urlopen()``. This object also has a ``.geturl()`` function, which shows the URL if there were any redirects. You can use this like:: form = doc.forms[0] form.inputs['foo'].value = 'bar' # etc response = form.submit() doc = parse(response) doc.make_links_absolute(response.geturl()) To change the HTTP requester, pass a function as ``open_http`` keyword argument that opens the URL for you. The function must have the following signature:: open_http(method, URL, values) The action is one of 'GET' or 'POST', the URL is the target URL as a string, and the values are a sequence of ``(name, value)`` tuples with the form data. """ values = form.form_values() if extra_values: if hasattr(extra_values, 'items'): extra_values = extra_values.items() values.extend(extra_values) if open_http is None: open_http = open_http_urllib if form.action: url = form.action else: url = form.base_url return open_http(form.method, url, values) def open_http_urllib(method, url, values): if not url: raise ValueError("cannot submit, no URL provided") ## FIXME: should test that it's not a relative URL or something try: from urllib import urlencode, urlopen except ImportError: # Python 3 from urllib.request import urlopen from urllib.parse import urlencode if method == 'GET': if '?' in url: url += '&' else: url += '?' url += urlencode(values) data = None else: data = urlencode(values) if not isinstance(data, bytes): data = data.encode('ASCII') return urlopen(url, data) class FieldsDict(MutableMapping): def __init__(self, inputs): self.inputs = inputs def __getitem__(self, item): return self.inputs[item].value def __setitem__(self, item, value): self.inputs[item].value = value def __delitem__(self, item): raise KeyError( "You cannot remove keys from ElementDict") def keys(self): return self.inputs.keys() def __contains__(self, item): return item in self.inputs def __iter__(self): return iter(self.inputs.keys()) def __len__(self): return len(self.inputs) def __repr__(self): return '<%s for form %s>' % ( self.__class__.__name__, self.inputs.form._name()) class InputGetter(object): """ An accessor that represents all the input fields in a form. You can get fields by name from this, with ``form.inputs['field_name']``. If there are a set of checkboxes with the same name, they are returned as a list (a `CheckboxGroup` which also allows value setting). Radio inputs are handled similarly. You can also iterate over this to get all input elements. This won't return the same thing as if you get all the names, as checkboxes and radio elements are returned individually. """ _name_xpath = etree.XPath(".//*[@name = $name and (local-name(.) = 'select' or local-name(.) = 'input' or local-name(.) = 'textarea')]") _all_xpath = etree.XPath(".//*[local-name() = 'select' or local-name() = 'input' or local-name() = 'textarea']") def __init__(self, form): self.form = form def __repr__(self): return '<%s for form %s>' % ( self.__class__.__name__, self.form._name()) ## FIXME: there should be more methods, and it's unclear if this is ## a dictionary-like object or list-like object def __getitem__(self, name): results = self._name_xpath(self.form, name=name) if results: type = results[0].get('type') if type == 'radio' and len(results) > 1: group = RadioGroup(results) group.name = name return group elif type == 'checkbox' and len(results) > 1: group = CheckboxGroup(results) group.name = name return group else: # I don't like throwing away elements like this return results[0] else: raise KeyError( "No input element with the name %r" % name) def __contains__(self, name): results = self._name_xpath(self.form, name=name) return bool(results) def keys(self): names = set() for el in self: names.add(el.name) if None in names: names.remove(None) return list(names) def __iter__(self): ## FIXME: kind of dumb to turn a list into an iterator, only ## to have it likely turned back into a list again :( return iter(self._all_xpath(self.form)) class InputMixin(object): """ Mix-in for all input elements (input, select, and textarea) """ @property def name(self): """ Get/set the name of the element """ return self.get('name') @name.setter def name(self, value): self.set('name', value) @name.deleter def name(self): attrib = self.attrib if 'name' in attrib: del attrib['name'] def __repr__(self): type_name = getattr(self, 'type', None) if type_name: type_name = ' type=%r' % type_name else: type_name = '' return '<%s %x name=%r%s>' % ( self.__class__.__name__, id(self), self.name, type_name) class TextareaElement(InputMixin, HtmlElement): """ ``<textarea>`` element. You can get the name with ``.name`` and get/set the value with ``.value`` """ @property def value(self): """ Get/set the value (which is the contents of this element) """ content = self.text or '' if self.tag.startswith("{%s}" % XHTML_NAMESPACE): serialisation_method = 'xml' else: serialisation_method = 'html' for el in self: # it's rare that we actually get here, so let's not use ''.join() content += etree.tostring( el, method=serialisation_method, encoding='unicode') return content @value.setter def value(self, value): del self[:] self.text = value @value.deleter def value(self): self.text = '' del self[:] HtmlElementClassLookup._default_element_classes['textarea'] = TextareaElement class SelectElement(InputMixin, HtmlElement): """ ``<select>`` element. You can get the name with ``.name``. ``.value`` will be the value of the selected option, unless this is a multi-select element (``<select multiple>``), in which case it will be a set-like object. In either case ``.value_options`` gives the possible values. The boolean attribute ``.multiple`` shows if this is a multi-select. """ @property def value(self): """ Get/set the value of this select (the selected option). If this is a multi-select, this is a set-like object that represents all the selected options. """ if self.multiple: return MultipleSelectOptions(self) options = _options_xpath(self) try: selected_option = next(el for el in reversed(options) if el.get('selected') is not None) except StopIteration: try: selected_option = next(el for el in options if el.get('disabled') is None) except StopIteration: return None value = selected_option.get('value') if value is None: value = (selected_option.text or '').strip() return value @value.setter def value(self, value): if self.multiple: if isinstance(value, basestring): raise TypeError("You must pass in a sequence") values = self.value values.clear() values.update(value) return checked_option = None if value is not None: for el in _options_xpath(self): opt_value = el.get('value') if opt_value is None: opt_value = (el.text or '').strip() if opt_value == value: checked_option = el break else: raise ValueError( "There is no option with the value of %r" % value) for el in _options_xpath(self): if 'selected' in el.attrib: del el.attrib['selected'] if checked_option is not None: checked_option.set('selected', '') @value.deleter def value(self): # FIXME: should del be allowed at all? if self.multiple: self.value.clear() else: self.value = None @property def value_options(self): """ All the possible values this select can have (the ``value`` attribute of all the ``<option>`` elements. """ options = [] for el in _options_xpath(self): value = el.get('value') if value is None: value = (el.text or '').strip() options.append(value) return options @property def multiple(self): """ Boolean attribute: is there a ``multiple`` attribute on this element. """ return 'multiple' in self.attrib @multiple.setter def multiple(self, value): if value: self.set('multiple', '') elif 'multiple' in self.attrib: del self.attrib['multiple'] HtmlElementClassLookup._default_element_classes['select'] = SelectElement class MultipleSelectOptions(SetMixin): """ Represents all the selected options in a ``<select multiple>`` element. You can add to this set-like option to select an option, or remove to unselect the option. """ def __init__(self, select): self.select = select @property def options(self): """ Iterator of all the ``<option>`` elements. """ return iter(_options_xpath(self.select)) def __iter__(self): for option in self.options: if 'selected' in option.attrib: opt_value = option.get('value') if opt_value is None: opt_value = (option.text or '').strip() yield opt_value def add(self, item): for option in self.options: opt_value = option.get('value') if opt_value is None: opt_value = (option.text or '').strip() if opt_value == item: option.set('selected', '') break else: raise ValueError( "There is no option with the value %r" % item) def remove(self, item): for option in self.options: opt_value = option.get('value') if opt_value is None: opt_value = (option.text or '').strip() if opt_value == item: if 'selected' in option.attrib: del option.attrib['selected'] else: raise ValueError( "The option %r is not currently selected" % item) break else: raise ValueError( "There is not option with the value %r" % item) def __repr__(self): return '<%s {%s} for select name=%r>' % ( self.__class__.__name__, ', '.join([repr(v) for v in self]), self.select.name) class RadioGroup(list): """ This object represents several ``<input type=radio>`` elements that have the same name. You can use this like a list, but also use the property ``.value`` to check/uncheck inputs. Also you can use ``.value_options`` to get the possible values. """ @property def value(self): """ Get/set the value, which checks the radio with that value (and unchecks any other value). """ for el in self: if 'checked' in el.attrib: return el.get('value') return None @value.setter def value(self, value): checked_option = None if value is not None: for el in self: if el.get('value') == value: checked_option = el break else: raise ValueError("There is no radio input with the value %r" % value) for el in self: if 'checked' in el.attrib: del el.attrib['checked'] if checked_option is not None: checked_option.set('checked', '') @value.deleter def value(self): self.value = None @property def value_options(self): """ Returns a list of all the possible values. """ return [el.get('value') for el in self] def __repr__(self): return '%s(%s)' % ( self.__class__.__name__, list.__repr__(self)) class CheckboxGroup(list): """ Represents a group of checkboxes (``<input type=checkbox>``) that have the same name. In addition to using this like a list, the ``.value`` attribute returns a set-like object that you can add to or remove from to check and uncheck checkboxes. You can also use ``.value_options`` to get the possible values. """ @property def value(self): """ Return a set-like object that can be modified to check or uncheck individual checkboxes according to their value. """ return CheckboxValues(self) @value.setter def value(self, value): values = self.value values.clear() if not hasattr(value, '__iter__'): raise ValueError( "A CheckboxGroup (name=%r) must be set to a sequence (not %r)" % (self[0].name, value)) values.update(value) @value.deleter def value(self): self.value.clear() @property def value_options(self): """ Returns a list of all the possible values. """ return [el.get('value') for el in self] def __repr__(self): return '%s(%s)' % ( self.__class__.__name__, list.__repr__(self)) class CheckboxValues(SetMixin): """ Represents the values of the checked checkboxes in a group of checkboxes with the same name. """ def __init__(self, group): self.group = group def __iter__(self): return iter([ el.get('value') for el in self.group if 'checked' in el.attrib]) def add(self, value): for el in self.group: if el.get('value') == value: el.set('checked', '') break else: raise KeyError("No checkbox with value %r" % value) def remove(self, value): for el in self.group: if el.get('value') == value: if 'checked' in el.attrib: del el.attrib['checked'] else: raise KeyError( "The checkbox with value %r was already unchecked" % value) break else: raise KeyError( "No checkbox with value %r" % value) def __repr__(self): return '<%s {%s} for checkboxes name=%r>' % ( self.__class__.__name__, ', '.join([repr(v) for v in self]), self.group.name) class InputElement(InputMixin, HtmlElement): """ Represents an ``<input>`` element. You can get the type with ``.type`` (which is lower-cased and defaults to ``'text'``). Also you can get and set the value with ``.value`` Checkboxes and radios have the attribute ``input.checkable == True`` (for all others it is false) and a boolean attribute ``.checked``. """ ## FIXME: I'm a little uncomfortable with the use of .checked @property def value(self): """ Get/set the value of this element, using the ``value`` attribute. Also, if this is a checkbox and it has no value, this defaults to ``'on'``. If it is a checkbox or radio that is not checked, this returns None. """ if self.checkable: if self.checked: return self.get('value') or 'on' else: return None return self.get('value') @value.setter def value(self, value): if self.checkable: if not value: self.checked = False else: self.checked = True if isinstance(value, basestring): self.set('value', value) else: self.set('value', value) @value.deleter def value(self): if self.checkable: self.checked = False else: if 'value' in self.attrib: del self.attrib['value'] @property def type(self): """ Return the type of this element (using the type attribute). """ return self.get('type', 'text').lower() @type.setter def type(self, value): self.set('type', value) @property def checkable(self): """ Boolean: can this element be checked? """ return self.type in ('checkbox', 'radio') @property def checked(self): """ Boolean attribute to get/set the presence of the ``checked`` attribute. You can only use this on checkable input types. """ if not self.checkable: raise AttributeError('Not a checkable input type') return 'checked' in self.attrib @checked.setter def checked(self, value): if not self.checkable: raise AttributeError('Not a checkable input type') if value: self.set('checked', '') else: attrib = self.attrib if 'checked' in attrib: del attrib['checked'] HtmlElementClassLookup._default_element_classes['input'] = InputElement class LabelElement(HtmlElement): """ Represents a ``<label>`` element. Label elements are linked to other elements with their ``for`` attribute. You can access this element with ``label.for_element``. """ @property def for_element(self): """ Get/set the element this label points to. Return None if it can't be found. """ id = self.get('for') if not id: return None return self.body.get_element_by_id(id) @for_element.setter def for_element(self, other): id = other.get('id') if not id: raise TypeError( "Element %r has no id attribute" % other) self.set('for', id) @for_element.deleter def for_element(self): attrib = self.attrib if 'id' in attrib: del attrib['id'] HtmlElementClassLookup._default_element_classes['label'] = LabelElement ############################################################ ## Serialization ############################################################ def html_to_xhtml(html): """Convert all tags in an HTML tree to XHTML by moving them to the XHTML namespace. """ try: html = html.getroot() except AttributeError: pass prefix = "{%s}" % XHTML_NAMESPACE for el in html.iter(etree.Element): tag = el.tag if tag[0] != '{': el.tag = prefix + tag def xhtml_to_html(xhtml): """Convert all tags in an XHTML tree to HTML by removing their XHTML namespace. """ try: xhtml = xhtml.getroot() except AttributeError: pass prefix = "{%s}" % XHTML_NAMESPACE prefix_len = len(prefix) for el in xhtml.iter(prefix + "*"): el.tag = el.tag[prefix_len:] # This isn't a general match, but it's a match for what libxml2 # specifically serialises: __str_replace_meta_content_type = re.compile( r'<meta http-equiv="Content-Type"[^>]*>').sub __bytes_replace_meta_content_type = re.compile( r'<meta http-equiv="Content-Type"[^>]*>'.encode('ASCII')).sub def tostring(doc, pretty_print=False, include_meta_content_type=False, encoding=None, method="html", with_tail=True, doctype=None): """Return an HTML string representation of the document. Note: if include_meta_content_type is true this will create a ``<meta http-equiv="Content-Type" ...>`` tag in the head; regardless of the value of include_meta_content_type any existing ``<meta http-equiv="Content-Type" ...>`` tag will be removed The ``encoding`` argument controls the output encoding (defauts to ASCII, with &#...; character references for any characters outside of ASCII). Note that you can pass the name ``'unicode'`` as ``encoding`` argument to serialise to a Unicode string. The ``method`` argument defines the output method. It defaults to 'html', but can also be 'xml' for xhtml output, or 'text' to serialise to plain text without markup. To leave out the tail text of the top-level element that is being serialised, pass ``with_tail=False``. The ``doctype`` option allows passing in a plain string that will be serialised before the XML tree. Note that passing in non well-formed content here will make the XML output non well-formed. Also, an existing doctype in the document tree will not be removed when serialising an ElementTree instance. Example:: >>> from lxml import html >>> root = html.fragment_fromstring('<p>Hello<br>world!</p>') >>> html.tostring(root) b'<p>Hello<br>world!</p>' >>> html.tostring(root, method='html') b'<p>Hello<br>world!</p>' >>> html.tostring(root, method='xml') b'<p>Hello<br/>world!</p>' >>> html.tostring(root, method='text') b'Helloworld!' >>> html.tostring(root, method='text', encoding='unicode') u'Helloworld!' >>> root = html.fragment_fromstring('<div><p>Hello<br>world!</p>TAIL</div>') >>> html.tostring(root[0], method='text', encoding='unicode') u'Helloworld!TAIL' >>> html.tostring(root[0], method='text', encoding='unicode', with_tail=False) u'Helloworld!' >>> doc = html.document_fromstring('<p>Hello<br>world!</p>') >>> html.tostring(doc, method='html', encoding='unicode') u'<html><body><p>Hello<br>world!</p></body></html>' >>> print(html.tostring(doc, method='html', encoding='unicode', ... doctype='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"' ... ' "http://www.w3.org/TR/html4/strict.dtd">')) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html><body><p>Hello<br>world!</p></body></html> """ html = etree.tostring(doc, method=method, pretty_print=pretty_print, encoding=encoding, with_tail=with_tail, doctype=doctype) if method == 'html' and not include_meta_content_type: if isinstance(html, str): html = __str_replace_meta_content_type('', html) else: html = __bytes_replace_meta_content_type(bytes(), html) return html tostring.__doc__ = __fix_docstring(tostring.__doc__) def open_in_browser(doc, encoding=None): """ Open the HTML document in a web browser, saving it to a temporary file to open it. Note that this does not delete the file after use. This is mainly meant for debugging. """ import os import webbrowser import tempfile if not isinstance(doc, etree._ElementTree): doc = etree.ElementTree(doc) handle, fn = tempfile.mkstemp(suffix='.html') f = os.fdopen(handle, 'wb') try: doc.write(f, method="html", encoding=encoding or doc.docinfo.encoding or "UTF-8") finally: # we leak the file itself here, but we should at least close it f.close() url = 'file://' + fn.replace(os.path.sep, '/') print(url) webbrowser.open(url) ################################################################################ # configure Element class lookup ################################################################################ class HTMLParser(etree.HTMLParser): """An HTML parser that is configured to return lxml.html Element objects. """ def __init__(self, **kwargs): super(HTMLParser, self).__init__(**kwargs) self.set_element_class_lookup(HtmlElementClassLookup()) class XHTMLParser(etree.XMLParser): """An XML parser that is configured to return lxml.html Element objects. Note that this parser is not really XHTML aware unless you let it load a DTD that declares the HTML entities. To do this, make sure you have the XHTML DTDs installed in your catalogs, and create the parser like this:: >>> parser = XHTMLParser(load_dtd=True) If you additionally want to validate the document, use this:: >>> parser = XHTMLParser(dtd_validation=True) For catalog support, see http://www.xmlsoft.org/catalog.html. """ def __init__(self, **kwargs): super(XHTMLParser, self).__init__(**kwargs) self.set_element_class_lookup(HtmlElementClassLookup()) def Element(*args, **kw): """Create a new HTML Element. This can also be used for XHTML documents. """ v = html_parser.makeelement(*args, **kw) return v html_parser = HTMLParser() xhtml_parser = XHTMLParser() ���������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/http/__init__.py���������������������������������������������������������������0000644�����������������00000020164�15253650023�0013216 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from 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/dnf/db/__init__.py��������������������������������������������������0000644�����������������00000001412�15253650316�0015664 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright (C) 2017 Red Hat, Inc. # # DNF database subpackage # # 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 Library 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. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/zoneinfo/__init__.py�����������������������������������������������������������0000644�����������������00000001277�15253655403�0014101 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������__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/python2.7/ensurepip/__init__.py�����������������������������������������������������������0000644�����������������00000016052�15253655732�0014211 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /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, ) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python2.7/test/support/__init__.py��������������������������������������������������������0000644�����������������00000227217�15253656157�0014703 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""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, '<test string>', '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) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python2.7/lib2to3/fixes/__init__.py�������������������������������������������������������0000644�����������������00000000057�15253656331�0014565 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Dummy file to make this directory a package. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python-internal/lib64/python3.11/lib2to3/__init__.py����������������������������������������0000644�����������������00000000234�15253656740�0017430 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import warnings warnings.warn( "lib2to3 package is deprecated and may not be able to parse Python 3.10+", DeprecationWarning, stacklevel=2, ) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python2.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py������������������������������0000644�����������������00000000441�15253660551�0021601 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������from __future__ import absolute_import, division, unicode_literals from .py import Trie as PyTrie Trie = PyTrie # pylint:disable=wrong-import-position try: from .datrie import Trie as DATrie except ImportError: pass else: Trie = DATrie # pylint:enable=wrong-import-position �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.12/importlib/metadata/__init__.py�������������������������������������������������0000644�����������������00000070125�15253663664�0016041 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os import re import abc import csv import sys import email import pathlib import zipfile import operator import textwrap import warnings import functools import itertools import posixpath import contextlib import collections import inspect from . import _adapters, _meta from ._collections import FreezableDefaultDict, Pair from ._functools import method_cache, pass_none from ._itertools import always_iterable, unique_everseen from ._meta import PackageMetadata, SimplePath from contextlib import suppress from importlib import import_module from importlib.abc import MetaPathFinder from itertools import starmap from typing import List, Mapping, Optional, cast __all__ = [ 'Distribution', 'DistributionFinder', 'PackageMetadata', 'PackageNotFoundError', 'distribution', 'distributions', 'entry_points', 'files', 'metadata', 'packages_distributions', 'requires', 'version', ] class PackageNotFoundError(ModuleNotFoundError): """The package was not found.""" def __str__(self): return f"No package metadata was found for {self.name}" @property def name(self): (name,) = self.args return name class Sectioned: """ A simple entry point config parser for performance >>> for item in Sectioned.read(Sectioned._sample): ... print(item) Pair(name='sec1', value='# comments ignored') Pair(name='sec1', value='a = 1') Pair(name='sec1', value='b = 2') Pair(name='sec2', value='a = 2') >>> res = Sectioned.section_pairs(Sectioned._sample) >>> item = next(res) >>> item.name 'sec1' >>> item.value Pair(name='a', value='1') >>> item = next(res) >>> item.value Pair(name='b', value='2') >>> item = next(res) >>> item.name 'sec2' >>> item.value Pair(name='a', value='2') >>> list(res) [] """ _sample = textwrap.dedent( """ [sec1] # comments ignored a = 1 b = 2 [sec2] a = 2 """ ).lstrip() @classmethod def section_pairs(cls, text): return ( section._replace(value=Pair.parse(section.value)) for section in cls.read(text, filter_=cls.valid) if section.name is not None ) @staticmethod def read(text, filter_=None): lines = filter(filter_, map(str.strip, text.splitlines())) name = None for value in lines: section_match = value.startswith('[') and value.endswith(']') if section_match: name = value.strip('[]') continue yield Pair(name, value) @staticmethod def valid(line): return line and not line.startswith('#') class DeprecatedTuple: """ Provide subscript item access for backward compatibility. >>> recwarn = getfixture('recwarn') >>> ep = EntryPoint(name='name', value='value', group='group') >>> ep[:] ('name', 'value', 'group') >>> ep[0] 'name' >>> len(recwarn) 1 """ # Do not remove prior to 2023-05-01 or Python 3.13 _warn = functools.partial( warnings.warn, "EntryPoint tuple interface is deprecated. Access members by name.", DeprecationWarning, stacklevel=2, ) def __getitem__(self, item): self._warn() return self._key()[item] class EntryPoint(DeprecatedTuple): """An entry point as defined by Python packaging conventions. See `the packaging docs on entry points <https://packaging.python.org/specifications/entry-points/>`_ for more information. >>> ep = EntryPoint( ... name=None, group=None, value='package.module:attr [extra1, extra2]') >>> ep.module 'package.module' >>> ep.attr 'attr' >>> ep.extras ['extra1', 'extra2'] """ pattern = re.compile( r'(?P<module>[\w.]+)\s*' r'(:\s*(?P<attr>[\w.]+)\s*)?' r'((?P<extras>\[.*\])\s*)?$' ) """ A regular expression describing the syntax for an entry point, which might look like: - module - package.module - package.module:attribute - package.module:object.attribute - package.module:attr [extra1, extra2] Other combinations are possible as well. The expression is lenient about whitespace around the ':', following the attr, and following any extras. """ name: str value: str group: str dist: Optional['Distribution'] = None def __init__(self, name, value, group): vars(self).update(name=name, value=value, group=group) def load(self): """Load the entry point from its definition. If only a module is indicated by the value, return that module. Otherwise, return the named object. """ match = self.pattern.match(self.value) module = import_module(match.group('module')) attrs = filter(None, (match.group('attr') or '').split('.')) return functools.reduce(getattr, attrs, module) @property def module(self): match = self.pattern.match(self.value) return match.group('module') @property def attr(self): match = self.pattern.match(self.value) return match.group('attr') @property def extras(self): match = self.pattern.match(self.value) return re.findall(r'\w+', match.group('extras') or '') def _for(self, dist): vars(self).update(dist=dist) return self def matches(self, **params): """ EntryPoint matches the given parameters. >>> ep = EntryPoint(group='foo', name='bar', value='bing:bong [extra1, extra2]') >>> ep.matches(group='foo') True >>> ep.matches(name='bar', value='bing:bong [extra1, extra2]') True >>> ep.matches(group='foo', name='other') False >>> ep.matches() True >>> ep.matches(extras=['extra1', 'extra2']) True >>> ep.matches(module='bing') True >>> ep.matches(attr='bong') True """ attrs = (getattr(self, param) for param in params) return all(map(operator.eq, params.values(), attrs)) def _key(self): return self.name, self.value, self.group def __lt__(self, other): return self._key() < other._key() def __eq__(self, other): return self._key() == other._key() def __setattr__(self, name, value): raise AttributeError("EntryPoint objects are immutable.") def __repr__(self): return ( f'EntryPoint(name={self.name!r}, value={self.value!r}, ' f'group={self.group!r})' ) def __hash__(self): return hash(self._key()) class EntryPoints(tuple): """ An immutable collection of selectable EntryPoint objects. """ __slots__ = () def __getitem__(self, name): # -> EntryPoint: """ Get the EntryPoint in self matching name. """ try: return next(iter(self.select(name=name))) except StopIteration: raise KeyError(name) def select(self, **params): """ Select entry points from self that match the given parameters (typically group and/or name). """ return EntryPoints(ep for ep in self if ep.matches(**params)) @property def names(self): """ Return the set of all names of all entry points. """ return {ep.name for ep in self} @property def groups(self): """ Return the set of all groups of all entry points. """ return {ep.group for ep in self} @classmethod def _from_text_for(cls, text, dist): return cls(ep._for(dist) for ep in cls._from_text(text)) @staticmethod def _from_text(text): return ( EntryPoint(name=item.value.name, value=item.value.value, group=item.name) for item in Sectioned.section_pairs(text or '') ) class PackagePath(pathlib.PurePosixPath): """A reference to a path in a package""" def read_text(self, encoding='utf-8'): with self.locate().open(encoding=encoding) as stream: return stream.read() def read_binary(self): with self.locate().open('rb') as stream: return stream.read() def locate(self): """Return a path-like object for this path""" return self.dist.locate_file(self) class FileHash: def __init__(self, spec): self.mode, _, self.value = spec.partition('=') def __repr__(self): return f'<FileHash mode: {self.mode} value: {self.value}>' class DeprecatedNonAbstract: def __new__(cls, *args, **kwargs): all_names = { name for subclass in inspect.getmro(cls) for name in vars(subclass) } abstract = { name for name in all_names if getattr(getattr(cls, name), '__isabstractmethod__', False) } if abstract: warnings.warn( f"Unimplemented abstract methods {abstract}", DeprecationWarning, stacklevel=2, ) return super().__new__(cls) class Distribution(DeprecatedNonAbstract): """A Python distribution package.""" @abc.abstractmethod def read_text(self, filename) -> Optional[str]: """Attempt to load metadata file given by the name. :param filename: The name of the file in the distribution info. :return: The text if found, otherwise None. """ @abc.abstractmethod def locate_file(self, path): """ Given a path to a file in this distribution, return a path to it. """ @classmethod def from_name(cls, name: str): """Return the Distribution for the given package name. :param name: The name of the distribution package to search for. :return: The Distribution instance (or subclass thereof) for the named package, if found. :raises PackageNotFoundError: When the named package's distribution metadata cannot be found. :raises ValueError: When an invalid value is supplied for name. """ if not name: raise ValueError("A distribution name is required.") try: return next(cls.discover(name=name)) except StopIteration: raise PackageNotFoundError(name) @classmethod def discover(cls, **kwargs): """Return an iterable of Distribution objects for all packages. Pass a ``context`` or pass keyword arguments for constructing a context. :context: A ``DistributionFinder.Context`` object. :return: Iterable of Distribution objects for all packages. """ context = kwargs.pop('context', None) if context and kwargs: raise ValueError("cannot accept context and kwargs") context = context or DistributionFinder.Context(**kwargs) return itertools.chain.from_iterable( resolver(context) for resolver in cls._discover_resolvers() ) @staticmethod def at(path): """Return a Distribution for the indicated metadata path :param path: a string or path-like object :return: a concrete Distribution instance for the path """ return PathDistribution(pathlib.Path(path)) @staticmethod def _discover_resolvers(): """Search the meta_path for resolvers.""" declared = ( getattr(finder, 'find_distributions', None) for finder in sys.meta_path ) return filter(None, declared) @property def metadata(self) -> _meta.PackageMetadata: """Return the parsed metadata for this Distribution. The returned object will have keys that name the various bits of metadata. See PEP 566 for details. """ opt_text = ( self.read_text('METADATA') or self.read_text('PKG-INFO') # This last clause is here to support old egg-info files. Its # effect is to just end up using the PathDistribution's self._path # (which points to the egg-info file) attribute unchanged. or self.read_text('') ) text = cast(str, opt_text) return _adapters.Message(email.message_from_string(text)) @property def name(self): """Return the 'Name' metadata for the distribution package.""" return self.metadata['Name'] @property def _normalized_name(self): """Return a normalized version of the name.""" return Prepared.normalize(self.name) @property def version(self): """Return the 'Version' metadata for the distribution package.""" return self.metadata['Version'] @property def entry_points(self): return EntryPoints._from_text_for(self.read_text('entry_points.txt'), self) @property def files(self): """Files in this distribution. :return: List of PackagePath for this distribution or None Result is `None` if the metadata file that enumerates files (i.e. RECORD for dist-info, or installed-files.txt or SOURCES.txt for egg-info) is missing. Result may be empty if the metadata exists but is empty. """ def make_file(name, hash=None, size_str=None): result = PackagePath(name) result.hash = FileHash(hash) if hash else None result.size = int(size_str) if size_str else None result.dist = self return result @pass_none def make_files(lines): return starmap(make_file, csv.reader(lines)) @pass_none def skip_missing_files(package_paths): return list(filter(lambda path: path.locate().exists(), package_paths)) return skip_missing_files( make_files( self._read_files_distinfo() or self._read_files_egginfo_installed() or self._read_files_egginfo_sources() ) ) def _read_files_distinfo(self): """ Read the lines of RECORD """ text = self.read_text('RECORD') return text and text.splitlines() def _read_files_egginfo_installed(self): """ Read installed-files.txt and return lines in a similar CSV-parsable format as RECORD: each file must be placed relative to the site-packages directory and must also be quoted (since file names can contain literal commas). This file is written when the package is installed by pip, but it might not be written for other installation methods. Assume the file is accurate if it exists. """ text = self.read_text('installed-files.txt') # Prepend the .egg-info/ subdir to the lines in this file. # But this subdir is only available from PathDistribution's # self._path. subdir = getattr(self, '_path', None) if not text or not subdir: return paths = ( (subdir / name) .resolve() .relative_to(self.locate_file('').resolve(), walk_up=True) .as_posix() for name in text.splitlines() ) return map('"{}"'.format, paths) def _read_files_egginfo_sources(self): """ Read SOURCES.txt and return lines in a similar CSV-parsable format as RECORD: each file name must be quoted (since it might contain literal commas). Note that SOURCES.txt is not a reliable source for what files are installed by a package. This file is generated for a source archive, and the files that are present there (e.g. setup.py) may not correctly reflect the files that are present after the package has been installed. """ text = self.read_text('SOURCES.txt') return text and map('"{}"'.format, text.splitlines()) @property def requires(self): """Generated requirements specified for this Distribution""" reqs = self._read_dist_info_reqs() or self._read_egg_info_reqs() return reqs and list(reqs) def _read_dist_info_reqs(self): return self.metadata.get_all('Requires-Dist') def _read_egg_info_reqs(self): source = self.read_text('requires.txt') return pass_none(self._deps_from_requires_text)(source) @classmethod def _deps_from_requires_text(cls, source): return cls._convert_egg_info_reqs_to_simple_reqs(Sectioned.read(source)) @staticmethod def _convert_egg_info_reqs_to_simple_reqs(sections): """ Historically, setuptools would solicit and store 'extra' requirements, including those with environment markers, in separate sections. More modern tools expect each dependency to be defined separately, with any relevant extras and environment markers attached directly to that requirement. This method converts the former to the latter. See _test_deps_from_requires_text for an example. """ def make_condition(name): return name and f'extra == "{name}"' def quoted_marker(section): section = section or '' extra, sep, markers = section.partition(':') if extra and markers: markers = f'({markers})' conditions = list(filter(None, [markers, make_condition(extra)])) return '; ' + ' and '.join(conditions) if conditions else '' def url_req_space(req): """ PEP 508 requires a space between the url_spec and the quoted_marker. Ref python/importlib_metadata#357. """ # '@' is uniquely indicative of a url_req. return ' ' * ('@' in req) for section in sections: space = url_req_space(section.value) yield section.value + space + quoted_marker(section.name) class DistributionFinder(MetaPathFinder): """ A MetaPathFinder capable of discovering installed distributions. """ class Context: """ Keyword arguments presented by the caller to ``distributions()`` or ``Distribution.discover()`` to narrow the scope of a search for distributions in all DistributionFinders. Each DistributionFinder may expect any parameters and should attempt to honor the canonical parameters defined below when appropriate. """ name = None """ Specific name for which a distribution finder should match. A name of ``None`` matches all distributions. """ def __init__(self, **kwargs): vars(self).update(kwargs) @property def path(self): """ The sequence of directory path that a distribution finder should search. Typically refers to Python installed package paths such as "site-packages" directories and defaults to ``sys.path``. """ return vars(self).get('path', sys.path) @abc.abstractmethod def find_distributions(self, context=Context()): """ Find distributions. Return an iterable of all Distribution instances capable of loading the metadata for packages matching the ``context``, a DistributionFinder.Context instance. """ class FastPath: """ Micro-optimized class for searching a path for children. >>> FastPath('').children() ['...'] """ @functools.lru_cache() # type: ignore def __new__(cls, root): return super().__new__(cls) def __init__(self, root): self.root = root def joinpath(self, child): return pathlib.Path(self.root, child) def children(self): with suppress(Exception): return os.listdir(self.root or '.') with suppress(Exception): return self.zip_children() return [] def zip_children(self): zip_path = zipfile.Path(self.root) names = zip_path.root.namelist() self.joinpath = zip_path.joinpath return dict.fromkeys(child.split(posixpath.sep, 1)[0] for child in names) def search(self, name): return self.lookup(self.mtime).search(name) @property def mtime(self): with suppress(OSError): return os.stat(self.root).st_mtime self.lookup.cache_clear() @method_cache def lookup(self, mtime): return Lookup(self) class Lookup: def __init__(self, path: FastPath): base = os.path.basename(path.root).lower() base_is_egg = base.endswith(".egg") self.infos = FreezableDefaultDict(list) self.eggs = FreezableDefaultDict(list) for child in path.children(): low = child.lower() if low.endswith((".dist-info", ".egg-info")): # rpartition is faster than splitext and suitable for this purpose. name = low.rpartition(".")[0].partition("-")[0] normalized = Prepared.normalize(name) self.infos[normalized].append(path.joinpath(child)) elif base_is_egg and low == "egg-info": name = base.rpartition(".")[0].partition("-")[0] legacy_normalized = Prepared.legacy_normalize(name) self.eggs[legacy_normalized].append(path.joinpath(child)) self.infos.freeze() self.eggs.freeze() def search(self, prepared): infos = ( self.infos[prepared.normalized] if prepared else itertools.chain.from_iterable(self.infos.values()) ) eggs = ( self.eggs[prepared.legacy_normalized] if prepared else itertools.chain.from_iterable(self.eggs.values()) ) return itertools.chain(infos, eggs) class Prepared: """ A prepared search for metadata on a possibly-named package. """ normalized = None legacy_normalized = None def __init__(self, name): self.name = name if name is None: return self.normalized = self.normalize(name) self.legacy_normalized = self.legacy_normalize(name) @staticmethod def normalize(name): """ PEP 503 normalization plus dashes as underscores. """ return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_') @staticmethod def legacy_normalize(name): """ Normalize the package name as found in the convention in older packaging tools versions and specs. """ return name.lower().replace('-', '_') def __bool__(self): return bool(self.name) class MetadataPathFinder(DistributionFinder): @classmethod def find_distributions(cls, context=DistributionFinder.Context()): """ Find distributions. Return an iterable of all Distribution instances capable of loading the metadata for packages matching ``context.name`` (or all names if ``None`` indicated) along the paths in the list of directories ``context.path``. """ found = cls._search_paths(context.name, context.path) return map(PathDistribution, found) @classmethod def _search_paths(cls, name, paths): """Find metadata directories in paths heuristically.""" prepared = Prepared(name) return itertools.chain.from_iterable( path.search(prepared) for path in map(FastPath, paths) ) @classmethod def invalidate_caches(cls): FastPath.__new__.cache_clear() class PathDistribution(Distribution): def __init__(self, path: SimplePath): """Construct a distribution. :param path: SimplePath indicating the metadata directory. """ self._path = path def read_text(self, filename): with suppress( FileNotFoundError, IsADirectoryError, KeyError, NotADirectoryError, PermissionError, ): return self._path.joinpath(filename).read_text(encoding='utf-8') read_text.__doc__ = Distribution.read_text.__doc__ def locate_file(self, path): return self._path.parent / path @property def _normalized_name(self): """ Performance optimization: where possible, resolve the normalized name from the file system path. """ stem = os.path.basename(str(self._path)) return ( pass_none(Prepared.normalize)(self._name_from_stem(stem)) or super()._normalized_name ) @staticmethod def _name_from_stem(stem): """ >>> PathDistribution._name_from_stem('foo-3.0.egg-info') 'foo' >>> PathDistribution._name_from_stem('CherryPy-3.0.dist-info') 'CherryPy' >>> PathDistribution._name_from_stem('face.egg-info') 'face' >>> PathDistribution._name_from_stem('foo.bar') """ filename, ext = os.path.splitext(stem) if ext not in ('.dist-info', '.egg-info'): return name, sep, rest = filename.partition('-') return name def distribution(distribution_name): """Get the ``Distribution`` instance for the named package. :param distribution_name: The name of the distribution package as a string. :return: A ``Distribution`` instance (or subclass thereof). """ return Distribution.from_name(distribution_name) def distributions(**kwargs): """Get all ``Distribution`` instances in the current environment. :return: An iterable of ``Distribution`` instances. """ return Distribution.discover(**kwargs) def metadata(distribution_name) -> _meta.PackageMetadata: """Get the metadata for the named package. :param distribution_name: The name of the distribution package to query. :return: A PackageMetadata containing the parsed metadata. """ return Distribution.from_name(distribution_name).metadata def version(distribution_name): """Get the version string for the named package. :param distribution_name: The name of the distribution package to query. :return: The version string for the package as defined in the package's "Version" metadata key. """ return distribution(distribution_name).version _unique = functools.partial( unique_everseen, key=operator.attrgetter('_normalized_name'), ) """ Wrapper for ``distributions`` to return unique distributions by name. """ def entry_points(**params) -> EntryPoints: """Return EntryPoint objects for all installed packages. Pass selection parameters (group or name) to filter the result to entry points matching those properties (see EntryPoints.select()). :return: EntryPoints for all installed packages. """ eps = itertools.chain.from_iterable( dist.entry_points for dist in _unique(distributions()) ) return EntryPoints(eps).select(**params) def files(distribution_name): """Return a list of files for the named package. :param distribution_name: The name of the distribution package to query. :return: List of files composing the distribution. """ return distribution(distribution_name).files def requires(distribution_name): """ Return a list of requirements for the named package. :return: An iterator of requirements, suitable for packaging.requirement.Requirement. """ return distribution(distribution_name).requires def packages_distributions() -> Mapping[str, List[str]]: """ Return a mapping of top-level packages to their distributions. >>> import collections.abc >>> pkgs = packages_distributions() >>> all(isinstance(dist, collections.abc.Sequence) for dist in pkgs.values()) True """ pkg_to_dist = collections.defaultdict(list) for dist in distributions(): for pkg in _top_level_declared(dist) or _top_level_inferred(dist): pkg_to_dist[pkg].append(dist.metadata['Name']) return dict(pkg_to_dist) def _top_level_declared(dist): return (dist.read_text('top_level.txt') or '').split() def _top_level_inferred(dist): opt_names = { f.parts[0] if len(f.parts) > 1 else inspect.getmodulename(f) for f in always_iterable(dist.files) } @pass_none def importable_name(name): return '.' not in name return filter(importable_name, opt_names) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib64/python3.6/test/support/__init__.py��������������������������������������������������������0000644�����������������00000311635�15253664504�0014674 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""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, '<test string>', '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'<FakePath {self.path!r}>' 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.12/turtledemo/__init__.py���������������������������������������������������������0000644�����������������00000000472�15253664506�0014436 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������""" -------------------------------------- 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! """ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/importlib/metadata/__init__.py�����������������������������������0000644�����������������00000074605�15253665564�0020367 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������import os import re import abc import csv import sys import email import pathlib import zipfile import operator import textwrap import warnings import functools import itertools import posixpath import collections from . import _adapters, _meta from ._collections import FreezableDefaultDict, Pair from ._functools import method_cache, pass_none from ._itertools import always_iterable, unique_everseen from ._meta import PackageMetadata, SimplePath from contextlib import suppress from importlib import import_module from importlib.abc import MetaPathFinder from itertools import starmap from typing import List, Mapping, Optional, Union __all__ = [ 'Distribution', 'DistributionFinder', 'PackageMetadata', 'PackageNotFoundError', 'distribution', 'distributions', 'entry_points', 'files', 'metadata', 'packages_distributions', 'requires', 'version', ] class PackageNotFoundError(ModuleNotFoundError): """The package was not found.""" def __str__(self): return f"No package metadata was found for {self.name}" @property def name(self): (name,) = self.args return name class Sectioned: """ A simple entry point config parser for performance >>> for item in Sectioned.read(Sectioned._sample): ... print(item) Pair(name='sec1', value='# comments ignored') Pair(name='sec1', value='a = 1') Pair(name='sec1', value='b = 2') Pair(name='sec2', value='a = 2') >>> res = Sectioned.section_pairs(Sectioned._sample) >>> item = next(res) >>> item.name 'sec1' >>> item.value Pair(name='a', value='1') >>> item = next(res) >>> item.value Pair(name='b', value='2') >>> item = next(res) >>> item.name 'sec2' >>> item.value Pair(name='a', value='2') >>> list(res) [] """ _sample = textwrap.dedent( """ [sec1] # comments ignored a = 1 b = 2 [sec2] a = 2 """ ).lstrip() @classmethod def section_pairs(cls, text): return ( section._replace(value=Pair.parse(section.value)) for section in cls.read(text, filter_=cls.valid) if section.name is not None ) @staticmethod def read(text, filter_=None): lines = filter(filter_, map(str.strip, text.splitlines())) name = None for value in lines: section_match = value.startswith('[') and value.endswith(']') if section_match: name = value.strip('[]') continue yield Pair(name, value) @staticmethod def valid(line): return line and not line.startswith('#') class DeprecatedTuple: """ Provide subscript item access for backward compatibility. >>> recwarn = getfixture('recwarn') >>> ep = EntryPoint(name='name', value='value', group='group') >>> ep[:] ('name', 'value', 'group') >>> ep[0] 'name' >>> len(recwarn) 1 """ _warn = functools.partial( warnings.warn, "EntryPoint tuple interface is deprecated. Access members by name.", DeprecationWarning, stacklevel=2, ) def __getitem__(self, item): self._warn() return self._key()[item] class EntryPoint(DeprecatedTuple): """An entry point as defined by Python packaging conventions. See `the packaging docs on entry points <https://packaging.python.org/specifications/entry-points/>`_ for more information. >>> ep = EntryPoint( ... name=None, group=None, value='package.module:attr [extra1, extra2]') >>> ep.module 'package.module' >>> ep.attr 'attr' >>> ep.extras ['extra1', 'extra2'] """ pattern = re.compile( r'(?P<module>[\w.]+)\s*' r'(:\s*(?P<attr>[\w.]+)\s*)?' r'((?P<extras>\[.*\])\s*)?$' ) """ A regular expression describing the syntax for an entry point, which might look like: - module - package.module - package.module:attribute - package.module:object.attribute - package.module:attr [extra1, extra2] Other combinations are possible as well. The expression is lenient about whitespace around the ':', following the attr, and following any extras. """ name: str value: str group: str dist: Optional['Distribution'] = None def __init__(self, name, value, group): vars(self).update(name=name, value=value, group=group) def load(self): """Load the entry point from its definition. If only a module is indicated by the value, return that module. Otherwise, return the named object. """ match = self.pattern.match(self.value) module = import_module(match.group('module')) attrs = filter(None, (match.group('attr') or '').split('.')) return functools.reduce(getattr, attrs, module) @property def module(self): match = self.pattern.match(self.value) return match.group('module') @property def attr(self): match = self.pattern.match(self.value) return match.group('attr') @property def extras(self): match = self.pattern.match(self.value) return re.findall(r'\w+', match.group('extras') or '') def _for(self, dist): vars(self).update(dist=dist) return self def __iter__(self): """ Supply iter so one may construct dicts of EntryPoints by name. """ msg = ( "Construction of dict of EntryPoints is deprecated in " "favor of EntryPoints." ) warnings.warn(msg, DeprecationWarning) return iter((self.name, self)) def matches(self, **params): """ EntryPoint matches the given parameters. >>> ep = EntryPoint(group='foo', name='bar', value='bing:bong [extra1, extra2]') >>> ep.matches(group='foo') True >>> ep.matches(name='bar', value='bing:bong [extra1, extra2]') True >>> ep.matches(group='foo', name='other') False >>> ep.matches() True >>> ep.matches(extras=['extra1', 'extra2']) True >>> ep.matches(module='bing') True >>> ep.matches(attr='bong') True """ attrs = (getattr(self, param) for param in params) return all(map(operator.eq, params.values(), attrs)) def _key(self): return self.name, self.value, self.group def __lt__(self, other): return self._key() < other._key() def __eq__(self, other): return self._key() == other._key() def __setattr__(self, name, value): raise AttributeError("EntryPoint objects are immutable.") def __repr__(self): return ( f'EntryPoint(name={self.name!r}, value={self.value!r}, ' f'group={self.group!r})' ) def __hash__(self): return hash(self._key()) class DeprecatedList(list): """ Allow an otherwise immutable object to implement mutability for compatibility. >>> recwarn = getfixture('recwarn') >>> dl = DeprecatedList(range(3)) >>> dl[0] = 1 >>> dl.append(3) >>> del dl[3] >>> dl.reverse() >>> dl.sort() >>> dl.extend([4]) >>> dl.pop(-1) 4 >>> dl.remove(1) >>> dl += [5] >>> dl + [6] [1, 2, 5, 6] >>> dl + (6,) [1, 2, 5, 6] >>> dl.insert(0, 0) >>> dl [0, 1, 2, 5] >>> dl == [0, 1, 2, 5] True >>> dl == (0, 1, 2, 5) True >>> len(recwarn) 1 """ __slots__ = () _warn = functools.partial( warnings.warn, "EntryPoints list interface is deprecated. Cast to list if needed.", DeprecationWarning, stacklevel=2, ) def _wrap_deprecated_method(method_name: str): # type: ignore def wrapped(self, *args, **kwargs): self._warn() return getattr(super(), method_name)(*args, **kwargs) return method_name, wrapped locals().update( map( _wrap_deprecated_method, '__setitem__ __delitem__ append reverse extend pop remove ' '__iadd__ insert sort'.split(), ) ) def __add__(self, other): if not isinstance(other, tuple): self._warn() other = tuple(other) return self.__class__(tuple(self) + other) def __eq__(self, other): if not isinstance(other, tuple): self._warn() other = tuple(other) return tuple(self).__eq__(other) class EntryPoints(DeprecatedList): """ An immutable collection of selectable EntryPoint objects. """ __slots__ = () def __getitem__(self, name): # -> EntryPoint: """ Get the EntryPoint in self matching name. """ if isinstance(name, int): warnings.warn( "Accessing entry points by index is deprecated. " "Cast to tuple if needed.", DeprecationWarning, stacklevel=2, ) return super().__getitem__(name) try: return next(iter(self.select(name=name))) except StopIteration: raise KeyError(name) def select(self, **params): """ Select entry points from self that match the given parameters (typically group and/or name). """ return EntryPoints(ep for ep in self if ep.matches(**params)) @property def names(self): """ Return the set of all names of all entry points. """ return {ep.name for ep in self} @property def groups(self): """ Return the set of all groups of all entry points. For coverage while SelectableGroups is present. >>> EntryPoints().groups set() """ return {ep.group for ep in self} @classmethod def _from_text_for(cls, text, dist): return cls(ep._for(dist) for ep in cls._from_text(text)) @staticmethod def _from_text(text): return ( EntryPoint(name=item.value.name, value=item.value.value, group=item.name) for item in Sectioned.section_pairs(text or '') ) class Deprecated: """ Compatibility add-in for mapping to indicate that mapping behavior is deprecated. >>> recwarn = getfixture('recwarn') >>> class DeprecatedDict(Deprecated, dict): pass >>> dd = DeprecatedDict(foo='bar') >>> dd.get('baz', None) >>> dd['foo'] 'bar' >>> list(dd) ['foo'] >>> list(dd.keys()) ['foo'] >>> 'foo' in dd True >>> list(dd.values()) ['bar'] >>> len(recwarn) 1 """ _warn = functools.partial( warnings.warn, "SelectableGroups dict interface is deprecated. Use select.", DeprecationWarning, stacklevel=2, ) def __getitem__(self, name): self._warn() return super().__getitem__(name) def get(self, name, default=None): self._warn() return super().get(name, default) def __iter__(self): self._warn() return super().__iter__() def __contains__(self, *args): self._warn() return super().__contains__(*args) def keys(self): self._warn() return super().keys() def values(self): self._warn() return super().values() class SelectableGroups(Deprecated, dict): """ A backward- and forward-compatible result from entry_points that fully implements the dict interface. """ @classmethod def load(cls, eps): by_group = operator.attrgetter('group') ordered = sorted(eps, key=by_group) grouped = itertools.groupby(ordered, by_group) return cls((group, EntryPoints(eps)) for group, eps in grouped) @property def _all(self): """ Reconstruct a list of all entrypoints from the groups. """ groups = super(Deprecated, self).values() return EntryPoints(itertools.chain.from_iterable(groups)) @property def groups(self): return self._all.groups @property def names(self): """ for coverage: >>> SelectableGroups().names set() """ return self._all.names def select(self, **params): if not params: return self return self._all.select(**params) class PackagePath(pathlib.PurePosixPath): """A reference to a path in a package""" def read_text(self, encoding='utf-8'): with self.locate().open(encoding=encoding) as stream: return stream.read() def read_binary(self): with self.locate().open('rb') as stream: return stream.read() def locate(self): """Return a path-like object for this path""" return self.dist.locate_file(self) class FileHash: def __init__(self, spec): self.mode, _, self.value = spec.partition('=') def __repr__(self): return f'<FileHash mode: {self.mode} value: {self.value}>' class Distribution: """A Python distribution package.""" @abc.abstractmethod def read_text(self, filename): """Attempt to load metadata file given by the name. :param filename: The name of the file in the distribution info. :return: The text if found, otherwise None. """ @abc.abstractmethod def locate_file(self, path): """ Given a path to a file in this distribution, return a path to it. """ @classmethod def from_name(cls, name: str): """Return the Distribution for the given package name. :param name: The name of the distribution package to search for. :return: The Distribution instance (or subclass thereof) for the named package, if found. :raises PackageNotFoundError: When the named package's distribution metadata cannot be found. :raises ValueError: When an invalid value is supplied for name. """ if not name: raise ValueError("A distribution name is required.") try: return next(cls.discover(name=name)) except StopIteration: raise PackageNotFoundError(name) @classmethod def discover(cls, **kwargs): """Return an iterable of Distribution objects for all packages. Pass a ``context`` or pass keyword arguments for constructing a context. :context: A ``DistributionFinder.Context`` object. :return: Iterable of Distribution objects for all packages. """ context = kwargs.pop('context', None) if context and kwargs: raise ValueError("cannot accept context and kwargs") context = context or DistributionFinder.Context(**kwargs) return itertools.chain.from_iterable( resolver(context) for resolver in cls._discover_resolvers() ) @staticmethod def at(path): """Return a Distribution for the indicated metadata path :param path: a string or path-like object :return: a concrete Distribution instance for the path """ return PathDistribution(pathlib.Path(path)) @staticmethod def _discover_resolvers(): """Search the meta_path for resolvers.""" declared = ( getattr(finder, 'find_distributions', None) for finder in sys.meta_path ) return filter(None, declared) @property def metadata(self) -> _meta.PackageMetadata: """Return the parsed metadata for this Distribution. The returned object will have keys that name the various bits of metadata. See PEP 566 for details. """ text = ( self.read_text('METADATA') or self.read_text('PKG-INFO') # This last clause is here to support old egg-info files. Its # effect is to just end up using the PathDistribution's self._path # (which points to the egg-info file) attribute unchanged. or self.read_text('') ) return _adapters.Message(email.message_from_string(text)) @property def name(self): """Return the 'Name' metadata for the distribution package.""" return self.metadata['Name'] @property def _normalized_name(self): """Return a normalized version of the name.""" return Prepared.normalize(self.name) @property def version(self): """Return the 'Version' metadata for the distribution package.""" return self.metadata['Version'] @property def entry_points(self): return EntryPoints._from_text_for(self.read_text('entry_points.txt'), self) @property def files(self): """Files in this distribution. :return: List of PackagePath for this distribution or None Result is `None` if the metadata file that enumerates files (i.e. RECORD for dist-info or SOURCES.txt for egg-info) is missing. Result may be empty if the metadata exists but is empty. """ def make_file(name, hash=None, size_str=None): result = PackagePath(name) result.hash = FileHash(hash) if hash else None result.size = int(size_str) if size_str else None result.dist = self return result @pass_none def make_files(lines): return list(starmap(make_file, csv.reader(lines))) return make_files(self._read_files_distinfo() or self._read_files_egginfo()) def _read_files_distinfo(self): """ Read the lines of RECORD """ text = self.read_text('RECORD') return text and text.splitlines() def _read_files_egginfo(self): """ SOURCES.txt might contain literal commas, so wrap each line in quotes. """ text = self.read_text('SOURCES.txt') return text and map('"{}"'.format, text.splitlines()) @property def requires(self): """Generated requirements specified for this Distribution""" reqs = self._read_dist_info_reqs() or self._read_egg_info_reqs() return reqs and list(reqs) def _read_dist_info_reqs(self): return self.metadata.get_all('Requires-Dist') def _read_egg_info_reqs(self): source = self.read_text('requires.txt') return pass_none(self._deps_from_requires_text)(source) @classmethod def _deps_from_requires_text(cls, source): return cls._convert_egg_info_reqs_to_simple_reqs(Sectioned.read(source)) @staticmethod def _convert_egg_info_reqs_to_simple_reqs(sections): """ Historically, setuptools would solicit and store 'extra' requirements, including those with environment markers, in separate sections. More modern tools expect each dependency to be defined separately, with any relevant extras and environment markers attached directly to that requirement. This method converts the former to the latter. See _test_deps_from_requires_text for an example. """ def make_condition(name): return name and f'extra == "{name}"' def quoted_marker(section): section = section or '' extra, sep, markers = section.partition(':') if extra and markers: markers = f'({markers})' conditions = list(filter(None, [markers, make_condition(extra)])) return '; ' + ' and '.join(conditions) if conditions else '' def url_req_space(req): """ PEP 508 requires a space between the url_spec and the quoted_marker. Ref python/importlib_metadata#357. """ # '@' is uniquely indicative of a url_req. return ' ' * ('@' in req) for section in sections: space = url_req_space(section.value) yield section.value + space + quoted_marker(section.name) class DistributionFinder(MetaPathFinder): """ A MetaPathFinder capable of discovering installed distributions. """ class Context: """ Keyword arguments presented by the caller to ``distributions()`` or ``Distribution.discover()`` to narrow the scope of a search for distributions in all DistributionFinders. Each DistributionFinder may expect any parameters and should attempt to honor the canonical parameters defined below when appropriate. """ name = None """ Specific name for which a distribution finder should match. A name of ``None`` matches all distributions. """ def __init__(self, **kwargs): vars(self).update(kwargs) @property def path(self): """ The sequence of directory path that a distribution finder should search. Typically refers to Python installed package paths such as "site-packages" directories and defaults to ``sys.path``. """ return vars(self).get('path', sys.path) @abc.abstractmethod def find_distributions(self, context=Context()): """ Find distributions. Return an iterable of all Distribution instances capable of loading the metadata for packages matching the ``context``, a DistributionFinder.Context instance. """ class FastPath: """ Micro-optimized class for searching a path for children. >>> FastPath('').children() ['...'] """ @functools.lru_cache() # type: ignore def __new__(cls, root): return super().__new__(cls) def __init__(self, root): self.root = root def joinpath(self, child): return pathlib.Path(self.root, child) def children(self): with suppress(Exception): return os.listdir(self.root or '.') with suppress(Exception): return self.zip_children() return [] def zip_children(self): zip_path = zipfile.Path(self.root) names = zip_path.root.namelist() self.joinpath = zip_path.joinpath return dict.fromkeys(child.split(posixpath.sep, 1)[0] for child in names) def search(self, name): return self.lookup(self.mtime).search(name) @property def mtime(self): with suppress(OSError): return os.stat(self.root).st_mtime self.lookup.cache_clear() @method_cache def lookup(self, mtime): return Lookup(self) class Lookup: def __init__(self, path: FastPath): base = os.path.basename(path.root).lower() base_is_egg = base.endswith(".egg") self.infos = FreezableDefaultDict(list) self.eggs = FreezableDefaultDict(list) for child in path.children(): low = child.lower() if low.endswith((".dist-info", ".egg-info")): # rpartition is faster than splitext and suitable for this purpose. name = low.rpartition(".")[0].partition("-")[0] normalized = Prepared.normalize(name) self.infos[normalized].append(path.joinpath(child)) elif base_is_egg and low == "egg-info": name = base.rpartition(".")[0].partition("-")[0] legacy_normalized = Prepared.legacy_normalize(name) self.eggs[legacy_normalized].append(path.joinpath(child)) self.infos.freeze() self.eggs.freeze() def search(self, prepared): infos = ( self.infos[prepared.normalized] if prepared else itertools.chain.from_iterable(self.infos.values()) ) eggs = ( self.eggs[prepared.legacy_normalized] if prepared else itertools.chain.from_iterable(self.eggs.values()) ) return itertools.chain(infos, eggs) class Prepared: """ A prepared search for metadata on a possibly-named package. """ normalized = None legacy_normalized = None def __init__(self, name): self.name = name if name is None: return self.normalized = self.normalize(name) self.legacy_normalized = self.legacy_normalize(name) @staticmethod def normalize(name): """ PEP 503 normalization plus dashes as underscores. """ return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_') @staticmethod def legacy_normalize(name): """ Normalize the package name as found in the convention in older packaging tools versions and specs. """ return name.lower().replace('-', '_') def __bool__(self): return bool(self.name) class MetadataPathFinder(DistributionFinder): @classmethod def find_distributions(cls, context=DistributionFinder.Context()): """ Find distributions. Return an iterable of all Distribution instances capable of loading the metadata for packages matching ``context.name`` (or all names if ``None`` indicated) along the paths in the list of directories ``context.path``. """ found = cls._search_paths(context.name, context.path) return map(PathDistribution, found) @classmethod def _search_paths(cls, name, paths): """Find metadata directories in paths heuristically.""" prepared = Prepared(name) return itertools.chain.from_iterable( path.search(prepared) for path in map(FastPath, paths) ) @classmethod def invalidate_caches(cls): FastPath.__new__.cache_clear() class PathDistribution(Distribution): def __init__(self, path: SimplePath): """Construct a distribution. :param path: SimplePath indicating the metadata directory. """ self._path = path def read_text(self, filename): with suppress( FileNotFoundError, IsADirectoryError, KeyError, NotADirectoryError, PermissionError, ): return self._path.joinpath(filename).read_text(encoding='utf-8') read_text.__doc__ = Distribution.read_text.__doc__ def locate_file(self, path): return self._path.parent / path @property def _normalized_name(self): """ Performance optimization: where possible, resolve the normalized name from the file system path. """ stem = os.path.basename(str(self._path)) return ( pass_none(Prepared.normalize)(self._name_from_stem(stem)) or super()._normalized_name ) @staticmethod def _name_from_stem(stem): """ >>> PathDistribution._name_from_stem('foo-3.0.egg-info') 'foo' >>> PathDistribution._name_from_stem('CherryPy-3.0.dist-info') 'CherryPy' >>> PathDistribution._name_from_stem('face.egg-info') 'face' >>> PathDistribution._name_from_stem('foo.bar') """ filename, ext = os.path.splitext(stem) if ext not in ('.dist-info', '.egg-info'): return name, sep, rest = filename.partition('-') return name def distribution(distribution_name): """Get the ``Distribution`` instance for the named package. :param distribution_name: The name of the distribution package as a string. :return: A ``Distribution`` instance (or subclass thereof). """ return Distribution.from_name(distribution_name) def distributions(**kwargs): """Get all ``Distribution`` instances in the current environment. :return: An iterable of ``Distribution`` instances. """ return Distribution.discover(**kwargs) def metadata(distribution_name) -> _meta.PackageMetadata: """Get the metadata for the named package. :param distribution_name: The name of the distribution package to query. :return: A PackageMetadata containing the parsed metadata. """ return Distribution.from_name(distribution_name).metadata def version(distribution_name): """Get the version string for the named package. :param distribution_name: The name of the distribution package to query. :return: The version string for the package as defined in the package's "Version" metadata key. """ return distribution(distribution_name).version _unique = functools.partial( unique_everseen, key=operator.attrgetter('_normalized_name'), ) """ Wrapper for ``distributions`` to return unique distributions by name. """ def entry_points(**params) -> Union[EntryPoints, SelectableGroups]: """Return EntryPoint objects for all installed packages. Pass selection parameters (group or name) to filter the result to entry points matching those properties (see EntryPoints.select()). For compatibility, returns ``SelectableGroups`` object unless selection parameters are supplied. In the future, this function will return ``EntryPoints`` instead of ``SelectableGroups`` even when no selection parameters are supplied. For maximum future compatibility, pass selection parameters or invoke ``.select`` with parameters on the result. :return: EntryPoints or SelectableGroups for all installed packages. """ eps = itertools.chain.from_iterable( dist.entry_points for dist in _unique(distributions()) ) return SelectableGroups.load(eps).select(**params) def files(distribution_name): """Return a list of files for the named package. :param distribution_name: The name of the distribution package to query. :return: List of files composing the distribution. """ return distribution(distribution_name).files def requires(distribution_name): """ Return a list of requirements for the named package. :return: An iterator of requirements, suitable for packaging.requirement.Requirement. """ return distribution(distribution_name).requires def packages_distributions() -> Mapping[str, List[str]]: """ Return a mapping of top-level packages to their distributions. >>> import collections.abc >>> pkgs = packages_distributions() >>> all(isinstance(dist, collections.abc.Sequence) for dist in pkgs.values()) True """ pkg_to_dist = collections.defaultdict(list) for dist in distributions(): for pkg in _top_level_declared(dist) or _top_level_inferred(dist): pkg_to_dist[pkg].append(dist.metadata['Name']) return dict(pkg_to_dist) def _top_level_declared(dist): return (dist.read_text('top_level.txt') or '').split() def _top_level_inferred(dist): return { f.parts[0] if len(f.parts) > 1 else f.with_suffix('').name for f in always_iterable(dist.files) if f.suffix == ".py" } ���������������������������������������������������������������������������������������������������������������������������usr/lib64/python2.7/xml/sax/__init__.py�������������������������������������������������������������0000644�����������������00000007042�15253674655�0013576 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"""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/lib/python3.6/site-packages/pyudev/__init__.py��������������������������������������������������0000644�����������������00000004676�15253700006�0016053 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# -*- coding: utf-8 -*- # Copyright (C) 2010, 2011, 2012 Sebastian Wiesner <lunaryorn@gmail.com> # 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 <lunaryorn@gmail.com> """ 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/lib/python3.6/site-packages/sepolicy/templates/__init__.py��������������������������������������0000644�����������������00000001324�15253702310�0020347 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2007-2012 Red Hat # # 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., 675 Mass Ave, Cambridge, MA 02139, USA. # ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python-internal/lib64/python3.11/lib2to3/pgen2/__init__.py����������������������������������0000644�����������������00000000217�15253704076�0020440 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright 2004-2005 Elemental Security, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement. """The pgen2 package.""" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������opt/alt/python311/lib64/python3.11/collections/__init__.py������������������������������������������0000644�����������������00000145462�15253705620�0017110 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������'''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 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__, list(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._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().__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 reversed(self.maps): d.update(dict.fromkeys(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__ 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 __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)) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������usr/lib/python3.6/site-packages/bs4/tests/__init__.py�����������������������������������������������0000644�����������������00000000033�15253712525�0016361 0����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"The beautifulsoup tests." ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������