ÿØÿà JFIF    ÿÛ „ ( %!1!%*+...983,7(-.- sre_compile.py000064400000000347152342670510007430 0ustar00import warnings warnings.warn(f"module {__name__!r} is deprecated", DeprecationWarning, stacklevel=2) from re import _compiler as _ globals().update({k: v for k, v in vars(_).items() if k[:2] != '__'}) typing.py000064400000350064152342670510006445 0ustar00""" The typing module: Support for gradual typing as defined by PEP 484 and subsequent PEPs. Among other things, the module includes the following: * Generic, Protocol, and internal machinery to support generic aliases. All subscripted types like X[int], Union[int, str] are generic aliases. * Various "special forms" that have unique meanings in type annotations: NoReturn, Never, ClassVar, Self, Concatenate, Unpack, and others. * Classes whose instances can be type arguments to generic classes and functions: TypeVar, ParamSpec, TypeVarTuple. * Public helper functions: get_type_hints, overload, cast, final, and others. * Several protocols to support duck-typing: SupportsFloat, SupportsIndex, SupportsAbs, and others. * Special types: NewType, NamedTuple, TypedDict. * Deprecated wrapper submodules for re and io related types. * Deprecated aliases for builtin types and collections.abc ABCs. Any name not present in __all__ is an implementation detail that may be changed without notice. Use at your own risk! """ from abc import abstractmethod, ABCMeta import collections from collections import defaultdict import collections.abc import copyreg import contextlib import functools import operator import re as stdlib_re # Avoid confusion with the re we export. import sys import types import warnings from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias from _typing import ( _idfunc, TypeVar, ParamSpec, TypeVarTuple, ParamSpecArgs, ParamSpecKwargs, TypeAliasType, Generic, ) # Please keep __all__ alphabetized within each category. __all__ = [ # Super-special typing primitives. 'Annotated', 'Any', 'Callable', 'ClassVar', 'Concatenate', 'Final', 'ForwardRef', 'Generic', 'Literal', 'Optional', 'ParamSpec', 'Protocol', 'Tuple', 'Type', 'TypeVar', 'TypeVarTuple', 'Union', # ABCs (from collections.abc). 'AbstractSet', # collections.abc.Set. 'ByteString', 'Container', 'ContextManager', 'Hashable', 'ItemsView', 'Iterable', 'Iterator', 'KeysView', 'Mapping', 'MappingView', 'MutableMapping', 'MutableSequence', 'MutableSet', 'Sequence', 'Sized', 'ValuesView', 'Awaitable', 'AsyncIterator', 'AsyncIterable', 'Coroutine', 'Collection', 'AsyncGenerator', 'AsyncContextManager', # Structural checks, a.k.a. protocols. 'Reversible', 'SupportsAbs', 'SupportsBytes', 'SupportsComplex', 'SupportsFloat', 'SupportsIndex', 'SupportsInt', 'SupportsRound', # Concrete collection types. 'ChainMap', 'Counter', 'Deque', 'Dict', 'DefaultDict', 'List', 'OrderedDict', 'Set', 'FrozenSet', 'NamedTuple', # Not really a type. 'TypedDict', # Not really a type. 'Generator', # Other concrete types. 'BinaryIO', 'IO', 'Match', 'Pattern', 'TextIO', # One-off things. 'AnyStr', 'assert_type', 'assert_never', 'cast', 'clear_overloads', 'dataclass_transform', 'final', 'get_args', 'get_origin', 'get_overloads', 'get_type_hints', 'is_typeddict', 'LiteralString', 'Never', 'NewType', 'no_type_check', 'no_type_check_decorator', 'NoReturn', 'NotRequired', 'overload', 'override', 'ParamSpecArgs', 'ParamSpecKwargs', 'Required', 'reveal_type', 'runtime_checkable', 'Self', 'Text', 'TYPE_CHECKING', 'TypeAlias', 'TypeGuard', 'TypeAliasType', 'Unpack', ] # The pseudo-submodules 're' and 'io' are part of the public # namespace, but excluded from __all__ because they might stomp on # legitimate imports of those modules. def _type_convert(arg, module=None, *, allow_special_forms=False): """For converting None to type(None), and strings to ForwardRef.""" if arg is None: return type(None) if isinstance(arg, str): return ForwardRef(arg, module=module, is_class=allow_special_forms) return arg def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms=False): """Check that the argument is a type, and return it (internal helper). As a special case, accept None and return type(None) instead. Also wrap strings into ForwardRef instances. Consider several corner cases, for example plain special forms like Union are not valid, while Union[int, str] is OK, etc. The msg argument is a human-readable error message, e.g.:: "Union[arg, ...]: arg should be a type." We append the repr() of the actual value (truncated to 100 chars). """ invalid_generic_forms = (Generic, Protocol) if not allow_special_forms: invalid_generic_forms += (ClassVar,) if is_argument: invalid_generic_forms += (Final,) arg = _type_convert(arg, module=module, allow_special_forms=allow_special_forms) if (isinstance(arg, _GenericAlias) and arg.__origin__ in invalid_generic_forms): raise TypeError(f"{arg} is not valid as type argument") if arg in (Any, LiteralString, NoReturn, Never, Self, TypeAlias): return arg if allow_special_forms and arg in (ClassVar, Final): return arg if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): raise TypeError(f"Plain {arg} is not valid as type argument") if type(arg) is tuple: raise TypeError(f"{msg} Got {arg!r:.100}.") return arg def _is_param_expr(arg): return arg is ... or isinstance(arg, (tuple, list, ParamSpec, _ConcatenateGenericAlias)) def _should_unflatten_callable_args(typ, args): """Internal helper for munging collections.abc.Callable's __args__. The canonical representation for a Callable's __args__ flattens the argument types, see https://github.com/python/cpython/issues/86361. For example:: >>> import collections.abc >>> P = ParamSpec('P') >>> collections.abc.Callable[[int, int], str].__args__ == (int, int, str) True >>> collections.abc.Callable[P, str].__args__ == (P, str) True As a result, if we need to reconstruct the Callable from its __args__, we need to unflatten it. """ return ( typ.__origin__ is collections.abc.Callable and not (len(args) == 2 and _is_param_expr(args[0])) ) def _type_repr(obj): """Return the repr() of an object, special-casing types (internal helper). If obj is a type, we return a shorter version than the default type.__repr__, based on the module and qualified name, which is typically enough to uniquely identify a type. For everything else, we fall back on repr(obj). """ # When changing this function, don't forget about # `_collections_abc._type_repr`, which does the same thing # and must be consistent with this one. if isinstance(obj, type): if obj.__module__ == 'builtins': return obj.__qualname__ return f'{obj.__module__}.{obj.__qualname__}' if obj is ...: return '...' if isinstance(obj, types.FunctionType): return obj.__name__ if isinstance(obj, tuple): # Special case for `repr` of types with `ParamSpec`: return '[' + ', '.join(_type_repr(t) for t in obj) + ']' return repr(obj) def _collect_parameters(args): """Collect all type variables and parameter specifications in args in order of first appearance (lexicographic order). For example:: >>> P = ParamSpec('P') >>> T = TypeVar('T') >>> _collect_parameters((T, Callable[P, T])) (~T, ~P) """ parameters = [] for t in args: if isinstance(t, type): # We don't want __parameters__ descriptor of a bare Python class. pass elif isinstance(t, tuple): # `t` might be a tuple, when `ParamSpec` is substituted with # `[T, int]`, or `[int, *Ts]`, etc. for x in t: for collected in _collect_parameters([x]): if collected not in parameters: parameters.append(collected) elif hasattr(t, '__typing_subst__'): if t not in parameters: parameters.append(t) else: for x in getattr(t, '__parameters__', ()): if x not in parameters: parameters.append(x) return tuple(parameters) def _check_generic(cls, parameters, elen): """Check correct count for parameters of a generic cls (internal helper). This gives a nice error message in case of count mismatch. """ if not elen: raise TypeError(f"{cls} is not a generic class") alen = len(parameters) if alen != elen: raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};" f" actual {alen}, expected {elen}") def _unpack_args(args): newargs = [] for arg in args: subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) if subargs is not None and not (subargs and subargs[-1] is ...): newargs.extend(subargs) else: newargs.append(arg) return newargs def _deduplicate(params, *, unhashable_fallback=False): # Weed out strict duplicates, preserving the first of each occurrence. try: return dict.fromkeys(params) except TypeError: if not unhashable_fallback: raise # Happens for cases like `Annotated[dict, {'x': IntValidator()}]` return _deduplicate_unhashable(params) def _deduplicate_unhashable(unhashable_params): new_unhashable = [] for t in unhashable_params: if t not in new_unhashable: new_unhashable.append(t) return new_unhashable def _compare_args_orderless(first_args, second_args): first_unhashable = _deduplicate_unhashable(first_args) second_unhashable = _deduplicate_unhashable(second_args) t = list(second_unhashable) try: for elem in first_unhashable: t.remove(elem) except ValueError: return False return not t def _remove_dups_flatten(parameters): """Internal helper for Union creation and substitution. Flatten Unions among parameters, then remove duplicates. """ # Flatten out Union[Union[...], ...]. params = [] for p in parameters: if isinstance(p, (_UnionGenericAlias, types.UnionType)): params.extend(p.__args__) else: params.append(p) return tuple(_deduplicate(params, unhashable_fallback=True)) def _flatten_literal_params(parameters): """Internal helper for Literal creation: flatten Literals among parameters.""" params = [] for p in parameters: if isinstance(p, _LiteralGenericAlias): params.extend(p.__args__) else: params.append(p) return tuple(params) _cleanups = [] _caches = {} def _tp_cache(func=None, /, *, typed=False): """Internal wrapper caching __getitem__ of generic types. For non-hashable arguments, the original function is used as a fallback. """ def decorator(func): # The callback 'inner' references the newly created lru_cache # indirectly by performing a lookup in the global '_caches' dictionary. # This breaks a reference that can be problematic when combined with # C API extensions that leak references to types. See GH-98253. cache = functools.lru_cache(typed=typed)(func) _caches[func] = cache _cleanups.append(cache.cache_clear) del cache @functools.wraps(func) def inner(*args, **kwds): try: return _caches[func](*args, **kwds) except TypeError: pass # All real errors (not unhashable args) are raised below. return func(*args, **kwds) return inner if func is not None: return decorator(func) return decorator def _eval_type(t, globalns, localns, type_params=None, *, recursive_guard=frozenset()): """Evaluate all forward references in the given type t. For use of globalns and localns see the docstring for get_type_hints(). recursive_guard is used to prevent infinite recursion with a recursive ForwardRef. """ if isinstance(t, ForwardRef): return t._evaluate(globalns, localns, type_params, recursive_guard=recursive_guard) if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): if isinstance(t, GenericAlias): args = tuple( ForwardRef(arg) if isinstance(arg, str) else arg for arg in t.__args__ ) is_unpacked = t.__unpacked__ if _should_unflatten_callable_args(t, args): t = t.__origin__[(args[:-1], args[-1])] else: t = t.__origin__[args] if is_unpacked: t = Unpack[t] ev_args = tuple( _eval_type( a, globalns, localns, type_params, recursive_guard=recursive_guard ) for a in t.__args__ ) if ev_args == t.__args__: return t if isinstance(t, GenericAlias): return GenericAlias(t.__origin__, ev_args) if isinstance(t, types.UnionType): return functools.reduce(operator.or_, ev_args) else: return t.copy_with(ev_args) return t class _Final: """Mixin to prohibit subclassing.""" __slots__ = ('__weakref__',) def __init_subclass__(cls, /, *args, **kwds): if '_root' not in kwds: raise TypeError("Cannot subclass special typing classes") class _NotIterable: """Mixin to prevent iteration, without being compatible with Iterable. That is, we could do:: def __iter__(self): raise TypeError() But this would make users of this mixin duck type-compatible with collections.abc.Iterable - isinstance(foo, Iterable) would be True. Luckily, we can instead prevent iteration by setting __iter__ to None, which is treated specially. """ __slots__ = () __iter__ = None # Internal indicator of special typing constructs. # See __doc__ instance attribute for specific docs. class _SpecialForm(_Final, _NotIterable, _root=True): __slots__ = ('_name', '__doc__', '_getitem') def __init__(self, getitem): self._getitem = getitem self._name = getitem.__name__ self.__doc__ = getitem.__doc__ def __getattr__(self, item): if item in {'__name__', '__qualname__'}: return self._name raise AttributeError(item) def __mro_entries__(self, bases): raise TypeError(f"Cannot subclass {self!r}") def __repr__(self): return 'typing.' + self._name def __reduce__(self): return self._name def __call__(self, *args, **kwds): raise TypeError(f"Cannot instantiate {self!r}") def __or__(self, other): return Union[self, other] def __ror__(self, other): return Union[other, self] def __instancecheck__(self, obj): raise TypeError(f"{self} cannot be used with isinstance()") def __subclasscheck__(self, cls): raise TypeError(f"{self} cannot be used with issubclass()") @_tp_cache def __getitem__(self, parameters): return self._getitem(self, parameters) class _LiteralSpecialForm(_SpecialForm, _root=True): def __getitem__(self, parameters): if not isinstance(parameters, tuple): parameters = (parameters,) return self._getitem(self, *parameters) class _AnyMeta(type): def __instancecheck__(self, obj): if self is Any: raise TypeError("typing.Any cannot be used with isinstance()") return super().__instancecheck__(obj) def __repr__(self): if self is Any: return "typing.Any" return super().__repr__() # respect to subclasses class Any(metaclass=_AnyMeta): """Special type indicating an unconstrained type. - Any is compatible with every type. - Any assumed to have all methods. - All values assumed to be instances of Any. Note that all the above statements are true from the point of view of static type checkers. At runtime, Any should not be used with instance checks. """ def __new__(cls, *args, **kwargs): if cls is Any: raise TypeError("Any cannot be instantiated") return super().__new__(cls) @_SpecialForm def NoReturn(self, parameters): """Special type indicating functions that never return. Example:: from typing import NoReturn def stop() -> NoReturn: raise Exception('no way') NoReturn can also be used as a bottom type, a type that has no values. Starting in Python 3.11, the Never type should be used for this concept instead. Type checkers should treat the two equivalently. """ raise TypeError(f"{self} is not subscriptable") # This is semantically identical to NoReturn, but it is implemented # separately so that type checkers can distinguish between the two # if they want. @_SpecialForm def Never(self, parameters): """The bottom type, a type that has no members. This can be used to define a function that should never be called, or a function that never returns:: from typing import Never def never_call_me(arg: Never) -> None: pass def int_or_str(arg: int | str) -> None: never_call_me(arg) # type checker error match arg: case int(): print("It's an int") case str(): print("It's a str") case _: never_call_me(arg) # OK, arg is of type Never """ raise TypeError(f"{self} is not subscriptable") @_SpecialForm def Self(self, parameters): """Used to spell the type of "self" in classes. Example:: from typing import Self class Foo: def return_self(self) -> Self: ... return self This is especially useful for: - classmethods that are used as alternative constructors - annotating an `__enter__` method which returns self """ raise TypeError(f"{self} is not subscriptable") @_SpecialForm def LiteralString(self, parameters): """Represents an arbitrary literal string. Example:: from typing import LiteralString def run_query(sql: LiteralString) -> None: ... def caller(arbitrary_string: str, literal_string: LiteralString) -> None: run_query("SELECT * FROM students") # OK run_query(literal_string) # OK run_query("SELECT * FROM " + literal_string) # OK run_query(arbitrary_string) # type checker error run_query( # type checker error f"SELECT * FROM students WHERE name = {arbitrary_string}" ) Only string literals and other LiteralStrings are compatible with LiteralString. This provides a tool to help prevent security issues such as SQL injection. """ raise TypeError(f"{self} is not subscriptable") @_SpecialForm def ClassVar(self, parameters): """Special type construct to mark class variables. An annotation wrapped in ClassVar indicates that a given attribute is intended to be used as a class variable and should not be set on instances of that class. Usage:: class Starship: stats: ClassVar[dict[str, int]] = {} # class variable damage: int = 10 # instance variable ClassVar accepts only types and cannot be further subscribed. Note that ClassVar is not a class itself, and should not be used with isinstance() or issubclass(). """ item = _type_check(parameters, f'{self} accepts only single type.') return _GenericAlias(self, (item,)) @_SpecialForm def Final(self, parameters): """Special typing construct to indicate final names to type checkers. A final name cannot be re-assigned or overridden in a subclass. For example:: MAX_SIZE: Final = 9000 MAX_SIZE += 1 # Error reported by type checker class Connection: TIMEOUT: Final[int] = 10 class FastConnector(Connection): TIMEOUT = 1 # Error reported by type checker There is no runtime checking of these properties. """ item = _type_check(parameters, f'{self} accepts only single type.') return _GenericAlias(self, (item,)) @_SpecialForm def Union(self, parameters): """Union type; Union[X, Y] means either X or Y. On Python 3.10 and higher, the | operator can also be used to denote unions; X | Y means the same thing to the type checker as Union[X, Y]. To define a union, use e.g. Union[int, str]. Details: - The arguments must be types and there must be at least one. - None as an argument is a special case and is replaced by type(None). - Unions of unions are flattened, e.g.:: assert Union[Union[int, str], float] == Union[int, str, float] - Unions of a single argument vanish, e.g.:: assert Union[int] == int # The constructor actually returns int - Redundant arguments are skipped, e.g.:: assert Union[int, str, int] == Union[int, str] - When comparing unions, the argument order is ignored, e.g.:: assert Union[int, str] == Union[str, int] - You cannot subclass or instantiate a union. - You can use Optional[X] as a shorthand for Union[X, None]. """ if parameters == (): raise TypeError("Cannot take a Union of no types.") if not isinstance(parameters, tuple): parameters = (parameters,) msg = "Union[arg, ...]: each arg must be a type." parameters = tuple(_type_check(p, msg) for p in parameters) parameters = _remove_dups_flatten(parameters) if len(parameters) == 1: return parameters[0] if len(parameters) == 2 and type(None) in parameters: return _UnionGenericAlias(self, parameters, name="Optional") return _UnionGenericAlias(self, parameters) def _make_union(left, right): """Used from the C implementation of TypeVar. TypeVar.__or__ calls this instead of returning types.UnionType because we want to allow unions between TypeVars and strings (forward references). """ return Union[left, right] @_SpecialForm def Optional(self, parameters): """Optional[X] is equivalent to Union[X, None].""" arg = _type_check(parameters, f"{self} requires a single type.") return Union[arg, type(None)] @_LiteralSpecialForm @_tp_cache(typed=True) def Literal(self, *parameters): """Special typing form to define literal types (a.k.a. value types). This form can be used to indicate to type checkers that the corresponding variable or function parameter has a value equivalent to the provided literal (or one of several literals):: def validate_simple(data: Any) -> Literal[True]: # always returns True ... MODE = Literal['r', 'rb', 'w', 'wb'] def open_helper(file: str, mode: MODE) -> str: ... open_helper('/some/path', 'r') # Passes type check open_helper('/other/path', 'typo') # Error in type checker Literal[...] cannot be subclassed. At runtime, an arbitrary value is allowed as type argument to Literal[...], but type checkers may impose restrictions. """ # There is no '_type_check' call because arguments to Literal[...] are # values, not types. parameters = _flatten_literal_params(parameters) try: parameters = tuple(p for p, _ in _deduplicate(list(_value_and_type_iter(parameters)))) except TypeError: # unhashable parameters pass return _LiteralGenericAlias(self, parameters) @_SpecialForm def TypeAlias(self, parameters): """Special form for marking type aliases. Use TypeAlias to indicate that an assignment should be recognized as a proper type alias definition by type checkers. For example:: Predicate: TypeAlias = Callable[..., bool] It's invalid when used anywhere except as in the example above. """ raise TypeError(f"{self} is not subscriptable") @_SpecialForm def Concatenate(self, parameters): """Special form for annotating higher-order functions. ``Concatenate`` can be used in conjunction with ``ParamSpec`` and ``Callable`` to represent a higher-order function which adds, removes or transforms the parameters of a callable. For example:: Callable[Concatenate[int, P], int] See PEP 612 for detailed information. """ if parameters == (): raise TypeError("Cannot take a Concatenate of no types.") if not isinstance(parameters, tuple): parameters = (parameters,) if not (parameters[-1] is ... or isinstance(parameters[-1], ParamSpec)): raise TypeError("The last parameter to Concatenate should be a " "ParamSpec variable or ellipsis.") msg = "Concatenate[arg, ...]: each arg must be a type." parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1]) return _ConcatenateGenericAlias(self, parameters) @_SpecialForm def TypeGuard(self, parameters): """Special typing construct for marking user-defined type guard functions. ``TypeGuard`` can be used to annotate the return type of a user-defined type guard function. ``TypeGuard`` only accepts a single type argument. At runtime, functions marked this way should return a boolean. ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static type checkers to determine a more precise type of an expression within a program's code flow. Usually type narrowing is done by analyzing conditional code flow and applying the narrowing to a block of code. The conditional expression here is sometimes referred to as a "type guard". Sometimes it would be convenient to use a user-defined boolean function as a type guard. Such a function should use ``TypeGuard[...]`` as its return type to alert static type checkers to this intention. Using ``-> TypeGuard`` tells the static type checker that for a given function: 1. The return value is a boolean. 2. If the return value is ``True``, the type of its argument is the type inside ``TypeGuard``. For example:: def is_str_list(val: list[object]) -> TypeGuard[list[str]]: '''Determines whether all objects in the list are strings''' return all(isinstance(x, str) for x in val) def func1(val: list[object]): if is_str_list(val): # Type of ``val`` is narrowed to ``list[str]``. print(" ".join(val)) else: # Type of ``val`` remains as ``list[object]``. print("Not a list of strings!") Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower form of ``TypeA`` (it can even be a wider form) and this may lead to type-unsafe results. The main reason is to allow for things like narrowing ``list[object]`` to ``list[str]`` even though the latter is not a subtype of the former, since ``list`` is invariant. The responsibility of writing type-safe type guards is left to the user. ``TypeGuard`` also works with type variables. For more information, see PEP 647 (User-Defined Type Guards). """ item = _type_check(parameters, f'{self} accepts only single type.') return _GenericAlias(self, (item,)) class ForwardRef(_Final, _root=True): """Internal wrapper to hold a forward reference.""" __slots__ = ('__forward_arg__', '__forward_code__', '__forward_evaluated__', '__forward_value__', '__forward_is_argument__', '__forward_is_class__', '__forward_module__') def __init__(self, arg, is_argument=True, module=None, *, is_class=False): if not isinstance(arg, str): raise TypeError(f"Forward reference must be a string -- got {arg!r}") # If we do `def f(*args: *Ts)`, then we'll have `arg = '*Ts'`. # Unfortunately, this isn't a valid expression on its own, so we # do the unpacking manually. if arg.startswith('*'): arg_to_compile = f'({arg},)[0]' # E.g. (*Ts,)[0] or (*tuple[int, int],)[0] else: arg_to_compile = arg try: code = compile(arg_to_compile, '', 'eval') except SyntaxError: raise SyntaxError(f"Forward reference must be an expression -- got {arg!r}") self.__forward_arg__ = arg self.__forward_code__ = code self.__forward_evaluated__ = False self.__forward_value__ = None self.__forward_is_argument__ = is_argument self.__forward_is_class__ = is_class self.__forward_module__ = module def _evaluate(self, globalns, localns, type_params=None, *, recursive_guard): if self.__forward_arg__ in recursive_guard: return self if not self.__forward_evaluated__ or localns is not globalns: if globalns is None and localns is None: globalns = localns = {} elif globalns is None: globalns = localns elif localns is None: localns = globalns if self.__forward_module__ is not None: globalns = getattr( sys.modules.get(self.__forward_module__, None), '__dict__', globalns ) # type parameters require some special handling, # as they exist in their own scope # but `eval()` does not have a dedicated parameter for that scope. # For classes, names in type parameter scopes should override # names in the global scope (which here are called `localns`!), # but should in turn be overridden by names in the class scope # (which here are called `globalns`!) if type_params: globalns, localns = dict(globalns), dict(localns) for param in type_params: param_name = param.__name__ if not self.__forward_is_class__ or param_name not in globalns: globalns[param_name] = param localns.pop(param_name, None) type_ = _type_check( eval(self.__forward_code__, globalns, localns), "Forward references must evaluate to types.", is_argument=self.__forward_is_argument__, allow_special_forms=self.__forward_is_class__, ) self.__forward_value__ = _eval_type( type_, globalns, localns, type_params, recursive_guard=(recursive_guard | {self.__forward_arg__}), ) self.__forward_evaluated__ = True return self.__forward_value__ def __eq__(self, other): if not isinstance(other, ForwardRef): return NotImplemented if self.__forward_evaluated__ and other.__forward_evaluated__: return (self.__forward_arg__ == other.__forward_arg__ and self.__forward_value__ == other.__forward_value__) return (self.__forward_arg__ == other.__forward_arg__ and self.__forward_module__ == other.__forward_module__) def __hash__(self): return hash((self.__forward_arg__, self.__forward_module__)) def __or__(self, other): return Union[self, other] def __ror__(self, other): return Union[other, self] def __repr__(self): if self.__forward_module__ is None: module_repr = '' else: module_repr = f', module={self.__forward_module__!r}' return f'ForwardRef({self.__forward_arg__!r}{module_repr})' def _is_unpacked_typevartuple(x: Any) -> bool: return ((not isinstance(x, type)) and getattr(x, '__typing_is_unpacked_typevartuple__', False)) def _is_typevar_like(x: Any) -> bool: return isinstance(x, (TypeVar, ParamSpec)) or _is_unpacked_typevartuple(x) class _PickleUsingNameMixin: """Mixin enabling pickling based on self.__name__.""" def __reduce__(self): return self.__name__ def _typevar_subst(self, arg): msg = "Parameters to generic types must be types." arg = _type_check(arg, msg, is_argument=True) if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or (isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))): raise TypeError(f"{arg} is not valid as type argument") return arg def _typevartuple_prepare_subst(self, alias, args): params = alias.__parameters__ typevartuple_index = params.index(self) for param in params[typevartuple_index + 1:]: if isinstance(param, TypeVarTuple): raise TypeError(f"More than one TypeVarTuple parameter in {alias}") alen = len(args) plen = len(params) left = typevartuple_index right = plen - typevartuple_index - 1 var_tuple_index = None fillarg = None for k, arg in enumerate(args): if not isinstance(arg, type): subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) if subargs and len(subargs) == 2 and subargs[-1] is ...: if var_tuple_index is not None: raise TypeError("More than one unpacked arbitrary-length tuple argument") var_tuple_index = k fillarg = subargs[0] if var_tuple_index is not None: left = min(left, var_tuple_index) right = min(right, alen - var_tuple_index - 1) elif left + right > alen: raise TypeError(f"Too few arguments for {alias};" f" actual {alen}, expected at least {plen-1}") return ( *args[:left], *([fillarg]*(typevartuple_index - left)), tuple(args[left: alen - right]), *([fillarg]*(plen - right - left - typevartuple_index - 1)), *args[alen - right:], ) def _paramspec_subst(self, arg): if isinstance(arg, (list, tuple)): arg = tuple(_type_check(a, "Expected a type.") for a in arg) elif not _is_param_expr(arg): raise TypeError(f"Expected a list of types, an ellipsis, " f"ParamSpec, or Concatenate. Got {arg}") return arg def _paramspec_prepare_subst(self, alias, args): params = alias.__parameters__ i = params.index(self) if i >= len(args): raise TypeError(f"Too few arguments for {alias}") # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612. if len(params) == 1 and not _is_param_expr(args[0]): assert i == 0 args = (args,) # Convert lists to tuples to help other libraries cache the results. elif isinstance(args[i], list): args = (*args[:i], tuple(args[i]), *args[i+1:]) return args @_tp_cache def _generic_class_getitem(cls, params): """Parameterizes a generic class. At least, parameterizing a generic class is the *main* thing this method does. For example, for some generic class `Foo`, this is called when we do `Foo[int]` - there, with `cls=Foo` and `params=int`. However, note that this method is also called when defining generic classes in the first place with `class Foo(Generic[T]): ...`. """ if not isinstance(params, tuple): params = (params,) params = tuple(_type_convert(p) for p in params) is_generic_or_protocol = cls in (Generic, Protocol) if is_generic_or_protocol: # Generic and Protocol can only be subscripted with unique type variables. if not params: raise TypeError( f"Parameter list to {cls.__qualname__}[...] cannot be empty" ) if not all(_is_typevar_like(p) for p in params): raise TypeError( f"Parameters to {cls.__name__}[...] must all be type variables " f"or parameter specification variables.") if len(set(params)) != len(params): raise TypeError( f"Parameters to {cls.__name__}[...] must all be unique") else: # Subscripting a regular Generic subclass. for param in cls.__parameters__: prepare = getattr(param, '__typing_prepare_subst__', None) if prepare is not None: params = prepare(cls, params) _check_generic(cls, params, len(cls.__parameters__)) new_args = [] for param, new_arg in zip(cls.__parameters__, params): if isinstance(param, TypeVarTuple): new_args.extend(new_arg) else: new_args.append(new_arg) params = tuple(new_args) return _GenericAlias(cls, params) def _generic_init_subclass(cls, *args, **kwargs): super(Generic, cls).__init_subclass__(*args, **kwargs) tvars = [] if '__orig_bases__' in cls.__dict__: error = Generic in cls.__orig_bases__ else: error = (Generic in cls.__bases__ and cls.__name__ != 'Protocol' and type(cls) != _TypedDictMeta) if error: raise TypeError("Cannot inherit from plain Generic") if '__orig_bases__' in cls.__dict__: tvars = _collect_parameters(cls.__orig_bases__) # Look for Generic[T1, ..., Tn]. # If found, tvars must be a subset of it. # If not found, tvars is it. # Also check for and reject plain Generic, # and reject multiple Generic[...]. gvars = None for base in cls.__orig_bases__: if (isinstance(base, _GenericAlias) and base.__origin__ is Generic): if gvars is not None: raise TypeError( "Cannot inherit from Generic[...] multiple times.") gvars = base.__parameters__ if gvars is not None: tvarset = set(tvars) gvarset = set(gvars) if not tvarset <= gvarset: s_vars = ', '.join(str(t) for t in tvars if t not in gvarset) s_args = ', '.join(str(g) for g in gvars) raise TypeError(f"Some type variables ({s_vars}) are" f" not listed in Generic[{s_args}]") tvars = gvars cls.__parameters__ = tuple(tvars) def _is_dunder(attr): return attr.startswith('__') and attr.endswith('__') class _BaseGenericAlias(_Final, _root=True): """The central part of the internal API. This represents a generic version of type 'origin' with type arguments 'params'. There are two kind of these aliases: user defined and special. The special ones are wrappers around builtin collections and ABCs in collections.abc. These must have 'name' always set. If 'inst' is False, then the alias can't be instantiated; this is used by e.g. typing.List and typing.Dict. """ def __init__(self, origin, *, inst=True, name=None): self._inst = inst self._name = name self.__origin__ = origin self.__slots__ = None # This is not documented. def __call__(self, *args, **kwargs): if not self._inst: raise TypeError(f"Type {self._name} cannot be instantiated; " f"use {self.__origin__.__name__}() instead") result = self.__origin__(*args, **kwargs) try: result.__orig_class__ = self # Some objects raise TypeError (or something even more exotic) # if you try to set attributes on them; we guard against that here except Exception: pass return result def __mro_entries__(self, bases): res = [] if self.__origin__ not in bases: res.append(self.__origin__) i = bases.index(self) for b in bases[i+1:]: if isinstance(b, _BaseGenericAlias) or issubclass(b, Generic): break else: res.append(Generic) return tuple(res) def __getattr__(self, attr): if attr in {'__name__', '__qualname__'}: return self._name or self.__origin__.__name__ # We are careful for copy and pickle. # Also for simplicity we don't relay any dunder names if '__origin__' in self.__dict__ and not _is_dunder(attr): return getattr(self.__origin__, attr) raise AttributeError(attr) def __setattr__(self, attr, val): if _is_dunder(attr) or attr in {'_name', '_inst', '_nparams'}: super().__setattr__(attr, val) else: setattr(self.__origin__, attr, val) def __instancecheck__(self, obj): return self.__subclasscheck__(type(obj)) def __subclasscheck__(self, cls): raise TypeError("Subscripted generics cannot be used with" " class and instance checks") def __dir__(self): return list(set(super().__dir__() + [attr for attr in dir(self.__origin__) if not _is_dunder(attr)])) # Special typing constructs Union, Optional, Generic, Callable and Tuple # use three special attributes for internal bookkeeping of generic types: # * __parameters__ is a tuple of unique free type parameters of a generic # type, for example, Dict[T, T].__parameters__ == (T,); # * __origin__ keeps a reference to a type that was subscripted, # e.g., Union[T, int].__origin__ == Union, or the non-generic version of # the type. # * __args__ is a tuple of all arguments used in subscripting, # e.g., Dict[T, int].__args__ == (T, int). class _GenericAlias(_BaseGenericAlias, _root=True): # The type of parameterized generics. # # That is, for example, `type(List[int])` is `_GenericAlias`. # # Objects which are instances of this class include: # * Parameterized container types, e.g. `Tuple[int]`, `List[int]`. # * Note that native container types, e.g. `tuple`, `list`, use # `types.GenericAlias` instead. # * Parameterized classes: # class C[T]: pass # # C[int] is a _GenericAlias # * `Callable` aliases, generic `Callable` aliases, and # parameterized `Callable` aliases: # T = TypeVar('T') # # _CallableGenericAlias inherits from _GenericAlias. # A = Callable[[], None] # _CallableGenericAlias # B = Callable[[T], None] # _CallableGenericAlias # C = B[int] # _CallableGenericAlias # * Parameterized `Final`, `ClassVar` and `TypeGuard`: # # All _GenericAlias # Final[int] # ClassVar[float] # TypeVar[bool] def __init__(self, origin, args, *, inst=True, name=None): super().__init__(origin, inst=inst, name=name) if not isinstance(args, tuple): args = (args,) self.__args__ = tuple(... if a is _TypingEllipsis else a for a in args) self.__parameters__ = _collect_parameters(args) if not name: self.__module__ = origin.__module__ def __eq__(self, other): if not isinstance(other, _GenericAlias): return NotImplemented return (self.__origin__ == other.__origin__ and self.__args__ == other.__args__) def __hash__(self): return hash((self.__origin__, self.__args__)) def __or__(self, right): return Union[self, right] def __ror__(self, left): return Union[left, self] @_tp_cache def __getitem__(self, args): # Parameterizes an already-parameterized object. # # For example, we arrive here doing something like: # T1 = TypeVar('T1') # T2 = TypeVar('T2') # T3 = TypeVar('T3') # class A(Generic[T1]): pass # B = A[T2] # B is a _GenericAlias # C = B[T3] # Invokes _GenericAlias.__getitem__ # # We also arrive here when parameterizing a generic `Callable` alias: # T = TypeVar('T') # C = Callable[[T], None] # C[int] # Invokes _GenericAlias.__getitem__ if self.__origin__ in (Generic, Protocol): # Can't subscript Generic[...] or Protocol[...]. raise TypeError(f"Cannot subscript already-subscripted {self}") if not self.__parameters__: raise TypeError(f"{self} is not a generic class") # Preprocess `args`. if not isinstance(args, tuple): args = (args,) args = tuple(_type_convert(p) for p in args) args = _unpack_args(args) new_args = self._determine_new_args(args) r = self.copy_with(new_args) return r def _determine_new_args(self, args): # Determines new __args__ for __getitem__. # # For example, suppose we had: # T1 = TypeVar('T1') # T2 = TypeVar('T2') # class A(Generic[T1, T2]): pass # T3 = TypeVar('T3') # B = A[int, T3] # C = B[str] # `B.__args__` is `(int, T3)`, so `C.__args__` should be `(int, str)`. # Unfortunately, this is harder than it looks, because if `T3` is # anything more exotic than a plain `TypeVar`, we need to consider # edge cases. params = self.__parameters__ # In the example above, this would be {T3: str} for param in params: prepare = getattr(param, '__typing_prepare_subst__', None) if prepare is not None: args = prepare(self, args) alen = len(args) plen = len(params) if alen != plen: raise TypeError(f"Too {'many' if alen > plen else 'few'} arguments for {self};" f" actual {alen}, expected {plen}") new_arg_by_param = dict(zip(params, args)) return tuple(self._make_substitution(self.__args__, new_arg_by_param)) def _make_substitution(self, args, new_arg_by_param): """Create a list of new type arguments.""" new_args = [] for old_arg in args: if isinstance(old_arg, type): new_args.append(old_arg) continue substfunc = getattr(old_arg, '__typing_subst__', None) if substfunc: new_arg = substfunc(new_arg_by_param[old_arg]) else: subparams = getattr(old_arg, '__parameters__', ()) if not subparams: new_arg = old_arg else: subargs = [] for x in subparams: if isinstance(x, TypeVarTuple): subargs.extend(new_arg_by_param[x]) else: subargs.append(new_arg_by_param[x]) new_arg = old_arg[tuple(subargs)] if self.__origin__ == collections.abc.Callable and isinstance(new_arg, tuple): # Consider the following `Callable`. # C = Callable[[int], str] # Here, `C.__args__` should be (int, str) - NOT ([int], str). # That means that if we had something like... # P = ParamSpec('P') # T = TypeVar('T') # C = Callable[P, T] # D = C[[int, str], float] # ...we need to be careful; `new_args` should end up as # `(int, str, float)` rather than `([int, str], float)`. new_args.extend(new_arg) elif _is_unpacked_typevartuple(old_arg): # Consider the following `_GenericAlias`, `B`: # class A(Generic[*Ts]): ... # B = A[T, *Ts] # If we then do: # B[float, int, str] # The `new_arg` corresponding to `T` will be `float`, and the # `new_arg` corresponding to `*Ts` will be `(int, str)`. We # should join all these types together in a flat list # `(float, int, str)` - so again, we should `extend`. new_args.extend(new_arg) elif isinstance(old_arg, tuple): # Corner case: # P = ParamSpec('P') # T = TypeVar('T') # class Base(Generic[P]): ... # Can be substituted like this: # X = Base[[int, T]] # In this case, `old_arg` will be a tuple: new_args.append( tuple(self._make_substitution(old_arg, new_arg_by_param)), ) else: new_args.append(new_arg) return new_args def copy_with(self, args): return self.__class__(self.__origin__, args, name=self._name, inst=self._inst) def __repr__(self): if self._name: name = 'typing.' + self._name else: name = _type_repr(self.__origin__) if self.__args__: args = ", ".join([_type_repr(a) for a in self.__args__]) else: # To ensure the repr is eval-able. args = "()" return f'{name}[{args}]' def __reduce__(self): if self._name: origin = globals()[self._name] else: origin = self.__origin__ args = tuple(self.__args__) if len(args) == 1 and not isinstance(args[0], tuple): args, = args return operator.getitem, (origin, args) def __mro_entries__(self, bases): if isinstance(self.__origin__, _SpecialForm): raise TypeError(f"Cannot subclass {self!r}") if self._name: # generic version of an ABC or built-in class return super().__mro_entries__(bases) if self.__origin__ is Generic: if Protocol in bases: return () i = bases.index(self) for b in bases[i+1:]: if isinstance(b, _BaseGenericAlias) and b is not self: return () return (self.__origin__,) def __iter__(self): yield Unpack[self] # _nparams is the number of accepted parameters, e.g. 0 for Hashable, # 1 for List and 2 for Dict. It may be -1 if variable number of # parameters are accepted (needs custom __getitem__). class _SpecialGenericAlias(_NotIterable, _BaseGenericAlias, _root=True): def __init__(self, origin, nparams, *, inst=True, name=None): if name is None: name = origin.__name__ super().__init__(origin, inst=inst, name=name) self._nparams = nparams if origin.__module__ == 'builtins': self.__doc__ = f'A generic version of {origin.__qualname__}.' else: self.__doc__ = f'A generic version of {origin.__module__}.{origin.__qualname__}.' @_tp_cache def __getitem__(self, params): if not isinstance(params, tuple): params = (params,) msg = "Parameters to generic types must be types." params = tuple(_type_check(p, msg) for p in params) _check_generic(self, params, self._nparams) return self.copy_with(params) def copy_with(self, params): return _GenericAlias(self.__origin__, params, name=self._name, inst=self._inst) def __repr__(self): return 'typing.' + self._name def __subclasscheck__(self, cls): if isinstance(cls, _SpecialGenericAlias): return issubclass(cls.__origin__, self.__origin__) if not isinstance(cls, _GenericAlias): return issubclass(cls, self.__origin__) return super().__subclasscheck__(cls) def __reduce__(self): return self._name def __or__(self, right): return Union[self, right] def __ror__(self, left): return Union[left, self] class _DeprecatedGenericAlias(_SpecialGenericAlias, _root=True): def __init__( self, origin, nparams, *, removal_version, inst=True, name=None ): super().__init__(origin, nparams, inst=inst, name=name) self._removal_version = removal_version def __instancecheck__(self, inst): import warnings warnings._deprecated( f"{self.__module__}.{self._name}", remove=self._removal_version ) return super().__instancecheck__(inst) class _CallableGenericAlias(_NotIterable, _GenericAlias, _root=True): def __repr__(self): assert self._name == 'Callable' args = self.__args__ if len(args) == 2 and _is_param_expr(args[0]): return super().__repr__() return (f'typing.Callable' f'[[{", ".join([_type_repr(a) for a in args[:-1]])}], ' f'{_type_repr(args[-1])}]') def __reduce__(self): args = self.__args__ if not (len(args) == 2 and _is_param_expr(args[0])): args = list(args[:-1]), args[-1] return operator.getitem, (Callable, args) class _CallableType(_SpecialGenericAlias, _root=True): def copy_with(self, params): return _CallableGenericAlias(self.__origin__, params, name=self._name, inst=self._inst) def __getitem__(self, params): if not isinstance(params, tuple) or len(params) != 2: raise TypeError("Callable must be used as " "Callable[[arg, ...], result].") args, result = params # This relaxes what args can be on purpose to allow things like # PEP 612 ParamSpec. Responsibility for whether a user is using # Callable[...] properly is deferred to static type checkers. if isinstance(args, list): params = (tuple(args), result) else: params = (args, result) return self.__getitem_inner__(params) @_tp_cache def __getitem_inner__(self, params): args, result = params msg = "Callable[args, result]: result must be a type." result = _type_check(result, msg) if args is Ellipsis: return self.copy_with((_TypingEllipsis, result)) if not isinstance(args, tuple): args = (args,) args = tuple(_type_convert(arg) for arg in args) params = args + (result,) return self.copy_with(params) class _TupleType(_SpecialGenericAlias, _root=True): @_tp_cache def __getitem__(self, params): if not isinstance(params, tuple): params = (params,) if len(params) >= 2 and params[-1] is ...: msg = "Tuple[t, ...]: t must be a type." params = tuple(_type_check(p, msg) for p in params[:-1]) return self.copy_with((*params, _TypingEllipsis)) msg = "Tuple[t0, t1, ...]: each t must be a type." params = tuple(_type_check(p, msg) for p in params) return self.copy_with(params) class _UnionGenericAlias(_NotIterable, _GenericAlias, _root=True): def copy_with(self, params): return Union[params] def __eq__(self, other): if not isinstance(other, (_UnionGenericAlias, types.UnionType)): return NotImplemented try: # fast path return set(self.__args__) == set(other.__args__) except TypeError: # not hashable, slow path return _compare_args_orderless(self.__args__, other.__args__) def __hash__(self): return hash(frozenset(self.__args__)) def __repr__(self): args = self.__args__ if len(args) == 2: if args[0] is type(None): return f'typing.Optional[{_type_repr(args[1])}]' elif args[1] is type(None): return f'typing.Optional[{_type_repr(args[0])}]' return super().__repr__() def __instancecheck__(self, obj): for arg in self.__args__: if isinstance(obj, arg): return True return False def __subclasscheck__(self, cls): for arg in self.__args__: if issubclass(cls, arg): return True return False def __reduce__(self): func, (origin, args) = super().__reduce__() return func, (Union, args) def _value_and_type_iter(parameters): return ((p, type(p)) for p in parameters) class _LiteralGenericAlias(_GenericAlias, _root=True): def __eq__(self, other): if not isinstance(other, _LiteralGenericAlias): return NotImplemented return set(_value_and_type_iter(self.__args__)) == set(_value_and_type_iter(other.__args__)) def __hash__(self): return hash(frozenset(_value_and_type_iter(self.__args__))) class _ConcatenateGenericAlias(_GenericAlias, _root=True): def copy_with(self, params): if isinstance(params[-1], (list, tuple)): return (*params[:-1], *params[-1]) if isinstance(params[-1], _ConcatenateGenericAlias): params = (*params[:-1], *params[-1].__args__) return super().copy_with(params) @_SpecialForm def Unpack(self, parameters): """Type unpack operator. The type unpack operator takes the child types from some container type, such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For example:: # For some generic class `Foo`: Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str] Ts = TypeVarTuple('Ts') # Specifies that `Bar` is generic in an arbitrary number of types. # (Think of `Ts` as a tuple of an arbitrary number of individual # `TypeVar`s, which the `Unpack` is 'pulling out' directly into the # `Generic[]`.) class Bar(Generic[Unpack[Ts]]): ... Bar[int] # Valid Bar[int, str] # Also valid From Python 3.11, this can also be done using the `*` operator:: Foo[*tuple[int, str]] class Bar(Generic[*Ts]): ... And from Python 3.12, it can be done using built-in syntax for generics:: Foo[*tuple[int, str]] class Bar[*Ts]: ... The operator can also be used along with a `TypedDict` to annotate `**kwargs` in a function signature:: class Movie(TypedDict): name: str year: int # This function expects two keyword arguments - *name* of type `str` and # *year* of type `int`. def foo(**kwargs: Unpack[Movie]): ... Note that there is only some runtime checking of this operator. Not everything the runtime allows may be accepted by static type checkers. For more information, see PEPs 646 and 692. """ item = _type_check(parameters, f'{self} accepts only single type.') return _UnpackGenericAlias(origin=self, args=(item,)) class _UnpackGenericAlias(_GenericAlias, _root=True): def __repr__(self): # `Unpack` only takes one argument, so __args__ should contain only # a single item. return f'typing.Unpack[{_type_repr(self.__args__[0])}]' def __getitem__(self, args): if self.__typing_is_unpacked_typevartuple__: return args return super().__getitem__(args) @property def __typing_unpacked_tuple_args__(self): assert self.__origin__ is Unpack assert len(self.__args__) == 1 arg, = self.__args__ if isinstance(arg, (_GenericAlias, types.GenericAlias)): if arg.__origin__ is not tuple: raise TypeError("Unpack[...] must be used with a tuple type") return arg.__args__ return None @property def __typing_is_unpacked_typevartuple__(self): assert self.__origin__ is Unpack assert len(self.__args__) == 1 return isinstance(self.__args__[0], TypeVarTuple) class _TypingEllipsis: """Internal placeholder for ... (ellipsis).""" _TYPING_INTERNALS = frozenset({ '__parameters__', '__orig_bases__', '__orig_class__', '_is_protocol', '_is_runtime_protocol', '__protocol_attrs__', '__non_callable_proto_members__', '__type_params__', }) _SPECIAL_NAMES = frozenset({ '__abstractmethods__', '__annotations__', '__dict__', '__doc__', '__init__', '__module__', '__new__', '__slots__', '__subclasshook__', '__weakref__', '__class_getitem__' }) # These special attributes will be not collected as protocol members. EXCLUDED_ATTRIBUTES = _TYPING_INTERNALS | _SPECIAL_NAMES | {'_MutableMapping__marker'} def _get_protocol_attrs(cls): """Collect protocol members from a protocol class objects. This includes names actually defined in the class dictionary, as well as names that appear in annotations. Special names (above) are skipped. """ attrs = set() for base in cls.__mro__[:-1]: # without object if base.__name__ in {'Protocol', 'Generic'}: continue annotations = getattr(base, '__annotations__', {}) for attr in (*base.__dict__, *annotations): if not attr.startswith('_abc_') and attr not in EXCLUDED_ATTRIBUTES: attrs.add(attr) return attrs def _no_init_or_replace_init(self, *args, **kwargs): cls = type(self) if cls._is_protocol: raise TypeError('Protocols cannot be instantiated') # Already using a custom `__init__`. No need to calculate correct # `__init__` to call. This can lead to RecursionError. See bpo-45121. if cls.__init__ is not _no_init_or_replace_init: return # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`. # The first instantiation of the subclass will call `_no_init_or_replace_init` which # searches for a proper new `__init__` in the MRO. The new `__init__` # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent # instantiation of the protocol subclass will thus use the new # `__init__` and no longer call `_no_init_or_replace_init`. for base in cls.__mro__: init = base.__dict__.get('__init__', _no_init_or_replace_init) if init is not _no_init_or_replace_init: cls.__init__ = init break else: # should not happen cls.__init__ = object.__init__ cls.__init__(self, *args, **kwargs) def _caller(depth=1, default='__main__'): try: return sys._getframemodulename(depth + 1) or default except AttributeError: # For platforms without _getframemodulename() pass try: return sys._getframe(depth + 1).f_globals.get('__name__', default) except (AttributeError, ValueError): # For platforms without _getframe() pass return None def _allow_reckless_class_checks(depth=2): """Allow instance and class checks for special stdlib modules. The abc and functools modules indiscriminately call isinstance() and issubclass() on the whole MRO of a user class, which may contain protocols. """ return _caller(depth) in {'abc', 'functools', None} _PROTO_ALLOWLIST = { 'collections.abc': [ 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable', 'AsyncIterator', 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', 'Buffer', ], 'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'], } @functools.cache def _lazy_load_getattr_static(): # Import getattr_static lazily so as not to slow down the import of typing.py # Cache the result so we don't slow down _ProtocolMeta.__instancecheck__ unnecessarily from inspect import getattr_static return getattr_static _cleanups.append(_lazy_load_getattr_static.cache_clear) def _pickle_psargs(psargs): return ParamSpecArgs, (psargs.__origin__,) copyreg.pickle(ParamSpecArgs, _pickle_psargs) def _pickle_pskwargs(pskwargs): return ParamSpecKwargs, (pskwargs.__origin__,) copyreg.pickle(ParamSpecKwargs, _pickle_pskwargs) del _pickle_psargs, _pickle_pskwargs class _ProtocolMeta(ABCMeta): # This metaclass is somewhat unfortunate, # but is necessary for several reasons... def __new__(mcls, name, bases, namespace, /, **kwargs): if name == "Protocol" and bases == (Generic,): pass elif Protocol in bases: for base in bases: if not ( base in {object, Generic} or base.__name__ in _PROTO_ALLOWLIST.get(base.__module__, []) or ( issubclass(base, Generic) and getattr(base, "_is_protocol", False) ) ): raise TypeError( f"Protocols can only inherit from other protocols, " f"got {base!r}" ) return super().__new__(mcls, name, bases, namespace, **kwargs) def __init__(cls, *args, **kwargs): super().__init__(*args, **kwargs) if getattr(cls, "_is_protocol", False): cls.__protocol_attrs__ = _get_protocol_attrs(cls) def __subclasscheck__(cls, other): if cls is Protocol: return type.__subclasscheck__(cls, other) if ( getattr(cls, '_is_protocol', False) and not _allow_reckless_class_checks() ): if not isinstance(other, type): # Same error message as for issubclass(1, int). raise TypeError('issubclass() arg 1 must be a class') if not getattr(cls, '_is_runtime_protocol', False): raise TypeError( "Instance and class checks can only be used with " "@runtime_checkable protocols" ) if ( # this attribute is set by @runtime_checkable: cls.__non_callable_proto_members__ and cls.__dict__.get("__subclasshook__") is _proto_hook ): raise TypeError( "Protocols with non-method members don't support issubclass()" ) return super().__subclasscheck__(other) def __instancecheck__(cls, instance): # We need this method for situations where attributes are # assigned in __init__. if cls is Protocol: return type.__instancecheck__(cls, instance) if not getattr(cls, "_is_protocol", False): # i.e., it's a concrete subclass of a protocol return super().__instancecheck__(instance) if ( not getattr(cls, '_is_runtime_protocol', False) and not _allow_reckless_class_checks() ): raise TypeError("Instance and class checks can only be used with" " @runtime_checkable protocols") if super().__instancecheck__(instance): return True getattr_static = _lazy_load_getattr_static() for attr in cls.__protocol_attrs__: try: val = getattr_static(instance, attr) except AttributeError: break # this attribute is set by @runtime_checkable: if val is None and attr not in cls.__non_callable_proto_members__: break else: return True return False @classmethod def _proto_hook(cls, other): if not cls.__dict__.get('_is_protocol', False): return NotImplemented for attr in cls.__protocol_attrs__: for base in other.__mro__: # Check if the members appears in the class dictionary... if attr in base.__dict__: if base.__dict__[attr] is None: return NotImplemented break # ...or in annotations, if it is a sub-protocol. annotations = getattr(base, '__annotations__', {}) if (isinstance(annotations, collections.abc.Mapping) and attr in annotations and issubclass(other, Generic) and getattr(other, '_is_protocol', False)): break else: return NotImplemented return True class Protocol(Generic, metaclass=_ProtocolMeta): """Base class for protocol classes. Protocol classes are defined as:: class Proto(Protocol): def meth(self) -> int: ... Such classes are primarily used with static type checkers that recognize structural subtyping (static duck-typing). For example:: class C: def meth(self) -> int: return 0 def func(x: Proto) -> int: return x.meth() func(C()) # Passes static type check See PEP 544 for details. Protocol classes decorated with @typing.runtime_checkable act as simple-minded runtime protocols that check only the presence of given attributes, ignoring their type signatures. Protocol classes can be generic, they are defined as:: class GenProto[T](Protocol): def meth(self) -> T: ... """ __slots__ = () _is_protocol = True _is_runtime_protocol = False def __init_subclass__(cls, *args, **kwargs): super().__init_subclass__(*args, **kwargs) # Determine if this is a protocol or a concrete subclass. if not cls.__dict__.get('_is_protocol', False): cls._is_protocol = any(b is Protocol for b in cls.__bases__) # Set (or override) the protocol subclass hook. if '__subclasshook__' not in cls.__dict__: cls.__subclasshook__ = _proto_hook # Prohibit instantiation for protocol classes if cls._is_protocol and cls.__init__ is Protocol.__init__: cls.__init__ = _no_init_or_replace_init class _AnnotatedAlias(_NotIterable, _GenericAlias, _root=True): """Runtime representation of an annotated type. At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't' with extra annotations. The alias behaves like a normal typing alias. Instantiating is the same as instantiating the underlying type; binding it to types is also the same. The metadata itself is stored in a '__metadata__' attribute as a tuple. """ def __init__(self, origin, metadata): if isinstance(origin, _AnnotatedAlias): metadata = origin.__metadata__ + metadata origin = origin.__origin__ super().__init__(origin, origin, name='Annotated') self.__metadata__ = metadata def copy_with(self, params): assert len(params) == 1 new_type = params[0] return _AnnotatedAlias(new_type, self.__metadata__) def __repr__(self): return "typing.Annotated[{}, {}]".format( _type_repr(self.__origin__), ", ".join(repr(a) for a in self.__metadata__) ) def __reduce__(self): return operator.getitem, ( Annotated, (self.__origin__,) + self.__metadata__ ) def __eq__(self, other): if not isinstance(other, _AnnotatedAlias): return NotImplemented return (self.__origin__ == other.__origin__ and self.__metadata__ == other.__metadata__) def __hash__(self): return hash((self.__origin__, self.__metadata__)) def __getattr__(self, attr): if attr in {'__name__', '__qualname__'}: return 'Annotated' return super().__getattr__(attr) def __mro_entries__(self, bases): return (self.__origin__,) class Annotated: """Add context-specific metadata to a type. Example: Annotated[int, runtime_check.Unsigned] indicates to the hypothetical runtime_check module that this type is an unsigned int. Every other consumer of this type can ignore this metadata and treat this type as int. The first argument to Annotated must be a valid type. Details: - It's an error to call `Annotated` with less than two arguments. - Access the metadata via the ``__metadata__`` attribute:: assert Annotated[int, '$'].__metadata__ == ('$',) - Nested Annotated types are flattened:: assert Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3] - Instantiating an annotated type is equivalent to instantiating the underlying type:: assert Annotated[C, Ann1](5) == C(5) - Annotated can be used as a generic type alias:: type Optimized[T] = Annotated[T, runtime.Optimize()] # type checker will treat Optimized[int] # as equivalent to Annotated[int, runtime.Optimize()] type OptimizedList[T] = Annotated[list[T], runtime.Optimize()] # type checker will treat OptimizedList[int] # as equivalent to Annotated[list[int], runtime.Optimize()] - Annotated cannot be used with an unpacked TypeVarTuple:: type Variadic[*Ts] = Annotated[*Ts, Ann1] # NOT valid This would be equivalent to:: Annotated[T1, T2, T3, ..., Ann1] where T1, T2 etc. are TypeVars, which would be invalid, because only one type should be passed to Annotated. """ __slots__ = () def __new__(cls, *args, **kwargs): raise TypeError("Type Annotated cannot be instantiated.") def __class_getitem__(cls, params): if not isinstance(params, tuple): params = (params,) return cls._class_getitem_inner(cls, *params) @_tp_cache(typed=True) def _class_getitem_inner(cls, *params): if len(params) < 2: raise TypeError("Annotated[...] should be used " "with at least two arguments (a type and an " "annotation).") if _is_unpacked_typevartuple(params[0]): raise TypeError("Annotated[...] should not be used with an " "unpacked TypeVarTuple") msg = "Annotated[t, ...]: t must be a type." origin = _type_check(params[0], msg, allow_special_forms=True) metadata = tuple(params[1:]) return _AnnotatedAlias(origin, metadata) def __init_subclass__(cls, *args, **kwargs): raise TypeError( "Cannot subclass {}.Annotated".format(cls.__module__) ) def runtime_checkable(cls): """Mark a protocol class as a runtime protocol. Such protocol can be used with isinstance() and issubclass(). Raise TypeError if applied to a non-protocol class. This allows a simple-minded structural check very similar to one trick ponies in collections.abc such as Iterable. For example:: @runtime_checkable class Closable(Protocol): def close(self): ... assert isinstance(open('/some/file'), Closable) Warning: this will check only the presence of the required methods, not their type signatures! """ if not issubclass(cls, Generic) or not getattr(cls, '_is_protocol', False): raise TypeError('@runtime_checkable can be only applied to protocol classes,' ' got %r' % cls) cls._is_runtime_protocol = True # PEP 544 prohibits using issubclass() # with protocols that have non-method members. # See gh-113320 for why we compute this attribute here, # rather than in `_ProtocolMeta.__init__` cls.__non_callable_proto_members__ = set() for attr in cls.__protocol_attrs__: try: is_callable = callable(getattr(cls, attr, None)) except Exception as e: raise TypeError( f"Failed to determine whether protocol member {attr!r} " "is a method member" ) from e else: if not is_callable: cls.__non_callable_proto_members__.add(attr) return cls def cast(typ, val): """Cast a value to a type. This returns the value unchanged. To the type checker this signals that the return value has the designated type, but at runtime we intentionally don't check anything (we want this to be as fast as possible). """ return val def assert_type(val, typ, /): """Ask a static type checker to confirm that the value is of the given type. At runtime this does nothing: it returns the first argument unchanged with no checks or side effects, no matter the actual type of the argument. When a static type checker encounters a call to assert_type(), it emits an error if the value is not of the specified type:: def greet(name: str) -> None: assert_type(name, str) # OK assert_type(name, int) # type checker error """ return val _allowed_types = (types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.ModuleType, WrapperDescriptorType, MethodWrapperType, MethodDescriptorType) def get_type_hints(obj, globalns=None, localns=None, include_extras=False): """Return type hints for an object. This is often the same as obj.__annotations__, but it handles forward references encoded as string literals and recursively replaces all 'Annotated[T, ...]' with 'T' (unless 'include_extras=True'). The argument may be a module, class, method, or function. The annotations are returned as a dictionary. For classes, annotations include also inherited members. TypeError is raised if the argument is not of a type that can contain annotations, and an empty dictionary is returned if no annotations are present. BEWARE -- the behavior of globalns and localns is counterintuitive (unless you are familiar with how eval() and exec() work). The search order is locals first, then globals. - If no dict arguments are passed, an attempt is made to use the globals from obj (or the respective module's globals for classes), and these are also used as the locals. If the object does not appear to have globals, an empty dictionary is used. For classes, the search order is globals first then locals. - If one dict argument is passed, it is used for both globals and locals. - If two dict arguments are passed, they specify globals and locals, respectively. """ if getattr(obj, '__no_type_check__', None): return {} # Classes require a special treatment. if isinstance(obj, type): hints = {} for base in reversed(obj.__mro__): if globalns is None: base_globals = getattr(sys.modules.get(base.__module__, None), '__dict__', {}) else: base_globals = globalns ann = base.__dict__.get('__annotations__', {}) if isinstance(ann, types.GetSetDescriptorType): ann = {} base_locals = dict(vars(base)) if localns is None else localns if localns is None and globalns is None: # This is surprising, but required. Before Python 3.10, # get_type_hints only evaluated the globalns of # a class. To maintain backwards compatibility, we reverse # the globalns and localns order so that eval() looks into # *base_globals* first rather than *base_locals*. # This only affects ForwardRefs. base_globals, base_locals = base_locals, base_globals for name, value in ann.items(): if value is None: value = type(None) if isinstance(value, str): value = ForwardRef(value, is_argument=False, is_class=True) value = _eval_type(value, base_globals, base_locals, base.__type_params__) hints[name] = value return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} if globalns is None: if isinstance(obj, types.ModuleType): globalns = obj.__dict__ else: nsobj = obj # Find globalns for the unwrapped object. while hasattr(nsobj, '__wrapped__'): nsobj = nsobj.__wrapped__ globalns = getattr(nsobj, '__globals__', {}) if localns is None: localns = globalns elif localns is None: localns = globalns hints = getattr(obj, '__annotations__', None) if hints is None: # Return empty annotations for something that _could_ have them. if isinstance(obj, _allowed_types): return {} else: raise TypeError('{!r} is not a module, class, method, ' 'or function.'.format(obj)) hints = dict(hints) type_params = getattr(obj, "__type_params__", ()) for name, value in hints.items(): if value is None: value = type(None) if isinstance(value, str): # class-level forward refs were handled above, this must be either # a module-level annotation or a function argument annotation value = ForwardRef( value, is_argument=not isinstance(obj, types.ModuleType), is_class=False, ) hints[name] = _eval_type(value, globalns, localns, type_params) return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} def _strip_annotations(t): """Strip the annotations from a given type.""" if isinstance(t, _AnnotatedAlias): return _strip_annotations(t.__origin__) if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired): return _strip_annotations(t.__args__[0]) if isinstance(t, _GenericAlias): stripped_args = tuple(_strip_annotations(a) for a in t.__args__) if stripped_args == t.__args__: return t return t.copy_with(stripped_args) if isinstance(t, GenericAlias): stripped_args = tuple(_strip_annotations(a) for a in t.__args__) if stripped_args == t.__args__: return t return GenericAlias(t.__origin__, stripped_args) if isinstance(t, types.UnionType): stripped_args = tuple(_strip_annotations(a) for a in t.__args__) if stripped_args == t.__args__: return t return functools.reduce(operator.or_, stripped_args) return t def get_origin(tp): """Get the unsubscripted version of a type. This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar, Annotated, and others. Return None for unsupported types. Examples:: >>> P = ParamSpec('P') >>> assert get_origin(Literal[42]) is Literal >>> assert get_origin(int) is None >>> assert get_origin(ClassVar[int]) is ClassVar >>> assert get_origin(Generic) is Generic >>> assert get_origin(Generic[T]) is Generic >>> assert get_origin(Union[T, int]) is Union >>> assert get_origin(List[Tuple[T, T]][int]) is list >>> assert get_origin(P.args) is P """ if isinstance(tp, _AnnotatedAlias): return Annotated if isinstance(tp, (_BaseGenericAlias, GenericAlias, ParamSpecArgs, ParamSpecKwargs)): return tp.__origin__ if tp is Generic: return Generic if isinstance(tp, types.UnionType): return types.UnionType return None def get_args(tp): """Get type arguments with all substitutions performed. For unions, basic simplifications used by Union constructor are performed. Examples:: >>> T = TypeVar('T') >>> assert get_args(Dict[str, int]) == (str, int) >>> assert get_args(int) == () >>> assert get_args(Union[int, Union[T, int], str][int]) == (int, str) >>> assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) >>> assert get_args(Callable[[], T][int]) == ([], int) """ if isinstance(tp, _AnnotatedAlias): return (tp.__origin__,) + tp.__metadata__ if isinstance(tp, (_GenericAlias, GenericAlias)): res = tp.__args__ if _should_unflatten_callable_args(tp, res): res = (list(res[:-1]), res[-1]) return res if isinstance(tp, types.UnionType): return tp.__args__ return () def is_typeddict(tp): """Check if an annotation is a TypedDict class. For example:: >>> from typing import TypedDict >>> class Film(TypedDict): ... title: str ... year: int ... >>> is_typeddict(Film) True >>> is_typeddict(dict) False """ return isinstance(tp, _TypedDictMeta) _ASSERT_NEVER_REPR_MAX_LENGTH = 100 def assert_never(arg: Never, /) -> Never: """Statically assert that a line of code is unreachable. Example:: def int_or_str(arg: int | str) -> None: match arg: case int(): print("It's an int") case str(): print("It's a str") case _: assert_never(arg) If a type checker finds that a call to assert_never() is reachable, it will emit an error. At runtime, this throws an exception when called. """ value = repr(arg) if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH: value = value[:_ASSERT_NEVER_REPR_MAX_LENGTH] + '...' raise AssertionError(f"Expected code to be unreachable, but got: {value}") def no_type_check(arg): """Decorator to indicate that annotations are not type hints. The argument must be a class or function; if it is a class, it applies recursively to all methods and classes defined in that class (but not to methods defined in its superclasses or subclasses). This mutates the function(s) or class(es) in place. """ if isinstance(arg, type): for key in dir(arg): obj = getattr(arg, key) if ( not hasattr(obj, '__qualname__') or obj.__qualname__ != f'{arg.__qualname__}.{obj.__name__}' or getattr(obj, '__module__', None) != arg.__module__ ): # We only modify objects that are defined in this type directly. # If classes / methods are nested in multiple layers, # we will modify them when processing their direct holders. continue # Instance, class, and static methods: if isinstance(obj, types.FunctionType): obj.__no_type_check__ = True if isinstance(obj, types.MethodType): obj.__func__.__no_type_check__ = True # Nested types: if isinstance(obj, type): no_type_check(obj) try: arg.__no_type_check__ = True except TypeError: # built-in classes pass return arg def no_type_check_decorator(decorator): """Decorator to give another decorator the @no_type_check effect. This wraps the decorator with something that wraps the decorated function in @no_type_check. """ @functools.wraps(decorator) def wrapped_decorator(*args, **kwds): func = decorator(*args, **kwds) func = no_type_check(func) return func return wrapped_decorator def _overload_dummy(*args, **kwds): """Helper for @overload to raise when called.""" raise NotImplementedError( "You should not call an overloaded function. " "A series of @overload-decorated functions " "outside a stub module should always be followed " "by an implementation that is not @overload-ed.") # {module: {qualname: {firstlineno: func}}} _overload_registry = defaultdict(functools.partial(defaultdict, dict)) def overload(func): """Decorator for overloaded functions/methods. In a stub file, place two or more stub definitions for the same function in a row, each decorated with @overload. For example:: @overload def utf8(value: None) -> None: ... @overload def utf8(value: bytes) -> bytes: ... @overload def utf8(value: str) -> bytes: ... In a non-stub file (i.e. a regular .py file), do the same but follow it with an implementation. The implementation should *not* be decorated with @overload:: @overload def utf8(value: None) -> None: ... @overload def utf8(value: bytes) -> bytes: ... @overload def utf8(value: str) -> bytes: ... def utf8(value): ... # implementation goes here The overloads for a function can be retrieved at runtime using the get_overloads() function. """ # classmethod and staticmethod f = getattr(func, "__func__", func) try: _overload_registry[f.__module__][f.__qualname__][f.__code__.co_firstlineno] = func except AttributeError: # Not a normal function; ignore. pass return _overload_dummy def get_overloads(func): """Return all defined overloads for *func* as a sequence.""" # classmethod and staticmethod f = getattr(func, "__func__", func) if f.__module__ not in _overload_registry: return [] mod_dict = _overload_registry[f.__module__] if f.__qualname__ not in mod_dict: return [] return list(mod_dict[f.__qualname__].values()) def clear_overloads(): """Clear all overloads in the registry.""" _overload_registry.clear() def final(f): """Decorator to indicate final methods and final classes. Use this decorator to indicate to type checkers that the decorated method cannot be overridden, and decorated class cannot be subclassed. For example:: class Base: @final def done(self) -> None: ... class Sub(Base): def done(self) -> None: # Error reported by type checker ... @final class Leaf: ... class Other(Leaf): # Error reported by type checker ... There is no runtime checking of these properties. The decorator attempts to set the ``__final__`` attribute to ``True`` on the decorated object to allow runtime introspection. """ try: f.__final__ = True except (AttributeError, TypeError): # Skip the attribute silently if it is not writable. # AttributeError happens if the object has __slots__ or a # read-only property, TypeError if it's a builtin class. pass return f # Some unconstrained type variables. These were initially used by the container types. # They were never meant for export and are now unused, but we keep them around to # avoid breaking compatibility with users who import them. T = TypeVar('T') # Any type. KT = TypeVar('KT') # Key type. VT = TypeVar('VT') # Value type. T_co = TypeVar('T_co', covariant=True) # Any type covariant containers. V_co = TypeVar('V_co', covariant=True) # Any type covariant containers. VT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers. T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant. # Internal type variable used for Type[]. CT_co = TypeVar('CT_co', covariant=True, bound=type) # A useful type variable with constraints. This represents string types. # (This one *is* for export!) AnyStr = TypeVar('AnyStr', bytes, str) # Various ABCs mimicking those in collections.abc. _alias = _SpecialGenericAlias Hashable = _alias(collections.abc.Hashable, 0) # Not generic. Awaitable = _alias(collections.abc.Awaitable, 1) Coroutine = _alias(collections.abc.Coroutine, 3) AsyncIterable = _alias(collections.abc.AsyncIterable, 1) AsyncIterator = _alias(collections.abc.AsyncIterator, 1) Iterable = _alias(collections.abc.Iterable, 1) Iterator = _alias(collections.abc.Iterator, 1) Reversible = _alias(collections.abc.Reversible, 1) Sized = _alias(collections.abc.Sized, 0) # Not generic. Container = _alias(collections.abc.Container, 1) Collection = _alias(collections.abc.Collection, 1) Callable = _CallableType(collections.abc.Callable, 2) Callable.__doc__ = \ """Deprecated alias to collections.abc.Callable. Callable[[int], str] signifies a function that takes a single parameter of type int and returns a str. The subscription syntax must always be used with exactly two values: the argument list and the return type. The argument list must be a list of types, a ParamSpec, Concatenate or ellipsis. The return type must be a single type. There is no syntax to indicate optional or keyword arguments; such function types are rarely used as callback types. """ AbstractSet = _alias(collections.abc.Set, 1, name='AbstractSet') MutableSet = _alias(collections.abc.MutableSet, 1) # NOTE: Mapping is only covariant in the value type. Mapping = _alias(collections.abc.Mapping, 2) MutableMapping = _alias(collections.abc.MutableMapping, 2) Sequence = _alias(collections.abc.Sequence, 1) MutableSequence = _alias(collections.abc.MutableSequence, 1) ByteString = _DeprecatedGenericAlias( collections.abc.ByteString, 0, removal_version=(3, 14) # Not generic. ) # Tuple accepts variable number of parameters. Tuple = _TupleType(tuple, -1, inst=False, name='Tuple') Tuple.__doc__ = \ """Deprecated alias to builtins.tuple. Tuple[X, Y] is the cross-product type of X and Y. Example: Tuple[T1, T2] is a tuple of two elements corresponding to type variables T1 and T2. Tuple[int, float, str] is a tuple of an int, a float and a string. To specify a variable-length tuple of homogeneous type, use Tuple[T, ...]. """ List = _alias(list, 1, inst=False, name='List') Deque = _alias(collections.deque, 1, name='Deque') Set = _alias(set, 1, inst=False, name='Set') FrozenSet = _alias(frozenset, 1, inst=False, name='FrozenSet') MappingView = _alias(collections.abc.MappingView, 1) KeysView = _alias(collections.abc.KeysView, 1) ItemsView = _alias(collections.abc.ItemsView, 2) ValuesView = _alias(collections.abc.ValuesView, 1) ContextManager = _alias(contextlib.AbstractContextManager, 1, name='ContextManager') AsyncContextManager = _alias(contextlib.AbstractAsyncContextManager, 1, name='AsyncContextManager') Dict = _alias(dict, 2, inst=False, name='Dict') DefaultDict = _alias(collections.defaultdict, 2, name='DefaultDict') OrderedDict = _alias(collections.OrderedDict, 2) Counter = _alias(collections.Counter, 1) ChainMap = _alias(collections.ChainMap, 2) Generator = _alias(collections.abc.Generator, 3) AsyncGenerator = _alias(collections.abc.AsyncGenerator, 2) Type = _alias(type, 1, inst=False, name='Type') Type.__doc__ = \ """Deprecated alias to builtins.type. builtins.type or typing.Type can be used to annotate class objects. For example, suppose we have the following classes:: class User: ... # Abstract base for User classes class BasicUser(User): ... class ProUser(User): ... class TeamUser(User): ... And a function that takes a class argument that's a subclass of User and returns an instance of the corresponding class:: def new_user[U](user_class: Type[U]) -> U: user = user_class() # (Here we could write the user object to a database) return user joe = new_user(BasicUser) At this point the type checker knows that joe has type BasicUser. """ @runtime_checkable class SupportsInt(Protocol): """An ABC with one abstract method __int__.""" __slots__ = () @abstractmethod def __int__(self) -> int: pass @runtime_checkable class SupportsFloat(Protocol): """An ABC with one abstract method __float__.""" __slots__ = () @abstractmethod def __float__(self) -> float: pass @runtime_checkable class SupportsComplex(Protocol): """An ABC with one abstract method __complex__.""" __slots__ = () @abstractmethod def __complex__(self) -> complex: pass @runtime_checkable class SupportsBytes(Protocol): """An ABC with one abstract method __bytes__.""" __slots__ = () @abstractmethod def __bytes__(self) -> bytes: pass @runtime_checkable class SupportsIndex(Protocol): """An ABC with one abstract method __index__.""" __slots__ = () @abstractmethod def __index__(self) -> int: pass @runtime_checkable class SupportsAbs[T](Protocol): """An ABC with one abstract method __abs__ that is covariant in its return type.""" __slots__ = () @abstractmethod def __abs__(self) -> T: pass @runtime_checkable class SupportsRound[T](Protocol): """An ABC with one abstract method __round__ that is covariant in its return type.""" __slots__ = () @abstractmethod def __round__(self, ndigits: int = 0) -> T: pass def _make_nmtuple(name, types, module, defaults = ()): fields = [n for n, t in types] types = {n: _type_check(t, f"field {n} annotation must be a type") for n, t in types} nm_tpl = collections.namedtuple(name, fields, defaults=defaults, module=module) nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = types return nm_tpl # attributes prohibited to set in NamedTuple class syntax _prohibited = frozenset({'__new__', '__init__', '__slots__', '__getnewargs__', '_fields', '_field_defaults', '_make', '_replace', '_asdict', '_source'}) _special = frozenset({'__module__', '__name__', '__annotations__'}) class NamedTupleMeta(type): def __new__(cls, typename, bases, ns): assert _NamedTuple in bases for base in bases: if base is not _NamedTuple and base is not Generic: raise TypeError( 'can only inherit from a NamedTuple type and Generic') bases = tuple(tuple if base is _NamedTuple else base for base in bases) types = ns.get('__annotations__', {}) default_names = [] for field_name in types: if field_name in ns: default_names.append(field_name) elif default_names: raise TypeError(f"Non-default namedtuple field {field_name} " f"cannot follow default field" f"{'s' if len(default_names) > 1 else ''} " f"{', '.join(default_names)}") nm_tpl = _make_nmtuple(typename, types.items(), defaults=[ns[n] for n in default_names], module=ns['__module__']) nm_tpl.__bases__ = bases if Generic in bases: class_getitem = _generic_class_getitem nm_tpl.__class_getitem__ = classmethod(class_getitem) # update from user namespace without overriding special namedtuple attributes for key in ns: if key in _prohibited: raise AttributeError("Cannot overwrite NamedTuple attribute " + key) elif key not in _special and key not in nm_tpl._fields: setattr(nm_tpl, key, ns[key]) if Generic in bases: nm_tpl.__init_subclass__() return nm_tpl def NamedTuple(typename, fields=None, /, **kwargs): """Typed version of namedtuple. Usage:: class Employee(NamedTuple): name: str id: int This is equivalent to:: Employee = collections.namedtuple('Employee', ['name', 'id']) The resulting class has an extra __annotations__ attribute, giving a dict that maps field names to types. (The field names are also in the _fields attribute, which is part of the namedtuple API.) An alternative equivalent functional syntax is also accepted:: Employee = NamedTuple('Employee', [('name', str), ('id', int)]) """ if fields is None: fields = kwargs.items() elif kwargs: raise TypeError("Either list of fields or keywords" " can be provided to NamedTuple, not both") nt = _make_nmtuple(typename, fields, module=_caller()) nt.__orig_bases__ = (NamedTuple,) return nt _NamedTuple = type.__new__(NamedTupleMeta, 'NamedTuple', (), {}) def _namedtuple_mro_entries(bases): assert NamedTuple in bases return (_NamedTuple,) NamedTuple.__mro_entries__ = _namedtuple_mro_entries class _TypedDictMeta(type): def __new__(cls, name, bases, ns, total=True): """Create a new typed dict class object. This method is called when TypedDict is subclassed, or when TypedDict is instantiated. This way TypedDict supports all three syntax forms described in its docstring. Subclasses and instances of TypedDict return actual dictionaries. """ for base in bases: if type(base) is not _TypedDictMeta and base is not Generic: raise TypeError('cannot inherit from both a TypedDict type ' 'and a non-TypedDict base class') if any(issubclass(b, Generic) for b in bases): generic_base = (Generic,) else: generic_base = () tp_dict = type.__new__(_TypedDictMeta, name, (*generic_base, dict), ns) if not hasattr(tp_dict, '__orig_bases__'): tp_dict.__orig_bases__ = bases annotations = {} own_annotations = ns.get('__annotations__', {}) msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" own_annotations = { n: _type_check(tp, msg, module=tp_dict.__module__) for n, tp in own_annotations.items() } required_keys = set() optional_keys = set() for base in bases: annotations.update(base.__dict__.get('__annotations__', {})) base_required = base.__dict__.get('__required_keys__', set()) required_keys |= base_required optional_keys -= base_required base_optional = base.__dict__.get('__optional_keys__', set()) required_keys -= base_optional optional_keys |= base_optional annotations.update(own_annotations) for annotation_key, annotation_type in own_annotations.items(): annotation_origin = get_origin(annotation_type) if annotation_origin is Annotated: annotation_args = get_args(annotation_type) if annotation_args: annotation_type = annotation_args[0] annotation_origin = get_origin(annotation_type) if annotation_origin is Required: is_required = True elif annotation_origin is NotRequired: is_required = False else: is_required = total if is_required: required_keys.add(annotation_key) optional_keys.discard(annotation_key) else: optional_keys.add(annotation_key) required_keys.discard(annotation_key) assert required_keys.isdisjoint(optional_keys), ( f"Required keys overlap with optional keys in {name}:" f" {required_keys=}, {optional_keys=}" ) tp_dict.__annotations__ = annotations tp_dict.__required_keys__ = frozenset(required_keys) tp_dict.__optional_keys__ = frozenset(optional_keys) if not hasattr(tp_dict, '__total__'): tp_dict.__total__ = total return tp_dict __call__ = dict # static method def __subclasscheck__(cls, other): # Typed dicts are only for static structural subtyping. raise TypeError('TypedDict does not support instance and class checks') __instancecheck__ = __subclasscheck__ def TypedDict(typename, fields=None, /, *, total=True, **kwargs): """A simple typed namespace. At runtime it is equivalent to a plain dict. TypedDict creates a dictionary type such that a type checker will expect all instances to have a certain set of keys, where each key is associated with a value of a consistent type. This expectation is not checked at runtime. Usage:: >>> class Point2D(TypedDict): ... x: int ... y: int ... label: str ... >>> a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK >>> b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check >>> Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') True The type info can be accessed via the Point2D.__annotations__ dict, and the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets. TypedDict supports an additional equivalent form:: Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) By default, all keys must be present in a TypedDict. It is possible to override this by specifying totality:: class Point2D(TypedDict, total=False): x: int y: int This means that a Point2D TypedDict can have any of the keys omitted. A type checker is only expected to support a literal False or True as the value of the total argument. True is the default, and makes all items defined in the class body be required. The Required and NotRequired special forms can also be used to mark individual keys as being required or not required:: class Point2D(TypedDict): x: int # the "x" key must always be present (Required is the default) y: NotRequired[int] # the "y" key can be omitted See PEP 655 for more details on Required and NotRequired. """ if fields is None: fields = kwargs elif kwargs: raise TypeError("TypedDict takes either a dict or keyword arguments," " but not both") if kwargs: warnings.warn( "The kwargs-based syntax for TypedDict definitions is deprecated " "in Python 3.11, will be removed in Python 3.13, and may not be " "understood by third-party type checkers.", DeprecationWarning, stacklevel=2, ) ns = {'__annotations__': dict(fields)} module = _caller() if module is not None: # Setting correct module is necessary to make typed dict classes pickleable. ns['__module__'] = module td = _TypedDictMeta(typename, (), ns, total=total) td.__orig_bases__ = (TypedDict,) return td _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {}) TypedDict.__mro_entries__ = lambda bases: (_TypedDict,) @_SpecialForm def Required(self, parameters): """Special typing construct to mark a TypedDict key as required. This is mainly useful for total=False TypedDicts. For example:: class Movie(TypedDict, total=False): title: Required[str] year: int m = Movie( title='The Matrix', # typechecker error if key is omitted year=1999, ) There is no runtime checking that a required key is actually provided when instantiating a related TypedDict. """ item = _type_check(parameters, f'{self._name} accepts only a single type.') return _GenericAlias(self, (item,)) @_SpecialForm def NotRequired(self, parameters): """Special typing construct to mark a TypedDict key as potentially missing. For example:: class Movie(TypedDict): title: str year: NotRequired[int] m = Movie( title='The Matrix', # typechecker error if key is omitted year=1999, ) """ item = _type_check(parameters, f'{self._name} accepts only a single type.') return _GenericAlias(self, (item,)) class NewType: """NewType creates simple unique types with almost zero runtime overhead. NewType(name, tp) is considered a subtype of tp by static type checkers. At runtime, NewType(name, tp) returns a dummy callable that simply returns its argument. Usage:: UserId = NewType('UserId', int) def name_by_id(user_id: UserId) -> str: ... UserId('user') # Fails type check name_by_id(42) # Fails type check name_by_id(UserId(42)) # OK num = UserId(5) + 1 # type: int """ __call__ = _idfunc def __init__(self, name, tp): self.__qualname__ = name if '.' in name: name = name.rpartition('.')[-1] self.__name__ = name self.__supertype__ = tp def_mod = _caller() if def_mod != 'typing': self.__module__ = def_mod def __mro_entries__(self, bases): # We defined __mro_entries__ to get a better error message # if a user attempts to subclass a NewType instance. bpo-46170 superclass_name = self.__name__ class Dummy: def __init_subclass__(cls): subclass_name = cls.__name__ raise TypeError( f"Cannot subclass an instance of NewType. Perhaps you were looking for: " f"`{subclass_name} = NewType({subclass_name!r}, {superclass_name})`" ) return (Dummy,) def __repr__(self): return f'{self.__module__}.{self.__qualname__}' def __reduce__(self): return self.__qualname__ def __or__(self, other): return Union[self, other] def __ror__(self, other): return Union[other, self] # Python-version-specific alias (Python 2: unicode; Python 3: str) Text = str # Constant that's True when type checking, but False here. TYPE_CHECKING = False class IO(Generic[AnyStr]): """Generic base class for TextIO and BinaryIO. This is an abstract, generic version of the return of open(). NOTE: This does not distinguish between the different possible classes (text vs. binary, read vs. write vs. read/write, append-only, unbuffered). The TextIO and BinaryIO subclasses below capture the distinctions between text vs. binary, which is pervasive in the interface; however we currently do not offer a way to track the other distinctions in the type system. """ __slots__ = () @property @abstractmethod def mode(self) -> str: pass @property @abstractmethod def name(self) -> str: pass @abstractmethod def close(self) -> None: pass @property @abstractmethod def closed(self) -> bool: pass @abstractmethod def fileno(self) -> int: pass @abstractmethod def flush(self) -> None: pass @abstractmethod def isatty(self) -> bool: pass @abstractmethod def read(self, n: int = -1) -> AnyStr: pass @abstractmethod def readable(self) -> bool: pass @abstractmethod def readline(self, limit: int = -1) -> AnyStr: pass @abstractmethod def readlines(self, hint: int = -1) -> List[AnyStr]: pass @abstractmethod def seek(self, offset: int, whence: int = 0) -> int: pass @abstractmethod def seekable(self) -> bool: pass @abstractmethod def tell(self) -> int: pass @abstractmethod def truncate(self, size: int = None) -> int: pass @abstractmethod def writable(self) -> bool: pass @abstractmethod def write(self, s: AnyStr) -> int: pass @abstractmethod def writelines(self, lines: List[AnyStr]) -> None: pass @abstractmethod def __enter__(self) -> 'IO[AnyStr]': pass @abstractmethod def __exit__(self, type, value, traceback) -> None: pass class BinaryIO(IO[bytes]): """Typed version of the return of open() in binary mode.""" __slots__ = () @abstractmethod def write(self, s: Union[bytes, bytearray]) -> int: pass @abstractmethod def __enter__(self) -> 'BinaryIO': pass class TextIO(IO[str]): """Typed version of the return of open() in text mode.""" __slots__ = () @property @abstractmethod def buffer(self) -> BinaryIO: pass @property @abstractmethod def encoding(self) -> str: pass @property @abstractmethod def errors(self) -> Optional[str]: pass @property @abstractmethod def line_buffering(self) -> bool: pass @property @abstractmethod def newlines(self) -> Any: pass @abstractmethod def __enter__(self) -> 'TextIO': pass class _DeprecatedType(type): def __getattribute__(cls, name): if name not in {"__dict__", "__module__", "__doc__"} and name in cls.__dict__: warnings.warn( f"{cls.__name__} is deprecated, import directly " f"from typing instead. {cls.__name__} will be removed " "in Python 3.13.", DeprecationWarning, stacklevel=2, ) return super().__getattribute__(name) class io(metaclass=_DeprecatedType): """Wrapper namespace for IO generic classes.""" __all__ = ['IO', 'TextIO', 'BinaryIO'] IO = IO TextIO = TextIO BinaryIO = BinaryIO io.__name__ = __name__ + '.io' sys.modules[io.__name__] = io Pattern = _alias(stdlib_re.Pattern, 1) Match = _alias(stdlib_re.Match, 1) class re(metaclass=_DeprecatedType): """Wrapper namespace for re type aliases.""" __all__ = ['Pattern', 'Match'] Pattern = Pattern Match = Match re.__name__ = __name__ + '.re' sys.modules[re.__name__] = re def reveal_type[T](obj: T, /) -> T: """Ask a static type checker to reveal the inferred type of an expression. When a static type checker encounters a call to ``reveal_type()``, it will emit the inferred type of the argument:: x: int = 1 reveal_type(x) Running a static type checker (e.g., mypy) on this example will produce output similar to 'Revealed type is "builtins.int"'. At runtime, the function prints the runtime type of the argument and returns the argument unchanged. """ print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr) return obj class _IdentityCallable(Protocol): def __call__[T](self, arg: T, /) -> T: ... def dataclass_transform( *, eq_default: bool = True, order_default: bool = False, kw_only_default: bool = False, frozen_default: bool = False, field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = (), **kwargs: Any, ) -> _IdentityCallable: """Decorator to mark an object as providing dataclass-like behaviour. The decorator can be applied to a function, class, or metaclass. Example usage with a decorator function:: @dataclass_transform() def create_model[T](cls: type[T]) -> type[T]: ... return cls @create_model class CustomerModel: id: int name: str On a base class:: @dataclass_transform() class ModelBase: ... class CustomerModel(ModelBase): id: int name: str On a metaclass:: @dataclass_transform() class ModelMeta(type): ... class ModelBase(metaclass=ModelMeta): ... class CustomerModel(ModelBase): id: int name: str The ``CustomerModel`` classes defined above will be treated by type checkers similarly to classes created with ``@dataclasses.dataclass``. For example, type checkers will assume these classes have ``__init__`` methods that accept ``id`` and ``name``. The arguments to this decorator can be used to customize this behavior: - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be ``True`` or ``False`` if it is omitted by the caller. - ``order_default`` indicates whether the ``order`` parameter is assumed to be True or False if it is omitted by the caller. - ``kw_only_default`` indicates whether the ``kw_only`` parameter is assumed to be True or False if it is omitted by the caller. - ``frozen_default`` indicates whether the ``frozen`` parameter is assumed to be True or False if it is omitted by the caller. - ``field_specifiers`` specifies a static list of supported classes or functions that describe fields, similar to ``dataclasses.field()``. - Arbitrary other keyword arguments are accepted in order to allow for possible future extensions. At runtime, this decorator records its arguments in the ``__dataclass_transform__`` attribute on the decorated object. It has no other runtime effect. See PEP 681 for more details. """ def decorator(cls_or_fn): cls_or_fn.__dataclass_transform__ = { "eq_default": eq_default, "order_default": order_default, "kw_only_default": kw_only_default, "frozen_default": frozen_default, "field_specifiers": field_specifiers, "kwargs": kwargs, } return cls_or_fn return decorator type _Func = Callable[..., Any] def override[F: _Func](method: F, /) -> F: """Indicate that a method is intended to override a method in a base class. Usage:: class Base: def method(self) -> None: pass class Child(Base): @override def method(self) -> None: super().method() When this decorator is applied to a method, the type checker will validate that it overrides a method or attribute with the same name on a base class. This helps prevent bugs that may occur when a base class is changed without an equivalent change to a child class. There is no runtime checking of this property. The decorator attempts to set the ``__override__`` attribute to ``True`` on the decorated object to allow runtime introspection. See PEP 698 for details. """ try: method.__override__ = True except (AttributeError, TypeError): # Skip the attribute silently if it is not writable. # AttributeError happens if the object has __slots__ or a # read-only property, TypeError if it's a builtin class. pass return method _sysconfigdata__linux_x86_64-linux-gnu.py000064400000214704152342670510014450 0ustar00# system configuration generated and used by the sysconfig module build_time_vars = {'ABIFLAGS': '', 'AC_APPLE_UNIVERSAL_BUILD': 0, 'AIX_BUILDDATE': 0, 'AIX_GENUINE_CPLUSPLUS': 0, 'ALIGNOF_LONG': 8, 'ALIGNOF_MAX_ALIGN_T': 16, 'ALIGNOF_SIZE_T': 8, 'ALT_SOABI': 0, 'ANDROID_API_LEVEL': 0, 'AR': 'ar', 'ARFLAGS': 'rcs', 'BASECFLAGS': '-fno-strict-overflow -Wsign-compare', 'BASECPPFLAGS': '-IObjects -IInclude -IPython', 'BASEMODLIBS': '', 'BINDIR': '/usr/bin', 'BINLIBDEST': '/usr/lib64/python3.12', 'BLDLIBRARY': '-L. -lpython3.12', 'BLDSHARED': 'gcc -pthread -shared -Wl,-z,relro -Wl,-z,now -Wl,-z,relro ' '-Wl,-z,now', 'BOOTSTRAP_HEADERS': '\\', 'BUILDEXE': '', 'BUILDPYTHON': 'python', 'BUILD_GNU_TYPE': 'x86_64-redhat-linux-gnu', 'BUILD_SCRIPTS_DIR': 'build/scripts-3.12', 'BYTESTR_DEPS': '\\', 'CC': 'gcc -pthread', 'CCSHARED': '-fPIC', 'CFLAGS': '-fno-strict-overflow -Wsign-compare ' '-DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection ' '-fcf-protection -O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection ' '-fcf-protection', 'CFLAGSFORSHARED': '-fPIC', 'CFLAGS_ALIASING': '', 'CODECS_COMMON_HEADERS': '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/multibytecodec.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/cjkcodecs.h', 'COMPILEALL_OPTS': '-j0', 'CONFIGFILES': 'configure configure.ac acconfig.h pyconfig.h.in ' 'Makefile.pre.in', 'CONFIGURE_CFLAGS': '-O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection ' '-fcf-protection', 'CONFIGURE_CFLAGS_NODIST': '-O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 ' '-m64 -mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection ' '-D_GNU_SOURCE -fPIC -fwrapv ' '-fno-semantic-interposition -flto ' '-fuse-linker-plugin -ffat-lto-objects ' '-flto-partition=none -g -std=c11 -Wextra ' '-Wno-unused-parameter ' '-Wno-missing-field-initializers ' '-Werror=implicit-function-declaration ' '-fvisibility=hidden', 'CONFIGURE_CPPFLAGS': '', 'CONFIGURE_LDFLAGS': '-Wl,-z,relro -Wl,-z,now', 'CONFIGURE_LDFLAGS_NODIST': '-Wl,-z,relro -Wl,-z,now ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-ld ' '-g -fno-semantic-interposition -flto ' '-fuse-linker-plugin -ffat-lto-objects ' '-flto-partition=none -g', 'CONFIGURE_LDFLAGS_NOLTO': '-fno-lto', 'CONFIG_ARGS': "'--build=x86_64-redhat-linux-gnu' " "'--host=x86_64-redhat-linux-gnu' '--program-prefix=' " "'--disable-dependency-tracking' '--prefix=/usr' " "'--exec-prefix=/usr' '--bindir=/usr/bin' " "'--sbindir=/usr/sbin' '--sysconfdir=/etc' " "'--datadir=/usr/share' '--includedir=/usr/include' " "'--libdir=/usr/lib64' '--libexecdir=/usr/libexec' " "'--localstatedir=/var' '--sharedstatedir=/var/lib' " "'--mandir=/usr/share/man' '--infodir=/usr/share/info' " "'--with-platlibdir=lib64' '--enable-ipv6' '--enable-shared' " "'--with-computed-gotos=yes' " "'--with-dbmliborder=gdbm:ndbm:bdb' '--with-system-expat' " "'--with-system-ffi' '--with-system-libmpdec' " "'--enable-loadable-sqlite-extensions' '--with-dtrace' " "'--with-lto' '--with-ssl-default-suites=openssl' " "'--with-builtin-hashlib-hashes=blake2' " "'--without-static-libpython' " "'--with-wheel-pkg-dir=/usr/share/python3.12-wheels' " "'--with-valgrind' '--without-ensurepip' " "'--enable-optimizations' " "'build_alias=x86_64-redhat-linux-gnu' " "'host_alias=x86_64-redhat-linux-gnu' " "'PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig' " "'CFLAGS= -O2 -g -pipe -Wall -Werror=format-security " '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong -grecord-gcc-switches ' '-m64 -mtune=generic -fasynchronous-unwind-tables ' "-fstack-clash-protection -fcf-protection ' 'LDFLAGS= " "-Wl,-z,relro -Wl,-z,now ' 'CPPFLAGS='", 'CONFINCLUDEDIR': '/usr/include', 'CONFINCLUDEPY': '/usr/include/python3.12', 'COREPYTHONPATH': '', 'COVERAGE_INFO': '/builddir/build/BUILD/Python-3.12.13/build/optimized/coverage.info', 'COVERAGE_LCOV_OPTIONS': '--rc lcov_branch_coverage=1', 'COVERAGE_REPORT': '/builddir/build/BUILD/Python-3.12.13/build/optimized/lcov-report', 'COVERAGE_REPORT_OPTIONS': '--rc lcov_branch_coverage=1 --branch-coverage ' '--title "CPython 3.12 LCOV report [commit $(shell ' ')]"', 'CPPFLAGS': '-IObjects -IInclude -IPython -I. ' '-I/builddir/build/BUILD/Python-3.12.13/Include', 'CXX': 'g++ -pthread', 'DEEPFREEZE_C': 'Python/deepfreeze/deepfreeze.c', 'DEEPFREEZE_DEPS': '/builddir/build/BUILD/Python-3.12.13/Tools/build/deepfreeze.py ' '_bootstrap_python ' '/builddir/build/BUILD/Python-3.12.13/Programs/_freeze_module.py ' '\\', 'DEEPFREEZE_OBJS': 'Python/deepfreeze/deepfreeze.o', 'DESTDIRS': '/usr /usr/lib64 /usr/lib64/python3.12 ' '/usr/lib64/python3.12/lib-dynload', 'DESTLIB': '/usr/lib64/python3.12', 'DESTPATH': '', 'DESTSHARED': '/usr/lib64/python3.12/lib-dynload', 'DFLAGS': '', 'DIRMODE': 755, 'DIST': 'README.rst ChangeLog configure configure.ac acconfig.h pyconfig.h.in ' 'Makefile.pre.in Include Lib Misc Ext-dummy', 'DISTDIRS': 'Include Lib Misc Ext-dummy', 'DISTFILES': 'README.rst ChangeLog configure configure.ac acconfig.h ' 'pyconfig.h.in Makefile.pre.in', 'DLINCLDIR': '.', 'DLLLIBRARY': '', 'DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754': 0, 'DOUBLE_IS_BIG_ENDIAN_IEEE754': 0, 'DOUBLE_IS_LITTLE_ENDIAN_IEEE754': 1, 'DSYMUTIL': '', 'DSYMUTIL_PATH': '', 'DTRACE': '/usr/bin/dtrace', 'DTRACE_DEPS': '\\', 'DTRACE_HEADERS': 'Include/pydtrace_probes.h', 'DTRACE_OBJS': 'Python/pydtrace.o', 'DYNLOADFILE': 'dynload_shlib.o', 'ENABLE_IPV6': 1, 'ENSUREPIP': 'no', 'EXE': '', 'EXEMODE': 755, 'EXENAME': '/usr/bin/python3.12', 'EXPORTSFROM': '', 'EXPORTSYMS': '', 'EXTRATESTOPTS': '', 'EXT_SUFFIX': '.cpython-312-x86_64-linux-gnu.so', 'FILEMODE': 644, 'FREEZE_MODULE': './_bootstrap_python ' '/builddir/build/BUILD/Python-3.12.13/Programs/_freeze_module.py', 'FREEZE_MODULE_BOOTSTRAP': './Programs/_freeze_module', 'FREEZE_MODULE_BOOTSTRAP_DEPS': 'Programs/_freeze_module', 'FREEZE_MODULE_DEPS': '_bootstrap_python ' '/builddir/build/BUILD/Python-3.12.13/Programs/_freeze_module.py', 'FROZEN_FILES_IN': '\\', 'FROZEN_FILES_OUT': '\\', 'GETPGRP_HAVE_ARG': 0, 'GITBRANCH': '', 'GITTAG': '', 'GITVERSION': '', 'GNULD': 'yes', 'HAVE_ACCEPT': 1, 'HAVE_ACCEPT4': 1, 'HAVE_ACOSH': 1, 'HAVE_ADDRINFO': 1, 'HAVE_ALARM': 1, 'HAVE_ALIGNED_REQUIRED': 0, 'HAVE_ALLOCA_H': 1, 'HAVE_ALTZONE': 0, 'HAVE_ASINH': 1, 'HAVE_ASM_TYPES_H': 1, 'HAVE_ATANH': 1, 'HAVE_BIND': 1, 'HAVE_BIND_TEXTDOMAIN_CODESET': 1, 'HAVE_BLUETOOTH_BLUETOOTH_H': 1, 'HAVE_BLUETOOTH_H': 0, 'HAVE_BROKEN_MBSTOWCS': 0, 'HAVE_BROKEN_NICE': 0, 'HAVE_BROKEN_PIPE_BUF': 0, 'HAVE_BROKEN_POLL': 0, 'HAVE_BROKEN_POSIX_SEMAPHORES': 0, 'HAVE_BROKEN_PTHREAD_SIGMASK': 0, 'HAVE_BROKEN_SEM_GETVALUE': 0, 'HAVE_BROKEN_UNSETENV': 0, 'HAVE_BUILTIN_ATOMIC': 1, 'HAVE_BZLIB_H': 0, 'HAVE_CHFLAGS': 0, 'HAVE_CHMOD': 1, 'HAVE_CHOWN': 1, 'HAVE_CHROOT': 1, 'HAVE_CLOCK': 1, 'HAVE_CLOCK_GETRES': 1, 'HAVE_CLOCK_GETTIME': 1, 'HAVE_CLOCK_NANOSLEEP': 1, 'HAVE_CLOCK_SETTIME': 1, 'HAVE_CLOSE_RANGE': 0, 'HAVE_COMPUTED_GOTOS': 1, 'HAVE_CONFSTR': 1, 'HAVE_CONIO_H': 0, 'HAVE_CONNECT': 1, 'HAVE_COPY_FILE_RANGE': 1, 'HAVE_CRYPT_H': 1, 'HAVE_CRYPT_R': 1, 'HAVE_CTERMID': 1, 'HAVE_CTERMID_R': 0, 'HAVE_CURSES_FILTER': 1, 'HAVE_CURSES_H': 1, 'HAVE_CURSES_HAS_KEY': 1, 'HAVE_CURSES_IMMEDOK': 1, 'HAVE_CURSES_IS_PAD': 1, 'HAVE_CURSES_IS_TERM_RESIZED': 1, 'HAVE_CURSES_RESIZETERM': 1, 'HAVE_CURSES_RESIZE_TERM': 1, 'HAVE_CURSES_SYNCOK': 1, 'HAVE_CURSES_TYPEAHEAD': 1, 'HAVE_CURSES_USE_ENV': 1, 'HAVE_CURSES_WCHGAT': 1, 'HAVE_DB_H': 0, 'HAVE_DECL_RTLD_DEEPBIND': 1, 'HAVE_DECL_RTLD_GLOBAL': 1, 'HAVE_DECL_RTLD_LAZY': 1, 'HAVE_DECL_RTLD_LOCAL': 1, 'HAVE_DECL_RTLD_MEMBER': 0, 'HAVE_DECL_RTLD_NODELETE': 1, 'HAVE_DECL_RTLD_NOLOAD': 1, 'HAVE_DECL_RTLD_NOW': 1, 'HAVE_DECL_TZNAME': 0, 'HAVE_DEVICE_MACROS': 1, 'HAVE_DEV_PTC': 0, 'HAVE_DEV_PTMX': 1, 'HAVE_DIRECT_H': 0, 'HAVE_DIRENT_D_TYPE': 1, 'HAVE_DIRENT_H': 1, 'HAVE_DIRFD': 1, 'HAVE_DLFCN_H': 1, 'HAVE_DLOPEN': 1, 'HAVE_DUP': 1, 'HAVE_DUP2': 1, 'HAVE_DUP3': 1, 'HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH': 0, 'HAVE_DYNAMIC_LOADING': 1, 'HAVE_EDITLINE_READLINE_H': 0, 'HAVE_ENDIAN_H': 1, 'HAVE_EPOLL': 1, 'HAVE_EPOLL_CREATE1': 1, 'HAVE_ERF': 1, 'HAVE_ERFC': 1, 'HAVE_ERRNO_H': 1, 'HAVE_EVENTFD': 1, 'HAVE_EXECV': 1, 'HAVE_EXPLICIT_BZERO': 1, 'HAVE_EXPLICIT_MEMSET': 0, 'HAVE_EXPM1': 1, 'HAVE_FACCESSAT': 1, 'HAVE_FCHDIR': 1, 'HAVE_FCHMOD': 1, 'HAVE_FCHMODAT': 1, 'HAVE_FCHOWN': 1, 'HAVE_FCHOWNAT': 1, 'HAVE_FCNTL_H': 1, 'HAVE_FDATASYNC': 1, 'HAVE_FDOPENDIR': 1, 'HAVE_FDWALK': 0, 'HAVE_FEXECVE': 1, 'HAVE_FFI_CLOSURE_ALLOC': 1, 'HAVE_FFI_PREP_CIF_VAR': 1, 'HAVE_FFI_PREP_CLOSURE_LOC': 1, 'HAVE_FLOCK': 1, 'HAVE_FORK': 1, 'HAVE_FORK1': 0, 'HAVE_FORKPTY': 1, 'HAVE_FPATHCONF': 1, 'HAVE_FSEEK64': 0, 'HAVE_FSEEKO': 1, 'HAVE_FSTATAT': 1, 'HAVE_FSTATVFS': 1, 'HAVE_FSYNC': 1, 'HAVE_FTELL64': 0, 'HAVE_FTELLO': 1, 'HAVE_FTIME': 1, 'HAVE_FTRUNCATE': 1, 'HAVE_FUTIMENS': 1, 'HAVE_FUTIMES': 1, 'HAVE_FUTIMESAT': 1, 'HAVE_GAI_STRERROR': 1, 'HAVE_GCC_ASM_FOR_MC68881': 0, 'HAVE_GCC_ASM_FOR_X64': 1, 'HAVE_GCC_ASM_FOR_X87': 1, 'HAVE_GCC_UINT128_T': 1, 'HAVE_GDBM_DASH_NDBM_H': 0, 'HAVE_GDBM_H': 1, 'HAVE_GDBM_NDBM_H': 1, 'HAVE_GETADDRINFO': 1, 'HAVE_GETC_UNLOCKED': 1, 'HAVE_GETEGID': 1, 'HAVE_GETENTROPY': 1, 'HAVE_GETEUID': 1, 'HAVE_GETGID': 1, 'HAVE_GETGRGID': 1, 'HAVE_GETGRGID_R': 1, 'HAVE_GETGRNAM_R': 1, 'HAVE_GETGROUPLIST': 1, 'HAVE_GETGROUPS': 1, 'HAVE_GETHOSTBYADDR': 1, 'HAVE_GETHOSTBYNAME': 1, 'HAVE_GETHOSTBYNAME_R': 1, 'HAVE_GETHOSTBYNAME_R_3_ARG': 0, 'HAVE_GETHOSTBYNAME_R_5_ARG': 0, 'HAVE_GETHOSTBYNAME_R_6_ARG': 1, 'HAVE_GETHOSTNAME': 1, 'HAVE_GETITIMER': 1, 'HAVE_GETLOADAVG': 1, 'HAVE_GETLOGIN': 1, 'HAVE_GETNAMEINFO': 1, 'HAVE_GETPAGESIZE': 1, 'HAVE_GETPEERNAME': 1, 'HAVE_GETPGID': 1, 'HAVE_GETPGRP': 1, 'HAVE_GETPID': 1, 'HAVE_GETPPID': 1, 'HAVE_GETPRIORITY': 1, 'HAVE_GETPROTOBYNAME': 1, 'HAVE_GETPWENT': 1, 'HAVE_GETPWNAM_R': 1, 'HAVE_GETPWUID': 1, 'HAVE_GETPWUID_R': 1, 'HAVE_GETRANDOM': 1, 'HAVE_GETRANDOM_SYSCALL': 1, 'HAVE_GETRESGID': 1, 'HAVE_GETRESUID': 1, 'HAVE_GETRUSAGE': 1, 'HAVE_GETSERVBYNAME': 1, 'HAVE_GETSERVBYPORT': 1, 'HAVE_GETSID': 1, 'HAVE_GETSOCKNAME': 1, 'HAVE_GETSPENT': 1, 'HAVE_GETSPNAM': 1, 'HAVE_GETUID': 1, 'HAVE_GETWD': 1, 'HAVE_GLIBC_MEMMOVE_BUG': 0, 'HAVE_GRP_H': 1, 'HAVE_HSTRERROR': 1, 'HAVE_HTOLE64': 1, 'HAVE_IEEEFP_H': 0, 'HAVE_IF_NAMEINDEX': 1, 'HAVE_INET_ATON': 1, 'HAVE_INET_NTOA': 1, 'HAVE_INET_PTON': 1, 'HAVE_INITGROUPS': 1, 'HAVE_INTTYPES_H': 1, 'HAVE_IO_H': 0, 'HAVE_IPA_PURE_CONST_BUG': 0, 'HAVE_KILL': 1, 'HAVE_KILLPG': 1, 'HAVE_KQUEUE': 0, 'HAVE_LANGINFO_H': 1, 'HAVE_LARGEFILE_SUPPORT': 0, 'HAVE_LCHFLAGS': 0, 'HAVE_LCHMOD': 0, 'HAVE_LCHOWN': 1, 'HAVE_LIBB2': 0, 'HAVE_LIBDB': 0, 'HAVE_LIBDL': 1, 'HAVE_LIBDLD': 0, 'HAVE_LIBIEEE': 0, 'HAVE_LIBINTL_H': 1, 'HAVE_LIBRESOLV': 0, 'HAVE_LIBSENDFILE': 0, 'HAVE_LIBSQLITE3': 1, 'HAVE_LIBUTIL_H': 0, 'HAVE_LINK': 1, 'HAVE_LINKAT': 1, 'HAVE_LINUX_AUXVEC_H': 1, 'HAVE_LINUX_CAN_BCM_H': 1, 'HAVE_LINUX_CAN_H': 1, 'HAVE_LINUX_CAN_J1939_H': 0, 'HAVE_LINUX_CAN_RAW_FD_FRAMES': 1, 'HAVE_LINUX_CAN_RAW_H': 1, 'HAVE_LINUX_CAN_RAW_JOIN_FILTERS': 1, 'HAVE_LINUX_FS_H': 1, 'HAVE_LINUX_LIMITS_H': 1, 'HAVE_LINUX_MEMFD_H': 1, 'HAVE_LINUX_NETLINK_H': 1, 'HAVE_LINUX_QRTR_H': 1, 'HAVE_LINUX_RANDOM_H': 1, 'HAVE_LINUX_SOUNDCARD_H': 1, 'HAVE_LINUX_TIPC_H': 1, 'HAVE_LINUX_VM_SOCKETS_H': 1, 'HAVE_LINUX_WAIT_H': 1, 'HAVE_LISTEN': 1, 'HAVE_LOCKF': 1, 'HAVE_LOG1P': 1, 'HAVE_LOG2': 1, 'HAVE_LOGIN_TTY': 1, 'HAVE_LONG_DOUBLE': 1, 'HAVE_LSTAT': 1, 'HAVE_LUTIMES': 1, 'HAVE_LZMA_H': 0, 'HAVE_MADVISE': 1, 'HAVE_MAKEDEV': 1, 'HAVE_MBRTOWC': 1, 'HAVE_MEMFD_CREATE': 1, 'HAVE_MEMORY_H': 1, 'HAVE_MEMRCHR': 1, 'HAVE_MKDIRAT': 1, 'HAVE_MKFIFO': 1, 'HAVE_MKFIFOAT': 1, 'HAVE_MKNOD': 1, 'HAVE_MKNODAT': 1, 'HAVE_MKTIME': 1, 'HAVE_MMAP': 1, 'HAVE_MREMAP': 1, 'HAVE_NANOSLEEP': 1, 'HAVE_NCURSESW': 1, 'HAVE_NCURSES_H': 1, 'HAVE_NDBM_H': 1, 'HAVE_NDIR_H': 0, 'HAVE_NETCAN_CAN_H': 0, 'HAVE_NETDB_H': 1, 'HAVE_NETINET_IN_H': 1, 'HAVE_NETPACKET_PACKET_H': 1, 'HAVE_NET_ETHERNET_H': 1, 'HAVE_NET_IF_H': 1, 'HAVE_NICE': 1, 'HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION': 0, 'HAVE_OPENAT': 1, 'HAVE_OPENDIR': 1, 'HAVE_OPENPTY': 1, 'HAVE_PANEL_H': 1, 'HAVE_PATHCONF': 1, 'HAVE_PAUSE': 1, 'HAVE_PIPE': 1, 'HAVE_PIPE2': 1, 'HAVE_PLOCK': 0, 'HAVE_POLL': 1, 'HAVE_POLL_H': 1, 'HAVE_POSIX_FADVISE': 1, 'HAVE_POSIX_FALLOCATE': 1, 'HAVE_POSIX_SPAWN': 1, 'HAVE_POSIX_SPAWNP': 1, 'HAVE_PREAD': 1, 'HAVE_PREADV': 1, 'HAVE_PREADV2': 1, 'HAVE_PRLIMIT': 1, 'HAVE_PROCESS_H': 0, 'HAVE_PROTOTYPES': 1, 'HAVE_PTHREAD_CONDATTR_SETCLOCK': 1, 'HAVE_PTHREAD_DESTRUCTOR': 0, 'HAVE_PTHREAD_GETCPUCLOCKID': 1, 'HAVE_PTHREAD_H': 1, 'HAVE_PTHREAD_INIT': 0, 'HAVE_PTHREAD_KILL': 1, 'HAVE_PTHREAD_SIGMASK': 1, 'HAVE_PTHREAD_STUBS': 0, 'HAVE_PTY_H': 1, 'HAVE_PWRITE': 1, 'HAVE_PWRITEV': 1, 'HAVE_PWRITEV2': 1, 'HAVE_READLINE_READLINE_H': 1, 'HAVE_READLINK': 1, 'HAVE_READLINKAT': 1, 'HAVE_READV': 1, 'HAVE_REALPATH': 1, 'HAVE_RECVFROM': 1, 'HAVE_RENAMEAT': 1, 'HAVE_RL_APPEND_HISTORY': 1, 'HAVE_RL_CATCH_SIGNAL': 1, 'HAVE_RL_COMPDISP_FUNC_T': 1, 'HAVE_RL_COMPLETION_APPEND_CHARACTER': 1, 'HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK': 1, 'HAVE_RL_COMPLETION_MATCHES': 1, 'HAVE_RL_COMPLETION_SUPPRESS_APPEND': 1, 'HAVE_RL_PRE_INPUT_HOOK': 1, 'HAVE_RL_RESIZE_TERMINAL': 1, 'HAVE_RPC_RPC_H': 1, 'HAVE_RTPSPAWN': 0, 'HAVE_SCHED_GET_PRIORITY_MAX': 1, 'HAVE_SCHED_H': 1, 'HAVE_SCHED_RR_GET_INTERVAL': 1, 'HAVE_SCHED_SETAFFINITY': 1, 'HAVE_SCHED_SETPARAM': 1, 'HAVE_SCHED_SETSCHEDULER': 1, 'HAVE_SEM_CLOCKWAIT': 0, 'HAVE_SEM_GETVALUE': 1, 'HAVE_SEM_OPEN': 1, 'HAVE_SEM_TIMEDWAIT': 1, 'HAVE_SEM_UNLINK': 1, 'HAVE_SENDFILE': 1, 'HAVE_SENDTO': 1, 'HAVE_SETEGID': 1, 'HAVE_SETEUID': 1, 'HAVE_SETGID': 1, 'HAVE_SETGROUPS': 1, 'HAVE_SETHOSTNAME': 1, 'HAVE_SETITIMER': 1, 'HAVE_SETJMP_H': 1, 'HAVE_SETLOCALE': 1, 'HAVE_SETNS': 1, 'HAVE_SETPGID': 1, 'HAVE_SETPGRP': 1, 'HAVE_SETPRIORITY': 1, 'HAVE_SETREGID': 1, 'HAVE_SETRESGID': 1, 'HAVE_SETRESUID': 1, 'HAVE_SETREUID': 1, 'HAVE_SETSID': 1, 'HAVE_SETSOCKOPT': 1, 'HAVE_SETUID': 1, 'HAVE_SETVBUF': 1, 'HAVE_SHADOW_H': 1, 'HAVE_SHM_OPEN': 1, 'HAVE_SHM_UNLINK': 1, 'HAVE_SHUTDOWN': 1, 'HAVE_SIGACTION': 1, 'HAVE_SIGALTSTACK': 1, 'HAVE_SIGFILLSET': 1, 'HAVE_SIGINFO_T_SI_BAND': 1, 'HAVE_SIGINTERRUPT': 1, 'HAVE_SIGNAL_H': 1, 'HAVE_SIGPENDING': 1, 'HAVE_SIGRELSE': 1, 'HAVE_SIGTIMEDWAIT': 1, 'HAVE_SIGWAIT': 1, 'HAVE_SIGWAITINFO': 1, 'HAVE_SNPRINTF': 1, 'HAVE_SOCKADDR_ALG': 1, 'HAVE_SOCKADDR_SA_LEN': 0, 'HAVE_SOCKADDR_STORAGE': 1, 'HAVE_SOCKET': 1, 'HAVE_SOCKETPAIR': 1, 'HAVE_SPAWN_H': 1, 'HAVE_SPLICE': 1, 'HAVE_SSIZE_T': 1, 'HAVE_STATVFS': 1, 'HAVE_STAT_TV_NSEC': 1, 'HAVE_STAT_TV_NSEC2': 0, 'HAVE_STDINT_H': 1, 'HAVE_STDLIB_H': 1, 'HAVE_STD_ATOMIC': 1, 'HAVE_STRFTIME': 1, 'HAVE_STRINGS_H': 1, 'HAVE_STRING_H': 1, 'HAVE_STRLCPY': 0, 'HAVE_STROPTS_H': 0, 'HAVE_STRSIGNAL': 1, 'HAVE_STRUCT_PASSWD_PW_GECOS': 1, 'HAVE_STRUCT_PASSWD_PW_PASSWD': 1, 'HAVE_STRUCT_STAT_ST_BIRTHTIME': 0, 'HAVE_STRUCT_STAT_ST_BLKSIZE': 1, 'HAVE_STRUCT_STAT_ST_BLOCKS': 1, 'HAVE_STRUCT_STAT_ST_FLAGS': 0, 'HAVE_STRUCT_STAT_ST_GEN': 0, 'HAVE_STRUCT_STAT_ST_RDEV': 1, 'HAVE_STRUCT_TM_TM_ZONE': 1, 'HAVE_SYMLINK': 1, 'HAVE_SYMLINKAT': 1, 'HAVE_SYNC': 1, 'HAVE_SYSCONF': 1, 'HAVE_SYSEXITS_H': 1, 'HAVE_SYSLOG_H': 1, 'HAVE_SYSTEM': 1, 'HAVE_SYS_AUDIOIO_H': 0, 'HAVE_SYS_AUXV_H': 1, 'HAVE_SYS_BSDTTY_H': 0, 'HAVE_SYS_DEVPOLL_H': 0, 'HAVE_SYS_DIR_H': 0, 'HAVE_SYS_ENDIAN_H': 0, 'HAVE_SYS_EPOLL_H': 1, 'HAVE_SYS_EVENTFD_H': 1, 'HAVE_SYS_EVENT_H': 0, 'HAVE_SYS_FILE_H': 1, 'HAVE_SYS_IOCTL_H': 1, 'HAVE_SYS_KERN_CONTROL_H': 0, 'HAVE_SYS_LOADAVG_H': 0, 'HAVE_SYS_LOCK_H': 0, 'HAVE_SYS_MEMFD_H': 0, 'HAVE_SYS_MKDEV_H': 0, 'HAVE_SYS_MMAN_H': 1, 'HAVE_SYS_MODEM_H': 0, 'HAVE_SYS_NDIR_H': 0, 'HAVE_SYS_PARAM_H': 1, 'HAVE_SYS_PIDFD_H': 0, 'HAVE_SYS_POLL_H': 1, 'HAVE_SYS_RANDOM_H': 1, 'HAVE_SYS_RESOURCE_H': 1, 'HAVE_SYS_SELECT_H': 1, 'HAVE_SYS_SENDFILE_H': 1, 'HAVE_SYS_SOCKET_H': 1, 'HAVE_SYS_SOUNDCARD_H': 1, 'HAVE_SYS_STATVFS_H': 1, 'HAVE_SYS_STAT_H': 1, 'HAVE_SYS_SYSCALL_H': 1, 'HAVE_SYS_SYSMACROS_H': 1, 'HAVE_SYS_SYS_DOMAIN_H': 0, 'HAVE_SYS_TERMIO_H': 0, 'HAVE_SYS_TIMES_H': 1, 'HAVE_SYS_TIME_H': 1, 'HAVE_SYS_TYPES_H': 1, 'HAVE_SYS_UIO_H': 1, 'HAVE_SYS_UN_H': 1, 'HAVE_SYS_UTSNAME_H': 1, 'HAVE_SYS_WAIT_H': 1, 'HAVE_SYS_XATTR_H': 1, 'HAVE_TCGETPGRP': 1, 'HAVE_TCSETPGRP': 1, 'HAVE_TEMPNAM': 1, 'HAVE_TERMIOS_H': 1, 'HAVE_TERM_H': 1, 'HAVE_TIMEGM': 1, 'HAVE_TIMES': 1, 'HAVE_TMPFILE': 1, 'HAVE_TMPNAM': 1, 'HAVE_TMPNAM_R': 1, 'HAVE_TM_ZONE': 1, 'HAVE_TRUNCATE': 1, 'HAVE_TTYNAME_R': 1, 'HAVE_TZNAME': 0, 'HAVE_UMASK': 1, 'HAVE_UNAME': 1, 'HAVE_UNISTD_H': 1, 'HAVE_UNLINKAT': 1, 'HAVE_UNSHARE': 1, 'HAVE_USABLE_WCHAR_T': 0, 'HAVE_UTIL_H': 0, 'HAVE_UTIMENSAT': 1, 'HAVE_UTIMES': 1, 'HAVE_UTIME_H': 1, 'HAVE_UTMP_H': 1, 'HAVE_UUID_CREATE': 0, 'HAVE_UUID_ENC_BE': 0, 'HAVE_UUID_GENERATE_TIME_SAFE': 1, 'HAVE_UUID_H': 1, 'HAVE_UUID_UUID_H': 0, 'HAVE_VFORK': 1, 'HAVE_WAIT': 1, 'HAVE_WAIT3': 1, 'HAVE_WAIT4': 1, 'HAVE_WAITID': 1, 'HAVE_WAITPID': 1, 'HAVE_WCHAR_H': 1, 'HAVE_WCSCOLL': 1, 'HAVE_WCSFTIME': 1, 'HAVE_WCSXFRM': 1, 'HAVE_WMEMCMP': 1, 'HAVE_WORKING_TZSET': 1, 'HAVE_WRITEV': 1, 'HAVE_ZLIB_COPY': 1, 'HAVE_ZLIB_H': 0, 'HAVE__GETPTY': 0, 'HOSTRUNNER': '', 'HOST_GNU_TYPE': 'x86_64-redhat-linux-gnu', 'INCLDIRSTOMAKE': '/usr/include /usr/include /usr/include/python3.12 ' '/usr/include/python3.12', 'INCLUDEDIR': '/usr/include', 'INCLUDEPY': '/usr/include/python3.12', 'INSTALL': '/usr/bin/install -c', 'INSTALL_DATA': '/usr/bin/install -c -m 644', 'INSTALL_PROGRAM': '/usr/bin/install -c', 'INSTALL_SCRIPT': '/usr/bin/install -c', 'INSTALL_SHARED': '/usr/bin/install -c -m 755', 'INSTSONAME': 'libpython3.12.so.1.0', 'IO_H': 'Modules/_io/_iomodule.h', 'IO_OBJS': '\\', 'LDCXXSHARED': 'g++ -pthread -shared -Wl,-z,relro -Wl,-z,now -Wl,-z,relro ' '-Wl,-z,now', 'LDFLAGS': '-Wl,-z,relro -Wl,-z,now -Wl,-z,relro -Wl,-z,now', 'LDLIBRARY': 'libpython3.12.so', 'LDLIBRARYDIR': '', 'LDSHARED': 'gcc -pthread -shared -Wl,-z,relro -Wl,-z,now -Wl,-z,relro ' '-Wl,-z,now', 'LDVERSION': '3.12', 'LIBC': '', 'LIBDEST': '/usr/lib64/python3.12', 'LIBDIR': '/usr/lib64', 'LIBEXPAT_A': 'Modules/expat/libexpat.a', 'LIBEXPAT_CFLAGS': '-fno-strict-overflow -Wsign-compare ' '-DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -fno-semantic-interposition -flto ' '-fuse-linker-plugin -ffat-lto-objects ' '-flto-partition=none -g -std=c11 -Wextra ' '-Wno-unused-parameter -Wno-missing-field-initializers ' '-Werror=implicit-function-declaration -fvisibility=hidden ' '-O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -O3 -fprofile-use -fprofile-correction ' '-I/builddir/build/BUILD/Python-3.12.13/Include/internal ' '-IObjects -IInclude -IPython -I. ' '-I/builddir/build/BUILD/Python-3.12.13/Include -fPIC ' '-fPIC', 'LIBEXPAT_HEADERS': '\\', 'LIBEXPAT_OBJS': '\\', 'LIBHACL_CFLAGS': '-I/builddir/build/BUILD/Python-3.12.13/Modules/_hacl/include ' '-D_BSD_SOURCE -D_DEFAULT_SOURCE -fno-strict-overflow ' '-Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG ' '-O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection ' '-fcf-protection -O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection ' '-fcf-protection -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -fno-semantic-interposition -flto ' '-fuse-linker-plugin -ffat-lto-objects -flto-partition=none ' '-g -std=c11 -Wextra -Wno-unused-parameter ' '-Wno-missing-field-initializers ' '-Werror=implicit-function-declaration -fvisibility=hidden ' '-O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -O3 -fprofile-use -fprofile-correction ' '-I/builddir/build/BUILD/Python-3.12.13/Include/internal ' '-IObjects -IInclude -IPython -I. ' '-I/builddir/build/BUILD/Python-3.12.13/Include -fPIC -fPIC', 'LIBHACL_HEADERS': '\\', 'LIBHACL_SHA2_A': 'Modules/_hacl/libHacl_Hash_SHA2.a', 'LIBHACL_SHA2_HEADERS': '\\', 'LIBHACL_SHA2_OBJS': '\\', 'LIBM': '-lm', 'LIBMPDEC_A': 'Modules/_decimal/libmpdec/libmpdec.a', 'LIBMPDEC_CFLAGS': '-DCONFIG_64=1 -DANSI=1 -DHAVE_UINT128_T=1 ' '-fno-strict-overflow -Wsign-compare ' '-DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -fno-semantic-interposition -flto ' '-fuse-linker-plugin -ffat-lto-objects ' '-flto-partition=none -g -std=c11 -Wextra ' '-Wno-unused-parameter -Wno-missing-field-initializers ' '-Werror=implicit-function-declaration -fvisibility=hidden ' '-O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -O3 -fprofile-use -fprofile-correction ' '-I/builddir/build/BUILD/Python-3.12.13/Include/internal ' '-IObjects -IInclude -IPython -I. ' '-I/builddir/build/BUILD/Python-3.12.13/Include -fPIC ' '-fPIC', 'LIBMPDEC_HEADERS': '\\', 'LIBMPDEC_OBJS': '\\', 'LIBOBJDIR': 'Python/', 'LIBOBJS': '', 'LIBPC': '/usr/lib64/pkgconfig', 'LIBPL': '/usr/lib64/python3.12/config-3.12-x86_64-linux-gnu', 'LIBPYTHON': '', 'LIBRARY': 'libpython3.12.a', 'LIBRARY_DEPS': 'libpython3.12.so libpython3.so', 'LIBRARY_OBJS': '\\', 'LIBRARY_OBJS_OMIT_FROZEN': '\\', 'LIBS': '-lpthread -ldl -lutil', 'LIBSUBDIRS': 'asyncio \\', 'LINKCC': 'gcc', 'LINKFORSHARED': '-Xlinker -export-dynamic', 'LINK_PYTHON_DEPS': 'libpython3.12.so libpython3.so', 'LINK_PYTHON_OBJS': '-L. -lpython3.12', 'LIPO_32BIT_FLAGS': '', 'LIPO_INTEL64_FLAGS': '', 'LLVM_PROF_ERR': 'no', 'LLVM_PROF_FILE': '', 'LLVM_PROF_MERGER': 'true', 'LN': 'ln', 'LOCALMODLIBS': '', 'MACHDEP': 'linux', 'MACHDEP_OBJS': '', 'MACHDESTLIB': '/usr/lib64/python3.12', 'MACOSX_DEPLOYMENT_TARGET': '', 'MAJOR_IN_MKDEV': 0, 'MAJOR_IN_SYSMACROS': 1, 'MAKESETUP': '/builddir/build/BUILD/Python-3.12.13/Modules/makesetup', 'MANDIR': '/usr/share/man', 'MKDIR_P': '/usr/bin/mkdir -p', 'MODBUILT_NAMES': 'array _asyncio _bisect _contextvars _csv _heapq ' '_json _lsprof _opcode _pickle _queue _random ' '_struct _xxsubinterpreters _xxinterpchannels _zoneinfo ' 'audioop math cmath _statistics _datetime _decimal ' 'binascii _bz2 _lzma zlib _dbm _gdbm readline ' '_blake2 pyexpat _elementtree _codecs_cn _codecs_hk ' '_codecs_iso2022 _codecs_jp _codecs_kr _codecs_tw ' '_multibytecodec unicodedata _crypt fcntl grp mmap ' 'nis ossaudiodev _posixsubprocess resource select ' '_socket spwd syslog termios _posixshmem ' '_multiprocessing _ctypes _curses _curses_panel ' '_sqlite3 _ssl _hashlib _uuid _tkinter xxsubtype ' '_xxtestfuzz _testbuffer _testinternalcapi _testcapi ' '_testclinic _testimportmultiple _testmultiphase ' '_testsinglephase _ctypes_test xxlimited xxlimited_35 ' 'atexit faulthandler posix _signal _tracemalloc ' '_codecs _collections errno _io itertools _sre ' '_thread time _typing _weakref _abc _functools ' '_locale _operator _stat _symtable pwd', 'MODDISABLED_NAMES': '', 'MODLIBS': '', 'MODOBJS': 'Modules/atexitmodule.o Modules/faulthandler.o ' 'Modules/posixmodule.o Modules/signalmodule.o ' 'Modules/_tracemalloc.o Modules/_codecsmodule.o ' 'Modules/_collectionsmodule.o Modules/errnomodule.o ' 'Modules/_io/_iomodule.o Modules/_io/iobase.o Modules/_io/fileio.o ' 'Modules/_io/bytesio.o Modules/_io/bufferedio.o ' 'Modules/_io/textio.o Modules/_io/stringio.o ' 'Modules/itertoolsmodule.o Modules/_sre/sre.o ' 'Modules/_threadmodule.o Modules/timemodule.o ' 'Modules/_typingmodule.o Modules/_weakref.o Modules/_abc.o ' 'Modules/_functoolsmodule.o Modules/_localemodule.o ' 'Modules/_operator.o Modules/_stat.o Modules/symtablemodule.o ' 'Modules/pwdmodule.o', 'MODSHARED_NAMES': 'array _asyncio _bisect _contextvars _csv _heapq _json ' '_lsprof _opcode _pickle _queue _random _struct ' '_xxsubinterpreters _xxinterpchannels _zoneinfo audioop ' 'math cmath _statistics _datetime _decimal binascii _bz2 ' '_lzma zlib _dbm _gdbm readline _blake2 pyexpat ' '_elementtree _codecs_cn _codecs_hk _codecs_iso2022 ' '_codecs_jp _codecs_kr _codecs_tw _multibytecodec ' 'unicodedata _crypt fcntl grp mmap nis ossaudiodev ' '_posixsubprocess resource select _socket spwd syslog ' 'termios _posixshmem _multiprocessing _ctypes _curses ' '_curses_panel _sqlite3 _ssl _hashlib _uuid _tkinter ' 'xxsubtype _xxtestfuzz _testbuffer _testinternalcapi ' '_testcapi _testclinic _testimportmultiple _testmultiphase ' '_testsinglephase _ctypes_test xxlimited xxlimited_35', 'MODULE_ARRAY_STATE': 'yes', 'MODULE_ATEXIT_LDFLAGS': '', 'MODULE_AUDIOOP_LDFLAGS': '-lm', 'MODULE_AUDIOOP_STATE': 'yes', 'MODULE_BINASCII_CFLAGS': '-DUSE_ZLIB_CRC32', 'MODULE_BINASCII_LDFLAGS': '-lz', 'MODULE_BINASCII_STATE': 'yes', 'MODULE_CMATH_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/_math.h', 'MODULE_CMATH_LDFLAGS': '-lm', 'MODULE_CMATH_STATE': 'yes', 'MODULE_DEPS_SHARED': 'Modules/config.c', 'MODULE_DEPS_STATIC': 'Modules/config.c', 'MODULE_ERRNO_LDFLAGS': '', 'MODULE_FAULTHANDLER_LDFLAGS': '', 'MODULE_FCNTL_LDFLAGS': '', 'MODULE_FCNTL_STATE': 'yes', 'MODULE_GRP_STATE': 'yes', 'MODULE_ITERTOOLS_LDFLAGS': '', 'MODULE_MATH_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/_math.h', 'MODULE_MATH_LDFLAGS': '-lm', 'MODULE_MATH_STATE': 'yes', 'MODULE_MMAP_STATE': 'yes', 'MODULE_NIS_CFLAGS': '-I/usr/include/tirpc', 'MODULE_NIS_LDFLAGS': '-lnsl -ltirpc', 'MODULE_NIS_STATE': 'yes', 'MODULE_OBJS': '\\', 'MODULE_OSSAUDIODEV_LDFLAGS': '', 'MODULE_OSSAUDIODEV_STATE': 'yes', 'MODULE_POSIX_LDFLAGS': '', 'MODULE_PWD_LDFLAGS': '', 'MODULE_PWD_STATE': 'yes', 'MODULE_PYEXPAT_CFLAGS': '', 'MODULE_PYEXPAT_DEPS': '', 'MODULE_PYEXPAT_LDFLAGS': '-lexpat', 'MODULE_PYEXPAT_STATE': 'yes', 'MODULE_READLINE_CFLAGS': '', 'MODULE_READLINE_LDFLAGS': '-lreadline', 'MODULE_READLINE_STATE': 'yes', 'MODULE_RESOURCE_STATE': 'yes', 'MODULE_SELECT_STATE': 'yes', 'MODULE_SPWD_STATE': 'yes', 'MODULE_SYSLOG_STATE': 'yes', 'MODULE_TERMIOS_STATE': 'yes', 'MODULE_TIME_LDFLAGS': '', 'MODULE_TIME_STATE': 'yes', 'MODULE_UNICODEDATA_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/unicodedata_db.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/unicodename_db.h', 'MODULE_UNICODEDATA_STATE': 'yes', 'MODULE_XXLIMITED_35_STATE': 'yes', 'MODULE_XXLIMITED_STATE': 'yes', 'MODULE_XXSUBTYPE_STATE': 'yes', 'MODULE_ZLIB_CFLAGS': '', 'MODULE_ZLIB_LDFLAGS': '-lz', 'MODULE_ZLIB_STATE': 'yes', 'MODULE__ABC_LDFLAGS': '', 'MODULE__ASYNCIO_STATE': 'yes', 'MODULE__BISECT_STATE': 'yes', 'MODULE__BLAKE2_CFLAGS': '', 'MODULE__BLAKE2_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2-config.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2-impl.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2b-load-sse2.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2b-load-sse41.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2b-ref.c ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2b-round.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2b.c ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2s-load-sse2.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2s-load-sse41.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2s-load-xop.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2s-ref.c ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2s-round.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/impl/blake2s.c ' '/builddir/build/BUILD/Python-3.12.13/Modules/_blake2/blake2module.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/hashlib.h', 'MODULE__BLAKE2_LDFLAGS': '-lssl -lcrypto', 'MODULE__BLAKE2_STATE': 'yes', 'MODULE__BZ2_CFLAGS': '', 'MODULE__BZ2_LDFLAGS': '-lbz2', 'MODULE__BZ2_STATE': 'yes', 'MODULE__CODECS_CN_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/mappings_cn.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/multibytecodec.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/cjkcodecs.h', 'MODULE__CODECS_CN_STATE': 'yes', 'MODULE__CODECS_HK_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/mappings_hk.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/multibytecodec.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/cjkcodecs.h', 'MODULE__CODECS_HK_STATE': 'yes', 'MODULE__CODECS_ISO2022_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/mappings_jisx0213_pair.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/alg_jisx0201.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/emu_jisx0213_2000.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/multibytecodec.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/cjkcodecs.h', 'MODULE__CODECS_ISO2022_STATE': 'yes', 'MODULE__CODECS_JP_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/mappings_jisx0213_pair.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/alg_jisx0201.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/emu_jisx0213_2000.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/mappings_jp.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/multibytecodec.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/cjkcodecs.h', 'MODULE__CODECS_JP_STATE': 'yes', 'MODULE__CODECS_KR_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/mappings_kr.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/multibytecodec.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/cjkcodecs.h', 'MODULE__CODECS_KR_STATE': 'yes', 'MODULE__CODECS_LDFLAGS': '', 'MODULE__CODECS_TW_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/mappings_tw.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/multibytecodec.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/cjkcodecs.h', 'MODULE__CODECS_TW_STATE': 'yes', 'MODULE__COLLECTIONS_LDFLAGS': '', 'MODULE__CONTEXTVARS_STATE': 'yes', 'MODULE__CRYPT_CFLAGS': '', 'MODULE__CRYPT_LDFLAGS': '-L/lib64 -lcrypt', 'MODULE__CRYPT_STATE': 'yes', 'MODULE__CSV_STATE': 'yes', 'MODULE__CTYPES_CFLAGS': '-fno-strict-overflow', 'MODULE__CTYPES_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/_ctypes/ctypes.h', 'MODULE__CTYPES_LDFLAGS': '-lffi -ldl', 'MODULE__CTYPES_MALLOC_CLOSURE': '', 'MODULE__CTYPES_STATE': 'yes', 'MODULE__CTYPES_TEST_LDFLAGS': '-lm', 'MODULE__CTYPES_TEST_STATE': 'yes', 'MODULE__CURSES_CFLAGS': '-D_GNU_SOURCE -D_DEFAULT_SOURCE', 'MODULE__CURSES_LDFLAGS': '-lncursesw -ltinfo', 'MODULE__CURSES_PANEL_CFLAGS': '-D_GNU_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE ' '-D_DEFAULT_SOURCE', 'MODULE__CURSES_PANEL_LDFLAGS': '-lpanelw -lncursesw -ltinfo', 'MODULE__CURSES_PANEL_STATE': 'yes', 'MODULE__CURSES_STATE': 'yes', 'MODULE__DATETIME_LDFLAGS': '-lm', 'MODULE__DATETIME_STATE': 'yes', 'MODULE__DBM_CFLAGS': '-DUSE_GDBM_COMPAT', 'MODULE__DBM_LDFLAGS': '-lgdbm_compat', 'MODULE__DBM_STATE': 'yes', 'MODULE__DECIMAL_CFLAGS': '-DCONFIG_64=1 -DANSI=1 -DHAVE_UINT128_T=1', 'MODULE__DECIMAL_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/_decimal/docstrings.h', 'MODULE__DECIMAL_LDFLAGS': '-lmpdec', 'MODULE__DECIMAL_STATE': 'yes', 'MODULE__ELEMENTTREE_CFLAGS': '', 'MODULE__ELEMENTTREE_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/pyexpat.c', 'MODULE__ELEMENTTREE_STATE': 'yes', 'MODULE__FUNCTOOLS_LDFLAGS': '', 'MODULE__GDBM_CFLAGS': '', 'MODULE__GDBM_LDFLAGS': '-lgdbm', 'MODULE__GDBM_STATE': 'yes', 'MODULE__HASHLIB_CFLAGS': '', 'MODULE__HASHLIB_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/hashlib.h', 'MODULE__HASHLIB_LDFLAGS': '-lcrypto', 'MODULE__HASHLIB_STATE': 'yes', 'MODULE__HEAPQ_STATE': 'yes', 'MODULE__IO_CFLAGS': '-I/builddir/build/BUILD/Python-3.12.13/Modules/_io', 'MODULE__IO_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/_io/_iomodule.h', 'MODULE__IO_LDFLAGS': '', 'MODULE__IO_STATE': 'yes', 'MODULE__JSON_STATE': 'yes', 'MODULE__LOCALE_LDFLAGS': '', 'MODULE__LSPROF_STATE': 'yes', 'MODULE__LZMA_CFLAGS': '', 'MODULE__LZMA_LDFLAGS': '-llzma', 'MODULE__LZMA_STATE': 'yes', 'MODULE__MD5_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/hashlib.h ' '\\ Modules/_hacl/Hacl_Hash_MD5.h ' 'Modules/_hacl/Hacl_Hash_MD5.c', 'MODULE__MD5_STATE': 'disabled', 'MODULE__MULTIBYTECODEC_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/cjkcodecs/multibytecodec.h', 'MODULE__MULTIBYTECODEC_STATE': 'yes', 'MODULE__MULTIPROCESSING_CFLAGS': '-I/builddir/build/BUILD/Python-3.12.13/Modules/_multiprocessing', 'MODULE__MULTIPROCESSING_STATE': 'yes', 'MODULE__OPCODE_STATE': 'yes', 'MODULE__OPERATOR_LDFLAGS': '', 'MODULE__PICKLE_STATE': 'yes', 'MODULE__POSIXSHMEM_CFLAGS': '-I/builddir/build/BUILD/Python-3.12.13/Modules/_multiprocessing', 'MODULE__POSIXSHMEM_LDFLAGS': '-lrt', 'MODULE__POSIXSHMEM_STATE': 'yes', 'MODULE__POSIXSUBPROCESS_STATE': 'yes', 'MODULE__QUEUE_STATE': 'yes', 'MODULE__RANDOM_STATE': 'yes', 'MODULE__SCPROXY_STATE': 'n/a', 'MODULE__SHA1_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/hashlib.h ' '\\ Modules/_hacl/Hacl_Hash_SHA1.h ' 'Modules/_hacl/Hacl_Hash_SHA1.c', 'MODULE__SHA1_STATE': 'disabled', 'MODULE__SHA2_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/hashlib.h ' '\\ Modules/_hacl/libHacl_Hash_SHA2.a', 'MODULE__SHA2_STATE': 'disabled', 'MODULE__SHA3_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/hashlib.h ' '\\ Modules/_hacl/Hacl_Hash_SHA3.h ' 'Modules/_hacl/Hacl_Hash_SHA3.c', 'MODULE__SHA3_STATE': 'disabled', 'MODULE__SIGNAL_LDFLAGS': '', 'MODULE__SOCKET_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/socketmodule.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/addrinfo.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/getaddrinfo.c ' '/builddir/build/BUILD/Python-3.12.13/Modules/getnameinfo.c', 'MODULE__SOCKET_STATE': 'yes', 'MODULE__SQLITE3_CFLAGS': '-I/builddir/build/BUILD/Python-3.12.13/Modules/_sqlite', 'MODULE__SQLITE3_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/_sqlite/connection.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_sqlite/cursor.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_sqlite/microprotocols.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_sqlite/module.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_sqlite/prepare_protocol.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_sqlite/row.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_sqlite/util.h', 'MODULE__SQLITE3_LDFLAGS': '-lsqlite3', 'MODULE__SQLITE3_STATE': 'yes', 'MODULE__SRE_LDFLAGS': '', 'MODULE__SSL_CFLAGS': '', 'MODULE__SSL_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/_ssl.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_ssl/cert.c ' '/builddir/build/BUILD/Python-3.12.13/Modules/_ssl/debughelpers.c ' '/builddir/build/BUILD/Python-3.12.13/Modules/_ssl/misc.c ' '/builddir/build/BUILD/Python-3.12.13/Modules/_ssl_data.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_ssl_data_111.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_ssl_data_300.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/socketmodule.h', 'MODULE__SSL_LDFLAGS': '-lssl -lcrypto', 'MODULE__SSL_STATE': 'yes', 'MODULE__STATISTICS_LDFLAGS': '-lm', 'MODULE__STATISTICS_STATE': 'yes', 'MODULE__STAT_LDFLAGS': '', 'MODULE__STRUCT_STATE': 'yes', 'MODULE__SYMTABLE_LDFLAGS': '', 'MODULE__TESTBUFFER_STATE': 'yes', 'MODULE__TESTCAPI_DEPS': '/builddir/build/BUILD/Python-3.12.13/Modules/_testcapi/testcapi_long.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_testcapi/parts.h ' '/builddir/build/BUILD/Python-3.12.13/Modules/_testcapi/util.h', 'MODULE__TESTCAPI_STATE': 'yes', 'MODULE__TESTCLINIC_STATE': 'yes', 'MODULE__TESTIMPORTMULTIPLE_STATE': 'yes', 'MODULE__TESTINTERNALCAPI_STATE': 'yes', 'MODULE__TESTMULTIPHASE_STATE': 'yes', 'MODULE__THREAD_LDFLAGS': '', 'MODULE__TKINTER_CFLAGS': '-Wno-strict-prototypes -DWITH_APPINIT=1', 'MODULE__TKINTER_LDFLAGS': '-ltk8.6 -ltkstub8.6 -ltcl8.6 -ltclstub8.6', 'MODULE__TKINTER_STATE': 'yes', 'MODULE__TRACEMALLOC_LDFLAGS': '', 'MODULE__TYPING_LDFLAGS': '', 'MODULE__TYPING_STATE': 'yes', 'MODULE__UUID_CFLAGS': '-I/usr/include/uuid', 'MODULE__UUID_LDFLAGS': '-luuid', 'MODULE__UUID_STATE': 'yes', 'MODULE__WEAKREF_LDFLAGS': '', 'MODULE__XXINTERPCHANNELS_STATE': 'yes', 'MODULE__XXSUBINTERPRETERS_STATE': 'yes', 'MODULE__XXTESTFUZZ_STATE': 'yes', 'MODULE__ZONEINFO_STATE': 'yes', 'MULTIARCH': 'x86_64-linux-gnu', 'MULTIARCH_CPPFLAGS': '-DMULTIARCH=\\"x86_64-linux-gnu\\"', 'MVWDELCH_IS_EXPRESSION': 1, 'NO_AS_NEEDED': '-Wl,--no-as-needed', 'OBJECT_OBJS': '\\', 'OPT': '-DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection', 'PACKAGE_BUGREPORT': 0, 'PACKAGE_NAME': 0, 'PACKAGE_STRING': 0, 'PACKAGE_TARNAME': 0, 'PACKAGE_URL': 0, 'PACKAGE_VERSION': 0, 'PARSER_HEADERS': '\\', 'PARSER_OBJS': '\\ \\ Parser/myreadline.o Parser/tokenizer.o', 'PEGEN_HEADERS': '\\', 'PEGEN_OBJS': '\\', 'PGO_PROF_GEN_FLAG': '-fprofile-generate', 'PGO_PROF_USE_FLAG': '-fprofile-use -fprofile-correction', 'PLATLIBDIR': 'lib64', 'POBJS': '\\', 'POSIX_SEMAPHORES_NOT_ENABLED': 0, 'PROFILE_TASK': '-m test --pgo --timeout=1200', 'PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT': 1, 'PTHREAD_SYSTEM_SCHED_SUPPORTED': 1, 'PY3LIBRARY': 'libpython3.so', 'PYLONG_BITS_IN_DIGIT': 0, 'PYTHON': 'python', 'PYTHONFRAMEWORK': '', 'PYTHONFRAMEWORKDIR': 'no-framework', 'PYTHONFRAMEWORKINSTALLDIR': '', 'PYTHONFRAMEWORKPREFIX': '', 'PYTHONPATH': '', 'PYTHON_FOR_BUILD': './python -E', 'PYTHON_FOR_BUILD_DEPS': 'python', 'PYTHON_FOR_FREEZE': './_bootstrap_python', 'PYTHON_FOR_REGEN': '', 'PYTHON_HEADERS': '\\', 'PYTHON_OBJS': '\\', 'PY_BUILTIN_HASHLIB_HASHES': '"blake2"', 'PY_BUILTIN_MODULE_CFLAGS': '-fno-strict-overflow -Wsign-compare ' '-DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g ' '-pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-m64 -mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g ' '-pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-m64 -mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g ' '-pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-m64 -mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g ' '-pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 ' '-m64 -mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection ' '-D_GNU_SOURCE -fPIC -fwrapv ' '-fno-semantic-interposition -flto ' '-fuse-linker-plugin -ffat-lto-objects ' '-flto-partition=none -g -std=c11 -Wextra ' '-Wno-unused-parameter ' '-Wno-missing-field-initializers ' '-Werror=implicit-function-declaration ' '-fvisibility=hidden -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 ' '-m64 -mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection ' '-D_GNU_SOURCE -fPIC -fwrapv -O3 -fprofile-use ' '-fprofile-correction ' '-I/builddir/build/BUILD/Python-3.12.13/Include/internal ' '-IObjects -IInclude -IPython -I. ' '-I/builddir/build/BUILD/Python-3.12.13/Include ' '-fPIC -DPy_BUILD_CORE_BUILTIN', 'PY_CFLAGS': '-fno-strict-overflow -Wsign-compare ' '-DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection ' '-fcf-protection -O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection ' '-fcf-protection', 'PY_CFLAGS_NODIST': '-O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -fno-semantic-interposition -flto ' '-fuse-linker-plugin -ffat-lto-objects ' '-flto-partition=none -g -std=c11 -Wextra ' '-Wno-unused-parameter -Wno-missing-field-initializers ' '-Werror=implicit-function-declaration ' '-fvisibility=hidden -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -O3 -fprofile-use -fprofile-correction ' '-I/builddir/build/BUILD/Python-3.12.13/Include/internal', 'PY_COERCE_C_LOCALE': 1, 'PY_CORE_CFLAGS': '-fno-strict-overflow -Wsign-compare ' '-DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g -pipe ' '-Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -fno-semantic-interposition -flto ' '-fuse-linker-plugin -ffat-lto-objects -flto-partition=none ' '-g -std=c11 -Wextra -Wno-unused-parameter ' '-Wno-missing-field-initializers ' '-Werror=implicit-function-declaration -fvisibility=hidden ' '-O2 -g -pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -D_GNU_SOURCE ' '-fPIC -fwrapv -O3 -fprofile-use -fprofile-correction ' '-I/builddir/build/BUILD/Python-3.12.13/Include/internal ' '-IObjects -IInclude -IPython -I. ' '-I/builddir/build/BUILD/Python-3.12.13/Include -fPIC ' '-DPy_BUILD_CORE', 'PY_CORE_LDFLAGS': '-Wl,-z,relro -Wl,-z,now -Wl,-z,relro -Wl,-z,now ' '-Wl,-z,relro -Wl,-z,now ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-ld -g ' '-fno-semantic-interposition -flto -fuse-linker-plugin ' '-ffat-lto-objects -flto-partition=none -g -Wl,-z,relro ' '-Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld ' '-g', 'PY_CPPFLAGS': '-IObjects -IInclude -IPython -I. ' '-I/builddir/build/BUILD/Python-3.12.13/Include', 'PY_ENABLE_SHARED': 1, 'PY_HAVE_PERF_TRAMPOLINE': 1, 'PY_LDFLAGS': '-Wl,-z,relro -Wl,-z,now -Wl,-z,relro -Wl,-z,now', 'PY_LDFLAGS_NODIST': '-Wl,-z,relro -Wl,-z,now ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-ld -g ' '-fno-semantic-interposition -flto -fuse-linker-plugin ' '-ffat-lto-objects -flto-partition=none -g -Wl,-z,relro ' '-Wl,-z,now ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-ld -g', 'PY_LDFLAGS_NOLTO': '-Wl,-z,relro -Wl,-z,now -Wl,-z,relro -Wl,-z,now ' '-fno-lto -Wl,-z,relro -Wl,-z,now ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-ld -g', 'PY_SQLITE_ENABLE_LOAD_EXTENSION': 1, 'PY_SQLITE_HAVE_SERIALIZE': 0, 'PY_SSL_DEFAULT_CIPHERS': 2, 'PY_SSL_DEFAULT_CIPHER_STRING': 0, 'PY_STDMODULE_CFLAGS': '-fno-strict-overflow -Wsign-compare ' '-DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g ' '-pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection ' '-fcf-protection -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection -O2 -g ' '-pipe -Wall -Werror=format-security ' '-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS ' '-fexceptions -fstack-protector-strong ' '-grecord-gcc-switches -m64 -mtune=generic ' '-fasynchronous-unwind-tables -fstack-clash-protection ' '-fcf-protection -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection ' '-D_GNU_SOURCE -fPIC -fwrapv ' '-fno-semantic-interposition -flto -fuse-linker-plugin ' '-ffat-lto-objects -flto-partition=none -g -std=c11 ' '-Wextra -Wno-unused-parameter ' '-Wno-missing-field-initializers ' '-Werror=implicit-function-declaration ' '-fvisibility=hidden -O2 -g -pipe -Wall ' '-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 ' '-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions ' '-fstack-protector-strong -grecord-gcc-switches ' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 ' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 ' '-mtune=generic -fasynchronous-unwind-tables ' '-fstack-clash-protection -fcf-protection ' '-D_GNU_SOURCE -fPIC -fwrapv -O3 -fprofile-use ' '-fprofile-correction ' '-I/builddir/build/BUILD/Python-3.12.13/Include/internal ' '-IObjects -IInclude -IPython -I. ' '-I/builddir/build/BUILD/Python-3.12.13/Include -fPIC', 'PY_SUPPORT_TIER': 1, 'Py_DEBUG': 0, 'Py_ENABLE_SHARED': 1, 'Py_HASH_ALGORITHM': 0, 'Py_STATS': 0, 'Py_SUNOS_VERSION': 0, 'Py_TRACE_REFS': 0, 'QUICKTESTOPTS': '-x test_subprocess test_io test_lib2to3 \\', 'READELF': '@READELF@', 'RESSRCDIR': 'Mac/Resources/framework', 'RETSIGTYPE': 'void', 'RUNSHARED': 'LD_LIBRARY_PATH=/builddir/build/BUILD/Python-3.12.13/build/optimized', 'SCRIPTDIR': '/usr/lib64', 'SCRIPT_2TO3': 'build/scripts-3.12/2to3-3.12', 'SCRIPT_IDLE': 'build/scripts-3.12/idle3.12', 'SCRIPT_PYDOC': 'build/scripts-3.12/pydoc3.12', 'SETPGRP_HAVE_ARG': 0, 'SHAREDMODS': 'Modules/array.cpython-312-x86_64-linux-gnu.so ' 'Modules/_asyncio.cpython-312-x86_64-linux-gnu.so ' 'Modules/_bisect.cpython-312-x86_64-linux-gnu.so ' 'Modules/_contextvars.cpython-312-x86_64-linux-gnu.so ' 'Modules/_csv.cpython-312-x86_64-linux-gnu.so ' 'Modules/_heapq.cpython-312-x86_64-linux-gnu.so ' 'Modules/_json.cpython-312-x86_64-linux-gnu.so ' 'Modules/_lsprof.cpython-312-x86_64-linux-gnu.so ' 'Modules/_opcode.cpython-312-x86_64-linux-gnu.so ' 'Modules/_pickle.cpython-312-x86_64-linux-gnu.so ' 'Modules/_queue.cpython-312-x86_64-linux-gnu.so ' 'Modules/_random.cpython-312-x86_64-linux-gnu.so ' 'Modules/_struct.cpython-312-x86_64-linux-gnu.so ' 'Modules/_xxsubinterpreters.cpython-312-x86_64-linux-gnu.so ' 'Modules/_xxinterpchannels.cpython-312-x86_64-linux-gnu.so ' 'Modules/_zoneinfo.cpython-312-x86_64-linux-gnu.so ' 'Modules/audioop.cpython-312-x86_64-linux-gnu.so ' 'Modules/math.cpython-312-x86_64-linux-gnu.so ' 'Modules/cmath.cpython-312-x86_64-linux-gnu.so ' 'Modules/_statistics.cpython-312-x86_64-linux-gnu.so ' 'Modules/_datetime.cpython-312-x86_64-linux-gnu.so ' 'Modules/_decimal.cpython-312-x86_64-linux-gnu.so ' 'Modules/binascii.cpython-312-x86_64-linux-gnu.so ' 'Modules/_bz2.cpython-312-x86_64-linux-gnu.so ' 'Modules/_lzma.cpython-312-x86_64-linux-gnu.so ' 'Modules/zlib.cpython-312-x86_64-linux-gnu.so ' 'Modules/_dbm.cpython-312-x86_64-linux-gnu.so ' 'Modules/_gdbm.cpython-312-x86_64-linux-gnu.so ' 'Modules/readline.cpython-312-x86_64-linux-gnu.so ' 'Modules/_blake2.cpython-312-x86_64-linux-gnu.so ' 'Modules/pyexpat.cpython-312-x86_64-linux-gnu.so ' 'Modules/_elementtree.cpython-312-x86_64-linux-gnu.so ' 'Modules/_codecs_cn.cpython-312-x86_64-linux-gnu.so ' 'Modules/_codecs_hk.cpython-312-x86_64-linux-gnu.so ' 'Modules/_codecs_iso2022.cpython-312-x86_64-linux-gnu.so ' 'Modules/_codecs_jp.cpython-312-x86_64-linux-gnu.so ' 'Modules/_codecs_kr.cpython-312-x86_64-linux-gnu.so ' 'Modules/_codecs_tw.cpython-312-x86_64-linux-gnu.so ' 'Modules/_multibytecodec.cpython-312-x86_64-linux-gnu.so ' 'Modules/unicodedata.cpython-312-x86_64-linux-gnu.so ' 'Modules/_crypt.cpython-312-x86_64-linux-gnu.so ' 'Modules/fcntl.cpython-312-x86_64-linux-gnu.so ' 'Modules/grp.cpython-312-x86_64-linux-gnu.so ' 'Modules/mmap.cpython-312-x86_64-linux-gnu.so ' 'Modules/nis.cpython-312-x86_64-linux-gnu.so ' 'Modules/ossaudiodev.cpython-312-x86_64-linux-gnu.so ' 'Modules/_posixsubprocess.cpython-312-x86_64-linux-gnu.so ' 'Modules/resource.cpython-312-x86_64-linux-gnu.so ' 'Modules/select.cpython-312-x86_64-linux-gnu.so ' 'Modules/_socket.cpython-312-x86_64-linux-gnu.so ' 'Modules/spwd.cpython-312-x86_64-linux-gnu.so ' 'Modules/syslog.cpython-312-x86_64-linux-gnu.so ' 'Modules/termios.cpython-312-x86_64-linux-gnu.so ' 'Modules/_posixshmem.cpython-312-x86_64-linux-gnu.so ' 'Modules/_multiprocessing.cpython-312-x86_64-linux-gnu.so ' 'Modules/_ctypes.cpython-312-x86_64-linux-gnu.so ' 'Modules/_curses.cpython-312-x86_64-linux-gnu.so ' 'Modules/_curses_panel.cpython-312-x86_64-linux-gnu.so ' 'Modules/_sqlite3.cpython-312-x86_64-linux-gnu.so ' 'Modules/_ssl.cpython-312-x86_64-linux-gnu.so ' 'Modules/_hashlib.cpython-312-x86_64-linux-gnu.so ' 'Modules/_uuid.cpython-312-x86_64-linux-gnu.so ' 'Modules/_tkinter.cpython-312-x86_64-linux-gnu.so ' 'Modules/xxsubtype.cpython-312-x86_64-linux-gnu.so ' 'Modules/_xxtestfuzz.cpython-312-x86_64-linux-gnu.so ' 'Modules/_testbuffer.cpython-312-x86_64-linux-gnu.so ' 'Modules/_testinternalcapi.cpython-312-x86_64-linux-gnu.so ' 'Modules/_testcapi.cpython-312-x86_64-linux-gnu.so ' 'Modules/_testclinic.cpython-312-x86_64-linux-gnu.so ' 'Modules/_testimportmultiple.cpython-312-x86_64-linux-gnu.so ' 'Modules/_testmultiphase.cpython-312-x86_64-linux-gnu.so ' 'Modules/_testsinglephase.cpython-312-x86_64-linux-gnu.so ' 'Modules/_ctypes_test.cpython-312-x86_64-linux-gnu.so ' 'Modules/xxlimited.cpython-312-x86_64-linux-gnu.so ' 'Modules/xxlimited_35.cpython-312-x86_64-linux-gnu.so', 'SHELL': '/bin/sh -e', 'SHLIBS': '-lpthread -ldl -lutil', 'SHLIB_SUFFIX': '.so', 'SIGNED_RIGHT_SHIFT_ZERO_FILLS': 0, 'SITEPATH': '', 'SIZEOF_DOUBLE': 8, 'SIZEOF_FLOAT': 4, 'SIZEOF_FPOS_T': 16, 'SIZEOF_INT': 4, 'SIZEOF_LONG': 8, 'SIZEOF_LONG_DOUBLE': 16, 'SIZEOF_LONG_LONG': 8, 'SIZEOF_OFF_T': 8, 'SIZEOF_PID_T': 4, 'SIZEOF_PTHREAD_KEY_T': 4, 'SIZEOF_PTHREAD_T': 8, 'SIZEOF_SHORT': 2, 'SIZEOF_SIZE_T': 8, 'SIZEOF_TIME_T': 8, 'SIZEOF_UINTPTR_T': 8, 'SIZEOF_VOID_P': 8, 'SIZEOF_WCHAR_T': 4, 'SIZEOF__BOOL': 1, 'SOABI': 'cpython-312-x86_64-linux-gnu', 'SRCDIRS': 'Modules Modules/_blake2 Modules/_ctypes Modules/_decimal ' 'Modules/_decimal/libmpdec Modules/_hacl Modules/_io ' 'Modules/_multiprocessing Modules/_sqlite Modules/_sre ' 'Modules/_testcapi Modules/_xxtestfuzz Modules/cjkcodecs ' 'Modules/expat Objects Parser Programs Python ' 'Python/frozen_modules Python/deepfreeze', 'SRC_GDB_HOOKS': '/builddir/build/BUILD/Python-3.12.13/Tools/gdb/libpython.py', 'STATIC_LIBPYTHON': 0, 'STDC_HEADERS': 1, 'STRICT_SYSV_CURSES': "/* Don't use ncurses extensions */", 'STRIPFLAG': '-s', 'SUBDIRS': '', 'SUBDIRSTOO': 'Include Lib Misc', 'SYSLIBS': '-lm', 'SYS_SELECT_WITH_SYS_TIME': 1, 'TESTOPTS': '', 'TESTPATH': '', 'TESTPYTHON': 'LD_LIBRARY_PATH=/builddir/build/BUILD/Python-3.12.13/build/optimized ' './python -E', 'TESTPYTHONOPTS': '', 'TESTRUNNER': 'LD_LIBRARY_PATH=/builddir/build/BUILD/Python-3.12.13/build/optimized ' './python -E ' '/builddir/build/BUILD/Python-3.12.13/Tools/scripts/run_tests.py', 'TESTSUBDIRS': 'idlelib/idle_test \\', 'TESTTIMEOUT': 1200, 'TEST_MODULES': 'yes', 'THREAD_STACK_SIZE': 0, 'TIMEMODULE_LIB': 0, 'TM_IN_SYS_TIME': 0, 'TZPATH': '/usr/share/zoneinfo:/usr/lib/zoneinfo:/usr/share/lib/zoneinfo:/etc/zoneinfo', 'UNICODE_DEPS': '\\', 'UNIVERSALSDK': '', 'UPDATE_FILE': '/builddir/build/BUILD/Python-3.12.13/Tools/build/update_file.py', 'USE_COMPUTED_GOTOS': 1, 'VERSION': '3.12', 'VPATH': '/builddir/build/BUILD/Python-3.12.13', 'WASM_ASSETS_DIR': './usr', 'WASM_STDLIB': './usr/lib/python3.12/os.py', 'WHEEL_PKG_DIR': '/usr/share/python3.12-wheels', 'WINDOW_HAS_FLAGS': 1, 'WITH_DECIMAL_CONTEXTVAR': 1, 'WITH_DOC_STRINGS': 1, 'WITH_DTRACE': 1, 'WITH_DYLD': 0, 'WITH_EDITLINE': 0, 'WITH_FREELISTS': 1, 'WITH_LIBINTL': 0, 'WITH_NEXT_FRAMEWORK': 0, 'WITH_PYMALLOC': 1, 'WITH_VALGRIND': 1, 'X87_DOUBLE_ROUNDING': 0, 'XMLLIBSUBDIRS': 'xml xml/dom xml/etree xml/parsers xml/sax', 'abs_builddir': '/builddir/build/BUILD/Python-3.12.13/build/optimized', 'abs_srcdir': '/builddir/build/BUILD/Python-3.12.13', 'datarootdir': '/usr/share', 'exec_prefix': '/usr', 'prefix': '/usr', 'srcdir': '/builddir/build/BUILD/Python-3.12.13'} sched.py000064400000014317152342670510006217 0ustar00"""A generally useful event scheduler class. Each instance of this class manages its own queue. No multi-threading is implied; you are supposed to hack that yourself, or use a single instance per application. Each instance is parametrized with two functions, one that is supposed to return the current time, one that is supposed to implement a delay. You can implement real-time scheduling by substituting time and sleep from built-in module time, or you can implement simulated time by writing your own functions. This can also be used to integrate scheduling with STDWIN events; the delay function is allowed to modify the queue. Time can be expressed as integers or floating-point numbers, as long as it is consistent. Events are specified by tuples (time, priority, action, argument, kwargs). As in UNIX, lower priority numbers mean higher priority; in this way the queue can be maintained as a priority queue. Execution of the event means calling the action function, passing it the argument sequence in "argument" (remember that in Python, multiple function arguments are be packed in a sequence) and keyword parameters in "kwargs". The action function may be an instance method so it has another way to reference private data (besides global variables). """ import time import heapq from collections import namedtuple from itertools import count import threading from time import monotonic as _time __all__ = ["scheduler"] Event = namedtuple('Event', 'time, priority, sequence, action, argument, kwargs') Event.time.__doc__ = ('''Numeric type compatible with the return value of the timefunc function passed to the constructor.''') Event.priority.__doc__ = ('''Events scheduled for the same time will be executed in the order of their priority.''') Event.sequence.__doc__ = ('''A continually increasing sequence number that separates events if time and priority are equal.''') Event.action.__doc__ = ('''Executing the event means executing action(*argument, **kwargs)''') Event.argument.__doc__ = ('''argument is a sequence holding the positional arguments for the action.''') Event.kwargs.__doc__ = ('''kwargs is a dictionary holding the keyword arguments for the action.''') _sentinel = object() class scheduler: def __init__(self, timefunc=_time, delayfunc=time.sleep): """Initialize a new instance, passing the time and delay functions""" self._queue = [] self._lock = threading.RLock() self.timefunc = timefunc self.delayfunc = delayfunc self._sequence_generator = count() def enterabs(self, time, priority, action, argument=(), kwargs=_sentinel): """Enter a new event in the queue at an absolute time. Returns an ID for the event which can be used to remove it, if necessary. """ if kwargs is _sentinel: kwargs = {} with self._lock: event = Event(time, priority, next(self._sequence_generator), action, argument, kwargs) heapq.heappush(self._queue, event) return event # The ID def enter(self, delay, priority, action, argument=(), kwargs=_sentinel): """A variant that specifies the time as a relative time. This is actually the more commonly used interface. """ time = self.timefunc() + delay return self.enterabs(time, priority, action, argument, kwargs) def cancel(self, event): """Remove an event from the queue. This must be presented the ID as returned by enter(). If the event is not in the queue, this raises ValueError. """ with self._lock: self._queue.remove(event) heapq.heapify(self._queue) def empty(self): """Check whether the queue is empty.""" with self._lock: return not self._queue def run(self, blocking=True): """Execute events until the queue is empty. If blocking is False executes the scheduled events due to expire soonest (if any) and then return the deadline of the next scheduled call in the scheduler. When there is a positive delay until the first event, the delay function is called and the event is left in the queue; otherwise, the event is removed from the queue and executed (its action function is called, passing it the argument). If the delay function returns prematurely, it is simply restarted. It is legal for both the delay function and the action function to modify the queue or to raise an exception; exceptions are not caught but the scheduler's state remains well-defined so run() may be called again. A questionable hack is added to allow other threads to run: just after an event is executed, a delay of 0 is executed, to avoid monopolizing the CPU when other threads are also runnable. """ # localize variable access to minimize overhead # and to improve thread safety lock = self._lock q = self._queue delayfunc = self.delayfunc timefunc = self.timefunc pop = heapq.heappop while True: with lock: if not q: break (time, priority, sequence, action, argument, kwargs) = q[0] now = timefunc() if time > now: delay = True else: delay = False pop(q) if delay: if not blocking: return time - now delayfunc(time - now) else: action(*argument, **kwargs) delayfunc(0) # Let other threads run @property def queue(self): """An ordered list of upcoming events. Events are named tuples with fields for: time, priority, action, arguments, kwargs """ # Use heapq to sort the queue rather than using 'sorted(self._queue)'. # With heapq, two events scheduled at the same time will show in # the actual order they would be retrieved. with self._lock: events = self._queue[:] return list(map(heapq.heappop, [events]*len(events))) fractions.py000064400000112403152342670510007114 0ustar00# Originally contributed by Sjoerd Mullender. # Significantly modified by Jeffrey Yasskin . """Fraction, infinite-precision, rational numbers.""" from decimal import Decimal import functools import math import numbers import operator import re import sys __all__ = ['Fraction'] # Constants related to the hash implementation; hash(x) is based # on the reduction of x modulo the prime _PyHASH_MODULUS. _PyHASH_MODULUS = sys.hash_info.modulus # Value to be used for rationals that reduce to infinity modulo # _PyHASH_MODULUS. _PyHASH_INF = sys.hash_info.inf @functools.lru_cache(maxsize = 1 << 14) def _hash_algorithm(numerator, denominator): # To make sure that the hash of a Fraction agrees with the hash # of a numerically equal integer, float or Decimal instance, we # follow the rules for numeric hashes outlined in the # documentation. (See library docs, 'Built-in Types'). try: dinv = pow(denominator, -1, _PyHASH_MODULUS) except ValueError: # ValueError means there is no modular inverse. hash_ = _PyHASH_INF else: # The general algorithm now specifies that the absolute value of # the hash is # (|N| * dinv) % P # where N is self._numerator and P is _PyHASH_MODULUS. That's # optimized here in two ways: first, for a non-negative int i, # hash(i) == i % P, but the int hash implementation doesn't need # to divide, and is faster than doing % P explicitly. So we do # hash(|N| * dinv) # instead. Second, N is unbounded, so its product with dinv may # be arbitrarily expensive to compute. The final answer is the # same if we use the bounded |N| % P instead, which can again # be done with an int hash() call. If 0 <= i < P, hash(i) == i, # so this nested hash() call wastes a bit of time making a # redundant copy when |N| < P, but can save an arbitrarily large # amount of computation for large |N|. hash_ = hash(hash(abs(numerator)) * dinv) result = hash_ if numerator >= 0 else -hash_ return -2 if result == -1 else result _RATIONAL_FORMAT = re.compile(r""" \A\s* # optional whitespace at the start, (?P[-+]?) # an optional sign, then (?=\d|\.\d) # lookahead for digit or .digit (?P\d*|\d+(_\d+)*) # numerator (possibly empty) (?: # followed by (?:\s*/\s*(?P\d+(_\d+)*))? # an optional denominator | # or (?:\.(?P\d*|\d+(_\d+)*))? # an optional fractional part (?:E(?P[-+]?\d+(_\d+)*))? # and optional exponent ) \s*\Z # and optional whitespace to finish """, re.VERBOSE | re.IGNORECASE) # Helpers for formatting def _round_to_exponent(n, d, exponent, no_neg_zero=False): """Round a rational number to the nearest multiple of a given power of 10. Rounds the rational number n/d to the nearest integer multiple of 10**exponent, rounding to the nearest even integer multiple in the case of a tie. Returns a pair (sign: bool, significand: int) representing the rounded value (-1)**sign * significand * 10**exponent. If no_neg_zero is true, then the returned sign will always be False when the significand is zero. Otherwise, the sign reflects the sign of the input. d must be positive, but n and d need not be relatively prime. """ if exponent >= 0: d *= 10**exponent else: n *= 10**-exponent # The divmod quotient is correct for round-ties-towards-positive-infinity; # In the case of a tie, we zero out the least significant bit of q. q, r = divmod(n + (d >> 1), d) if r == 0 and d & 1 == 0: q &= -2 sign = q < 0 if no_neg_zero else n < 0 return sign, abs(q) def _round_to_figures(n, d, figures): """Round a rational number to a given number of significant figures. Rounds the rational number n/d to the given number of significant figures using the round-ties-to-even rule, and returns a triple (sign: bool, significand: int, exponent: int) representing the rounded value (-1)**sign * significand * 10**exponent. In the special case where n = 0, returns a significand of zero and an exponent of 1 - figures, for compatibility with formatting. Otherwise, the returned significand satisfies 10**(figures - 1) <= significand < 10**figures. d must be positive, but n and d need not be relatively prime. figures must be positive. """ # Special case for n == 0. if n == 0: return False, 0, 1 - figures # Find integer m satisfying 10**(m - 1) <= abs(n)/d <= 10**m. (If abs(n)/d # is a power of 10, either of the two possible values for m is fine.) str_n, str_d = str(abs(n)), str(d) m = len(str_n) - len(str_d) + (str_d <= str_n) # Round to a multiple of 10**(m - figures). The significand we get # satisfies 10**(figures - 1) <= significand <= 10**figures. exponent = m - figures sign, significand = _round_to_exponent(n, d, exponent) # Adjust in the case where significand == 10**figures, to ensure that # 10**(figures - 1) <= significand < 10**figures. if len(str(significand)) == figures + 1: significand //= 10 exponent += 1 return sign, significand, exponent # Pattern for matching float-style format specifications; # supports 'e', 'E', 'f', 'F', 'g', 'G' and '%' presentation types. _FLOAT_FORMAT_SPECIFICATION_MATCHER = re.compile(r""" (?: (?P.)? (?P[<>=^]) )? (?P[-+ ]?) (?Pz)? (?P\#)? # A '0' that's *not* followed by another digit is parsed as a minimum width # rather than a zeropad flag. (?P0(?=[0-9]))? (?P0|[1-9][0-9]*)? (?P[,_])? (?:\.(?P0|[1-9][0-9]*))? (?P[eEfFgG%]) """, re.DOTALL | re.VERBOSE).fullmatch class Fraction(numbers.Rational): """This class implements rational numbers. In the two-argument form of the constructor, Fraction(8, 6) will produce a rational number equivalent to 4/3. Both arguments must be Rational. The numerator defaults to 0 and the denominator defaults to 1 so that Fraction(3) == 3 and Fraction() == 0. Fractions can also be constructed from: - numeric strings similar to those accepted by the float constructor (for example, '-2.3' or '1e10') - strings of the form '123/456' - float and Decimal instances - other Rational instances (including integers) """ __slots__ = ('_numerator', '_denominator') # We're immutable, so use __new__ not __init__ def __new__(cls, numerator=0, denominator=None): """Constructs a Rational. Takes a string like '3/2' or '1.5', another Rational instance, a numerator/denominator pair, or a float. Examples -------- >>> Fraction(10, -8) Fraction(-5, 4) >>> Fraction(Fraction(1, 7), 5) Fraction(1, 35) >>> Fraction(Fraction(1, 7), Fraction(2, 3)) Fraction(3, 14) >>> Fraction('314') Fraction(314, 1) >>> Fraction('-35/4') Fraction(-35, 4) >>> Fraction('3.1415') # conversion from numeric string Fraction(6283, 2000) >>> Fraction('-47e-2') # string may include a decimal exponent Fraction(-47, 100) >>> Fraction(1.47) # direct construction from float (exact conversion) Fraction(6620291452234629, 4503599627370496) >>> Fraction(2.25) Fraction(9, 4) >>> Fraction(Decimal('1.47')) Fraction(147, 100) """ self = super(Fraction, cls).__new__(cls) if denominator is None: if type(numerator) is int: self._numerator = numerator self._denominator = 1 return self elif isinstance(numerator, numbers.Rational): self._numerator = numerator.numerator self._denominator = numerator.denominator return self elif isinstance(numerator, (float, Decimal)): # Exact conversion self._numerator, self._denominator = numerator.as_integer_ratio() return self elif isinstance(numerator, str): # Handle construction from strings. m = _RATIONAL_FORMAT.match(numerator) if m is None: raise ValueError('Invalid literal for Fraction: %r' % numerator) numerator = int(m.group('num') or '0') denom = m.group('denom') if denom: denominator = int(denom) else: denominator = 1 decimal = m.group('decimal') if decimal: decimal = decimal.replace('_', '') scale = 10**len(decimal) numerator = numerator * scale + int(decimal) denominator *= scale exp = m.group('exp') if exp: exp = int(exp) if exp >= 0: numerator *= 10**exp else: denominator *= 10**-exp if m.group('sign') == '-': numerator = -numerator else: raise TypeError("argument should be a string " "or a Rational instance") elif type(numerator) is int is type(denominator): pass # *very* normal case elif (isinstance(numerator, numbers.Rational) and isinstance(denominator, numbers.Rational)): numerator, denominator = ( numerator.numerator * denominator.denominator, denominator.numerator * numerator.denominator ) else: raise TypeError("both arguments should be " "Rational instances") if denominator == 0: raise ZeroDivisionError('Fraction(%s, 0)' % numerator) g = math.gcd(numerator, denominator) if denominator < 0: g = -g numerator //= g denominator //= g self._numerator = numerator self._denominator = denominator return self @classmethod def from_float(cls, f): """Converts a finite float to a rational number, exactly. Beware that Fraction.from_float(0.3) != Fraction(3, 10). """ if isinstance(f, numbers.Integral): return cls(f) elif not isinstance(f, float): raise TypeError("%s.from_float() only takes floats, not %r (%s)" % (cls.__name__, f, type(f).__name__)) return cls._from_coprime_ints(*f.as_integer_ratio()) @classmethod def from_decimal(cls, dec): """Converts a finite Decimal instance to a rational number, exactly.""" from decimal import Decimal if isinstance(dec, numbers.Integral): dec = Decimal(int(dec)) elif not isinstance(dec, Decimal): raise TypeError( "%s.from_decimal() only takes Decimals, not %r (%s)" % (cls.__name__, dec, type(dec).__name__)) return cls._from_coprime_ints(*dec.as_integer_ratio()) @classmethod def _from_coprime_ints(cls, numerator, denominator, /): """Convert a pair of ints to a rational number, for internal use. The ratio of integers should be in lowest terms and the denominator should be positive. """ obj = super(Fraction, cls).__new__(cls) obj._numerator = numerator obj._denominator = denominator return obj def is_integer(self): """Return True if the Fraction is an integer.""" return self._denominator == 1 def as_integer_ratio(self): """Return a pair of integers, whose ratio is equal to the original Fraction. The ratio is in lowest terms and has a positive denominator. """ return (self._numerator, self._denominator) def limit_denominator(self, max_denominator=1000000): """Closest Fraction to self with denominator at most max_denominator. >>> Fraction('3.141592653589793').limit_denominator(10) Fraction(22, 7) >>> Fraction('3.141592653589793').limit_denominator(100) Fraction(311, 99) >>> Fraction(4321, 8765).limit_denominator(10000) Fraction(4321, 8765) """ # Algorithm notes: For any real number x, define a *best upper # approximation* to x to be a rational number p/q such that: # # (1) p/q >= x, and # (2) if p/q > r/s >= x then s > q, for any rational r/s. # # Define *best lower approximation* similarly. Then it can be # proved that a rational number is a best upper or lower # approximation to x if, and only if, it is a convergent or # semiconvergent of the (unique shortest) continued fraction # associated to x. # # To find a best rational approximation with denominator <= M, # we find the best upper and lower approximations with # denominator <= M and take whichever of these is closer to x. # In the event of a tie, the bound with smaller denominator is # chosen. If both denominators are equal (which can happen # only when max_denominator == 1 and self is midway between # two integers) the lower bound---i.e., the floor of self, is # taken. if max_denominator < 1: raise ValueError("max_denominator should be at least 1") if self._denominator <= max_denominator: return Fraction(self) p0, q0, p1, q1 = 0, 1, 1, 0 n, d = self._numerator, self._denominator while True: a = n//d q2 = q0+a*q1 if q2 > max_denominator: break p0, q0, p1, q1 = p1, q1, p0+a*p1, q2 n, d = d, n-a*d k = (max_denominator-q0)//q1 # Determine which of the candidates (p0+k*p1)/(q0+k*q1) and p1/q1 is # closer to self. The distance between them is 1/(q1*(q0+k*q1)), while # the distance from p1/q1 to self is d/(q1*self._denominator). So we # need to compare 2*(q0+k*q1) with self._denominator/d. if 2*d*(q0+k*q1) <= self._denominator: return Fraction._from_coprime_ints(p1, q1) else: return Fraction._from_coprime_ints(p0+k*p1, q0+k*q1) @property def numerator(a): return a._numerator @property def denominator(a): return a._denominator def __repr__(self): """repr(self)""" return '%s(%s, %s)' % (self.__class__.__name__, self._numerator, self._denominator) def __str__(self): """str(self)""" if self._denominator == 1: return str(self._numerator) else: return '%s/%s' % (self._numerator, self._denominator) def __format__(self, format_spec, /): """Format this fraction according to the given format specification.""" # Backwards compatiblility with existing formatting. if not format_spec: return str(self) # Validate and parse the format specifier. match = _FLOAT_FORMAT_SPECIFICATION_MATCHER(format_spec) if match is None: raise ValueError( f"Invalid format specifier {format_spec!r} " f"for object of type {type(self).__name__!r}" ) elif match["align"] is not None and match["zeropad"] is not None: # Avoid the temptation to guess. raise ValueError( f"Invalid format specifier {format_spec!r} " f"for object of type {type(self).__name__!r}; " "can't use explicit alignment when zero-padding" ) fill = match["fill"] or " " align = match["align"] or ">" pos_sign = "" if match["sign"] == "-" else match["sign"] no_neg_zero = bool(match["no_neg_zero"]) alternate_form = bool(match["alt"]) zeropad = bool(match["zeropad"]) minimumwidth = int(match["minimumwidth"] or "0") thousands_sep = match["thousands_sep"] precision = int(match["precision"] or "6") presentation_type = match["presentation_type"] trim_zeros = presentation_type in "gG" and not alternate_form trim_point = not alternate_form exponent_indicator = "E" if presentation_type in "EFG" else "e" # Round to get the digits we need, figure out where to place the point, # and decide whether to use scientific notation. 'point_pos' is the # relative to the _end_ of the digit string: that is, it's the number # of digits that should follow the point. if presentation_type in "fF%": exponent = -precision if presentation_type == "%": exponent -= 2 negative, significand = _round_to_exponent( self._numerator, self._denominator, exponent, no_neg_zero) scientific = False point_pos = precision else: # presentation_type in "eEgG" figures = ( max(precision, 1) if presentation_type in "gG" else precision + 1 ) negative, significand, exponent = _round_to_figures( self._numerator, self._denominator, figures) scientific = ( presentation_type in "eE" or exponent > 0 or exponent + figures <= -4 ) point_pos = figures - 1 if scientific else -exponent # Get the suffix - the part following the digits, if any. if presentation_type == "%": suffix = "%" elif scientific: suffix = f"{exponent_indicator}{exponent + point_pos:+03d}" else: suffix = "" # String of output digits, padded sufficiently with zeros on the left # so that we'll have at least one digit before the decimal point. digits = f"{significand:0{point_pos + 1}d}" # Before padding, the output has the form f"{sign}{leading}{trailing}", # where `leading` includes thousands separators if necessary and # `trailing` includes the decimal separator where appropriate. sign = "-" if negative else pos_sign leading = digits[: len(digits) - point_pos] frac_part = digits[len(digits) - point_pos :] if trim_zeros: frac_part = frac_part.rstrip("0") separator = "" if trim_point and not frac_part else "." trailing = separator + frac_part + suffix # Do zero padding if required. if zeropad: min_leading = minimumwidth - len(sign) - len(trailing) # When adding thousands separators, they'll be added to the # zero-padded portion too, so we need to compensate. leading = leading.zfill( 3 * min_leading // 4 + 1 if thousands_sep else min_leading ) # Insert thousands separators if required. if thousands_sep: first_pos = 1 + (len(leading) - 1) % 3 leading = leading[:first_pos] + "".join( thousands_sep + leading[pos : pos + 3] for pos in range(first_pos, len(leading), 3) ) # We now have a sign and a body. Pad with fill character if necessary # and return. body = leading + trailing padding = fill * (minimumwidth - len(sign) - len(body)) if align == ">": return padding + sign + body elif align == "<": return sign + body + padding elif align == "^": half = len(padding) // 2 return padding[:half] + sign + body + padding[half:] else: # align == "=" return sign + padding + body def _operator_fallbacks(monomorphic_operator, fallback_operator): """Generates forward and reverse operators given a purely-rational operator and a function from the operator module. Use this like: __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op) In general, we want to implement the arithmetic operations so that mixed-mode operations either call an implementation whose author knew about the types of both arguments, or convert both to the nearest built in type and do the operation there. In Fraction, that means that we define __add__ and __radd__ as: def __add__(self, other): # Both types have numerators/denominator attributes, # so do the operation directly if isinstance(other, (int, Fraction)): return Fraction(self.numerator * other.denominator + other.numerator * self.denominator, self.denominator * other.denominator) # float and complex don't have those operations, but we # know about those types, so special case them. elif isinstance(other, float): return float(self) + other elif isinstance(other, complex): return complex(self) + other # Let the other type take over. return NotImplemented def __radd__(self, other): # radd handles more types than add because there's # nothing left to fall back to. if isinstance(other, numbers.Rational): return Fraction(self.numerator * other.denominator + other.numerator * self.denominator, self.denominator * other.denominator) elif isinstance(other, Real): return float(other) + float(self) elif isinstance(other, Complex): return complex(other) + complex(self) return NotImplemented There are 5 different cases for a mixed-type addition on Fraction. I'll refer to all of the above code that doesn't refer to Fraction, float, or complex as "boilerplate". 'r' will be an instance of Fraction, which is a subtype of Rational (r : Fraction <: Rational), and b : B <: Complex. The first three involve 'r + b': 1. If B <: Fraction, int, float, or complex, we handle that specially, and all is well. 2. If Fraction falls back to the boilerplate code, and it were to return a value from __add__, we'd miss the possibility that B defines a more intelligent __radd__, so the boilerplate should return NotImplemented from __add__. In particular, we don't handle Rational here, even though we could get an exact answer, in case the other type wants to do something special. 3. If B <: Fraction, Python tries B.__radd__ before Fraction.__add__. This is ok, because it was implemented with knowledge of Fraction, so it can handle those instances before delegating to Real or Complex. The next two situations describe 'b + r'. We assume that b didn't know about Fraction in its implementation, and that it uses similar boilerplate code: 4. If B <: Rational, then __radd_ converts both to the builtin rational type (hey look, that's us) and proceeds. 5. Otherwise, __radd__ tries to find the nearest common base ABC, and fall back to its builtin type. Since this class doesn't subclass a concrete type, there's no implementation to fall back to, so we need to try as hard as possible to return an actual value, or the user will get a TypeError. """ def forward(a, b): if isinstance(b, Fraction): return monomorphic_operator(a, b) elif isinstance(b, int): return monomorphic_operator(a, Fraction(b)) elif isinstance(b, float): return fallback_operator(float(a), b) elif isinstance(b, complex): return fallback_operator(complex(a), b) else: return NotImplemented forward.__name__ = '__' + fallback_operator.__name__ + '__' forward.__doc__ = monomorphic_operator.__doc__ def reverse(b, a): if isinstance(a, numbers.Rational): # Includes ints. return monomorphic_operator(Fraction(a), b) elif isinstance(a, numbers.Real): return fallback_operator(float(a), float(b)) elif isinstance(a, numbers.Complex): return fallback_operator(complex(a), complex(b)) else: return NotImplemented reverse.__name__ = '__r' + fallback_operator.__name__ + '__' reverse.__doc__ = monomorphic_operator.__doc__ return forward, reverse # Rational arithmetic algorithms: Knuth, TAOCP, Volume 2, 4.5.1. # # Assume input fractions a and b are normalized. # # 1) Consider addition/subtraction. # # Let g = gcd(da, db). Then # # na nb na*db ± nb*da # a ± b == -- ± -- == ------------- == # da db da*db # # na*(db//g) ± nb*(da//g) t # == ----------------------- == - # (da*db)//g d # # Now, if g > 1, we're working with smaller integers. # # Note, that t, (da//g) and (db//g) are pairwise coprime. # # Indeed, (da//g) and (db//g) share no common factors (they were # removed) and da is coprime with na (since input fractions are # normalized), hence (da//g) and na are coprime. By symmetry, # (db//g) and nb are coprime too. Then, # # gcd(t, da//g) == gcd(na*(db//g), da//g) == 1 # gcd(t, db//g) == gcd(nb*(da//g), db//g) == 1 # # Above allows us optimize reduction of the result to lowest # terms. Indeed, # # g2 = gcd(t, d) == gcd(t, (da//g)*(db//g)*g) == gcd(t, g) # # t//g2 t//g2 # a ± b == ----------------------- == ---------------- # (da//g)*(db//g)*(g//g2) (da//g)*(db//g2) # # is a normalized fraction. This is useful because the unnormalized # denominator d could be much larger than g. # # We should special-case g == 1 (and g2 == 1), since 60.8% of # randomly-chosen integers are coprime: # https://en.wikipedia.org/wiki/Coprime_integers#Probability_of_coprimality # Note, that g2 == 1 always for fractions, obtained from floats: here # g is a power of 2 and the unnormalized numerator t is an odd integer. # # 2) Consider multiplication # # Let g1 = gcd(na, db) and g2 = gcd(nb, da), then # # na*nb na*nb (na//g1)*(nb//g2) # a*b == ----- == ----- == ----------------- # da*db db*da (db//g1)*(da//g2) # # Note, that after divisions we're multiplying smaller integers. # # Also, the resulting fraction is normalized, because each of # two factors in the numerator is coprime to each of the two factors # in the denominator. # # Indeed, pick (na//g1). It's coprime with (da//g2), because input # fractions are normalized. It's also coprime with (db//g1), because # common factors are removed by g1 == gcd(na, db). # # As for addition/subtraction, we should special-case g1 == 1 # and g2 == 1 for same reason. That happens also for multiplying # rationals, obtained from floats. def _add(a, b): """a + b""" na, da = a._numerator, a._denominator nb, db = b._numerator, b._denominator g = math.gcd(da, db) if g == 1: return Fraction._from_coprime_ints(na * db + da * nb, da * db) s = da // g t = na * (db // g) + nb * s g2 = math.gcd(t, g) if g2 == 1: return Fraction._from_coprime_ints(t, s * db) return Fraction._from_coprime_ints(t // g2, s * (db // g2)) __add__, __radd__ = _operator_fallbacks(_add, operator.add) def _sub(a, b): """a - b""" na, da = a._numerator, a._denominator nb, db = b._numerator, b._denominator g = math.gcd(da, db) if g == 1: return Fraction._from_coprime_ints(na * db - da * nb, da * db) s = da // g t = na * (db // g) - nb * s g2 = math.gcd(t, g) if g2 == 1: return Fraction._from_coprime_ints(t, s * db) return Fraction._from_coprime_ints(t // g2, s * (db // g2)) __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) def _mul(a, b): """a * b""" na, da = a._numerator, a._denominator nb, db = b._numerator, b._denominator g1 = math.gcd(na, db) if g1 > 1: na //= g1 db //= g1 g2 = math.gcd(nb, da) if g2 > 1: nb //= g2 da //= g2 return Fraction._from_coprime_ints(na * nb, db * da) __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul) def _div(a, b): """a / b""" # Same as _mul(), with inversed b. nb, db = b._numerator, b._denominator if nb == 0: raise ZeroDivisionError('Fraction(%s, 0)' % db) na, da = a._numerator, a._denominator g1 = math.gcd(na, nb) if g1 > 1: na //= g1 nb //= g1 g2 = math.gcd(db, da) if g2 > 1: da //= g2 db //= g2 n, d = na * db, nb * da if d < 0: n, d = -n, -d return Fraction._from_coprime_ints(n, d) __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) def _floordiv(a, b): """a // b""" return (a.numerator * b.denominator) // (a.denominator * b.numerator) __floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv) def _divmod(a, b): """(a // b, a % b)""" da, db = a.denominator, b.denominator div, n_mod = divmod(a.numerator * db, da * b.numerator) return div, Fraction(n_mod, da * db) __divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod) def _mod(a, b): """a % b""" da, db = a.denominator, b.denominator return Fraction((a.numerator * db) % (b.numerator * da), da * db) __mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod) def __pow__(a, b): """a ** b If b is not an integer, the result will be a float or complex since roots are generally irrational. If b is an integer, the result will be rational. """ if isinstance(b, numbers.Rational): if b.denominator == 1: power = b.numerator if power >= 0: return Fraction._from_coprime_ints(a._numerator ** power, a._denominator ** power) elif a._numerator > 0: return Fraction._from_coprime_ints(a._denominator ** -power, a._numerator ** -power) elif a._numerator == 0: raise ZeroDivisionError('Fraction(%s, 0)' % a._denominator ** -power) else: return Fraction._from_coprime_ints((-a._denominator) ** -power, (-a._numerator) ** -power) else: # A fractional power will generally produce an # irrational number. return float(a) ** float(b) elif isinstance(b, (float, complex)): return float(a) ** b else: return NotImplemented def __rpow__(b, a): """a ** b""" if b._denominator == 1 and b._numerator >= 0: # If a is an int, keep it that way if possible. return a ** b._numerator if isinstance(a, numbers.Rational): return Fraction(a.numerator, a.denominator) ** b if b._denominator == 1: return a ** b._numerator return a ** float(b) def __pos__(a): """+a: Coerces a subclass instance to Fraction""" return Fraction._from_coprime_ints(a._numerator, a._denominator) def __neg__(a): """-a""" return Fraction._from_coprime_ints(-a._numerator, a._denominator) def __abs__(a): """abs(a)""" return Fraction._from_coprime_ints(abs(a._numerator), a._denominator) def __int__(a, _index=operator.index): """int(a)""" if a._numerator < 0: return _index(-(-a._numerator // a._denominator)) else: return _index(a._numerator // a._denominator) def __trunc__(a): """math.trunc(a)""" if a._numerator < 0: return -(-a._numerator // a._denominator) else: return a._numerator // a._denominator def __floor__(a): """math.floor(a)""" return a._numerator // a._denominator def __ceil__(a): """math.ceil(a)""" # The negations cleverly convince floordiv to return the ceiling. return -(-a._numerator // a._denominator) def __round__(self, ndigits=None): """round(self, ndigits) Rounds half toward even. """ if ndigits is None: d = self._denominator floor, remainder = divmod(self._numerator, d) if remainder * 2 < d: return floor elif remainder * 2 > d: return floor + 1 # Deal with the half case: elif floor % 2 == 0: return floor else: return floor + 1 shift = 10**abs(ndigits) # See _operator_fallbacks.forward to check that the results of # these operations will always be Fraction and therefore have # round(). if ndigits > 0: return Fraction(round(self * shift), shift) else: return Fraction(round(self / shift) * shift) def __hash__(self): """hash(self)""" return _hash_algorithm(self._numerator, self._denominator) def __eq__(a, b): """a == b""" if type(b) is int: return a._numerator == b and a._denominator == 1 if isinstance(b, numbers.Rational): return (a._numerator == b.numerator and a._denominator == b.denominator) if isinstance(b, numbers.Complex) and b.imag == 0: b = b.real if isinstance(b, float): if math.isnan(b) or math.isinf(b): # comparisons with an infinity or nan should behave in # the same way for any finite a, so treat a as zero. return 0.0 == b else: return a == a.from_float(b) else: # Since a doesn't know how to compare with b, let's give b # a chance to compare itself with a. return NotImplemented def _richcmp(self, other, op): """Helper for comparison operators, for internal use only. Implement comparison between a Rational instance `self`, and either another Rational instance or a float `other`. If `other` is not a Rational instance or a float, return NotImplemented. `op` should be one of the six standard comparison operators. """ # convert other to a Rational instance where reasonable. if isinstance(other, numbers.Rational): return op(self._numerator * other.denominator, self._denominator * other.numerator) if isinstance(other, float): if math.isnan(other) or math.isinf(other): return op(0.0, other) else: return op(self, self.from_float(other)) else: return NotImplemented def __lt__(a, b): """a < b""" return a._richcmp(b, operator.lt) def __gt__(a, b): """a > b""" return a._richcmp(b, operator.gt) def __le__(a, b): """a <= b""" return a._richcmp(b, operator.le) def __ge__(a, b): """a >= b""" return a._richcmp(b, operator.ge) def __bool__(a): """a != 0""" # bpo-39274: Use bool() because (a._numerator != 0) can return an # object which is not a bool. return bool(a._numerator) # support for pickling, copy, and deepcopy def __reduce__(self): return (self.__class__, (self._numerator, self._denominator)) def __copy__(self): if type(self) == Fraction: return self # I'm immutable; therefore I am my own clone return self.__class__(self._numerator, self._denominator) def __deepcopy__(self, memo): if type(self) == Fraction: return self # My components are also immutable return self.__class__(self._numerator, self._denominator) tempfile.py000064400000077202152342670510006740 0ustar00"""Temporary files. This module provides generic, low- and high-level interfaces for creating temporary files and directories. All of the interfaces provided by this module can be used without fear of race conditions except for 'mktemp'. 'mktemp' is subject to race conditions and should not be used; it is provided for backward compatibility only. The default path names are returned as str. If you supply bytes as input, all return values will be in bytes. Ex: >>> tempfile.mkstemp() (4, '/tmp/tmptpu9nin8') >>> tempfile.mkdtemp(suffix=b'') b'/tmp/tmppbi8f0hy' This module also provides some data items to the user: TMP_MAX - maximum number of names that will be tried before giving up. tempdir - If this is set to a string before the first use of any routine from this module, it will be considered as another candidate location to store temporary files. """ __all__ = [ "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces "SpooledTemporaryFile", "TemporaryDirectory", "mkstemp", "mkdtemp", # low level safe interfaces "mktemp", # deprecated unsafe interface "TMP_MAX", "gettempprefix", # constants "tempdir", "gettempdir", "gettempprefixb", "gettempdirb", ] # Imports. import functools as _functools import warnings as _warnings import io as _io import os as _os import shutil as _shutil import errno as _errno from random import Random as _Random import sys as _sys import types as _types import weakref as _weakref import _thread _allocate_lock = _thread.allocate_lock _text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL if hasattr(_os, 'O_NOFOLLOW'): _text_openflags |= _os.O_NOFOLLOW _bin_openflags = _text_openflags if hasattr(_os, 'O_BINARY'): _bin_openflags |= _os.O_BINARY if hasattr(_os, 'TMP_MAX'): TMP_MAX = _os.TMP_MAX else: TMP_MAX = 10000 # This variable _was_ unused for legacy reasons, see issue 10354. # But as of 3.5 we actually use it at runtime so changing it would # have a possibly desirable side effect... But we do not want to support # that as an API. It is undocumented on purpose. Do not depend on this. template = "tmp" # Internal routines. _once_lock = _allocate_lock() def _exists(fn): try: _os.lstat(fn) except OSError: return False else: return True def _infer_return_type(*args): """Look at the type of all args and divine their implied return type.""" return_type = None for arg in args: if arg is None: continue if isinstance(arg, _os.PathLike): arg = _os.fspath(arg) if isinstance(arg, bytes): if return_type is str: raise TypeError("Can't mix bytes and non-bytes in " "path components.") return_type = bytes else: if return_type is bytes: raise TypeError("Can't mix bytes and non-bytes in " "path components.") return_type = str if return_type is None: if tempdir is None or isinstance(tempdir, str): return str # tempfile APIs return a str by default. else: # we could check for bytes but it'll fail later on anyway return bytes return return_type def _sanitize_params(prefix, suffix, dir): """Common parameter processing for most APIs in this module.""" output_type = _infer_return_type(prefix, suffix, dir) if suffix is None: suffix = output_type() if prefix is None: if output_type is str: prefix = template else: prefix = _os.fsencode(template) if dir is None: if output_type is str: dir = gettempdir() else: dir = gettempdirb() return prefix, suffix, dir, output_type class _RandomNameSequence: """An instance of _RandomNameSequence generates an endless sequence of unpredictable strings which can safely be incorporated into file names. Each string is eight characters long. Multiple threads can safely use the same instance at the same time. _RandomNameSequence is an iterator.""" characters = "abcdefghijklmnopqrstuvwxyz0123456789_" @property def rng(self): cur_pid = _os.getpid() if cur_pid != getattr(self, '_rng_pid', None): self._rng = _Random() self._rng_pid = cur_pid return self._rng def __iter__(self): return self def __next__(self): return ''.join(self.rng.choices(self.characters, k=8)) def _candidate_tempdir_list(): """Generate a list of candidate temporary directories which _get_default_tempdir will try.""" dirlist = [] # First, try the environment. for envname in 'TMPDIR', 'TEMP', 'TMP': dirname = _os.getenv(envname) if dirname: dirlist.append(dirname) # Failing that, try OS-specific locations. if _os.name == 'nt': dirlist.extend([ _os.path.expanduser(r'~\AppData\Local\Temp'), _os.path.expandvars(r'%SYSTEMROOT%\Temp'), r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) else: dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) # As a last resort, the current directory. try: dirlist.append(_os.getcwd()) except (AttributeError, OSError): dirlist.append(_os.curdir) return dirlist def _get_default_tempdir(): """Calculate the default directory to use for temporary files. This routine should be called exactly once. We determine whether or not a candidate temp dir is usable by trying to create and write to a file in that directory. If this is successful, the test file is deleted. To prevent denial of service, the name of the test file must be randomized.""" namer = _RandomNameSequence() dirlist = _candidate_tempdir_list() for dir in dirlist: if dir != _os.curdir: dir = _os.path.abspath(dir) # Try only a few names per directory. for seq in range(100): name = next(namer) filename = _os.path.join(dir, name) try: fd = _os.open(filename, _bin_openflags, 0o600) try: try: _os.write(fd, b'blat') finally: _os.close(fd) finally: _os.unlink(filename) return dir except FileExistsError: pass except PermissionError: # This exception is thrown when a directory with the chosen name # already exists on windows. if (_os.name == 'nt' and _os.path.isdir(dir) and _os.access(dir, _os.W_OK)): continue break # no point trying more names in this directory except OSError: break # no point trying more names in this directory raise FileNotFoundError(_errno.ENOENT, "No usable temporary directory found in %s" % dirlist) _name_sequence = None def _get_candidate_names(): """Common setup sequence for all user-callable interfaces.""" global _name_sequence if _name_sequence is None: _once_lock.acquire() try: if _name_sequence is None: _name_sequence = _RandomNameSequence() finally: _once_lock.release() return _name_sequence def _mkstemp_inner(dir, pre, suf, flags, output_type): """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.""" dir = _os.path.abspath(dir) names = _get_candidate_names() if output_type is bytes: names = map(_os.fsencode, names) for seq in range(TMP_MAX): name = next(names) file = _os.path.join(dir, pre + name + suf) _sys.audit("tempfile.mkstemp", file) try: fd = _os.open(file, flags, 0o600) except FileExistsError: continue # try again except PermissionError: # This exception is thrown when a directory with the chosen name # already exists on windows. if (_os.name == 'nt' and _os.path.isdir(dir) and _os.access(dir, _os.W_OK)): continue else: raise return fd, file raise FileExistsError(_errno.EEXIST, "No usable temporary file name found") def _dont_follow_symlinks(func, path, *args): # Pass follow_symlinks=False, unless not supported on this platform. if func in _os.supports_follow_symlinks: func(path, *args, follow_symlinks=False) elif _os.name == 'nt' or not _os.path.islink(path): func(path, *args) def _resetperms(path): try: chflags = _os.chflags except AttributeError: pass else: _dont_follow_symlinks(chflags, path, 0) _dont_follow_symlinks(_os.chmod, path, 0o700) # User visible interfaces. def gettempprefix(): """The default prefix for temporary directories as string.""" return _os.fsdecode(template) def gettempprefixb(): """The default prefix for temporary directories as bytes.""" return _os.fsencode(template) tempdir = None def _gettempdir(): """Private accessor for tempfile.tempdir.""" global tempdir if tempdir is None: _once_lock.acquire() try: if tempdir is None: tempdir = _get_default_tempdir() finally: _once_lock.release() return tempdir def gettempdir(): """Returns tempfile.tempdir as str.""" return _os.fsdecode(_gettempdir()) def gettempdirb(): """Returns tempfile.tempdir as bytes.""" return _os.fsencode(_gettempdir()) def mkstemp(suffix=None, prefix=None, dir=None, text=False): """User-callable function to create and return a unique temporary file. The return value is a pair (fd, name) where fd is the file descriptor returned by os.open, and name is the filename. If 'suffix' is not None, the file name will end with that suffix, otherwise there will be no suffix. If 'prefix' is not None, the file name will begin with that prefix, otherwise a default prefix is used. If 'dir' is not None, the file will be created in that directory, otherwise a default directory is used. If 'text' is specified and true, the file is opened in text mode. Else (the default) the file is opened in binary mode. If any of 'suffix', 'prefix' and 'dir' are not None, they must be the same type. If they are bytes, the returned name will be bytes; str otherwise. The file is readable and writable only by the creating user ID. If the operating system uses permission bits to indicate whether a file is executable, the file is executable by no one. The file descriptor is not inherited by children of this process. Caller is responsible for deleting the file when done with it. """ prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) if text: flags = _text_openflags else: flags = _bin_openflags return _mkstemp_inner(dir, prefix, suffix, flags, output_type) def mkdtemp(suffix=None, prefix=None, dir=None): """User-callable function to create and return a unique temporary directory. The return value is the pathname of the directory. Arguments are as for mkstemp, except that the 'text' argument is not accepted. The directory is readable, writable, and searchable only by the creating user. Caller is responsible for deleting the directory when done with it. """ prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) names = _get_candidate_names() if output_type is bytes: names = map(_os.fsencode, names) for seq in range(TMP_MAX): name = next(names) file = _os.path.join(dir, prefix + name + suffix) _sys.audit("tempfile.mkdtemp", file) try: _os.mkdir(file, 0o700) except FileExistsError: continue # try again except PermissionError: # This exception is thrown when a directory with the chosen name # already exists on windows. if (_os.name == 'nt' and _os.path.isdir(dir) and _os.access(dir, _os.W_OK)): continue else: raise return _os.path.abspath(file) raise FileExistsError(_errno.EEXIST, "No usable temporary directory name found") def mktemp(suffix="", prefix=template, dir=None): """User-callable function to return a unique temporary file name. The file is not created. Arguments are similar to mkstemp, except that the 'text' argument is not accepted, and suffix=None, prefix=None and bytes file names are not supported. THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may refer to a file that did not exist at some point, but by the time you get around to creating it, someone else may have beaten you to the punch. """ ## from warnings import warn as _warn ## _warn("mktemp is a potential security risk to your program", ## RuntimeWarning, stacklevel=2) if dir is None: dir = gettempdir() names = _get_candidate_names() for seq in range(TMP_MAX): name = next(names) file = _os.path.join(dir, prefix + name + suffix) if not _exists(file): return file raise FileExistsError(_errno.EEXIST, "No usable temporary filename found") class _TemporaryFileCloser: """A separate object allowing proper closing of a temporary file's underlying file object, without adding a __del__ method to the temporary file.""" cleanup_called = False close_called = False def __init__(self, file, name, delete=True, delete_on_close=True): self.file = file self.name = name self.delete = delete self.delete_on_close = delete_on_close def cleanup(self, windows=(_os.name == 'nt'), unlink=_os.unlink): if not self.cleanup_called: self.cleanup_called = True try: if not self.close_called: self.close_called = True self.file.close() finally: # Windows provides delete-on-close as a primitive, in which # case the file was deleted by self.file.close(). if self.delete and not (windows and self.delete_on_close): try: unlink(self.name) except FileNotFoundError: pass def close(self): if not self.close_called: self.close_called = True try: self.file.close() finally: if self.delete and self.delete_on_close: self.cleanup() def __del__(self): self.cleanup() class _TemporaryFileWrapper: """Temporary file wrapper This class provides a wrapper around files opened for temporary use. In particular, it seeks to automatically remove the file when it is no longer needed. """ def __init__(self, file, name, delete=True, delete_on_close=True): self.file = file self.name = name self._closer = _TemporaryFileCloser(file, name, delete, delete_on_close) def __getattr__(self, name): # Attribute lookups are delegated to the underlying file # and cached for non-numeric results # (i.e. methods are cached, closed and friends are not) file = self.__dict__['file'] a = getattr(file, name) if hasattr(a, '__call__'): func = a @_functools.wraps(func) def func_wrapper(*args, **kwargs): return func(*args, **kwargs) # Avoid closing the file as long as the wrapper is alive, # see issue #18879. func_wrapper._closer = self._closer a = func_wrapper if not isinstance(a, int): setattr(self, name, a) return a # The underlying __enter__ method returns the wrong object # (self.file) so override it to return the wrapper def __enter__(self): self.file.__enter__() return self # Need to trap __exit__ as well to ensure the file gets # deleted when used in a with statement def __exit__(self, exc, value, tb): result = self.file.__exit__(exc, value, tb) self._closer.cleanup() return result def close(self): """ Close the temporary file, possibly deleting it. """ self._closer.close() # iter() doesn't use __getattr__ to find the __iter__ method def __iter__(self): # Don't return iter(self.file), but yield from it to avoid closing # file as long as it's being used as iterator (see issue #23700). We # can't use 'yield from' here because iter(file) returns the file # object itself, which has a close method, and thus the file would get # closed when the generator is finalized, due to PEP380 semantics. for line in self.file: yield line def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None, delete_on_close=True): """Create and return a temporary file. Arguments: 'prefix', 'suffix', 'dir' -- as for mkstemp. 'mode' -- the mode argument to io.open (default "w+b"). 'buffering' -- the buffer size argument to io.open (default -1). 'encoding' -- the encoding argument to io.open (default None) 'newline' -- the newline argument to io.open (default None) 'delete' -- whether the file is automatically deleted (default True). 'delete_on_close' -- if 'delete', whether the file is deleted on close (default True) or otherwise either on context manager exit (if context manager was used) or on object finalization. . 'errors' -- the errors argument to io.open (default None) The file is created as mkstemp() would do it. Returns an object with a file-like interface; the name of the file is accessible as its 'name' attribute. The file will be automatically deleted when it is closed unless the 'delete' argument is set to False. On POSIX, NamedTemporaryFiles cannot be automatically deleted if the creating process is terminated abruptly with a SIGKILL signal. Windows can delete the file even in this case. """ prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) flags = _bin_openflags # Setting O_TEMPORARY in the flags causes the OS to delete # the file when it is closed. This is only supported by Windows. if _os.name == 'nt' and delete and delete_on_close: flags |= _os.O_TEMPORARY if "b" not in mode: encoding = _io.text_encoding(encoding) name = None def opener(*args): nonlocal name fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type) return fd try: file = _io.open(dir, mode, buffering=buffering, newline=newline, encoding=encoding, errors=errors, opener=opener) try: raw = getattr(file, 'buffer', file) raw = getattr(raw, 'raw', raw) raw.name = name return _TemporaryFileWrapper(file, name, delete, delete_on_close) except: file.close() raise except: if name is not None and not ( _os.name == 'nt' and delete and delete_on_close): _os.unlink(name) raise if _os.name != 'posix' or _sys.platform == 'cygwin': # On non-POSIX and Cygwin systems, assume that we cannot unlink a file # while it is open. TemporaryFile = NamedTemporaryFile else: # Is the O_TMPFILE flag available and does it work? # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an # IsADirectoryError exception _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE') def TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None): """Create and return a temporary file. Arguments: 'prefix', 'suffix', 'dir' -- as for mkstemp. 'mode' -- the mode argument to io.open (default "w+b"). 'buffering' -- the buffer size argument to io.open (default -1). 'encoding' -- the encoding argument to io.open (default None) 'newline' -- the newline argument to io.open (default None) 'errors' -- the errors argument to io.open (default None) The file is created as mkstemp() would do it. Returns an object with a file-like interface. The file has no name, and will cease to exist when it is closed. """ global _O_TMPFILE_WORKS if "b" not in mode: encoding = _io.text_encoding(encoding) prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) flags = _bin_openflags if _O_TMPFILE_WORKS: fd = None def opener(*args): nonlocal fd flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT fd = _os.open(dir, flags2, 0o600) return fd try: file = _io.open(dir, mode, buffering=buffering, newline=newline, encoding=encoding, errors=errors, opener=opener) raw = getattr(file, 'buffer', file) raw = getattr(raw, 'raw', raw) raw.name = fd return file except IsADirectoryError: # Linux kernel older than 3.11 ignores the O_TMPFILE flag: # O_TMPFILE is read as O_DIRECTORY. Trying to open a directory # with O_RDWR|O_DIRECTORY fails with IsADirectoryError, a # directory cannot be open to write. Set flag to False to not # try again. _O_TMPFILE_WORKS = False except OSError: # The filesystem of the directory does not support O_TMPFILE. # For example, OSError(95, 'Operation not supported'). # # On Linux kernel older than 3.11, trying to open a regular # file (or a symbolic link to a regular file) with O_TMPFILE # fails with NotADirectoryError, because O_TMPFILE is read as # O_DIRECTORY. pass # Fallback to _mkstemp_inner(). fd = None def opener(*args): nonlocal fd fd, name = _mkstemp_inner(dir, prefix, suffix, flags, output_type) try: _os.unlink(name) except BaseException as e: _os.close(fd) raise return fd file = _io.open(dir, mode, buffering=buffering, newline=newline, encoding=encoding, errors=errors, opener=opener) raw = getattr(file, 'buffer', file) raw = getattr(raw, 'raw', raw) raw.name = fd return file class SpooledTemporaryFile(_io.IOBase): """Temporary file wrapper, specialized to switch from BytesIO or StringIO to a real file when it exceeds a certain size or when a fileno is needed. """ _rolled = False def __init__(self, max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None): if 'b' in mode: self._file = _io.BytesIO() else: encoding = _io.text_encoding(encoding) self._file = _io.TextIOWrapper(_io.BytesIO(), encoding=encoding, errors=errors, newline=newline) self._max_size = max_size self._rolled = False self._TemporaryFileArgs = {'mode': mode, 'buffering': buffering, 'suffix': suffix, 'prefix': prefix, 'encoding': encoding, 'newline': newline, 'dir': dir, 'errors': errors} __class_getitem__ = classmethod(_types.GenericAlias) def _check(self, file): if self._rolled: return max_size = self._max_size if max_size and file.tell() > max_size: self.rollover() def rollover(self): if self._rolled: return file = self._file newfile = self._file = TemporaryFile(**self._TemporaryFileArgs) del self._TemporaryFileArgs pos = file.tell() if hasattr(newfile, 'buffer'): newfile.buffer.write(file.detach().getvalue()) else: newfile.write(file.getvalue()) newfile.seek(pos, 0) self._rolled = True # The method caching trick from NamedTemporaryFile # won't work here, because _file may change from a # BytesIO/StringIO instance to a real file. So we list # all the methods directly. # Context management protocol def __enter__(self): if self._file.closed: raise ValueError("Cannot enter context with closed file") return self def __exit__(self, exc, value, tb): self._file.close() # file protocol def __iter__(self): return self._file.__iter__() def __del__(self): if not self.closed: _warnings.warn( "Unclosed file {!r}".format(self), ResourceWarning, stacklevel=2, source=self ) self.close() def close(self): self._file.close() @property def closed(self): return self._file.closed @property def encoding(self): return self._file.encoding @property def errors(self): return self._file.errors def fileno(self): self.rollover() return self._file.fileno() def flush(self): self._file.flush() def isatty(self): return self._file.isatty() @property def mode(self): try: return self._file.mode except AttributeError: return self._TemporaryFileArgs['mode'] @property def name(self): try: return self._file.name except AttributeError: return None @property def newlines(self): return self._file.newlines def readable(self): return self._file.readable() def read(self, *args): return self._file.read(*args) def read1(self, *args): return self._file.read1(*args) def readinto(self, b): return self._file.readinto(b) def readinto1(self, b): return self._file.readinto1(b) def readline(self, *args): return self._file.readline(*args) def readlines(self, *args): return self._file.readlines(*args) def seekable(self): return self._file.seekable() def seek(self, *args): return self._file.seek(*args) def tell(self): return self._file.tell() def truncate(self, size=None): if size is None: return self._file.truncate() else: if size > self._max_size: self.rollover() return self._file.truncate(size) def writable(self): return self._file.writable() def write(self, s): file = self._file rv = file.write(s) self._check(file) return rv def writelines(self, iterable): if self._max_size == 0 or self._rolled: return self._file.writelines(iterable) it = iter(iterable) for line in it: self.write(line) if self._rolled: return self._file.writelines(it) def detach(self): return self._file.detach() class TemporaryDirectory: """Create and return a temporary directory. This has the same behavior as mkdtemp but can be used as a context manager. For example: with TemporaryDirectory() as tmpdir: ... Upon exiting the context, the directory and everything contained in it are removed (unless delete=False is passed or an exception is raised during cleanup and ignore_cleanup_errors is not True). Optional Arguments: suffix - A str suffix for the directory name. (see mkdtemp) prefix - A str prefix for the directory name. (see mkdtemp) dir - A directory to create this temp dir in. (see mkdtemp) ignore_cleanup_errors - False; ignore exceptions during cleanup? delete - True; whether the directory is automatically deleted. """ def __init__(self, suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False, *, delete=True): self.name = mkdtemp(suffix, prefix, dir) self._ignore_cleanup_errors = ignore_cleanup_errors self._delete = delete self._finalizer = _weakref.finalize( self, self._cleanup, self.name, warn_message="Implicitly cleaning up {!r}".format(self), ignore_errors=self._ignore_cleanup_errors, delete=self._delete) @classmethod def _rmtree(cls, name, ignore_errors=False, repeated=False): def onexc(func, path, exc): if isinstance(exc, PermissionError): if repeated and path == name: if ignore_errors: return raise try: if path != name: _resetperms(_os.path.dirname(path)) _resetperms(path) try: _os.unlink(path) except IsADirectoryError: cls._rmtree(path, ignore_errors=ignore_errors) except PermissionError: # The PermissionError handler was originally added for # FreeBSD in directories, but it seems that it is raised # on Windows too. # bpo-43153: Calling _rmtree again may # raise NotADirectoryError and mask the PermissionError. # So we must re-raise the current PermissionError if # path is not a directory. if not _os.path.isdir(path) or _os.path.isjunction(path): if ignore_errors: return raise cls._rmtree(path, ignore_errors=ignore_errors, repeated=(path == name)) except FileNotFoundError: pass elif isinstance(exc, FileNotFoundError): pass else: if not ignore_errors: raise _shutil.rmtree(name, onexc=onexc) @classmethod def _cleanup(cls, name, warn_message, ignore_errors=False, delete=True): if delete: cls._rmtree(name, ignore_errors=ignore_errors) _warnings.warn(warn_message, ResourceWarning) def __repr__(self): return "<{} {!r}>".format(self.__class__.__name__, self.name) def __enter__(self): return self.name def __exit__(self, exc, value, tb): if self._delete: self.cleanup() def cleanup(self): if self._finalizer.detach() or _os.path.exists(self.name): self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors) __class_getitem__ = classmethod(_types.GenericAlias) _osx_support.py000064400000053007152342670510007674 0ustar00"""Shared OS X support functions.""" import os import re import sys __all__ = [ 'compiler_fixup', 'customize_config_vars', 'customize_compiler', 'get_platform_osx', ] # configuration variables that may contain universal build flags, # like "-arch" or "-isdkroot", that may need customization for # the user environment _UNIVERSAL_CONFIG_VARS = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC', 'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS', 'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS') # configuration variables that may contain compiler calls _COMPILER_CONFIG_VARS = ('BLDSHARED', 'LDSHARED', 'CC', 'CXX') # prefix added to original configuration variable names _INITPRE = '_OSX_SUPPORT_INITIAL_' def _find_executable(executable, path=None): """Tries to find 'executable' in the directories listed in 'path'. A string listing directories separated by 'os.pathsep'; defaults to os.environ['PATH']. Returns the complete filename or None if not found. """ if path is None: path = os.environ['PATH'] paths = path.split(os.pathsep) base, ext = os.path.splitext(executable) if (sys.platform == 'win32') and (ext != '.exe'): executable = executable + '.exe' if not os.path.isfile(executable): for p in paths: f = os.path.join(p, executable) if os.path.isfile(f): # the file exists, we have a shot at spawn working return f return None else: return executable def _read_output(commandstring, capture_stderr=False): """Output from successful command execution or None""" # Similar to os.popen(commandstring, "r").read(), # but without actually using os.popen because that # function is not usable during python bootstrap. # tempfile is also not available then. import contextlib try: import tempfile fp = tempfile.NamedTemporaryFile() except ImportError: fp = open("/tmp/_osx_support.%s"%( os.getpid(),), "w+b") with contextlib.closing(fp) as fp: if capture_stderr: cmd = "%s >'%s' 2>&1" % (commandstring, fp.name) else: cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name) return fp.read().decode('utf-8').strip() if not os.system(cmd) else None def _find_build_tool(toolname): """Find a build tool on current path or using xcrun""" return (_find_executable(toolname) or _read_output("/usr/bin/xcrun -find %s" % (toolname,)) or '' ) _SYSTEM_VERSION = None def _get_system_version(): """Return the OS X system version as a string""" # Reading this plist is a documented way to get the system # version (see the documentation for the Gestalt Manager) # We avoid using platform.mac_ver to avoid possible bootstrap issues during # the build of Python itself (distutils is used to build standard library # extensions). global _SYSTEM_VERSION if _SYSTEM_VERSION is None: _SYSTEM_VERSION = '' try: f = open('/System/Library/CoreServices/SystemVersion.plist', encoding="utf-8") except OSError: # We're on a plain darwin box, fall back to the default # behaviour. pass else: try: m = re.search(r'ProductUserVisibleVersion\s*' r'(.*?)', f.read()) finally: f.close() if m is not None: _SYSTEM_VERSION = '.'.join(m.group(1).split('.')[:2]) # else: fall back to the default behaviour return _SYSTEM_VERSION _SYSTEM_VERSION_TUPLE = None def _get_system_version_tuple(): """ Return the macOS system version as a tuple The return value is safe to use to compare two version numbers. """ global _SYSTEM_VERSION_TUPLE if _SYSTEM_VERSION_TUPLE is None: osx_version = _get_system_version() if osx_version: try: _SYSTEM_VERSION_TUPLE = tuple(int(i) for i in osx_version.split('.')) except ValueError: _SYSTEM_VERSION_TUPLE = () return _SYSTEM_VERSION_TUPLE def _remove_original_values(_config_vars): """Remove original unmodified values for testing""" # This is needed for higher-level cross-platform tests of get_platform. for k in list(_config_vars): if k.startswith(_INITPRE): del _config_vars[k] def _save_modified_value(_config_vars, cv, newvalue): """Save modified and original unmodified value of configuration var""" oldvalue = _config_vars.get(cv, '') if (oldvalue != newvalue) and (_INITPRE + cv not in _config_vars): _config_vars[_INITPRE + cv] = oldvalue _config_vars[cv] = newvalue _cache_default_sysroot = None def _default_sysroot(cc): """ Returns the root of the default SDK for this system, or '/' """ global _cache_default_sysroot if _cache_default_sysroot is not None: return _cache_default_sysroot contents = _read_output('%s -c -E -v - "): in_incdirs = True elif line.startswith("End of search list"): in_incdirs = False elif in_incdirs: line = line.strip() if line == '/usr/include': _cache_default_sysroot = '/' elif line.endswith(".sdk/usr/include"): _cache_default_sysroot = line[:-12] if _cache_default_sysroot is None: _cache_default_sysroot = '/' return _cache_default_sysroot def _supports_universal_builds(): """Returns True if universal builds are supported on this system""" # As an approximation, we assume that if we are running on 10.4 or above, # then we are running with an Xcode environment that supports universal # builds, in particular -isysroot and -arch arguments to the compiler. This # is in support of allowing 10.4 universal builds to run on 10.3.x systems. osx_version = _get_system_version_tuple() return bool(osx_version >= (10, 4)) if osx_version else False def _supports_arm64_builds(): """Returns True if arm64 builds are supported on this system""" # There are two sets of systems supporting macOS/arm64 builds: # 1. macOS 11 and later, unconditionally # 2. macOS 10.15 with Xcode 12.2 or later # For now the second category is ignored. osx_version = _get_system_version_tuple() return osx_version >= (11, 0) if osx_version else False def _find_appropriate_compiler(_config_vars): """Find appropriate C compiler for extension module builds""" # Issue #13590: # The OSX location for the compiler varies between OSX # (or rather Xcode) releases. With older releases (up-to 10.5) # the compiler is in /usr/bin, with newer releases the compiler # can only be found inside Xcode.app if the "Command Line Tools" # are not installed. # # Furthermore, the compiler that can be used varies between # Xcode releases. Up to Xcode 4 it was possible to use 'gcc-4.2' # as the compiler, after that 'clang' should be used because # gcc-4.2 is either not present, or a copy of 'llvm-gcc' that # miscompiles Python. # skip checks if the compiler was overridden with a CC env variable if 'CC' in os.environ: return _config_vars # The CC config var might contain additional arguments. # Ignore them while searching. cc = oldcc = _config_vars['CC'].split()[0] if not _find_executable(cc): # Compiler is not found on the shell search PATH. # Now search for clang, first on PATH (if the Command LIne # Tools have been installed in / or if the user has provided # another location via CC). If not found, try using xcrun # to find an uninstalled clang (within a selected Xcode). # NOTE: Cannot use subprocess here because of bootstrap # issues when building Python itself (and os.popen is # implemented on top of subprocess and is therefore not # usable as well) cc = _find_build_tool('clang') elif os.path.basename(cc).startswith('gcc'): # Compiler is GCC, check if it is LLVM-GCC data = _read_output("'%s' --version" % (cc.replace("'", "'\"'\"'"),)) if data and 'llvm-gcc' in data: # Found LLVM-GCC, fall back to clang cc = _find_build_tool('clang') if not cc: raise SystemError( "Cannot locate working compiler") if cc != oldcc: # Found a replacement compiler. # Modify config vars using new compiler, if not already explicitly # overridden by an env variable, preserving additional arguments. for cv in _COMPILER_CONFIG_VARS: if cv in _config_vars and cv not in os.environ: cv_split = _config_vars[cv].split() cv_split[0] = cc if cv != 'CXX' else cc + '++' _save_modified_value(_config_vars, cv, ' '.join(cv_split)) return _config_vars def _remove_universal_flags(_config_vars): """Remove all universal build arguments from config vars""" for cv in _UNIVERSAL_CONFIG_VARS: # Do not alter a config var explicitly overridden by env var if cv in _config_vars and cv not in os.environ: flags = _config_vars[cv] flags = re.sub(r'-arch\s+\w+\s', ' ', flags, flags=re.ASCII) flags = re.sub(r'-isysroot\s*\S+', ' ', flags) _save_modified_value(_config_vars, cv, flags) return _config_vars def _remove_unsupported_archs(_config_vars): """Remove any unsupported archs from config vars""" # Different Xcode releases support different sets for '-arch' # flags. In particular, Xcode 4.x no longer supports the # PPC architectures. # # This code automatically removes '-arch ppc' and '-arch ppc64' # when these are not supported. That makes it possible to # build extensions on OSX 10.7 and later with the prebuilt # 32-bit installer on the python.org website. # skip checks if the compiler was overridden with a CC env variable if 'CC' in os.environ: return _config_vars if re.search(r'-arch\s+ppc', _config_vars['CFLAGS']) is not None: # NOTE: Cannot use subprocess here because of bootstrap # issues when building Python itself status = os.system( """echo 'int main{};' | """ """'%s' -c -arch ppc -x c -o /dev/null /dev/null 2>/dev/null""" %(_config_vars['CC'].replace("'", "'\"'\"'"),)) if status: # The compile failed for some reason. Because of differences # across Xcode and compiler versions, there is no reliable way # to be sure why it failed. Assume here it was due to lack of # PPC support and remove the related '-arch' flags from each # config variables not explicitly overridden by an environment # variable. If the error was for some other reason, we hope the # failure will show up again when trying to compile an extension # module. for cv in _UNIVERSAL_CONFIG_VARS: if cv in _config_vars and cv not in os.environ: flags = _config_vars[cv] flags = re.sub(r'-arch\s+ppc\w*\s', ' ', flags) _save_modified_value(_config_vars, cv, flags) return _config_vars def _override_all_archs(_config_vars): """Allow override of all archs with ARCHFLAGS env var""" # NOTE: This name was introduced by Apple in OSX 10.5 and # is used by several scripting languages distributed with # that OS release. if 'ARCHFLAGS' in os.environ: arch = os.environ['ARCHFLAGS'] for cv in _UNIVERSAL_CONFIG_VARS: if cv in _config_vars and '-arch' in _config_vars[cv]: flags = _config_vars[cv] flags = re.sub(r'-arch\s+\w+\s', ' ', flags) flags = flags + ' ' + arch _save_modified_value(_config_vars, cv, flags) return _config_vars def _check_for_unavailable_sdk(_config_vars): """Remove references to any SDKs not available""" # If we're on OSX 10.5 or later and the user tries to # compile an extension using an SDK that is not present # on the current machine it is better to not use an SDK # than to fail. This is particularly important with # the standalone Command Line Tools alternative to a # full-blown Xcode install since the CLT packages do not # provide SDKs. If the SDK is not present, it is assumed # that the header files and dev libs have been installed # to /usr and /System/Library by either a standalone CLT # package or the CLT component within Xcode. cflags = _config_vars.get('CFLAGS', '') m = re.search(r'-isysroot\s*(\S+)', cflags) if m is not None: sdk = m.group(1) if not os.path.exists(sdk): for cv in _UNIVERSAL_CONFIG_VARS: # Do not alter a config var explicitly overridden by env var if cv in _config_vars and cv not in os.environ: flags = _config_vars[cv] flags = re.sub(r'-isysroot\s*\S+(?:\s|$)', ' ', flags) _save_modified_value(_config_vars, cv, flags) return _config_vars def compiler_fixup(compiler_so, cc_args): """ This function will strip '-isysroot PATH' and '-arch ARCH' from the compile flags if the user has specified one them in extra_compile_flags. This is needed because '-arch ARCH' adds another architecture to the build, without a way to remove an architecture. Furthermore GCC will barf if multiple '-isysroot' arguments are present. """ stripArch = stripSysroot = False compiler_so = list(compiler_so) if not _supports_universal_builds(): # OSX before 10.4.0, these don't support -arch and -isysroot at # all. stripArch = stripSysroot = True else: stripArch = '-arch' in cc_args stripSysroot = any(arg for arg in cc_args if arg.startswith('-isysroot')) if stripArch or 'ARCHFLAGS' in os.environ: while True: try: index = compiler_so.index('-arch') # Strip this argument and the next one: del compiler_so[index:index+2] except ValueError: break elif not _supports_arm64_builds(): # Look for "-arch arm64" and drop that for idx in reversed(range(len(compiler_so))): if compiler_so[idx] == '-arch' and compiler_so[idx+1] == "arm64": del compiler_so[idx:idx+2] if 'ARCHFLAGS' in os.environ and not stripArch: # User specified different -arch flags in the environ, # see also distutils.sysconfig compiler_so = compiler_so + os.environ['ARCHFLAGS'].split() if stripSysroot: while True: indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')] if not indices: break index = indices[0] if compiler_so[index] == '-isysroot': # Strip this argument and the next one: del compiler_so[index:index+2] else: # It's '-isysroot/some/path' in one arg del compiler_so[index:index+1] # Check if the SDK that is used during compilation actually exists, # the universal build requires the usage of a universal SDK and not all # users have that installed by default. sysroot = None argvar = cc_args indices = [i for i,x in enumerate(cc_args) if x.startswith('-isysroot')] if not indices: argvar = compiler_so indices = [i for i,x in enumerate(compiler_so) if x.startswith('-isysroot')] for idx in indices: if argvar[idx] == '-isysroot': sysroot = argvar[idx+1] break else: sysroot = argvar[idx][len('-isysroot'):] break if sysroot and not os.path.isdir(sysroot): sys.stderr.write(f"Compiling with an SDK that doesn't seem to exist: {sysroot}\n") sys.stderr.write("Please check your Xcode installation\n") sys.stderr.flush() return compiler_so def customize_config_vars(_config_vars): """Customize Python build configuration variables. Called internally from sysconfig with a mutable mapping containing name/value pairs parsed from the configured makefile used to build this interpreter. Returns the mapping updated as needed to reflect the environment in which the interpreter is running; in the case of a Python from a binary installer, the installed environment may be very different from the build environment, i.e. different OS levels, different built tools, different available CPU architectures. This customization is performed whenever distutils.sysconfig.get_config_vars() is first called. It may be used in environments where no compilers are present, i.e. when installing pure Python dists. Customization of compiler paths and detection of unavailable archs is deferred until the first extension module build is requested (in distutils.sysconfig.customize_compiler). Currently called from distutils.sysconfig """ if not _supports_universal_builds(): # On Mac OS X before 10.4, check if -arch and -isysroot # are in CFLAGS or LDFLAGS and remove them if they are. # This is needed when building extensions on a 10.3 system # using a universal build of python. _remove_universal_flags(_config_vars) # Allow user to override all archs with ARCHFLAGS env var _override_all_archs(_config_vars) # Remove references to sdks that are not found _check_for_unavailable_sdk(_config_vars) return _config_vars def customize_compiler(_config_vars): """Customize compiler path and configuration variables. This customization is performed when the first extension module build is requested in distutils.sysconfig.customize_compiler. """ # Find a compiler to use for extension module builds _find_appropriate_compiler(_config_vars) # Remove ppc arch flags if not supported here _remove_unsupported_archs(_config_vars) # Allow user to override all archs with ARCHFLAGS env var _override_all_archs(_config_vars) return _config_vars def get_platform_osx(_config_vars, osname, release, machine): """Filter values for get_platform()""" # called from get_platform() in sysconfig and distutils.util # # For our purposes, we'll assume that the system version from # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set # to. This makes the compatibility story a bit more sane because the # machine is going to compile and link as if it were # MACOSX_DEPLOYMENT_TARGET. macver = _config_vars.get('MACOSX_DEPLOYMENT_TARGET', '') if macver and '.' not in macver: # Ensure that the version includes at least a major # and minor version, even if MACOSX_DEPLOYMENT_TARGET # is set to a single-label version like "14". macver += '.0' macrelease = _get_system_version() or macver macver = macver or macrelease if macver: release = macver osname = "macosx" # Use the original CFLAGS value, if available, so that we # return the same machine type for the platform string. # Otherwise, distutils may consider this a cross-compiling # case and disallow installs. cflags = _config_vars.get(_INITPRE+'CFLAGS', _config_vars.get('CFLAGS', '')) if macrelease: try: macrelease = tuple(int(i) for i in macrelease.split('.')[0:2]) except ValueError: macrelease = (10, 3) else: # assume no universal support macrelease = (10, 3) if (macrelease >= (10, 4)) and '-arch' in cflags.strip(): # The universal build will build fat binaries, but not on # systems before 10.4 machine = 'fat' archs = re.findall(r'-arch\s+(\S+)', cflags) archs = tuple(sorted(set(archs))) if len(archs) == 1: machine = archs[0] elif archs == ('arm64', 'x86_64'): machine = 'universal2' elif archs == ('i386', 'ppc'): machine = 'fat' elif archs == ('i386', 'x86_64'): machine = 'intel' elif archs == ('i386', 'ppc', 'x86_64'): machine = 'fat3' elif archs == ('ppc64', 'x86_64'): machine = 'fat64' elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): machine = 'universal' else: raise ValueError( "Don't know machine value for archs=%r" % (archs,)) elif machine == 'i386': # On OSX the machine type returned by uname is always the # 32-bit variant, even if the executable architecture is # the 64-bit variant if sys.maxsize >= 2**32: machine = 'x86_64' elif machine in ('PowerPC', 'Power_Macintosh'): # Pick a sane name for the PPC architecture. # See 'i386' case if sys.maxsize >= 2**32: machine = 'ppc64' else: machine = 'ppc' return (osname, release, machine) runpy.py000064400000031125152342670510006302 0ustar00"""runpy.py - locating and running Python code using the module namespace Provides support for locating and running Python scripts using the Python module namespace instead of the native filesystem. This allows Python code to play nicely with non-filesystem based PEP 302 importers when locating support scripts as well as when importing modules. """ # Written by Nick Coghlan # to implement PEP 338 (Executing Modules as Scripts) import sys import importlib.machinery # importlib first so we can test #15386 via -m import importlib.util import io import os __all__ = [ "run_module", "run_path", ] # avoid 'import types' just for ModuleType ModuleType = type(sys) class _TempModule(object): """Temporarily replace a module in sys.modules with an empty namespace""" def __init__(self, mod_name): self.mod_name = mod_name self.module = ModuleType(mod_name) self._saved_module = [] def __enter__(self): mod_name = self.mod_name try: self._saved_module.append(sys.modules[mod_name]) except KeyError: pass sys.modules[mod_name] = self.module return self def __exit__(self, *args): if self._saved_module: sys.modules[self.mod_name] = self._saved_module[0] else: del sys.modules[self.mod_name] self._saved_module = [] class _ModifiedArgv0(object): def __init__(self, value): self.value = value self._saved_value = self._sentinel = object() def __enter__(self): if self._saved_value is not self._sentinel: raise RuntimeError("Already preserving saved value") self._saved_value = sys.argv[0] sys.argv[0] = self.value def __exit__(self, *args): self.value = self._sentinel sys.argv[0] = self._saved_value # TODO: Replace these helpers with importlib._bootstrap_external functions. def _run_code(code, run_globals, init_globals=None, mod_name=None, mod_spec=None, pkg_name=None, script_name=None): """Helper to run code in nominated namespace""" if init_globals is not None: run_globals.update(init_globals) if mod_spec is None: loader = None fname = script_name cached = None else: loader = mod_spec.loader fname = mod_spec.origin cached = mod_spec.cached if pkg_name is None: pkg_name = mod_spec.parent run_globals.update(__name__ = mod_name, __file__ = fname, __cached__ = cached, __doc__ = None, __loader__ = loader, __package__ = pkg_name, __spec__ = mod_spec) exec(code, run_globals) return run_globals def _run_module_code(code, init_globals=None, mod_name=None, mod_spec=None, pkg_name=None, script_name=None): """Helper to run code in new namespace with sys modified""" fname = script_name if mod_spec is None else mod_spec.origin with _TempModule(mod_name) as temp_module, _ModifiedArgv0(fname): mod_globals = temp_module.module.__dict__ _run_code(code, mod_globals, init_globals, mod_name, mod_spec, pkg_name, script_name) # Copy the globals of the temporary module, as they # may be cleared when the temporary module goes away return mod_globals.copy() # Helper to get the full name, spec and code for a module def _get_module_details(mod_name, error=ImportError): if mod_name.startswith("."): raise error("Relative module names not supported") pkg_name, _, _ = mod_name.rpartition(".") if pkg_name: # Try importing the parent to avoid catching initialization errors try: __import__(pkg_name) except ImportError as e: # If the parent or higher ancestor package is missing, let the # error be raised by find_spec() below and then be caught. But do # not allow other errors to be caught. if e.name is None or (e.name != pkg_name and not pkg_name.startswith(e.name + ".")): raise # Warn if the module has already been imported under its normal name existing = sys.modules.get(mod_name) if existing is not None and not hasattr(existing, "__path__"): from warnings import warn msg = "{mod_name!r} found in sys.modules after import of " \ "package {pkg_name!r}, but prior to execution of " \ "{mod_name!r}; this may result in unpredictable " \ "behaviour".format(mod_name=mod_name, pkg_name=pkg_name) warn(RuntimeWarning(msg)) try: spec = importlib.util.find_spec(mod_name) except (ImportError, AttributeError, TypeError, ValueError) as ex: # This hack fixes an impedance mismatch between pkgutil and # importlib, where the latter raises other errors for cases where # pkgutil previously raised ImportError msg = "Error while finding module specification for {!r} ({}: {})" if mod_name.endswith(".py"): msg += (f". Try using '{mod_name[:-3]}' instead of " f"'{mod_name}' as the module name.") raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex if spec is None: raise error("No module named %s" % mod_name) if spec.submodule_search_locations is not None: if mod_name == "__main__" or mod_name.endswith(".__main__"): raise error("Cannot use package as __main__ module") try: pkg_main_name = mod_name + ".__main__" return _get_module_details(pkg_main_name, error) except error as e: if mod_name not in sys.modules: raise # No module loaded; being a package is irrelevant raise error(("%s; %r is a package and cannot " + "be directly executed") %(e, mod_name)) loader = spec.loader if loader is None: raise error("%r is a namespace package and cannot be executed" % mod_name) try: code = loader.get_code(mod_name) except ImportError as e: raise error(format(e)) from e if code is None: raise error("No code object available for %s" % mod_name) return mod_name, spec, code class _Error(Exception): """Error that _run_module_as_main() should report without a traceback""" # XXX ncoghlan: Should this be documented and made public? # (Current thoughts: don't repeat the mistake that lead to its # creation when run_module() no longer met the needs of # mainmodule.c, but couldn't be changed because it was public) def _run_module_as_main(mod_name, alter_argv=True): """Runs the designated module in the __main__ namespace Note that the executed module will have full access to the __main__ namespace. If this is not desirable, the run_module() function should be used to run the module code in a fresh namespace. At the very least, these variables in __main__ will be overwritten: __name__ __file__ __cached__ __loader__ __package__ """ try: if alter_argv or mod_name != "__main__": # i.e. -m switch mod_name, mod_spec, code = _get_module_details(mod_name, _Error) else: # i.e. directory or zipfile execution mod_name, mod_spec, code = _get_main_module_details(_Error) except _Error as exc: msg = "%s: %s" % (sys.executable, exc) sys.exit(msg) main_globals = sys.modules["__main__"].__dict__ if alter_argv: sys.argv[0] = mod_spec.origin return _run_code(code, main_globals, None, "__main__", mod_spec) def run_module(mod_name, init_globals=None, run_name=None, alter_sys=False): """Execute a module's code without importing it. mod_name -- an absolute module name or package name. Optional arguments: init_globals -- dictionary used to pre-populate the module’s globals dictionary before the code is executed. run_name -- if not None, this will be used for setting __name__; otherwise, __name__ will be set to mod_name + '__main__' if the named module is a package and to just mod_name otherwise. alter_sys -- if True, sys.argv[0] is updated with the value of __file__ and sys.modules[__name__] is updated with a temporary module object for the module being executed. Both are restored to their original values before the function returns. Returns the resulting module globals dictionary. """ mod_name, mod_spec, code = _get_module_details(mod_name) if run_name is None: run_name = mod_name if alter_sys: return _run_module_code(code, init_globals, run_name, mod_spec) else: # Leave the sys module alone return _run_code(code, {}, init_globals, run_name, mod_spec) def _get_main_module_details(error=ImportError): # Helper that gives a nicer error message when attempting to # execute a zipfile or directory by invoking __main__.py # Also moves the standard __main__ out of the way so that the # preexisting __loader__ entry doesn't cause issues main_name = "__main__" saved_main = sys.modules[main_name] del sys.modules[main_name] try: return _get_module_details(main_name) except ImportError as exc: if main_name in str(exc): raise error("can't find %r module in %r" % (main_name, sys.path[0])) from exc raise finally: sys.modules[main_name] = saved_main def _get_code_from_file(fname): # Check for a compiled file first from pkgutil import read_code code_path = os.path.abspath(fname) with io.open_code(code_path) as f: code = read_code(f) if code is None: # That didn't work, so try it as normal source code with io.open_code(code_path) as f: code = compile(f.read(), fname, 'exec') return code def run_path(path_name, init_globals=None, run_name=None): """Execute code located at the specified filesystem location. path_name -- filesystem location of a Python script, zipfile, or directory containing a top level __main__.py script. Optional arguments: init_globals -- dictionary used to pre-populate the module’s globals dictionary before the code is executed. run_name -- if not None, this will be used to set __name__; otherwise, '' will be used for __name__. Returns the resulting module globals dictionary. """ if run_name is None: run_name = "" pkg_name = run_name.rpartition(".")[0] from pkgutil import get_importer importer = get_importer(path_name) path_name = os.fsdecode(path_name) if isinstance(importer, type(None)): # Not a valid sys.path entry, so run the code directly # execfile() doesn't help as we want to allow compiled files code = _get_code_from_file(path_name) return _run_module_code(code, init_globals, run_name, pkg_name=pkg_name, script_name=path_name) else: # Finder is defined for path, so add it to # the start of sys.path sys.path.insert(0, path_name) try: # Here's where things are a little different from the run_module # case. There, we only had to replace the module in sys while the # code was running and doing so was somewhat optional. Here, we # have no choice and we have to remove it even while we read the # code. If we don't do this, a __loader__ attribute in the # existing __main__ module may prevent location of the new module. mod_name, mod_spec, code = _get_main_module_details() with _TempModule(run_name) as temp_module, \ _ModifiedArgv0(path_name): mod_globals = temp_module.module.__dict__ return _run_code(code, mod_globals, init_globals, run_name, mod_spec, pkg_name).copy() finally: try: sys.path.remove(path_name) except ValueError: pass if __name__ == "__main__": # Run the module specified as the next command line argument if len(sys.argv) < 2: print("No module specified for execution", file=sys.stderr) else: del sys.argv[0] # Make the requested module sys.argv[0] _run_module_as_main(sys.argv[0]) pickletools.py000064400000267544152342670510007475 0ustar00'''"Executable documentation" for the pickle module. Extensive comments about the pickle protocols and pickle-machine opcodes can be found here. Some functions meant for external use: genops(pickle) Generate all the opcodes in a pickle, as (opcode, arg, position) triples. dis(pickle, out=None, memo=None, indentlevel=4) Print a symbolic disassembly of a pickle. ''' import codecs import io import pickle import re import sys __all__ = ['dis', 'genops', 'optimize'] bytes_types = pickle.bytes_types # Other ideas: # # - A pickle verifier: read a pickle and check it exhaustively for # well-formedness. dis() does a lot of this already. # # - A protocol identifier: examine a pickle and return its protocol number # (== the highest .proto attr value among all the opcodes in the pickle). # dis() already prints this info at the end. # # - A pickle optimizer: for example, tuple-building code is sometimes more # elaborate than necessary, catering for the possibility that the tuple # is recursive. Or lots of times a PUT is generated that's never accessed # by a later GET. # "A pickle" is a program for a virtual pickle machine (PM, but more accurately # called an unpickling machine). It's a sequence of opcodes, interpreted by the # PM, building an arbitrarily complex Python object. # # For the most part, the PM is very simple: there are no looping, testing, or # conditional instructions, no arithmetic and no function calls. Opcodes are # executed once each, from first to last, until a STOP opcode is reached. # # The PM has two data areas, "the stack" and "the memo". # # Many opcodes push Python objects onto the stack; e.g., INT pushes a Python # integer object on the stack, whose value is gotten from a decimal string # literal immediately following the INT opcode in the pickle bytestream. Other # opcodes take Python objects off the stack. The result of unpickling is # whatever object is left on the stack when the final STOP opcode is executed. # # The memo is simply an array of objects, or it can be implemented as a dict # mapping little integers to objects. The memo serves as the PM's "long term # memory", and the little integers indexing the memo are akin to variable # names. Some opcodes pop a stack object into the memo at a given index, # and others push a memo object at a given index onto the stack again. # # At heart, that's all the PM has. Subtleties arise for these reasons: # # + Object identity. Objects can be arbitrarily complex, and subobjects # may be shared (for example, the list [a, a] refers to the same object a # twice). It can be vital that unpickling recreate an isomorphic object # graph, faithfully reproducing sharing. # # + Recursive objects. For example, after "L = []; L.append(L)", L is a # list, and L[0] is the same list. This is related to the object identity # point, and some sequences of pickle opcodes are subtle in order to # get the right result in all cases. # # + Things pickle doesn't know everything about. Examples of things pickle # does know everything about are Python's builtin scalar and container # types, like ints and tuples. They generally have opcodes dedicated to # them. For things like module references and instances of user-defined # classes, pickle's knowledge is limited. Historically, many enhancements # have been made to the pickle protocol in order to do a better (faster, # and/or more compact) job on those. # # + Backward compatibility and micro-optimization. As explained below, # pickle opcodes never go away, not even when better ways to do a thing # get invented. The repertoire of the PM just keeps growing over time. # For example, protocol 0 had two opcodes for building Python integers (INT # and LONG), protocol 1 added three more for more-efficient pickling of short # integers, and protocol 2 added two more for more-efficient pickling of # long integers (before protocol 2, the only ways to pickle a Python long # took time quadratic in the number of digits, for both pickling and # unpickling). "Opcode bloat" isn't so much a subtlety as a source of # wearying complication. # # # Pickle protocols: # # For compatibility, the meaning of a pickle opcode never changes. Instead new # pickle opcodes get added, and each version's unpickler can handle all the # pickle opcodes in all protocol versions to date. So old pickles continue to # be readable forever. The pickler can generally be told to restrict itself to # the subset of opcodes available under previous protocol versions too, so that # users can create pickles under the current version readable by older # versions. However, a pickle does not contain its version number embedded # within it. If an older unpickler tries to read a pickle using a later # protocol, the result is most likely an exception due to seeing an unknown (in # the older unpickler) opcode. # # The original pickle used what's now called "protocol 0", and what was called # "text mode" before Python 2.3. The entire pickle bytestream is made up of # printable 7-bit ASCII characters, plus the newline character, in protocol 0. # That's why it was called text mode. Protocol 0 is small and elegant, but # sometimes painfully inefficient. # # The second major set of additions is now called "protocol 1", and was called # "binary mode" before Python 2.3. This added many opcodes with arguments # consisting of arbitrary bytes, including NUL bytes and unprintable "high bit" # bytes. Binary mode pickles can be substantially smaller than equivalent # text mode pickles, and sometimes faster too; e.g., BININT represents a 4-byte # int as 4 bytes following the opcode, which is cheaper to unpickle than the # (perhaps) 11-character decimal string attached to INT. Protocol 1 also added # a number of opcodes that operate on many stack elements at once (like APPENDS # and SETITEMS), and "shortcut" opcodes (like EMPTY_DICT and EMPTY_TUPLE). # # The third major set of additions came in Python 2.3, and is called "protocol # 2". This added: # # - A better way to pickle instances of new-style classes (NEWOBJ). # # - A way for a pickle to identify its protocol (PROTO). # # - Time- and space- efficient pickling of long ints (LONG{1,4}). # # - Shortcuts for small tuples (TUPLE{1,2,3}}. # # - Dedicated opcodes for bools (NEWTRUE, NEWFALSE). # # - The "extension registry", a vector of popular objects that can be pushed # efficiently by index (EXT{1,2,4}). This is akin to the memo and GET, but # the registry contents are predefined (there's nothing akin to the memo's # PUT). # # Another independent change with Python 2.3 is the abandonment of any # pretense that it might be safe to load pickles received from untrusted # parties -- no sufficient security analysis has been done to guarantee # this and there isn't a use case that warrants the expense of such an # analysis. # # To this end, all tests for __safe_for_unpickling__ or for # copyreg.safe_constructors are removed from the unpickling code. # References to these variables in the descriptions below are to be seen # as describing unpickling in Python 2.2 and before. # Meta-rule: Descriptions are stored in instances of descriptor objects, # with plain constructors. No meta-language is defined from which # descriptors could be constructed. If you want, e.g., XML, write a little # program to generate XML from the objects. ############################################################################## # Some pickle opcodes have an argument, following the opcode in the # bytestream. An argument is of a specific type, described by an instance # of ArgumentDescriptor. These are not to be confused with arguments taken # off the stack -- ArgumentDescriptor applies only to arguments embedded in # the opcode stream, immediately following an opcode. # Represents the number of bytes consumed by an argument delimited by the # next newline character. UP_TO_NEWLINE = -1 # Represents the number of bytes consumed by a two-argument opcode where # the first argument gives the number of bytes in the second argument. TAKEN_FROM_ARGUMENT1 = -2 # num bytes is 1-byte unsigned int TAKEN_FROM_ARGUMENT4 = -3 # num bytes is 4-byte signed little-endian int TAKEN_FROM_ARGUMENT4U = -4 # num bytes is 4-byte unsigned little-endian int TAKEN_FROM_ARGUMENT8U = -5 # num bytes is 8-byte unsigned little-endian int class ArgumentDescriptor(object): __slots__ = ( # name of descriptor record, also a module global name; a string 'name', # length of argument, in bytes; an int; UP_TO_NEWLINE and # TAKEN_FROM_ARGUMENT{1,4,8} are negative values for variable-length # cases 'n', # a function taking a file-like object, reading this kind of argument # from the object at the current position, advancing the current # position by n bytes, and returning the value of the argument 'reader', # human-readable docs for this arg descriptor; a string 'doc', ) def __init__(self, name, n, reader, doc): assert isinstance(name, str) self.name = name assert isinstance(n, int) and (n >= 0 or n in (UP_TO_NEWLINE, TAKEN_FROM_ARGUMENT1, TAKEN_FROM_ARGUMENT4, TAKEN_FROM_ARGUMENT4U, TAKEN_FROM_ARGUMENT8U)) self.n = n self.reader = reader assert isinstance(doc, str) self.doc = doc from struct import unpack as _unpack def read_uint1(f): r""" >>> import io >>> read_uint1(io.BytesIO(b'\xff')) 255 """ data = f.read(1) if data: return data[0] raise ValueError("not enough data in stream to read uint1") uint1 = ArgumentDescriptor( name='uint1', n=1, reader=read_uint1, doc="One-byte unsigned integer.") def read_uint2(f): r""" >>> import io >>> read_uint2(io.BytesIO(b'\xff\x00')) 255 >>> read_uint2(io.BytesIO(b'\xff\xff')) 65535 """ data = f.read(2) if len(data) == 2: return _unpack(">> import io >>> read_int4(io.BytesIO(b'\xff\x00\x00\x00')) 255 >>> read_int4(io.BytesIO(b'\x00\x00\x00\x80')) == -(2**31) True """ data = f.read(4) if len(data) == 4: return _unpack(">> import io >>> read_uint4(io.BytesIO(b'\xff\x00\x00\x00')) 255 >>> read_uint4(io.BytesIO(b'\x00\x00\x00\x80')) == 2**31 True """ data = f.read(4) if len(data) == 4: return _unpack(">> import io >>> read_uint8(io.BytesIO(b'\xff\x00\x00\x00\x00\x00\x00\x00')) 255 >>> read_uint8(io.BytesIO(b'\xff' * 8)) == 2**64-1 True """ data = f.read(8) if len(data) == 8: return _unpack(">> import io >>> read_stringnl(io.BytesIO(b"'abcd'\nefg\n")) 'abcd' >>> read_stringnl(io.BytesIO(b"\n")) Traceback (most recent call last): ... ValueError: no string quotes around b'' >>> read_stringnl(io.BytesIO(b"\n"), stripquotes=False) '' >>> read_stringnl(io.BytesIO(b"''\n")) '' >>> read_stringnl(io.BytesIO(b'"abcd"')) Traceback (most recent call last): ... ValueError: no newline found when trying to read stringnl Embedded escapes are undone in the result. >>> read_stringnl(io.BytesIO(br"'a\n\\b\x00c\td'" + b"\n'e'")) 'a\n\\b\x00c\td' """ data = f.readline() if not data.endswith(b'\n'): raise ValueError("no newline found when trying to read stringnl") data = data[:-1] # lose the newline if stripquotes: for q in (b'"', b"'"): if data.startswith(q): if not data.endswith(q): raise ValueError("strinq quote %r not found at both " "ends of %r" % (q, data)) data = data[1:-1] break else: raise ValueError("no string quotes around %r" % data) if decode: data = codecs.escape_decode(data)[0].decode(encoding) return data stringnl = ArgumentDescriptor( name='stringnl', n=UP_TO_NEWLINE, reader=read_stringnl, doc="""A newline-terminated string. This is a repr-style string, with embedded escapes, and bracketing quotes. """) def read_stringnl_noescape(f): return read_stringnl(f, stripquotes=False, encoding='utf-8') stringnl_noescape = ArgumentDescriptor( name='stringnl_noescape', n=UP_TO_NEWLINE, reader=read_stringnl_noescape, doc="""A newline-terminated string. This is a str-style string, without embedded escapes, or bracketing quotes. It should consist solely of printable ASCII characters. """) def read_stringnl_noescape_pair(f): r""" >>> import io >>> read_stringnl_noescape_pair(io.BytesIO(b"Queue\nEmpty\njunk")) 'Queue Empty' """ return "%s %s" % (read_stringnl_noescape(f), read_stringnl_noescape(f)) stringnl_noescape_pair = ArgumentDescriptor( name='stringnl_noescape_pair', n=UP_TO_NEWLINE, reader=read_stringnl_noescape_pair, doc="""A pair of newline-terminated strings. These are str-style strings, without embedded escapes, or bracketing quotes. They should consist solely of printable ASCII characters. The pair is returned as a single string, with a single blank separating the two strings. """) def read_string1(f): r""" >>> import io >>> read_string1(io.BytesIO(b"\x00")) '' >>> read_string1(io.BytesIO(b"\x03abcdef")) 'abc' """ n = read_uint1(f) assert n >= 0 data = f.read(n) if len(data) == n: return data.decode("latin-1") raise ValueError("expected %d bytes in a string1, but only %d remain" % (n, len(data))) string1 = ArgumentDescriptor( name="string1", n=TAKEN_FROM_ARGUMENT1, reader=read_string1, doc="""A counted string. The first argument is a 1-byte unsigned int giving the number of bytes in the string, and the second argument is that many bytes. """) def read_string4(f): r""" >>> import io >>> read_string4(io.BytesIO(b"\x00\x00\x00\x00abc")) '' >>> read_string4(io.BytesIO(b"\x03\x00\x00\x00abcdef")) 'abc' >>> read_string4(io.BytesIO(b"\x00\x00\x00\x03abcdef")) Traceback (most recent call last): ... ValueError: expected 50331648 bytes in a string4, but only 6 remain """ n = read_int4(f) if n < 0: raise ValueError("string4 byte count < 0: %d" % n) data = f.read(n) if len(data) == n: return data.decode("latin-1") raise ValueError("expected %d bytes in a string4, but only %d remain" % (n, len(data))) string4 = ArgumentDescriptor( name="string4", n=TAKEN_FROM_ARGUMENT4, reader=read_string4, doc="""A counted string. The first argument is a 4-byte little-endian signed int giving the number of bytes in the string, and the second argument is that many bytes. """) def read_bytes1(f): r""" >>> import io >>> read_bytes1(io.BytesIO(b"\x00")) b'' >>> read_bytes1(io.BytesIO(b"\x03abcdef")) b'abc' """ n = read_uint1(f) assert n >= 0 data = f.read(n) if len(data) == n: return data raise ValueError("expected %d bytes in a bytes1, but only %d remain" % (n, len(data))) bytes1 = ArgumentDescriptor( name="bytes1", n=TAKEN_FROM_ARGUMENT1, reader=read_bytes1, doc="""A counted bytes string. The first argument is a 1-byte unsigned int giving the number of bytes, and the second argument is that many bytes. """) def read_bytes4(f): r""" >>> import io >>> read_bytes4(io.BytesIO(b"\x00\x00\x00\x00abc")) b'' >>> read_bytes4(io.BytesIO(b"\x03\x00\x00\x00abcdef")) b'abc' >>> read_bytes4(io.BytesIO(b"\x00\x00\x00\x03abcdef")) Traceback (most recent call last): ... ValueError: expected 50331648 bytes in a bytes4, but only 6 remain """ n = read_uint4(f) assert n >= 0 if n > sys.maxsize: raise ValueError("bytes4 byte count > sys.maxsize: %d" % n) data = f.read(n) if len(data) == n: return data raise ValueError("expected %d bytes in a bytes4, but only %d remain" % (n, len(data))) bytes4 = ArgumentDescriptor( name="bytes4", n=TAKEN_FROM_ARGUMENT4U, reader=read_bytes4, doc="""A counted bytes string. The first argument is a 4-byte little-endian unsigned int giving the number of bytes, and the second argument is that many bytes. """) def read_bytes8(f): r""" >>> import io, struct, sys >>> read_bytes8(io.BytesIO(b"\x00\x00\x00\x00\x00\x00\x00\x00abc")) b'' >>> read_bytes8(io.BytesIO(b"\x03\x00\x00\x00\x00\x00\x00\x00abcdef")) b'abc' >>> bigsize8 = struct.pack(">> read_bytes8(io.BytesIO(bigsize8 + b"abcdef")) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: expected ... bytes in a bytes8, but only 6 remain """ n = read_uint8(f) assert n >= 0 if n > sys.maxsize: raise ValueError("bytes8 byte count > sys.maxsize: %d" % n) data = f.read(n) if len(data) == n: return data raise ValueError("expected %d bytes in a bytes8, but only %d remain" % (n, len(data))) bytes8 = ArgumentDescriptor( name="bytes8", n=TAKEN_FROM_ARGUMENT8U, reader=read_bytes8, doc="""A counted bytes string. The first argument is an 8-byte little-endian unsigned int giving the number of bytes, and the second argument is that many bytes. """) def read_bytearray8(f): r""" >>> import io, struct, sys >>> read_bytearray8(io.BytesIO(b"\x00\x00\x00\x00\x00\x00\x00\x00abc")) bytearray(b'') >>> read_bytearray8(io.BytesIO(b"\x03\x00\x00\x00\x00\x00\x00\x00abcdef")) bytearray(b'abc') >>> bigsize8 = struct.pack(">> read_bytearray8(io.BytesIO(bigsize8 + b"abcdef")) #doctest: +ELLIPSIS Traceback (most recent call last): ... ValueError: expected ... bytes in a bytearray8, but only 6 remain """ n = read_uint8(f) assert n >= 0 if n > sys.maxsize: raise ValueError("bytearray8 byte count > sys.maxsize: %d" % n) data = f.read(n) if len(data) == n: return bytearray(data) raise ValueError("expected %d bytes in a bytearray8, but only %d remain" % (n, len(data))) bytearray8 = ArgumentDescriptor( name="bytearray8", n=TAKEN_FROM_ARGUMENT8U, reader=read_bytearray8, doc="""A counted bytearray. The first argument is an 8-byte little-endian unsigned int giving the number of bytes, and the second argument is that many bytes. """) def read_unicodestringnl(f): r""" >>> import io >>> read_unicodestringnl(io.BytesIO(b"abc\\uabcd\njunk")) == 'abc\uabcd' True """ data = f.readline() if not data.endswith(b'\n'): raise ValueError("no newline found when trying to read " "unicodestringnl") data = data[:-1] # lose the newline return str(data, 'raw-unicode-escape') unicodestringnl = ArgumentDescriptor( name='unicodestringnl', n=UP_TO_NEWLINE, reader=read_unicodestringnl, doc="""A newline-terminated Unicode string. This is raw-unicode-escape encoded, so consists of printable ASCII characters, and may contain embedded escape sequences. """) def read_unicodestring1(f): r""" >>> import io >>> s = 'abcd\uabcd' >>> enc = s.encode('utf-8') >>> enc b'abcd\xea\xaf\x8d' >>> n = bytes([len(enc)]) # little-endian 1-byte length >>> t = read_unicodestring1(io.BytesIO(n + enc + b'junk')) >>> s == t True >>> read_unicodestring1(io.BytesIO(n + enc[:-1])) Traceback (most recent call last): ... ValueError: expected 7 bytes in a unicodestring1, but only 6 remain """ n = read_uint1(f) assert n >= 0 data = f.read(n) if len(data) == n: return str(data, 'utf-8', 'surrogatepass') raise ValueError("expected %d bytes in a unicodestring1, but only %d " "remain" % (n, len(data))) unicodestring1 = ArgumentDescriptor( name="unicodestring1", n=TAKEN_FROM_ARGUMENT1, reader=read_unicodestring1, doc="""A counted Unicode string. The first argument is a 1-byte little-endian signed int giving the number of bytes in the string, and the second argument-- the UTF-8 encoding of the Unicode string -- contains that many bytes. """) def read_unicodestring4(f): r""" >>> import io >>> s = 'abcd\uabcd' >>> enc = s.encode('utf-8') >>> enc b'abcd\xea\xaf\x8d' >>> n = bytes([len(enc), 0, 0, 0]) # little-endian 4-byte length >>> t = read_unicodestring4(io.BytesIO(n + enc + b'junk')) >>> s == t True >>> read_unicodestring4(io.BytesIO(n + enc[:-1])) Traceback (most recent call last): ... ValueError: expected 7 bytes in a unicodestring4, but only 6 remain """ n = read_uint4(f) assert n >= 0 if n > sys.maxsize: raise ValueError("unicodestring4 byte count > sys.maxsize: %d" % n) data = f.read(n) if len(data) == n: return str(data, 'utf-8', 'surrogatepass') raise ValueError("expected %d bytes in a unicodestring4, but only %d " "remain" % (n, len(data))) unicodestring4 = ArgumentDescriptor( name="unicodestring4", n=TAKEN_FROM_ARGUMENT4U, reader=read_unicodestring4, doc="""A counted Unicode string. The first argument is a 4-byte little-endian signed int giving the number of bytes in the string, and the second argument-- the UTF-8 encoding of the Unicode string -- contains that many bytes. """) def read_unicodestring8(f): r""" >>> import io >>> s = 'abcd\uabcd' >>> enc = s.encode('utf-8') >>> enc b'abcd\xea\xaf\x8d' >>> n = bytes([len(enc)]) + b'\0' * 7 # little-endian 8-byte length >>> t = read_unicodestring8(io.BytesIO(n + enc + b'junk')) >>> s == t True >>> read_unicodestring8(io.BytesIO(n + enc[:-1])) Traceback (most recent call last): ... ValueError: expected 7 bytes in a unicodestring8, but only 6 remain """ n = read_uint8(f) assert n >= 0 if n > sys.maxsize: raise ValueError("unicodestring8 byte count > sys.maxsize: %d" % n) data = f.read(n) if len(data) == n: return str(data, 'utf-8', 'surrogatepass') raise ValueError("expected %d bytes in a unicodestring8, but only %d " "remain" % (n, len(data))) unicodestring8 = ArgumentDescriptor( name="unicodestring8", n=TAKEN_FROM_ARGUMENT8U, reader=read_unicodestring8, doc="""A counted Unicode string. The first argument is an 8-byte little-endian signed int giving the number of bytes in the string, and the second argument-- the UTF-8 encoding of the Unicode string -- contains that many bytes. """) def read_decimalnl_short(f): r""" >>> import io >>> read_decimalnl_short(io.BytesIO(b"1234\n56")) 1234 >>> read_decimalnl_short(io.BytesIO(b"1234L\n56")) Traceback (most recent call last): ... ValueError: invalid literal for int() with base 10: b'1234L' """ s = read_stringnl(f, decode=False, stripquotes=False) # There's a hack for True and False here. if s == b"00": return False elif s == b"01": return True return int(s) def read_decimalnl_long(f): r""" >>> import io >>> read_decimalnl_long(io.BytesIO(b"1234L\n56")) 1234 >>> read_decimalnl_long(io.BytesIO(b"123456789012345678901234L\n6")) 123456789012345678901234 """ s = read_stringnl(f, decode=False, stripquotes=False) if s[-1:] == b'L': s = s[:-1] return int(s) decimalnl_short = ArgumentDescriptor( name='decimalnl_short', n=UP_TO_NEWLINE, reader=read_decimalnl_short, doc="""A newline-terminated decimal integer literal. This never has a trailing 'L', and the integer fit in a short Python int on the box where the pickle was written -- but there's no guarantee it will fit in a short Python int on the box where the pickle is read. """) decimalnl_long = ArgumentDescriptor( name='decimalnl_long', n=UP_TO_NEWLINE, reader=read_decimalnl_long, doc="""A newline-terminated decimal integer literal. This has a trailing 'L', and can represent integers of any size. """) def read_floatnl(f): r""" >>> import io >>> read_floatnl(io.BytesIO(b"-1.25\n6")) -1.25 """ s = read_stringnl(f, decode=False, stripquotes=False) return float(s) floatnl = ArgumentDescriptor( name='floatnl', n=UP_TO_NEWLINE, reader=read_floatnl, doc="""A newline-terminated decimal floating literal. In general this requires 17 significant digits for roundtrip identity, and pickling then unpickling infinities, NaNs, and minus zero doesn't work across boxes, or on some boxes even on itself (e.g., Windows can't read the strings it produces for infinities or NaNs). """) def read_float8(f): r""" >>> import io, struct >>> raw = struct.pack(">d", -1.25) >>> raw b'\xbf\xf4\x00\x00\x00\x00\x00\x00' >>> read_float8(io.BytesIO(raw + b"\n")) -1.25 """ data = f.read(8) if len(data) == 8: return _unpack(">d", data)[0] raise ValueError("not enough data in stream to read float8") float8 = ArgumentDescriptor( name='float8', n=8, reader=read_float8, doc="""An 8-byte binary representation of a float, big-endian. The format is unique to Python, and shared with the struct module (format string '>d') "in theory" (the struct and pickle implementations don't share the code -- they should). It's strongly related to the IEEE-754 double format, and, in normal cases, is in fact identical to the big-endian 754 double format. On other boxes the dynamic range is limited to that of a 754 double, and "add a half and chop" rounding is used to reduce the precision to 53 bits. However, even on a 754 box, infinities, NaNs, and minus zero may not be handled correctly (may not survive roundtrip pickling intact). """) # Protocol 2 formats from pickle import decode_long def read_long1(f): r""" >>> import io >>> read_long1(io.BytesIO(b"\x00")) 0 >>> read_long1(io.BytesIO(b"\x02\xff\x00")) 255 >>> read_long1(io.BytesIO(b"\x02\xff\x7f")) 32767 >>> read_long1(io.BytesIO(b"\x02\x00\xff")) -256 >>> read_long1(io.BytesIO(b"\x02\x00\x80")) -32768 """ n = read_uint1(f) data = f.read(n) if len(data) != n: raise ValueError("not enough data in stream to read long1") return decode_long(data) long1 = ArgumentDescriptor( name="long1", n=TAKEN_FROM_ARGUMENT1, reader=read_long1, doc="""A binary long, little-endian, using 1-byte size. This first reads one byte as an unsigned size, then reads that many bytes and interprets them as a little-endian 2's-complement long. If the size is 0, that's taken as a shortcut for the long 0L. """) def read_long4(f): r""" >>> import io >>> read_long4(io.BytesIO(b"\x02\x00\x00\x00\xff\x00")) 255 >>> read_long4(io.BytesIO(b"\x02\x00\x00\x00\xff\x7f")) 32767 >>> read_long4(io.BytesIO(b"\x02\x00\x00\x00\x00\xff")) -256 >>> read_long4(io.BytesIO(b"\x02\x00\x00\x00\x00\x80")) -32768 >>> read_long1(io.BytesIO(b"\x00\x00\x00\x00")) 0 """ n = read_int4(f) if n < 0: raise ValueError("long4 byte count < 0: %d" % n) data = f.read(n) if len(data) != n: raise ValueError("not enough data in stream to read long4") return decode_long(data) long4 = ArgumentDescriptor( name="long4", n=TAKEN_FROM_ARGUMENT4, reader=read_long4, doc="""A binary representation of a long, little-endian. This first reads four bytes as a signed size (but requires the size to be >= 0), then reads that many bytes and interprets them as a little-endian 2's-complement long. If the size is 0, that's taken as a shortcut for the int 0, although LONG1 should really be used then instead (and in any case where # of bytes < 256). """) ############################################################################## # Object descriptors. The stack used by the pickle machine holds objects, # and in the stack_before and stack_after attributes of OpcodeInfo # descriptors we need names to describe the various types of objects that can # appear on the stack. class StackObject(object): __slots__ = ( # name of descriptor record, for info only 'name', # type of object, or tuple of type objects (meaning the object can # be of any type in the tuple) 'obtype', # human-readable docs for this kind of stack object; a string 'doc', ) def __init__(self, name, obtype, doc): assert isinstance(name, str) self.name = name assert isinstance(obtype, type) or isinstance(obtype, tuple) if isinstance(obtype, tuple): for contained in obtype: assert isinstance(contained, type) self.obtype = obtype assert isinstance(doc, str) self.doc = doc def __repr__(self): return self.name pyint = pylong = StackObject( name='int', obtype=int, doc="A Python integer object.") pyinteger_or_bool = StackObject( name='int_or_bool', obtype=(int, bool), doc="A Python integer or boolean object.") pybool = StackObject( name='bool', obtype=bool, doc="A Python boolean object.") pyfloat = StackObject( name='float', obtype=float, doc="A Python float object.") pybytes_or_str = pystring = StackObject( name='bytes_or_str', obtype=(bytes, str), doc="A Python bytes or (Unicode) string object.") pybytes = StackObject( name='bytes', obtype=bytes, doc="A Python bytes object.") pybytearray = StackObject( name='bytearray', obtype=bytearray, doc="A Python bytearray object.") pyunicode = StackObject( name='str', obtype=str, doc="A Python (Unicode) string object.") pynone = StackObject( name="None", obtype=type(None), doc="The Python None object.") pytuple = StackObject( name="tuple", obtype=tuple, doc="A Python tuple object.") pylist = StackObject( name="list", obtype=list, doc="A Python list object.") pydict = StackObject( name="dict", obtype=dict, doc="A Python dict object.") pyset = StackObject( name="set", obtype=set, doc="A Python set object.") pyfrozenset = StackObject( name="frozenset", obtype=set, doc="A Python frozenset object.") pybuffer = StackObject( name='buffer', obtype=object, doc="A Python buffer-like object.") anyobject = StackObject( name='any', obtype=object, doc="Any kind of object whatsoever.") markobject = StackObject( name="mark", obtype=StackObject, doc="""'The mark' is a unique object. Opcodes that operate on a variable number of objects generally don't embed the count of objects in the opcode, or pull it off the stack. Instead the MARK opcode is used to push a special marker object on the stack, and then some other opcodes grab all the objects from the top of the stack down to (but not including) the topmost marker object. """) stackslice = StackObject( name="stackslice", obtype=StackObject, doc="""An object representing a contiguous slice of the stack. This is used in conjunction with markobject, to represent all of the stack following the topmost markobject. For example, the POP_MARK opcode changes the stack from [..., markobject, stackslice] to [...] No matter how many object are on the stack after the topmost markobject, POP_MARK gets rid of all of them (including the topmost markobject too). """) ############################################################################## # Descriptors for pickle opcodes. class OpcodeInfo(object): __slots__ = ( # symbolic name of opcode; a string 'name', # the code used in a bytestream to represent the opcode; a # one-character string 'code', # If the opcode has an argument embedded in the byte string, an # instance of ArgumentDescriptor specifying its type. Note that # arg.reader(s) can be used to read and decode the argument from # the bytestream s, and arg.doc documents the format of the raw # argument bytes. If the opcode doesn't have an argument embedded # in the bytestream, arg should be None. 'arg', # what the stack looks like before this opcode runs; a list 'stack_before', # what the stack looks like after this opcode runs; a list 'stack_after', # the protocol number in which this opcode was introduced; an int 'proto', # human-readable docs for this opcode; a string 'doc', ) def __init__(self, name, code, arg, stack_before, stack_after, proto, doc): assert isinstance(name, str) self.name = name assert isinstance(code, str) assert len(code) == 1 self.code = code assert arg is None or isinstance(arg, ArgumentDescriptor) self.arg = arg assert isinstance(stack_before, list) for x in stack_before: assert isinstance(x, StackObject) self.stack_before = stack_before assert isinstance(stack_after, list) for x in stack_after: assert isinstance(x, StackObject) self.stack_after = stack_after assert isinstance(proto, int) and 0 <= proto <= pickle.HIGHEST_PROTOCOL self.proto = proto assert isinstance(doc, str) self.doc = doc I = OpcodeInfo opcodes = [ # Ways to spell integers. I(name='INT', code='I', arg=decimalnl_short, stack_before=[], stack_after=[pyinteger_or_bool], proto=0, doc="""Push an integer or bool. The argument is a newline-terminated decimal literal string. The intent may have been that this always fit in a short Python int, but INT can be generated in pickles written on a 64-bit box that require a Python long on a 32-bit box. The difference between this and LONG then is that INT skips a trailing 'L', and produces a short int whenever possible. Another difference is due to that, when bool was introduced as a distinct type in 2.3, builtin names True and False were also added to 2.2.2, mapping to ints 1 and 0. For compatibility in both directions, True gets pickled as INT + "I01\\n", and False as INT + "I00\\n". Leading zeroes are never produced for a genuine integer. The 2.3 (and later) unpicklers special-case these and return bool instead; earlier unpicklers ignore the leading "0" and return the int. """), I(name='BININT', code='J', arg=int4, stack_before=[], stack_after=[pyint], proto=1, doc="""Push a four-byte signed integer. This handles the full range of Python (short) integers on a 32-bit box, directly as binary bytes (1 for the opcode and 4 for the integer). If the integer is non-negative and fits in 1 or 2 bytes, pickling via BININT1 or BININT2 saves space. """), I(name='BININT1', code='K', arg=uint1, stack_before=[], stack_after=[pyint], proto=1, doc="""Push a one-byte unsigned integer. This is a space optimization for pickling very small non-negative ints, in range(256). """), I(name='BININT2', code='M', arg=uint2, stack_before=[], stack_after=[pyint], proto=1, doc="""Push a two-byte unsigned integer. This is a space optimization for pickling small positive ints, in range(256, 2**16). Integers in range(256) can also be pickled via BININT2, but BININT1 instead saves a byte. """), I(name='LONG', code='L', arg=decimalnl_long, stack_before=[], stack_after=[pyint], proto=0, doc="""Push a long integer. The same as INT, except that the literal ends with 'L', and always unpickles to a Python long. There doesn't seem a real purpose to the trailing 'L'. Note that LONG takes time quadratic in the number of digits when unpickling (this is simply due to the nature of decimal->binary conversion). Proto 2 added linear-time (in C; still quadratic-time in Python) LONG1 and LONG4 opcodes. """), I(name="LONG1", code='\x8a', arg=long1, stack_before=[], stack_after=[pyint], proto=2, doc="""Long integer using one-byte length. A more efficient encoding of a Python long; the long1 encoding says it all."""), I(name="LONG4", code='\x8b', arg=long4, stack_before=[], stack_after=[pyint], proto=2, doc="""Long integer using four-byte length. A more efficient encoding of a Python long; the long4 encoding says it all."""), # Ways to spell strings (8-bit, not Unicode). I(name='STRING', code='S', arg=stringnl, stack_before=[], stack_after=[pybytes_or_str], proto=0, doc="""Push a Python string object. The argument is a repr-style string, with bracketing quote characters, and perhaps embedded escapes. The argument extends until the next newline character. These are usually decoded into a str instance using the encoding given to the Unpickler constructor. or the default, 'ASCII'. If the encoding given was 'bytes' however, they will be decoded as bytes object instead. """), I(name='BINSTRING', code='T', arg=string4, stack_before=[], stack_after=[pybytes_or_str], proto=1, doc="""Push a Python string object. There are two arguments: the first is a 4-byte little-endian signed int giving the number of bytes in the string, and the second is that many bytes, which are taken literally as the string content. These are usually decoded into a str instance using the encoding given to the Unpickler constructor. or the default, 'ASCII'. If the encoding given was 'bytes' however, they will be decoded as bytes object instead. """), I(name='SHORT_BINSTRING', code='U', arg=string1, stack_before=[], stack_after=[pybytes_or_str], proto=1, doc="""Push a Python string object. There are two arguments: the first is a 1-byte unsigned int giving the number of bytes in the string, and the second is that many bytes, which are taken literally as the string content. These are usually decoded into a str instance using the encoding given to the Unpickler constructor. or the default, 'ASCII'. If the encoding given was 'bytes' however, they will be decoded as bytes object instead. """), # Bytes (protocol 3 and higher) I(name='BINBYTES', code='B', arg=bytes4, stack_before=[], stack_after=[pybytes], proto=3, doc="""Push a Python bytes object. There are two arguments: the first is a 4-byte little-endian unsigned int giving the number of bytes, and the second is that many bytes, which are taken literally as the bytes content. """), I(name='SHORT_BINBYTES', code='C', arg=bytes1, stack_before=[], stack_after=[pybytes], proto=3, doc="""Push a Python bytes object. There are two arguments: the first is a 1-byte unsigned int giving the number of bytes, and the second is that many bytes, which are taken literally as the string content. """), I(name='BINBYTES8', code='\x8e', arg=bytes8, stack_before=[], stack_after=[pybytes], proto=4, doc="""Push a Python bytes object. There are two arguments: the first is an 8-byte unsigned int giving the number of bytes in the string, and the second is that many bytes, which are taken literally as the string content. """), # Bytearray (protocol 5 and higher) I(name='BYTEARRAY8', code='\x96', arg=bytearray8, stack_before=[], stack_after=[pybytearray], proto=5, doc="""Push a Python bytearray object. There are two arguments: the first is an 8-byte unsigned int giving the number of bytes in the bytearray, and the second is that many bytes, which are taken literally as the bytearray content. """), # Out-of-band buffer (protocol 5 and higher) I(name='NEXT_BUFFER', code='\x97', arg=None, stack_before=[], stack_after=[pybuffer], proto=5, doc="Push an out-of-band buffer object."), I(name='READONLY_BUFFER', code='\x98', arg=None, stack_before=[pybuffer], stack_after=[pybuffer], proto=5, doc="Make an out-of-band buffer object read-only."), # Ways to spell None. I(name='NONE', code='N', arg=None, stack_before=[], stack_after=[pynone], proto=0, doc="Push None on the stack."), # Ways to spell bools, starting with proto 2. See INT for how this was # done before proto 2. I(name='NEWTRUE', code='\x88', arg=None, stack_before=[], stack_after=[pybool], proto=2, doc="Push True onto the stack."), I(name='NEWFALSE', code='\x89', arg=None, stack_before=[], stack_after=[pybool], proto=2, doc="Push False onto the stack."), # Ways to spell Unicode strings. I(name='UNICODE', code='V', arg=unicodestringnl, stack_before=[], stack_after=[pyunicode], proto=0, # this may be pure-text, but it's a later addition doc="""Push a Python Unicode string object. The argument is a raw-unicode-escape encoding of a Unicode string, and so may contain embedded escape sequences. The argument extends until the next newline character. """), I(name='SHORT_BINUNICODE', code='\x8c', arg=unicodestring1, stack_before=[], stack_after=[pyunicode], proto=4, doc="""Push a Python Unicode string object. There are two arguments: the first is a 1-byte little-endian signed int giving the number of bytes in the string. The second is that many bytes, and is the UTF-8 encoding of the Unicode string. """), I(name='BINUNICODE', code='X', arg=unicodestring4, stack_before=[], stack_after=[pyunicode], proto=1, doc="""Push a Python Unicode string object. There are two arguments: the first is a 4-byte little-endian unsigned int giving the number of bytes in the string. The second is that many bytes, and is the UTF-8 encoding of the Unicode string. """), I(name='BINUNICODE8', code='\x8d', arg=unicodestring8, stack_before=[], stack_after=[pyunicode], proto=4, doc="""Push a Python Unicode string object. There are two arguments: the first is an 8-byte little-endian signed int giving the number of bytes in the string. The second is that many bytes, and is the UTF-8 encoding of the Unicode string. """), # Ways to spell floats. I(name='FLOAT', code='F', arg=floatnl, stack_before=[], stack_after=[pyfloat], proto=0, doc="""Newline-terminated decimal float literal. The argument is repr(a_float), and in general requires 17 significant digits for roundtrip conversion to be an identity (this is so for IEEE-754 double precision values, which is what Python float maps to on most boxes). In general, FLOAT cannot be used to transport infinities, NaNs, or minus zero across boxes (or even on a single box, if the platform C library can't read the strings it produces for such things -- Windows is like that), but may do less damage than BINFLOAT on boxes with greater precision or dynamic range than IEEE-754 double. """), I(name='BINFLOAT', code='G', arg=float8, stack_before=[], stack_after=[pyfloat], proto=1, doc="""Float stored in binary form, with 8 bytes of data. This generally requires less than half the space of FLOAT encoding. In general, BINFLOAT cannot be used to transport infinities, NaNs, or minus zero, raises an exception if the exponent exceeds the range of an IEEE-754 double, and retains no more than 53 bits of precision (if there are more than that, "add a half and chop" rounding is used to cut it back to 53 significant bits). """), # Ways to build lists. I(name='EMPTY_LIST', code=']', arg=None, stack_before=[], stack_after=[pylist], proto=1, doc="Push an empty list."), I(name='APPEND', code='a', arg=None, stack_before=[pylist, anyobject], stack_after=[pylist], proto=0, doc="""Append an object to a list. Stack before: ... pylist anyobject Stack after: ... pylist+[anyobject] although pylist is really extended in-place. """), I(name='APPENDS', code='e', arg=None, stack_before=[pylist, markobject, stackslice], stack_after=[pylist], proto=1, doc="""Extend a list by a slice of stack objects. Stack before: ... pylist markobject stackslice Stack after: ... pylist+stackslice although pylist is really extended in-place. """), I(name='LIST', code='l', arg=None, stack_before=[markobject, stackslice], stack_after=[pylist], proto=0, doc="""Build a list out of the topmost stack slice, after markobject. All the stack entries following the topmost markobject are placed into a single Python list, which single list object replaces all of the stack from the topmost markobject onward. For example, Stack before: ... markobject 1 2 3 'abc' Stack after: ... [1, 2, 3, 'abc'] """), # Ways to build tuples. I(name='EMPTY_TUPLE', code=')', arg=None, stack_before=[], stack_after=[pytuple], proto=1, doc="Push an empty tuple."), I(name='TUPLE', code='t', arg=None, stack_before=[markobject, stackslice], stack_after=[pytuple], proto=0, doc="""Build a tuple out of the topmost stack slice, after markobject. All the stack entries following the topmost markobject are placed into a single Python tuple, which single tuple object replaces all of the stack from the topmost markobject onward. For example, Stack before: ... markobject 1 2 3 'abc' Stack after: ... (1, 2, 3, 'abc') """), I(name='TUPLE1', code='\x85', arg=None, stack_before=[anyobject], stack_after=[pytuple], proto=2, doc="""Build a one-tuple out of the topmost item on the stack. This code pops one value off the stack and pushes a tuple of length 1 whose one item is that value back onto it. In other words: stack[-1] = tuple(stack[-1:]) """), I(name='TUPLE2', code='\x86', arg=None, stack_before=[anyobject, anyobject], stack_after=[pytuple], proto=2, doc="""Build a two-tuple out of the top two items on the stack. This code pops two values off the stack and pushes a tuple of length 2 whose items are those values back onto it. In other words: stack[-2:] = [tuple(stack[-2:])] """), I(name='TUPLE3', code='\x87', arg=None, stack_before=[anyobject, anyobject, anyobject], stack_after=[pytuple], proto=2, doc="""Build a three-tuple out of the top three items on the stack. This code pops three values off the stack and pushes a tuple of length 3 whose items are those values back onto it. In other words: stack[-3:] = [tuple(stack[-3:])] """), # Ways to build dicts. I(name='EMPTY_DICT', code='}', arg=None, stack_before=[], stack_after=[pydict], proto=1, doc="Push an empty dict."), I(name='DICT', code='d', arg=None, stack_before=[markobject, stackslice], stack_after=[pydict], proto=0, doc="""Build a dict out of the topmost stack slice, after markobject. All the stack entries following the topmost markobject are placed into a single Python dict, which single dict object replaces all of the stack from the topmost markobject onward. The stack slice alternates key, value, key, value, .... For example, Stack before: ... markobject 1 2 3 'abc' Stack after: ... {1: 2, 3: 'abc'} """), I(name='SETITEM', code='s', arg=None, stack_before=[pydict, anyobject, anyobject], stack_after=[pydict], proto=0, doc="""Add a key+value pair to an existing dict. Stack before: ... pydict key value Stack after: ... pydict where pydict has been modified via pydict[key] = value. """), I(name='SETITEMS', code='u', arg=None, stack_before=[pydict, markobject, stackslice], stack_after=[pydict], proto=1, doc="""Add an arbitrary number of key+value pairs to an existing dict. The slice of the stack following the topmost markobject is taken as an alternating sequence of keys and values, added to the dict immediately under the topmost markobject. Everything at and after the topmost markobject is popped, leaving the mutated dict at the top of the stack. Stack before: ... pydict markobject key_1 value_1 ... key_n value_n Stack after: ... pydict where pydict has been modified via pydict[key_i] = value_i for i in 1, 2, ..., n, and in that order. """), # Ways to build sets I(name='EMPTY_SET', code='\x8f', arg=None, stack_before=[], stack_after=[pyset], proto=4, doc="Push an empty set."), I(name='ADDITEMS', code='\x90', arg=None, stack_before=[pyset, markobject, stackslice], stack_after=[pyset], proto=4, doc="""Add an arbitrary number of items to an existing set. The slice of the stack following the topmost markobject is taken as a sequence of items, added to the set immediately under the topmost markobject. Everything at and after the topmost markobject is popped, leaving the mutated set at the top of the stack. Stack before: ... pyset markobject item_1 ... item_n Stack after: ... pyset where pyset has been modified via pyset.add(item_i) = item_i for i in 1, 2, ..., n, and in that order. """), # Way to build frozensets I(name='FROZENSET', code='\x91', arg=None, stack_before=[markobject, stackslice], stack_after=[pyfrozenset], proto=4, doc="""Build a frozenset out of the topmost slice, after markobject. All the stack entries following the topmost markobject are placed into a single Python frozenset, which single frozenset object replaces all of the stack from the topmost markobject onward. For example, Stack before: ... markobject 1 2 3 Stack after: ... frozenset({1, 2, 3}) """), # Stack manipulation. I(name='POP', code='0', arg=None, stack_before=[anyobject], stack_after=[], proto=0, doc="Discard the top stack item, shrinking the stack by one item."), I(name='DUP', code='2', arg=None, stack_before=[anyobject], stack_after=[anyobject, anyobject], proto=0, doc="Push the top stack item onto the stack again, duplicating it."), I(name='MARK', code='(', arg=None, stack_before=[], stack_after=[markobject], proto=0, doc="""Push markobject onto the stack. markobject is a unique object, used by other opcodes to identify a region of the stack containing a variable number of objects for them to work on. See markobject.doc for more detail. """), I(name='POP_MARK', code='1', arg=None, stack_before=[markobject, stackslice], stack_after=[], proto=1, doc="""Pop all the stack objects at and above the topmost markobject. When an opcode using a variable number of stack objects is done, POP_MARK is used to remove those objects, and to remove the markobject that delimited their starting position on the stack. """), # Memo manipulation. There are really only two operations (get and put), # each in all-text, "short binary", and "long binary" flavors. I(name='GET', code='g', arg=decimalnl_short, stack_before=[], stack_after=[anyobject], proto=0, doc="""Read an object from the memo and push it on the stack. The index of the memo object to push is given by the newline-terminated decimal string following. BINGET and LONG_BINGET are space-optimized versions. """), I(name='BINGET', code='h', arg=uint1, stack_before=[], stack_after=[anyobject], proto=1, doc="""Read an object from the memo and push it on the stack. The index of the memo object to push is given by the 1-byte unsigned integer following. """), I(name='LONG_BINGET', code='j', arg=uint4, stack_before=[], stack_after=[anyobject], proto=1, doc="""Read an object from the memo and push it on the stack. The index of the memo object to push is given by the 4-byte unsigned little-endian integer following. """), I(name='PUT', code='p', arg=decimalnl_short, stack_before=[], stack_after=[], proto=0, doc="""Store the stack top into the memo. The stack is not popped. The index of the memo location to write into is given by the newline- terminated decimal string following. BINPUT and LONG_BINPUT are space-optimized versions. """), I(name='BINPUT', code='q', arg=uint1, stack_before=[], stack_after=[], proto=1, doc="""Store the stack top into the memo. The stack is not popped. The index of the memo location to write into is given by the 1-byte unsigned integer following. """), I(name='LONG_BINPUT', code='r', arg=uint4, stack_before=[], stack_after=[], proto=1, doc="""Store the stack top into the memo. The stack is not popped. The index of the memo location to write into is given by the 4-byte unsigned little-endian integer following. """), I(name='MEMOIZE', code='\x94', arg=None, stack_before=[anyobject], stack_after=[anyobject], proto=4, doc="""Store the stack top into the memo. The stack is not popped. The index of the memo location to write is the number of elements currently present in the memo. """), # Access the extension registry (predefined objects). Akin to the GET # family. I(name='EXT1', code='\x82', arg=uint1, stack_before=[], stack_after=[anyobject], proto=2, doc="""Extension code. This code and the similar EXT2 and EXT4 allow using a registry of popular objects that are pickled by name, typically classes. It is envisioned that through a global negotiation and registration process, third parties can set up a mapping between ints and object names. In order to guarantee pickle interchangeability, the extension code registry ought to be global, although a range of codes may be reserved for private use. EXT1 has a 1-byte integer argument. This is used to index into the extension registry, and the object at that index is pushed on the stack. """), I(name='EXT2', code='\x83', arg=uint2, stack_before=[], stack_after=[anyobject], proto=2, doc="""Extension code. See EXT1. EXT2 has a two-byte integer argument. """), I(name='EXT4', code='\x84', arg=int4, stack_before=[], stack_after=[anyobject], proto=2, doc="""Extension code. See EXT1. EXT4 has a four-byte integer argument. """), # Push a class object, or module function, on the stack, via its module # and name. I(name='GLOBAL', code='c', arg=stringnl_noescape_pair, stack_before=[], stack_after=[anyobject], proto=0, doc="""Push a global object (module.attr) on the stack. Two newline-terminated strings follow the GLOBAL opcode. The first is taken as a module name, and the second as a class name. The class object module.class is pushed on the stack. More accurately, the object returned by self.find_class(module, class) is pushed on the stack, so unpickling subclasses can override this form of lookup. """), I(name='STACK_GLOBAL', code='\x93', arg=None, stack_before=[pyunicode, pyunicode], stack_after=[anyobject], proto=4, doc="""Push a global object (module.attr) on the stack. """), # Ways to build objects of classes pickle doesn't know about directly # (user-defined classes). I despair of documenting this accurately # and comprehensibly -- you really have to read the pickle code to # find all the special cases. I(name='REDUCE', code='R', arg=None, stack_before=[anyobject, anyobject], stack_after=[anyobject], proto=0, doc="""Push an object built from a callable and an argument tuple. The opcode is named to remind of the __reduce__() method. Stack before: ... callable pytuple Stack after: ... callable(*pytuple) The callable and the argument tuple are the first two items returned by a __reduce__ method. Applying the callable to the argtuple is supposed to reproduce the original object, or at least get it started. If the __reduce__ method returns a 3-tuple, the last component is an argument to be passed to the object's __setstate__, and then the REDUCE opcode is followed by code to create setstate's argument, and then a BUILD opcode to apply __setstate__ to that argument. If not isinstance(callable, type), REDUCE complains unless the callable has been registered with the copyreg module's safe_constructors dict, or the callable has a magic '__safe_for_unpickling__' attribute with a true value. I'm not sure why it does this, but I've sure seen this complaint often enough when I didn't want to . """), I(name='BUILD', code='b', arg=None, stack_before=[anyobject, anyobject], stack_after=[anyobject], proto=0, doc="""Finish building an object, via __setstate__ or dict update. Stack before: ... anyobject argument Stack after: ... anyobject where anyobject may have been mutated, as follows: If the object has a __setstate__ method, anyobject.__setstate__(argument) is called. Else the argument must be a dict, the object must have a __dict__, and the object is updated via anyobject.__dict__.update(argument) """), I(name='INST', code='i', arg=stringnl_noescape_pair, stack_before=[markobject, stackslice], stack_after=[anyobject], proto=0, doc="""Build a class instance. This is the protocol 0 version of protocol 1's OBJ opcode. INST is followed by two newline-terminated strings, giving a module and class name, just as for the GLOBAL opcode (and see GLOBAL for more details about that). self.find_class(module, name) is used to get a class object. In addition, all the objects on the stack following the topmost markobject are gathered into a tuple and popped (along with the topmost markobject), just as for the TUPLE opcode. Now it gets complicated. If all of these are true: + The argtuple is empty (markobject was at the top of the stack at the start). + The class object does not have a __getinitargs__ attribute. then we want to create an old-style class instance without invoking its __init__() method (pickle has waffled on this over the years; not calling __init__() is current wisdom). In this case, an instance of an old-style dummy class is created, and then we try to rebind its __class__ attribute to the desired class object. If this succeeds, the new instance object is pushed on the stack, and we're done. Else (the argtuple is not empty, it's not an old-style class object, or the class object does have a __getinitargs__ attribute), the code first insists that the class object have a __safe_for_unpickling__ attribute. Unlike as for the __safe_for_unpickling__ check in REDUCE, it doesn't matter whether this attribute has a true or false value, it only matters whether it exists (XXX this is a bug). If __safe_for_unpickling__ doesn't exist, UnpicklingError is raised. Else (the class object does have a __safe_for_unpickling__ attr), the class object obtained from INST's arguments is applied to the argtuple obtained from the stack, and the resulting instance object is pushed on the stack. NOTE: checks for __safe_for_unpickling__ went away in Python 2.3. NOTE: the distinction between old-style and new-style classes does not make sense in Python 3. """), I(name='OBJ', code='o', arg=None, stack_before=[markobject, anyobject, stackslice], stack_after=[anyobject], proto=1, doc="""Build a class instance. This is the protocol 1 version of protocol 0's INST opcode, and is very much like it. The major difference is that the class object is taken off the stack, allowing it to be retrieved from the memo repeatedly if several instances of the same class are created. This can be much more efficient (in both time and space) than repeatedly embedding the module and class names in INST opcodes. Unlike INST, OBJ takes no arguments from the opcode stream. Instead the class object is taken off the stack, immediately above the topmost markobject: Stack before: ... markobject classobject stackslice Stack after: ... new_instance_object As for INST, the remainder of the stack above the markobject is gathered into an argument tuple, and then the logic seems identical, except that no __safe_for_unpickling__ check is done (XXX this is a bug). See INST for the gory details. NOTE: In Python 2.3, INST and OBJ are identical except for how they get the class object. That was always the intent; the implementations had diverged for accidental reasons. """), I(name='NEWOBJ', code='\x81', arg=None, stack_before=[anyobject, anyobject], stack_after=[anyobject], proto=2, doc="""Build an object instance. The stack before should be thought of as containing a class object followed by an argument tuple (the tuple being the stack top). Call these cls and args. They are popped off the stack, and the value returned by cls.__new__(cls, *args) is pushed back onto the stack. """), I(name='NEWOBJ_EX', code='\x92', arg=None, stack_before=[anyobject, anyobject, anyobject], stack_after=[anyobject], proto=4, doc="""Build an object instance. The stack before should be thought of as containing a class object followed by an argument tuple and by a keyword argument dict (the dict being the stack top). Call these cls and args. They are popped off the stack, and the value returned by cls.__new__(cls, *args, *kwargs) is pushed back onto the stack. """), # Machine control. I(name='PROTO', code='\x80', arg=uint1, stack_before=[], stack_after=[], proto=2, doc="""Protocol version indicator. For protocol 2 and above, a pickle must start with this opcode. The argument is the protocol version, an int in range(2, 256). """), I(name='STOP', code='.', arg=None, stack_before=[anyobject], stack_after=[], proto=0, doc="""Stop the unpickling machine. Every pickle ends with this opcode. The object at the top of the stack is popped, and that's the result of unpickling. The stack should be empty then. """), # Framing support. I(name='FRAME', code='\x95', arg=uint8, stack_before=[], stack_after=[], proto=4, doc="""Indicate the beginning of a new frame. The unpickler may use this opcode to safely prefetch data from its underlying stream. """), # Ways to deal with persistent IDs. I(name='PERSID', code='P', arg=stringnl_noescape, stack_before=[], stack_after=[anyobject], proto=0, doc="""Push an object identified by a persistent ID. The pickle module doesn't define what a persistent ID means. PERSID's argument is a newline-terminated str-style (no embedded escapes, no bracketing quote characters) string, which *is* "the persistent ID". The unpickler passes this string to self.persistent_load(). Whatever object that returns is pushed on the stack. There is no implementation of persistent_load() in Python's unpickler: it must be supplied by an unpickler subclass. """), I(name='BINPERSID', code='Q', arg=None, stack_before=[anyobject], stack_after=[anyobject], proto=1, doc="""Push an object identified by a persistent ID. Like PERSID, except the persistent ID is popped off the stack (instead of being a string embedded in the opcode bytestream). The persistent ID is passed to self.persistent_load(), and whatever object that returns is pushed on the stack. See PERSID for more detail. """), ] del I # Verify uniqueness of .name and .code members. name2i = {} code2i = {} for i, d in enumerate(opcodes): if d.name in name2i: raise ValueError("repeated name %r at indices %d and %d" % (d.name, name2i[d.name], i)) if d.code in code2i: raise ValueError("repeated code %r at indices %d and %d" % (d.code, code2i[d.code], i)) name2i[d.name] = i code2i[d.code] = i del name2i, code2i, i, d ############################################################################## # Build a code2op dict, mapping opcode characters to OpcodeInfo records. # Also ensure we've got the same stuff as pickle.py, although the # introspection here is dicey. code2op = {} for d in opcodes: code2op[d.code] = d del d def assure_pickle_consistency(verbose=False): copy = code2op.copy() for name in pickle.__all__: if not re.match("[A-Z][A-Z0-9_]+$", name): if verbose: print("skipping %r: it doesn't look like an opcode name" % name) continue picklecode = getattr(pickle, name) if not isinstance(picklecode, bytes) or len(picklecode) != 1: if verbose: print(("skipping %r: value %r doesn't look like a pickle " "code" % (name, picklecode))) continue picklecode = picklecode.decode("latin-1") if picklecode in copy: if verbose: print("checking name %r w/ code %r for consistency" % ( name, picklecode)) d = copy[picklecode] if d.name != name: raise ValueError("for pickle code %r, pickle.py uses name %r " "but we're using name %r" % (picklecode, name, d.name)) # Forget this one. Any left over in copy at the end are a problem # of a different kind. del copy[picklecode] else: raise ValueError("pickle.py appears to have a pickle opcode with " "name %r and code %r, but we don't" % (name, picklecode)) if copy: msg = ["we appear to have pickle opcodes that pickle.py doesn't have:"] for code, d in copy.items(): msg.append(" name %r with code %r" % (d.name, code)) raise ValueError("\n".join(msg)) assure_pickle_consistency() del assure_pickle_consistency ############################################################################## # A pickle opcode generator. def _genops(data, yield_end_pos=False): if isinstance(data, bytes_types): data = io.BytesIO(data) if hasattr(data, "tell"): getpos = data.tell else: getpos = lambda: None while True: pos = getpos() code = data.read(1) opcode = code2op.get(code.decode("latin-1")) if opcode is None: if code == b"": raise ValueError("pickle exhausted before seeing STOP") else: raise ValueError("at position %s, opcode %r unknown" % ( "" if pos is None else pos, code)) if opcode.arg is None: arg = None else: arg = opcode.arg.reader(data) if yield_end_pos: yield opcode, arg, pos, getpos() else: yield opcode, arg, pos if code == b'.': assert opcode.name == 'STOP' break def genops(pickle): """Generate all the opcodes in a pickle. 'pickle' is a file-like object, or string, containing the pickle. Each opcode in the pickle is generated, from the current pickle position, stopping after a STOP opcode is delivered. A triple is generated for each opcode: opcode, arg, pos opcode is an OpcodeInfo record, describing the current opcode. If the opcode has an argument embedded in the pickle, arg is its decoded value, as a Python object. If the opcode doesn't have an argument, arg is None. If the pickle has a tell() method, pos was the value of pickle.tell() before reading the current opcode. If the pickle is a bytes object, it's wrapped in a BytesIO object, and the latter's tell() result is used. Else (the pickle doesn't have a tell(), and it's not obvious how to query its current position) pos is None. """ return _genops(pickle) ############################################################################## # A pickle optimizer. def optimize(p): 'Optimize a pickle string by removing unused PUT opcodes' put = 'PUT' get = 'GET' oldids = set() # set of all PUT ids newids = {} # set of ids used by a GET opcode opcodes = [] # (op, idx) or (pos, end_pos) proto = 0 protoheader = b'' for opcode, arg, pos, end_pos in _genops(p, yield_end_pos=True): if 'PUT' in opcode.name: oldids.add(arg) opcodes.append((put, arg)) elif opcode.name == 'MEMOIZE': idx = len(oldids) oldids.add(idx) opcodes.append((put, idx)) elif 'FRAME' in opcode.name: pass elif 'GET' in opcode.name: if opcode.proto > proto: proto = opcode.proto newids[arg] = None opcodes.append((get, arg)) elif opcode.name == 'PROTO': if arg > proto: proto = arg if pos == 0: protoheader = p[pos:end_pos] else: opcodes.append((pos, end_pos)) else: opcodes.append((pos, end_pos)) del oldids # Copy the opcodes except for PUTS without a corresponding GET out = io.BytesIO() # Write the PROTO header before any framing out.write(protoheader) pickler = pickle._Pickler(out, proto) if proto >= 4: pickler.framer.start_framing() idx = 0 for op, arg in opcodes: frameless = False if op is put: if arg not in newids: continue data = pickler.put(idx) newids[arg] = idx idx += 1 elif op is get: data = pickler.get(newids[arg]) else: data = p[op:arg] frameless = len(data) > pickler.framer._FRAME_SIZE_TARGET pickler.framer.commit_frame(force=frameless) if frameless: pickler.framer.file_write(data) else: pickler.write(data) pickler.framer.end_framing() return out.getvalue() ############################################################################## # A symbolic pickle disassembler. def dis(pickle, out=None, memo=None, indentlevel=4, annotate=0): """Produce a symbolic disassembly of a pickle. 'pickle' is a file-like object, or string, containing a (at least one) pickle. The pickle is disassembled from the current position, through the first STOP opcode encountered. Optional arg 'out' is a file-like object to which the disassembly is printed. It defaults to sys.stdout. Optional arg 'memo' is a Python dict, used as the pickle's memo. It may be mutated by dis(), if the pickle contains PUT or BINPUT opcodes. Passing the same memo object to another dis() call then allows disassembly to proceed across multiple pickles that were all created by the same pickler with the same memo. Ordinarily you don't need to worry about this. Optional arg 'indentlevel' is the number of blanks by which to indent a new MARK level. It defaults to 4. Optional arg 'annotate' if nonzero instructs dis() to add short description of the opcode on each line of disassembled output. The value given to 'annotate' must be an integer and is used as a hint for the column where annotation should start. The default value is 0, meaning no annotations. In addition to printing the disassembly, some sanity checks are made: + All embedded opcode arguments "make sense". + Explicit and implicit pop operations have enough items on the stack. + When an opcode implicitly refers to a markobject, a markobject is actually on the stack. + A memo entry isn't referenced before it's defined. + The markobject isn't stored in the memo. + A memo entry isn't redefined. """ # Most of the hair here is for sanity checks, but most of it is needed # anyway to detect when a protocol 0 POP takes a MARK off the stack # (which in turn is needed to indent MARK blocks correctly). stack = [] # crude emulation of unpickler stack if memo is None: memo = {} # crude emulation of unpickler memo maxproto = -1 # max protocol number seen markstack = [] # bytecode positions of MARK opcodes indentchunk = ' ' * indentlevel errormsg = None annocol = annotate # column hint for annotations for opcode, arg, pos in genops(pickle): if pos is not None: print("%5d:" % pos, end=' ', file=out) line = "%-4s %s%s" % (repr(opcode.code)[1:-1], indentchunk * len(markstack), opcode.name) maxproto = max(maxproto, opcode.proto) before = opcode.stack_before # don't mutate after = opcode.stack_after # don't mutate numtopop = len(before) # See whether a MARK should be popped. markmsg = None if markobject in before or (opcode.name == "POP" and stack and stack[-1] is markobject): assert markobject not in after if __debug__: if markobject in before: assert before[-1] is stackslice if markstack: markpos = markstack.pop() if markpos is None: markmsg = "(MARK at unknown opcode offset)" else: markmsg = "(MARK at %d)" % markpos # Pop everything at and after the topmost markobject. while stack[-1] is not markobject: stack.pop() stack.pop() # Stop later code from popping too much. try: numtopop = before.index(markobject) except ValueError: assert opcode.name == "POP" numtopop = 0 else: errormsg = markmsg = "no MARK exists on stack" # Check for correct memo usage. if opcode.name in ("PUT", "BINPUT", "LONG_BINPUT", "MEMOIZE"): if opcode.name == "MEMOIZE": memo_idx = len(memo) markmsg = "(as %d)" % memo_idx else: assert arg is not None memo_idx = arg if memo_idx in memo: errormsg = "memo key %r already defined" % arg elif not stack: errormsg = "stack is empty -- can't store into memo" elif stack[-1] is markobject: errormsg = "can't store markobject in the memo" else: memo[memo_idx] = stack[-1] elif opcode.name in ("GET", "BINGET", "LONG_BINGET"): if arg in memo: assert len(after) == 1 after = [memo[arg]] # for better stack emulation else: errormsg = "memo key %r has never been stored into" % arg if arg is not None or markmsg: # make a mild effort to align arguments line += ' ' * (10 - len(opcode.name)) if arg is not None: if opcode.name in ("STRING", "BINSTRING", "SHORT_BINSTRING"): line += ' ' + ascii(arg) else: line += ' ' + repr(arg) if markmsg: line += ' ' + markmsg if annotate: line += ' ' * (annocol - len(line)) # make a mild effort to align annotations annocol = len(line) if annocol > 50: annocol = annotate line += ' ' + opcode.doc.split('\n', 1)[0] print(line, file=out) if errormsg: # Note that we delayed complaining until the offending opcode # was printed. raise ValueError(errormsg) # Emulate the stack effects. if len(stack) < numtopop: raise ValueError("tries to pop %d items from stack with " "only %d items" % (numtopop, len(stack))) if numtopop: del stack[-numtopop:] if markobject in after: assert markobject not in before markstack.append(pos) stack.extend(after) print("highest protocol among opcodes =", maxproto, file=out) if stack: raise ValueError("stack not empty after STOP: %r" % stack) # For use in the doctest, simply as an example of a class to pickle. class _Example: def __init__(self, value): self.value = value _dis_test = r""" >>> import pickle >>> x = [1, 2, (3, 4), {b'abc': "def"}] >>> pkl0 = pickle.dumps(x, 0) >>> dis(pkl0) 0: ( MARK 1: l LIST (MARK at 0) 2: p PUT 0 5: I INT 1 8: a APPEND 9: I INT 2 12: a APPEND 13: ( MARK 14: I INT 3 17: I INT 4 20: t TUPLE (MARK at 13) 21: p PUT 1 24: a APPEND 25: ( MARK 26: d DICT (MARK at 25) 27: p PUT 2 30: c GLOBAL '_codecs encode' 46: p PUT 3 49: ( MARK 50: V UNICODE 'abc' 55: p PUT 4 58: V UNICODE 'latin1' 66: p PUT 5 69: t TUPLE (MARK at 49) 70: p PUT 6 73: R REDUCE 74: p PUT 7 77: V UNICODE 'def' 82: p PUT 8 85: s SETITEM 86: a APPEND 87: . STOP highest protocol among opcodes = 0 Try again with a "binary" pickle. >>> pkl1 = pickle.dumps(x, 1) >>> dis(pkl1) 0: ] EMPTY_LIST 1: q BINPUT 0 3: ( MARK 4: K BININT1 1 6: K BININT1 2 8: ( MARK 9: K BININT1 3 11: K BININT1 4 13: t TUPLE (MARK at 8) 14: q BINPUT 1 16: } EMPTY_DICT 17: q BINPUT 2 19: c GLOBAL '_codecs encode' 35: q BINPUT 3 37: ( MARK 38: X BINUNICODE 'abc' 46: q BINPUT 4 48: X BINUNICODE 'latin1' 59: q BINPUT 5 61: t TUPLE (MARK at 37) 62: q BINPUT 6 64: R REDUCE 65: q BINPUT 7 67: X BINUNICODE 'def' 75: q BINPUT 8 77: s SETITEM 78: e APPENDS (MARK at 3) 79: . STOP highest protocol among opcodes = 1 Exercise the INST/OBJ/BUILD family. >>> import pickletools >>> dis(pickle.dumps(pickletools.dis, 0)) 0: c GLOBAL 'pickletools dis' 17: p PUT 0 20: . STOP highest protocol among opcodes = 0 >>> from pickletools import _Example >>> x = [_Example(42)] * 2 >>> dis(pickle.dumps(x, 0)) 0: ( MARK 1: l LIST (MARK at 0) 2: p PUT 0 5: c GLOBAL 'copy_reg _reconstructor' 30: p PUT 1 33: ( MARK 34: c GLOBAL 'pickletools _Example' 56: p PUT 2 59: c GLOBAL '__builtin__ object' 79: p PUT 3 82: N NONE 83: t TUPLE (MARK at 33) 84: p PUT 4 87: R REDUCE 88: p PUT 5 91: ( MARK 92: d DICT (MARK at 91) 93: p PUT 6 96: V UNICODE 'value' 103: p PUT 7 106: I INT 42 110: s SETITEM 111: b BUILD 112: a APPEND 113: g GET 5 116: a APPEND 117: . STOP highest protocol among opcodes = 0 >>> dis(pickle.dumps(x, 1)) 0: ] EMPTY_LIST 1: q BINPUT 0 3: ( MARK 4: c GLOBAL 'copy_reg _reconstructor' 29: q BINPUT 1 31: ( MARK 32: c GLOBAL 'pickletools _Example' 54: q BINPUT 2 56: c GLOBAL '__builtin__ object' 76: q BINPUT 3 78: N NONE 79: t TUPLE (MARK at 31) 80: q BINPUT 4 82: R REDUCE 83: q BINPUT 5 85: } EMPTY_DICT 86: q BINPUT 6 88: X BINUNICODE 'value' 98: q BINPUT 7 100: K BININT1 42 102: s SETITEM 103: b BUILD 104: h BINGET 5 106: e APPENDS (MARK at 3) 107: . STOP highest protocol among opcodes = 1 Try "the canonical" recursive-object test. >>> L = [] >>> T = L, >>> L.append(T) >>> L[0] is T True >>> T[0] is L True >>> L[0][0] is L True >>> T[0][0] is T True >>> dis(pickle.dumps(L, 0)) 0: ( MARK 1: l LIST (MARK at 0) 2: p PUT 0 5: ( MARK 6: g GET 0 9: t TUPLE (MARK at 5) 10: p PUT 1 13: a APPEND 14: . STOP highest protocol among opcodes = 0 >>> dis(pickle.dumps(L, 1)) 0: ] EMPTY_LIST 1: q BINPUT 0 3: ( MARK 4: h BINGET 0 6: t TUPLE (MARK at 3) 7: q BINPUT 1 9: a APPEND 10: . STOP highest protocol among opcodes = 1 Note that, in the protocol 0 pickle of the recursive tuple, the disassembler has to emulate the stack in order to realize that the POP opcode at 16 gets rid of the MARK at 0. >>> dis(pickle.dumps(T, 0)) 0: ( MARK 1: ( MARK 2: l LIST (MARK at 1) 3: p PUT 0 6: ( MARK 7: g GET 0 10: t TUPLE (MARK at 6) 11: p PUT 1 14: a APPEND 15: 0 POP 16: 0 POP (MARK at 0) 17: g GET 1 20: . STOP highest protocol among opcodes = 0 >>> dis(pickle.dumps(T, 1)) 0: ( MARK 1: ] EMPTY_LIST 2: q BINPUT 0 4: ( MARK 5: h BINGET 0 7: t TUPLE (MARK at 4) 8: q BINPUT 1 10: a APPEND 11: 1 POP_MARK (MARK at 0) 12: h BINGET 1 14: . STOP highest protocol among opcodes = 1 Try protocol 2. >>> dis(pickle.dumps(L, 2)) 0: \x80 PROTO 2 2: ] EMPTY_LIST 3: q BINPUT 0 5: h BINGET 0 7: \x85 TUPLE1 8: q BINPUT 1 10: a APPEND 11: . STOP highest protocol among opcodes = 2 >>> dis(pickle.dumps(T, 2)) 0: \x80 PROTO 2 2: ] EMPTY_LIST 3: q BINPUT 0 5: h BINGET 0 7: \x85 TUPLE1 8: q BINPUT 1 10: a APPEND 11: 0 POP 12: h BINGET 1 14: . STOP highest protocol among opcodes = 2 Try protocol 3 with annotations: >>> dis(pickle.dumps(T, 3), annotate=1) 0: \x80 PROTO 3 Protocol version indicator. 2: ] EMPTY_LIST Push an empty list. 3: q BINPUT 0 Store the stack top into the memo. The stack is not popped. 5: h BINGET 0 Read an object from the memo and push it on the stack. 7: \x85 TUPLE1 Build a one-tuple out of the topmost item on the stack. 8: q BINPUT 1 Store the stack top into the memo. The stack is not popped. 10: a APPEND Append an object to a list. 11: 0 POP Discard the top stack item, shrinking the stack by one item. 12: h BINGET 1 Read an object from the memo and push it on the stack. 14: . STOP Stop the unpickling machine. highest protocol among opcodes = 2 """ _memo_test = r""" >>> import pickle >>> import io >>> f = io.BytesIO() >>> p = pickle.Pickler(f, 2) >>> x = [1, 2, 3] >>> p.dump(x) >>> p.dump(x) >>> f.seek(0) 0 >>> memo = {} >>> dis(f, memo=memo) 0: \x80 PROTO 2 2: ] EMPTY_LIST 3: q BINPUT 0 5: ( MARK 6: K BININT1 1 8: K BININT1 2 10: K BININT1 3 12: e APPENDS (MARK at 5) 13: . STOP highest protocol among opcodes = 2 >>> dis(f, memo=memo) 14: \x80 PROTO 2 16: h BINGET 0 18: . STOP highest protocol among opcodes = 2 """ __test__ = {'disassembler_test': _dis_test, 'disassembler_memo_test': _memo_test, } def _test(): import doctest return doctest.testmod() if __name__ == "__main__": import argparse parser = argparse.ArgumentParser( description='disassemble one or more pickle files') parser.add_argument( 'pickle_file', nargs='*', help='the pickle file') parser.add_argument( '-o', '--output', help='the file where the output should be written') parser.add_argument( '-m', '--memo', action='store_true', help='preserve memo between disassemblies') parser.add_argument( '-l', '--indentlevel', default=4, type=int, help='the number of blanks by which to indent a new MARK level') parser.add_argument( '-a', '--annotate', action='store_true', help='annotate each line with a short opcode description') parser.add_argument( '-p', '--preamble', default="==> {name} <==", help='if more than one pickle file is specified, print this before' ' each disassembly') parser.add_argument( '-t', '--test', action='store_true', help='run self-test suite') parser.add_argument( '-v', action='store_true', help='run verbosely; only affects self-test run') args = parser.parse_args() if args.test: _test() else: if not args.pickle_file: parser.print_help() else: annotate = 30 if args.annotate else 0 memo = {} if args.memo else None if args.output is None: output = sys.stdout else: output = open(args.output, 'w') try: for arg in args.pickle_file: if len(args.pickle_file) > 1: name = '' if arg == '-' else arg preamble = args.preamble.format(name=name) output.write(preamble + '\n') if arg == '-': dis(sys.stdin.buffer, output, memo, args.indentlevel, annotate) else: with open(arg, 'rb') as f: dis(f, output, memo, args.indentlevel, annotate) finally: if output is not sys.stdout: output.close() modulefinder.py000064400000056223152342670510007610 0ustar00"""Find modules used by a script, using introspection.""" import dis import importlib._bootstrap_external import importlib.machinery import marshal import os import io import sys # Old imp constants: _SEARCH_ERROR = 0 _PY_SOURCE = 1 _PY_COMPILED = 2 _C_EXTENSION = 3 _PKG_DIRECTORY = 5 _C_BUILTIN = 6 _PY_FROZEN = 7 # Modulefinder does a good job at simulating Python's, but it can not # handle __path__ modifications packages make at runtime. Therefore there # is a mechanism whereby you can register extra paths in this map for a # package, and it will be honored. # Note this is a mapping is lists of paths. packagePathMap = {} # A Public interface def AddPackagePath(packagename, path): packagePathMap.setdefault(packagename, []).append(path) replacePackageMap = {} # This ReplacePackage mechanism allows modulefinder to work around # situations in which a package injects itself under the name # of another package into sys.modules at runtime by calling # ReplacePackage("real_package_name", "faked_package_name") # before running ModuleFinder. def ReplacePackage(oldname, newname): replacePackageMap[oldname] = newname def _find_module(name, path=None): """An importlib reimplementation of imp.find_module (for our purposes).""" # It's necessary to clear the caches for our Finder first, in case any # modules are being added/deleted/modified at runtime. In particular, # test_modulefinder.py changes file tree contents in a cache-breaking way: importlib.machinery.PathFinder.invalidate_caches() spec = importlib.machinery.PathFinder.find_spec(name, path) if spec is None: raise ImportError("No module named {name!r}".format(name=name), name=name) # Some special cases: if spec.loader is importlib.machinery.BuiltinImporter: return None, None, ("", "", _C_BUILTIN) if spec.loader is importlib.machinery.FrozenImporter: return None, None, ("", "", _PY_FROZEN) file_path = spec.origin if spec.loader.is_package(name): return None, os.path.dirname(file_path), ("", "", _PKG_DIRECTORY) if isinstance(spec.loader, importlib.machinery.SourceFileLoader): kind = _PY_SOURCE elif isinstance(spec.loader, importlib.machinery.ExtensionFileLoader): kind = _C_EXTENSION elif isinstance(spec.loader, importlib.machinery.SourcelessFileLoader): kind = _PY_COMPILED else: # Should never happen. return None, None, ("", "", _SEARCH_ERROR) file = io.open_code(file_path) suffix = os.path.splitext(file_path)[-1] return file, file_path, (suffix, "rb", kind) class Module: def __init__(self, name, file=None, path=None): self.__name__ = name self.__file__ = file self.__path__ = path self.__code__ = None # The set of global names that are assigned to in the module. # This includes those names imported through starimports of # Python modules. self.globalnames = {} # The set of starimports this module did that could not be # resolved, ie. a starimport from a non-Python module. self.starimports = {} def __repr__(self): s = "Module(%r" % (self.__name__,) if self.__file__ is not None: s = s + ", %r" % (self.__file__,) if self.__path__ is not None: s = s + ", %r" % (self.__path__,) s = s + ")" return s class ModuleFinder: def __init__(self, path=None, debug=0, excludes=None, replace_paths=None): if path is None: path = sys.path self.path = path self.modules = {} self.badmodules = {} self.debug = debug self.indent = 0 self.excludes = excludes if excludes is not None else [] self.replace_paths = replace_paths if replace_paths is not None else [] self.processed_paths = [] # Used in debugging only def msg(self, level, str, *args): if level <= self.debug: for i in range(self.indent): print(" ", end=' ') print(str, end=' ') for arg in args: print(repr(arg), end=' ') print() def msgin(self, *args): level = args[0] if level <= self.debug: self.indent = self.indent + 1 self.msg(*args) def msgout(self, *args): level = args[0] if level <= self.debug: self.indent = self.indent - 1 self.msg(*args) def run_script(self, pathname): self.msg(2, "run_script", pathname) with io.open_code(pathname) as fp: stuff = ("", "rb", _PY_SOURCE) self.load_module('__main__', fp, pathname, stuff) def load_file(self, pathname): dir, name = os.path.split(pathname) name, ext = os.path.splitext(name) with io.open_code(pathname) as fp: stuff = (ext, "rb", _PY_SOURCE) self.load_module(name, fp, pathname, stuff) def import_hook(self, name, caller=None, fromlist=None, level=-1): self.msg(3, "import_hook", name, caller, fromlist, level) parent = self.determine_parent(caller, level=level) q, tail = self.find_head_package(parent, name) m = self.load_tail(q, tail) if not fromlist: return q if m.__path__: self.ensure_fromlist(m, fromlist) return None def determine_parent(self, caller, level=-1): self.msgin(4, "determine_parent", caller, level) if not caller or level == 0: self.msgout(4, "determine_parent -> None") return None pname = caller.__name__ if level >= 1: # relative import if caller.__path__: level -= 1 if level == 0: parent = self.modules[pname] assert parent is caller self.msgout(4, "determine_parent ->", parent) return parent if pname.count(".") < level: raise ImportError("relative importpath too deep") pname = ".".join(pname.split(".")[:-level]) parent = self.modules[pname] self.msgout(4, "determine_parent ->", parent) return parent if caller.__path__: parent = self.modules[pname] assert caller is parent self.msgout(4, "determine_parent ->", parent) return parent if '.' in pname: i = pname.rfind('.') pname = pname[:i] parent = self.modules[pname] assert parent.__name__ == pname self.msgout(4, "determine_parent ->", parent) return parent self.msgout(4, "determine_parent -> None") return None def find_head_package(self, parent, name): self.msgin(4, "find_head_package", parent, name) if '.' in name: i = name.find('.') head = name[:i] tail = name[i+1:] else: head = name tail = "" if parent: qname = "%s.%s" % (parent.__name__, head) else: qname = head q = self.import_module(head, qname, parent) if q: self.msgout(4, "find_head_package ->", (q, tail)) return q, tail if parent: qname = head parent = None q = self.import_module(head, qname, parent) if q: self.msgout(4, "find_head_package ->", (q, tail)) return q, tail self.msgout(4, "raise ImportError: No module named", qname) raise ImportError("No module named " + qname) def load_tail(self, q, tail): self.msgin(4, "load_tail", q, tail) m = q while tail: i = tail.find('.') if i < 0: i = len(tail) head, tail = tail[:i], tail[i+1:] mname = "%s.%s" % (m.__name__, head) m = self.import_module(head, mname, m) if not m: self.msgout(4, "raise ImportError: No module named", mname) raise ImportError("No module named " + mname) self.msgout(4, "load_tail ->", m) return m def ensure_fromlist(self, m, fromlist, recursive=0): self.msg(4, "ensure_fromlist", m, fromlist, recursive) for sub in fromlist: if sub == "*": if not recursive: all = self.find_all_submodules(m) if all: self.ensure_fromlist(m, all, 1) elif not hasattr(m, sub): subname = "%s.%s" % (m.__name__, sub) submod = self.import_module(sub, subname, m) if not submod: raise ImportError("No module named " + subname) def find_all_submodules(self, m): if not m.__path__: return modules = {} # 'suffixes' used to be a list hardcoded to [".py", ".pyc"]. # But we must also collect Python extension modules - although # we cannot separate normal dlls from Python extensions. suffixes = [] suffixes += importlib.machinery.EXTENSION_SUFFIXES[:] suffixes += importlib.machinery.SOURCE_SUFFIXES[:] suffixes += importlib.machinery.BYTECODE_SUFFIXES[:] for dir in m.__path__: try: names = os.listdir(dir) except OSError: self.msg(2, "can't list directory", dir) continue for name in names: mod = None for suff in suffixes: n = len(suff) if name[-n:] == suff: mod = name[:-n] break if mod and mod != "__init__": modules[mod] = mod return modules.keys() def import_module(self, partname, fqname, parent): self.msgin(3, "import_module", partname, fqname, parent) try: m = self.modules[fqname] except KeyError: pass else: self.msgout(3, "import_module ->", m) return m if fqname in self.badmodules: self.msgout(3, "import_module -> None") return None if parent and parent.__path__ is None: self.msgout(3, "import_module -> None") return None try: fp, pathname, stuff = self.find_module(partname, parent and parent.__path__, parent) except ImportError: self.msgout(3, "import_module ->", None) return None try: m = self.load_module(fqname, fp, pathname, stuff) finally: if fp: fp.close() if parent: setattr(parent, partname, m) self.msgout(3, "import_module ->", m) return m def load_module(self, fqname, fp, pathname, file_info): suffix, mode, type = file_info self.msgin(2, "load_module", fqname, fp and "fp", pathname) if type == _PKG_DIRECTORY: m = self.load_package(fqname, pathname) self.msgout(2, "load_module ->", m) return m if type == _PY_SOURCE: co = compile(fp.read(), pathname, 'exec') elif type == _PY_COMPILED: try: data = fp.read() importlib._bootstrap_external._classify_pyc(data, fqname, {}) except ImportError as exc: self.msgout(2, "raise ImportError: " + str(exc), pathname) raise co = marshal.loads(memoryview(data)[16:]) else: co = None m = self.add_module(fqname) m.__file__ = pathname if co: if self.replace_paths: co = self.replace_paths_in_code(co) m.__code__ = co self.scan_code(co, m) self.msgout(2, "load_module ->", m) return m def _add_badmodule(self, name, caller): if name not in self.badmodules: self.badmodules[name] = {} if caller: self.badmodules[name][caller.__name__] = 1 else: self.badmodules[name]["-"] = 1 def _safe_import_hook(self, name, caller, fromlist, level=-1): # wrapper for self.import_hook() that won't raise ImportError if name in self.badmodules: self._add_badmodule(name, caller) return try: self.import_hook(name, caller, level=level) except ImportError as msg: self.msg(2, "ImportError:", str(msg)) self._add_badmodule(name, caller) except SyntaxError as msg: self.msg(2, "SyntaxError:", str(msg)) self._add_badmodule(name, caller) else: if fromlist: for sub in fromlist: fullname = name + "." + sub if fullname in self.badmodules: self._add_badmodule(fullname, caller) continue try: self.import_hook(name, caller, [sub], level=level) except ImportError as msg: self.msg(2, "ImportError:", str(msg)) self._add_badmodule(fullname, caller) def scan_opcodes(self, co): # Scan the code, and yield 'interesting' opcode combinations for name in dis._find_store_names(co): yield "store", (name,) for name, level, fromlist in dis._find_imports(co): if level == 0: # absolute import yield "absolute_import", (fromlist, name) else: # relative import yield "relative_import", (level, fromlist, name) def scan_code(self, co, m): code = co.co_code scanner = self.scan_opcodes for what, args in scanner(co): if what == "store": name, = args m.globalnames[name] = 1 elif what == "absolute_import": fromlist, name = args have_star = 0 if fromlist is not None: if "*" in fromlist: have_star = 1 fromlist = [f for f in fromlist if f != "*"] self._safe_import_hook(name, m, fromlist, level=0) if have_star: # We've encountered an "import *". If it is a Python module, # the code has already been parsed and we can suck out the # global names. mm = None if m.__path__: # At this point we don't know whether 'name' is a # submodule of 'm' or a global module. Let's just try # the full name first. mm = self.modules.get(m.__name__ + "." + name) if mm is None: mm = self.modules.get(name) if mm is not None: m.globalnames.update(mm.globalnames) m.starimports.update(mm.starimports) if mm.__code__ is None: m.starimports[name] = 1 else: m.starimports[name] = 1 elif what == "relative_import": level, fromlist, name = args if name: self._safe_import_hook(name, m, fromlist, level=level) else: parent = self.determine_parent(m, level=level) self._safe_import_hook(parent.__name__, None, fromlist, level=0) else: # We don't expect anything else from the generator. raise RuntimeError(what) for c in co.co_consts: if isinstance(c, type(co)): self.scan_code(c, m) def load_package(self, fqname, pathname): self.msgin(2, "load_package", fqname, pathname) newname = replacePackageMap.get(fqname) if newname: fqname = newname m = self.add_module(fqname) m.__file__ = pathname m.__path__ = [pathname] # As per comment at top of file, simulate runtime __path__ additions. m.__path__ = m.__path__ + packagePathMap.get(fqname, []) fp, buf, stuff = self.find_module("__init__", m.__path__) try: self.load_module(fqname, fp, buf, stuff) self.msgout(2, "load_package ->", m) return m finally: if fp: fp.close() def add_module(self, fqname): if fqname in self.modules: return self.modules[fqname] self.modules[fqname] = m = Module(fqname) return m def find_module(self, name, path, parent=None): if parent is not None: # assert path is not None fullname = parent.__name__+'.'+name else: fullname = name if fullname in self.excludes: self.msgout(3, "find_module -> Excluded", fullname) raise ImportError(name) if path is None: if name in sys.builtin_module_names: return (None, None, ("", "", _C_BUILTIN)) path = self.path return _find_module(name, path) def report(self): """Print a report to stdout, listing the found modules with their paths, as well as modules that are missing, or seem to be missing. """ print() print(" %-25s %s" % ("Name", "File")) print(" %-25s %s" % ("----", "----")) # Print modules found keys = sorted(self.modules.keys()) for key in keys: m = self.modules[key] if m.__path__: print("P", end=' ') else: print("m", end=' ') print("%-25s" % key, m.__file__ or "") # Print missing modules missing, maybe = self.any_missing_maybe() if missing: print() print("Missing modules:") for name in missing: mods = sorted(self.badmodules[name].keys()) print("?", name, "imported from", ', '.join(mods)) # Print modules that may be missing, but then again, maybe not... if maybe: print() print("Submodules that appear to be missing, but could also be", end=' ') print("global names in the parent package:") for name in maybe: mods = sorted(self.badmodules[name].keys()) print("?", name, "imported from", ', '.join(mods)) def any_missing(self): """Return a list of modules that appear to be missing. Use any_missing_maybe() if you want to know which modules are certain to be missing, and which *may* be missing. """ missing, maybe = self.any_missing_maybe() return missing + maybe def any_missing_maybe(self): """Return two lists, one with modules that are certainly missing and one with modules that *may* be missing. The latter names could either be submodules *or* just global names in the package. The reason it can't always be determined is that it's impossible to tell which names are imported when "from module import *" is done with an extension module, short of actually importing it. """ missing = [] maybe = [] for name in self.badmodules: if name in self.excludes: continue i = name.rfind(".") if i < 0: missing.append(name) continue subname = name[i+1:] pkgname = name[:i] pkg = self.modules.get(pkgname) if pkg is not None: if pkgname in self.badmodules[name]: # The package tried to import this module itself and # failed. It's definitely missing. missing.append(name) elif subname in pkg.globalnames: # It's a global in the package: definitely not missing. pass elif pkg.starimports: # It could be missing, but the package did an "import *" # from a non-Python module, so we simply can't be sure. maybe.append(name) else: # It's not a global in the package, the package didn't # do funny star imports, it's very likely to be missing. # The symbol could be inserted into the package from the # outside, but since that's not good style we simply list # it missing. missing.append(name) else: missing.append(name) missing.sort() maybe.sort() return missing, maybe def replace_paths_in_code(self, co): new_filename = original_filename = os.path.normpath(co.co_filename) for f, r in self.replace_paths: if original_filename.startswith(f): new_filename = r + original_filename[len(f):] break if self.debug and original_filename not in self.processed_paths: if new_filename != original_filename: self.msgout(2, "co_filename %r changed to %r" \ % (original_filename,new_filename,)) else: self.msgout(2, "co_filename %r remains unchanged" \ % (original_filename,)) self.processed_paths.append(original_filename) consts = list(co.co_consts) for i in range(len(consts)): if isinstance(consts[i], type(co)): consts[i] = self.replace_paths_in_code(consts[i]) return co.replace(co_consts=tuple(consts), co_filename=new_filename) def test(): # Parse command line import getopt try: opts, args = getopt.getopt(sys.argv[1:], "dmp:qx:") except getopt.error as msg: print(msg) return # Process options debug = 1 domods = 0 addpath = [] exclude = [] for o, a in opts: if o == '-d': debug = debug + 1 if o == '-m': domods = 1 if o == '-p': addpath = addpath + a.split(os.pathsep) if o == '-q': debug = 0 if o == '-x': exclude.append(a) # Provide default arguments if not args: script = "hello.py" else: script = args[0] # Set the path based on sys.path and the script directory path = sys.path[:] path[0] = os.path.dirname(script) path = addpath + path if debug > 1: print("path:") for item in path: print(" ", repr(item)) # Create the module finder and turn its crank mf = ModuleFinder(path, debug, exclude) for arg in args[1:]: if arg == '-m': domods = 1 continue if domods: if arg[-2:] == '.*': mf.import_hook(arg[:-2], None, ["*"]) else: mf.import_hook(arg) else: mf.load_file(arg) mf.run_script(script) mf.report() return mf # for -i debugging if __name__ == '__main__': try: mf = test() except KeyboardInterrupt: print("\n[interrupted]") tkinter/__main__.py000064400000000224152342670510010321 0ustar00"""Main entry point""" import sys if sys.argv[0].endswith("__main__.py"): sys.argv[0] = "python -m tkinter" from . import _test as main main() tkinter/__pycache__/constants.cpython-312.pyc000064400000003616152342670510015166 0ustar00 ֦i8dxZxZZdxZxZZdZdZdZdZ dZ dZ dZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#d Z$d!Z%d"Z&d#Z'd$Z(d%Z)d&Z*d'Z+d(Z,d)Z-d*Z.d+Z/d,Z0d-Z1d.Z2d/Z3d0Z4d1Z5d2Z6d3Z7d4Z8d5Z9d6Z:d7Z;d8Zd;Z?dZBd?ZCd@ZDdAZEdBZFdCZGdDZHdEZIdFZJdGZKdHZLyI)Jnswenwswnesensewnsewcenternonexybothlefttoprightbottomraisedsunkenflatridgegroovesolid horizontalverticalnumericcharwordbaselineinsideoutsideselz sel.firstzsel.lastendinsertcurrentanchorallnormaldisabledactivehiddencascade checkbuttoncommand radiobutton separatorsinglebrowsemultipleextendeddotbox underlinepieslicechordarcfirstlastbutt projectingroundbevelmitermovetoscrollunitspagesN)MNOFALSEOFFYESTRUEONNSWENWSWNESENSEWNSEWCENTERNONEXYBOTHLEFTTOPRIGHTBOTTOMRAISEDSUNKENFLATRIDGEGROOVESOLID HORIZONTALVERTICALNUMERICCHARWORDBASELINEINSIDEOUTSIDESEL SEL_FIRSTSEL_LASTENDINSERTCURRENTANCHORALLNORMALDISABLEDACTIVEHIDDENCASCADE CHECKBUTTONCOMMAND RADIOBUTTON SEPARATORSINGLEBROWSEMULTIPLEEXTENDEDDOTBOX UNDERLINEPIESLICECHORDARCFIRSTLASTBUTT PROJECTINGROUNDBEVELMITERMOVETOSCROLLUNITSPAGES*/usr/lib64/python3.12/tkinter/constants.pyrs5  D                                           rtkinter/__pycache__/scrolledtext.cpython-312.pyc000064400000006376152342670510015674 0ustar00 ֦i|dZddlmZmZmZmZmZmZddlm Z m Z m Z m Z dgZ GddeZdZedk(reyy) aA ScrolledText widget feels like a text widget but also has a vertical scroll bar on its right. (Later, options may be added to add a horizontal bar as well, to make the bars disappear automatically when not needed, to move them to the other side of the window, etc.) Configuration options are passed to the Text widget. A Frame widget is inserted between the master and the text, to hold the Scrollbar widget. Most methods calls are inherited from the Text widget; Pack, Grid and Place methods are redirected to the Frame widget however. )FrameText ScrollbarPackGridPlace)RIGHTLEFTYBOTH ScrolledTextceZdZddZdZy)r Nc $t||_t|j|_|jj t t |jd|jjitj||jfi||j ttd|j|jd<ttj}tt jtt"jztt$jz}|j'|}|D]8}|ddk7s |dk7s|d k7st)||t+|j|:y) N)sidefillyscrollcommandT)rrexpandcommandr_config configure)rframervbarpackr r updatesetr__init__r r yviewvarskeysrrr differencesetattrgetattr)selfmasterkw text_methsmethodsms -/usr/lib64/python3.12/tkinter/scrolledtext.pyrzScrolledText.__init__s6] djj)  E* #TYY]]34 dDJJ-"- t$t 4#zz )$Z__& t*//#d4joo&77$u+:J:J:LL$$Z0Ats{qH}k1AaQ!78c,t|jSN)strr)r$s r*__str__zScrolledText.__str__)s4::r+r-)__name__ __module__ __qualname__rr/r+r*r r s 9(r+cddlm}tdd}|j|t|j t td|j|jy)Nr)ENDwhite )bgheightT)rrr) tkinter.constantsr5r insert__doc__rr r focus_setmainloop)r5stexts r*exampler@-sE% GB /E LLg JJDtDJ1 OO NNr+__main__N)r<tkinterrrrrrrr:r r r r __all__r r@r0r3r+r*rDsE >=22  42 z Ir+tkinter/__pycache__/constants.cpython-312.opt-2.pyc000064400000003616152342670510016126 0ustar00 ֦i8dxZxZZdxZxZZdZdZdZdZ dZ dZ dZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#d Z$d!Z%d"Z&d#Z'd$Z(d%Z)d&Z*d'Z+d(Z,d)Z-d*Z.d+Z/d,Z0d-Z1d.Z2d/Z3d0Z4d1Z5d2Z6d3Z7d4Z8d5Z9d6Z:d7Z;d8Zd;Z?dZBd?ZCd@ZDdAZEdBZFdCZGdDZHdEZIdFZJdGZKdHZLyI)Jnswenwswnesensewnsewcenternonexybothlefttoprightbottomraisedsunkenflatridgegroovesolid horizontalverticalnumericcharwordbaselineinsideoutsideselz sel.firstzsel.lastendinsertcurrentanchorallnormaldisabledactivehiddencascade checkbuttoncommand radiobutton separatorsinglebrowsemultipleextendeddotbox underlinepieslicechordarcfirstlastbutt projectingroundbevelmitermovetoscrollunitspagesN)MNOFALSEOFFYESTRUEONNSWENWSWNESENSEWNSEWCENTERNONEXYBOTHLEFTTOPRIGHTBOTTOMRAISEDSUNKENFLATRIDGEGROOVESOLID HORIZONTALVERTICALNUMERICCHARWORDBASELINEINSIDEOUTSIDESEL SEL_FIRSTSEL_LASTENDINSERTCURRENTANCHORALLNORMALDISABLEDACTIVEHIDDENCASCADE CHECKBUTTONCOMMAND RADIOBUTTON SEPARATORSINGLEBROWSEMULTIPLEEXTENDEDDOTBOX UNDERLINEPIESLICECHORDARCFIRSTLASTBUTT PROJECTINGROUNDBEVELMITERMOVETOSCROLLUNITSPAGES*/usr/lib64/python3.12/tkinter/constants.pyrs5  D                                           rtkinter/__pycache__/commondialog.cpython-312.pyc000064400000003543152342670510015621 0ustar00 ֦i .dgZddlmZmZGddZy)Dialog)_get_temp_root_destroy_temp_rootc0eZdZdZddZdZdZdZdZy)rNc F||jd}||_||_y)Nparent)getmasteroptions)selfr r s -/usr/lib64/python3.12/tkinter/commondialog.py__init__zDialog.__init__s# >[[*F  cyN)r s r _fixoptionszDialog._fixoptions rc|Srr)r widgetresults r _fixresultzDialog._fixresults rc |jD]\}}||j|<|j|j}| t } |j ||j j|jg|j|j}|j||}t||S#t|wxYwr) itemsr rr r_test_callbacktkcallcommand_optionsrr)r r kvr ss r showz Dialog.show sMMODAqDLLO$  >#%F '    ' t||Lfoodll.KLA*A v & v &s A#C Ccyrr)r r s r rzDialog._test_callback4rrr) __name__ __module__ __qualname__rrrrr#rrrr rrs G  ( rN)__all__tkinterrrrrrr r*s *6% % rtkinter/__pycache__/font.cpython-312.opt-2.pyc000064400000023020152342670510015047 0ustar00 ֦iXddlZddlZdZgdZdZdZdZdZddZGd d Z dd Z dd Z e d k(rejZe ddeZeej#eej#deej#deej%eej'deej'dee eej)dej+deej+ee dZeej)dej+deej,edeZej1ej2edej4Zej1e edj7Zej%eej%eej:yy) Nz0.9)NORMALROMANBOLDITALIC nametofontFontfamiliesnamesnormalromanbolditalicc t|d|S)NT)nameexistsroot)r)rrs %/usr/lib64/python3.12/tkinter/font.pyrrs T$T 22ceZdZ ejdZdZdZdZddZ dZ dZ d Z d Z d Zd Zd ZddZdZdZeZddZdZy)rcg}|jD]3\}}|jd|z|jt|5t|SN-)itemsappendstrtuple)selfkwoptionskvs r_setz Font._set2sGHHJDAq NN3q5 ! NN3q6 "W~rcRg}|D]}|jd|zt|Sr)rr)rargsr r!s r_getz Font._get9s+A NN3q5 !W~rcbi}tdt|dD]}||dz|||dd<|S)Nrr)rangelen)rr%r is r_mkdictz Font._mkdict?s?q#d)Q'A#'!9GDGABK (rNc |tjd}t|d|}|r#|j|j dd|}n|j |}|s!dt t|jz}||_ |rd|_ |j|j|j ddvr-tjjd|jd|rF|jdd |jg|n&|jdd |jg|d |_ ||_ |j|_|j|_y) Nzuse fonttkfontactualFr z named font z does not already exist configurecreateT)tkinter_get_default_rootgetattr splitlistcallr#rnextcounterr delete_font_tkinterTclError_tk_split_call)rrr/rrr r.s r__init__z Font.__init__Es% <,,Z8D T4 & <<$ ?@D99W%DCT\\ 233D $D yy RWWVW-E FF&&//>BiiIKK TYY>> BGGFHdii 7$ 7#D ll gg rc|jSN)rrs r__str__z Font.__str__ds yyrc~d|jjd|jjd|jdS)N<.z object >) __class__ __module__ __qualname__rrCs r__repr__z Font.__repr__gs<4>>,,-Qt~~/J/J.K$))a) )rct|tstS|j|jk(xr|j|jk(SrB) isinstancerNotImplementedrr=)rothers r__eq__z Font.__eq__ks7%&! !yyEJJ&@488uyy+@@rc$|j|SrB)cget)rkeys r __getitem__zFont.__getitem__psyy~rc,|jdi||iy)N)r1)rrTvalues r __setitem__zFont.__setitem__ss&#u&rcx |jr|jdd|jyy#t$rYywxYw)Nr/delete)r:r?r ExceptionrCs r__del__z Font.__del__vs;  68TYY7    s )- 99cL t|jfi|jSrB)rr=r0rCs rcopyz Font.copy}s4DHH. ..rc  d}|rd|f}|r(|d|zfz}|jdd|jg|S|j|j|jdd|jg|S)NrW -displayofrr/r0)r?rr,r>)roption displayofr%s rr0z Font.actuals'  ),D 3<**D4::fh ADA A<< JDJJvxJTJKM MrcF |jdd|jd|zS)Nr/configr)r?r)rrbs rrSz Font.cgets"zz&(DIIs6zBBrc |r/|jdd|jg|j|y|j|j |jdd|jS)Nr/re)r?rr#r,r>)rr s rrez Font.configsc  DJJvx '99W% '<< DJJvxCDF Frc |f}|rd||f}|jj|jdd|jg|S)Nrar/measure)r=getintr?r)rtextrcr%s rrhz Font.measuresFw  )T2Dxxztzz&)TYYNNOOrc d}|jdd}|rd|f}|rL||j|z}|jj|jdd|j g|S|j |jdd|j g|}i}tdt|dD],}|jj||dz|||dd<.|S) NrWrcrar/metricsrr(r) popr&r=rir?rr>r)r*)rr rr%rcresr+s rrlz Font.metricss 7FF;-  ),D $))G,,D88?? 69dii?$?A A++jdjjDIIMMNCG1c#h*&*hhooc!A#h&?Aqr #+Nr)NNNFNNrB)__name__rJrK itertoolscountr9r#r&r,r@rDrLrQrUrYr]r_r0rSrer1rhrlrWrrrrsu*iooa G  >)A '/ MCFIPrrc |tjd}d}|rd|f}|jj|jjddg|S)Nzuse font.families()rWrar/r r3r4r.r6r7)rrcr%s rr r sX$ |(()>? Di( 77  \TWW\\&*DtD EErc |tjd}|jj|jj ddS)Nzuse font.names()r/r rt)rs rr r s?- |(();< 77  TWW\\&': ;;r__main__times)familysizeweightryr{hello linespace)rc)Courierr )r/z Hello, world)rjr/zQuit!)rjcommandr/)r{rBro)rqr3 __version____all__rrrrrrr r rpTkrfprintr0rerSrhrlLabelwpackButtondestroyr_fbmainlooprWrrrs   6   3 [[|F< z 7::dxd6Z?Gd7d8Z@Gd9d:ZAGd;d<ZBGd=d>e7ZCGd?d@eCe@eAeBZDGdAdBeCe;ZEGdCdDeDZFGdEdFeDe9e:ZGdaHGdGdHeDZIGdIdJeDe9ZJGdKdLeDZKGdMdNeDZLGdOdPeDe9e:ZMGdQdReDZNGdSdTeDZOGdUdVeDZPGdWdXeDZQGdYdZeDZRGd[d\eDZSGd]d^eDe9e:ZTGd_d`ZUGdadbeOZVGdcddZWGdedfeWZXGdgdheWZYdiZZdjZ[GdkdleDe9Z\GdmdneDZ]GdodpeDZ^dqZ_e`jDcgc]/\}}|jdrsec|ejs|dsvr|1c}}Zeefdtk(re_yy#e$rYwxYw#e$rYwxYwcc}}w)ya8Wrapper functions for Tcl/Tk. Tkinter provides classes which allow the display, positioning and control of widgets. Toplevel widgets are Tk and Toplevel. Other widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox LabelFrame and PanedWindow. Properties of the widgets are specified with keyword arguments. Keyword arguments have the same name as the corresponding resource under Tk. Widgets are positioned with one of the geometry managers Place, Pack or Grid. These managers can be called with methods place, pack, grid available in every Widget. Actions are bound to events by resources (e.g. keyword argument command) or with the method bind. Example (Hello, World): import tkinter from tkinter.constants import * tk = tkinter.Tk() frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2) frame.pack(fill=BOTH,expand=1) label = tkinter.Label(frame, text="Hello, World") label.pack(fill=X, expand=1) button = tkinter.Button(frame,text="Exit",command=tk.destroy) button.pack(side=BOTTOM) tk.mainloop() N)*Fz([\\{}])z([\s])c@djtt|S)Internal function. )joinmap _stringifyvalues )/usr/lib64/python3.12/tkinter/__init__.py_joinr:s 88C E* ++c&t|ttfrHt|dk(r*t |d}t j |rd|z}|Sdt|z}|St|tr t|d}n t|}|sd}|St j |rMt jd|}|jdd}tjd|}|dd k(rd |z}|S|dd k(stj |rd|z}|S) rrrz{%s}latin1z{}z\\\1 z\n"\) isinstancelisttuplelenr _magic_researchrbytesstrsubreplace _space_rer s r r r ?s%$' u:?uQx(E&& L#U5\)E" L eU #x(EJEE L  e $MM'51EMM$.EMM'51EQx3u  L1X_ 0 0 7UNE Lrctd}|D]0}t|ttfr|t|z}(|+||fz}2|S)r)rrr_flatten)seqresitems r r"r"[sE C dUDM *&C  -C  Jrc6t|tr|St|tdtfr|Si}t |D]} |j ||S#t tf$r3}td||jD] \}}|||< Yd}~Vd}~wwxYw)rNz_cnfmerge: fallback due to:) rdicttyperr"updateAttributeError TypeErrorprintitems)cnfscnfcmsgkvs r _cnfmerger4js$ D4:s+ , $A  1   #I. 3S9GGIDAqCF& sAB%)BBTc|j|}t|dzr tdt|}i}t ||D].\}}t |}|r |ddk(r|dd}|r||}|||<0|S)aReturn a properly formatted dict built from Tcl list pairs. If cut_minus is True, the supposed '-' prefix will be removed from keys. If conv is specified, it is used to convert values. Tcl list is expected to contain an even number of elements. zNTcl list representing a dict is expected to contain an even number of elementsr-rN) splitlistr RuntimeErroriterzipr) tkr3 cut_minusconvtitr'keyr s r _splitdictrBs QA 1vzCD D aB D"bk U#h Q3ab'C KES " KrceZdZdZy)_VersionInfoTypec|jdk(r(|jd|jd|jS|jd|j|jd|jS)Nfinal.r) releaselevelmajorminormicroserialselfs r __str__z_VersionInfoType.__str__sd    'jj\4::,a |< <jj\4::,t/@/@/C.DT[[MR RrN)__name__ __module__ __qualname__rOr!rr rDrDsSrrD)rIrJrKrHrLcddl}|jd|}|j\}}}}t|t|t|}}}|dk(r|}d}d}n d}ddd|}t |||||S)Nrz(\d+)\.(\d+)([ab.])(\d+)rGrFalphabeta)ab)re fullmatchgroupsintrD)versionrXmrIrJrHrLrKs r _parse_versionr^s  0':A)*&E5,u:s5z3v;&5Es $62<@ E5%v FFrceZdZdZeZdZdZeZdZdZ dZ dZ dZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#d Z$d!Z%d"Z&d#Z'd$Z(d%Z)y&)' EventType234567891011121314151617181920212223242526272829303132333435363738N)*rPrQrRKeyPressKey KeyRelease ButtonPressButton ButtonReleaseMotionEnterLeaveFocusInFocusOutKeymapExposeGraphicsExposeNoExpose VisibilityCreateDestroyUnmapMap MapRequestReparent ConfigureConfigureRequestGravity ResizeRequest CirculateCirculateRequestPropertySelectionClearSelectionRequest SelectionColormap ClientMessageMapping VirtualEventActivate Deactivate MouseWheelr!rr r`r`sH CJK FM F E EGH F FNHJ FG E CJHIGMIHNIHMGLHJJrr`ceZdZdZdZy)EventaContainer for the properties of an event. Instances of this type are generated if one of the following events occurs: KeyPress, KeyRelease - for keyboard events ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, Colormap, Gravity, Reparent, Property, Destroy, Activate, Deactivate - for window events. If a callback function for one of these events is registered using bind, bind_all, bind_class, or tag_bind, the callback is called with an Event as first argument. It will have the following attributes (in braces are the event types for which the attribute is valid): serial - serial number of event num - mouse button pressed (ButtonPress, ButtonRelease) focus - whether the window has the focus (Enter, Leave) height - height of the exposed window (Configure, Expose) width - width of the exposed window (Configure, Expose) keycode - keycode of the pressed key (KeyPress, KeyRelease) state - state of the event as a number (ButtonPress, ButtonRelease, Enter, KeyPress, KeyRelease, Leave, Motion) state - state as a string (Visibility) time - when the event occurred x - x-position of the mouse y - y-position of the mouse x_root - x-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) y_root - y-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) char - pressed character (KeyPress, KeyRelease) send_event - see X/Windows documentation keysym - keysym of the event as a string (KeyPress, KeyRelease) keysym_num - keysym of the event as a number (KeyPress, KeyRelease) type - type of the event as a number widget - widget in which the event occurred delta - delta of wheel movement (MouseWheel) c |jjDcic]\}}|dk7s ||c}} |js d=n'|jdk7rt|j d<t |dds d=|j dk(r d=nt |j tr|j }d}g}t|D]\}}|d|zzs|j|!|dt|zdz z}|s|s|jt|d j| d<|jdk(r d =d }d t |jd |jddj fd|DdScc}}w)Nz??char send_eventTrstate) ShiftLockControlMod1Mod2Mod3Mod4Mod5Button1Button2Button3Button4Button5r|delta) rrkeysymkeycodernumrfocusxywidthheight<namez eventc3>K|]}|vsd|d|yw)r=Nr!).0r2attrss r z!Event.__repr__..'s!Ida5j58,ds >)__dict__r-rreprgetattrrrr[ enumerateappendrhexrrr() rNr2r3rmodssinkeysrs @r __repr__zEvent.__repr__sh"&--"5"5"7E"7$!Q19A"7Eyyf YY$  OE&Mt\40l# ::?g  C (JJEKDA!$1AF#HHQK(q3t9}122EAU$ XXa[E'N ::?g - DIIvtyy 1 GGIdI I  AFs FFN)rPrQrR__doc__rr!rr rrs (T$ rrcdadaby)zInhibit setting of default root window. Call this function to inhibit that the first instance of Tk is used for windows without an explicit parent window. FN)_support_default_root _default_rootr!rr NoDefaultRootr/s"Mrcrts tdt|rtd|dt}tS)NINo master specified and tkinter is configured to not support default rootz Too early to z: no default root window)rr9rTk)whatroots r _get_default_rootr=sE DE E tf4LMN Nt rcts tdt}|%dat}da|j d|_|S)NrFT)rr9rrwithdraw _temporaryrs r _get_temp_rootrIsL DE E D | %t $  Krc`t|ddr |jyy#t$rYywxYw)NrF)rdestroyTclErrormasters r _destroy_temp_rootrZs6v|U+  NN ,   s ! --cyrNr!)errs r _tkerrorrbsrcb t|}t|#t$r Yt|wxYw)zBInternal function. Calling it will raise the exception SystemExit.)r[ ValueError SystemExit)codes r _exitrgs< 4y T    T  s  ..cteZdZdZdZdZdZddZdZdZ dZ e Z dZ d Z d Zd Zd Zd ZeZdZdZdZy)VariablezClass to define value holders for e.g. buttons. Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations that constrain the type of the value returned from get().rNc|t|ts td| td}|j |_|j |_|r||_n dttz|_tdz a ||j|y|j j|j jdd|js|j|jyy)a.Construct a variable MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. Nzname must be a stringzcreate variablePY_VARrinfoexists)rrr+r_rootr<_tk_namer_varnum initialize getbooleancall_defaultrNrr rs r __init__zVariable.__init__|s  JtS$934 4 >&'89F\\^ 99 DJ!DM1DJ qLG   OOE "$$TXX]]68TZZ%PQ OODMM *Rrch|jy|jj|jjdd|jr%|jj |j|j 4|j D]}|jj |d|_yy)zUnset the variable in Tcl.Nrr)rr r rglobalunsetvar _tclCommands deletecommandrNrs r __del__zVariable.__del__s 88   88  txx}}VXtzzJ K HH # #DJJ /    ())&&t,* $D  )rc|jS)z'Return the name of the variable in Tcl.)rrMs r rOzVariable.__str__s zzrcN|jj|j|SzSet the variable to VALUE.)r globalsetvarrrNr s r setz Variable.setsxx$$TZZ77rcL|jj|jS)zReturn value of variable.)r globalgetvarrrMs r getz Variable.getsxx$$TZZ00rczt|d|jj}tt |} |j } ||jz}|jj|||jg|_ |jj||S#t $rYgwxYw#t $rYfwxYwN) CallWrapperr__call__rid__func__r*rPr createcommandrr)rNcallbackfcbnames r _registerzVariable._registers $ 3 < <be ((H h///F vq)    $ "D    (       s# BB. B+*B+. B:9B:c~|j|}|jjddd|j||f|S)a#Define a trace callback for the variable. Mode is one of "read", "write", "unset", or a list or tuple of such strings. Callback must be a function which is called when the variable is read, written or unset. Return the name of the callback. traceaddvariabler'rr rrNmoder$r&s r trace_addzVariable.trace_adds:)  gujjj$  3 rcZ|jjddd|j|||jD](\}}|jj |d|k(s(y|jj | |j j|y#t$rYywxYw)aDelete the trace callback for a variable. Mode is one of "read", "write", "unset" or a list or tuple of such strings. Must be same as were specified in trace_add(). cbname is the name of the callback returned from trace_add(). r)remover+rN) rr r trace_infor8rrr1rrNr.r&r]cas r trace_removezVariable.trace_removes  gxjj$ 0__&EArxx!!"%a(F2' HH " "6 * !!((0  sB B*)B*c |jj}t|||jjddd|jDcgc]\}}|||fc}}Scc}}w)z&Return all trace callback information.r)rr+)rr8r r r)rNr8r2r3s r r2zVariable.trace_infosqHH&& .1) dhhmmGVZL M/OP/Oda1q!/OP PPsA*cz|j|}|jjdd|j|||S)aDefine a trace callback for the variable. MODE is one of "r", "w", "u" for read, write, undefine. CALLBACK must be a function which is called when the variable is read, written or undefined. Return the name of the callback. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_add() instead. r)r+r,r-s r trace_variablezVariable.trace_variables3)  gz4::tVD rc|jjdd|j|||jj|d}|j D](\}}|jj|d|k(s(y|jj | |j j|y#t$rYywxYw)aSDelete the trace callback for a variable. MODE is one of "r", "w", "u" for read, write, undefine. CBNAME is the name of the callback returned from trace_variable or trace. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_remove() instead. r)vdeleterN) rr rr8r2rrr1rr3s r trace_vdeletezVariable.trace_vdeletes  gy$**dFC##F+A.__&EArxx!!"%a(F2' HH " "6 * !!((0  sB;; CCc|jj|jjdd|jDcgc]}|jj|c}Scc}w)zReturn all trace callback information. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_info() instead. r)vinfo)rr8r rrNrs r trace_vinfozVariable.trace_vinfos`04xx/A/A HHMM'7DJJ 709:09!""1%09: ::s"A(ct|tstS|j|jk(xrH|jj |jj k(xr|j |j k(Sr)rrNotImplementedr __class__rPr)rNothers r __eq__zVariable.__eq__s]%*! ! ekk)*NN++u/G/GG*HH ) +rNNN)rPrQrRrr rrr rrOrrrr'r/r5r2r8r)r;r?rDr!rr rrssiAH CL+< %8J1" &P " E,:+rrc"eZdZdZdZddZdZy) StringVarz#Value holder for strings variables.rNc4tj||||y)a6Construct a string variable. MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. Nrr r s r r zStringVar.__init__+ $t4rc|jj|j}t|tr|St |S)z#Return value of variable as string.)rrrrrrs r rz StringVar.get7s3%%djj1 eS !L5zrrErPrQrRrr r rr!rr rGrG's-H 5rrGc"eZdZdZdZddZdZy)IntVarz#Value holder for integer variables.rNc4tj||||y)a7Construct an integer variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. NrIr s r r zIntVar.__init__CrJrc|jj|j} |jj|S#tt f$r't |jj|cYSwxYw)z/Return the value of the variable as an integer.)rrrgetintr+rr[ getdoublers r rz IntVar.getOs`%%djj1 288??5) )8$ 2txx))%01 1 2sA3A87A8rErLr!rr rNrN?s-H 52rrNc"eZdZdZdZddZdZy) DoubleVarz!Value holder for float variables.gNc4tj||||y)a6Construct a float variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0.0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. NrIr s r r zDoubleVar.__init__\rJrc~|jj|jj|jS)z,Return the value of the variable as a float.)rrRrrrMs r rz DoubleVar.geths*xx!!$(("7"7 "CDDrrErLr!rr rTrTXs+H 5ErrTc,eZdZdZdZddZdZeZdZy) BooleanVarz#Value holder for boolean variables.FNc4tj||||y)a:Construct a boolean variable. MASTER can be given as master widget. VALUE is an optional value (defaults to False) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. NrIr s r r zBooleanVar.__init__qrJrc|jj|j|jj|Sr)rrrr rs r rzBooleanVar.set}s,xx$$TZZ1D1DU1KLLrc |jj|jj|jS#t$r t dwxYw)z+Return the value of the variable as a bool. invalid literal for getboolean())rr rrrrrMs r rzBooleanVar.getsM A88&&txx'<'d9Z?d:Z@d;ZAd<ZBd=ZCdd>ZDd?ZEd@ZFdAZGdBZHddCZIdDZJdEZKdFZLdGZMdHZNdIZOdJZPdKZQdLZRdMZSdNZTdOZUdPZVdQZWdRZXdSZYdTZZdUZ[dVZ\dWZ]dXZ^dYZ_ddZZ`d[Zad\Zbd]Zcd^Zdd_Zed`ZfdaZgdbZhdcZiddZjdeZkddfZlddgZmddhZnddiZoddjZpddkZqdlZrddmZsdnZtddoZudpZvdqZwdrZxdsZydtZze{duZ|ddvZ}dwZ~e~ZddxZeZdyZdzZd{j eZd|Zd}Zd~ZdZdZddZeZdZeZdZdZdZdZdgZefdZeZdZeZdZddZeZddZeZdZdZifdZeZdZefdZifdZeZdZeZddZdZdZdZddZdZdZy)MisczRInternal class. Base class which defines methods common for interior widgets.Nc|j4|jD]}|jj|d|_yy)zkInternal function. Delete all Tcl commands created for this widget in the Tcl interpreter.N)rr<rrs r rz Misc.destroys?    ())%%d+* $D  )rc|jj| |jj|y#t$rYywxYw)zDInternal function. Delete the Tcl command provided in NAME.N)r<rrr1rrs r rzMisc.deletecommandsA d#     $ $T *   s9 AAcn|jj|jjdd|S)zSet Tcl internal variable, whether the look and feel should adhere to Motif. A parameter of 1 means adhere to Motif (e.g. no color change if mouse passes over slider). Returns the set value.rtk_strictMotif)r<r r rNbooleans r rezMisc.tk_strictMotifs2ww!!$'',, #W#./ /rc:|jjdy)zDChange the color scheme to light brown as used in Tk 3.6 and before. tk_bisqueNr<r rMs r rizMisc.tk_bisques  [!rc |jjdt|ztt|j zy)a Set a new color scheme for all widget elements. A single color as argument will cause that all colors of Tk widget elements are derived from this. Alternatively several keyword parameters and its associated colors can be given. The following keywords are valid: activeBackground, foreground, selectColor, activeForeground, highlightBackground, selectBackground, background, highlightColor, selectForeground, disabledForeground, insertBackground, troughColor.) tk_setPaletteN)r<r r"rr-rNargskws r rlzMisc.tk_setPalettes;  '!)$rxxz*:!;< =rc>|jjdd|y)zWait until the variable is modified. A parameter of type IntVar, StringVar, DoubleVar or BooleanVar must be given.tkwaitr+Nrjrs r wait_variablezMisc.wait_variables  Xz40rcZ||}|jjdd|jy)zQWait until a WIDGET is destroyed. If no parameter is given self is used.Nrqwindowr<r _wrNrts r wait_windowzMisc.wait_windows& >F  Xx3rcZ||}|jjdd|jy)zxWait until the visibility of a WIDGET changes (e.g. it appears). If no parameter is given self is used.Nrq visibilityrurws r wait_visibilityzMisc.wait_visibilitys& >F  X|VYY7rc<|jj||y)zSet Tcl variable NAME to VALUE.N)r<setvar)rNrr s r r}z Misc.setvars tU#rc8|jj|S)z"Return value of Tcl variable NAME.)r<getvarrs r rz Misc.getvarsww~~d##rc |jj|S#t$r}tt |d}~wwxYwr)r<rQrrrrNrexcs r rQz Misc.getints9 '77>>!$ $ 'SX& & ' ?:?c |jj|S#t$r}tt |d}~wwxYwr)r<rRrrrrs r rRzMisc.getdoubles; '77$$Q' ' 'SX& & 'rcj |jj|S#t$r tdwxYw)zPReturn a boolean value for Tcl boolean values true and false given as parameter.r\)r<r rr)rNrs r r zMisc.getbooleans: A77%%a( ( A?@ @ As2cP|jjd|jy)zDirect input focus to this widget. If the application currently does not have the focus this widget will get the focus if the application gets the focus through the window manager.rNrurMs r focus_setzMisc.focus_sets  Wdgg&rcR|jjdd|jy)ztDirect input focus to this widget even if the application does not have the focus. Use with caution!rz-forceNrurMs r focus_forcezMisc.focus_forces  Wh0rcj|jjd}|dk(s|sy|j|S)zReturn the widget which has currently the focus in the application. Use focus_displayof to allow working with several displays. Return None if application does not have the focus.rnoneN)r<r  _nametowidgetrs r focus_getzMisc.focus_gets2ww||G$ 6>d!!$''rc|jjdd|j}|dk(s|sy|j|S)zReturn the widget which has currently the focus on the display where this widget is located. Return None if the application does not have the focus.r -displayofrNr<r rvrrs r focus_displayofzMisc.focus_displayof(s: ww||G\477; 6>d!!$''rc|jjdd|j}|dk(s|sy|j|S)zyReturn the widget which would have the focus if top level for this widget gets the focus from the window manager.rz-lastforrNrrs r focus_lastforzMisc.focus_lastfor1s:ww||GZ9 6>d!!$''rc:|jjdy)zXThe widget under mouse will get automatically focus. Can not be disabled easily.tk_focusFollowsMouseNrjrMs r rzMisc.tk_focusFollowsMouse8s  +,rcv|jjd|j}|sy|j|S)anReturn the next widget in the focus order which follows widget which has currently the focus. The focus order first goes to the next child, then to the children of the child recursively and then to the next sibling which is higher in the stacking order. A widget is omitted if it has the takefocus resource set to 0. tk_focusNextNrrs r rzMisc.tk_focusNext=s2ww||NDGG4D!!$''rcv|jjd|j}|sy|j|S)zHReturn previous widget in the focus order. See tk_focusNext for details. tk_focusPrevNrrs r rzMisc.tk_focusPrevJs0ww||NDGG4D!!$''rc*jjd|yfd} j|_j |jjd|S#t$rt j|_YSwxYw)aCall function once after given time. MS specifies the time in milliseconds. FUNC gives the function which shall be called. Additional parameters are given as parameters to the function call. Return identifier to cancel scheduling with after_cancel.Nafterc  jy#t$rYywxYw# jw#t$rYwwxYwxYwr)rr)rnfuncrrNsr callitzMisc.after..callit\sY$K**40#**40#s5* ''A >A  A A  A  A )r<r rPr*r(r')rNmsrrnrrs` `` @r rz Misc.afterPs} < GGLL" %  6"&-->>&)D77<<T2 2 " 6"&t*"5"5 6sA,,#BBc*|jd|g|S)zCall FUNC once if the Tcl main loop has no event to process. Return an identifier to cancel the scheduling with after_cancel.idle)r)rNrrns r after_idlezMisc.after_idlels tzz&$...rc|s td |jjdd|}|jj|d}|j ||jjdd|y#t $rY)wxYw)zCancel scheduling of function identified with ID. Identifier returned by after or after_idle must be given as first parameter. z?id must be a valid identifier returned from after or after_idlerrrcancelN)rr<r r8rr)rNr!datascripts r after_cancelzMisc.after_cancelts 34 4 77<<4DWW&&t,Q/F   v &  Wh+   sA A99 BBc^|jjd|j|zy)zRing a display's bell.)bellN)r<r  _displayofrN displayofs r rz Misc.bells   Y!;; *6 ww||$84==;L$LMMww||04==3DDEE vJ s1A44 BBc d|vr|j|d<|jjd|j|zy)zClear the data in the Tk clipboard. A widget specified for the optional displayof keyword argument specifies the target display.r)rclearNrvr<r rrs r clipboard_clearzMisc.clipboard_clears7 b DGG"[/  +dmmB.??@rc d|vr|j|d<|jjd|j|zd|fzy)zAppend STRING to the Tk clipboard. A widget specified at the optional displayof keyword argument specifies the target display. The clipboard can be retrieved with selection_get.r)rr--Nr)rNstringros r clipboard_appendzMisc.clipboard_appendsE b DGG"[/  ,t}}R/@@v rcx|jjdd|j}|sy|j|S)zOReturn widget which has currently the grab in this application or None.grabcurrentNrrs r grab_currentzMisc.grab_currents4ww||FItww7D!!$''rcR|jjdd|jy)z.Release grab for this widget if currently set.rreleaseNrurMs r grab_releasezMisc.grab_releases  VY0rcR|jjdd|jy)zwSet grab for this widget. A grab directs all events to this and descendant widgets in the application.rrNrurMs r grab_setz Misc.grab_sets  VUDGG,rcT|jjddd|jy)zSet global grab for this widget. A global grab directs all events to this and descendant widgets on the display. Use with caution - other applications do not get events anymore.rrz-globalNrurMs r grab_set_globalzMisc.grab_set_globals  VUItww7rcb|jjdd|j}|dk(rd}|S)zYReturn None, "local" or "global" if this widget has no, a local or a global grab.rstatusrNru)rNrs r grab_statuszMisc.grab_statuss/fh8 V dV rcB|jjdd|||y)zSet a VALUE (second parameter) for an option PATTERN (first parameter). An optional third parameter gives the numeric priority (defaults to 80).optionr*Nrj)rNpatternr prioritys r option_addzMisc.option_adds  Xuguh?rc<|jjddy)zPClear the option database. It will be reloaded if option_add is called.rrNrjrMs r option_clearzMisc.option_clears  Xw'rcT|jjdd|j||S)zReturn the value for an option NAME for this widget with CLASSNAME. Values with higher priority override lower values.rrru)rNr classNames r option_getzMisc.option_gets# ww||HeTWWdIFFrc@|jjdd||y)zvRead file FILENAME into the option database. An optional second parameter gives the numeric priority.rreadfileNrj)rNfileNamers r option_readfilezMisc.option_readfiles  Xz8X>rc d|vr|j|d<|jjd|j|zy)zClear the current X selection.r) selectionrNrrs r selection_clearzMisc.selection_clears5 b DGG"[/  +dmmB.??@rc 2d|vr|j|d<d|vrB|jdk(r3 d|d<|jjd|j |zS|jjd|j |zS#t $r|d=Y;wxYw)aReturn the contents of the current X selection. A keyword parameter selection specifies the name of the selection and defaults to PRIMARY. A keyword parameter displayof specifies a widget on the display to use. A keyword parameter type specifies the form of data to be fetched, defaulting to STRING except on X11, where UTF8_STRING is tried before STRING.rr(rr)rr)rvrr<r rrrs r selection_getzMisc.selection_gets b DGG"[/   5 5 > *6 ww||$84==;L$LMMww||04==3DDEE vJ s1B BBc |j|}|jjd|j|z|j|fzy)aSpecify a function COMMAND to call if the X selection owned by this widget is queried by another application. This function must return the contents of the selection. The function will be called with the arguments OFFSET and LENGTH which allows the chunking of very long selections. The following keyword parameters can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).)rhandleN)r'r<r rrv)rNcommandrors r selection_handlezMisc.selection_handlesC~~g&  ,t}}R/@@$  !rc z|jjd|j|z|jfzy)zBecome owner of X selection. A keyword parameter selection specifies the name of the selection (default PRIMARY).rownN)r<r rrvrs r selection_ownzMisc.selection_owns6  )r"#&*ggZ0 1rc d|vr|j|d<|jjd|j|z}|sy|j |S)zReturn owner of X selection. The following keyword parameter can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).rrN)rvr<r rr)rNrors r selection_own_getzMisc.selection_own_get sO b DGG"[/ww||04==3DDED!!$''rcD|jjd||f|zS)zDSend Tcl command CMD to different interpreter INTERP to be executed.sendrj)rNinterpcmdrns r rz Misc.send,s!ww||VVS1D899rcR|jjd|j|y)z(Lower this widget in the stacking order.lowerNru)rN belowThiss r rz Misc.lower0  Wdggy1rcR|jjd|j|y)z(Raise this widget in the stacking order.raiseNru)rN aboveThiss r tkraisez Misc.tkraise4rrcP|jjdd}t|S)z-Returns the exact version of the Tcl library.r patchlevel)r<r r^)rNrs r info_patchlevelzMisc.info_patchlevel:s!WW\\&,7 j))rcd|j|z|fz}|jj|jj|S)z*Return integer which represents atom NAME.)winfoatom)rr<rQr )rNrrrns r winfo_atomzMisc.winfo_atom?s< 4??9#==Gww~~dggll4011rchd|j|z|fz}|jj|S)z'Return name of atom with identifier ID.)ratomname)rr<r rNr!rrns r winfo_atomnamezMisc.winfo_atomnameDs5$+,/1e4ww||D!!rc|jj|jjdd|jS)z7Return number of cells in the colormap for this widget.rcellsr<rQr rvrMs r winfo_cellszMisc.winfo_cellsJ/ww~~ GGLL'477 35 5rcg}|jj|jjdd|jD]#} |j |j |%|S#t $rY3wxYw)z?Return a list of all widgets which are children of this widget.rchildren)r<r8r rvrrKeyError)rNresultchilds r winfo_childrenzMisc.winfo_childrenOsqWW&& GGLL*dgg 68E  d0078 8   s A++ A76A7cP|jjdd|jS)z(Return window class name of this widget.rclassrurMs r winfo_classzMisc.winfo_class\sww||GWdgg66rc|jj|jjdd|jS)z?Return True if at the last color request the colormap was full.r colormapfullr<r r rvrMs r winfo_colormapfullzMisc.winfo_colormapfull`s1ww!! GGLL.$'' :<  >rc|jj|jjdd|jS)z:Return the x coordinate of the pointer on the root window.rpointerxrrMs r winfo_pointerxzMisc.winfo_pointerxr0rcn|j|jjdd|jS)zHReturn a tuple of x and y coordinates of the pointer on the root window.r pointerxy_getintsr<r rvrMs r winfo_pointerxyzMisc.winfo_pointerxys+}} GGLL+tww 79 9rc|jj|jjdd|jS)z:Return the y coordinate of the pointer on the root window.rpointeryrrMs r winfo_pointeryzMisc.winfo_pointeryr0rc|jj|jjdd|jS)z'Return requested height of this widget.r reqheightrrMs r winfo_reqheightzMisc.winfo_reqheights/ww~~ GGLL+tww 79 9rc|jj|jjdd|jS)z&Return requested width of this widget.rreqwidthrrMs r winfo_reqwidthzMisc.winfo_reqwidthr0rcp|j|jjdd|j|S)zNReturn a tuple of integer RGB values in range(65536) for color in this widget.rrgbrE)rNcolors r winfo_rgbzMisc.winfo_rgbs-}} GGLL%% 8: :rc|jj|jjdd|jS)zSReturn x coordinate of upper left corner of this widget on the root window.rrootxrrMs r winfo_rootxzMisc.winfo_rootx1ww~~ GGLL'477 35 5rc|jj|jjdd|jS)zSReturn y coordinate of upper left corner of this widget on the root window.rrootyrrMs r winfo_rootyzMisc.winfo_rootyrXrcP|jjdd|jS)z&Return the screen name of this widget.rscreenrurMs r winfo_screenzMisc.winfo_screenr9rc|jj|jjdd|jS)zTReturn the number of the cells in the colormap of the screen of this widget.r screencellsrrMs r winfo_screencellszMisc.winfo_screencells1ww~~ GGLL- 9; ;rc|jj|jjdd|jS)z\Return the number of bits per pixel of the root window of the screen of this widget.r screendepthrrMs r winfo_screendepthzMisc.winfo_screendepthrbrc|jj|jjdd|jS)zXReturn the number of pixels of the height of the screen of this widget in pixel.r screenheightrrMs r winfo_screenheightzMisc.winfo_screenheights1ww~~ GGLL.$'' :<  >rc|jj|jjdd|jS)zTReturn the number of pixels of the width of the screen of this widget in mm.r screenmmwidthrrMs r winfo_screenmmwidthzMisc.winfo_screenmmwidths1ww~~ GGLL/477 ;= =rcP|jjdd|jS)zReturn one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the default colormodel of this screen.r screenvisualrurMs r winfo_screenvisualzMisc.winfo_screenvisualsww||G^TWW==rc|jj|jjdd|jS)zWReturn the number of pixels of the width of the screen of this widget in pixel.r screenwidthrrMs r winfo_screenwidthzMisc.winfo_screenwidthrbrcP|jjdd|jS)zxReturn information of the X-Server of the screen of this widget in the form "XmajorRminor vendor vendorVersion".rserverrurMs r winfo_serverzMisc.winfo_serversww||GXtww77rcn|j|jjdd|jS)z*Return the toplevel widget of this widget.rtoplevel)rr<r rvrMs r winfo_toplevelzMisc.winfo_toplevel s/!!$'',, Z#*+ +rc|jj|jjdd|jS)zBReturn true if the widget and all its higher ancestors are mapped.rviewablerrMs r winfo_viewablezMisc.winfo_viewabler0rcP|jjdd|jS)zReturn one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the colormodel of this widget.rvisualrurMs r winfo_visualzMisc.winfo_visualsww||GXtww77rcP|jjdd|jS)z7Return the X identifier for the visual for this widget.rvisualidrurMs r winfo_visualidzMisc.winfo_visualidr%rc.|jjdd|j|rdnd}|jj|Dcgc]}|jj|}}|Dcgc]}|j |c}Scc}wcc}w)zReturn a list of all visuals available for the screen of this widget. Each item in the list consists of a visual name (see winfo_visual), a depth and if includeids is true is given also the X identifier.rvisualsavailable includeidsN)r<r rvr8_Misc__winfo_parseitem)rNrrrs r winfo_visualsavailablezMisc.winfo_visualsavailables ww||G%7,6LDB.2gg.?.?.EF.E!!!$.EF3784a&&q)488G8s "B 2Bc R|ddtt|j|ddzS)rNr)rr _Misc__winfo_getint)rNr?s r __winfo_parseitemzMisc.__winfo_parseitem(s+!uuS!4!4ae<===rct|dS)rr)r[r>s r __winfo_getintzMisc.__winfo_getint,s1ayrc|jj|jjdd|jS)zReturn the height of the virtual root window associated with this widget in pixels. If there is no virtual root window return the height of the screen.r vrootheightrrMs r winfo_vrootheightzMisc.winfo_vrootheight0s1ww~~ GGLL- 9; ;rc|jj|jjdd|jS)zReturn the width of the virtual root window associated with this widget in pixel. If there is no virtual root window return the width of the screen.r vrootwidthrrMs r winfo_vrootwidthzMisc.winfo_vrootwidth7s1ww~~ GGLL, 8: :rc|jj|jjdd|jS)ziReturn the x offset of the virtual root relative to the root window of the screen of this widget.rvrootxrrMs r winfo_vrootxzMisc.winfo_vrootx>1ww~~ GGLL(DGG 46 6rc|jj|jjdd|jS)ziReturn the y offset of the virtual root relative to the root window of the screen of this widget.rvrootyrrMs r winfo_vrootyzMisc.winfo_vrootyDrrc|jj|jjdd|jS)z Return the width of this widget.rrrrMs r winfo_widthzMisc.winfo_widthJrrc|jj|jjdd|jS)zVReturn the x coordinate of the upper left corner of this widget in the parent.rrrrMs r winfo_xz Misc.winfo_xO1ww~~ GGLL#tww /1 1rc|jj|jjdd|jS)zVReturn the y coordinate of the upper left corner of this widget in the parent.rrrrMs r winfo_yz Misc.winfo_yUrrc:|jjdy)zEEnter event loop until all pending events have been processed by Tcl.r)NrjrMs r r)z Misc.update[s  Xrc<|jjddy)zEnter event loop until all idle callbacks have been called. This will update the display of windows but not process events caused by the user.r) idletasksNrjrMs r update_idletaskszMisc.update_idletasks_s  X{+rc|?|jj|jjd|jS|jjd|j|y)a,Set or get the list of bindtags for this widget. With no argument return the list of all bindtags associated with this widget. With a list of strings as argument the bindtags are set to this list. The bindtags determine in which order events are processed (see bind).Nbindtagsr<r8r rv)rNtagLists r rz Misc.bindtagsesP ?77$$ Z13 3 GGLLTWWg 6rct|tr!|jj|||fzy|r\|j ||j |}|xrdxsdd|d|j d}|jj|||fz|S|r|jj||fzS|jj|jj|S)r+rif {"[rz]" == "break"} break N)rrr<r r' _substitute_subst_format_strr8)rNrsequencerr* needcleanupfuncidrs r _bindz Misc._bindrs dC GGLL4 00 1 ^^D$*:*:#%FKC%2%..0C GGLL3/ 0M 77<<{ 23 377$$TWW\\$%78 8rcB|jd|jf|||S)aOBind to this widget at event SEQUENCE a call to function FUNC. SEQUENCE is a string of concatenated event patterns. An event pattern is of the form where MODIFIER is one of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, B3, Alt, Button4, B4, Double, Button5, B5 Triple, Mod1, M1. TYPE is one of Activate, Enter, Map, ButtonPress, Button, Expose, Motion, ButtonRelease FocusIn, MouseWheel, Circulate, FocusOut, Property, Colormap, Gravity Reparent, Configure, KeyPress, Key, Unmap, Deactivate, KeyRelease Visibility, Destroy, Leave and DETAIL is the button number for ButtonPress, ButtonRelease and DETAIL is the Keysym for KeyPress and KeyRelease. Examples are for pressing Control and mouse button 1 or for pressing A and the Alt key (KeyPress can be omitted). An event pattern can also be a virtual event of the form <> where AString can be arbitrary. This event can be generated by event_generate. If events are concatenated they must appear shortly after each other. FUNC will be called if the event sequence occurs with an instance of Event as argument. If the return value of FUNC is "break" no further bound function is invoked. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. Bind will return an identifier to allow deletion of the bound function with unbind without memory leak. If FUNC or SEQUENCE is omitted the bound function or list of bound events are returned.bindrrvrNrrr*s r rz Misc.binds#Nzz6477+XtSAArcB|jd|j|f|y)aUnbind for this widget the event SEQUENCE. If FUNCID is given, only unbind the function identified with FUNCID and also delete the corresponding Tcl command. Otherwise destroy the current binding for SEQUENCE, leaving SEQUENCE unbound. rN_unbindrv)rNrrs r unbindz Misc.unbinds fdggx0&9rc^||jjg|dy|jj|jd}d|ddjfd|D}|j sd}|jjg|||j |y)Nrrrrc3DK|]}|js|ywr) startswith)rlineprefixs r rzMisc._unbind..s#=ed$(OOF$;"es )r<r splitrstripr)rNrrlineskeeprs @r rz Misc._unbinds > DGGLL #$ # #GGLL&,,T2Evha(F99=e==D::< DGGLL %$ % %   v &rcH|jjd|||dS)aBind to all widgets at an event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.)rallTrrrs r bind_allz Misc.bind_alls# zz|!!/8T3MMrcH|jjdd|fy)z8Unbind for all widgets for event SEQUENCE all functions.rrNrr)rNrs r unbind_allzMisc.unbind_alls feX67rcL|jjd|f|||dS)a=Bind to widgets with bindtag CLASSNAME at event SEQUENCE a call of function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.rTr)rNrrrr*s r bind_classzMisc.bind_classs(zz|!!69"5xsDQQrcH|jjd||fy)zWUnbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.rNr)rNrrs r unbind_classzMisc.unbind_classs fi:;rc:|jj|y)zCall the mainloop of Tk.N)r<r^)rNrs r r^z Misc.mainloops rc8|jjy)z8Quit the Tcl interpreter. All widgets will be destroyed.N)r<quitrMs r rz Misc.quits  rc|rBtt|jj|jj |Syr)rr r<rQr8rNrs r rFz Misc._getintss3 TWW^^TWW->->v-FGH H rc|rBtt|jj|jj |Syr)rr r<rRr8rs r _getdoubleszMisc._getdoubless5 TWW..0A0A&0IJK K rc>|r|jj|Syr)r<r rs r _getbooleanzMisc._getbooleans 77%%f- - rc0|rd|fS|d|jfSy)rrr!rvrs r rzMisc._displayofs(  ), ,   $''* *rc |jjS#t$r6|jj ddx}|j_|cYSwxYw)rr<windowingsystem)r_windowingsystem_cachedr*r<r )rNwss r rzMisc._windowingsystemsR ::<77 7  T+<= >B5I s.getint_event]s+ ay )  s  r)r _subst_formatr<r rQrrLrrrrrrtimerrrrrr keysym_numr`r(rrwidgetrx_rooty_rootr)rNrnr rnsignrWr%hr2rr?rrrAEKNWTXYDerQs @r rzMisc._substituteWs t9D../ /WW''  GKCq!Q1aAq!Q1aAq! G%=Q!!}QW? O q/aq/1o1o&qMQ\#A  q\AF ))!,AH ?? QiAGt 7  AF  AH  H% AGt  sZ E3? F!F2F'# F=3 E?>E? F FF$#F$'F:9F:=GGcztj\}}}|j}|j|||yr)sysexc_inforreport_callback_exception)rNrvaltbrs r _report_exceptionzMisc._report_exceptions0||~ S"zz| &&sC4rci}|jj|jj|D]5}|jj|}|dddf|ddz||ddd<7|S)z;Call Tcl configure command and return the result as a dict.rrNr<r8r )rNrnr/rs r _getconfigurezMisc._getconfigurest""<477<<#67A!!!$AqT!"XK!AB%/C!QRM8 rc|jj|jj|}|dddf|ddzS)NrrrrNrnrs r _getconfigure1zMisc._getconfigure1sB GG  ldggllD1 2!QR{QqrU""rc|rt||f}n |r t|}|&|jt|j|fSt |t r*|j t|j|d|zfS|jjt|j|f|j|zy)rNr7) r4rr"rvrrr r<r r)rNrr/ros r _configurezMisc._configures S"I&C C.C ;%%h~&>? ? c3 &&x#s3w0G'HI I  Xtwwn- c0BBCrc (|jd||S)zConfigure resources of a widget. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method keys. configurer rNr/ros r rzMisc.configures{C44rcV|jj|jdd|zS)z4Return the resource value for a KEY given as string.cgetr7rurNrAs r rz Misc.cgets!ww||DGGVS3Y77rc*|j||iyr)rrNrAr s r __setitem__zMisc.__setitem__s U|$rc|jj}||jj|jdDcgc]}||dddc}Scc}w)z3Return a list of all resource names of this widget.rrrNr)rNr8rs r rz Misc.keyss]GG%% $'',,tww <=?=)* ! Q#=? ??sAc|jS)z+Return the window path name of this widget.rrMs r rOz Misc.__str__s wwrc~d|jjd|jjd|jdS)NrrGz object r)rBrQrRrvrMs r rz Misc.__repr__s- NN % %t~~'B'BDGGM Mr_noarg_c|tjur6|j|jj dd|j S|jj dd|j |y)aSet or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given the current setting will be returned. pack propagateNrarrr<r rvrNflags r pack_propagatezMisc.pack_propagateY 4<< ##DGGLL TWW%./ / GGLLdggt s r pack_slaveszMisc.pack_slavess_!!77<<$'':<=<+,""1%<= ==Ac|jj|jjdd|jDcgc]}|j |c}Scc}w)r$placer%r&r>s r place_slaveszMisc.place_slavessb!!77<<$''3454+,""1%45 55r(cT|jjdd|j|y)zThe anchor value controls how to place the grid within the master when no row/column has any weight. The default anchor is nw.gridanchorNru)rNr.s r grid_anchorzMisc.grid_anchors  VXtww7rcdd|jf}| ||||fz}| ||||fz}|j|jj|xsdS)aReturn a tuple of integer coordinates for the bounding box of this widget controlled by the geometry manager grid. If COLUMN, ROW is given the bounding box applies from the cell with row and column 0 to the specified cell. If COL2 and ROW2 are given the bounding box starts at that cell. The returned integers specify the offset of the upper left corner in the master widget and the width and height. r-bboxN)rvrFr<r )rNcolumnrowcol2row2rns r grid_bboxzMisc.grid_bboxsh(  #/63-'D   04,&D}}\TWW\\4019T9rct|ttjfrI t|}|syd|vr|jj |S|jj |S|S#ttf$rY|SwxYw)NrG) rr_tkinterTcl_Objr<rRrQrr)rNr svalues r _gridconvvaluezMisc._gridconvvalues ec8#3#34 5 UF]77,,V4477>>&11 )   s A,A,A,,A?>A?c t|tr |s|dddk(r|dd}|dddk7rd|z}|f}n|j||}|sHt|j|jj d||j ||jS|jj d||j |f|z}t|dk(r|j|Sy)rrNrrr7r-)r>) rrrrBr<r rvr;r)rNrindexr/rooptionsr$s r _grid_configurezMisc._grid_configure's c3 23x3#2h2Aw#~#gfGmmC,G VWdggu=((* *ggll7DGGU3 w<1 &&s+ + rc *|jd|||S)zConfigure column INDEX of a grid. Valid resources are minsize (minimum size of the column), weight (how much does additional space propagate to this column) and pad (how much space to let additionally).columnconfigurer?rNr=r/ros r grid_columnconfigurezMisc.grid_columnconfigure<s ##$5uc2FFrc z|j|jjdd|j||xsdS)zReturn a tuple of column and row which identify the cell at which the pixel at position X and Y inside the master widget is located.r-locationNrErNrrs r grid_locationzMisc.grid_locationFs<}} GGLL DGGQ 34<7; >) to an event SEQUENCE such that the virtual event is triggered whenever SEQUENCE occurs.eventr*NrjrNvirtual sequencesrns r event_addzMisc.event_add{s%(94  TrcJdd|f|z}|jj|y)z-Unbind a virtual event VIRTUAL from SEQUENCE.rTdeleteNrjrUs r event_deletezMisc.event_deletes#7+i7  Trc dd|j|f}|jD]\}}|d|zt|fz}|jj |y)zGenerate an event SEQUENCE. Additional keyword arguments specify parameter of the event (e.g. x, y, rootx, rooty).rTgenerate-%sN)rvr-rr<r )rNrrornr2r3s r event_generatezMisc.event_generatesQTWWh7HHJDAq519c!f--D  Trcn|jj|jjdd|S)zuReturn a list of all virtual events or the information about the SEQUENCE bound to the virtual event VIRTUAL.rTrr)rNrVs r event_infozMisc.event_infos/ww  GGLL&' 24 4rcl|jj|jjddS)z*Return a list of all existing image names.imagenamesrrMs r image_nameszMisc.image_names&ww  gw!?@@rcl|jj|jjddS)z?Return a list of all available image types (e.g. photo bitmap).rctypesrrMs r image_typeszMisc.image_typesrfrr)r)r1rF)rrE)NrNNNNNN)rPrQrRr_last_child_idsrrrrerirlrrwaitvarrxr{r}rrQrRr rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrliftrrrrr r rrrrr!r$r'r)r,r/r3r5r8r<r?rBrGrJrMrPrTrWr[r^rarerhrkrnrqrtrwrzr}rrrrrrrrrrrrr)rrrrrrrrrrr^rrFrrrpropertyrrrrr'registerrrrrrrrr r rconfigr __getitem__rrrOrrr!rr'r%r+r/r.r6r1r;r?rDrArHrJrMrLrPrOrRrXr[r_rarerir!rr rarasE OL%/" =1 G48$$' ' A' E1 (((- (( 38/,"= F.A (1-8@( G?A F$! 1 (:22 D* 2 " 5 7< (G6 2 :6 <5 8 968"> 8 9 8 9 8 : 5 5 8; ; < > = > ; 8 + 8 8 : 9>;:6 6 5 1 1 , 79$'BR : 'N8R< I L . 4"!M,H CM/;z5 # D5F8K%? M kG") =I=F58F:& D ,*/1G+O<#* =,.D%L; D 9 4AArraceZdZdZdZdZy)rzwInternal class. Stores function to call when some user defined Tcl function is called e.g. after an event occurred.c.||_||_||_y)z(Store FUNC, SUBST and WIDGET as members.N)rrr)rNrrrs r r zCallWrapper.__init__s   rc |jr|j|}|j|S#t$r|jj YyxYw)z3Apply first function SUBST to arguments, than FUNC.N)rrrrrrNrns r r zCallWrapper.__call__sQ ,zz!tzz4(499d# #   , KK ) ) +s ),%ANrPrQrRrr r r!rr rrsD ,rrc"eZdZdZdZdZdZy)XViewzXMix-in class for querying and changing the horizontal position of a widget's window.cz|jj|jdg|}|s|j|Sy)z5Query and change the horizontal position of the view.xviewNr<r rvrrNrnr$s r r~z XView.xview:dggll477G3d3##C( (rcT|jj|jdd|y)zsAdjusts the view in the window so that FRACTION of the total width of the canvas is off-screen to the left.r~movetoNrurNfractions r xview_movetozXView.xview_moveto  TWWgx:rcV|jj|jdd||y)z\Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).r~scrollNrurNr rs r xview_scrollzXView.xview_scroll   TWWgx>rN)rPrQrRrr~rrr!rr r|r|) ; ?rr|c"eZdZdZdZdZdZy)YViewzVMix-in class for querying and changing the vertical position of a widget's window.cz|jj|jdg|}|s|j|Sy)z3Query and change the vertical position of the view.yviewNrrs r rz YView.yviewrrcT|jj|jdd|y)zsAdjusts the view in the window so that FRACTION of the total height of the canvas is off-screen to the top.rrNrurs r yview_movetozYView.yview_movetorrcV|jj|jdd||y)z\Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).rrNrurs r yview_scrollzYView.yview_scrollrrN)rPrQrRrrrrr!rr rrrrrc|eZdZdZ d"dZeZdZeZd#dZeZ dZ e Z d#dZ e Z dZeZd#d ZeZd ZeZd ZeZd#d ZeZ d"d ZeZd#dZeZd$dZeZdZeZd#dZ e Z!d#dZ"e"Z#d%dZ$e$Z%d$dZ&e&Z'd#dZ(e(Z)dZ*e*Z+d$dZ,e,Z-d$dZ.e.Z/d#dZ0e0Z1d#dZ2e2Z3d$dZ4e4Z5d$dZ6e6Z7d#dZ8e8Z9d#dZ:e:Z;d#dZe>Z?d!Z@e@ZAy)&WmzAProvides functions for the communication with the window manager.Nc v|j|jjdd|j||||S)zInstruct the window manager to set the aspect ratio (width/height) of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple of the actual values if no argument is given.wmaspectrE)rNminNumerminDenommaxNumermaxDenoms r wm_aspectz Wm.wm_aspects9 }} GGLLxxx )* *rc\dd|jf|z}|jj|S)aThis subcommand returns or sets platform specific attributes The first form returns a list of the platform specific flags and their values. The second form returns the value for the specific option. The third form sets one or more of the values. The values are as follows: On Windows, -disabled gets or sets whether the window is in a disabled state. -toolwindow gets or sets the style of the window to toolwindow (as defined in the MSDN). -topmost gets or sets whether this is a topmost window (displays above all other windows). On Macintosh, XXXXX On Unix, there are currently no special attribute values. r attributes)rvr<r rys r wm_attributeszWm.wm_attributess,$lDGG,t3ww||D!!rcR|jjdd|j|S)zVStore NAME in WM_CLIENT_MACHINE property of this widget. Return current value.rclientrurs r wm_clientz Wm.wm_clients!ww||D(DGGT::rc0t|dkDr|f}dd|jf|z}|r|jj|y|jj |jj|Dcgc]}|j |c}Scc}w)zStore list of window names (WLIST) into WM_COLORMAPWINDOWS property of this widget. This list contains windows whose colormaps differ from their parents. Return current list of widgets if WLIST is empty.rrcolormapwindowsN)rrvr<r r8r)rNwlistrnrs r wm_colormapwindowszWm.wm_colormapwindowss u:>HE'1E9  GGLL "WW..tww||D/ABDB&&q)BD DDs8BcR|jjdd|j|S)zStore VALUE in WM_COMMAND property. It is the command which shall be used to invoke the application. Return current command if VALUE is None.rrrurs r wm_commandz Wm.wm_commands!ww||D)TWWe<|jjdd|y)aAThe window will be unmapped from the screen and will no longer be managed by wm. toplevel windows will be treated like frame windows once they are no longer managed by wm, however, the menu option configuration will be remembered and the menus will return once the widget is managed again.rforgetNrjrws r wm_forgetz Wm.wm_forget5s  T8V,rcP|jjdd|jS)zAReturn identifier for decorative frame of this widget if present.rframerurMs r wm_framez Wm.wm_frame?sww||D'47733rcR|jjdd|j|S)ziSet geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return current value if None is given.rr#ru)rN newGeometrys r wm_geometryzWm.wm_geometryEs!ww||D*dgg{CCrc v|j|jjdd|j||||S)aInstruct the window manager that this widget shall only be resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the number of grid units requested in Tk_GeometryRequest.rr-rE)rN baseWidth baseHeightwidthInc heightIncs r wm_gridz Wm.wm_gridLs8}}TWW\\ &$'' z8Y89 9rcR|jjdd|j|S)z~Set the group leader widgets for related widgets to PATHNAME. Return the group leader of this widget if None is given.rgrouprurNpathNames r wm_groupz Wm.wm_groupY!ww||D'477H==rc|)|jjdd|jd|S|jjdd|j|S)aSet bitmap for the iconified widget to BITMAP. Return the bitmap if None is given. Under Windows, the DEFAULT parameter can be used to set the icon for the widget and any descendants that don't have an icon set explicitly. DEFAULT can be the relative path to a .ico file (example: root.iconbitmap(default='myicon.ico') ). See Tk documentation for more information.r iconbitmap-defaultru)rNbitmapdefaults r wm_iconbitmapzWm.wm_iconbitmap`sF  77<<lDGGZQ Q77<<lDGGVD DrcP|jjdd|jS)zDisplay widget as icon.riconifyrurMs r wm_iconifyz Wm.wm_iconifypsww||D)TWW55rcR|jjdd|j|S)zVSet mask for the icon bitmap of this widget. Return the mask if None is given.riconmaskru)rNrs r wm_iconmaskzWm.wm_iconmaskvs!ww||D*dggv>>rcR|jjdd|j|S)zSSet the name of the icon for this widget. Return the name if None is given.riconnameru)rNnewNames r wm_iconnamezWm.wm_iconname}s!ww||D*dggw??rc|r+|jjdd|jdg|y|jjdd|jg|y)aSets the titlebar icon for this window based on the named photo images passed through args. If default is True, this is applied to all future created toplevels as well. The data in the images is taken as a snapshot at the time of invocation. If the images are later changed, this is not reflected to the titlebar icons. Multiple images are accepted to allow different images sizes to be provided. The window manager may scale provided icons to an appropriate size. On Windows, the images are packed into a Windows icon structure. This will override an icon specified to wm_iconbitmap, and vice versa. On X, the images are arranged into the _NET_WM_ICON X property, which most modern window managers support. An icon specified by wm_iconbitmap may exist simultaneously. On Macintosh, this currently does nothing.r iconphotorNru)rNrrns r wm_iconphotozWm.wm_iconphotosG(  DGGLL{DGGZ G$ G DGGLL{DGG ;d ;rc r|j|jjdd|j||S)zSet the position of the icon of this widget to X and Y. Return a tuple of the current values of X and X if None is given.r iconpositionrErGs r wm_iconpositionzWm.wm_iconpositions3}}TWW\\ .$''1a12 2rcR|jjdd|j|S)zgSet widget PATHNAME to be displayed instead of icon. Return the current value if None is given.r iconwindowrurs r wm_iconwindowzWm.wm_iconwindows!ww||D,BBrc>|jjdd|y)zThe widget specified will become a stand alone top-level window. The window will be decorated with the window managers title bar, etc.rmanageNrj)rNrs r wm_managez Wm.wm_manages  T8V,rc r|j|jjdd|j||S)zSet max WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.rmaxsizerErNrrs r wm_maxsizez Wm.wm_maxsize3}}TWW\\ )TWWeV56 6rc r|j|jjdd|j||S)zSet min WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.rminsizerErs r wm_minsizez Wm.wm_minsizerrcp|j|jjdd|j|S)zInstruct the window manager to ignore this widget if BOOLEAN is given with 1. Return the current value if None is given.roverrideredirect)rr<r rvrfs r wm_overrideredirectzWm.wm_overrideredirects4 $dggw!89 9rcR|jjdd|j|S)zInstruct the window manager that the position of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".r positionfromrurNwhos r wm_positionfromzWm.wm_positionfroms!ww||D.$''3??rct|r|j|}n|}|jjdd|j||S)zBind function FUNC to command NAME for this widget. Return the function bound to NAME if None is given. NAME could be e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".rprotocol)rr'r<r rv)rNrrrs r wm_protocolzWm.wm_protocolsB D>nnT*GGww|| *dggtW6 6rcT|jjdd|j||S)zyInstruct the window manager whether this width can be resized in WIDTH or HEIGHT. Both values are boolean values.r resizablerurs r wm_resizablezWm.wm_resizables#ww||D+twwvFFrcR|jjdd|j|S)zInstruct the window manager that the size of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".rsizefromrurs r wm_sizefromzWm.wm_sizefroms!ww||D*dggs;;rcR|jjdd|j|S)zQuery or set the state of this widget as one of normal, icon, iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).rrru)rNnewstates r wm_statez Wm.wm_staterrcR|jjdd|j|S)zSet the title of this widget.rtitlerurs r wm_titlez Wm.wm_titlesww||D'477F;;rcR|jjdd|j|S)z_Instruct the window manager that this widget is transient with regard to widget MASTER.r transientru)rNrs r wm_transientzWm.wm_transient s!ww||D+tww??rcP|jjdd|jS)zWithdraw this widget from the screen such that it is unmapped and forgotten by the window manager. Re-draw it with wm_deiconify.rrrurMs r wm_withdrawzWm.wm_withdraw sww||D*dgg66rrmrrnrl)BrPrQrRrrrrrrrrrrrrrrrrrrrrr#rr-rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr!rr rrsK'+&* *F"*J; F D)O= G8 I@ J-F4 ED H%)"& 9 D> E EJ6G? H@ H<2I2 #LC J- F6G6G9+@ #L 6HG I< H> E< E@ I7 HrrcDeZdZdZdZ d dZdZdZdZdZ d Z d Z y) rzzToplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.rGNc d|_i|_d|_d|_|Wddl}|j j tjd}|j j|\}}|dvr||z}d} tj|||| t||||_tr|jjt|r|j!tj"j$s|j'||yy)aAReturn a new top level widget on screen SCREENNAME. A new Tcl interpreter will be created. BASENAME will be used for the identification of the profile file (see readprofile). It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME is the name of the widget class.NFr)z.pyz.pyc)rr _tkloadedr<ospathbasenamerargvsplitextr8create wantobjects_debugsettrace_print_command_loadtkflagsignore_environment readprofile) rN screenNamebaseNameruseTksyncuser ext interactives r r z Tk.__init__ s     ww'' 4HGG,,X6MHc/)#c> //*h ;P[]bdhjmn  GG  ^ ,  LLNyy++   Xy 1,rcr|js+|jj|jyyr)r r<loadtkrrMs r r!z Tk.loadtk3 s%~~ GGNN  LLNrcd|_|jjd}|tjk7r t dtjd|dt |jjd}|tjk7r t dtjd|d|jg|_|jjd t|jjd t|jjd |jjd trt|a|jd |j y) NT tk_versionztk.h version (z!) doesn't match libtk.a version () tcl_versionztcl.h version (z") doesn't match libtcl.a version (tkerrorexitWM_DELETE_WINDOW)r r<rr8 TK_VERSIONr9r TCL_VERSIONrr#rrrrrrr)rNr#r%s r rz Tk._loadtk8 sWW^^L1 ,, ,"*"5"5z CD D$''..78 (.. ."*"6"6  EF F    $ "D  i2 fe,   +   ( ]%: M ($,,7rct|jjD]}|j|jj d|j tj|tr t|urda yyy)zhDestroy this and all descendants widgets. This will end the application of this Tcl interpreter.rN) rrvaluesrr<r rvrarrrNr0s r rz Tk.destroyR s_dmm**,-Aqyy{-  Y( T ]d%: M&; rcNddl}d|jvr|jd}n |j}|jj |d|z}|jj |d|z}|jj |d|z}|jj |d|z}d|i} t d| |jj |r|jjd||jj |r#t t|j| |jj |r|jjd||jj |r$t t|j| yy) zInternal function. It reads .BASENAME.tcl and .CLASSNAME.tcl into the Tcl Interpreter and calls exec on the contents of .BASENAME.py and .CLASSNAME.py if such a file exists in the home directory.rNHOMEz.%s.tclz.%s.pyrNzfrom tkinter import *source) r environcurdirr rexecisfiler<r openread) rNrrr home class_tclclass_pybase_tclbase_pydirs r rzTk.readprofile\ s8  RZZ  6(:YYdGGLLy9'<= 77<<h&:;77<<i(&:;'',,tX%89tn $c* 77>>) $ GGLL9 - 77>>( # h$$& , 77>>( # GGLL8 , 77>>' " g##%s + #rcddl}tdtj|t_|t_|t_|t_|j|||y)zReport callback exception on sys.stderr. Applications may want to override this internal function, and should when sys.stderr is None.rNzException in Tkinter callbackfile) tracebackr,rstderrlast_exc last_type last_valuelast_tracebackprint_exception)rNrrrr@s r rzTk.report_callback_exceptionr sE  -CJJ?  !!#sB/rc.t|j|S)z3Delegate attribute access to the interpreter object)rr<)rNattrs r __getattr__zTk.__getattr__ stww%%r)NNrTFN) rPrQrRrrvr r!rrrrrIr!rr rr s6@ BAE-12: 84!,, 0&rrr>c4t|}t||y)Nr>)rr,)rr?s r rr s *C #Drct||||Sr)r)rrrrs r TclrL s j(Iu 55rcreZdZdZifdZexZxZZdZeZ dZ e Z e jxZZ e jxZZy)PackzQGeometry manager Pack. Base class to use the methods pack_* in every widget.c z|jjdd|jf|j||zy)a(Pack a widget in the parent widget. Use as options: after=widget - pack it after you have packed widget anchor=NSEW (or subset) - position widget according to given direction before=widget - pack it before you will pack widget expand=bool - expand widget if parent size grows fill=NONE or X or Y or BOTH - fill widget if widget grows in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. rrNr<r rvrrs r pack_configurezPack.pack_configure s5  {DGG, c2&' (rcR|jjdd|jy)z:Unmap this widget and do not use it for the packing order.rrNrurMs r pack_forgetzPack.pack_forget   VXtww/rct|j|jjdd|j}d|vr|j |d|d<|S)zEReturn information about the packing options for this widget.rrinrBr<r rvrrNds r pack_infozPack.pack_info M tww VVTWW E F 19''$0AdGrN)rPrQrRrrQrrrtrSrrZrrar!rr'r%r!rr rNrN sZ="$((!/.D.9v0F D!%!4!44I+++F[rrNcVeZdZdZifdZexZxZZdZeZ dZ e Z e jxZZ y)PlacezSGeometry manager Place. Base class to use the methods place_* in every widget.c z|jjdd|jf|j||zy)a Place a widget in the parent widget. Use as options: in=master - master relative to which the widget is placed in_=master - see 'in' option description x=amount - locate anchor of this widget at position x of master y=amount - locate anchor of this widget at position y of master relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge) rely=amount - locate anchor of this widget between 0.0 and 1.0 relative to height of master (1.0 is bottom edge) anchor=NSEW (or subset) - position anchor according to given direction width=amount - width of this widget in pixel height=amount - height of this widget in pixel relwidth=amount - width of this widget between 0.0 and 1.0 relative to width of master (1.0 is the same width as the master) relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master) bordermode="inside" or "outside" - whether to take border width of master widget into account r*rNrPrs r place_configurezPlace.place_configure s5,   TWW- c2&' (rcR|jjdd|jy)Unmap this widget.r*rNrurMs r place_forgetzPlace.place_forget s  Wh0rct|j|jjdd|j}d|vr|j |d|d<|S)zEReturn information about the placing options for this widget.r*rrVrWrXs r place_infozPlace.place_info sM tww Wfdgg F G 19''$0AdGrN)rPrQrRrr_r*rrtrbrrdrrar+r%r!rr r]r] sJ>#%(4"10E0I1F D ---F\rr]ceZdZdZifdZexZxZZejxZ Z ejxZ Z dZ e ZdZdZeZej$xZZej(xZZej,xZZej0xZZej4xZZy)GridzQGeometry manager Grid. Base class to use the methods grid_* in every widget.c z|jjdd|jf|j||zy)aPosition a widget in the parent widget in a grid. Use as options: column=number - use cell identified with given column (starting with 0) columnspan=number - this widget will span several columns in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction row=number - use cell identified with given row (starting with 0) rowspan=number - this widget will span several rows sticky=NSEW - if cell is larger on which sides will this widget stick to the cell boundary r-rNrPrs r grid_configurezGrid.grid_configure s5  {DGG, c2&' (rcR|jjdd|jy)rar-rNrurMs r grid_forgetzGrid.grid_forget rTrcR|jjdd|jy)z0Unmap this widget but remember the grid options.r-r1NrurMs r grid_removezGrid.grid_remove" rTrct|j|jjdd|j}d|vr|j |d|d<|S)zSReturn information about the options for positioning this widget in a grid.r-rrVrWrXs r grid_infozGrid.grid_info& r[rN)rPrQrRrrhr-rrtrar6r1rDrArjrrlrnrrHrFrJrrMrLrPrOrRr%r!rr rfrf s= "$(&!/.D.9v~~%D9-1-F-FFO*0F0 D#111H}!%!4!44I'+'='==L$~~%D9+++F[rrfc2eZdZdZdZiidfdZdZddZy) BaseWidgetzInternal class.c| t}||_|j|_d}d|vr|d}|d=|s|jjj }|dj r|dz }|ji|_|jj|ddz}||j|<|dk(rd|}nd||fz}||_ |jdk(r d|z|_ n|jdz|z|_ i|_ |j|jjvr1|jj|jj||jj|j<y) z6Internal function. Sets up information about children.Nrr!rrz!%s%drG) rrr<rBrPrisdigitrorrrvrr)rNrr/rcounts r _setupzBaseWidget._setup9 sS >&(F )) S=v;DF >>**002DBx! %%-)+&**..tQ7!;E+0F " "4 (z $$. 99c>DjDGii#o,DG ::-- - KK  , 4 4 6+/ TZZ(rr!c|r t||f}||_|j|||jg|_|j Dcgc]\}}t |t s||f}}}|D]\}}||= |jj||jf|z|j|z|D]\}}|j||ycc}}w)zdConstruct a widget with the parent widget MASTER, a name WIDGETNAME and appropriate options.N) r4 widgetNamerurr-rr(r<r rvrr) rNrrwr/roextrar2r3classess r r zBaseWidget.__init__Y s S"I&C$ FC    $ "D &)iikIkdaZ45HAq6kIDAqA   !E )DMM#,> > @DAq KKa  Js C(Ccpt|jjD]}|j|jj d|j |j|jjvr!|jj|j=tj|y)z)Destroy this and all descendants widgets.rN) rrr,rr<r rvrrrar-s r rzBaseWidget.destroyj srdmm**,-Aqyy{-  Y( ::-- - $$TZZ0 TrcV|jj|j|f|zSrru)rNrrns r _dozBaseWidget._dor s"ww||TWWdOd233rN)r!)rPrQrRrrur rr|r!rr rprp6 s#0@02b!"4rrpceZdZdZy)WidgetzxInternal class. Base class for a widget which can be positioned with the geometry managers Pack, Place or Grid.N)rPrQrRrr!rr r~r~w s  rr~ceZdZdZdifdZy)Toplevelz"Toplevel widget, e.g. for dialogs.Nc |r t||f}d}dD],}||vs||}|ddk(r d|ddz}nd|z}|||fz}||=.tj||d|i||j}|j |j |j |j |j d|jy) a%Construct a toplevel widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, menu, relief, screen, takefocus, use, visual, width.r!)r]class_r rcolormaprrr7Nryr()r4rpr rrrrr) rNrr/rorxwmkeyroptrs r r zToplevel.__init__ s S"I&CE|%j9#3uSbz>SIcc *J D&*c2uEzz| dmmo& 4::<  ($,,7rrPrQrRrr r!rr rr s,"8rrc(eZdZdZdifdZdZdZy)rzButton widget.Nc 6tj||d||y)aUConstruct a button widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, repeatdelay, repeatinterval, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS command, compound, default, height, overrelief, state, width buttonNr~r rNrr/ros r r zButton.__init__ s& fhR8rcP|jj|jdy)a_Flash the button. This is accomplished by redisplaying the button several times, alternating between active and normal colors. At the end of the flash the button is left in the same normal/active state as when the command was invoked. This command is ignored if the button's state is disabled. flashNrurMs r rz Button.flash s  TWWg&rcN|jj|jdS)aInvoke the command associated with the button. The return value is the return value from the command, or an empty string if there is no command associated with the button. This command is ignored if the button's state is disabled. invokerurMs r rz Button.invoke sww||DGGX..r)rPrQrRrr rrr!rr rr s"9* '/rrceZdZdZdifdZdZdZdZdZddZd=dZd=dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ d Z!d!Z"d"Z#dd:Z?d;Z@y)ACanvasz?Canvas widget to display graphical elements like lines or text.Nc 6tj||d||y)aConstruct a canvas widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, closeenough, confine, cursor, height, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, offset, relief, scrollregion, selectbackground, selectborderwidth, selectforeground, state, takefocus, width, xscrollcommand, xscrollincrement, yscrollcommand, yscrollincrement.canvasNrrs r r zCanvas.__init__ s fhR8rcX|jj|jdf|zy)raddtagNrurys r rz Canvas.addtag   dggx(4/0rc*|j|d|y)z*Add tag NEWTAG to all items above TAGORID.aboveNrrNnewtagtagOrIds r addtag_abovezCanvas.addtag_above  FGW-rc(|j|dy)zAdd tag NEWTAG to all items.rNr)rNrs r addtag_allzCanvas.addtag_all s FE"rc*|j|d|y)z*Add tag NEWTAG to all items below TAGORID.belowNrrs r addtag_belowzCanvas.addtag_below rrc0|j|d||||y)zAdd tag NEWTAG to item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.closestNr)rNrrrhalostarts r addtag_closestzCanvas.addtag_closest s FIq!T59rc0|j|d||||y)zLAdd tag NEWTAG to all items in the rectangle defined by X1,Y1,X2,Y2.enclosedNrrNrx1y1x2y2s r addtag_enclosedzCanvas.addtag_enclosed s FJBB7rc0|j|d||||y)zWAdd tag NEWTAG to all items which overlap the rectangle defined by X1,Y1,X2,Y2. overlappingNrrs r addtag_overlappingzCanvas.addtag_overlapping s FM2r2r:rc*|j|d|y)z)Add tag NEWTAG to all items with TAGORID.withtagNrrs r addtag_withtagzCanvas.addtag_withtag s FIw/rc||j|jj|jdf|zxsdS)z|Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses all items with tags specified as arguments.r1NrErys r r1z Canvas.bbox s;}} GGLL$''6*T1 24<7; =*+!!!$=> >>s"A6c t|}|d}t|ttfr|dd}ni}|jj |jj |jd|g||j||zS)rrNr) r"rr'rr<rQr rvr)rNitemTypernror/s r _createzCanvas._create' s{~2h cD%= )9DCww~~ldggll GGXx.T]]3++./ /rc(|jd||S)z6Create arc shaped region with coordinates x1,y1,x2,y2.arcrrms r create_arczCanvas.create_arc3 s||E4,,rc(|jd||S)z%Create bitmap with coordinates x1,y1.rrrms r create_bitmapzCanvas.create_bitmap7 ||HdB//rc(|jd||S)z)Create image item with coordinates x1,y1.rcrrms r create_imagezCanvas.create_image; s||GT2..rc(|jd||S)z-Create line with coordinates x1,y1,...,xn,yn.rrrms r create_linezCanvas.create_line? ||FD"--rc(|jd||S)z)Create oval with coordinates x1,y1,x2,y2.ovalrrms r create_ovalzCanvas.create_ovalC rrc(|jd||S)z0Create polygon with coordinates x1,y1,...,xn,yn.polygonrrms r create_polygonzCanvas.create_polygonG s||ItR00rc(|jd||S)z.Create rectangle with coordinates x1,y1,x2,y2. rectanglerrms r create_rectanglezCanvas.create_rectangleK s||Kr22rc(|jd||S)z#Create text with coordinates x1,y1.textrrms r create_textzCanvas.create_textO rrc(|jd||S)z+Create window with coordinates x1,y1,x2,y2.rtrrms r create_windowzCanvas.create_windowS rrcX|jj|jdf|zy)zDelete characters of text items identified by tag or id in ARGS (possibly several times) from FIRST to LAST character (including).dcharsNrurys r rz Canvas.dcharsW "  dggx(4/0rcX|jj|jdf|zy)z$>rcV|jj|jdd||y)z=Set the variable end of a selection in item TAGORID to INDEX.r"toNrur$s r select_tozCanvas.select_to s  TWWhgu=rcX|jj|jd|xsdS)z$Return the type of the item TAGORID.r(Nrurs r r(z Canvas.type s"ww||DGGVW5==rrnrrE)rr) )ArPrQrRrr rrrrrrrrr1rrrrrrrrrrrrrrrrrZrrrrrrrrrrrrr=rrr  itemconfigr rrrrrrqrrrr r%r(r+r-r0r(r!rr rr sKI" 91.#.:8 ; 0< C '7 7 > /-0/..13.01 1/ : + +75 8 -77 2 G1 ; DJ 0 E/7 ,0 D704< B1@?>>rrcLeZdZdZdifdZfdZdZdZdZdZ d Z xZ S) Checkbuttonz7Checkbutton widget which is either in on- or off-state.Nc 6tj||d||y)aConstruct a checkbutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, offvalue, onvalue, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, variable, width, wraplength. checkbuttonNrrs r r zCheckbutton.__init__  fmS"=rc|jds<|jjj}tdz ad|dt|d<t |||y)Nrrrrr7)rrBrPr_checkbutton_countsuperru)rNrr/rrBs r ruzCheckbutton._setup s[wwv>>**002D ! # dV1%7$89CK vs#rcP|jj|jdyzPut the button in off-state.deselectNrurMs r r>zCheckbutton.deselect s  TWWj)rcP|jj|jdyzFlash the button.rNrurMs r rzCheckbutton.flash"   TWWg&rcN|jj|jdSzrrr"rI __classcell__)rBs@r r5r5 s.A" > $*'/((rr5ceZdZdZdifdZddZdZdZdZdZ d Z d Z d Z e Z d ZeZd ZeZdZeZdZeZdZeZy)Entryz1Entry widget which allows displaying simple text.Nc 6tj||d||y)aConstruct an entry widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, invalidcommand, invcmd, justify, relief, selectbackground, selectborderwidth, selectforeground, show, state, takefocus, textvariable, validate, validatecommand, vcmd, width, xscrollcommand.entryNrrs r r zEntry.__init__6 s fgsB7rcT|jj|jd||y)z.Delete text from FIRST to LAST (not included).rZNrurNfirstlasts r rZz Entry.deleteC   TWWht4rcN|jj|jdS)zReturn the text.rrurMs r rz Entry.getG ww||DGGU++rcR|jj|jd|y)zInsert cursor at INDEX.rNrurNr=s r rz Entry.icursorK s  TWWi/rc|jj|jj|jd|S)zReturn position of cursor.r=rrWs r r=z Entry.indexO s1ww~~dggll GGWe%& &rcT|jj|jd||y)zInsert STRING at INDEX.rNru)rNr=rs r rz Entry.insertT s  TWWhv6rcT|jj|jdd|yrrur>s r rzEntry.scan_markX s  TWWffa0rcT|jj|jdd|y)zAdjust the view of the canvas to 10 times the difference between X and Y and the coordinates given in scan_mark.rrNrur>s r r zEntry.scan_dragto\ s  TWWfh2rcT|jj|jdd|y)z9Adjust the end of the selection near the cursor to INDEX.rr#NrurWs r selection_adjustzEntry.selection_adjustb   TWWk8U;rcR|jj|jddy)r'rrNrurMs r rzEntry.selection_clearh s  TWWk73rcT|jj|jdd|y)*Set the fixed end of a selection to INDEX.rr*NrurWs r selection_fromzEntry.selection_fromn s  TWWk659rc|jj|jj|jddS)zSReturn True if there are characters selected in the entry, False otherwise.rpresentrrMs r selection_presentzEntry.selection_presentt 3ww!! GGLL+y 9; ;rcV|jj|jdd||y)3Set the selection from START to END (not included).rrangeNrurNrends r selection_rangezEntry.selection_range| s  TWWk7E3?rcT|jj|jdd|y)-Set the variable end of a selection to INDEX.rr/NrurWs r selection_tozEntry.selection_to s  TWWk47rr)rPrQrRrr rZrrr=rrr r]r%rr(rbr+reselect_presentrl select_rangeror0r!rr rLrL3 s{;" 85,0& 713 <%M4#L:!K; 'N@#L8IrrLceZdZdZdifdZy)FramezFFrame widget which may contain other widgets and can have a 3D border.Nc t||f}d}d|vr d|df}|d=nd|vr d|df}|d=tj||d|i|y)aConstruct a frame widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.r!rz-classr rN)r4r~r )rNrr/rorxs r r zFrame.__init__ se b " s?s8}-EH ^s7|,EG fgsB>rrr!rr rsrs sP"?rrsceZdZdZdifdZy)Labelz0Label widget which can display text and bitmaps.Nc 6tj||d||y)aConstruct a label widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground, highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS height, state, width labelNrrs r r zLabel.__init__ s$ fgsB7rrr!rr rvrv s:"8rrvceZdZdZdifdZdZdZdZddZddZ d Z d Z d Z d Z d ZdZdZeZddZeZdZeZddZeZdZdZddZeZy)Listboxz3Listbox widget which can display a list of strings.Nc 6tj||d||y)aConstruct a listbox widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, relief, selectbackground, selectborderwidth, selectforeground, selectmode, setgrid, takefocus, width, xscrollcommand, yscrollcommand, listvariable.listboxNrrs r r zListbox.__init__ s fib9rcR|jj|jd|y)z"Activate item identified by INDEX.activateNrurWs r r~zListbox.activate   TWWj%0rcv|j|jj|jd|xsdS)zxReturn a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the item identified by the given index.r1NrErWs r r1z Listbox.bbox s-}}TWW\\$''65ABJdJrct|j|jj|jdxsdS)z.Return the indices of currently selected item. curselectionr!rErMs r rzListbox.curselection s)}}TWW\\$''>BCIrIrcT|jj|jd||y)z+Delete items from FIRST to LAST (included).rZNrurPs r rZzListbox.delete rSrc|A|jj|jj|jd||S|jj|jd|S)z0Get list of items from FIRST to LAST (included).rrrPs r rz Listbox.get sX  77$$TWW\\t&-. .77<<6 6rc|jj|jd|}|dk(ry|jj|S)z+Return index of item identified with INDEX.r=rNr<r rvrQrNr=rs r r=z Listbox.index s8 GGLL'5 1 ;tww~~a  rcZ|jj|jd|f|zy)zInsert ELEMENTS at INDEX.rNru)rNr=elementss r rzListbox.insert s"  dggx/(:;rc|jj|jj|jd|S)z5Get index of item which is nearest to y coordinate Y.nearestr)rNrs r rzListbox.nearest s1ww~~dggll GGY#$ $rcV|jj|jdd||yrrurGs r rzListbox.scan_mark rrcV|jj|jdd||y)zAdjust the view of the listbox to 10 times the difference between X and Y and the coordinates given in scan_mark.rrNrurGs r r zListbox.scan_dragto   TWWfh15rcR|jj|jd|y)z"Scroll such that INDEX is visible.seeNrurWs r rz Listbox.see   TWWeU+rcT|jj|jdd|y)z-Set the fixed end oft the selection to INDEX.rr.NrurWs r selection_anchorzListbox.selection_anchor r^rcV|jj|jdd||y)z2Clear the selection from FIRST to LAST (included).rrNrurPs r rzListbox.selection_clear s!  TWWgud 4rc|jj|jj|jdd|S)z.Return True if INDEX is part of the selection.rincludesrrWs r selection_includeszListbox.selection_includes s5ww!!$'',, GG[*e#56 6rcV|jj|jdd||y)ziSet the selection from FIRST to LAST (included) without changing the currently selected elements.rrNrurPs r selection_setzListbox.selection_set s   TWWk5%>rc|jj|jj|jdS)z-Return the number of elements in the listbox.rOrrMs r rOz Listbox.size s(ww~~dggll477F;<F!%F!3TZZ5GJ  J$6%* "J z:>2AD,,Q//q)45&&q) 3  TWWh7rcX|jj|jd|d|zS)z=Return the resource value of a menu item for OPTION at INDEX.rr7rurs r rzMenu.entrycget s#ww||DGG[%vFFrc ,|jd|f||S)zConfigure a menu item at INDEX.entryconfigurerrCs r rzMenu.entryconfigure s 0%8#rBBrc|jj|jd|}|dvrdS|jj|S)z4Return the index of a menu item identified by INDEX.r=)rrNrrs r r=z Menu.index s; GGLL'5 1L(t?dggnnQ.??rcP|jj|jd|S)zRInvoke a menu item identified by INDEX and execute the associated command.rrurWs r rz Menu.invoke sww||DGGXu55rcT|jj|jd||y)zDisplay a menu at position X,Y.postNrurGs r rz Menu.post s  TWWfa+rcP|jj|jd|S)z*Return the type of the menu item at INDEX.r(rurWs r r(z Menu.type sww||DGGVU33rcP|jj|jdy)z Unmap a menu.unpostNrurMs r rz Menu.unpost rGrc|jj|jj|jd|S)zNReturn the x-position of the leftmost pixel of the menu item at INDEX. xpositionrrWs r rzMenu.xposition s,ww~~dggll477KGHHrc|jj|jj|jd|S)zEReturn the y-position of the topmost pixel of the menu item at INDEX. ypositionrrWs r rzMenu.yposition s1ww~~dggll GG[%)* *rrr)rPrQrRrr rr~r*rrrrrrrrrrrrZrrrr=rrr(rrrr!rr rr) sZ"771!#) !'#%+!'#%+!#)+-) )+1-/5)+1-/5+-38 GC!K@ 6 ,4(I *rrceZdZdZdifdZy) Menubuttonz(Menubutton widget, obsolete since Tk8.0.Nc 6tj||d||y)N menubuttonrrs r r zMenubutton.__init__ sflCzRadiobutton.deselect s  TWWj)rcP|jj|jdyr@rurMs r rzRadiobutton.flash rArcN|jj|jdSrCrurMs r rzRadiobutton.invoke rDrcP|jj|jdyrFrurMs r r"zRadiobutton.select rGr) rPrQrRrr r>rrr"r!rr rr s#Q" >* '/(rrc6eZdZdZdifdZdZdZddZdZy) Scalez1Scale widget which can display a numerical scale.Nc 6tj||d||y)aConstruct a scale widget with the parent MASTER. Valid resource names: activebackground, background, bigincrement, bd, bg, borderwidth, command, cursor, digits, fg, font, foreground, from, highlightbackground, highlightcolor, highlightthickness, label, length, orient, relief, repeatdelay, repeatinterval, resolution, showvalue, sliderlength, sliderrelief, state, takefocus, tickinterval, to, troughcolor, variable, width.rNrrs r r zScale.__init__ s fgsB7rc|jj|jd} |jj|S#tt t f$r|jj|cYSwxYw)z*Get the current value as integer or float.r)r<r rvrQrr+rrRrs r rz Scale.get s] TWWe, ,77>>%( (Ix0 ,77$$U+ + ,sA/A54A5cR|jj|jd|y)zSet the value to VALUE.rNrurs r rz Scale.set rrcn|j|jj|jd|S)zReturn a tuple (X,Y) of the point along the centerline of the trough that corresponds to VALUE or the current value if None is given.rrErs r rz Scale.coords s( }}TWW\\$''8UCDDrcR|jj|jd||S)zcReturn where the point X,Y lies. Valid return values are "slider", "though1" and "though2".identifyrurGs r rzScale.identify !ww||DGGZA66rr) rPrQrRrr rrrrr!rr rr s$;" 8,,E7rrcBeZdZdZdifdZd dZdZdZdZdZ d Z y) Scrollbarz?Scrollbar widget which displays a slider at a certain position.Nc 6tj||d||y)alConstruct a scrollbar widget with the parent MASTER. Valid resource names: activebackground, activerelief, background, bd, bg, borderwidth, command, cursor, elementborderwidth, highlightbackground, highlightcolor, highlightthickness, jump, orient, relief, repeatdelay, repeatinterval, takefocus, troughcolor, width. scrollbarNrrs r r zScrollbar.__init__s fk3;rcX|jj|jd|xsdS)aMarks the element indicated by index as active. The only index values understood by this method are "arrow1", "slider", or "arrow2". If any other value is specified then no element of the scrollbar will be active. If index is not specified, the method returns the name of the element that is currently active, or None if no element is active.r~NrurWs r r~zScrollbar.activates$ww||DGGZ7?4?rc|jj|jj|jd||S)znReturn the fractional change of the scrollbar setting if it would be moved by DELTAX or DELTAY pixels.rr)rNdeltaxdeltays r rzScrollbar.deltas5ww  GGLL'66 :< 2rrceZdZdZdifdZdZdZdZd8dZd8dZ d Z d9d Z d Z d8d Z d ZdZdZdZd8dZdZd8dZifdZdZdZdZd8dZdZdZdZdZdZifdZdZ d Z!d!Z"d"Z# d:d#Z$d$Z%d%Z&d8d&Z'd8d'Z(d;d(Z)d)Z*d8d*Z+e+Z,d+Z-d8d,Z.d8d-Z/d8d.Z0d8d/Z1d8d0Z2d1Z3d8d2Z4d3Z5d8d4Z6e6Z7ifd5Z8d6Z9d7Z:y)<Textz4Text widget which can display text in various forms.Nc 6tj||d||y)aConstruct a text widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, padx, pady, relief, selectbackground, selectborderwidth, selectforeground, setgrid, takefocus, xscrollcommand, yscrollcommand, WIDGET-SPECIFIC OPTIONS autoseparators, height, maxundo, spacing1, spacing2, spacing3, state, tabs, undo, width, wrap, rNrrs r r z Text.__init__5s. ffc26rcv|j|jj|jd|xsdS)zReturn a tuple of (x,y,width,height) which gives the bounding box of the visible part of the character at the given index.r1NrErWs r r1z Text.bboxNs5}} TWWfe46>9= >rc |jj|jj|jd|||S)zReturn whether between index INDEX1 and index INDEX2 the relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.comparer)rNroprs r rz Text.compareTs9ww!!$'',, GGYF#45 5rc|Dcgc]}d|z }}|||gz }|jj|jdg|xsd}|t|dkr|fS|Scc}w)aCounts the number of relevant things between the two indices. If index1 is after index2, the result will be a negative number (and this holds for each of the possible options). The actual items which are counted depends on the options given by args. The result is a list of integers, one for the result of each counting option given. Valid counting options are "chars", "displaychars", "displayindices", "displaylines", "indices", "lines", "xpixels" and "ypixels". There is an additional possible option "update", which if given then all subsequent options ensure that any possible out of date information is recalculated.r^rtN)r<r rvr)rNrrrnargr$s r rtz Text.countZso(,,t t,   dggll477G3d3;t ?s4yA~7NJ -s Ac|?|jj|jj|jdS|jj|jd|y)zjTurn on the internal consistency checks of the B-Tree inside the text widget according to BOOLEAN.Ndebugrrfs r r z Text.debugnsI ?77%%dggll477G&DE E  TWWgw/rcT|jj|jd||y)z?Delete the characters between INDEX1 and INDEX2 (not included).rZNrurNrrs r rZz Text.deleteus  TWWh7rcn|j|jj|jd|S)zReturn tuple (x,y,width,height,baseline) giving the bounding box and baseline position of the visible part of the line containing the character at INDEX. dlineinforErWs r rzText.dlineinfoys(}}TWW\\$'';FGGrc g}d}d}|s g}|fd}|} t|ts|j|x}}|d|gz }|D]} || s |jd| z|j||r|j||jj |j dg|||r|j|SS#|r|j|wwxYw)aReturn the contents of the widget between index1 and index2. The type of contents returned in filtered based on the keyword parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are given and true, then the corresponding items are returned. The result is a list of triples of the form (key, value, index). If none of the keywords are true then 'all' is used by default. If the 'command' argument is given, it is called once for each element of the list of triples, with the values of each triple serving as the arguments to the function. In this case the list is not returned.Nc,|j|||fyr)r)rAr r=rs r append_triplez Text.dump..append_triples sE512rz-commandr7dump)rrr'rr<r rvr) rNrrrrorn func_namerrrAs r rz Text.dumps  F8> 3#G .gs+&*nnW&== G Z) )Dc7DKKc 2 KK  F# DGGLL& 04 0""9-y""9-s4CA#CCcR|jj|jdg|S)arInternal method This method controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the command are currently supported: edit_modified, edit_redo, edit_reset, edit_separator and edit_undo editrurys r rz Text.edits$tww||DGGV3d33rc&|jd|S)a;Get or Set the modified flag If arg is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to arg. modifiedr)rNr s r edit_modifiedzText.edit_modifiedsyyS))rc$|jdS)a Redo the last undone edit When the undo option is true, reapplies the last undone edits provided no other edits were done since then. Generates an error when the redo stack is empty. Does nothing when the undo option is false. redorrMs r edit_redozText.edit_redosyy  rc$|jdS)z(Clears the undo and redo stacks resetrrMs r edit_resetzText.edit_resetsyy!!rc$|jdS)znInserts a separator (boundary) on the undo stack. Does nothing when the undo option is false rrrMs r edit_separatorzText.edit_separators yy%%rc$|jdS)aDUndoes the last edit action If the undo option is true. An edit action is defined as all the insert and delete commands that are recorded on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the undo option is false undorrMs r edit_undozText.edit_undosyy  rcR|jj|jd||S)z5Return the text from INDEX1 to INDEX2 (not included).rrurs r rzText.getsww||DGGUFF;;rc|dddk7rd|z}|dddk(r|dd}|jj|jdd||S)z9Return the value of OPTION of an embedded image at INDEX.Nrr7rrrcrrurs r image_cgetzText.image_cgetsQ "1: 6\F "#;# CR[Fww||DGGWfeVDDrc .|jdd|f||S)z%Configure an embedded image at INDEX.rcrrrCs r image_configurezText.image_configuresercV|jj|jdd||fS)zChange the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). Return the current value if None is given for DIRECTION.rgravityru)rNmarkName directions r mark_gravityzText.mark_gravitys+ww|| WWfi9 =? ?rc|jj|jj|jddS)zReturn all mark names.rrdrrMs r mark_nameszText.mark_names s3ww   GGVW"&' 'rcV|jj|jdd||y)z0Set mark MARKNAME before the character at INDEX.rrNru)rNr4r=s r mark_setz Text.mark_sets  TWWfeXu=rcZ|jj|jddf|zy)zDelete all marks in MARKNAMES.runsetNru)rN markNamess r mark_unsetzText.mark_unsets"  dggvw/);ww   GGUK&&"BC Crc |jj|jj|jdd|||S)zReturn a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched backwards from INDEX1.rX prevrangerrls r tag_prevrangezText.tag_prevrangernrcV|jj|jdd||y)zaChange the priority of tag TAGNAME such that it is higher than the priority of ABOVETHIS.rXrNru)rNrYrs r rzText.tag_raises#  GGUGWi 9rc|jj|jj|jdd|S)z7Return a list of ranges of text which have tag TAGNAME.rXrangesr)rNrYs r tag_rangeszText.tag_rangess5ww   GGUHg"/0 0rcX|jj|jdd|||y)zARemove tag TAGNAME from all characters between INDEX1 and INDEX2.rXr1Nrurls r tag_removezText.tag_removes#  GGUHgvv ?rc|dddk7rd|z}|dddk(r|dd}|jj|jdd||S)z:Return the value of OPTION of an embedded window at INDEX.Nrr7rrrtrrurs r window_cgetzText.window_cgetsQ "1: 6\F "#;# CR[Fww||DGGXvufEErc .|jdd|f||S)z&Configure an embedded window at INDEX.rtrrrCs r window_configurezText.window_configures+u=sBGGrc ||jj|jdd|f|j||zy)zCreate a window at INDEX.rtrNrPrCs r window_createzText.window_creates5  ww(E2 c2&' (rc|jj|jj|jddS)z4Return all names of embedded windows in this widget.rtrdrrMs r window_nameszText.window_namess1ww  GGLL(G 46 6rcZ|jj|jddf|zy)zObsolete function, use see.rz -pickplaceNru)rNrs r yview_pickplacezText.yview_pickplaces"  dggw 5<=rrrn)NNNNNNNNrE);rPrQrRrr r1rrtr rZrrrrrr!r#r&rr)r+r-rer=rr6r8r:r>rArDrHrJrrr rrrZrrr_rarc tag_configrfr rirmrqrrurwryr{ window_configr}rrr!rr rr2sI>"72> 5 (08H %.P 4 *!" & !< EG')* 7:? ? ' >=DH,.%I G46 04047;.(,= Q '' EGJ<B : CC9 0 ? FH%M')( 6 >rrceZdZdZddZdZy)_setitz>Internal class. It wraps the command in the widget OptionMenu.Nc.||_||_||_yr) _setit__value _setit__var_setit__callback)rNvarr r$s r r z_setit.__init__s  "rc|jj|j|j|j|jg|yyr)rrrrrys r r z_setit.__call__s< t||$ ?? & DOODLL 04 0 'rrrzr!rr rrsH# 1rrc"eZdZdZdZdZdZy) OptionMenuz?OptionMenu which allows the user to select a value from a menu.c d|dtddd}tj||d|d|_t |dd x}|_|j |_|jd }d |vr|d =|r td tt|z|j|t||| |D] } |j| t|| | "||d<y )zConstruct an optionmenu widget with the parent MASTER, with the resource textvariable set to VARIABLE, the initially selected value VALUE, the other menu values VALUES and an additional keyword argument command.r6rr0) borderwidth textvariable indicatoronreliefr.highlightthicknessr tk_optionMenurr)rtearoffrzunknown option -)rxrN)RAISEDr~r rwr_OptionMenu__menurvmenunamerrr@r:rr) rNrr+r r,kwargsrorr$r3s r r zOptionMenu.__init__s &C$%' flB7)!$VQ??t{ ::i(  y! -d4<.@@A A u%:  <A   1#Ha:  <V rcP|dk(r |jStj||S)Nr)rr~rurs r ruzOptionMenu.__getitem__s& 6>;; !!$--rc<tj|d|_y)z,Destroy this widget and the associated menu.N)rrrrMs r rzOptionMenu.destroys4  rN)rPrQrRrr rurr!rr rrsI2. rrcVeZdZdZdZdidfdZdZdZdZdZ d Z e Z d Z d Z d Zy) ImagezBase class for images.rNc rd|_| td}t|d||_|s,txj dz c_dtj }|r|rt ||f}n|r|}d}|jD]\}}|d|z|fz}|jjdd||f|z||_y) Nz create imager<rpyimager!r7rcr) rrrr<r_last_idr4r-r ) rNimgtyperr/rror>r2r3s r r zImage.__init__s >&~6F&$/ NNa N"'..2D #YRy1s rIIKDAqQ *G   gx$87BC rc|jSr)rrMs r rOz Image.__str__s dii'rc|jr) |jjdd|jyy#t$rYywxYw)NrcrZ)rr<r rrMs r rz Image.__del__s? 99  Wh :   s'7 AAcZ|jj|jdd|z|yNrr7r<r rrs r rzImage.__setitem__s   TYY SWe2>rcP|jj|jdy)zDisplay a transparent image.blankNrrMs r rzPhotoImage.blankFs  TYY(rcV|jj|jdd|zS)zReturn the value of OPTION.rr7r)rNrs r rzPhotoImage.cgetJs!ww||DIIvsV|<s r rzSpinbox.scan_mark syy##rc&|jd|S)aCompute the difference between the given x argument and the x argument to the last scan mark command It then adjusts the view left or right by 10 times the difference in x-coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the spinbox at high speed through the window. The return value is an empty string. rrr>s r r zSpinbox.scan_dragtosyy1%%rc||j|jj|jdf|zxsdS)rrr!rErys r rzSpinbox.selections9}} GGLL$'';/$6 79?<> ?rc&|jd|S)aLocate the end of the selection nearest to the character given by index, Then adjust that end of the selection to be at index (i.e including but not going beyond index). The other end of the selection is made the anchor point for future select to commands. If the selection isn't currently in the spinbox, then a new selection is created to include the characters between index and the most recent selection anchor point, inclusive. r#rrWs r r]zSpinbox.selection_adjust#s~~h..rc$|jdS)zsClear the selection If the selection isn't in this widget then the command has no effect. rrrMs r rzSpinbox.selection_clear1s ~~g&&rcR|jj|jdd|S)zSets or gets the currently selected element. If a spinbutton element is specified, it will be displayed depressed. rrrurs r selection_elementzSpinbox.selection_element9s! ww||DGG[)WEErc(|jd|y)rar*NrrWs r rbzSpinbox.selection_fromAs vu%rc|jj|jj|jddS)zUReturn True if there are characters selected in the spinbox, False otherwise.rrdrrMs r rezSpinbox.selection_presentErfrc*|jd||y)rhriNrrjs r rlzSpinbox.selection_rangeKs ws+rc(|jd|y)rnr/NrrWs r rozSpinbox.selection_toOs tU#rr)rPrQrRrr r1rZrrrr=rrrrr rr]rrrbrerlror!rr rrsp":: K <,775 98: $ &? /'F&; ,$rrceZdZdZdifdZy) LabelFramezlabelframe widget.Nc 6tj||d||y)aConstruct a labelframe widget with the parent MASTER. STANDARD OPTIONS borderwidth, cursor, font, foreground, highlightbackground, highlightcolor, highlightthickness, padx, pady, relief, takefocus, text WIDGET-SPECIFIC OPTIONS background, class, colormap, container, height, labelanchor, labelwidget, visual, width labelframeNrrs r r zLabelFrame.__init__Ys flC B/F 7; # $ ) : )(/ 9J)XJArrct}d|jdz}|dz }t||}|jt |d|fd}|j||_t |d|j }|j|j|j|j|jy) NzThis is Tcl/Tk %s tk_patchLevelu This should be a cedilla: çrz Click me!cZ|jjd|jdzS)Nz[%s]rr)testrrs r z_test..7s) (;(; & 11)<)3r)rrQUIT) rrrvrrrrrr)rr^)rrrxrrs r _testr0s 4D !2!2?!C CD ..D $T "E JJL $["&3 4D IIKDI $VT\\ :DIIK LLNKKMNNMMOrr>r__main__)TNrrk)NNrF)gr collectionsenumrrhr8rtkinter.constantsrXrrfloatr) TkVersionr* TclVersionREADABLEWRITABLE EXCEPTIONcompilerASCIIrrr r"r*r4rB namedtuplerDr^ _simple_enumStrEnumr`rrrrrrrrrrrrGrNrTrXr^r[rQrRr rarr|rrrrArrLrNr]rfrpr~rrrr:r5rLrsrvrzrrrrrrrrrrrrrerirrrrglobalsr-rr ModuleType__all__rP)robjs00r r3s@@       (%% & 8'' (           BJJ{ # BJJy"(( + , 8!!X$##Y.S-{--.@=?S G4<< ''!'TO O d   "  q+q+h02X22EE*AA<:   =AAD(,,,??*??*mm` p&rp&f!$ ,6+,+,\0.0.f4,4,n>4>4B Zud 8z28<,/V,/^q>VUEq>h .(&.(bSFESl?F?(8F80qfeUqh~*6~*B==:f:(&(B$7F$7N/2/2dT>65%T>n 1 1$$N;7;7|QFQFh@%@3 3 m$fem$d==0}A&}AD*")!2 ,!2ID#//#&z#u?O?O/P?* !2 , z GEOt,tPN ,s*0 M2? M>,4N 2M;:M;>NNtkinter/__pycache__/tix.cpython-312.pyc000064400000332250152342670510013755 0ustar00 ֦i,vddlZddlZddlZddlddlmZejdeddZdZd Zd Z d Z d Z d Z dZ dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZd Z dZ!Gd!d"Z"Gd#d$ejFe"Z#Gd%d&Z$ejJjLe$fzejJ_&Gd'd(ejJZ'Gd)d*e'Z(Gd+d,Z)Gd-d.e'Z*Gd/d0e'Z+Gd1d2e'Z,Gd3d4e'Z-Gd5d6e'Z.Gd7d8e'Z/Gd9d:e'Z0Gd;de'Z2Gd?d@e'Z3GdAdBe'Z4GdCdDe'Z5GdEdFe'Z6GdGdHe'e7e8Z9GdIdJe'Z:GdKdLe'Z;GdMdNe'Z<GdOdPe'Z=GdQdRe'Z>GdSdTe'Z?GdUdVe'Z@GdWdXe'ZAGdYdZe'ZBGd[d\e'ZCGd]d^e'ZDGd_d`e'ZEGdadbe'ZFGdcdde'ZGGdedfe'ZHGdgdhe'ZIGdidje'ZJGdkdle'ZKGdmdne'ZLGdodpe'ZMGdqdre'e7e8ZNGdsdte'ZOGdudve'ZPGdwdxeQe(ZRGdydzeSe(ZTGd{d|eUe(ZVGd}d~eWe(ZXGddeYe(ZZGdde[e(Z\Gdde]e(Z^Gdde_e(Z`Gddeae(ZbGddece(ZdGddeFe(ZeGdde9e(ZfGddeEe(ZgGddeNe(ZhGdde,e(ZiGdde.e(ZjGdde0e(ZkGdde1e(ZlGdde4e(ZmGdde,e(ZnGddeMe(ZoGdde@e(ZpGddeBe(ZqdZrdZsGdde'ZtGdde'e7e8ZuGddeuZvy)N)*) _cnfmergeznThe Tix Tk extension is unmaintained, and the tkinter.tix wrapper module is deprecated in favor of tkinter.ttk) stacklevelwindowtextstatus immediateimage imagetextballoonauto acrosstopasciicellcolumn decreasing increasingintegermainmaxrealrowzs-regionzx-regionzy-region cFeZdZdZdZdZd dZd dZdZdZ d Z d d Z y) tixCommandaThe tix commands provide access to miscellaneous elements of Tix's internal state and the Tix application context. Most of the information manipulated by these commands pertains to the application as a whole, or to a screen or display, rather than to a particular window. This is a mixin class, assumed to be mixed to Tkinter.Tk that supports the self.tk.call method. c<|jjdd|S)aTix maintains a list of directories under which the tix_getimage and tix_getbitmap commands will search for image files. The standard bitmap directory is $TIX_LIBRARY/bitmaps. The addbitmapdir command adds directory into this list. By using this command, the image files of an applications can also be located using the tix_getimage or tix_getbitmap command. tix addbitmapdirtkcall)self directorys $/usr/lib64/python3.12/tkinter/tix.pytix_addbitmapdirztixCommand.tix_addbitmapdirYsww||E>9==c<|jjdd|S)zReturns the current value of the configuration option given by option. Option may be any of the options described in the CONFIGURATION OPTIONS section. r!cgetr#r&options r(tix_cgetztixCommand.tix_cgetes ww||E6622r*Nc |rt||f}n |r t|}||jddSt|tr|j ddd|zS|j j d|j|zS)aQuery or modify the configuration options of the Tix application context. If no option is specified, returns a dictionary all of the available options. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given option(s) to have the given value(s); in this case the command returns an empty string. Option may be any of the configuration options. r! configure-)r!r1)r _getconfigure isinstancestr_getconfigure1r$r%_optionsr&cnfkws r( tix_configureztixCommand.tix_configurels~ S"I&C C.C ;%%e[9 9 c3 &&uk3s7C Cww||04==3EEFFr*cx||jjdd|S|jjddS)aReturns the file selection dialog that may be shared among different calls from this application. This command will create a file selection dialog widget when it is called the first time. This dialog will be returned by all subsequent calls to tix_filedialog. An optional dlgclass parameter can be passed to specified what type of file selection dialog widget is desired. Possible options are tix FileSelectDialog or tixExFileSelectDialog. r! filedialogr#)r&dlgclasss r(tix_filedialogztixCommand.tix_filedialogs6  77<<|X> >77<<|4 4r*c<|jjdd|S)aLocates a bitmap file of the name name.xpm or name in one of the bitmap directories (see the tix_addbitmapdir command above). By using tix_getbitmap, you can avoid hard coding the pathnames of the bitmap files in your application. When successful, it returns the complete pathname of the bitmap file, prefixed with the character '@'. The returned value can be used to configure the -bitmap option of the TK and Tix widgets. r! getbitmapr#r&names r( tix_getbitmapztixCommand.tix_getbitmapsww||E;55r*c<|jjdd|S)aLocates an image file of the name name.xpm, name.xbm or name.ppm in one of the bitmap directories (see the addbitmapdir command above). If more than one file with the same name (but different extensions) exist, then the image type is chosen according to the depth of the X display: xbm images are chosen on monochrome displays and color images are chosen on color displays. By using tix_ getimage, you can avoid hard coding the pathnames of the image files in your application. When successful, this command returns the name of the newly created image, which can be used to configure the -image option of the Tk and Tix widgets. r!getimager#rBs r( tix_getimageztixCommand.tix_getimagesww||E:t44r*c>|jjddd|S)a@Gets the options maintained by the Tix scheme mechanism. Available options include: active_bg active_fg bg bold_font dark1_bg dark1_fg dark2_bg dark2_fg disabled_fg fg fixed_font font inactive_bg inactive_fg input1_bg input2_bg italic_font light1_bg light1_fg light2_bg light2_fg menu_font output1_bg output2_bg select_bg select_fg selector r!r.getr#rBs r(tix_option_getztixCommand.tix_option_getsww||E8UD99r*c||jjdd|||S|jjdd||S)aResets the scheme and fontset of the Tix application to newScheme and newFontSet, respectively. This affects only those widgets created after this call. Therefore, it is best to call the resetoptions command before the creation of any widgets in a Tix application. The optional parameter newScmPrio can be given to reset the priority level of the Tk options set by the Tix schemes. Because of the way Tk handles the X option database, after Tix has been has imported and inited, it is not possible to reset the color schemes and font sets using the tix config command. Instead, the tix_resetoptions command must be used. r! resetoptionsr#)r& newScheme newFontSet newScmPrios r(tix_resetoptionsztixCommand.tix_resetoptionss>  !77<<~y*jY Y77<<~y*M Mr*N) __name__ __module__ __qualname____doc__r)r/r;r?rDrGrJrPr*r(rrNs1 >3G, 5 6 5:"Nr*rceZdZdZddZdZy)Tkz{Toplevel widget of Tix which represents mostly the main window of an application. It has an associated Tcl interpreter.Ncntjj||||tjj d}|j jd|<|j jd|z|j jd|z|j jdy)N TIX_LIBRARYz}|t|jdzd} |j|j |@|S#YGxYw)zReturn all subwidgets.rN)_subwidget_namesrrqrr)r&namesretlistrCs r(subwidgets_allzTixWidget.subwidgets_allasl%%'IDDGG Q(D t11$78 s AA cp |jj|jd|S#t$rYywxYw)z7Get a subwidget name (returns a String, not a Widget !)rN)r$r%rqrrBs r(rzTixWidget._subwidget_nameps4 77<<d; ;  s &) 55c |jj|jdd}|jj|S#t$rYywxYw)z"Return the name of all subwidgets. subwidgetsz-allN)r$r%rqrrrs r(rzTixWidget._subwidget_nameswsH  TWWlF;A77$$Q' '  sAA AAc|dk(ryt|ts t|}t|ts t|}|j}|D]#}|jj |dd|z|%y)z8Set configuration options for all subwidgets (and self).rfNr1r2)r4r5reprrr$r%)r&r.rwrrCs r( config_allzTixWidget.config_allsd R< FC(&\F%%KE%%'D GGLL{C&L% @r*c ||}|r|rt||f}n|r|}d}|jD]+\}}t|r|j|}|d|z|fz}-|jj dd|f|zS)NrVr2r create)rrcallable _registerr$r%)r&imgtyper9rr:rrrs r( image_createzTixWidget.image_creates >F #YRy1s rIIKDAq{NN1%Q *G yy~~w';gEFFr*c^ |jjdd|y#t$rYywxYw)Nr delete)r$r%r)r&imgnames r( image_deletezTixWidget.image_deletes-  GGLL(G 4   s  ,,)rRrSrTrUr\rrrrrrrrrrVr*r(rrsQ  $#&!Z# 5%  A)+4 Gr*rc eZdZdZ ddZdZy) TixSubWidgetzSubwidget class. This is used to mirror child widgets automatically created by Tix/Tk as part of a mega-widget in Python (which is not informed of this)c|r>|j|} |t|jdzd}|jd}|s#tj ||ddd|i||_ y|}t tdz D]-}dj|d|dz} |j| } | }/|r|d}tj ||ddd|i||_ y#g}YxYw#t$rt|||dd}YwxYw)Nr.rCr)destroy_physicallycheck_intermediate) rrrqsplitrr\rangejoinrKeyErrorrr) r&rrCrrpathplistparentirws r(r\zTixSubWidget.__init__s" ))$/D C N1,-. 3"   tVT4&4 I$#5F3u:>*HHU4AaC[)@,,Q/AF +Ry   tVT4&4 I"4/  @)&%(=>=>@F@s,CC"C"D?Dct|jjD]}|j|j|j jvr!|j j|j=|j|j j vr!|j j |j=|jr'|jjd|jyy)Nrh) rchildrenvaluesrhrrrrr$r%rqr&cs r(rhzTixSubWidget.destroys dmm**,-Aqyy{- ::-- - $$TZZ0 ::33 3 **4::6  " " GGLLDGG , #r*N)rrrkrVr*r(rrs9:5@ -r*rcHeZdZdZifdddZdZdZdZdZifd Z d Z y) DisplayStylezRDisplayStyle - handle configuration options shared by (multiple) Display ItemsN)rc |)d|vr|d}nd|vr|d}ntjd}|j|_|jjd|g|j |||_y)N refwindowzcreate display styletixDisplayStyle)r[_get_default_rootr$r%r7 stylename)r&itemtyper9rr:s r(r\zDisplayStyle.__init__st >b K#[) 223IJ))%&75!]]3r25r*c|jSrQ)rris r(__str__zDisplayStyle.__str__s ~~r*cz|r|rt||f}n|r|}d}|jD]\}}|d|z|fz}|S)NrVr2)rr)r&r9r:optsrrs r(r7zDisplayStyle._optionssM #S"I&C CIIKDAq3q5!*$D  r*cP|jj|jdyNrr$r%rris r(rzDisplayStyle.deletes  T^^X.r*cZ|jj|jdd|z|y)Nr1-%srrus r(rxzDisplayStyle.__setitem__s   T^^[%)UCr*c ^|j|jdg|j||S)Nr1)r3rr7r8s r(rrzDisplayStyle.configs6!t!! NNKA*.--B*?A Ar*cV|jj|jdd|zS)Nr,rr)r&rvs r( __getitem__zDisplayStyle.__getitem__s!ww||DNNFE#I>>r*) rRrSrTrUr\rr7rrxrrrrVr*r(rrs= &( 54 5/DA?r*rc,eZdZdZdifdZifdZdZy)BalloonzBalloon help widget. Subwidget Class --------- ----- label Label message MessageNc gd}tj||d|||t|dd|jd<t|dd|jd<y)N)rinstallcolormapinitwait statusbarcursor tixBalloonlabelrrmessagerr\ _dummyLabelrr&rr9r:statics r(r\zBalloon.__init__s[4vsBG'24FG(IG$)4T9HI*KI&r*c |jj|jd|jg|j||y)zkBind balloon widget to another. One balloon widget may be bound to several widgets at the same timebindNrp)r&widgetr9r:s r( bind_widgetzBalloon.bind_widgets2  TWWffiiI$--R2HIr*cf|jj|jd|jyNunbindr{r&rs r( unbind_widgetzBalloon.unbind_widget  TWWh 2r*)rRrSrTrUr\rrrVr*r(rrs$#K')J 3r*rc,eZdZdZdifdZifdZdZy) ButtonBoxzgButtonBox - A container for pushbuttons. Subwidgets are the buttons added with the add method. Nc <tj||dddg||y)N tixButtonBox orientationrrr\r&rr9r:s r(r\zButtonBox.__init__&s#4)95sB @r*c |jj|jd|g|j||}t |||j |<|S)z$Add a button with given name to box.addr$r%rqr7 _dummyButtonr)r&rCr9r:btns r(r z ButtonBox.add*sLdggll477E4I$--R2HI$0t$<D! r*cp||jvr(|jj|jd|yyNinvokerr$r%rqrBs r(rzButtonBox.invoke1- 4&& & GGLL(D 1 'r*rRrSrTrUr\r rrVr*r(rr"s##@2r*rc4eZdZdZdifdZdZdZdZdZy)ComboBoxaComboBox - an Entry field with a dropdown menu. The user can select a choice by either typing in the entry subwidget or selecting from the listbox subwidget. Subwidget Class --------- ----- entry Entry arrow Button slistbox ScrolledListBox tick Button cross Button : present if created with the fancy optionNc tj||dgd||t|d|jd<t |d|jd<t |d|jd<t |d|jd< t |d|jd<t |d|jd<y#t$rYywxYw) N tixComboBox)editabledropdownfancyrrentryarrowslistboxtickcross)rr\rr _dummyEntryr _dummyScrolledListBox TypeErrorrs r(r\zComboBox.__init__Cs4G $(34'AG$'24'AG$'3D''BG$*?@J+LJ' *6tV*DD   '+7g+FD   (   s2B55 CCcR|jj|jd|y)N addhistoryr{r&r5s r( add_historyzComboBox.add_historyUs  TWWlC0r*cR|jj|jd|y)N appendhistoryr{r%s r(append_historyzComboBox.append_historyXs  TWWos3r*cT|jj|jd||yNinsertr{)r&indexr5s r(r,zComboBox.insert[s  TWWhs3r*cR|jj|jd|y)Npickr{r&r-s r(r/z ComboBox.pick^s  TWWfe,r*) rRrSrTrUr\r&r)r,r/rVr*r(rr5s( E $$144-r*rc4eZdZdZdifdZdZdZdZdZy)ControlaControl - An entry field with value change arrows. The user can adjust the value by pressing the two arrow buttons or by entering the value directly into the entry. The new value will be checked against the user-defined upper and lower limits. Subwidget Class --------- ----- incr Button decr Button entry Entry label LabelNc tj||ddg||t|d|jd<t|d|jd<t |d|jd<t |d|jd<y)N tixControlrincrdecrrr)rr\r rrr rs r(r\zControl.__init__osx4 {CL&24&@F#&24&@F#'24'AG$'24'AG$r*cP|jj|jdy)Nr6r{ris r( decrementzControl.decrementv  TWWf%r*cP|jj|jdy)Nr5r{ris r( incrementzControl.incrementyr9r*cP|jj|jdyrr{ris r(rzControl.invoke|  TWWh'r*cP|jj|jdy)Nupdater{ris r(r?zControl.updater=r*) rRrSrTrUr\r8r;rr?rVr*r(r2r2as(  $B&&((r*r2c eZdZdZifdZdZy)DirListaRDirList - displays a list view of a directory, its previous directories and its sub-directories. The user can choose one of the directories displayed in the list or change to another directory. Subwidget Class --------- ----- hlist HList hsb Scrollbar vsb Scrollbarc tj||ddg||t|d|jd<t |d|jd<t |d|jd<y)N tixDirListrhlistvsbhsbrr\ _dummyHListr_dummyScrollbarrs r(r\zDirList.__init__a4 {CL'24'AG$%4T5%AE"%4T5%AE"r*cR|jj|jd|yNchdirr{r&dirs r(rMz DirList.chdir  TWWgs+r*NrRrSrTrUr\rMrVr*r(rArAs"$&B ,r*rAc eZdZdZifdZdZy)DirTreeaDirTree - Directory Listing in a hierarchical view. Displays a tree view of a directory, its previous directories and its sub-directories. The user can choose one of the directories displayed in the list or change to another directory. Subwidget Class --------- ----- hlist HList hsb Scrollbar vsb Scrollbarc tj||ddg||t|d|jd<t |d|jd<t |d|jd<y)N tixDirTreerrDrErFrGrs r(r\zDirTree.__init__rJr*cR|jj|jd|yrLr{rNs r(rMz DirTree.chdirrPr*NrQrVr*r(rSrSs !$&B ,r*rSceZdZdZifdZy) DirSelectBoxaDirSelectBox - Motif style file select box. It is generally used for the user to choose a file. FileSelectBox stores the files mostly recently selected into a ComboBox widget so that they can be quickly selected again. Subwidget Class --------- ----- selection ComboBox filter ComboBox dirlist ScrolledListBox filelist ScrolledListBoxc tj||ddg||t|d|jd<t |d|jd<y)NtixDirSelectBoxrdirlistdircbx)rr\ _dummyDirListr_dummyFileComboBoxrs r(r\zDirSelectBox.__init__sK4):YKbQ)6tY)GI&(:4(JH%r*NrRrSrTrUr\rVr*r(rXrXs '$&Kr*rXc&eZdZdZifdZdZdZy)ExFileSelectBoxaExFileSelectBox - MS Windows style file select box. It provides a convenient method for the user to select files. Subwidget Class --------- ----- cancel Button ok Button hidden Checkbutton types ComboBox dir ComboBox file ComboBox dirlist ScrolledListBox filelist ScrolledListBoxc tj||ddg||t|d|jd<t|d|jd<t |d|jd<t |d|jd<t |d|jd<t |d|jd<t |d |jd <t|d |jd <y) NtixExFileSelectBoxrcancelokhiddentypesrOr[filefilelist)rr\r r_dummyCheckbutton_dummyComboBoxr]r!rs r(r\zExFileSelectBox.__init__s4)= {CQST(4T8(DH%$0t$<D!(9$(IH%'5dG'DG$%3D%%@E")6tY)GI&&4T6&BF#*?j*QJ'r*cP|jj|jdyNfilterr{ris r(rnzExFileSelectBox.filterr=r*cP|jj|jdyrr{ris r(rzExFileSelectBox.invoker=r*N)rRrSrTrUr\rnrrVr*r(raras &$& R((r*rac&eZdZdZifdZdZdZy)DirSelectDialoga#The DirSelectDialog widget presents the directories in the file system in a dialog window. The user can use this dialog window to navigate through the file system to select the desired directory. Subwidgets Class ---------- ----- dirbox DirSelectDialogc ltj||ddg||t|d|jd<y)NtixDirSelectDialogrdirbox)rr\_dummyDirSelectBoxrrs r(r\zDirSelectDialog.__init__s74)=%;R 1(:4(JH%r*cP|jj|jdyNpopupr{ris r(rxzDirSelectDialog.popup  TWWg&r*cP|jj|jdyNpopdownr{ris r(r|zDirSelectDialog.popdown  TWWi(r*NrRrSrTrUr\rxr|rVr*r(rqrqs$$&K ')r*rqc&eZdZdZifdZdZdZy)ExFileSelectDialogzExFileSelectDialog - MS Windows style file select dialog. It provides a convenient method for the user to select files. Subwidgets Class ---------- ----- fsbox ExFileSelectBoxc ltj||ddg||t|d|jd<y)NtixExFileSelectDialogrfsbox)rr\_dummyExFileSelectBoxrrs r(r\zExFileSelectDialog.__init__s74)@%;R 1'tY)OI&*?j*QJ'(6tX(FH%+9$ +LK(r*cP|jj|jdyrmr{ris r( apply_filterzFileSelectBox.apply_filter#r=r*cP|jj|jdyrr{ris r(rzFileSelectBox.invoke&r=r*N)rRrSrTrUr\rrrVr*r(rrs '$&M((r*rc&eZdZdZifdZdZdZy)FileSelectDialogzFileSelectDialog - Motif style file select dialog. Subwidgets Class ---------- ----- btns StdButtonBox fsbox FileSelectBoxc tj||ddg||t|d|jd<t |d|jd<y)NtixFileSelectDialogrbtnsr)rr\_dummyStdButtonBoxr_dummyFileSelectBoxrs r(r\zFileSelectDialog.__init__3sN4)>%;R 1&8v&FF#':4'IG$r*cP|jj|jdyrwr{ris r(rxzFileSelectDialog.popup9ryr*cP|jj|jdyr{r{ris r(r|zFileSelectDialog.popdown<r}r*Nr~rVr*r(rr*s!$&J ')r*rc&eZdZdZifdZdZdZy) FileEntrya_FileEntry - Entry field with button that invokes a FileSelectDialog. The user can type in the filename manually. Alternatively, the user can press the button widget that sits next to the entry, which will bring up a file selection dialog. Subwidgets Class ---------- ----- button Button entry Entryc tj||dddg||t|d|jd<t |d|jd<y)N tixFileEntry dialogtyperbuttonr)rr\r rr rs r(r\zFileEntry.__init__KsP4()4c2 ?(4T8(DH%'24'AG$r*cP|jj|jdyrr{ris r(rzFileEntry.invokeQr=r*cyrQrVris r( file_dialogzFileEntry.file_dialogTs r*N)rRrSrTrUr\rrrVr*r(rr?s$&B ( r*rceZdZdZdifdZifdZdifdZdZdZd7dZ d Z d Z d Z d Z d ZdZdZdZifdZifdZdZdZeZdZdZdZifdZifdZdZdZdZdZdZ dZ!d8d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,ifd+Z-ifd,Z.d-Z/d.Z0d/Z1ifd0Z2d1Z3d2Z4ifd3Z5d4Z6d8d5Z7d6Z8y)9HListaHList - Hierarchy display widget can be used to display any data that have a hierarchical structure, for example, file system directory trees. The list entries are indented and connected by branch lines according to their places in the hierarchy. Subwidgets - NoneNc <tj||dddg||y)NtixHListcolumnsrrrs r(r\zHList.__init__`s"4%y13 Ftww||WWj&K37==b3IK Kr*cT|jj|jdd|yNanchorsetr{r&rs r( anchor_setzHList.anchor_setm  TWWhu5r*cR|jj|jddyNrclearr{ris r( anchor_clearzHList.anchor_clearp  TWWh0r*c|s)|jj|jdd||S|jj|jdd|d|S)Nrwidthz-charr{)r&colrcharss r( column_widthzHList.column_widthssJ77<<7CG G77<<7C '0 0r*cR|jj|jddy)Nrallr{ris r( delete_allzHList.delete_allzs  TWWh.r*cT|jj|jdd|y)Nrrr{rs r( delete_entryzHList.delete_entry}s  TWWh7r*cT|jj|jdd|y)Nr offspringsr{rs r(delete_offspringszHList.delete_offspringss  TWWh eFAE Fr*c|jj|jdd|}|jj|S)Nrrr$r%rqr)r&rrs r( info_childrenzHList.info_childrens3 GGLL&*e <ww  ##r*cR|jj|jdd|S)Nrdatar{rs r( info_datazHList.info_dataww||DGGVVU;;r*cP|jj|jddS)Nrrr{ris r( info_dragsitezHList.info_dragsiteww||DGGVZ88r*cP|jj|jddS)Nrrr{ris r( info_dropsitezHList.info_dropsiterr*cR|jj|jdd|S)Nrrr{rs r( info_existszHList.info_existsww||DGGVXu==r*cR|jj|jdd|S)Nrrfr{rs r( info_hiddenzHList.info_hiddenrr*cR|jj|jdd|S)Nrnextr{rs r( info_nextzHList.info_nextr r*cR|jj|jdd|S)Nrrr{rs r( info_parentzHList.info_parentrr*cR|jj|jdd|S)Nrprevr{rs r( info_prevzHList.info_prevr r*c|jj|jdd}|jj|SNrrrrs r(info_selectionzHList.info_selection1 GGLL&+ 6ww  ##r*cV|jj|jdd|||S)Nitemr,r{)r&rrrs r( item_cgetzHList.item_cgets#ww||DGGVVUCEEr*c ||j|jdd||S|jj|jdd||g|j ||y)Nr%r1rr&rrr9r:s r(item_configurezHList.item_configuresW ;%%dggv{E3O O TWWfk5# '}}S"% 'r*c z|jj|jdd||g|j||y)Nr%rrpr(s r( item_createzHList.item_creates8 ggvx N6:mmC6L Nr*cT|jj|jdd||S)Nr%rr{r&rrs r( item_existszHList.item_existss!ww||DGGVXucBBr*cV|jj|jdd||y)Nr%rr{r-s r( item_deletezHList.item_deletes  TWWfhs;r*cR|jj|jd||S)N entrycgetr{rs r(r2zHList.entrycgetsww||DGG[%==r*c ||j|jd|S|jj|jd|g|j ||yNentryconfigurerrs r(r5zHList.entryconfiguresQ ;%%dgg/?G G TWW. '}}S"% 'r*cP|jj|jd|SNnearestr{)r&rs r(r8z HList.nearestsww||DGGY22r*cR|jj|jd|yNseer{rs r(r;z HList.see   TWWeU+r*c v|jj|jddg|j||yNrrrpr8s r(selection_clearzHList.selection_clear, TWWk7LT]]35KLr*cR|jj|jdd|SNrincludesr{rs r(selection_includeszHList.selection_includesww||DGG[*eDDr*cV|jj|jdd||yNrrr{r&firstlasts r( selection_setzHList.selection_set  TWWk5%>r*cR|jj|jdd|S)Nshowrr{rs r( show_entryzHList.show_entryww||DGGVWe<><><$F.0' +-NC<>)+' 3,#%ME?=r*rceZdZdZdifdZy) InputOnlyz?InputOnly - Invisible widget. Unix only. Subwidgets - NoneNc 8tj||dd||y)N tixInputOnlyrrs r(r\zInputOnly.__init__s4sBGr*r_rVr*r(rSrSs#rHr*rSceZdZdZdifdZy) LabelEntryaLabelEntry - Entry field with label. Packages an entry widget and a label into one mega widget. It can be used to simplify the creation of ``entry-form'' type of interface. Subwidgets Class ---------- ----- label Label entry EntryNc tj||dddg||t|d|jd<t |d|jd<y)N tixLabelEntry labelsiderrr)rr\rrr rs r(r\zLabelEntry.__init__,P4' 2C ='24'AG$'24'AG$r*r_rVr*r(rWrW"s#rBr*rWceZdZdZdifdZy) LabelFrameaeLabelFrame - Labelled Frame container. Packages a frame widget and a label into one mega widget. To create widgets inside a LabelFrame widget, one creates the new widgets relative to the frame subwidget and manage them inside the frame subwidget. Subwidgets Class ---------- ----- label Label frame FrameNc tj||dddg||t|d|jd<t |d|jd<y)N tixLabelFramerZrrframe)rr\rr _dummyFramers r(r\zLabelFrame.__init__=r[r*r_rVr*r(r]r]2s#rBr*r]c6eZdZdZifdZifdZdZdZdZy) ListNoteBookaA ListNoteBook widget is very similar to the TixNoteBook widget: it can be used to display many windows in a limited space using a notebook metaphor. The notebook is divided into a stack of pages (windows). At one time only one of these pages can be shown. The user can navigate through these pages by choosing the name of the desired page in the hlist subwidget.c tj||ddg||t|dd|jd<t |d|jd<t |d|jd<y)NtixListNoteBookrpanerrrDshlist)rr\_dummyPanedWindowrrH_dummyScrolledHListrs r(r\zListNoteBook.__init__Lsh4):YKbQ&7fKL'NF#'24'AG$(;D((KH%r*c |jj|jd|g|j||t |||j |<|j |Srr$r%rqr7rrr&rCr9r:s r(r zListNoteBook.addTT TWWeTCDMM#r,BC$0t$<D!""4((r*c$|j|SrQrrBs r(pagezListNoteBook.pageY~~d##r*c|jj|jj|jd}g}|D]"}|j |j |$|SNpagesr$rr%rqrrr&rretrs r(rtzListNoteBook.pages\R!!$'',,tww"@AA JJt~~a( ) r*cR|jj|jd|yNraiser{rBs r( raise_pagezListNoteBook.raise_paged  TWWgt,r*N) rRrSrTrUr\r rprtr|rVr*r(rcrcDs,E$&L) $-r*rcceZdZdZdifdZy)MeterzuThe Meter widget can be used to show the progress of a background job which may take a long time to execute. Nc :tj||ddg||y)NtixMeterrrrs r(r\zMeter.__init__ls4%;R 1r*r_rVr*r(rrgs#1r*rcDeZdZdZdifdZifdZdZdZdZdZ d Z y) NoteBookzNoteBook - Multi-page container widget (tabbed notebook metaphor). Subwidgets Class ---------- ----- nbframe NoteBookFrame page widgets added dynamically with the add methodNc ptj||ddg||t|dd|jd<y)N tixNoteBookrnbframerr)rr\rrrs r(r\zNoteBook.__init__xs94}yk3K)5dIIJ*LI&r*c |jj|jd|g|j||t |||j |<|j |Srrkrls r(r z NoteBook.add}rmr*c|jj|jd||j|j |j|=yrr$r%rqrrhrBs r(rzNoteBook.delete?  TWWh- D!))+    %r*c$|j|SrQrorBs r(rpz NoteBook.pagerqr*c|jj|jj|jd}g}|D]"}|j |j |$|Srsrurvs r(rtzNoteBook.pagesrxr*cR|jj|jd|yrzr{rBs r(r|zNoteBook.raise_pager}r*cN|jj|jdS)Nraisedr{ris r(rzNoteBook.raisedsww||DGGX..r*) rRrSrTrUr\r rrprtr|rrVr*r(rrps8H#rL ) & $-/r*rc eZdZy) NoteBookFrameN)rRrSrTrVr*r(rrsr*rc@eZdZdZifdZifdZifdZdZdZdZ y) OptionMenuzOptionMenu - creates a menu button of options. Subwidget Class --------- ----- menubutton Menubutton menu Menuc tj||ddg||t|d|jd<t |d|jd<y)N tixOptionMenur menubuttonmenurr\_dummyMenubuttonr _dummyMenurs r(r\zOptionMenu.__init__sJ49+sBO,F#r*c x|jj|jdd|g|j||y)Nr commandrprls r( add_commandzOptionMenu.add_commands. TWWeYNt}}S"7MNr*c x|jj|jdd|g|j||y)Nr  separatorrprls r( add_separatorzOptionMenu.add_separators. TWWe[$PsB9OPr*cR|jj|jd|yrr{rBs r(rzOptionMenu.delete  TWWh-r*cR|jj|jd|y)Ndisabler{rBs r(rzOptionMenu.disables  TWWi.r*cR|jj|jd|y)Nenabler{rBs r(rzOptionMenu.enablerr*N) rRrSrTrUr\rrrrrrVr*r(rrs6$&? %'O')Q./.r*rcFeZdZdZifdZifdZdZdZdZifdZ dZ y ) PanedWindowaPanedWindow - Multi-pane container widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally.The user changes the sizes of the panes by dragging the resize handle between two panes. Subwidgets Class ---------- ----- g/p widgets added dynamically with the add method.c <tj||dddg||y)NtixPanedWindowrrrrs r(r\zPanedWindow.__init__s"4)9M9;UWZ\^_r*c |jj|jd|g|j||t ||d|j |<|j |S)Nr r)rrkrls r(r zPanedWindow.addsZ TWWeTCDMM#r,BC$0tDE%GD!""4((r*c|jj|jd||j|j |j|=yrrrBs r(rzPanedWindow.deleterr*cR|jj|jd|y)Nr}r{rBs r(r}zPanedWindow.forgetrr*cR|jj|jd||S)Npanecgetr{rs r(rzPanedWindow.panecgetsww||DGGZ<F#r*cf|jj|jd|jy)Nrr{rs r(rzPopupMenu.bind_widget  TWWffii0r*cf|jj|jd|jyrr{rs r(rzPopupMenu.unbind_widgetrr*cj|jj|jd|j||y)Npostr{)r&rrrs r( post_widgetzPopupMenu.post_widgets"  TWWffiiA6r*N)rRrSrTrUr\rrrrVr*r(rrs $&? 137r*rc2eZdZdZifdZdZdZdZdZy) ResizeHandlez;Internal widget to draw resize handles on Scrolled widgets.c @gd}tj||d|||y)N) rrcursorfgcursorbg handlesize hintcolor hintwidthrrtixResizeHandler)r&rr9r:flagss r(r\zResizeHandle.__init__s' 4): #r +r*cf|jj|jd|jy)N attachwidgetr{rs r( attach_widgetzResizeHandle.attach_widget  TWWnfii8r*cf|jj|jd|jy)N detachwidgetr{rs r( detach_widgetzResizeHandle.detach_widget rr*cf|jj|jd|jy)Nrr{rs r(rzResizeHandle.hide rr*cf|jj|jd|jy)NrNr{rs r(rNzResizeHandle.showrr*N) rRrSrTrUr\rrrrNrVr*r(rrs!E#%+9911r*rceZdZdZifdZy) ScrolledHListz0ScrolledHList - HList with automatic scrollbars.c tj||ddg||t|d|jd<t |d|jd<t |d|jd<y)NtixScrolledHListrrDrErFrGrs r(r\zScrolledHList.__init__e4);i[ $'24'AG$%4T5%AE"%4T5%AE"r*Nr_rVr*r(rr:$&Br*rceZdZdZifdZy)ScrolledListBoxz4ScrolledListBox - Listbox with automatic scrollbars.c tj||ddg||t|d|jd<t |d|jd<t |d|jd<y)NtixScrolledListBoxrlistboxrErF)rr\ _dummyListboxrrIrs r(r\zScrolledListBox.__init__"sc4)= {CQST)6tY)GI&%4T5%AE"%4T5%AE"r*Nr_rVr*r(rrs>$&Br*rceZdZdZifdZy) ScrolledTextz.ScrolledText - Text with automatic scrollbars.c tj||ddg||t|d|jd<t |d|jd<t |d|jd<y)NtixScrolledTextrrrErF)rr\ _dummyTextrrIrs r(r\zScrolledText.__init__,sb4):YKbQ&0v&>F#%4T5%AE"%4T5%AE"r*Nr_rVr*r(rr(s8$&Br*rceZdZdZifdZy) ScrolledTListz0ScrolledTList - TList with automatic scrollbars.c tj||ddg||t|d|jd<t |d|jd<t |d|jd<y)NtixScrolledTListrtlistrErF)rr\ _dummyTListrrIrs r(r\zScrolledTList.__init__6rr*Nr_rVr*r(rr2rr*rceZdZdZifdZy)ScrolledWindowz2ScrolledWindow - Window with automatic scrollbars.c tj||ddg||t|d|jd<t |d|jd<t |d|jd<y)NtixScrolledWindowrrrErF)rr\rarrIrs r(r\zScrolledWindow.__init__Asc4)rpr8s r(r?zTList.selection_clearr@r*cR|jj|jdd|SrBr{r0s r(rDzTList.selection_includesrEr*cV|jj|jdd||yrGr{rHs r(rKzTList.selection_setrLr*rQ)rRrSrTrUr\rrrrrrrrrr,r!rr%r(r+r"r.r1r8r;r?rDrKrVr*r(r r s#rK616138383!#H77<<=$5:6,#%ME?r*r c<eZdZdZdifdZdZdZdZdZd dZ y) TreezTree - The tixTree widget can be used to display hierarchical data in a tree form. The user can adjust the view of the tree by opening or closing parts of the tree.Nc tj||ddg||t|d|jd<t |d|jd<t |d|jd<y)NtixTreerrDrErFrGrs r(r\z Tree.__init__sd4%;R 1'24'AG$%4T5%AE"%4T5%AE"r*cP|jj|jdya This command calls the setmode method for all the entries in this Tree widget: if an entry has no child entries, its mode is set to none. Otherwise, if the entry has any hidden child entries, its mode is set to open; otherwise its mode is set to close. autosetmodeNr{ris r(r>zTree.autosetmode  TWWm,r*cR|jj|jd|yz8Close the entry given by entryPath if its mode is close.closeNr{r& entrypaths r(rBz Tree.close  TWWgy1r*cP|jj|jd|Sz9Returns the current mode of the entry given by entryPath.getmoder{rCs r(rHz Tree.getmodeww||DGGY ::r*cR|jj|jd|yz6Open the entry given by entryPath if its mode is open.openNr{rCs r(rLz Tree.open  TWWfi0r*cT|jj|jd||y)aThis command is used to indicate whether the entry given by entryPath has children entries and whether the children are visible. mode must be one of open, close or none. If mode is set to open, a (+) indicator is drawn next the entry. If mode is set to close, a (-) indicator is drawn next the entry. If mode is set to none, no indicators will be drawn for this entry. The default mode is none. The open mode indicates the entry has hidden children and this entry can be opened by the user. The close mode indicates that all the children of the entry are now visible and the entry can be closed by the user.setmodeNr{r&rDmodes r(rOz Tree.setmodes  TWWiD9r*)none) rRrSrTrUr\r>rBrHrLrOrVr*r(r9r9s.E #B-2;1 :r*r9cJeZdZdZdifdZdZdZdZdZd dZ d Z d d Z y) CheckListzThe CheckList widget displays a list of items to be selected by the user. CheckList acts similarly to the Tk checkbutton or radiobutton widgets, except it is capable of handling many more items than checkbuttons or radiobuttons. Nc tj||dddg||t|d|jd<t |d|jd<t |d|jd<y)N tixCheckListrrrDrErFrGrs r(r\zCheckList.__init__sg4%w/b :'24'AG$%4T5%AE"%4T5%AE"r*cP|jj|jdyr=r{ris r(r>zCheckList.autosetmoder?r*cR|jj|jd|yrAr{rCs r(rBzCheckList.close#rEr*cP|jj|jd|SrGr{rCs r(rHzCheckList.getmode'rIr*cR|jj|jd|yrKr{rCs r(rLzCheckList.open+rMr*c|jj|jj|jd|S)zReturns a list of items whose status matches status. If status is not specified, the list of items in the "on" status will be returned. Mode can be on, off, default getselection)r$rr%rq)r&rQs r(r\zCheckList.getselection/s.ww  dgg~t!LMMr*cP|jj|jd|S)z(Returns the current status of entryPath. getstatusr{rCs r(r^zCheckList.getstatus5sww||DGG[)<rBrHrLr\r^r`rVr*r(rTrTs8 #B-2;1N =B?NrgrhrVr*r(rkrksr*rkceZdZddZy)r]ctj||||t|d|jd<t |d|jd<t |d|jd<yrrres r(r\z_dummyDirList.__init__rr*NrgrhrVr*r(r]r]r~r*r]ceZdZddZy)ructj||||t|d|jd<t |d|jd<y)Nr[r\)rr\r]rr^res r(r\z_dummyDirSelectBox.__init__sEdFD2DE)6tY)GI&(:4(JH%r*NrgrhrVr*r(rurusKr*ruceZdZddZy)rctj||||t|d|jd<t|d|jd<t |d|jd<t |d|jd<t |d|jd<t |d|jd<t |d|jd<t |d|jd<y) NrdrerfrgrOr[rhri)rr\r rrjrkr!res r(r\z_dummyExFileSelectBox.__init__sdFD2DE(4T8(DH%$0t$<D!(9$(IH%'5dG'DG$%3D%%@E")>tY)OI&&4T6&BF#*?j*QJ'r*NrgrhrVr*r(rrs Rr*rceZdZddZy)rctj||||t|d|jd<t|d|jd<t |d|jd<t |d|jd<y)Nr[rirnr)rr\r!rrkres r(r\z_dummyFileSelectBox.__init__ssdFD2DE)>tY)OI&*?j*QJ'(6tX(FH%+9$ +LK(r*NrgrhrVr*r(rrsMr*rceZdZddZy)r^cftj||||t|d|jd<y)Nr\)rr\rkrres r(r\z_dummyFileComboBox.__init__s.dFD2DE(6tX(FH%r*NrgrhrVr*r(r^r^sGr*r^ceZdZddZy)rctj||||t|d|jd<t|d|jd<t|d|jd<t|d|jd<y)Nrer rdr )rr\r rres r(r\z_dummyStdButtonBox.__init__ssdFD2DE$0t$<D!'3D''BG$(4T8(DH%&24&@F#r*NrgrhrVr*r(rrsAr*rceZdZddZy)_dummyNoteBookFramec4tj||||yrQrdres r(r\z_dummyNoteBookFrame.__init__rfr*N)rrhrVr*r(rrrir*rceZdZddZy)rhc4tj||||yrQrdres r(r\z_dummyPanedWindow.__init__rfr*NrgrhrVr*r(rhrhrir*rhcN|jjd|jS)zzReturns the qualified path name for the widget. Normally used to set default options for subwidgets. See tixwidgets.py tixOptionNamer{)rs r( OptionNamers 99>>/699 55r*chd}|jD]}|dz|zdz|zdz||zdz}|S)Nrfz{{z} {z - z}} )keys)dictstypes r( FileTypeListrsF A  HtOe #d *U 2T$Z ?% G Hr*ceZdZdZy)CObjViewaBThis file implements the Canvas Object View widget. This is a base class of IconView. It implements automatic placement/adjustment of the scrollbars according to the canvas objects inside the canvas subwidget. The scrollbars are adjusted so that the canvas is just large enough to see all the objects. N)rRrSrTrUrVr*r(rrs  r*rceZdZdZdifdZdZdZdZddZddZ d Z d Z d Z dd Z d ZdZdZdZdZddZdZdZdZy)Grida}The Tix Grid command creates a new window and makes it into a tixGrid widget. Additional options, may be specified on the command line or in the option database to configure aspects such as its cursor and relief. A Grid widget displays its contents in a two dimensional grid of cells. Each cell may contain one Tix display item, which may be in text, graphics or other formats. See the DisplayStyle class for more information about Tix display items. Individual cells, or groups of cells, can be formatted with a wide range of attributes, such as its color, relief and border. Subwidgets - NoneNc Jg}||_tj||d|||y)NtixGridr9rr\rs r(r\z Grid.__init__s&4FCDr*c>|jj|ddy)zRemoves the selection anchor.rrNr#ris r(rzGrid.anchor_clears  T8W-r*cZ|j|jj|ddS)z3Get the (x,y) coordinate of the current anchor cellrrIrr$r%ris r( anchor_getzGrid.anchor_get s"}}TWW\\$%@AAr*cB|jj|dd||y)z/Set the selection anchor to the cell at (x, y).rrNr#r3s r(rzGrid.anchor_sets  T8UAq1r*c||jj|dd|y|jj|dd||y)zdDelete rows between from_ and to inclusive. If to is not provided, delete only row at from_Nrrr#rs r( delete_rowzGrid.delete_rows7 : GGLLx 6 GGLLxr :r*c||jj|dd|y|jj|dd||y)zjDelete columns between from_ and to inclusive. If to is not provided, delete only column at from_Nrrr#rs r( delete_columnzGrid.delete_columns7 : GGLLx5 9 GGLLx5" =r*c>|jj|ddy)zUIf any cell is being edited, de-highlight the cell and applies the changes.editr Nr#ris r( edit_applyzGrid.edit_apply#s  T67+r*cB|jj|dd||y)zmHighlights the cell at (x, y) for editing, if the -editnotify command returns True for this cell.rrNr#r3s r(edit_setz Grid.edit_set(s  T65!Q/r*c^|r |ddk7rd|z}|jj|d|||S)z&Get the option value for cell at (x,y)rr2r2r#)r&rrr.s r(r2zGrid.entrycget-s4 fQi3&6\Fww||D+q!V<, 0 = B L8@ = B/ 64I2-r*rceZdZdZdifdZy) ScrolledGridzScrolled Grid widgetsNc Jg}||_tj||d|||y)NtixScrolledGridrrs r(r\zScrolledGrid.__init__s'4):FCLr*r_rVr*r(rrs#Mr*r)wr]warningsr[rwarnDeprecationWarningWINDOWTEXTSTATUS IMMEDIATEIMAGE IMAGETEXTBALLOONAUTO ACROSSTOPASCIICELLCOLUMN DECREASING INCREASINGINTEGERMAINMAXREALROWS_REGIONX_REGIONY_REGION TCL_DONT_WAITTCL_WINDOW_EVENTSTCL_FILE_EVENTSTCL_TIMER_EVENTSTCL_IDLE_EVENTSTCL_ALL_EVENTSrrXrmr __bases__rrrrrrr2rArSrXrarqrrrrXViewYViewrrSrWr]rcrrrrrrrrrrrrrrrrr r9rTButtonr  CheckbuttonrjEntryr FrameraLabelrListboxrMenur Menubuttonr ScrollbarrITextrr!rHrirrkr]rurrr^rrrhrrrrrrVr*r(rs4   -                         ~N~N@!Z!.)7)7Z#>>33tg=GGX3-93-p(?(?^3i362 2&*-y*-X(i(B,i,*,i,,K9K&(i(D)i)0))((I(8)y)*  2@=Iue@=DH HBB BB$!-9!-F1I1&/y&/P I ..8'2)'2R7 741910 BI BBiBB9B BI BBYB.Y.,TIT()(2 29 2Q?IueQ?f*:9*:\.< .[[*F  cyN)r s r _fixoptionszDialog._fixoptions rc|Srr)r widgetresults r _fixresultzDialog._fixresults rc |jD]\}}||j|<|j|j}| t } |j ||j j|jg|j|j}|j||}t||S#t|wxYwr) itemsr rr r_test_callbacktkcallcommand_optionsrr)r r kvr ss r showz Dialog.show sMMODAqDLLO$  >#%F '    ' t||Lfoodll.KLA*A v & v &s A#C Ccyrr)r r s r rzDialog._test_callback4rrr) __name__ __module__ __qualname__rrrrr#rrrr rrs G  ( rN)__all__tkinterrrrrrr r*s *6% % rtkinter/__pycache__/simpledialog.cpython-312.pyc000064400000042202152342670510015615 0ustar00 ֦i-dZddlddlmZmZddlmZGddZGddeZdd Zd Z Gd d eZ Gdde Z dZ Gdde Z dZGdde ZdZedk(r dZey y )a&This modules handles dialog boxes. It contains the following public symbols: SimpleDialog -- A simple but flexible modal dialog box Dialog -- a base class for dialogs askinteger -- get an integer from the user askfloat -- get a float from the user askstring -- get a string from the user )*)_get_temp_root_destroy_temp_root) messageboxc8eZdZdgddddfdZdZdZdZdZy) SimpleDialogNc|rt|||_nt||_|r6|jj||jj|t |jt |j|d|_|j jdtt|j|_ |jj||_ ||_ ||_ |jjd|jt!t#|D][}||} t%|j| ||fd} ||k(r| j't(d | jt*td ]|jj-d |j.|jj1|t3|j|y) N)class_i)textaspect)expandfillc$|j|SN)doneselfnums -/usr/lib64/python3.12/tkinter/simpledialog.pyz'SimpleDialog.__init__..9s 499S>r command)relief borderwidth)siderrWM_DELETE_WINDOW)Toplevelroottitleiconname _setup_dialogMessagemessagepackBOTHFrameframercanceldefaultbind return_eventrangelenButtonconfigRIDGELEFTprotocolwm_delete_window transient _place_window) rmasterr buttonsr.r-r$r rsbs r__init__zSimpleDialog.__init__!se  7DI (DI  IIOOE " II  u %dii tyytC@  .499%     z4#4#45W&C Atzz,0c ILAg~15 FF4F 2 ' -t/D/DE F#dii(rc|jj|jj|jj|jj |j Sr)r#wait_visibilitygrab_setmainloopdestroyrrs rgozSimpleDialog.goAsK !!#   xxrc|j|jjy|j|jyr)r.r#bellrrevents rr0zSimpleDialog.return_eventHs* <<  IINN  IIdll #rc|j|jjy|j|jyr)r-r#rHrrEs rr8zSimpleDialog.wm_delete_windowNs* ;;  IINN  IIdkk "rcF||_|jjyr)rr#quitrs rrzSimpleDialog.doneTs r)__name__ __module__ __qualname__r?rFr0r8rrrrrs,"d4D)@$ # rrcFeZdZdZd dZdZdZdZd dZd dZ d Z d Z y) DialogzZClass to open dialogs. This class is intended as a base class for custom dialogs Nc|}| t}tj|||j|!|j r|j ||r|j |t|||_d|_ t|}|j||_ |jdd|j|j||_ |jd|j t#|||jj%|j'|j)|j+|y)zInitialize a dialog. Arguments: parent -- a parent window (the application window) title -- the dialog title N)padxpadyr!)rr"r?withdrawwinfo_viewabler9r$r&parentresultr+body initial_focusr) buttonboxr7r-r: focus_setrArB wait_window)rrZr$r;r\s rr?zDialog.__init__`s >#%F$'   &"7"7"9 NN6 "  JJu d  T{!YYt_ qq !     %!%D  ($++6dF# $$&   rcfd|_tj|t|jy)zDestroy the windowN)r]r"rDrr;rEs rrDzDialog.destroys$!4;;'rcy)zcreate dialog body. return widget that should have initial focus. This method should be overridden, and is called by the __init__ method. NrQ)rr;s rr\z Dialog.body rcxt|}t|dd|jt}|j t ddt|dd|j }|j t dd|jd|j|jd |j |j y ) z[add standard button box. override if you do not want the standard buttons OK )r widthrr.rU)r rVrWCancel)r rgrrzN)r+r3okACTIVEr)r6r-r/)rboxws rr^zDialog.buttonboxs Dk 3TTWWf M Dqq) 3XR E Dqq) *dgg& *dkk*  rc|js|jjy|j|j  |j |j y#|j wxYwr)validater]r_rXupdate_idletasksapplyr-rIs rriz Dialog.oksV}}    ( ( *     JJL KKMDKKMs A..Bcp|j|jj|jyr)rZr_rDrIs rr-z Dialog.cancels' ;; " KK ! ! # rcy)zvalidate the data This method is called automatically to validate the data before the dialog is destroyed. By default, it always validates OK. rrQrEs rrnzDialog.validatesrcy)zprocess the data This method is called automatically to process the data, *after* the dialog is destroyed. By default, it does nothing. NrQrEs rrpz Dialog.applyrcrr) rNrOrP__doc__r?rDr\r^rir-rnrprQrrrSrSYs0 1f( *  rrSNc<|j|j|j}|j}|j }|j }||j r|j|j|z dzz}|j|j|z dzz}|j}|j} t|||z|z }t||}t|| |z|z }t|| }|jdk(r9t|d}n,|j!|z dz}|j#|z dz}|j%|||j'd||fz|j)y)Naquaz+%d+%d) wm_withdrawrowinfo_reqwidthwinfo_reqheightwinfo_vrootwidthwinfo_vrootheightwinfo_ismapped winfo_rootx winfo_width winfo_rooty winfo_height winfo_vrootx winfo_vrootyminmax_windowingsystemwinfo_screenwidthwinfo_screenheight wm_maxsize wm_geometry wm_deiconify) rlrZminwidth minheightmaxwidth maxheightxyvrootxvrootys rr:r:s|MMO!H!!#I!!#H##%I f335    F$6$6$88$C#I I    F$7$7$9I$E!#K K!! 6H$x/ 0 6N 6I% 1 2 6N   'Ar A  "X -! 3  ! ! #i /A 5LL9%MM(aV#$NNrc|jdk(r |jjdd|ddy|jdk(r|jddyy) Nrwz!::tk::unsupported::MacWindowStylestyle moveableModalr x11z-typedialog)rtkcall wm_attributes)rls rr&r&sMV#  5w_b *  u $ * %rc,eZdZ ddZdZdZdZy) _QueryDialogNcj||_||_||_||_tj |||yr)promptminvaluemaxvalue initialvaluerSr?)rr$rrrrrZs rr?z_QueryDialog.__init__s1      (fe,rc<d|_tj|yr)entryrSrDrEs rrDz_QueryDialog.destroys trct||jt}|jddtt |d|_|j jddttz|jF|j jd|j|j jdt|j S)N)r justifyrrU)rowrVstickyr)namer) Labelrr6gridWEntryrErinsert select_rangeEND)rr;rls rr\z_QueryDialog.body!s &t{{D 9 11Q'60  AAac2    ( JJ  a!2!2 3 JJ # #As +zzrc |j}|j 5||j kr&tjdd|j z|y|j 5||j kDr&tjdd|j z|y||_y #t$r(tjd|jdz|YywxYw) Nz Illegal valuez Please try again)rZrz Too smallz2The allowed minimum value is %s. Please try again.z Too largez2The allowed maximum value is %s. Please try again.r) getresult ValueErrorr showwarning errormessagerrr[)rr[s rrnz_QueryDialog.validate/s ^^%F == $$--)?  " "$&*mm4    == $$--)?  " "$&*mm4    9   " "!!$88    sB.C  C )NNNN)rNrOrPr?rDr\rnrQrrrrs!#-1 - rrceZdZdZdZy) _QueryIntegerzNot an integer.cT|j|jjSr)getintrgetrEs rrz_QueryInteger.getresultTs{{4::>>+,,rNrNrOrPrrrQrrrrQs $L-rrc 4t||fi|}|jS)zget an integer from the user Arguments: title -- the dialog title prompt -- the label text **kw -- see SimpleDialog class Return value is an integer )rr[r$rkwds r askintegerrXs eV*r*A 88OrceZdZdZdZy) _QueryFloatzNot a floating-point value.cT|j|jjSr) getdoublerrrEs rrz_QueryFloat.getresultjs~~djjnn.//rNrrQrrrrgs 0L0rrc 4t||fi|}|jS)zget a float from the user Arguments: title -- the dialog title prompt -- the label text **kw -- see SimpleDialog class Return value is a float )rr[rs raskfloatrns E6(R(A 88OrceZdZdZdZdZy) _QueryStringchd|vr|d|_|d=nd|_tj|g|i|y)Nshow)_QueryString__showrr?)rargsrs rr?z_QueryString.__init__~s: R<V*DK6 DKd0T0R0rctj||}|j|j|j|S)N)r)rr\r configure)rr;rs rr\z_QueryString.bodys5!!$/ ;; " OOO - rc6|jjSr)rrrEs rrz_QueryString.getresultszz~~rN)rNrOrPr?r\rrQrrrr}s1  rrc 4t||fi|}|jS)zget a string from the user Arguments: title -- the dialog title prompt -- the label text **kw -- see SimpleDialog class Return value is a string )rr[rs r askstringrs UF)b)A 88Or__main__ct}|fd}t|d|}|jt|d|j}|j|j y)Nct|dgdddd}t|jttddd tt dd d d tt ddy)NzThis is a test dialog. Would this have been an actual dialog, the buttons below would have been glowing in soft pink light. Do you believe this?)YesNorhrrvz Test Dialog)r r<r.r-r$Spamz Egg count)rzEgg weight (in tons)rd)rrz Egg label)rprintrFrrr)r#rs rdoitztest..doitsiT5 "9!" !, .A !$$&M *V[uE F (6#:Q$') * )FK0 1rTestrQuit)Tkr3r)rMrC)r#rtqs rtestrsNt 2 4fd 3  4faff 5  rr)rttkinterrrrrr"rSr:r&rrrrrrrrNrrQrrrs 677tI XI \:+@6@F-L- 0,0  < &  z0 F5rtkinter/__pycache__/simpledialog.cpython-312.opt-1.pyc000064400000042202152342670510016554 0ustar00 ֦i-dZddlddlmZmZddlmZGddZGddeZdd Zd Z Gd d eZ Gdde Z dZ Gdde Z dZGdde ZdZedk(r dZey y )a&This modules handles dialog boxes. It contains the following public symbols: SimpleDialog -- A simple but flexible modal dialog box Dialog -- a base class for dialogs askinteger -- get an integer from the user askfloat -- get a float from the user askstring -- get a string from the user )*)_get_temp_root_destroy_temp_root) messageboxc8eZdZdgddddfdZdZdZdZdZy) SimpleDialogNc|rt|||_nt||_|r6|jj||jj|t |jt |j|d|_|j jdtt|j|_ |jj||_ ||_ ||_ |jjd|jt!t#|D][}||} t%|j| ||fd} ||k(r| j't(d | jt*td ]|jj-d |j.|jj1|t3|j|y) N)class_i)textaspect)expandfillc$|j|SN)doneselfnums -/usr/lib64/python3.12/tkinter/simpledialog.pyz'SimpleDialog.__init__..9s 499S>r command)relief borderwidth)siderrWM_DELETE_WINDOW)Toplevelroottitleiconname _setup_dialogMessagemessagepackBOTHFrameframercanceldefaultbind return_eventrangelenButtonconfigRIDGELEFTprotocolwm_delete_window transient _place_window) rmasterr buttonsr.r-r$r rsbs r__init__zSimpleDialog.__init__!se  7DI (DI  IIOOE " II  u %dii tyytC@  .499%     z4#4#45W&C Atzz,0c ILAg~15 FF4F 2 ' -t/D/DE F#dii(rc|jj|jj|jj|jj |j Sr)r#wait_visibilitygrab_setmainloopdestroyrrs rgozSimpleDialog.goAsK !!#   xxrc|j|jjy|j|jyr)r.r#bellrrevents rr0zSimpleDialog.return_eventHs* <<  IINN  IIdll #rc|j|jjy|j|jyr)r-r#rHrrEs rr8zSimpleDialog.wm_delete_windowNs* ;;  IINN  IIdkk "rcF||_|jjyr)rr#quitrs rrzSimpleDialog.doneTs r)__name__ __module__ __qualname__r?rFr0r8rrrrrs,"d4D)@$ # rrcFeZdZdZd dZdZdZdZd dZd dZ d Z d Z y) DialogzZClass to open dialogs. This class is intended as a base class for custom dialogs Nc|}| t}tj|||j|!|j r|j ||r|j |t|||_d|_ t|}|j||_ |jdd|j|j||_ |jd|j t#|||jj%|j'|j)|j+|y)zInitialize a dialog. Arguments: parent -- a parent window (the application window) title -- the dialog title N)padxpadyr!)rr"r?withdrawwinfo_viewabler9r$r&parentresultr+body initial_focusr) buttonboxr7r-r: focus_setrArB wait_window)rrZr$r;r\s rr?zDialog.__init__`s >#%F$'   &"7"7"9 NN6 "  JJu d  T{!YYt_ qq !     %!%D  ($++6dF# $$&   rcfd|_tj|t|jy)zDestroy the windowN)r]r"rDrr;rEs rrDzDialog.destroys$!4;;'rcy)zcreate dialog body. return widget that should have initial focus. This method should be overridden, and is called by the __init__ method. NrQ)rr;s rr\z Dialog.body rcxt|}t|dd|jt}|j t ddt|dd|j }|j t dd|jd|j|jd |j |j y ) z[add standard button box. override if you do not want the standard buttons OK )r widthrr.rU)r rVrWCancel)r rgrrzN)r+r3okACTIVEr)r6r-r/)rboxws rr^zDialog.buttonboxs Dk 3TTWWf M Dqq) 3XR E Dqq) *dgg& *dkk*  rc|js|jjy|j|j  |j |j y#|j wxYwr)validater]r_rXupdate_idletasksapplyr-rIs rriz Dialog.oksV}}    ( ( *     JJL KKMDKKMs A..Bcp|j|jj|jyr)rZr_rDrIs rr-z Dialog.cancels' ;; " KK ! ! # rcy)zvalidate the data This method is called automatically to validate the data before the dialog is destroyed. By default, it always validates OK. rrQrEs rrnzDialog.validatesrcy)zprocess the data This method is called automatically to process the data, *after* the dialog is destroyed. By default, it does nothing. NrQrEs rrpz Dialog.applyrcrr) rNrOrP__doc__r?rDr\r^rir-rnrprQrrrSrSYs0 1f( *  rrSNc<|j|j|j}|j}|j }|j }||j r|j|j|z dzz}|j|j|z dzz}|j}|j} t|||z|z }t||}t|| |z|z }t|| }|jdk(r9t|d}n,|j!|z dz}|j#|z dz}|j%|||j'd||fz|j)y)Naquaz+%d+%d) wm_withdrawrowinfo_reqwidthwinfo_reqheightwinfo_vrootwidthwinfo_vrootheightwinfo_ismapped winfo_rootx winfo_width winfo_rooty winfo_height winfo_vrootx winfo_vrootyminmax_windowingsystemwinfo_screenwidthwinfo_screenheight wm_maxsize wm_geometry wm_deiconify) rlrZminwidth minheightmaxwidth maxheightxyvrootxvrootys rr:r:s|MMO!H!!#I!!#H##%I f335    F$6$6$88$C#I I    F$7$7$9I$E!#K K!! 6H$x/ 0 6N 6I% 1 2 6N   'Ar A  "X -! 3  ! ! #i /A 5LL9%MM(aV#$NNrc|jdk(r |jjdd|ddy|jdk(r|jddyy) Nrwz!::tk::unsupported::MacWindowStylestyle moveableModalr x11z-typedialog)rtkcall wm_attributes)rls rr&r&sMV#  5w_b *  u $ * %rc,eZdZ ddZdZdZdZy) _QueryDialogNcj||_||_||_||_tj |||yr)promptminvaluemaxvalue initialvaluerSr?)rr$rrrrrZs rr?z_QueryDialog.__init__s1      (fe,rc<d|_tj|yr)entryrSrDrEs rrDz_QueryDialog.destroys trct||jt}|jddtt |d|_|j jddttz|jF|j jd|j|j jdt|j S)N)r justifyrrU)rowrVstickyr)namer) Labelrr6gridWEntryrErinsert select_rangeEND)rr;rls rr\z_QueryDialog.body!s &t{{D 9 11Q'60  AAac2    ( JJ  a!2!2 3 JJ # #As +zzrc |j}|j 5||j kr&tjdd|j z|y|j 5||j kDr&tjdd|j z|y||_y #t$r(tjd|jdz|YywxYw) Nz Illegal valuez Please try again)rZrz Too smallz2The allowed minimum value is %s. Please try again.z Too largez2The allowed maximum value is %s. Please try again.r) getresult ValueErrorr showwarning errormessagerrr[)rr[s rrnz_QueryDialog.validate/s ^^%F == $$--)?  " "$&*mm4    == $$--)?  " "$&*mm4    9   " "!!$88    sB.C  C )NNNN)rNrOrPr?rDr\rnrQrrrrs!#-1 - rrceZdZdZdZy) _QueryIntegerzNot an integer.cT|j|jjSr)getintrgetrEs rrz_QueryInteger.getresultTs{{4::>>+,,rNrNrOrPrrrQrrrrQs $L-rrc 4t||fi|}|jS)zget an integer from the user Arguments: title -- the dialog title prompt -- the label text **kw -- see SimpleDialog class Return value is an integer )rr[r$rkwds r askintegerrXs eV*r*A 88OrceZdZdZdZy) _QueryFloatzNot a floating-point value.cT|j|jjSr) getdoublerrrEs rrz_QueryFloat.getresultjs~~djjnn.//rNrrQrrrrgs 0L0rrc 4t||fi|}|jS)zget a float from the user Arguments: title -- the dialog title prompt -- the label text **kw -- see SimpleDialog class Return value is a float )rr[rs raskfloatrns E6(R(A 88OrceZdZdZdZdZy) _QueryStringchd|vr|d|_|d=nd|_tj|g|i|y)Nshow)_QueryString__showrr?)rargsrs rr?z_QueryString.__init__~s: R<V*DK6 DKd0T0R0rctj||}|j|j|j|S)N)r)rr\r configure)rr;rs rr\z_QueryString.bodys5!!$/ ;; " OOO - rc6|jjSr)rrrEs rrz_QueryString.getresultszz~~rN)rNrOrPr?r\rrQrrrr}s1  rrc 4t||fi|}|jS)zget a string from the user Arguments: title -- the dialog title prompt -- the label text **kw -- see SimpleDialog class Return value is a string )rr[rs r askstringrs UF)b)A 88Or__main__ct}|fd}t|d|}|jt|d|j}|j|j y)Nct|dgdddd}t|jttddd tt dd d d tt ddy)NzThis is a test dialog. Would this have been an actual dialog, the buttons below would have been glowing in soft pink light. Do you believe this?)YesNorhrrvz Test Dialog)r r<r.r-r$Spamz Egg count)rzEgg weight (in tons)rd)rrz Egg label)rprintrFrrr)r#rs rdoitztest..doitsiT5 "9!" !, .A !$$&M *V[uE F (6#:Q$') * )FK0 1rTestrQuit)Tkr3r)rMrC)r#rtqs rtestrsNt 2 4fd 3  4faff 5  rr)rttkinterrrrrr"rSr:r&rrrrrrrrNrrQrrrs 677tI XI \:+@6@F-L- 0,0  < &  z0 F5rtkinter/__pycache__/commondialog.cpython-312.opt-2.pyc000064400000003543152342670510016561 0ustar00 ֦i .dgZddlmZmZGddZy)Dialog)_get_temp_root_destroy_temp_rootc0eZdZdZddZdZdZdZdZy)rNc F||jd}||_||_y)Nparent)getmasteroptions)selfr r s -/usr/lib64/python3.12/tkinter/commondialog.py__init__zDialog.__init__s# >[[*F  cyN)r s r _fixoptionszDialog._fixoptions rc|Srr)r widgetresults r _fixresultzDialog._fixresults rc |jD]\}}||j|<|j|j}| t } |j ||j j|jg|j|j}|j||}t||S#t|wxYwr) itemsr rr r_test_callbacktkcallcommand_optionsrr)r r kvr ss r showz Dialog.show sMMODAqDLLO$  >#%F '    ' t||Lfoodll.KLA*A v & v &s A#C Ccyrr)r r s r rzDialog._test_callback4rrr) __name__ __module__ __qualname__rrrrr#rrrr rrs G  ( rN)__all__tkinterrrrrrr r*s *6% % rtkinter/__pycache__/filedialog.cpython-312.opt-2.pyc000064400000050536152342670510016214 0ustar00 ֦i[: gdZddlZddlZddlmZmZmZmZmZm Z m Z m Z m Z m Z mZmZmZmZmZmZddlmZddlmZddlmZiZGddZGd d eZGd d eZGd dej*ZGddeZGddeZGddej*Z dZ!dZ"dZ#ddZ$ddZ%ddZ&dZ'dZ(e)dk(re(yy) ) FileDialogLoadFileDialogSaveFileDialogOpenSaveAs Directoryaskopenfilenameasksaveasfilenameaskopenfilenames askopenfile askopenfiles asksaveasfile askdirectoryN)FrameLEFTYESBOTTOMEntryTOPButtonTkXToplevelRIGHTYENDListboxBOTH Scrollbar)Dialog) commondialog) _setup_dialogceZdZ dZddZej dddfdZddZdZ d Z d Z d Z d Z d ZddZdZdZddZdZdZy)rzFile Selection DialogNc* | |j}||_d|_t||_|jj||jj |t |jt|j|_|jjttt|j|_ |jjtt|jjd|jt|j|_|j jt"t|j jd|j$t|j|_|j&jt(t*t-|j&|_|j.jt0t2t5|j&d|j.df|_|j6jt0t(t*|j6j9}|j6j9|dd|ddz|j6jd |j:|j6jd |j<|j.j?|j6d f t-|j&|_ |j@jtBt2t5|j&d|j@df|_"|jDjtBt(t*|j@j?|jDd f |jDj9}|jDj9|dd|ddz|jDjd |jF|jDjd |jHtK|jd |jL|_'|jNjtBtK|jd|j$|_(|jPjtBt(tK|jd|jR|_*|jTjt0|jjWd|jR|jjd|jR|jjd|jRy)N)sidefillz)expandr&rset)exportselectionyscrollcommand)r%r'r&zzyview)commandOK)textr-)r%Filter)r%r'CancelWM_DELETE_WINDOWzz),titlemaster directoryrtopiconnamer"rbotframepackrrr selectionbindok_eventfilterrfilter_commandmidframerrrfilesbarrrrfilesbindtagsfiles_select_eventfiles_double_eventconfigdirsbarrdirsdirs_select_eventdirs_double_eventr ok_command ok_button filter_buttoncancel_command cancel_buttonprotocol)selfr4r3btagss +/usr/lib64/python3.12/tkinter/filedialog.py__init__zFileDialog.__init__:s =$**% F# u % dhhdhh  Q/txx a0 J 6DHHo  c* T%8%89dhh  #D1!$--0  A.T]]A-1]]E,BD  U3T: ##% E!"Ibq 12 +T-D-DE 2D4K4KL djj'%:; /  t!,DMM1,0LL%+@B  D48 TYY$89 ""$ 59uRay01 *D,B,BC 143I3IJ &*)-: &#DMM)1,0,?,?A T#6#DMM)1,0,?,?A U+ ,d.A.AB  i!4!45  i!4!45*cb|r|tvrt|\|_}nmtjj |}tjj |r||_n'tjj |\|_}|j|j||j||j|jj|jj|jjd|_|j j#|rS|j%\}}|jr)tjj'|j}||ft|<|jj)|jSN) dialogstatesr5ospath expanduserisdirsplit set_filter set_selectionr>r: focus_setr6wait_visibilitygrab_sethowr4mainloop get_filterdirnamedestroy)rP dir_or_filepatterndefaultkeyr5s rRgoz FileDialog.gozs- 3,&&23&7 #DNG'',,[9Kww}}[)!,*,''-- *D' 0 7#    "   "   !%!2 IwxxGGOODHH5 )7 2L  xxrTcF||_|jjyrX)rdr4quit)rPrds rRrozFileDialog.quits rTc$|jyrX)r>rPevents rRrIzFileDialog.dirs_double_events rTc|j\}}|jjd}tjj tjj |j|}|j||yNactive) rfrGgetrZr[normpathjoinr5r_)rPrrdirpatsubdirs rRrHzFileDialog.dirs_select_eventsY??$Sx(ggrww||DNNFCD S!rTc$|jyrXrJrqs rRrDzFileDialog.files_double_event  rTc\|jjd}|j|yrt)rArvr`)rPrrfiles rRrCzFileDialog.files_select_events"zz~~h' 4 rTc$|jyrXr}rqs rRr<zFileDialog.ok_eventr~rTcB|j|jyrX)ro get_selectionrPs rRrJzFileDialog.ok_commands $$$&'rTc|j\}} tj|}||_|j|||jtjg}g}|D]{}tjj||}tjj|r|j|Ttj||sk|j|}|jj!dt"|D]"}|jj%t"|$|j&j!dt"|D]"}|j&j%t"|$tjj)|j+\} } | tj,k(rd} |j/| y#t$r|jj YywxYw)NrrV)rfrZlistdirOSErrorr4bellr5r_sortpardirr[rxr]appendfnmatchrGdeleterinsertrAr^rcurdirr`) rPrrryrznamessubdirs matchingfilesnamefullnameheadtails rRr>zFileDialog.filter_commandsq??$S JJsOE S! 99+ Dww||C.Hww}}X&t$s+$$T*  C D II  S$ ' !S!!D JJ  c4 ("WW]]4#5#5#78 d 299 Rd 4 -  KK     sG #G10G1c\|jj}tjj |}|ddtj k(stjj |r tjj|d}tjj|S)NrU) r=rvrZr[r\sepr]rxr^)rPr=s rRrfzFileDialog.get_filtersn"##F+ "#;"&& BGGMM&$9WW\\&#.Fww}}V$$rTcx|jj}tjj |}|SrX)r:rvrZr[r\rPrs rRrzFileDialog.get_selections-~~!!#ww!!$' rTc$|jyrX)rorqs rRrMzFileDialog.cancel_commands  rTctjj|sV tj}|r?tjj ||}tjj |}|jjdt|jjttjj |xstj|xsdy#t$rd}YwxYw)NrrU) rZr[isabsgetcwdrrxrwr=rrrr)rPryrzpwds rRr_zFileDialog.set_filtersww}}S! iikggll3,gg&&s+ 1c" 3 S-=BIIszc JK   sC++ C98C9c|jjdt|jjttj j |j|y)Nr)r:rrrrZr[rxr5rs rRr`zFileDialog.set_selections= a% c277<<#EFrTrX)__name__ __module__ __qualname__r3rSrZrrmrorIrHrDrCr<rJr>rfrrMr_r`rTrRrr!sk* $E>6@ YYRT2" !(!8%  LGrTrceZdZ dZdZy)rzLoad File Selection Dialogc|j}tjj|s|jj y|j |yrX)rrZr[isfiler4rrors rRrJzLoadFileDialog.ok_commands;!!#ww~~d# KK    IIdOrTNrrrr3rJrrTrRrrsB (ErTrceZdZ dZdZy)rzSave File Selection Dialogc|j}tjj|ritjj |r|j j yt|jdd|dddd}|jdk7r]ytjj|\}}tjj |s|j j y|j|y) Nz Overwrite Existing File QuestionzOverwrite existing file ? questheadr+)Yesr1)r3r/bitmaprkstringsr) rrZr[existsr]r4rr r6numr^ro)rPrdrrs rRrJzSaveFileDialog.ok_commands!!# 77>>$ ww}}T"   "txx?=AC) 0 2A uuzt,JD$77==&   " $rTNrrrTrRrrsJ (ErTrceZdZdZdZy)_Dialogcn t|jd|jd<y#t$rYywxYw)N filetypes)tupleoptionsKeyErrorrs rR _fixoptionsz_Dialog._fixoptions2s5 (-dll;.G(HDLL %   s %( 44c|rM |j}tjj |\}}||j d<||j d<||_|S#t$rYTwxYw)N initialdir initialfile)stringAttributeErrorrZr[r^rfilename)rPwidgetresultr[rs rR _fixresultz_Dialog._fixresult9sg  v.JD$)-DLL &*.DLL '  "  s A A%$A%N)rrrrrrrTrRrr0s  rTrceZdZ dZdZy)rtk_getOpenFilec t|tr\t|Dcgc]}t|d|c}}|r4tjj |d\}}||j d<|S|jjs9d|j vr+|j||jj|Stj|||Scc}w)Nrrrmultiple) isinstancergetattrrZr[r^rtk wantobjectsr splitlistr)rPrrrr[rs rRrzOpen._fixresultQs fe $VDVGAx3VDEFWW]]6!95 d-1 \*Myy$$&:+E??6699+>+>v+FG G!!$77EsCNrrrr-rrrTrRrrLs G 8rTrceZdZ dZy)rtk_getSaveFileN)rrrr-rrTrRrr`s #GrTrceZdZ dZdZy)rtk_chooseDirectorycn|r |j}||jd<||_|S#t$rY#wxYw)Nr)rrrr5)rPrrs rRrzDirectory._fixresultlsC   *0DLL & "  s ( 44NrrrTrRrrgs"G rTrc 6 tdi|jSNrrshowrs rRrr}s ?'?   !!rTc 6 tdi|jSr)rrrs rRr r s#  G  ! ! ##rTc @ d|d<tdi|jS)Nr+rrrrs rRr r s( GJ ?'?   !!rTc T tdi|j}|r t||Syr)rropenmoderrs rRr r s,>g##%HHd## rTc n tdi|}|r&g}|D]}|jt|||}|Sr)r rr)rrrAofilesrs rRr r sE  'w 'E H MM$x. / LrTc T tdi|j}|r t||Syr)rrrrs rRr r s.A  %%'HHd## rTc 6 tdi|jSr)rrrs rRrrs3  w  $ $ &&rTc t}|jt|}|jd}t |}|jd}t ||d} ddl}|j|jd|j|j}tdg} t|d}|jt d |j#|t%} t d | j#|y#ttf$rY|wxYw#t $r }t d t |Yd}~zd}~wwxYw) Ntest)rlzutf-8rrV)z all filesrU)rrzCould not open File: rsaveas)rwithdrawrrmrprintlocale setlocaleLC_ALL nl_langinfoCODESET ImportErrorrrrclose BaseExceptionencoder ) rootfdloadfilesavefileencr openfilenamefpexcsaveasfilenames rRrrs& 4DMMO  Buuu H  Buuu H (H C r*  0 !,>+?@L  S !   &,%%c*+%&N (N))#./%  (     %& c s*%;D .D DD E )EE __main__)r)w)*__all__rrZtkinterrrrrrrrrrrrrrrrrtkinter.dialogr r!tkinter.simpledialogr"rYrrrrrrrrr r r r r rrrrrTrRrs  K  " . EGEGP Z Zrl!!8878(W ##," $ ""'(0V zFrTtkinter/__pycache__/__main__.cpython-312.opt-2.pyc000064400000000613152342670510015624 0ustar00 ֦i ddlZejdjdrdejd<ddlmZey)Nz __main__.pyzpython -m tkinter)_test)sysargvendswithrmain)/usr/lib64/python3.12/tkinter/__main__.pyr s6 88A; &%CHHQKr tkinter/__pycache__/ttk.cpython-312.pyc000064400000217617152342670510013764 0ustar00 ֦i"dZdZdZgdZddlZddlmZmZmZmZdBdZ dCdZ d Z dBd Z dBd Z dDd Zd ZdZdZdZdZdZdZdZdEdZGddeZGddej4ZGddeZGddeZGddeej:ZGd d!eZGd"d#eZGd$d%eZ Gd&d'eZ!e!Z"Gd(d)eZ#Gd*d+eZ$Gd,d-eejJZ&e&Z%Gd.d/eZ'Gd0d1eZ(Gd2d3eejRZ)Gd4d5eejTZ*Gd6d7eZ+Gd8d9eZ,Gd:d;eZ-Gd<d=eej\ej^Z0Gd>d?eZ1Gd@dAe#Z2y)FaTtk wrapper. This module provides classes to allow using Tk themed widget set. Ttk is based on a revised and enhanced version of TIP #48 (http://tip.tcl.tk/48) specified style engine. Its basic idea is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. Widget class bindings are primarily responsible for maintaining the widget state and invoking callbacks, all aspects of the widgets appearance lies at Themes. z0.3.1z!Guilherme Polo )Button CheckbuttonComboboxEntryFrameLabel Labelframe LabelFrame MenubuttonNotebook Panedwindow PanedWindow Progressbar RadiobuttonScale Scrollbar SeparatorSizegripSpinboxStyleTreeview LabeledScale OptionMenu tclobjs_to_py setup_masterN)_flatten_join _stringify _splitdictcf|r t|}|St|ttfr t |}|S)zInternal function.)r isinstancelisttupler)valuescripts $/usr/lib64/python3.12/tkinter/ttk.py_format_optvaluer' s6 5! L ED%= )e  Lcg}|jD]>\}}|r||vs |jd|z|$|jt||@t|S)zFormats optdict to a tuple to pass it to tk.call. E.g. (script=False): {'foreground': 'blue', 'padding': [1, 2, 3, 4]} returns: ('-foreground', 'blue', '-padding', '1 2 3 4')-%s)itemsappendr'r)optdictr%ignoreoptsoptr$s r&_format_optdictr1*s] Dmmo UF* KK $  ,UF;< & D>r(cg}|D]S^}}t|dk(r |dxsd}ndj|}|j||C|j|U|S)Nr )lenjoinr,)r+opt_valstatevals r&_mapdict_valuesr;:sdG  u:?!HNEHHUOEu ? NN3  Nr(c g}|jD].\}}|jd|ztt||f0t |S)zFormats mapdict to pass it to tk.call. E.g. (script=False): {'expand': [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])]} returns: ('-expand', '{active selected} grey focus {1, 2, 3, 4}')r*)r+extendr'r;r)mapdictr%r/r0r$s r&_format_mapdictr?OsQ Dmmo U US[%oe&r(cXd}d}|dvr_|dk(r$|d}tt|dd}|d|}n)|dd\}} tt|dd} |d| d| }t||}n(|d k(r#|d}t|dkDrt |d|f}|rd |z}dj |}||fS) zAFormats args and kw according to the given element factory etype.N)imagevsapirBrr3r5fromz{%s})rr;r1r6r'r7) etyper%argskwspecr/iname imagespec class_namepart_idstatemaps r&_format_elemcreaterO`s D D "" G GEod12h78I#Y/D#'r( J_T!"X67H!+Wh?Dr6* &Aw t9q=$T!Wf57D }xx~ :r(cg}|D]}|\}}|xsi}djt|dd}d|z||rd|znd}d|vrZ|j|dz||z }t|d||\} }|j| ||z}|jdd|zz|j|d j||fS) a$Formats a layout list so we can pass the result to ttk::style layout and ttk::style settings. Note that the layout doesn't have to be a list necessarily. E.g.: [("Menubutton.background", None), ("Menubutton.button", {"children": [("Menubutton.focus", {"children": [("Menubutton.padding", {"children": [("Menubutton.label", {"side": "left", "expand": 1})] })] })] }), ("Menubutton.indicator", {"side": "right"}) ] returns: Menubutton.background Menubutton.button -children { Menubutton.focus -children { Menubutton.padding -children { Menubutton.label -side left -expand 1 } } } Menubutton.indicator -side rightr5T)childrenz %sr4rQz -children {z%s} )r7r1r,_format_layoutlist) layoutindent indent_sizer% layout_elemelemr/foptshead newscripts r&rSrSs8F  dzrt]CD<% R/OP   MM$/ 0 k !F 24 3CV! Iv MM) $ k !F MM%3<0 1 MM$ " 99V f $$r(c <g}|jD]v\}}|jdr6djt|dd}|j d|d|d|jdr6djt |dd}|j d|d|dd|vr1|dsd }nt |d\}}|j d |d |d |jd s|d }|d}d}|t|kr2t||ds#|dz }|t|krt||ds#|d|} |t|kr ||r||ni} t|dg| i| \} }|j d|d|d| d|ydj|S)zReturns an appropriate script, based on settings, according to theme_settings definition to be used by theme_settings and theme_create. configurer5Tzttk::style configure ;mapzttk::style map rTnullzttk::style layout z { z }zelement createrr3r+zttk::style element create rR) r+getr7r1r,r?rSr6hasattrrO) settingsr%namer/s_eoptsrFargcelemargselemkwrIs r&_script_from_settingsrksFnn& d 88K k):DABA MM4C D 88E?ed; t >)$x.91 MMT1E F 88$ %)*E!HEDU#GE$K,I U#GE$K,IQt}H$(3u:$5%+U4[2F+E4M(MfMJD$ MMeT4) *='B 99V r(ct|tr|Sg}t|}t||D]\}}t |drt|j }n:t|tr|j }nt|t tfs|f}t |dr t|}|jg|||S)ztConstruct a list from the given statespec tuple according to the accepted statespec accepted by _format_mapdict.typename) r!striterziprbsplitr#r"r,)stupleresultitr9r:s r&_list_from_statespecrus&# F fB"bk s 5* %J$$&E s #KKMEEE4=1HE 3 #c(C mmsm$" Mr(c\|j|}g}d}|t|kr||}i}|j||f|dz }|t|krL|||dz\}}|jdsn/|dd}|dz }|dk(r t ||}|||<|t|krL|t|kr|S)zpConstruct a list from the tuple returned by ttk::layout, this is somewhat the reverse of _format_layoutlist.rr3rD-NrQ) splitlistr6r, startswith_list_from_layouttuple)tkltupleresindxrdr/r0r:s r&rzrzs\\& !F C D V d| D$<   S[ d4!8,HC>>#&ab'C AIDj ,R5DIS[ V & Jr(ct|}|j||z}t|dzr|St||tS)ahFormat options then call Tk command with args and options and return the appropriate result. If no option is specified, a dict is returned. If an option is specified with the None value, the value for that option is returned. Otherwise, the function just sets the passed options and the caller shouldn't be expecting a return value anyway.rD)conv)r1callr6r _tclobj_to_py)r{optionsrGr}s r& _val_or_dictrsBg&G "''D7N $C 7|a b#M 22r(c`t|} t|}|S#ttf$rY|SwxYw)zAConverts a value to, hopefully, a more appropriate Python object.)rnint ValueError TypeError)r$s r&_convert_stringvalr s> JE E  L  "  L s --c^t|trd|vr t|}|St|}|S)N.)r!rnfloatr)xs r& _to_numberr*s3!S !8aA HAA Hr(c|rWt|drKt|ts;t|ddddk(r t |}|St t t|}|St|dr t|}|S)z8Return value converted from Tcl object to Python object.__len__rrmN StateSpec)rbr!rngetattrrur"r_r)r:s r&rr2ss wsI&z#s/C 3q6:t , ;&s+C J s-s34C J j ! % Jr(cR|jD]\}}t|||<|S)zOReturns adict with its values converted from Tcl objects to Python objects.)r+r)adictr0r:s r&rr?s-KKMS"3'c " Lr(c2|tj}|S)aIf master is not None, itself is returned. If master is None, the default master is returned if there is one, otherwise a new master is created and returned. If it is not allowed to use the default root and master is None, RuntimeError is raised.)tkinter_get_default_root)masters r&rrGs~**, Mr(cjeZdZdZdZddZddZddZddZddZ d Z d Z d Z dd Z d ZdZddZy)rzManipulate style database.z ttk::styleNc^t|}||_|jj|_yN)rrr{)selfrs r&__init__zStyle.__init__Xs"f% ++..r(c d|d||<t|j||jd|}|s|r|Sy)zQuery or sets the default value of the specified option(s) in style. Each key in kw is an option and each value is either a string or a sequence identifying the value for that option.Nr])rr{_name)rstyle query_optrHrss r&r]zStyle.configure^s<   ByMdggr4::{EJ YMr(c |O|jj|jd|d|z}t|jj |S|jj|jd|gt |}t |j|jDcic]*\}}|t|jj |,c}}Scc}}w)aSQuery or sets dynamic values of the specified option(s) in style. Each key in kw is an option and each value should be a list or a tuple (usually) containing statespecs grouped in tuples, or list, or something else of your preference. A statespec is compound of one or more states and then a value.r_r*)r{rrrurxr?rr+)rrrrHrskvs r&r_z Style.mapks  WW\\$**eUEI >r(ct|dg|i|\}}|jj|jdd|||g|y)z9Create a new element in the current theme of given etype.FelementcreateN)rOr{rr)r elementnamerFrGrHrIr/s r&element_createzStyle.element_createsG'uBtBrB d TZZHk5   r(c td|jj|jj|jddDS)z:Returns the list of elements defined in the current theme.c3>K|]}|jdywrwNlstrip).0ns r& z&Style.element_names..s!;-:qQXXc]-:rnamesr#r{rxrrrs r& element_nameszStyle.element_namessB;DGG,=,= GGLLY 8-:;; ;r(c td|jj|jj|jdd|DS)z)Return the list of elementname's options.c3>K|]}|jdywrr)ros r&rz(Style.element_options..s$J-IqQXXc]-Irrrr)rrs r&element_optionszStyle.element_optionssIJDGG,=,= GGLLY ; G-IJJ Jr(c |r t|nd}|r-|jj|jdd|d|d|y|jj|jdd|d|y)a.Creates a new theme. It is an error if themename already exists. If parent is specified, the new theme will inherit styles, elements and layouts from the specified parent theme. If settings are present, they are expected to have the same syntax used for theme_settings.r4themerz-parentz -settingsNrkr{rr)r themenameparentrcr%s r& theme_createzStyle.theme_creates^5=&x0"  GGLLWh 6; 8 GGLLWh V %r(clt|}|jj|jdd||y)aTemporarily sets the current theme to themename, apply specified settings and then restore the previous theme. Each key in settings is a style and each value may contain the keys 'configure', 'map', 'layout' and 'element create' and they are expected to have the same format as specified by the methods configure, map, layout and element_create respectively.rrcNr)rrrcr%s r&theme_settingszStyle.theme_settingss*'x0  TZZ*iHr(c|jj|jj|jddS)z#Returns a list of all known themes.rr)r{rxrrrs r& theme_nameszStyle.theme_namess,ww  djj'7!KLLr(cv||jjdS|jjd|y)zIf themename is None, returns the theme in use, otherwise, set the current theme to themename, refreshes all widgets and emits a <> event.Nzreturn $ttk::currentThemez ttk::setTheme)r{evalr)rrs r& theme_usezStyle.theme_uses4  77<< ;< <  _i0r(rNN)__name__ __module__ __qualname____doc__rrr]r_rrTrrrrrrrrAr(r&rrSsK$ E! A" (>V; J %" IM 1r(rc.eZdZdZddZdZddZddZy)Widgetz!Base class for Tk themed widgets.Nc`t|}tjj||||y)aConstructs a Ttk Widget with the parent master. STANDARD OPTIONS class, cursor, takefocus, style SCROLLABLE WIDGET OPTIONS xscrollcommand, yscrollcommand LABEL WIDGET OPTIONS text, textvariable, underline, image, compound, width WIDGET STATES active, disabled, focus, pressed, selected, background, readonly, alternate, invalid )rHN)rrrr)rr widgetnamerHs r&rzWidget.__init__s)(f%fjR@r(cR|jj|jd||S)zReturns the name of the element at position x, y, or the empty string if the point does not lie within any element. x and y are pixel coordinates relative to the widget.identifyr{r_wrrys r&rzWidget.identifys! ww||DGGZA66r(c |jj|jj|jddj |}|r |||i|S|S)a1Test the widget's state. If callback is not specified, returns True if the widget state matches statespec and False otherwise. If callback is specified, then it will be invoked with *args, **kw if the widget state matches statespec. statespec is expected to be a sequence.instater5)r{ getbooleanrrr7)r statespeccallbackrGrHrets r&rzWidget.instatesWgg   TWWi)1DEG 8'T(R( ( r(c |dj|}|jjt|jj |j d|S)aModify or inquire widget state. Widget state is returned if statespec is None, otherwise it is set according to the statespec flags and then a new state spec is returned indicating which flags were changed. statespec is expected to be a sequence.r5r9)r7r{rxrnrr)rrs r&r9z Widget.state)sG  +Iww  TWW\\$''7I%N!OPPr(r)rrrrrrrr9rAr(r&rrs+A07  Qr(rceZdZdZddZdZy)rzcTtk Button widget, displays a textual label and/or image, and evaluates a command when pressed.Nc 4tj||d|y)aConstruct a Ttk Button widget with the parent master. STANDARD OPTIONS class, compound, cursor, image, state, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS command, default, width z ttk::buttonNrrrrrHs r&rzButton.__init__:s fmR8r(cN|jj|jdS)z/Invokes the command associated with the button.invokerrs r&rz Button.invokeIsww||DGGX..r(rrrrrrrrAr(r&rr6s) 9/r(rceZdZdZddZdZy)rz;Ttk Checkbutton widget which is either in on- or off-state.Nc 4tj||d|y)a'Construct a Ttk Checkbutton widget with the parent master. STANDARD OPTIONS class, compound, cursor, image, state, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS command, offvalue, onvalue, variable zttk::checkbuttonNrrs r&rzCheckbutton.__init__Q f&8"=r(cN|jj|jdS)aWToggles between the selected and deselected states and invokes the associated command. If the widget is currently selected, sets the option variable to the offvalue option and deselects the widget; otherwise, sets the option variable to the option onvalue. Returns the result of the associated command.rrrs r&rzCheckbutton.invoke`sww||DGGX..r(rrrAr(r&rrNsE >/r(rc*eZdZdZddZdZdZdZy)rzeTtk Entry widget displays a one-line text string and allows that string to be edited by the user.Nc <tj|||xsd|y)aConstructs a Ttk Entry widget with the parent master. STANDARD OPTIONS class, cursor, style, takefocus, xscrollcommand WIDGET-SPECIFIC OPTIONS exportselection, invalidcommand, justify, show, state, textvariable, validate, validatecommand, width VALIDATION MODES none, key, focus, focusin, focusout, all z ttk::entryNr)rrwidgetrHs r&rzEntry.__init__os ff&< bAr(cn|j|jj|jd|S)zqReturn a tuple of (x, y, width, height) which describes the bounding box of the character given by index.bbox_getintsr{rr)rindexs r&rz Entry.bboxs(}}TWW\\$''65ABBr(cR|jj|jd||S)zxReturns the name of the element at position x, y, or the empty string if the coordinates are outside the window.rrrs r&rzEntry.identify!ww||DGGZA66r(c|jj|jj|jdS)zForce revalidation, independent of the conditions specified by the validate option. Returns False if validation fails, True if it succeeds. Sets or clears the invalid state accordingly.validater{rrrrs r&rzEntry.validates,ww!!$'',,tww "CDDr(r)rrrrrrrrrAr(r&rrks(B&C 7 Er(rc&eZdZdZddZddZdZy)rzMTtk Combobox widget combines a text field with a pop-down list of values.Nc 4tj||dfi|y)aConstruct a Ttk Combobox widget with the parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS exportselection, justify, height, postcommand, state, textvariable, values, width z ttk::comboboxNrrrs r&rzCombobox.__init__s tV_;;r(c|G|jj|jd}|dk(ry|jj|S|jj|jd|S)aIf newindex is supplied, sets the combobox value to the element at position newindex in the list of values. Otherwise, returns the index of the current value in the list of values or -1 if the current value does not appear in the list.currentr4)r{rrgetint)rnewindexr}s r&rzCombobox.currentsZ  '',,tww 2Cby77>>#& &ww||DGGY99r(cR|jj|jd|y)z(Sets the value of the combobox to value.setNrrr$s r&rz Combobox.set  TWWeU+r(r)rrrrrrrrAr(r&rrs < :,r(rceZdZdZddZy)rzJTtk Frame widget is a container, used to group other widgets together.Nc 4tj||d|y)zConstruct a Ttk Frame with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS borderwidth, relief, padding, width, height z ttk::frameNrrs r&rzFrame.__init__ flB7r(rrrrrrrAr(r&rrs  8r(rceZdZdZddZy)rz7Ttk Label widget displays a textual label and/or image.Nc 4tj||d|y)aGConstruct a Ttk Label with parent master. STANDARD OPTIONS class, compound, cursor, image, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS anchor, background, font, foreground, justify, padding, relief, text, wraplength z ttk::labelNrrs r&rzLabel.__init__s flB7r(rr rAr(r&rrs A 8r(rceZdZdZddZy)rzTtk Labelframe widget is a container used to group other widgets together. It has an optional label, which may be a plain text string or another widget.Nc 4tj||d|y)zConstruct a Ttk Labelframe with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS labelanchor, text, underline, padding, labelwidget, width, height zttk::labelframeNrrs r&rzLabelframe.__init__s f&7 t >)$x.91 MMT1E F 88$ %)*E!HEDU#GE$K,I U#GE$K,IQt}H$(3u:$5%+U4[2F+E4M(MfMJD$ MMeT4) *='B 99V r(ct|tr|Sg}t|}t||D]\}}t |drt|j }n:t|tr|j }nt|t tfs|f}t |dr t|}|jg|||S)ztConstruct a list from the given statespec tuple according to the accepted statespec accepted by _format_mapdict.typename) r!striterziprbsplitr#r"r,)stupleresultitr9r:s r&_list_from_statespecrus&# F fB"bk s 5* %J$$&E s #KKMEEE4=1HE 3 #c(C mmsm$" Mr(c\|j|}g}d}|t|kr||}i}|j||f|dz }|t|krL|||dz\}}|jdsn/|dd}|dz }|dk(r t ||}|||<|t|krL|t|kr|S)zpConstruct a list from the tuple returned by ttk::layout, this is somewhat the reverse of _format_layoutlist.rr3rD-NrQ) splitlistr6r, startswith_list_from_layouttuple)tkltupleresindxrdr/r0r:s r&rzrzs\\& !F C D V d| D$<   S[ d4!8,HC>>#&ab'C AIDj ,R5DIS[ V & Jr(ct|}|j||z}t|dzr|St||tS)ahFormat options then call Tk command with args and options and return the appropriate result. If no option is specified, a dict is returned. If an option is specified with the None value, the value for that option is returned. Otherwise, the function just sets the passed options and the caller shouldn't be expecting a return value anyway.rD)conv)r1callr6r _tclobj_to_py)r{optionsrGr}s r& _val_or_dictrsBg&G "''D7N $C 7|a b#M 22r(c`t|} t|}|S#ttf$rY|SwxYw)zAConverts a value to, hopefully, a more appropriate Python object.)rnint ValueError TypeError)r$s r&_convert_stringvalr s> JE E  L  "  L s --c^t|trd|vr t|}|St|}|S)N.)r!rnfloatr)xs r& _to_numberr*s3!S !8aA HAA Hr(c|rWt|drKt|ts;t|ddddk(r t |}|St t t|}|St|dr t|}|S)z8Return value converted from Tcl object to Python object.__len__rrmN StateSpec)rbr!rngetattrrur"r_r)r:s r&rr2ss wsI&z#s/C 3q6:t , ;&s+C J s-s34C J j ! % Jr(cR|jD]\}}t|||<|S)zOReturns adict with its values converted from Tcl objects to Python objects.)r+r)adictr0r:s r&rr?s-KKMS"3'c " Lr(c2|tj}|S)aIf master is not None, itself is returned. If master is None, the default master is returned if there is one, otherwise a new master is created and returned. If it is not allowed to use the default root and master is None, RuntimeError is raised.)tkinter_get_default_root)masters r&rrGs~**, Mr(cjeZdZdZdZddZddZddZddZddZ d Z d Z d Z dd Z d ZdZddZy)rzManipulate style database.z ttk::styleNc^t|}||_|jj|_yN)rrr{)selfrs r&__init__zStyle.__init__Xs"f% ++..r(c d|d||<t|j||jd|}|s|r|Sy)zQuery or sets the default value of the specified option(s) in style. Each key in kw is an option and each value is either a string or a sequence identifying the value for that option.Nr])rr{_name)rstyle query_optrHrss r&r]zStyle.configure^s<   ByMdggr4::{EJ YMr(c |O|jj|jd|d|z}t|jj |S|jj|jd|gt |}t |j|jDcic]*\}}|t|jj |,c}}Scc}}w)aSQuery or sets dynamic values of the specified option(s) in style. Each key in kw is an option and each value should be a list or a tuple (usually) containing statespecs grouped in tuples, or list, or something else of your preference. A statespec is compound of one or more states and then a value.r_r*)r{rrrurxr?rr+)rrrrHrskvs r&r_z Style.mapks  WW\\$**eUEI >r(ct|dg|i|\}}|jj|jdd|||g|y)z9Create a new element in the current theme of given etype.FelementcreateN)rOr{rr)r elementnamerFrGrHrIr/s r&element_createzStyle.element_createsG'uBtBrB d TZZHk5   r(c td|jj|jj|jddDS)z:Returns the list of elements defined in the current theme.c3>K|]}|jdywrwNlstrip).0ns r& z&Style.element_names..s!;-:qQXXc]-:rnamesr#r{rxrrrs r& element_nameszStyle.element_namessB;DGG,=,= GGLLY 8-:;; ;r(c td|jj|jj|jdd|DS)z)Return the list of elementname's options.c3>K|]}|jdywrr)ros r&rz(Style.element_options..s$J-IqQXXc]-Irrrr)rrs r&element_optionszStyle.element_optionssIJDGG,=,= GGLLY ; G-IJJ Jr(c |r t|nd}|r-|jj|jdd|d|d|y|jj|jdd|d|y)a.Creates a new theme. It is an error if themename already exists. If parent is specified, the new theme will inherit styles, elements and layouts from the specified parent theme. If settings are present, they are expected to have the same syntax used for theme_settings.r4themerz-parentz -settingsNrkr{rr)r themenameparentrcr%s r& theme_createzStyle.theme_creates^5=&x0"  GGLLWh 6; 8 GGLLWh V %r(clt|}|jj|jdd||y)aTemporarily sets the current theme to themename, apply specified settings and then restore the previous theme. Each key in settings is a style and each value may contain the keys 'configure', 'map', 'layout' and 'element create' and they are expected to have the same format as specified by the methods configure, map, layout and element_create respectively.rrcNr)rrrcr%s r&theme_settingszStyle.theme_settingss*'x0  TZZ*iHr(c|jj|jj|jddS)z#Returns a list of all known themes.rr)r{rxrrrs r& theme_nameszStyle.theme_namess,ww  djj'7!KLLr(cv||jjdS|jjd|y)zIf themename is None, returns the theme in use, otherwise, set the current theme to themename, refreshes all widgets and emits a <> event.Nzreturn $ttk::currentThemez ttk::setTheme)r{evalr)rrs r& theme_usezStyle.theme_uses4  77<< ;< <  _i0r(rNN)__name__ __module__ __qualname____doc__rrr]r_rrTrrrrrrrrAr(r&rrSsK$ E! A" (>V; J %" IM 1r(rc.eZdZdZddZdZddZddZy)Widgetz!Base class for Tk themed widgets.Nc`t|}tjj||||y)aConstructs a Ttk Widget with the parent master. STANDARD OPTIONS class, cursor, takefocus, style SCROLLABLE WIDGET OPTIONS xscrollcommand, yscrollcommand LABEL WIDGET OPTIONS text, textvariable, underline, image, compound, width WIDGET STATES active, disabled, focus, pressed, selected, background, readonly, alternate, invalid )rHN)rrrr)rr widgetnamerHs r&rzWidget.__init__s)(f%fjR@r(cR|jj|jd||S)zReturns the name of the element at position x, y, or the empty string if the point does not lie within any element. x and y are pixel coordinates relative to the widget.identifyr{r_wrrys r&rzWidget.identifys! ww||DGGZA66r(c |jj|jj|jddj |}|r |||i|S|S)a1Test the widget's state. If callback is not specified, returns True if the widget state matches statespec and False otherwise. If callback is specified, then it will be invoked with *args, **kw if the widget state matches statespec. statespec is expected to be a sequence.instater5)r{ getbooleanrrr7)r statespeccallbackrGrHrets r&rzWidget.instatesWgg   TWWi)1DEG 8'T(R( ( r(c |dj|}|jjt|jj |j d|S)aModify or inquire widget state. Widget state is returned if statespec is None, otherwise it is set according to the statespec flags and then a new state spec is returned indicating which flags were changed. statespec is expected to be a sequence.r5r9)r7r{rxrnrr)rrs r&r9z Widget.state)sG  +Iww  TWW\\$''7I%N!OPPr(r)rrrrrrrr9rAr(r&rrs+A07  Qr(rceZdZdZddZdZy)rzcTtk Button widget, displays a textual label and/or image, and evaluates a command when pressed.Nc 4tj||d|y)aConstruct a Ttk Button widget with the parent master. STANDARD OPTIONS class, compound, cursor, image, state, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS command, default, width z ttk::buttonNrrrrrHs r&rzButton.__init__:s fmR8r(cN|jj|jdS)z/Invokes the command associated with the button.invokerrs r&rz Button.invokeIsww||DGGX..r(rrrrrrrrAr(r&rr6s) 9/r(rceZdZdZddZdZy)rz;Ttk Checkbutton widget which is either in on- or off-state.Nc 4tj||d|y)a'Construct a Ttk Checkbutton widget with the parent master. STANDARD OPTIONS class, compound, cursor, image, state, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS command, offvalue, onvalue, variable zttk::checkbuttonNrrs r&rzCheckbutton.__init__Q f&8"=r(cN|jj|jdS)aWToggles between the selected and deselected states and invokes the associated command. If the widget is currently selected, sets the option variable to the offvalue option and deselects the widget; otherwise, sets the option variable to the option onvalue. Returns the result of the associated command.rrrs r&rzCheckbutton.invoke`sww||DGGX..r(rrrAr(r&rrNsE >/r(rc*eZdZdZddZdZdZdZy)rzeTtk Entry widget displays a one-line text string and allows that string to be edited by the user.Nc <tj|||xsd|y)aConstructs a Ttk Entry widget with the parent master. STANDARD OPTIONS class, cursor, style, takefocus, xscrollcommand WIDGET-SPECIFIC OPTIONS exportselection, invalidcommand, justify, show, state, textvariable, validate, validatecommand, width VALIDATION MODES none, key, focus, focusin, focusout, all z ttk::entryNr)rrwidgetrHs r&rzEntry.__init__os ff&< bAr(cn|j|jj|jd|S)zqReturn a tuple of (x, y, width, height) which describes the bounding box of the character given by index.bbox_getintsr{rr)rindexs r&rz Entry.bboxs(}}TWW\\$''65ABBr(cR|jj|jd||S)zxReturns the name of the element at position x, y, or the empty string if the coordinates are outside the window.rrrs r&rzEntry.identify!ww||DGGZA66r(c|jj|jj|jdS)zForce revalidation, independent of the conditions specified by the validate option. Returns False if validation fails, True if it succeeds. Sets or clears the invalid state accordingly.validater{rrrrs r&rzEntry.validates,ww!!$'',,tww "CDDr(r)rrrrrrrrrAr(r&rrks(B&C 7 Er(rc&eZdZdZddZddZdZy)rzMTtk Combobox widget combines a text field with a pop-down list of values.Nc 4tj||dfi|y)aConstruct a Ttk Combobox widget with the parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS exportselection, justify, height, postcommand, state, textvariable, values, width z ttk::comboboxNrrrs r&rzCombobox.__init__s tV_;;r(c|G|jj|jd}|dk(ry|jj|S|jj|jd|S)aIf newindex is supplied, sets the combobox value to the element at position newindex in the list of values. Otherwise, returns the index of the current value in the list of values or -1 if the current value does not appear in the list.currentr4)r{rrgetint)rnewindexr}s r&rzCombobox.currentsZ  '',,tww 2Cby77>>#& &ww||DGGY99r(cR|jj|jd|y)z(Sets the value of the combobox to value.setNrrr$s r&rz Combobox.set  TWWeU+r(r)rrrrrrrrAr(r&rrs < :,r(rceZdZdZddZy)rzJTtk Frame widget is a container, used to group other widgets together.Nc 4tj||d|y)zConstruct a Ttk Frame with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS borderwidth, relief, padding, width, height z ttk::frameNrrs r&rzFrame.__init__ flB7r(rrrrrrrAr(r&rrs  8r(rceZdZdZddZy)rz7Ttk Label widget displays a textual label and/or image.Nc 4tj||d|y)aGConstruct a Ttk Label with parent master. STANDARD OPTIONS class, compound, cursor, image, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS anchor, background, font, foreground, justify, padding, relief, text, wraplength z ttk::labelNrrs r&rzLabel.__init__s flB7r(rr rAr(r&rrs A 8r(rceZdZdZddZy)rzTtk Labelframe widget is a container used to group other widgets together. It has an optional label, which may be a plain text string or another widget.Nc 4tj||d|y)zConstruct a Ttk Labelframe with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS labelanchor, text, underline, padding, labelwidget, width, height zttk::labelframeNrrs r&rzLabelframe.__init__s f&7 t >)$x.91 MMT1E F 88$ %)*E!HEDU#GE$K,I U#GE$K,IQt}H$(3u:$5%+U4[2F+E4M(MfMJD$ MMeT4) *='B 99V r)c t|tr|Sg}t|}t||D]\}}t |drt|j }n:t|tr|j }nt|t tfs|f}t |dr t|}|jg|||S)Ntypename) r"striterziprdsplitr$r#r.)stupleresultitr;r<s r'_list_from_statespecrws7&# F fB"bk s 5* %J$$&E s #KKMEEE4=1HE 3 #c(C mmsm$" Mr)c^ |j|}g}d}|t|kr||}i}|j||f|dz }|t|krL|||dz\}}|jdsn/|dd}|dz }|dk(r t ||}|||<|t|krL|t|kr|S)Nrr5rF-rS) splitlistr8r. startswith_list_from_layouttuple)tkltupleresindxrfr1r2r<s r'r|r|s3 \\& !F C D V d| D$<   S[ d4!8,HC>>#&ab'C AIDj ,R5DIS[ V & Jr)c t|}|j||z}t|dzr|St||tS)NrF)conv)r3callr8r _tclobj_to_py)r}optionsrIrs r' _val_or_dictrsG5g&G "''D7N $C 7|a b#M 22r)cb t|} t|}|S#ttf$rY|SwxYwr!)rpint ValueError TypeError)r%s r'_convert_stringvalr sAK JE E  L  "  L s ..c^t|trd|vr t|}|St|}|S)N.)r"rpfloatr)xs r' _to_numberr*s3!S !8aA HAA Hr)c |rWt|drKt|ts;t|ddddk(r t |}|St t t|}|St|dr t|}|S)N__len__rro StateSpec)rdr"rpgetattrrwr#rar)r<s r'rr2svB wsI&z#s/C 3q6:t , ;&s+C J s-s34C J j ! % Jr)cT |jD]\}}t|||<|Sr!)r-r)adictr2r<s r'rr?s0KKMS"3'c " Lr)c4 |tj}|Sr!)tkinter_get_default_root)masters r'rrGs! ~**, Mr)cheZdZ dZddZddZddZddZddZdZ d Z d Z dd Z d Z d ZddZy)rz ttk::styleNc^t|}||_|jj|_yr!)rrr})selfrs r'__init__zStyle.__init__Xs"f% ++..r)c f |d||<t|j||jd|}|s|r|Sy)Nr_)rr}_name)rstyle query_optrJrus r'r_zStyle.configure^sA =   ByMdggr4::{EJ YMr)c  |O|jj|jd|d|z}t|jj |S|jj|jd|gt |}t |j|jDcic]*\}}|t|jj |,c}}Scc}}w)Nrar,)r}rrrwrzrArr-)rrrrJrukvs r'raz Style.mapks 0  WW\\$**eUEI &z215E  #E&dgg GGLLXue <> >r)c t|dg|i|\}}|jj|jdd|||g|y)NFelementcreate)rQr}rr)r elementnamerHrIrJrKr1s r'element_createzStyle.element_createsJG'uBtBrB d TZZHk5   r)c  td|jj|jj|jddDS)Nc3>K|]}|jdywryNlstrip).0ns r' z&Style.element_names..s!;-:qQXXc]-:rnamesr$r}rzrrrs r' element_nameszStyle.element_namessEH;DGG,=,= GGLLY 8-:;; ;r)c  td|jj|jj|jdd|DS)Nc3>K|]}|jdywrr)ros r'rz(Style.element_options..s$J-IqQXXc]-Irrrr)rrs r'element_optionszStyle.element_optionssL7JDGG,=,= GGLLY ; G-IJJ Jr)c  |r t|nd}|r-|jj|jdd|d|d|y|jj|jdd|d|y)Nr6themerz-parentz -settingsrmr}rr)r themenameparentrer&s r' theme_createzStyle.theme_createsd N 5=&x0"  GGLLWh 6; 8 GGLLWh V %r)cn t|}|jj|jdd||y)Nrrer)rrrer&s r'theme_settingszStyle.theme_settingss0 C'x0  TZZ*iHr)c |jj|jj|jddS)Nrr)r}rzrrrs r' theme_nameszStyle.theme_namess/1ww  djj'7!KLLr)cx ||jjdS|jjd|y)Nzreturn $ttk::currentThemez ttk::setTheme)r}evalr)rrs r' theme_usezStyle.theme_uses9 %  77<< ;< <  _i0r)r!NN)__name__ __module__ __qualname__rrr_rarrVrrrrrrrrCr)r'rrSsK$ E! A" (>V; J %" IM 1r)rc,eZdZ ddZdZddZddZy)WidgetNcb t|}tjj||||y)N)rJ)rrrr)rr widgetnamerJs r'rzWidget.__init__s. &f%fjR@r)cT |jj|jd||SNidentifyr}r_wrrys r'rzWidget.identifys' Aww||DGGZA66r)c  |jj|jj|jddj |}|r |||i|S|S)Ninstater7)r} getbooleanrrr9)r statespeccallbackrIrJrets r'rzWidget.instates] F gg   TWWi)1DEG 8'T(R( ( r)c  |dj|}|jjt|jj |j d|S)Nr7r;)r9r}rzrprr)rrs r'r;z Widget.state)sL &  +Iww  TWW\\$''7I%N!OPPr)r!)rrrrrrr;rCr)r'rrs+A07  Qr)rceZdZ ddZdZy)rNc 6 tj||d|y)Nz ttk::buttonrrrrrJs r'rzButton.__init__:s  fmR8r)cP |jj|jdSNinvokerrs r'rz Button.invokeIs=ww||DGGX..r)r!rrrrrrCr)r'rr6s) 9/r)rceZdZ ddZdZy)rNc 6 tj||d|y)Nzttk::checkbuttonrrs r'rzCheckbutton.__init__Q  f&8"=r)cP |jj|jdSrrrs r'rzCheckbutton.invoke`s" 9ww||DGGX..r)r!rrCr)r'rrNsE >/r)rc(eZdZ ddZdZdZdZy)rNc > tj|||xsd|y)Nz ttk::entryr)rrwidgetrJs r'rzEntry.__init__os   ff&< bAr)cp |j|jj|jd|S)Nbbox_getintsr}rr)rindexs r'rz Entry.bboxs+ 9}}TWW\\$''65ABBr)cT |jj|jd||Srrrs r'rzEntry.identifys% Cww||DGGZA66r)c |jj|jj|jdS)Nvalidater}rrrrs r'rzEntry.validates2 Iww!!$'',,tww "CDDr)r)rrrrrrrrCr)r'rrks(B&C 7 Er)rc$eZdZ ddZddZdZy)rNc 6 tj||dfi|y)Nz ttk::comboboxrrrs r'rzCombobox.__init__s  tV_;;r)c |G|jj|jd}|dk(ry|jj|S|jj|jd|S)Ncurrentr6)r}rrgetint)rnewindexrs r'rzCombobox.currents` C  '',,tww 2Cby77>>#& &ww||DGGY99r)cT |jj|jd|yNsetrrr%s r'rz Combobox.sets6  TWWeU+r)r!)rrrrrrrCr)r'rrs < :,r)rceZdZ ddZy)rNc 6 tj||d|y)Nz ttk::framerrs r'rzFrame.__init__  flB7r)r!rrrrrCr)r'rrs  8r)rceZdZ ddZy)rNc 6 tj||d|y)Nz ttk::labelrrs r'rzLabel.__init__s  flB7r)r!r rCr)r'rrs A 8r)rceZdZ ddZy)rNc 6 tj||d|y)Nzttk::labelframerrs r'rzLabelframe.__init__s  f&7!D"EEr)cR |jjd|jy)Nzttk::notebook::enableTraversalrrs r'enable_traversalzNotebook.enable_traversalrs  ,  5tww?r)r!)rrrrrrr rrr'r,r.r1r4rCr)r'r r sFK;@D0 .7 F L7AF @r)r cXeZdZ ddZej j ZdZddZddZ y)r Nc 6 tj||d|y)Nzttk::panedwindowrrs r'rzPanedwindow.__init__s  f&8"=r)c l |jj|jd||gt|yr&rr(s r'r'zPanedwindow.insertr*r)c X |d||<t|j||jd|S)Npaner/)rr9rrJs r'r9zPanedwindow.panes4 D  BvJDGGR&$??r)c |jj|jj|jd||S)Nsashposr$)rrnewposs r'r;zPanedwindow.sashposs3 :ww~~dggll477IufMNNr)r!) rrrrrr rr'r9r;rCr)r'r r s1*>$ ' 'FL @Or)r c,eZdZ ddZddZddZdZy)rNc 6 tj||d|y)Nzttk::progressbarrrs r'rzProgressbar.__init__s  f&8"=r)cT |jj|jd|y)Nstartr)rintervals r'r@zProgressbar.starts" N  TWWgx0r)cT |jj|jd|y)Nstepr)ramounts r'rCzProgressbar.steps! .  TWWff-r)cR |jj|jdy)Nstoprrs r'rFzProgressbar.stops   TWWf%r)r!)rrrrr@rCrFrCr)r'rrs$ >1.&r)rceZdZ ddZdZy)rNc 6 tj||d|y)Nzttk::radiobuttonrrs r'rzRadiobutton.__init__rr)cP |jj|jdSrrrs r'rzRadiobutton.invokes" $ ww||DGGX..r)r!rrCr)r'rrs* >/r)rc&eZdZ ddZddZddZy)rNc 6 tj||d|y)Nz ttk::scalerrs r'rzScale.__init__r r)c tj||fi|}t|tdtfs|j |t d|vd|vd|vgr|jd|S)NrGfrom_to<>)rr_r"typerpupdateanyevent_generate)rcnfrJretvals r'r_zScale.configuresm /!!$2r2#T C01 IIcN " gmTRZ8 9    2 3 r)cT |jj|jd||S)Nrcrrs r'rcz Scale.get,s&  ww||DGGUAq11r)r!r)rrrrr_rcrCr)r'rr s@ 8 2r)rceZdZ ddZy)rNc 6 tj||d|y)Nzttk::scrollbarrrs r'rzScrollbar.__init__8  f&6;r)r!r rCr)r'rr5s E  u%r)c* |jd|y)Nremoverros r'selection_removezTreeview.selection_removesC %(r)c* |jd|y)Ntogglerros r'selection_togglezTreeview.selection_toggles@ %(r)c |jj|jd|||}||t|j|dtS|S)NrF) cut_minusr)r}rrrr)rrdrer%rs r'rz Treeview.setsT G ggll477E4? >emdggs(-MC CJr)cL |j|jdd|f||dy)Ntagbindr)r)_bindr)rtagnamesequencers r'tag_bindzTreeview.tag_binds* 1 DGGUFG4ha Pr)c Z |d||<t|j||jdd|S)Nrr_r/)rrrrJs r' tag_configurezTreeview.tag_configures: )  BvJDGGR%  r)c  |A|jj|jj|jdd|S|jj |jj|jdd||S)Nrhas)r}rzrrr)rrrds r'tag_haszTreeview.tag_hassv " <77$$ TWWeUG<> >77%% TWWeUGTBD Dr)r!r)%rrrrrrhrkrernrqrsrurxrrrrrrr'rdrreattachrrrrrrrrrrrrrrrCr)r'rrs ;.PE=D/ /I 4 E@B* - -.D . @;H3 5 3 +E 9& & ) ) Q  Dr)rcbeZdZ ddZfdZdZedZejdZxZ S)rc b |jdddk(|_tj||fi||xst j ||_|j j|||_t||_ t||j |||_ |jjd|j|jrdnd}|dk(rdnd}|jj|dt|}|j||j!|jj#|dk(rd nd |j j%d |j|_|jd |j|jd|jy)Ncompoundtop)variablerMrNrObottomr)sidefill)rrrg)anchorwritez z)pop _label_toprrrIntVar _variabler _last_validrlabelrscaler_adjustpacklowerplace trace_add_LabeledScale__tracecb) rrrrMrNrJ scale_side label_sidedummys r'rzLabeledScale.__init__sK &&U3u< tV*r*!;W^^F%; 5! 4[ 4$.."M  *DLL9"&Xe (H4U(  Zc2d  #  zU':D11'4<<H -. '4<<(r)c |jjd|j|`t|d|_d|_y#t$rY(wxYw)Nr)r trace_removerAttributeErrorsuperdestroyrrr __class__s r'rzLabeledScale.destroysVG  NN ' ' @      s&A AAcD fd}tjd}tjd}||kr||}}jj}||cxkr|ksnj_y|_|j d<j|y)Ncjjj\}}jr6jj j j z }n5jj j j z}j j||y)N)rr)update_idletasksrcoordsrwinfo_yrwinfo_reqheightplace_configure)rrrs r' adjust_labelz*LabeledScale._adjust..adjust_labels  ! ! #::$$&DAqJJ&&(4::+E+E+GGJJ..04::3M3M3OO JJ & &a & 0r)rGrNtext)rrrrcrr%r after_idle)rrIrrMrNnewvals` r'rzLabeledScale._adjusts? 14::f-.  4( ) :E2E##%$"$))DJ !# 6  %r)c8 |jjSr!)rrcrs r'r%zLabeledScale.values)~~!!##r)c< |jj|yr!)rr)rr<s r'r%zLabeledScale.value#s" 3r))NNr ) rrrrrrpropertyr%setter __classcell__rs@r'rrsD. #)L &6$$ \\  r)rc6eZdZ ddZdZddZfdZxZS)rc  ||jdd|jddd}tj||fi|tj|d|d<||_|jdd|_|r8tjdtt|jz|j|g|y) Nr direction) textvariablerrF)tearoffmenurwzunknown option -%s) rr rrMenur _callbackTclErrorrrqkeysset_menu)rrrrvalueskwargsrJs r'rzOptionMenu.__init__-s 'GT1J!::k48:D&/B/||D%8V !It4 ""#7T&++-()$+, ,  g''r)c|dk(r%|jtj||Stj||S)Nr) nametowidgetr __getitem__rgs r'rzOptionMenu.__getitem__Js: 6>$$Z%;%;D$%GH H%%dD11r)c d}|jdd|D]3}|j|jdn|ffd j5|rjj |yy)Nrrendc&j|Sr!)r)r<rs r'z%OptionMenu.set_menu..Zs)     s  !!r!)rrrrrrrrrs@r'rr)s!/(:2("r)r)F)FN)rrFr!)2 __version__ __author____all__rrrrrr(r3r=rArQrUrmrwr|rrrrrrobjectrrrrrrrrrr r r r r rrrrrrrXViewYViewrrrrCr)r'rs  0  ,;; *"#J/%b(T(83    a1Fa1H<QW^^<Q~/V/0/&/:'EFGMM'ET",u",J8F8$8F8&==$ ==&B@vB@J6O&'--6Op '&&'&T/&/8%2FGMM%2P<))<"<<$ ;v ;,e,6CDvw}}gmmCDP ] 5] @??r)tkinter/__pycache__/constants.cpython-312.opt-1.pyc000064400000003616152342670510016125 0ustar00 ֦i8dxZxZZdxZxZZdZdZdZdZ dZ dZ dZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#d Z$d!Z%d"Z&d#Z'd$Z(d%Z)d&Z*d'Z+d(Z,d)Z-d*Z.d+Z/d,Z0d-Z1d.Z2d/Z3d0Z4d1Z5d2Z6d3Z7d4Z8d5Z9d6Z:d7Z;d8Zd;Z?dZBd?ZCd@ZDdAZEdBZFdCZGdDZHdEZIdFZJdGZKdHZLyI)Jnswenwswnesensewnsewcenternonexybothlefttoprightbottomraisedsunkenflatridgegroovesolid horizontalverticalnumericcharwordbaselineinsideoutsideselz sel.firstzsel.lastendinsertcurrentanchorallnormaldisabledactivehiddencascade checkbuttoncommand radiobutton separatorsinglebrowsemultipleextendeddotbox underlinepieslicechordarcfirstlastbutt projectingroundbevelmitermovetoscrollunitspagesN)MNOFALSEOFFYESTRUEONNSWENWSWNESENSEWNSEWCENTERNONEXYBOTHLEFTTOPRIGHTBOTTOMRAISEDSUNKENFLATRIDGEGROOVESOLID HORIZONTALVERTICALNUMERICCHARWORDBASELINEINSIDEOUTSIDESEL SEL_FIRSTSEL_LASTENDINSERTCURRENTANCHORALLNORMALDISABLEDACTIVEHIDDENCASCADE CHECKBUTTONCOMMAND RADIOBUTTON SEPARATORSINGLEBROWSEMULTIPLEEXTENDEDDOTBOX UNDERLINEPIESLICECHORDARCFIRSTLASTBUTT PROJECTINGROUNDBEVELMITERMOVETOSCROLLUNITSPAGES*/usr/lib64/python3.12/tkinter/constants.pyrs5  D                                           rtkinter/__pycache__/__init__.cpython-312.pyc000064400000740113152342670510014711 0ustar00 ֦ip dZddlZddlZddlZddlZddlZej ZddlddlZdZ dZ e ejZ e ejZej Zej"Zej$Zej&dZej&dej*ZdZd Zd Zej2Zd Zej6Zdud ZGddej:ddZdZej@ejBGddZ"GddZ#d a$da%dZ&dvdZ'dZ(dZ)dZ*dwdZ+da,GddZ-Gdde-Z.Gd d!e-Z/Gd"d#e-Z0Gd$d%e-Z1dwd&Z2e3Z4e Z5d'Z6Gd(d)Z7Gd*d+Z8Gd,d-Z9Gd.d/Z:Gd0d1Z;Gd2d3e7e;Zdxd6Z?Gd7d8Z@Gd9d:ZAGd;d<ZBGd=d>e7ZCGd?d@eCe@eAeBZDGdAdBeCe;ZEGdCdDeDZFGdEdFeDe9e:ZGdaHGdGdHeDZIGdIdJeDe9ZJGdKdLeDZKGdMdNeDZLGdOdPeDe9e:ZMGdQdReDZNGdSdTeDZOGdUdVeDZPGdWdXeDZQGdYdZeDZRGd[d\eDZSGd]d^eDe9e:ZTGd_d`ZUGdadbeOZVGdcddZWGdedfeWZXGdgdheWZYdiZZdjZ[GdkdleDe9Z\GdmdneDZ]GdodpeDZ^dqZ_e`jDcgc]/\}}|jdrsec|ejs|dsvr|1c}}Zeefdtk(re_yy#e$rYwxYw#e$rYwxYwcc}}w)ya8Wrapper functions for Tcl/Tk. Tkinter provides classes which allow the display, positioning and control of widgets. Toplevel widgets are Tk and Toplevel. Other widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox LabelFrame and PanedWindow. Properties of the widgets are specified with keyword arguments. Keyword arguments have the same name as the corresponding resource under Tk. Widgets are positioned with one of the geometry managers Place, Pack or Grid. These managers can be called with methods place, pack, grid available in every Widget. Actions are bound to events by resources (e.g. keyword argument command) or with the method bind. Example (Hello, World): import tkinter from tkinter.constants import * tk = tkinter.Tk() frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2) frame.pack(fill=BOTH,expand=1) label = tkinter.Label(frame, text="Hello, World") label.pack(fill=X, expand=1) button = tkinter.Button(frame,text="Exit",command=tk.destroy) button.pack(side=BOTTOM) tk.mainloop() N)*Fz([\\{}])z([\s])c@djtt|S)Internal function. )joinmap _stringifyvalues )/usr/lib64/python3.12/tkinter/__init__.py_joinr:s 88C E* ++c&t|ttfrHt|dk(r*t |d}t j |rd|z}|Sdt|z}|St|tr t|d}n t|}|sd}|St j |rMt jd|}|jdd}tjd|}|dd k(rd |z}|S|dd k(stj |rd|z}|S) rrrz{%s}latin1z{}z\\\1 z\n"\) isinstancelisttuplelenr _magic_researchrbytesstrsubreplace _space_rer s r r r ?s%$' u:?uQx(E&& L#U5\)E" L eU #x(EJEE L  e $MM'51EMM$.EMM'51EQx3u  L1X_ 0 0 7UNE Lrctd}|D]0}t|ttfr|t|z}(|+||fz}2|S)r)rrr_flatten)seqresitems r r"r"[sE C dUDM *&C  -C  Jrc6t|tr|St|tdtfr|Si}t |D]} |j ||S#t tf$r3}td||jD] \}}|||< Yd}~Vd}~wwxYw)rNz_cnfmerge: fallback due to:) rdicttyperr"updateAttributeError TypeErrorprintitems)cnfscnfcmsgkvs r _cnfmerger4js$ D4:s+ , $A  1   #I. 3S9GGIDAqCF& sAB%)BBTc|j|}t|dzr tdt|}i}t ||D].\}}t |}|r |ddk(r|dd}|r||}|||<0|S)aReturn a properly formatted dict built from Tcl list pairs. If cut_minus is True, the supposed '-' prefix will be removed from keys. If conv is specified, it is used to convert values. Tcl list is expected to contain an even number of elements. zNTcl list representing a dict is expected to contain an even number of elementsr-rN) splitlistr RuntimeErroriterzipr) tkr3 cut_minusconvtitr'keyr s r _splitdictrBs QA 1vzCD D aB D"bk U#h Q3ab'C KES " KrceZdZdZy)_VersionInfoTypec|jdk(r(|jd|jd|jS|jd|j|jd|jS)Nfinal.r) releaselevelmajorminormicroserialselfs r __str__z_VersionInfoType.__str__sd    'jj\4::,a |< <jj\4::,t/@/@/C.DT[[MR RrN)__name__ __module__ __qualname__rOr!rr rDrDsSrrD)rIrJrKrHrLcddl}|jd|}|j\}}}}t|t|t|}}}|dk(r|}d}d}n d}ddd|}t |||||S)Nrz(\d+)\.(\d+)([ab.])(\d+)rGrFalphabeta)ab)re fullmatchgroupsintrD)versionrXmrIrJrHrLrKs r _parse_versionr^s  0':A)*&E5,u:s5z3v;&5Es $62<@ E5%v FFrceZdZdZeZdZdZeZdZdZ dZ dZ dZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#d Z$d!Z%d"Z&d#Z'd$Z(d%Z)y&)' EventType234567891011121314151617181920212223242526272829303132333435363738N)*rPrQrRKeyPressKey KeyRelease ButtonPressButton ButtonReleaseMotionEnterLeaveFocusInFocusOutKeymapExposeGraphicsExposeNoExpose VisibilityCreateDestroyUnmapMap MapRequestReparent ConfigureConfigureRequestGravity ResizeRequest CirculateCirculateRequestPropertySelectionClearSelectionRequest SelectionColormap ClientMessageMapping VirtualEventActivate Deactivate MouseWheelr!rr r`r`sH CJK FM F E EGH F FNHJ FG E CJHIGMIHNIHMGLHJJrr`ceZdZdZdZy)EventaContainer for the properties of an event. Instances of this type are generated if one of the following events occurs: KeyPress, KeyRelease - for keyboard events ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, Colormap, Gravity, Reparent, Property, Destroy, Activate, Deactivate - for window events. If a callback function for one of these events is registered using bind, bind_all, bind_class, or tag_bind, the callback is called with an Event as first argument. It will have the following attributes (in braces are the event types for which the attribute is valid): serial - serial number of event num - mouse button pressed (ButtonPress, ButtonRelease) focus - whether the window has the focus (Enter, Leave) height - height of the exposed window (Configure, Expose) width - width of the exposed window (Configure, Expose) keycode - keycode of the pressed key (KeyPress, KeyRelease) state - state of the event as a number (ButtonPress, ButtonRelease, Enter, KeyPress, KeyRelease, Leave, Motion) state - state as a string (Visibility) time - when the event occurred x - x-position of the mouse y - y-position of the mouse x_root - x-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) y_root - y-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) char - pressed character (KeyPress, KeyRelease) send_event - see X/Windows documentation keysym - keysym of the event as a string (KeyPress, KeyRelease) keysym_num - keysym of the event as a number (KeyPress, KeyRelease) type - type of the event as a number widget - widget in which the event occurred delta - delta of wheel movement (MouseWheel) c |jjDcic]\}}|dk7s ||c}} |js d=n'|jdk7rt|j d<t |dds d=|j dk(r d=nt |j tr|j }d}g}t|D]\}}|d|zzs|j|!|dt|zdz z}|s|s|jt|d j| d<|jdk(r d =d }d t |jd |jddj fd|DdScc}}w)Nz??char send_eventTrstate) ShiftLockControlMod1Mod2Mod3Mod4Mod5Button1Button2Button3Button4Button5r|delta) rrkeysymkeycodernumrfocusxywidthheight<namez eventc3>K|]}|vsd|d|yw)r=Nr!).0r2attrss r z!Event.__repr__..'s!Ida5j58,ds >)__dict__r-rreprgetattrrrr[ enumerateappendrhexrrr() rNr2r3rmodssinkeysrs @r __repr__zEvent.__repr__sh"&--"5"5"7E"7$!Q19A"7Eyyf YY$  OE&Mt\40l# ::?g  C (JJEKDA!$1AF#HHQK(q3t9}122EAU$ XXa[E'N ::?g - DIIvtyy 1 GGIdI I  AFs FFN)rPrQrR__doc__rr!rr rrs (T$ rrcdadaby)zInhibit setting of default root window. Call this function to inhibit that the first instance of Tk is used for windows without an explicit parent window. FN)_support_default_root _default_rootr!rr NoDefaultRootr/s"Mrcts tdt%|rtd|dt}t|usJtS)NINo master specified and tkinter is configured to not support default rootz Too early to z: no default root window)rr9rTk)whatroots r _get_default_rootr=sS DE E tf4LMN Nt$$$ rcts tdt}|5tsJdat}datJ|j d|_|S)NrFT)rr9rrwithdraw _temporaryrs r _get_temp_rootrIsa DE E D |$$$ %t $$$$  Krc`t|ddr |jyy#t$rYywxYw)NrF)rdestroyTclErrormasters r _destroy_temp_rootrZs6v|U+  NN ,   s ! --cyrNr!)errs r _tkerrorrbsrcb t|}t|#t$r Yt|wxYw)zBInternal function. Calling it will raise the exception SystemExit.)r[ ValueError SystemExit)codes r _exitrgs< 4y T    T  s  ..cteZdZdZdZdZdZddZdZdZ dZ e Z dZ d Z d Zd Zd Zd ZeZdZdZdZy)VariablezClass to define value holders for e.g. buttons. Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations that constrain the type of the value returned from get().rNc|t|ts td| td}|j |_|j |_|r||_n dttz|_tdz a ||j|y|j j|j jdd|js|j|jyy)a.Construct a variable MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. Nzname must be a stringzcreate variablePY_VARrinfoexists)rrr+r_rootr<_tk_namer_varnum initialize getbooleancall_defaultrNrr rs r __init__zVariable.__init__|s  JtS$934 4 >&'89F\\^ 99 DJ!DM1DJ qLG   OOE "$$TXX]]68TZZ%PQ OODMM *Rrch|jy|jj|jjdd|jr%|jj |j|j 4|j D]}|jj |d|_yy)zUnset the variable in Tcl.Nrr)rr r rglobalunsetvar _tclCommands deletecommandrNrs r __del__zVariable.__del__s 88   88  txx}}VXtzzJ K HH # #DJJ /    ())&&t,* $D  )rc|jS)z'Return the name of the variable in Tcl.)rrMs r rOzVariable.__str__s zzrcN|jj|j|SzSet the variable to VALUE.)r globalsetvarrrNr s r setz Variable.setsxx$$TZZ77rcL|jj|jS)zReturn value of variable.)r globalgetvarrrMs r getz Variable.getsxx$$TZZ00rczt|d|jj}tt |} |j } ||jz}|jj|||jg|_ |jj||S#t $rYgwxYw#t $rYfwxYwN) CallWrapperr__call__rid__func__r*rPr createcommandrr)rNcallbackfcbnames r _registerzVariable._registers $ 3 < <be ((H h///F vq)    $ "D    (       s# BB. B+*B+. B:9B:c~|j|}|jjddd|j||f|S)a#Define a trace callback for the variable. Mode is one of "read", "write", "unset", or a list or tuple of such strings. Callback must be a function which is called when the variable is read, written or unset. Return the name of the callback. traceaddvariabler'rr rrNmoder$r&s r trace_addzVariable.trace_adds:)  gujjj$  3 rcZ|jjddd|j|||jD](\}}|jj |d|k(s(y|jj | |j j|y#t$rYywxYw)aDelete the trace callback for a variable. Mode is one of "read", "write", "unset" or a list or tuple of such strings. Must be same as were specified in trace_add(). cbname is the name of the callback returned from trace_add(). r)remover+rN) rr r trace_infor8rrr1rrNr.r&r]cas r trace_removezVariable.trace_removes  gxjj$ 0__&EArxx!!"%a(F2' HH " "6 * !!((0  sB B*)B*c |jj}t|||jjddd|jDcgc]\}}|||fc}}Scc}}w)z&Return all trace callback information.r)rr+)rr8r r r)rNr8r2r3s r r2zVariable.trace_infosqHH&& .1) dhhmmGVZL M/OP/Oda1q!/OP PPsA*cz|j|}|jjdd|j|||S)aDefine a trace callback for the variable. MODE is one of "r", "w", "u" for read, write, undefine. CALLBACK must be a function which is called when the variable is read, written or undefined. Return the name of the callback. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_add() instead. r)r+r,r-s r trace_variablezVariable.trace_variables3)  gz4::tVD rc|jjdd|j|||jj|d}|j D](\}}|jj|d|k(s(y|jj | |j j|y#t$rYywxYw)aSDelete the trace callback for a variable. MODE is one of "r", "w", "u" for read, write, undefine. CBNAME is the name of the callback returned from trace_variable or trace. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_remove() instead. r)vdeleterN) rr rr8r2rrr1rr3s r trace_vdeletezVariable.trace_vdeletes  gy$**dFC##F+A.__&EArxx!!"%a(F2' HH " "6 * !!((0  sB;; CCc|jj|jjdd|jDcgc]}|jj|c}Scc}w)zReturn all trace callback information. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_info() instead. r)vinfo)rr8r rrNrs r trace_vinfozVariable.trace_vinfos`04xx/A/A HHMM'7DJJ 709:09!""1%09: ::s"A(ct|tstS|j|jk(xrH|jj |jj k(xr|j |j k(Sr)rrNotImplementedr __class__rPr)rNothers r __eq__zVariable.__eq__s]%*! ! ekk)*NN++u/G/GG*HH ) +rNNN)rPrQrRrr rrr rrOrrrr'r/r5r2r8r)r;r?rDr!rr rrssiAH CL+< %8J1" &P " E,:+rrc"eZdZdZdZddZdZy) StringVarz#Value holder for strings variables.rNc4tj||||y)a6Construct a string variable. MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. Nrr r s r r zStringVar.__init__+ $t4rc|jj|j}t|tr|St |S)z#Return value of variable as string.)rrrrrrs r rz StringVar.get7s3%%djj1 eS !L5zrrErPrQrRrr r rr!rr rGrG's-H 5rrGc"eZdZdZdZddZdZy)IntVarz#Value holder for integer variables.rNc4tj||||y)a7Construct an integer variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. NrIr s r r zIntVar.__init__CrJrc|jj|j} |jj|S#tt f$r't |jj|cYSwxYw)z/Return the value of the variable as an integer.)rrrgetintr+rr[ getdoublers r rz IntVar.getOs`%%djj1 288??5) )8$ 2txx))%01 1 2sA3A87A8rErLr!rr rNrN?s-H 52rrNc"eZdZdZdZddZdZy) DoubleVarz!Value holder for float variables.gNc4tj||||y)a6Construct a float variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0.0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. NrIr s r r zDoubleVar.__init__\rJrc~|jj|jj|jS)z,Return the value of the variable as a float.)rrRrrrMs r rz DoubleVar.geths*xx!!$(("7"7 "CDDrrErLr!rr rTrTXs+H 5ErrTc,eZdZdZdZddZdZeZdZy) BooleanVarz#Value holder for boolean variables.FNc4tj||||y)a:Construct a boolean variable. MASTER can be given as master widget. VALUE is an optional value (defaults to False) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. NrIr s r r zBooleanVar.__init__qrJrc|jj|j|jj|Sr)rrrr rs r rzBooleanVar.set}s,xx$$TZZ1D1DU1KLLrc |jj|jj|jS#t$r t dwxYw)z+Return the value of the variable as a bool. invalid literal for getboolean())rr rrrrrMs r rzBooleanVar.getsM A88&&txx'<'d9Z?d:Z@d;ZAd<ZBd=ZCdd>ZDd?ZEd@ZFdAZGdBZHddCZIdDZJdEZKdFZLdGZMdHZNdIZOdJZPdKZQdLZRdMZSdNZTdOZUdPZVdQZWdRZXdSZYdTZZdUZ[dVZ\dWZ]dXZ^dYZ_ddZZ`d[Zad\Zbd]Zcd^Zdd_Zed`ZfdaZgdbZhdcZiddZjdeZkddfZlddgZmddhZnddiZoddjZpddkZqdlZrddmZsdnZtddoZudpZvdqZwdrZxdsZydtZze{duZ|ddvZ}dwZ~e~ZddxZeZdyZdzZd{j eZd|Zd}Zd~ZdZdZddZeZdZeZdZdZdZdZdgZefdZeZdZeZdZddZeZddZeZdZdZifdZeZdZefdZifdZeZdZeZddZdZdZdZddZdZdZy)MisczRInternal class. Base class which defines methods common for interior widgets.Nc|j4|jD]}|jj|d|_yy)zkInternal function. Delete all Tcl commands created for this widget in the Tcl interpreter.N)rr<rrs r rz Misc.destroys?    ())%%d+* $D  )rc|jj| |jj|y#t$rYywxYw)zDInternal function. Delete the Tcl command provided in NAME.N)r<rrr1rrs r rzMisc.deletecommandsA d#     $ $T *   s9 AAcn|jj|jjdd|S)zSet Tcl internal variable, whether the look and feel should adhere to Motif. A parameter of 1 means adhere to Motif (e.g. no color change if mouse passes over slider). Returns the set value.rtk_strictMotif)r<r r rNbooleans r rezMisc.tk_strictMotifs2ww!!$'',, #W#./ /rc:|jjdy)zDChange the color scheme to light brown as used in Tk 3.6 and before. tk_bisqueNr<r rMs r rizMisc.tk_bisques  [!rc |jjdt|ztt|j zy)a Set a new color scheme for all widget elements. A single color as argument will cause that all colors of Tk widget elements are derived from this. Alternatively several keyword parameters and its associated colors can be given. The following keywords are valid: activeBackground, foreground, selectColor, activeForeground, highlightBackground, selectBackground, background, highlightColor, selectForeground, disabledForeground, insertBackground, troughColor.) tk_setPaletteN)r<r r"rr-rNargskws r rlzMisc.tk_setPalettes;  '!)$rxxz*:!;< =rc>|jjdd|y)zWait until the variable is modified. A parameter of type IntVar, StringVar, DoubleVar or BooleanVar must be given.tkwaitr+Nrjrs r wait_variablezMisc.wait_variables  Xz40rcZ||}|jjdd|jy)zQWait until a WIDGET is destroyed. If no parameter is given self is used.Nrqwindowr<r _wrNrts r wait_windowzMisc.wait_windows& >F  Xx3rcZ||}|jjdd|jy)zxWait until the visibility of a WIDGET changes (e.g. it appears). If no parameter is given self is used.Nrq visibilityrurws r wait_visibilityzMisc.wait_visibilitys& >F  X|VYY7rc<|jj||y)zSet Tcl variable NAME to VALUE.N)r<setvar)rNrr s r r}z Misc.setvars tU#rc8|jj|S)z"Return value of Tcl variable NAME.)r<getvarrs r rz Misc.getvarsww~~d##rc |jj|S#t$r}tt |d}~wwxYwr)r<rQrrrrNrexcs r rQz Misc.getints9 '77>>!$ $ 'SX& & ' ?:?c |jj|S#t$r}tt |d}~wwxYwr)r<rRrrrrs r rRzMisc.getdoubles; '77$$Q' ' 'SX& & 'rcj |jj|S#t$r tdwxYw)zPReturn a boolean value for Tcl boolean values true and false given as parameter.r\)r<r rr)rNrs r r zMisc.getbooleans: A77%%a( ( A?@ @ As2cP|jjd|jy)zDirect input focus to this widget. If the application currently does not have the focus this widget will get the focus if the application gets the focus through the window manager.rNrurMs r focus_setzMisc.focus_sets  Wdgg&rcR|jjdd|jy)ztDirect input focus to this widget even if the application does not have the focus. Use with caution!rz-forceNrurMs r focus_forcezMisc.focus_forces  Wh0rcj|jjd}|dk(s|sy|j|S)zReturn the widget which has currently the focus in the application. Use focus_displayof to allow working with several displays. Return None if application does not have the focus.rnoneN)r<r  _nametowidgetrs r focus_getzMisc.focus_gets2ww||G$ 6>d!!$''rc|jjdd|j}|dk(s|sy|j|S)zReturn the widget which has currently the focus on the display where this widget is located. Return None if the application does not have the focus.r -displayofrNr<r rvrrs r focus_displayofzMisc.focus_displayof(s: ww||G\477; 6>d!!$''rc|jjdd|j}|dk(s|sy|j|S)zyReturn the widget which would have the focus if top level for this widget gets the focus from the window manager.rz-lastforrNrrs r focus_lastforzMisc.focus_lastfor1s:ww||GZ9 6>d!!$''rc:|jjdy)zXThe widget under mouse will get automatically focus. Can not be disabled easily.tk_focusFollowsMouseNrjrMs r rzMisc.tk_focusFollowsMouse8s  +,rcv|jjd|j}|sy|j|S)anReturn the next widget in the focus order which follows widget which has currently the focus. The focus order first goes to the next child, then to the children of the child recursively and then to the next sibling which is higher in the stacking order. A widget is omitted if it has the takefocus resource set to 0. tk_focusNextNrrs r rzMisc.tk_focusNext=s2ww||NDGG4D!!$''rcv|jjd|j}|sy|j|S)zHReturn previous widget in the focus order. See tk_focusNext for details. tk_focusPrevNrrs r rzMisc.tk_focusPrevJs0ww||NDGG4D!!$''rc*jjd|yfd} j|_j |jjd|S#t$rt j|_YSwxYw)aCall function once after given time. MS specifies the time in milliseconds. FUNC gives the function which shall be called. Additional parameters are given as parameters to the function call. Return identifier to cancel scheduling with after_cancel.Nafterc  jy#t$rYywxYw# jw#t$rYwwxYwxYwr)rr)rnfuncrrNsr callitzMisc.after..callit\sY$K**40#**40#s5* ''A >A  A A  A  A )r<r rPr*r(r')rNmsrrnrrs` `` @r rz Misc.afterPs} < GGLL" %  6"&-->>&)D77<<T2 2 " 6"&t*"5"5 6sA,,#BBc*|jd|g|S)zCall FUNC once if the Tcl main loop has no event to process. Return an identifier to cancel the scheduling with after_cancel.idle)r)rNrrns r after_idlezMisc.after_idlels tzz&$...rc|s td |jjdd|}|jj|d}|j ||jjdd|y#t $rY)wxYw)zCancel scheduling of function identified with ID. Identifier returned by after or after_idle must be given as first parameter. z?id must be a valid identifier returned from after or after_idlerrrcancelN)rr<r r8rr)rNr!datascripts r after_cancelzMisc.after_cancelts 34 4 77<<4DWW&&t,Q/F   v &  Wh+   sA A99 BBc^|jjd|j|zy)zRing a display's bell.)bellN)r<r  _displayofrN displayofs r rz Misc.bells   Y!;; *6 ww||$84==;L$LMMww||04==3DDEE vJ s1A44 BBc d|vr|j|d<|jjd|j|zy)zClear the data in the Tk clipboard. A widget specified for the optional displayof keyword argument specifies the target display.r)rclearNrvr<r rrs r clipboard_clearzMisc.clipboard_clears7 b DGG"[/  +dmmB.??@rc d|vr|j|d<|jjd|j|zd|fzy)zAppend STRING to the Tk clipboard. A widget specified at the optional displayof keyword argument specifies the target display. The clipboard can be retrieved with selection_get.r)rr--Nr)rNstringros r clipboard_appendzMisc.clipboard_appendsE b DGG"[/  ,t}}R/@@v rcx|jjdd|j}|sy|j|S)zOReturn widget which has currently the grab in this application or None.grabcurrentNrrs r grab_currentzMisc.grab_currents4ww||FItww7D!!$''rcR|jjdd|jy)z.Release grab for this widget if currently set.rreleaseNrurMs r grab_releasezMisc.grab_releases  VY0rcR|jjdd|jy)zwSet grab for this widget. A grab directs all events to this and descendant widgets in the application.rrNrurMs r grab_setz Misc.grab_sets  VUDGG,rcT|jjddd|jy)zSet global grab for this widget. A global grab directs all events to this and descendant widgets on the display. Use with caution - other applications do not get events anymore.rrz-globalNrurMs r grab_set_globalzMisc.grab_set_globals  VUItww7rcb|jjdd|j}|dk(rd}|S)zYReturn None, "local" or "global" if this widget has no, a local or a global grab.rstatusrNru)rNrs r grab_statuszMisc.grab_statuss/fh8 V dV rcB|jjdd|||y)zSet a VALUE (second parameter) for an option PATTERN (first parameter). An optional third parameter gives the numeric priority (defaults to 80).optionr*Nrj)rNpatternr prioritys r option_addzMisc.option_adds  Xuguh?rc<|jjddy)zPClear the option database. It will be reloaded if option_add is called.rrNrjrMs r option_clearzMisc.option_clears  Xw'rcT|jjdd|j||S)zReturn the value for an option NAME for this widget with CLASSNAME. Values with higher priority override lower values.rrru)rNr classNames r option_getzMisc.option_gets# ww||HeTWWdIFFrc@|jjdd||y)zvRead file FILENAME into the option database. An optional second parameter gives the numeric priority.rreadfileNrj)rNfileNamers r option_readfilezMisc.option_readfiles  Xz8X>rc d|vr|j|d<|jjd|j|zy)zClear the current X selection.r) selectionrNrrs r selection_clearzMisc.selection_clears5 b DGG"[/  +dmmB.??@rc 2d|vr|j|d<d|vrB|jdk(r3 d|d<|jjd|j |zS|jjd|j |zS#t $r|d=Y;wxYw)aReturn the contents of the current X selection. A keyword parameter selection specifies the name of the selection and defaults to PRIMARY. A keyword parameter displayof specifies a widget on the display to use. A keyword parameter type specifies the form of data to be fetched, defaulting to STRING except on X11, where UTF8_STRING is tried before STRING.rr(rr)rr)rvrr<r rrrs r selection_getzMisc.selection_gets b DGG"[/   5 5 > *6 ww||$84==;L$LMMww||04==3DDEE vJ s1B BBc |j|}|jjd|j|z|j|fzy)aSpecify a function COMMAND to call if the X selection owned by this widget is queried by another application. This function must return the contents of the selection. The function will be called with the arguments OFFSET and LENGTH which allows the chunking of very long selections. The following keyword parameters can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).)rhandleN)r'r<r rrv)rNcommandrors r selection_handlezMisc.selection_handlesC~~g&  ,t}}R/@@$  !rc z|jjd|j|z|jfzy)zBecome owner of X selection. A keyword parameter selection specifies the name of the selection (default PRIMARY).rownN)r<r rrvrs r selection_ownzMisc.selection_owns6  )r"#&*ggZ0 1rc d|vr|j|d<|jjd|j|z}|sy|j |S)zReturn owner of X selection. The following keyword parameter can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).rrN)rvr<r rr)rNrors r selection_own_getzMisc.selection_own_get sO b DGG"[/ww||04==3DDED!!$''rcD|jjd||f|zS)zDSend Tcl command CMD to different interpreter INTERP to be executed.sendrj)rNinterpcmdrns r rz Misc.send,s!ww||VVS1D899rcR|jjd|j|y)z(Lower this widget in the stacking order.lowerNru)rN belowThiss r rz Misc.lower0  Wdggy1rcR|jjd|j|y)z(Raise this widget in the stacking order.raiseNru)rN aboveThiss r tkraisez Misc.tkraise4rrcP|jjdd}t|S)z-Returns the exact version of the Tcl library.r patchlevel)r<r r^)rNrs r info_patchlevelzMisc.info_patchlevel:s!WW\\&,7 j))rcd|j|z|fz}|jj|jj|S)z*Return integer which represents atom NAME.)winfoatom)rr<rQr )rNrrrns r winfo_atomzMisc.winfo_atom?s< 4??9#==Gww~~dggll4011rchd|j|z|fz}|jj|S)z'Return name of atom with identifier ID.)ratomname)rr<r rNr!rrns r winfo_atomnamezMisc.winfo_atomnameDs5$+,/1e4ww||D!!rc|jj|jjdd|jS)z7Return number of cells in the colormap for this widget.rcellsr<rQr rvrMs r winfo_cellszMisc.winfo_cellsJ/ww~~ GGLL'477 35 5rcg}|jj|jjdd|jD]#} |j |j |%|S#t $rY3wxYw)z?Return a list of all widgets which are children of this widget.rchildren)r<r8r rvrrKeyError)rNresultchilds r winfo_childrenzMisc.winfo_childrenOsqWW&& GGLL*dgg 68E  d0078 8   s A++ A76A7cP|jjdd|jS)z(Return window class name of this widget.rclassrurMs r winfo_classzMisc.winfo_class\sww||GWdgg66rc|jj|jjdd|jS)z?Return True if at the last color request the colormap was full.r colormapfullr<r r rvrMs r winfo_colormapfullzMisc.winfo_colormapfull`s1ww!! GGLL.$'' :<  >rc|jj|jjdd|jS)z:Return the x coordinate of the pointer on the root window.rpointerxrrMs r winfo_pointerxzMisc.winfo_pointerxr0rcn|j|jjdd|jS)zHReturn a tuple of x and y coordinates of the pointer on the root window.r pointerxy_getintsr<r rvrMs r winfo_pointerxyzMisc.winfo_pointerxys+}} GGLL+tww 79 9rc|jj|jjdd|jS)z:Return the y coordinate of the pointer on the root window.rpointeryrrMs r winfo_pointeryzMisc.winfo_pointeryr0rc|jj|jjdd|jS)z'Return requested height of this widget.r reqheightrrMs r winfo_reqheightzMisc.winfo_reqheights/ww~~ GGLL+tww 79 9rc|jj|jjdd|jS)z&Return requested width of this widget.rreqwidthrrMs r winfo_reqwidthzMisc.winfo_reqwidthr0rcp|j|jjdd|j|S)zNReturn a tuple of integer RGB values in range(65536) for color in this widget.rrgbrE)rNcolors r winfo_rgbzMisc.winfo_rgbs-}} GGLL%% 8: :rc|jj|jjdd|jS)zSReturn x coordinate of upper left corner of this widget on the root window.rrootxrrMs r winfo_rootxzMisc.winfo_rootx1ww~~ GGLL'477 35 5rc|jj|jjdd|jS)zSReturn y coordinate of upper left corner of this widget on the root window.rrootyrrMs r winfo_rootyzMisc.winfo_rootyrXrcP|jjdd|jS)z&Return the screen name of this widget.rscreenrurMs r winfo_screenzMisc.winfo_screenr9rc|jj|jjdd|jS)zTReturn the number of the cells in the colormap of the screen of this widget.r screencellsrrMs r winfo_screencellszMisc.winfo_screencells1ww~~ GGLL- 9; ;rc|jj|jjdd|jS)z\Return the number of bits per pixel of the root window of the screen of this widget.r screendepthrrMs r winfo_screendepthzMisc.winfo_screendepthrbrc|jj|jjdd|jS)zXReturn the number of pixels of the height of the screen of this widget in pixel.r screenheightrrMs r winfo_screenheightzMisc.winfo_screenheights1ww~~ GGLL.$'' :<  >rc|jj|jjdd|jS)zTReturn the number of pixels of the width of the screen of this widget in mm.r screenmmwidthrrMs r winfo_screenmmwidthzMisc.winfo_screenmmwidths1ww~~ GGLL/477 ;= =rcP|jjdd|jS)zReturn one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the default colormodel of this screen.r screenvisualrurMs r winfo_screenvisualzMisc.winfo_screenvisualsww||G^TWW==rc|jj|jjdd|jS)zWReturn the number of pixels of the width of the screen of this widget in pixel.r screenwidthrrMs r winfo_screenwidthzMisc.winfo_screenwidthrbrcP|jjdd|jS)zxReturn information of the X-Server of the screen of this widget in the form "XmajorRminor vendor vendorVersion".rserverrurMs r winfo_serverzMisc.winfo_serversww||GXtww77rcn|j|jjdd|jS)z*Return the toplevel widget of this widget.rtoplevel)rr<r rvrMs r winfo_toplevelzMisc.winfo_toplevel s/!!$'',, Z#*+ +rc|jj|jjdd|jS)zBReturn true if the widget and all its higher ancestors are mapped.rviewablerrMs r winfo_viewablezMisc.winfo_viewabler0rcP|jjdd|jS)zReturn one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the colormodel of this widget.rvisualrurMs r winfo_visualzMisc.winfo_visualsww||GXtww77rcP|jjdd|jS)z7Return the X identifier for the visual for this widget.rvisualidrurMs r winfo_visualidzMisc.winfo_visualidr%rc.|jjdd|j|rdnd}|jj|Dcgc]}|jj|}}|Dcgc]}|j |c}Scc}wcc}w)zReturn a list of all visuals available for the screen of this widget. Each item in the list consists of a visual name (see winfo_visual), a depth and if includeids is true is given also the X identifier.rvisualsavailable includeidsN)r<r rvr8_Misc__winfo_parseitem)rNrrrs r winfo_visualsavailablezMisc.winfo_visualsavailables ww||G%7,6LDB.2gg.?.?.EF.E!!!$.EF3784a&&q)488G8s "B 2Bc R|ddtt|j|ddzS)rNr)rr _Misc__winfo_getint)rNr?s r __winfo_parseitemzMisc.__winfo_parseitem(s+!uuS!4!4ae<===rct|dS)rr)r[r>s r __winfo_getintzMisc.__winfo_getint,s1ayrc|jj|jjdd|jS)zReturn the height of the virtual root window associated with this widget in pixels. If there is no virtual root window return the height of the screen.r vrootheightrrMs r winfo_vrootheightzMisc.winfo_vrootheight0s1ww~~ GGLL- 9; ;rc|jj|jjdd|jS)zReturn the width of the virtual root window associated with this widget in pixel. If there is no virtual root window return the width of the screen.r vrootwidthrrMs r winfo_vrootwidthzMisc.winfo_vrootwidth7s1ww~~ GGLL, 8: :rc|jj|jjdd|jS)ziReturn the x offset of the virtual root relative to the root window of the screen of this widget.rvrootxrrMs r winfo_vrootxzMisc.winfo_vrootx>1ww~~ GGLL(DGG 46 6rc|jj|jjdd|jS)ziReturn the y offset of the virtual root relative to the root window of the screen of this widget.rvrootyrrMs r winfo_vrootyzMisc.winfo_vrootyDrrc|jj|jjdd|jS)z Return the width of this widget.rrrrMs r winfo_widthzMisc.winfo_widthJrrc|jj|jjdd|jS)zVReturn the x coordinate of the upper left corner of this widget in the parent.rrrrMs r winfo_xz Misc.winfo_xO1ww~~ GGLL#tww /1 1rc|jj|jjdd|jS)zVReturn the y coordinate of the upper left corner of this widget in the parent.rrrrMs r winfo_yz Misc.winfo_yUrrc:|jjdy)zEEnter event loop until all pending events have been processed by Tcl.r)NrjrMs r r)z Misc.update[s  Xrc<|jjddy)zEnter event loop until all idle callbacks have been called. This will update the display of windows but not process events caused by the user.r) idletasksNrjrMs r update_idletaskszMisc.update_idletasks_s  X{+rc|?|jj|jjd|jS|jjd|j|y)a,Set or get the list of bindtags for this widget. With no argument return the list of all bindtags associated with this widget. With a list of strings as argument the bindtags are set to this list. The bindtags determine in which order events are processed (see bind).Nbindtagsr<r8r rv)rNtagLists r rz Misc.bindtagsesP ?77$$ Z13 3 GGLLTWWg 6rct|tr!|jj|||fzy|r\|j ||j |}|xrdxsdd|d|j d}|jj|||fz|S|r|jj||fzS|jj|jj|S)r+rif {"[rz]" == "break"} break N)rrr<r r' _substitute_subst_format_strr8)rNrsequencerr* needcleanupfuncidrs r _bindz Misc._bindrs dC GGLL4 00 1 ^^D$*:*:#%FKC%2%..0C GGLL3/ 0M 77<<{ 23 377$$TWW\\$%78 8rcB|jd|jf|||S)aOBind to this widget at event SEQUENCE a call to function FUNC. SEQUENCE is a string of concatenated event patterns. An event pattern is of the form where MODIFIER is one of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, B3, Alt, Button4, B4, Double, Button5, B5 Triple, Mod1, M1. TYPE is one of Activate, Enter, Map, ButtonPress, Button, Expose, Motion, ButtonRelease FocusIn, MouseWheel, Circulate, FocusOut, Property, Colormap, Gravity Reparent, Configure, KeyPress, Key, Unmap, Deactivate, KeyRelease Visibility, Destroy, Leave and DETAIL is the button number for ButtonPress, ButtonRelease and DETAIL is the Keysym for KeyPress and KeyRelease. Examples are for pressing Control and mouse button 1 or for pressing A and the Alt key (KeyPress can be omitted). An event pattern can also be a virtual event of the form <> where AString can be arbitrary. This event can be generated by event_generate. If events are concatenated they must appear shortly after each other. FUNC will be called if the event sequence occurs with an instance of Event as argument. If the return value of FUNC is "break" no further bound function is invoked. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. Bind will return an identifier to allow deletion of the bound function with unbind without memory leak. If FUNC or SEQUENCE is omitted the bound function or list of bound events are returned.bindrrvrNrrr*s r rz Misc.binds#Nzz6477+XtSAArcB|jd|j|f|y)aUnbind for this widget the event SEQUENCE. If FUNCID is given, only unbind the function identified with FUNCID and also delete the corresponding Tcl command. Otherwise destroy the current binding for SEQUENCE, leaving SEQUENCE unbound. rN_unbindrv)rNrrs r unbindz Misc.unbinds fdggx0&9rc^||jjg|dy|jj|jd}d|ddjfd|D}|j sd}|jjg|||j |y)Nrrrrc3DK|]}|js|ywr) startswith)rlineprefixs r rzMisc._unbind..s#=ed$(OOF$;"es )r<r splitrstripr)rNrrlineskeeprs @r rz Misc._unbinds > DGGLL #$ # #GGLL&,,T2Evha(F99=e==D::< DGGLL %$ % %   v &rcH|jjd|||dS)aBind to all widgets at an event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.)rallTrrrs r bind_allz Misc.bind_alls# zz|!!/8T3MMrcH|jjdd|fy)z8Unbind for all widgets for event SEQUENCE all functions.rrNrr)rNrs r unbind_allzMisc.unbind_alls feX67rcL|jjd|f|||dS)a=Bind to widgets with bindtag CLASSNAME at event SEQUENCE a call of function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.rTr)rNrrrr*s r bind_classzMisc.bind_classs(zz|!!69"5xsDQQrcH|jjd||fy)zWUnbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.rNr)rNrrs r unbind_classzMisc.unbind_classs fi:;rc:|jj|y)zCall the mainloop of Tk.N)r<r^)rNrs r r^z Misc.mainloops rc8|jjy)z8Quit the Tcl interpreter. All widgets will be destroyed.N)r<quitrMs r rz Misc.quits  rc|rBtt|jj|jj |Syr)rr r<rQr8rNrs r rFz Misc._getintss3 TWW^^TWW->->v-FGH H rc|rBtt|jj|jj |Syr)rr r<rRr8rs r _getdoubleszMisc._getdoubless5 TWW..0A0A&0IJK K rc>|r|jj|Syr)r<r rs r _getbooleanzMisc._getbooleans 77%%f- - rc0|rd|fS|d|jfSy)rrr!rvrs r rzMisc._displayofs(  ), ,   $''* *rc |jjS#t$r6|jj ddx}|j_|cYSwxYw)rr<windowingsystem)r_windowingsystem_cachedr*r<r )rNwss r rzMisc._windowingsystemsR ::<77 7  T+<= >B5I s.getint_event]s+ ay )  s  r)r _subst_formatr<r rQrrLrrrrrrtimerrrrrr keysym_numr`r(rrwidgetrx_rooty_rootr)rNrnr rnsignrWr%hr2rr?rrrAEKNWTXYDerQs @r rzMisc._substituteWs t9D../ /WW''  GKCq!Q1aAq!Q1aAq! G%=Q!!}QW? O q/aq/1o1o&qMQ\#A  q\AF ))!,AH ?? QiAGt 7  AF  AH  H% AGt  sZ E3? F!F2F'# F=3 E?>E? F FF$#F$'F:9F:=GGcztj\}}}|j}|j|||yr)sysexc_inforreport_callback_exception)rNrvaltbrs r _report_exceptionzMisc._report_exceptions0||~ S"zz| &&sC4rci}|jj|jj|D]5}|jj|}|dddf|ddz||ddd<7|S)z;Call Tcl configure command and return the result as a dict.rrNr<r8r )rNrnr/rs r _getconfigurezMisc._getconfigurest""<477<<#67A!!!$AqT!"XK!AB%/C!QRM8 rc|jj|jj|}|dddf|ddzS)NrrrrNrnrs r _getconfigure1zMisc._getconfigure1sB GG  ldggllD1 2!QR{QqrU""rc|rt||f}n |r t|}|&|jt|j|fSt |t r*|j t|j|d|zfS|jjt|j|f|j|zy)rNr7) r4rr"rvrrr r<r r)rNrr/ros r _configurezMisc._configures S"I&C C.C ;%%h~&>? ? c3 &&x#s3w0G'HI I  Xtwwn- c0BBCrc (|jd||S)zConfigure resources of a widget. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method keys. configurer rNr/ros r rzMisc.configures{C44rcV|jj|jdd|zS)z4Return the resource value for a KEY given as string.cgetr7rurNrAs r rz Misc.cgets!ww||DGGVS3Y77rc*|j||iyr)rrNrAr s r __setitem__zMisc.__setitem__s U|$rc|jj}||jj|jdDcgc]}||dddc}Scc}w)z3Return a list of all resource names of this widget.rrrNr)rNr8rs r rz Misc.keyss]GG%% $'',,tww <=?=)* ! Q#=? ??sAc|jS)z+Return the window path name of this widget.rrMs r rOz Misc.__str__s wwrc~d|jjd|jjd|jdS)NrrGz object r)rBrQrRrvrMs r rz Misc.__repr__s- NN % %t~~'B'BDGGM Mr_noarg_c|tjur6|j|jj dd|j S|jj dd|j |y)aSet or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given the current setting will be returned. pack propagateNrarrr<r rvrNflags r pack_propagatezMisc.pack_propagateY 4<< ##DGGLL TWW%./ / GGLLdggt s r pack_slaveszMisc.pack_slavess_!!77<<$'':<=<+,""1%<= ==Ac|jj|jjdd|jDcgc]}|j |c}Scc}w)r$placer%r&r>s r place_slaveszMisc.place_slavessb!!77<<$''3454+,""1%45 55r(cT|jjdd|j|y)zThe anchor value controls how to place the grid within the master when no row/column has any weight. The default anchor is nw.gridanchorNru)rNr.s r grid_anchorzMisc.grid_anchors  VXtww7rcdd|jf}| ||||fz}| ||||fz}|j|jj|xsdS)aReturn a tuple of integer coordinates for the bounding box of this widget controlled by the geometry manager grid. If COLUMN, ROW is given the bounding box applies from the cell with row and column 0 to the specified cell. If COL2 and ROW2 are given the bounding box starts at that cell. The returned integers specify the offset of the upper left corner in the master widget and the width and height. r-bboxN)rvrFr<r )rNcolumnrowcol2row2rns r grid_bboxzMisc.grid_bboxsh(  #/63-'D   04,&D}}\TWW\\4019T9rct|ttjfrI t|}|syd|vr|jj |S|jj |S|S#ttf$rY|SwxYw)NrG) rr_tkinterTcl_Objr<rRrQrr)rNr svalues r _gridconvvaluezMisc._gridconvvalues ec8#3#34 5 UF]77,,V4477>>&11 )   s A,A,A,,A?>A?c t|tr |s|dddk(r|dd}|dddk7rd|z}|f}n|j||}|sHt|j|jj d||j ||jS|jj d||j |f|z}t|dk(r|j|Sy)rrNrrr7r-)r>) rrrrBr<r rvr;r)rNrindexr/rooptionsr$s r _grid_configurezMisc._grid_configure's c3 23x3#2h2Aw#~#gfGmmC,G VWdggu=((* *ggll7DGGU3 w<1 &&s+ + rc *|jd|||S)zConfigure column INDEX of a grid. Valid resources are minsize (minimum size of the column), weight (how much does additional space propagate to this column) and pad (how much space to let additionally).columnconfigurer?rNr=r/ros r grid_columnconfigurezMisc.grid_columnconfigure<s ##$5uc2FFrc z|j|jjdd|j||xsdS)zReturn a tuple of column and row which identify the cell at which the pixel at position X and Y inside the master widget is located.r-locationNrErNrrs r grid_locationzMisc.grid_locationFs<}} GGLL DGGQ 34<7; >) to an event SEQUENCE such that the virtual event is triggered whenever SEQUENCE occurs.eventr*NrjrNvirtual sequencesrns r event_addzMisc.event_add{s%(94  TrcJdd|f|z}|jj|y)z-Unbind a virtual event VIRTUAL from SEQUENCE.rTdeleteNrjrUs r event_deletezMisc.event_deletes#7+i7  Trc dd|j|f}|jD]\}}|d|zt|fz}|jj |y)zGenerate an event SEQUENCE. Additional keyword arguments specify parameter of the event (e.g. x, y, rootx, rooty).rTgenerate-%sN)rvr-rr<r )rNrrornr2r3s r event_generatezMisc.event_generatesQTWWh7HHJDAq519c!f--D  Trcn|jj|jjdd|S)zuReturn a list of all virtual events or the information about the SEQUENCE bound to the virtual event VIRTUAL.rTrr)rNrVs r event_infozMisc.event_infos/ww  GGLL&' 24 4rcl|jj|jjddS)z*Return a list of all existing image names.imagenamesrrMs r image_nameszMisc.image_names&ww  gw!?@@rcl|jj|jjddS)z?Return a list of all available image types (e.g. photo bitmap).rctypesrrMs r image_typeszMisc.image_typesrfrr)r)r1rF)rrE)NrNNNNNN)rPrQrRr_last_child_idsrrrrerirlrrwaitvarrxr{r}rrQrRr rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrliftrrrrr r rrrrr!r$r'r)r,r/r3r5r8r<r?rBrGrJrMrPrTrWr[r^rarerhrkrnrqrtrwrzr}rrrrrrrrrrrrr)rrrrrrrrrrr^rrFrrrpropertyrrrrr'registerrrrrrrrr r rconfigr __getitem__rrrOrrr!rr'r%r+r/r.r6r1r;r?rDrArHrJrMrLrPrOrRrXr[r_rarerir!rr rarasE OL%/" =1 G48$$' ' A' E1 (((- (( 38/,"= F.A (1-8@( G?A F$! 1 (:22 D* 2 " 5 7< (G6 2 :6 <5 8 968"> 8 9 8 9 8 : 5 5 8; ; < > = > ; 8 + 8 8 : 9>;:6 6 5 1 1 , 79$'BR : 'N8R< I L . 4"!M,H CM/;z5 # D5F8K%? M kG") =I=F58F:& D ,*/1G+O<#* =,.D%L; D 9 4AArraceZdZdZdZdZy)rzwInternal class. Stores function to call when some user defined Tcl function is called e.g. after an event occurred.c.||_||_||_y)z(Store FUNC, SUBST and WIDGET as members.N)rrr)rNrrrs r r zCallWrapper.__init__s   rc |jr|j|}|j|S#t$r|jj YyxYw)z3Apply first function SUBST to arguments, than FUNC.N)rrrrrrNrns r r zCallWrapper.__call__sQ ,zz!tzz4(499d# #   , KK ) ) +s ),%ANrPrQrRrr r r!rr rrsD ,rrc"eZdZdZdZdZdZy)XViewzXMix-in class for querying and changing the horizontal position of a widget's window.cz|jj|jdg|}|s|j|Sy)z5Query and change the horizontal position of the view.xviewNr<r rvrrNrnr$s r r~z XView.xview:dggll477G3d3##C( (rcT|jj|jdd|y)zsAdjusts the view in the window so that FRACTION of the total width of the canvas is off-screen to the left.r~movetoNrurNfractions r xview_movetozXView.xview_moveto  TWWgx:rcV|jj|jdd||y)z\Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).r~scrollNrurNr rs r xview_scrollzXView.xview_scroll   TWWgx>rN)rPrQrRrr~rrr!rr r|r|) ; ?rr|c"eZdZdZdZdZdZy)YViewzVMix-in class for querying and changing the vertical position of a widget's window.cz|jj|jdg|}|s|j|Sy)z3Query and change the vertical position of the view.yviewNrrs r rz YView.yviewrrcT|jj|jdd|y)zsAdjusts the view in the window so that FRACTION of the total height of the canvas is off-screen to the top.rrNrurs r yview_movetozYView.yview_movetorrcV|jj|jdd||y)z\Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).rrNrurs r yview_scrollzYView.yview_scrollrrN)rPrQrRrrrrr!rr rrrrrc|eZdZdZ d"dZeZdZeZd#dZeZ dZ e Z d#dZ e Z dZeZd#d ZeZd ZeZd ZeZd#d ZeZ d"d ZeZd#dZeZd$dZeZdZeZd#dZ e Z!d#dZ"e"Z#d%dZ$e$Z%d$dZ&e&Z'd#dZ(e(Z)dZ*e*Z+d$dZ,e,Z-d$dZ.e.Z/d#dZ0e0Z1d#dZ2e2Z3d$dZ4e4Z5d$dZ6e6Z7d#dZ8e8Z9d#dZ:e:Z;d#dZe>Z?d!Z@e@ZAy)&WmzAProvides functions for the communication with the window manager.Nc v|j|jjdd|j||||S)zInstruct the window manager to set the aspect ratio (width/height) of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple of the actual values if no argument is given.wmaspectrE)rNminNumerminDenommaxNumermaxDenoms r wm_aspectz Wm.wm_aspects9 }} GGLLxxx )* *rc\dd|jf|z}|jj|S)aThis subcommand returns or sets platform specific attributes The first form returns a list of the platform specific flags and their values. The second form returns the value for the specific option. The third form sets one or more of the values. The values are as follows: On Windows, -disabled gets or sets whether the window is in a disabled state. -toolwindow gets or sets the style of the window to toolwindow (as defined in the MSDN). -topmost gets or sets whether this is a topmost window (displays above all other windows). On Macintosh, XXXXX On Unix, there are currently no special attribute values. r attributes)rvr<r rys r wm_attributeszWm.wm_attributess,$lDGG,t3ww||D!!rcR|jjdd|j|S)zVStore NAME in WM_CLIENT_MACHINE property of this widget. Return current value.rclientrurs r wm_clientz Wm.wm_clients!ww||D(DGGT::rc0t|dkDr|f}dd|jf|z}|r|jj|y|jj |jj|Dcgc]}|j |c}Scc}w)zStore list of window names (WLIST) into WM_COLORMAPWINDOWS property of this widget. This list contains windows whose colormaps differ from their parents. Return current list of widgets if WLIST is empty.rrcolormapwindowsN)rrvr<r r8r)rNwlistrnrs r wm_colormapwindowszWm.wm_colormapwindowss u:>HE'1E9  GGLL "WW..tww||D/ABDB&&q)BD DDs8BcR|jjdd|j|S)zStore VALUE in WM_COMMAND property. It is the command which shall be used to invoke the application. Return current command if VALUE is None.rrrurs r wm_commandz Wm.wm_commands!ww||D)TWWe<|jjdd|y)aAThe window will be unmapped from the screen and will no longer be managed by wm. toplevel windows will be treated like frame windows once they are no longer managed by wm, however, the menu option configuration will be remembered and the menus will return once the widget is managed again.rforgetNrjrws r wm_forgetz Wm.wm_forget5s  T8V,rcP|jjdd|jS)zAReturn identifier for decorative frame of this widget if present.rframerurMs r wm_framez Wm.wm_frame?sww||D'47733rcR|jjdd|j|S)ziSet geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return current value if None is given.rr#ru)rN newGeometrys r wm_geometryzWm.wm_geometryEs!ww||D*dgg{CCrc v|j|jjdd|j||||S)aInstruct the window manager that this widget shall only be resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the number of grid units requested in Tk_GeometryRequest.rr-rE)rN baseWidth baseHeightwidthInc heightIncs r wm_gridz Wm.wm_gridLs8}}TWW\\ &$'' z8Y89 9rcR|jjdd|j|S)z~Set the group leader widgets for related widgets to PATHNAME. Return the group leader of this widget if None is given.rgrouprurNpathNames r wm_groupz Wm.wm_groupY!ww||D'477H==rc|)|jjdd|jd|S|jjdd|j|S)aSet bitmap for the iconified widget to BITMAP. Return the bitmap if None is given. Under Windows, the DEFAULT parameter can be used to set the icon for the widget and any descendants that don't have an icon set explicitly. DEFAULT can be the relative path to a .ico file (example: root.iconbitmap(default='myicon.ico') ). See Tk documentation for more information.r iconbitmap-defaultru)rNbitmapdefaults r wm_iconbitmapzWm.wm_iconbitmap`sF  77<<lDGGZQ Q77<<lDGGVD DrcP|jjdd|jS)zDisplay widget as icon.riconifyrurMs r wm_iconifyz Wm.wm_iconifypsww||D)TWW55rcR|jjdd|j|S)zVSet mask for the icon bitmap of this widget. Return the mask if None is given.riconmaskru)rNrs r wm_iconmaskzWm.wm_iconmaskvs!ww||D*dggv>>rcR|jjdd|j|S)zSSet the name of the icon for this widget. Return the name if None is given.riconnameru)rNnewNames r wm_iconnamezWm.wm_iconname}s!ww||D*dggw??rc|r+|jjdd|jdg|y|jjdd|jg|y)aSets the titlebar icon for this window based on the named photo images passed through args. If default is True, this is applied to all future created toplevels as well. The data in the images is taken as a snapshot at the time of invocation. If the images are later changed, this is not reflected to the titlebar icons. Multiple images are accepted to allow different images sizes to be provided. The window manager may scale provided icons to an appropriate size. On Windows, the images are packed into a Windows icon structure. This will override an icon specified to wm_iconbitmap, and vice versa. On X, the images are arranged into the _NET_WM_ICON X property, which most modern window managers support. An icon specified by wm_iconbitmap may exist simultaneously. On Macintosh, this currently does nothing.r iconphotorNru)rNrrns r wm_iconphotozWm.wm_iconphotosG(  DGGLL{DGGZ G$ G DGGLL{DGG ;d ;rc r|j|jjdd|j||S)zSet the position of the icon of this widget to X and Y. Return a tuple of the current values of X and X if None is given.r iconpositionrErGs r wm_iconpositionzWm.wm_iconpositions3}}TWW\\ .$''1a12 2rcR|jjdd|j|S)zgSet widget PATHNAME to be displayed instead of icon. Return the current value if None is given.r iconwindowrurs r wm_iconwindowzWm.wm_iconwindows!ww||D,BBrc>|jjdd|y)zThe widget specified will become a stand alone top-level window. The window will be decorated with the window managers title bar, etc.rmanageNrj)rNrs r wm_managez Wm.wm_manages  T8V,rc r|j|jjdd|j||S)zSet max WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.rmaxsizerErNrrs r wm_maxsizez Wm.wm_maxsize3}}TWW\\ )TWWeV56 6rc r|j|jjdd|j||S)zSet min WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.rminsizerErs r wm_minsizez Wm.wm_minsizerrcp|j|jjdd|j|S)zInstruct the window manager to ignore this widget if BOOLEAN is given with 1. Return the current value if None is given.roverrideredirect)rr<r rvrfs r wm_overrideredirectzWm.wm_overrideredirects4 $dggw!89 9rcR|jjdd|j|S)zInstruct the window manager that the position of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".r positionfromrurNwhos r wm_positionfromzWm.wm_positionfroms!ww||D.$''3??rct|r|j|}n|}|jjdd|j||S)zBind function FUNC to command NAME for this widget. Return the function bound to NAME if None is given. NAME could be e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".rprotocol)rr'r<r rv)rNrrrs r wm_protocolzWm.wm_protocolsB D>nnT*GGww|| *dggtW6 6rcT|jjdd|j||S)zyInstruct the window manager whether this width can be resized in WIDTH or HEIGHT. Both values are boolean values.r resizablerurs r wm_resizablezWm.wm_resizables#ww||D+twwvFFrcR|jjdd|j|S)zInstruct the window manager that the size of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".rsizefromrurs r wm_sizefromzWm.wm_sizefroms!ww||D*dggs;;rcR|jjdd|j|S)zQuery or set the state of this widget as one of normal, icon, iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).rrru)rNnewstates r wm_statez Wm.wm_staterrcR|jjdd|j|S)zSet the title of this widget.rtitlerurs r wm_titlez Wm.wm_titlesww||D'477F;;rcR|jjdd|j|S)z_Instruct the window manager that this widget is transient with regard to widget MASTER.r transientru)rNrs r wm_transientzWm.wm_transient s!ww||D+tww??rcP|jjdd|jS)zWithdraw this widget from the screen such that it is unmapped and forgotten by the window manager. Re-draw it with wm_deiconify.rrrurMs r wm_withdrawzWm.wm_withdraw sww||D*dgg66rrmrrnrl)BrPrQrRrrrrrrrrrrrrrrrrrrrrr#rr-rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr!rr rrsK'+&* *F"*J; F D)O= G8 I@ J-F4 ED H%)"& 9 D> E EJ6G? H@ H<2I2 #LC J- F6G6G9+@ #L 6HG I< H> E< E@ I7 HrrcDeZdZdZdZ d dZdZdZdZdZ d Z d Z y) rzzToplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.rGNc d|_i|_d|_d|_|Wddl}|j j tjd}|j j|\}}|dvr||z}d} tj|||| t||||_tr|jjt|r|j!tj"j$s|j'||yy)aAReturn a new top level widget on screen SCREENNAME. A new Tcl interpreter will be created. BASENAME will be used for the identification of the profile file (see readprofile). It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME is the name of the widget class.NFr)z.pyz.pyc)rr _tkloadedr<ospathbasenamerargvsplitextr8create wantobjects_debugsettrace_print_command_loadtkflagsignore_environment readprofile) rN screenNamebaseNameruseTksyncuser ext interactives r r z Tk.__init__ s     ww'' 4HGG,,X6MHc/)#c> //*h ;P[]bdhjmn  GG  ^ ,  LLNyy++   Xy 1,rcr|js+|jj|jyyr)r r<loadtkrrMs r r!z Tk.loadtk3 s%~~ GGNN  LLNrcd|_|jjd}|tjk7r t dtjd|dt |jjd}|tjk7r t dtjd|d|jg|_|jjd t|jjd t|jjd |jjd trt|a|jd |j y) NT tk_versionztk.h version (z!) doesn't match libtk.a version () tcl_versionztcl.h version (z") doesn't match libtcl.a version (tkerrorexitWM_DELETE_WINDOW)r r<rr8 TK_VERSIONr9r TCL_VERSIONrr#rrrrrrr)rNr#r%s r rz Tk._loadtk8 sWW^^L1 ,, ,"*"5"5z CD D$''..78 (.. ."*"6"6  EF F    $ "D  i2 fe,   +   ( ]%: M ($,,7rct|jjD]}|j|jj d|j tj|tr t|urda yyy)zhDestroy this and all descendants widgets. This will end the application of this Tcl interpreter.rN) rrvaluesrr<r rvrarrrNr0s r rz Tk.destroyR s_dmm**,-Aqyy{-  Y( T ]d%: M&; rcNddl}d|jvr|jd}n |j}|jj |d|z}|jj |d|z}|jj |d|z}|jj |d|z}d|i} t d| |jj |r|jjd||jj |r#t t|j| |jj |r|jjd||jj |r$t t|j| yy) zInternal function. It reads .BASENAME.tcl and .CLASSNAME.tcl into the Tcl Interpreter and calls exec on the contents of .BASENAME.py and .CLASSNAME.py if such a file exists in the home directory.rNHOMEz.%s.tclz.%s.pyrNzfrom tkinter import *source) r environcurdirr rexecisfiler<r openread) rNrrr home class_tclclass_pybase_tclbase_pydirs r rzTk.readprofile\ s8  RZZ  6(:YYdGGLLy9'<= 77<<h&:;77<<i(&:;'',,tX%89tn $c* 77>>) $ GGLL9 - 77>>( # h$$& , 77>>( # GGLL8 , 77>>' " g##%s + #rcddl}tdtj|t_|t_|t_|t_|j|||y)zReport callback exception on sys.stderr. Applications may want to override this internal function, and should when sys.stderr is None.rNzException in Tkinter callbackfile) tracebackr,rstderrlast_exc last_type last_valuelast_tracebackprint_exception)rNrrrr@s r rzTk.report_callback_exceptionr sE  -CJJ?  !!#sB/rc.t|j|S)z3Delegate attribute access to the interpreter object)rr<)rNattrs r __getattr__zTk.__getattr__ stww%%r)NNrTFN) rPrQrRrrvr r!rrrrrIr!rr rr s6@ BAE-12: 84!,, 0&rrr>cXt|tsJt|}t||y)Nr>)rrrr,)rr?s r rr s% c5 !! ! *C #Drct||||Sr)r)rrrrs r TclrL s j(Iu 55rcreZdZdZifdZexZxZZdZeZ dZ e Z e jxZZ e jxZZy)PackzQGeometry manager Pack. Base class to use the methods pack_* in every widget.c z|jjdd|jf|j||zy)a(Pack a widget in the parent widget. Use as options: after=widget - pack it after you have packed widget anchor=NSEW (or subset) - position widget according to given direction before=widget - pack it before you will pack widget expand=bool - expand widget if parent size grows fill=NONE or X or Y or BOTH - fill widget if widget grows in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. rrNr<r rvrrs r pack_configurezPack.pack_configure s5  {DGG, c2&' (rcR|jjdd|jy)z:Unmap this widget and do not use it for the packing order.rrNrurMs r pack_forgetzPack.pack_forget   VXtww/rct|j|jjdd|j}d|vr|j |d|d<|S)zEReturn information about the packing options for this widget.rrinrBr<r rvrrNds r pack_infozPack.pack_info M tww VVTWW E F 19''$0AdGrN)rPrQrRrrQrrrtrSrrZrrar!rr'r%r!rr rNrN sZ="$((!/.D.9v0F D!%!4!44I+++F[rrNcVeZdZdZifdZexZxZZdZeZ dZ e Z e jxZZ y)PlacezSGeometry manager Place. Base class to use the methods place_* in every widget.c z|jjdd|jf|j||zy)a Place a widget in the parent widget. Use as options: in=master - master relative to which the widget is placed in_=master - see 'in' option description x=amount - locate anchor of this widget at position x of master y=amount - locate anchor of this widget at position y of master relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge) rely=amount - locate anchor of this widget between 0.0 and 1.0 relative to height of master (1.0 is bottom edge) anchor=NSEW (or subset) - position anchor according to given direction width=amount - width of this widget in pixel height=amount - height of this widget in pixel relwidth=amount - width of this widget between 0.0 and 1.0 relative to width of master (1.0 is the same width as the master) relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master) bordermode="inside" or "outside" - whether to take border width of master widget into account r*rNrPrs r place_configurezPlace.place_configure s5,   TWW- c2&' (rcR|jjdd|jy)Unmap this widget.r*rNrurMs r place_forgetzPlace.place_forget s  Wh0rct|j|jjdd|j}d|vr|j |d|d<|S)zEReturn information about the placing options for this widget.r*rrVrWrXs r place_infozPlace.place_info sM tww Wfdgg F G 19''$0AdGrN)rPrQrRrr_r*rrtrbrrdrrar+r%r!rr r]r] sJ>#%(4"10E0I1F D ---F\rr]ceZdZdZifdZexZxZZejxZ Z ejxZ Z dZ e ZdZdZeZej$xZZej(xZZej,xZZej0xZZej4xZZy)GridzQGeometry manager Grid. Base class to use the methods grid_* in every widget.c z|jjdd|jf|j||zy)aPosition a widget in the parent widget in a grid. Use as options: column=number - use cell identified with given column (starting with 0) columnspan=number - this widget will span several columns in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction row=number - use cell identified with given row (starting with 0) rowspan=number - this widget will span several rows sticky=NSEW - if cell is larger on which sides will this widget stick to the cell boundary r-rNrPrs r grid_configurezGrid.grid_configure s5  {DGG, c2&' (rcR|jjdd|jy)rar-rNrurMs r grid_forgetzGrid.grid_forget rTrcR|jjdd|jy)z0Unmap this widget but remember the grid options.r-r1NrurMs r grid_removezGrid.grid_remove" rTrct|j|jjdd|j}d|vr|j |d|d<|S)zSReturn information about the options for positioning this widget in a grid.r-rrVrWrXs r grid_infozGrid.grid_info& r[rN)rPrQrRrrhr-rrtrar6r1rDrArjrrlrnrrHrFrJrrMrLrPrOrRr%r!rr rfrf s= "$(&!/.D.9v~~%D9-1-F-FFO*0F0 D#111H}!%!4!44I'+'='==L$~~%D9+++F[rrfc2eZdZdZdZiidfdZdZddZy) BaseWidgetzInternal class.c| t}||_|j|_d}d|vr|d}|d=|s|jjj }|dj r|dz }|ji|_|jj|ddz}||j|<|dk(rd|}nd||fz}||_ |jdk(r d|z|_ n|jdz|z|_ i|_ |j|jjvr1|jj|jj||jj|j<y) z6Internal function. Sets up information about children.Nrr!rrz!%s%drG) rrr<rBrPrisdigitrorrrvrr)rNrr/rcounts r _setupzBaseWidget._setup9 sS >&(F )) S=v;DF >>**002DBx! %%-)+&**..tQ7!;E+0F " "4 (z $$. 99c>DjDGii#o,DG ::-- - KK  , 4 4 6+/ TZZ(rr!c|r t||f}||_|j|||jg|_|j Dcgc]\}}t |t s||f}}}|D]\}}||= |jj||jf|z|j|z|D]\}}|j||ycc}}w)zdConstruct a widget with the parent widget MASTER, a name WIDGETNAME and appropriate options.N) r4 widgetNamerurr-rr(r<r rvrr) rNrrwr/roextrar2r3classess r r zBaseWidget.__init__Y s S"I&C$ FC    $ "D &)iikIkdaZ45HAq6kIDAqA   !E )DMM#,> > @DAq KKa  Js C(Ccpt|jjD]}|j|jj d|j |j|jjvr!|jj|j=tj|y)z)Destroy this and all descendants widgets.rN) rrr,rr<r rvrrrar-s r rzBaseWidget.destroyj srdmm**,-Aqyy{-  Y( ::-- - $$TZZ0 TrcV|jj|j|f|zSrru)rNrrns r _dozBaseWidget._dor s"ww||TWWdOd233rN)r!)rPrQrRrrur rr|r!rr rprp6 s#0@02b!"4rrpceZdZdZy)WidgetzxInternal class. Base class for a widget which can be positioned with the geometry managers Pack, Place or Grid.N)rPrQrRrr!rr r~r~w s  rr~ceZdZdZdifdZy)Toplevelz"Toplevel widget, e.g. for dialogs.Nc |r t||f}d}dD],}||vs||}|ddk(r d|ddz}nd|z}|||fz}||=.tj||d|i||j}|j |j |j |j |j d|jy) a%Construct a toplevel widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, menu, relief, screen, takefocus, use, visual, width.r!)r]class_r rcolormaprrr7Nryr()r4rpr rrrrr) rNrr/rorxwmkeyroptrs r r zToplevel.__init__ s S"I&CE|%j9#3uSbz>SIcc *J D&*c2uEzz| dmmo& 4::<  ($,,7rrPrQrRrr r!rr rr s,"8rrc(eZdZdZdifdZdZdZy)rzButton widget.Nc 6tj||d||y)aUConstruct a button widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, repeatdelay, repeatinterval, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS command, compound, default, height, overrelief, state, width buttonNr~r rNrr/ros r r zButton.__init__ s& fhR8rcP|jj|jdy)a_Flash the button. This is accomplished by redisplaying the button several times, alternating between active and normal colors. At the end of the flash the button is left in the same normal/active state as when the command was invoked. This command is ignored if the button's state is disabled. flashNrurMs r rz Button.flash s  TWWg&rcN|jj|jdS)aInvoke the command associated with the button. The return value is the return value from the command, or an empty string if there is no command associated with the button. This command is ignored if the button's state is disabled. invokerurMs r rz Button.invoke sww||DGGX..r)rPrQrRrr rrr!rr rr s"9* '/rrceZdZdZdifdZdZdZdZdZddZd=dZd=dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ d Z!d!Z"d"Z#dd:Z?d;Z@y)ACanvasz?Canvas widget to display graphical elements like lines or text.Nc 6tj||d||y)aConstruct a canvas widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, closeenough, confine, cursor, height, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, offset, relief, scrollregion, selectbackground, selectborderwidth, selectforeground, state, takefocus, width, xscrollcommand, xscrollincrement, yscrollcommand, yscrollincrement.canvasNrrs r r zCanvas.__init__ s fhR8rcX|jj|jdf|zy)raddtagNrurys r rz Canvas.addtag   dggx(4/0rc*|j|d|y)z*Add tag NEWTAG to all items above TAGORID.aboveNrrNnewtagtagOrIds r addtag_abovezCanvas.addtag_above  FGW-rc(|j|dy)zAdd tag NEWTAG to all items.rNr)rNrs r addtag_allzCanvas.addtag_all s FE"rc*|j|d|y)z*Add tag NEWTAG to all items below TAGORID.belowNrrs r addtag_belowzCanvas.addtag_below rrc0|j|d||||y)zAdd tag NEWTAG to item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.closestNr)rNrrrhalostarts r addtag_closestzCanvas.addtag_closest s FIq!T59rc0|j|d||||y)zLAdd tag NEWTAG to all items in the rectangle defined by X1,Y1,X2,Y2.enclosedNrrNrx1y1x2y2s r addtag_enclosedzCanvas.addtag_enclosed s FJBB7rc0|j|d||||y)zWAdd tag NEWTAG to all items which overlap the rectangle defined by X1,Y1,X2,Y2. overlappingNrrs r addtag_overlappingzCanvas.addtag_overlapping s FM2r2r:rc*|j|d|y)z)Add tag NEWTAG to all items with TAGORID.withtagNrrs r addtag_withtagzCanvas.addtag_withtag s FIw/rc||j|jj|jdf|zxsdS)z|Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses all items with tags specified as arguments.r1NrErys r r1z Canvas.bbox s;}} GGLL$''6*T1 24<7; =*+!!!$=> >>s"A6c t|}|d}t|ttfr|dd}ni}|jj |jj |jd|g||j||zS)rrNr) r"rr'rr<rQr rvr)rNitemTypernror/s r _createzCanvas._create' s{~2h cD%= )9DCww~~ldggll GGXx.T]]3++./ /rc(|jd||S)z6Create arc shaped region with coordinates x1,y1,x2,y2.arcrrms r create_arczCanvas.create_arc3 s||E4,,rc(|jd||S)z%Create bitmap with coordinates x1,y1.rrrms r create_bitmapzCanvas.create_bitmap7 ||HdB//rc(|jd||S)z)Create image item with coordinates x1,y1.rcrrms r create_imagezCanvas.create_image; s||GT2..rc(|jd||S)z-Create line with coordinates x1,y1,...,xn,yn.rrrms r create_linezCanvas.create_line? ||FD"--rc(|jd||S)z)Create oval with coordinates x1,y1,x2,y2.ovalrrms r create_ovalzCanvas.create_ovalC rrc(|jd||S)z0Create polygon with coordinates x1,y1,...,xn,yn.polygonrrms r create_polygonzCanvas.create_polygonG s||ItR00rc(|jd||S)z.Create rectangle with coordinates x1,y1,x2,y2. rectanglerrms r create_rectanglezCanvas.create_rectangleK s||Kr22rc(|jd||S)z#Create text with coordinates x1,y1.textrrms r create_textzCanvas.create_textO rrc(|jd||S)z+Create window with coordinates x1,y1,x2,y2.rtrrms r create_windowzCanvas.create_windowS rrcX|jj|jdf|zy)zDelete characters of text items identified by tag or id in ARGS (possibly several times) from FIRST to LAST character (including).dcharsNrurys r rz Canvas.dcharsW "  dggx(4/0rcX|jj|jdf|zy)z$>rcV|jj|jdd||y)z=Set the variable end of a selection in item TAGORID to INDEX.r"toNrur$s r select_tozCanvas.select_to s  TWWhgu=rcX|jj|jd|xsdS)z$Return the type of the item TAGORID.r(Nrurs r r(z Canvas.type s"ww||DGGVW5==rrnrrE)rr) )ArPrQrRrr rrrrrrrrr1rrrrrrrrrrrrrrrrrZrrrrrrrrrrrrr=rrr  itemconfigr rrrrrrqrrrr r%r(r+r-r0r(r!rr rr sKI" 91.#.:8 ; 0< C '7 7 > /-0/..13.01 1/ : + +75 8 -77 2 G1 ; DJ 0 E/7 ,0 D704< B1@?>>rrcLeZdZdZdifdZfdZdZdZdZdZ d Z xZ S) Checkbuttonz7Checkbutton widget which is either in on- or off-state.Nc 6tj||d||y)aConstruct a checkbutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, offvalue, onvalue, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, variable, width, wraplength. checkbuttonNrrs r r zCheckbutton.__init__  fmS"=rc|jds<|jjj}tdz ad|dt|d<t |||y)Nrrrrr7)rrBrPr_checkbutton_countsuperru)rNrr/rrBs r ruzCheckbutton._setup s[wwv>>**002D ! # dV1%7$89CK vs#rcP|jj|jdyzPut the button in off-state.deselectNrurMs r r>zCheckbutton.deselect s  TWWj)rcP|jj|jdyzFlash the button.rNrurMs r rzCheckbutton.flash"   TWWg&rcN|jj|jdSzrrr"rI __classcell__)rBs@r r5r5 s.A" > $*'/((rr5ceZdZdZdifdZddZdZdZdZdZ d Z d Z d Z e Z d ZeZd ZeZdZeZdZeZdZeZy)Entryz1Entry widget which allows displaying simple text.Nc 6tj||d||y)aConstruct an entry widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, invalidcommand, invcmd, justify, relief, selectbackground, selectborderwidth, selectforeground, show, state, takefocus, textvariable, validate, validatecommand, vcmd, width, xscrollcommand.entryNrrs r r zEntry.__init__6 s fgsB7rcT|jj|jd||y)z.Delete text from FIRST to LAST (not included).rZNrurNfirstlasts r rZz Entry.deleteC   TWWht4rcN|jj|jdS)zReturn the text.rrurMs r rz Entry.getG ww||DGGU++rcR|jj|jd|y)zInsert cursor at INDEX.rNrurNr=s r rz Entry.icursorK s  TWWi/rc|jj|jj|jd|S)zReturn position of cursor.r=rrWs r r=z Entry.indexO s1ww~~dggll GGWe%& &rcT|jj|jd||y)zInsert STRING at INDEX.rNru)rNr=rs r rz Entry.insertT s  TWWhv6rcT|jj|jdd|yrrur>s r rzEntry.scan_markX s  TWWffa0rcT|jj|jdd|y)zAdjust the view of the canvas to 10 times the difference between X and Y and the coordinates given in scan_mark.rrNrur>s r r zEntry.scan_dragto\ s  TWWfh2rcT|jj|jdd|y)z9Adjust the end of the selection near the cursor to INDEX.rr#NrurWs r selection_adjustzEntry.selection_adjustb   TWWk8U;rcR|jj|jddy)r'rrNrurMs r rzEntry.selection_clearh s  TWWk73rcT|jj|jdd|y)*Set the fixed end of a selection to INDEX.rr*NrurWs r selection_fromzEntry.selection_fromn s  TWWk659rc|jj|jj|jddS)zSReturn True if there are characters selected in the entry, False otherwise.rpresentrrMs r selection_presentzEntry.selection_presentt 3ww!! GGLL+y 9; ;rcV|jj|jdd||y)3Set the selection from START to END (not included).rrangeNrurNrends r selection_rangezEntry.selection_range| s  TWWk7E3?rcT|jj|jdd|y)-Set the variable end of a selection to INDEX.rr/NrurWs r selection_tozEntry.selection_to s  TWWk47rr)rPrQrRrr rZrrr=rrr r]r%rr(rbr+reselect_presentrl select_rangeror0r!rr rLrL3 s{;" 85,0& 713 <%M4#L:!K; 'N@#L8IrrLceZdZdZdifdZy)FramezFFrame widget which may contain other widgets and can have a 3D border.Nc t||f}d}d|vr d|df}|d=nd|vr d|df}|d=tj||d|i|y)aConstruct a frame widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.r!rz-classr rN)r4r~r )rNrr/rorxs r r zFrame.__init__ se b " s?s8}-EH ^s7|,EG fgsB>rrr!rr rsrs sP"?rrsceZdZdZdifdZy)Labelz0Label widget which can display text and bitmaps.Nc 6tj||d||y)aConstruct a label widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground, highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS height, state, width labelNrrs r r zLabel.__init__ s$ fgsB7rrr!rr rvrv s:"8rrvceZdZdZdifdZdZdZdZddZddZ d Z d Z d Z d Z d ZdZdZeZddZeZdZeZddZeZdZdZddZeZy)Listboxz3Listbox widget which can display a list of strings.Nc 6tj||d||y)aConstruct a listbox widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, relief, selectbackground, selectborderwidth, selectforeground, selectmode, setgrid, takefocus, width, xscrollcommand, yscrollcommand, listvariable.listboxNrrs r r zListbox.__init__ s fib9rcR|jj|jd|y)z"Activate item identified by INDEX.activateNrurWs r r~zListbox.activate   TWWj%0rcv|j|jj|jd|xsdS)zxReturn a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the item identified by the given index.r1NrErWs r r1z Listbox.bbox s-}}TWW\\$''65ABJdJrct|j|jj|jdxsdS)z.Return the indices of currently selected item. curselectionr!rErMs r rzListbox.curselection s)}}TWW\\$''>BCIrIrcT|jj|jd||y)z+Delete items from FIRST to LAST (included).rZNrurPs r rZzListbox.delete rSrc|A|jj|jj|jd||S|jj|jd|S)z0Get list of items from FIRST to LAST (included).rrrPs r rz Listbox.get sX  77$$TWW\\t&-. .77<<6 6rc|jj|jd|}|dk(ry|jj|S)z+Return index of item identified with INDEX.r=rNr<r rvrQrNr=rs r r=z Listbox.index s8 GGLL'5 1 ;tww~~a  rcZ|jj|jd|f|zy)zInsert ELEMENTS at INDEX.rNru)rNr=elementss r rzListbox.insert s"  dggx/(:;rc|jj|jj|jd|S)z5Get index of item which is nearest to y coordinate Y.nearestr)rNrs r rzListbox.nearest s1ww~~dggll GGY#$ $rcV|jj|jdd||yrrurGs r rzListbox.scan_mark rrcV|jj|jdd||y)zAdjust the view of the listbox to 10 times the difference between X and Y and the coordinates given in scan_mark.rrNrurGs r r zListbox.scan_dragto   TWWfh15rcR|jj|jd|y)z"Scroll such that INDEX is visible.seeNrurWs r rz Listbox.see   TWWeU+rcT|jj|jdd|y)z-Set the fixed end oft the selection to INDEX.rr.NrurWs r selection_anchorzListbox.selection_anchor r^rcV|jj|jdd||y)z2Clear the selection from FIRST to LAST (included).rrNrurPs r rzListbox.selection_clear s!  TWWgud 4rc|jj|jj|jdd|S)z.Return True if INDEX is part of the selection.rincludesrrWs r selection_includeszListbox.selection_includes s5ww!!$'',, GG[*e#56 6rcV|jj|jdd||y)ziSet the selection from FIRST to LAST (included) without changing the currently selected elements.rrNrurPs r selection_setzListbox.selection_set s   TWWk5%>rc|jj|jj|jdS)z-Return the number of elements in the listbox.rOrrMs r rOz Listbox.size s(ww~~dggll477F;<F!%F!3TZZ5GJ  J$6%* "J z:>2AD,,Q//q)45&&q) 3  TWWh7rcX|jj|jd|d|zS)z=Return the resource value of a menu item for OPTION at INDEX.rr7rurs r rzMenu.entrycget s#ww||DGG[%vFFrc ,|jd|f||S)zConfigure a menu item at INDEX.entryconfigurerrCs r rzMenu.entryconfigure s 0%8#rBBrc|jj|jd|}|dvrdS|jj|S)z4Return the index of a menu item identified by INDEX.r=)rrNrrs r r=z Menu.index s; GGLL'5 1L(t?dggnnQ.??rcP|jj|jd|S)zRInvoke a menu item identified by INDEX and execute the associated command.rrurWs r rz Menu.invoke sww||DGGXu55rcT|jj|jd||y)zDisplay a menu at position X,Y.postNrurGs r rz Menu.post s  TWWfa+rcP|jj|jd|S)z*Return the type of the menu item at INDEX.r(rurWs r r(z Menu.type sww||DGGVU33rcP|jj|jdy)z Unmap a menu.unpostNrurMs r rz Menu.unpost rGrc|jj|jj|jd|S)zNReturn the x-position of the leftmost pixel of the menu item at INDEX. xpositionrrWs r rzMenu.xposition s,ww~~dggll477KGHHrc|jj|jj|jd|S)zEReturn the y-position of the topmost pixel of the menu item at INDEX. ypositionrrWs r rzMenu.yposition s1ww~~dggll GG[%)* *rrr)rPrQrRrr rr~r*rrrrrrrrrrrrZrrrr=rrr(rrrr!rr rr) sZ"771!#) !'#%+!'#%+!#)+-) )+1-/5)+1-/5+-38 GC!K@ 6 ,4(I *rrceZdZdZdifdZy) Menubuttonz(Menubutton widget, obsolete since Tk8.0.Nc 6tj||d||y)N menubuttonrrs r r zMenubutton.__init__ sflCzRadiobutton.deselect s  TWWj)rcP|jj|jdyr@rurMs r rzRadiobutton.flash rArcN|jj|jdSrCrurMs r rzRadiobutton.invoke rDrcP|jj|jdyrFrurMs r r"zRadiobutton.select rGr) rPrQrRrr r>rrr"r!rr rr s#Q" >* '/(rrc6eZdZdZdifdZdZdZddZdZy) Scalez1Scale widget which can display a numerical scale.Nc 6tj||d||y)aConstruct a scale widget with the parent MASTER. Valid resource names: activebackground, background, bigincrement, bd, bg, borderwidth, command, cursor, digits, fg, font, foreground, from, highlightbackground, highlightcolor, highlightthickness, label, length, orient, relief, repeatdelay, repeatinterval, resolution, showvalue, sliderlength, sliderrelief, state, takefocus, tickinterval, to, troughcolor, variable, width.rNrrs r r zScale.__init__ s fgsB7rc|jj|jd} |jj|S#tt t f$r|jj|cYSwxYw)z*Get the current value as integer or float.r)r<r rvrQrr+rrRrs r rz Scale.get s] TWWe, ,77>>%( (Ix0 ,77$$U+ + ,sA/A54A5cR|jj|jd|y)zSet the value to VALUE.rNrurs r rz Scale.set rrcn|j|jj|jd|S)zReturn a tuple (X,Y) of the point along the centerline of the trough that corresponds to VALUE or the current value if None is given.rrErs r rz Scale.coords s( }}TWW\\$''8UCDDrcR|jj|jd||S)zcReturn where the point X,Y lies. Valid return values are "slider", "though1" and "though2".identifyrurGs r rzScale.identify !ww||DGGZA66rr) rPrQrRrr rrrrr!rr rr s$;" 8,,E7rrcBeZdZdZdifdZd dZdZdZdZdZ d Z y) Scrollbarz?Scrollbar widget which displays a slider at a certain position.Nc 6tj||d||y)alConstruct a scrollbar widget with the parent MASTER. Valid resource names: activebackground, activerelief, background, bd, bg, borderwidth, command, cursor, elementborderwidth, highlightbackground, highlightcolor, highlightthickness, jump, orient, relief, repeatdelay, repeatinterval, takefocus, troughcolor, width. scrollbarNrrs r r zScrollbar.__init__s fk3;rcX|jj|jd|xsdS)aMarks the element indicated by index as active. The only index values understood by this method are "arrow1", "slider", or "arrow2". If any other value is specified then no element of the scrollbar will be active. If index is not specified, the method returns the name of the element that is currently active, or None if no element is active.r~NrurWs r r~zScrollbar.activates$ww||DGGZ7?4?rc|jj|jj|jd||S)znReturn the fractional change of the scrollbar setting if it would be moved by DELTAX or DELTAY pixels.rr)rNdeltaxdeltays r rzScrollbar.deltas5ww  GGLL'66 :< 2rrceZdZdZdifdZdZdZdZd8dZd8dZ d Z d9d Z d Z d8d Z d ZdZdZdZd8dZdZd8dZifdZdZdZdZd8dZdZdZdZdZdZifdZdZ d Z!d!Z"d"Z# d:d#Z$d$Z%d%Z&d8d&Z'd8d'Z(d;d(Z)d)Z*d8d*Z+e+Z,d+Z-d8d,Z.d8d-Z/d8d.Z0d8d/Z1d8d0Z2d1Z3d8d2Z4d3Z5d8d4Z6e6Z7ifd5Z8d6Z9d7Z:y)<Textz4Text widget which can display text in various forms.Nc 6tj||d||y)aConstruct a text widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, padx, pady, relief, selectbackground, selectborderwidth, selectforeground, setgrid, takefocus, xscrollcommand, yscrollcommand, WIDGET-SPECIFIC OPTIONS autoseparators, height, maxundo, spacing1, spacing2, spacing3, state, tabs, undo, width, wrap, rNrrs r r z Text.__init__5s. ffc26rcv|j|jj|jd|xsdS)zReturn a tuple of (x,y,width,height) which gives the bounding box of the visible part of the character at the given index.r1NrErWs r r1z Text.bboxNs5}} TWWfe46>9= >rc |jj|jj|jd|||S)zReturn whether between index INDEX1 and index INDEX2 the relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.comparer)rNroprs r rz Text.compareTs9ww!!$'',, GGYF#45 5rc|Dcgc]}d|z }}|||gz }|jj|jdg|xsd}|t|dkr|fS|Scc}w)aCounts the number of relevant things between the two indices. If index1 is after index2, the result will be a negative number (and this holds for each of the possible options). The actual items which are counted depends on the options given by args. The result is a list of integers, one for the result of each counting option given. Valid counting options are "chars", "displaychars", "displayindices", "displaylines", "indices", "lines", "xpixels" and "ypixels". There is an additional possible option "update", which if given then all subsequent options ensure that any possible out of date information is recalculated.r^rtN)r<r rvr)rNrrrnargr$s r rtz Text.countZso(,,t t,   dggll477G3d3;t ?s4yA~7NJ -s Ac|?|jj|jj|jdS|jj|jd|y)zjTurn on the internal consistency checks of the B-Tree inside the text widget according to BOOLEAN.Ndebugrrfs r r z Text.debugnsI ?77%%dggll477G&DE E  TWWgw/rcT|jj|jd||y)z?Delete the characters between INDEX1 and INDEX2 (not included).rZNrurNrrs r rZz Text.deleteus  TWWh7rcn|j|jj|jd|S)zReturn tuple (x,y,width,height,baseline) giving the bounding box and baseline position of the visible part of the line containing the character at INDEX. dlineinforErWs r rzText.dlineinfoys(}}TWW\\$'';FGGrc g}d}d}|s g}|fd}|} t|ts|j|x}}|d|gz }|D]} || s |jd| z|j||r|j||jj |j dg|||r|j|SS#|r|j|wwxYw)aReturn the contents of the widget between index1 and index2. The type of contents returned in filtered based on the keyword parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are given and true, then the corresponding items are returned. The result is a list of triples of the form (key, value, index). If none of the keywords are true then 'all' is used by default. If the 'command' argument is given, it is called once for each element of the list of triples, with the values of each triple serving as the arguments to the function. In this case the list is not returned.Nc,|j|||fyr)r)rAr r=rs r append_triplez Text.dump..append_triples sE512rz-commandr7dump)rrr'rr<r rvr) rNrrrrorn func_namerrrAs r rz Text.dumps  F8> 3#G .gs+&*nnW&== G Z) )Dc7DKKc 2 KK  F# DGGLL& 04 0""9-y""9-s4CA#CCcR|jj|jdg|S)arInternal method This method controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the command are currently supported: edit_modified, edit_redo, edit_reset, edit_separator and edit_undo editrurys r rz Text.edits$tww||DGGV3d33rc&|jd|S)a;Get or Set the modified flag If arg is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to arg. modifiedr)rNr s r edit_modifiedzText.edit_modifiedsyyS))rc$|jdS)a Redo the last undone edit When the undo option is true, reapplies the last undone edits provided no other edits were done since then. Generates an error when the redo stack is empty. Does nothing when the undo option is false. redorrMs r edit_redozText.edit_redosyy  rc$|jdS)z(Clears the undo and redo stacks resetrrMs r edit_resetzText.edit_resetsyy!!rc$|jdS)znInserts a separator (boundary) on the undo stack. Does nothing when the undo option is false rrrMs r edit_separatorzText.edit_separators yy%%rc$|jdS)aDUndoes the last edit action If the undo option is true. An edit action is defined as all the insert and delete commands that are recorded on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the undo option is false undorrMs r edit_undozText.edit_undosyy  rcR|jj|jd||S)z5Return the text from INDEX1 to INDEX2 (not included).rrurs r rzText.getsww||DGGUFF;;rc|dddk7rd|z}|dddk(r|dd}|jj|jdd||S)z9Return the value of OPTION of an embedded image at INDEX.Nrr7rrrcrrurs r image_cgetzText.image_cgetsQ "1: 6\F "#;# CR[Fww||DGGWfeVDDrc .|jdd|f||S)z%Configure an embedded image at INDEX.rcrrrCs r image_configurezText.image_configuresercV|jj|jdd||fS)zChange the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). Return the current value if None is given for DIRECTION.rgravityru)rNmarkName directions r mark_gravityzText.mark_gravitys+ww|| WWfi9 =? ?rc|jj|jj|jddS)zReturn all mark names.rrdrrMs r mark_nameszText.mark_names s3ww   GGVW"&' 'rcV|jj|jdd||y)z0Set mark MARKNAME before the character at INDEX.rrNru)rNr4r=s r mark_setz Text.mark_sets  TWWfeXu=rcZ|jj|jddf|zy)zDelete all marks in MARKNAMES.runsetNru)rN markNamess r mark_unsetzText.mark_unsets"  dggvw/);ww   GGUK&&"BC Crc |jj|jj|jdd|||S)zReturn a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched backwards from INDEX1.rX prevrangerrls r tag_prevrangezText.tag_prevrangernrcV|jj|jdd||y)zaChange the priority of tag TAGNAME such that it is higher than the priority of ABOVETHIS.rXrNru)rNrYrs r rzText.tag_raises#  GGUGWi 9rc|jj|jj|jdd|S)z7Return a list of ranges of text which have tag TAGNAME.rXrangesr)rNrYs r tag_rangeszText.tag_rangess5ww   GGUHg"/0 0rcX|jj|jdd|||y)zARemove tag TAGNAME from all characters between INDEX1 and INDEX2.rXr1Nrurls r tag_removezText.tag_removes#  GGUHgvv ?rc|dddk7rd|z}|dddk(r|dd}|jj|jdd||S)z:Return the value of OPTION of an embedded window at INDEX.Nrr7rrrtrrurs r window_cgetzText.window_cgetsQ "1: 6\F "#;# CR[Fww||DGGXvufEErc .|jdd|f||S)z&Configure an embedded window at INDEX.rtrrrCs r window_configurezText.window_configures+u=sBGGrc ||jj|jdd|f|j||zy)zCreate a window at INDEX.rtrNrPrCs r window_createzText.window_creates5  ww(E2 c2&' (rc|jj|jj|jddS)z4Return all names of embedded windows in this widget.rtrdrrMs r window_nameszText.window_namess1ww  GGLL(G 46 6rcZ|jj|jddf|zy)zObsolete function, use see.rz -pickplaceNru)rNrs r yview_pickplacezText.yview_pickplaces"  dggw 5<=rrrn)NNNNNNNNrE);rPrQrRrr r1rrtr rZrrrrrr!r#r&rr)r+r-rer=rr6r8r:r>rArDrHrJrrr rrrZrrr_rarc tag_configrfr rirmrqrrurwryr{ window_configr}rrr!rr rr2sI>"72> 5 (08H %.P 4 *!" & !< EG')* 7:? ? ' >=DH,.%I G46 04047;.(,= Q '' EGJ<B : CC9 0 ? FH%M')( 6 >rrceZdZdZddZdZy)_setitz>Internal class. It wraps the command in the widget OptionMenu.Nc.||_||_||_yr) _setit__value _setit__var_setit__callback)rNvarr r$s r r z_setit.__init__s  "rc|jj|j|j|j|jg|yyr)rrrrrys r r z_setit.__call__s< t||$ ?? & DOODLL 04 0 'rrrzr!rr rrsH# 1rrc"eZdZdZdZdZdZy) OptionMenuz?OptionMenu which allows the user to select a value from a menu.c d|dtddd}tj||d|d|_t |dd x}|_|j |_|jd }d |vr|d =|r td tt|z|j|t||| |D] } |j| t|| | "||d<y )zConstruct an optionmenu widget with the parent MASTER, with the resource textvariable set to VARIABLE, the initially selected value VALUE, the other menu values VALUES and an additional keyword argument command.r6rr0) borderwidth textvariable indicatoronreliefr.highlightthicknessr tk_optionMenurr)rtearoffrzunknown option -)rxrN)RAISEDr~r rwr_OptionMenu__menurvmenunamerrr@r:rr) rNrr+r r,kwargsrorr$r3s r r zOptionMenu.__init__s &C$%' flB7)!$VQ??t{ ::i(  y! -d4<.@@A A u%:  <A   1#Ha:  <V rcP|dk(r |jStj||S)Nr)rr~rurs r ruzOptionMenu.__getitem__s& 6>;; !!$--rc<tj|d|_y)z,Destroy this widget and the associated menu.N)rrrrMs r rzOptionMenu.destroys4  rN)rPrQrRrr rurr!rr rrsI2. rrcVeZdZdZdZdidfdZdZdZdZdZ d Z e Z d Z d Z d Zy) ImagezBase class for images.rNc rd|_| td}t|d||_|s,txj dz c_dtj }|r|rt ||f}n|r|}d}|jD]\}}|d|z|fz}|jjdd||f|z||_y) Nz create imager<rpyimager!r7rcr) rrrr<r_last_idr4r-r ) rNimgtyperr/rror>r2r3s r r zImage.__init__s >&~6F&$/ NNa N"'..2D #YRy1s rIIKDAqQ *G   gx$87BC rc|jSr)rrMs r rOz Image.__str__s dii'rc|jr) |jjdd|jyy#t$rYywxYw)NrcrZ)rr<r rrMs r rz Image.__del__s? 99  Wh :   s'7 AAcZ|jj|jdd|z|yNrr7r<r rrs r rzImage.__setitem__s   TYY SWe2>rcP|jj|jdy)zDisplay a transparent image.blankNrrMs r rzPhotoImage.blankFs  TYY(rcV|jj|jdd|zS)zReturn the value of OPTION.rr7r)rNrs r rzPhotoImage.cgetJs!ww||DIIvsV|<s r rzSpinbox.scan_mark syy##rc&|jd|S)aCompute the difference between the given x argument and the x argument to the last scan mark command It then adjusts the view left or right by 10 times the difference in x-coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the spinbox at high speed through the window. The return value is an empty string. rrr>s r r zSpinbox.scan_dragtosyy1%%rc||j|jj|jdf|zxsdS)rrr!rErys r rzSpinbox.selections9}} GGLL$'';/$6 79?<> ?rc&|jd|S)aLocate the end of the selection nearest to the character given by index, Then adjust that end of the selection to be at index (i.e including but not going beyond index). The other end of the selection is made the anchor point for future select to commands. If the selection isn't currently in the spinbox, then a new selection is created to include the characters between index and the most recent selection anchor point, inclusive. r#rrWs r r]zSpinbox.selection_adjust#s~~h..rc$|jdS)zsClear the selection If the selection isn't in this widget then the command has no effect. rrrMs r rzSpinbox.selection_clear1s ~~g&&rcR|jj|jdd|S)zSets or gets the currently selected element. If a spinbutton element is specified, it will be displayed depressed. rrrurs r selection_elementzSpinbox.selection_element9s! ww||DGG[)WEErc(|jd|y)rar*NrrWs r rbzSpinbox.selection_fromAs vu%rc|jj|jj|jddS)zUReturn True if there are characters selected in the spinbox, False otherwise.rrdrrMs r rezSpinbox.selection_presentErfrc*|jd||y)rhriNrrjs r rlzSpinbox.selection_rangeKs ws+rc(|jd|y)rnr/NrrWs r rozSpinbox.selection_toOs tU#rr)rPrQrRrr r1rZrrrr=rrrrr rr]rrrbrerlror!rr rrsp":: K <,775 98: $ &? /'F&; ,$rrceZdZdZdifdZy) LabelFramezlabelframe widget.Nc 6tj||d||y)aConstruct a labelframe widget with the parent MASTER. STANDARD OPTIONS borderwidth, cursor, font, foreground, highlightbackground, highlightcolor, highlightthickness, padx, pady, relief, takefocus, text WIDGET-SPECIFIC OPTIONS background, class, colormap, container, height, labelanchor, labelwidget, visual, width labelframeNrrs r r zLabelFrame.__init__Ys flC B/F 7; # $ ) : )(/ 9J)XJArrct}d|jdz}|dz }t||}|jt |d|fd}|j||_t |d|j }|j|j|j|j|jy) NzThis is Tcl/Tk %s tk_patchLevelu This should be a cedilla: çrz Click me!cZ|jjd|jdzS)Nz[%s]rr)testrrs r z_test..7s) (;(; & 11)<)3r)rrQUIT) rrrvrrrrrr)rr^)rrrxrrs r _testr0s 4D !2!2?!C CD ..D $T "E JJL $["&3 4D IIKDI $VT\\ :DIIK LLNKKMNNMMOrr>r__main__)TNrrk)NNrF)gr collectionsenumrrhr8rtkinter.constantsrXrrfloatr) TkVersionr* TclVersionREADABLEWRITABLE EXCEPTIONcompilerASCIIrrr r"r*r4rB namedtuplerDr^ _simple_enumStrEnumr`rrrrrrrrrrrrGrNrTrXr^r[rQrRr rarr|rrrrArrLrNr]rfrpr~rrrr:r5rLrsrvrzrrrrrrrrrrrrrerirrrrglobalsr-rr ModuleType__all__rP)robjs00r r3s@@       (%% & 8'' (           BJJ{ # BJJy"(( + , 8!!X$##Y.S-{--.@=?S G4<< ''!'TO O d   "  q+q+h02X22EE*AA<:   =AAD(,,,??*??*mm` p&rp&f!$ ,6+,+,\0.0.f4,4,n>4>4B Zud 8z28<,/V,/^q>VUEq>h .(&.(bSFESl?F?(8F80qfeUqh~*6~*B==:f:(&(B$7F$7N/2/2dT>65%T>n 1 1$$N;7;7|QFQFh@%@3 3 m$fem$d==0}A&}AD*")!2 ,!2ID#//#&z#u?O?O/P?* !2 , z GEOt,tPN ,s*0 M2? M>,4N 2M;:M;>NNtkinter/dialog.py000064400000002777152342670510010057 0ustar00# dialog.py -- Tkinter interface to the tk_dialog script. from tkinter import _cnfmerge, Widget, TclError, Button, Pack __all__ = ["Dialog"] DIALOG_ICON = 'questhead' class Dialog(Widget): def __init__(self, master=None, cnf={}, **kw): cnf = _cnfmerge((cnf, kw)) self.widgetName = '__dialog__' self._setup(master, cnf) self.num = self.tk.getint( self.tk.call( 'tk_dialog', self._w, cnf['title'], cnf['text'], cnf['bitmap'], cnf['default'], *cnf['strings'])) try: Widget.destroy(self) except TclError: pass def destroy(self): pass def _test(): d = Dialog(None, {'title': 'File Modified', 'text': 'File "Python.h" has been modified' ' since the last time it was saved.' ' Do you want to save it before' ' exiting the application.', 'bitmap': DIALOG_ICON, 'default': 0, 'strings': ('Save File', 'Discard Changes', 'Return to Editor')}) print(d.num) if __name__ == '__main__': t = Button(None, {'text': 'Test', 'command': _test, Pack: {}}) q = Button(None, {'text': 'Quit', 'command': t.quit, Pack: {}}) t.mainloop() tkinter/constants.py000064400000002725152342670510010625 0ustar00# Symbolic constants for Tk # Booleans NO=FALSE=OFF=0 YES=TRUE=ON=1 # -anchor and -sticky N='n' S='s' W='w' E='e' NW='nw' SW='sw' NE='ne' SE='se' NS='ns' EW='ew' NSEW='nsew' CENTER='center' # -fill NONE='none' X='x' Y='y' BOTH='both' # -side LEFT='left' TOP='top' RIGHT='right' BOTTOM='bottom' # -relief RAISED='raised' SUNKEN='sunken' FLAT='flat' RIDGE='ridge' GROOVE='groove' SOLID = 'solid' # -orient HORIZONTAL='horizontal' VERTICAL='vertical' # -tabs NUMERIC='numeric' # -wrap CHAR='char' WORD='word' # -align BASELINE='baseline' # -bordermode INSIDE='inside' OUTSIDE='outside' # Special tags, marks and insert positions SEL='sel' SEL_FIRST='sel.first' SEL_LAST='sel.last' END='end' INSERT='insert' CURRENT='current' ANCHOR='anchor' ALL='all' # e.g. Canvas.delete(ALL) # Text widget and button states NORMAL='normal' DISABLED='disabled' ACTIVE='active' # Canvas state HIDDEN='hidden' # Menu item types CASCADE='cascade' CHECKBUTTON='checkbutton' COMMAND='command' RADIOBUTTON='radiobutton' SEPARATOR='separator' # Selection modes for list boxes SINGLE='single' BROWSE='browse' MULTIPLE='multiple' EXTENDED='extended' # Activestyle for list boxes # NONE='none' is also valid DOTBOX='dotbox' UNDERLINE='underline' # Various canvas styles PIESLICE='pieslice' CHORD='chord' ARC='arc' FIRST='first' LAST='last' BUTT='butt' PROJECTING='projecting' ROUND='round' BEVEL='bevel' MITER='miter' # Arguments to xview/yview MOVETO='moveto' SCROLL='scroll' UNITS='units' PAGES='pages' tkinter/dnd.py000064400000026574152342670510007366 0ustar00"""Drag-and-drop support for Tkinter. This is very preliminary. I currently only support dnd *within* one application, between different windows (or within the same window). I am trying to make this as generic as possible -- not dependent on the use of a particular widget or icon type, etc. I also hope that this will work with Pmw. To enable an object to be dragged, you must create an event binding for it that starts the drag-and-drop process. Typically, you should bind to a callback function that you write. The function should call Tkdnd.dnd_start(source, event), where 'source' is the object to be dragged, and 'event' is the event that invoked the call (the argument to your callback function). Even though this is a class instantiation, the returned instance should not be stored -- it will be kept alive automatically for the duration of the drag-and-drop. When a drag-and-drop is already in process for the Tk interpreter, the call is *ignored*; this normally averts starting multiple simultaneous dnd processes, e.g. because different button callbacks all dnd_start(). The object is *not* necessarily a widget -- it can be any application-specific object that is meaningful to potential drag-and-drop targets. Potential drag-and-drop targets are discovered as follows. Whenever the mouse moves, and at the start and end of a drag-and-drop move, the Tk widget directly under the mouse is inspected. This is the target widget (not to be confused with the target object, yet to be determined). If there is no target widget, there is no dnd target object. If there is a target widget, and it has an attribute dnd_accept, this should be a function (or any callable object). The function is called as dnd_accept(source, event), where 'source' is the object being dragged (the object passed to dnd_start() above), and 'event' is the most recent event object (generally a event; it can also be or ). If the dnd_accept() function returns something other than None, this is the new dnd target object. If dnd_accept() returns None, or if the target widget has no dnd_accept attribute, the target widget's parent is considered as the target widget, and the search for a target object is repeated from there. If necessary, the search is repeated all the way up to the root widget. If none of the target widgets can produce a target object, there is no target object (the target object is None). The target object thus produced, if any, is called the new target object. It is compared with the old target object (or None, if there was no old target widget). There are several cases ('source' is the source object, and 'event' is the most recent event object): - Both the old and new target objects are None. Nothing happens. - The old and new target objects are the same object. Its method dnd_motion(source, event) is called. - The old target object was None, and the new target object is not None. The new target object's method dnd_enter(source, event) is called. - The new target object is None, and the old target object is not None. The old target object's method dnd_leave(source, event) is called. - The old and new target objects differ and neither is None. The old target object's method dnd_leave(source, event), and then the new target object's method dnd_enter(source, event) is called. Once this is done, the new target object replaces the old one, and the Tk mainloop proceeds. The return value of the methods mentioned above is ignored; if they raise an exception, the normal exception handling mechanisms take over. The drag-and-drop processes can end in two ways: a final target object is selected, or no final target object is selected. When a final target object is selected, it will always have been notified of the potential drop by a call to its dnd_enter() method, as described above, and possibly one or more calls to its dnd_motion() method; its dnd_leave() method has not been called since the last call to dnd_enter(). The target is notified of the drop by a call to its method dnd_commit(source, event). If no final target object is selected, and there was an old target object, its dnd_leave(source, event) method is called to complete the dnd sequence. Finally, the source object is notified that the drag-and-drop process is over, by a call to source.dnd_end(target, event), specifying either the selected target object, or None if no target object was selected. The source object can use this to implement the commit action; this is sometimes simpler than to do it in the target's dnd_commit(). The target's dnd_commit() method could then simply be aliased to dnd_leave(). At any time during a dnd sequence, the application can cancel the sequence by calling the cancel() method on the object returned by dnd_start(). This will call dnd_leave() if a target is currently active; it will never call dnd_commit(). """ import tkinter __all__ = ["dnd_start", "DndHandler"] # The factory function def dnd_start(source, event): h = DndHandler(source, event) if h.root is not None: return h else: return None # The class that does the work class DndHandler: root = None def __init__(self, source, event): if event.num > 5: return root = event.widget._root() try: root.__dnd return # Don't start recursive dnd except AttributeError: root.__dnd = self self.root = root self.source = source self.target = None self.initial_button = button = event.num self.initial_widget = widget = event.widget self.release_pattern = "" % (button, button) self.save_cursor = widget['cursor'] or "" widget.bind(self.release_pattern, self.on_release) widget.bind("", self.on_motion) widget['cursor'] = "hand2" def __del__(self): root = self.root self.root = None if root is not None: try: del root.__dnd except AttributeError: pass def on_motion(self, event): x, y = event.x_root, event.y_root target_widget = self.initial_widget.winfo_containing(x, y) source = self.source new_target = None while target_widget is not None: try: attr = target_widget.dnd_accept except AttributeError: pass else: new_target = attr(source, event) if new_target is not None: break target_widget = target_widget.master old_target = self.target if old_target is new_target: if old_target is not None: old_target.dnd_motion(source, event) else: if old_target is not None: self.target = None old_target.dnd_leave(source, event) if new_target is not None: new_target.dnd_enter(source, event) self.target = new_target def on_release(self, event): self.finish(event, 1) def cancel(self, event=None): self.finish(event, 0) def finish(self, event, commit=0): target = self.target source = self.source widget = self.initial_widget root = self.root try: del root.__dnd self.initial_widget.unbind(self.release_pattern) self.initial_widget.unbind("") widget['cursor'] = self.save_cursor self.target = self.source = self.initial_widget = self.root = None if target is not None: if commit: target.dnd_commit(source, event) else: target.dnd_leave(source, event) finally: source.dnd_end(target, event) # ---------------------------------------------------------------------- # The rest is here for testing and demonstration purposes only! class Icon: def __init__(self, name): self.name = name self.canvas = self.label = self.id = None def attach(self, canvas, x=10, y=10): if canvas is self.canvas: self.canvas.coords(self.id, x, y) return if self.canvas is not None: self.detach() if canvas is None: return label = tkinter.Label(canvas, text=self.name, borderwidth=2, relief="raised") id = canvas.create_window(x, y, window=label, anchor="nw") self.canvas = canvas self.label = label self.id = id label.bind("", self.press) def detach(self): canvas = self.canvas if canvas is None: return id = self.id label = self.label self.canvas = self.label = self.id = None canvas.delete(id) label.destroy() def press(self, event): if dnd_start(self, event): # where the pointer is relative to the label widget: self.x_off = event.x self.y_off = event.y # where the widget is relative to the canvas: self.x_orig, self.y_orig = self.canvas.coords(self.id) def move(self, event): x, y = self.where(self.canvas, event) self.canvas.coords(self.id, x, y) def putback(self): self.canvas.coords(self.id, self.x_orig, self.y_orig) def where(self, canvas, event): # where the corner of the canvas is relative to the screen: x_org = canvas.winfo_rootx() y_org = canvas.winfo_rooty() # where the pointer is relative to the canvas widget: x = event.x_root - x_org y = event.y_root - y_org # compensate for initial pointer offset return x - self.x_off, y - self.y_off def dnd_end(self, target, event): pass class Tester: def __init__(self, root): self.top = tkinter.Toplevel(root) self.canvas = tkinter.Canvas(self.top, width=100, height=100) self.canvas.pack(fill="both", expand=1) self.canvas.dnd_accept = self.dnd_accept def dnd_accept(self, source, event): return self def dnd_enter(self, source, event): self.canvas.focus_set() # Show highlight border x, y = source.where(self.canvas, event) x1, y1, x2, y2 = source.canvas.bbox(source.id) dx, dy = x2-x1, y2-y1 self.dndid = self.canvas.create_rectangle(x, y, x+dx, y+dy) self.dnd_motion(source, event) def dnd_motion(self, source, event): x, y = source.where(self.canvas, event) x1, y1, x2, y2 = self.canvas.bbox(self.dndid) self.canvas.move(self.dndid, x-x1, y-y1) def dnd_leave(self, source, event): self.top.focus_set() # Hide highlight border self.canvas.delete(self.dndid) self.dndid = None def dnd_commit(self, source, event): self.dnd_leave(source, event) x, y = source.where(self.canvas, event) source.attach(self.canvas, x, y) def test(): root = tkinter.Tk() root.geometry("+1+1") tkinter.Button(command=root.quit, text="Quit").pack() t1 = Tester(root) t1.top.geometry("+1+60") t2 = Tester(root) t2.top.geometry("+120+60") t3 = Tester(root) t3.top.geometry("+240+60") i1 = Icon("ICON1") i2 = Icon("ICON2") i3 = Icon("ICON3") i1.attach(t1.canvas) i2.attach(t2.canvas) i3.attach(t3.canvas) root.mainloop() if __name__ == '__main__': test() tkinter/ttk.py000064400000155776152342670510007432 0ustar00"""Ttk wrapper. This module provides classes to allow using Tk themed widget set. Ttk is based on a revised and enhanced version of TIP #48 (http://tip.tcl.tk/48) specified style engine. Its basic idea is to separate, to the extent possible, the code implementing a widget's behavior from the code implementing its appearance. Widget class bindings are primarily responsible for maintaining the widget state and invoking callbacks, all aspects of the widgets appearance lies at Themes. """ __version__ = "0.3.1" __author__ = "Guilherme Polo " __all__ = ["Button", "Checkbutton", "Combobox", "Entry", "Frame", "Label", "Labelframe", "LabelFrame", "Menubutton", "Notebook", "Panedwindow", "PanedWindow", "Progressbar", "Radiobutton", "Scale", "Scrollbar", "Separator", "Sizegrip", "Spinbox", "Style", "Treeview", # Extensions "LabeledScale", "OptionMenu", # functions "tclobjs_to_py", "setup_master"] import tkinter from tkinter import _flatten, _join, _stringify, _splitdict def _format_optvalue(value, script=False): """Internal function.""" if script: # if caller passes a Tcl script to tk.call, all the values need to # be grouped into words (arguments to a command in Tcl dialect) value = _stringify(value) elif isinstance(value, (list, tuple)): value = _join(value) return value def _format_optdict(optdict, script=False, ignore=None): """Formats optdict to a tuple to pass it to tk.call. E.g. (script=False): {'foreground': 'blue', 'padding': [1, 2, 3, 4]} returns: ('-foreground', 'blue', '-padding', '1 2 3 4')""" opts = [] for opt, value in optdict.items(): if not ignore or opt not in ignore: opts.append("-%s" % opt) if value is not None: opts.append(_format_optvalue(value, script)) return _flatten(opts) def _mapdict_values(items): # each value in mapdict is expected to be a sequence, where each item # is another sequence containing a state (or several) and a value # E.g. (script=False): # [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])] # returns: # ['active selected', 'grey', 'focus', [1, 2, 3, 4]] opt_val = [] for *state, val in items: if len(state) == 1: # if it is empty (something that evaluates to False), then # format it to Tcl code to denote the "normal" state state = state[0] or '' else: # group multiple states state = ' '.join(state) # raise TypeError if not str opt_val.append(state) if val is not None: opt_val.append(val) return opt_val def _format_mapdict(mapdict, script=False): """Formats mapdict to pass it to tk.call. E.g. (script=False): {'expand': [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])]} returns: ('-expand', '{active selected} grey focus {1, 2, 3, 4}')""" opts = [] for opt, value in mapdict.items(): opts.extend(("-%s" % opt, _format_optvalue(_mapdict_values(value), script))) return _flatten(opts) def _format_elemcreate(etype, script=False, *args, **kw): """Formats args and kw according to the given element factory etype.""" spec = None opts = () if etype in ("image", "vsapi"): if etype == "image": # define an element based on an image # first arg should be the default image name iname = args[0] # next args, if any, are statespec/value pairs which is almost # a mapdict, but we just need the value imagespec = _join(_mapdict_values(args[1:])) spec = "%s %s" % (iname, imagespec) else: # define an element whose visual appearance is drawn using the # Microsoft Visual Styles API which is responsible for the # themed styles on Windows XP and Vista. # Availability: Tk 8.6, Windows XP and Vista. class_name, part_id = args[:2] statemap = _join(_mapdict_values(args[2:])) spec = "%s %s %s" % (class_name, part_id, statemap) opts = _format_optdict(kw, script) elif etype == "from": # clone an element # it expects a themename and optionally an element to clone from, # otherwise it will clone {} (empty element) spec = args[0] # theme name if len(args) > 1: # elementfrom specified opts = (_format_optvalue(args[1], script),) if script: spec = '{%s}' % spec opts = ' '.join(opts) return spec, opts def _format_layoutlist(layout, indent=0, indent_size=2): """Formats a layout list so we can pass the result to ttk::style layout and ttk::style settings. Note that the layout doesn't have to be a list necessarily. E.g.: [("Menubutton.background", None), ("Menubutton.button", {"children": [("Menubutton.focus", {"children": [("Menubutton.padding", {"children": [("Menubutton.label", {"side": "left", "expand": 1})] })] })] }), ("Menubutton.indicator", {"side": "right"}) ] returns: Menubutton.background Menubutton.button -children { Menubutton.focus -children { Menubutton.padding -children { Menubutton.label -side left -expand 1 } } } Menubutton.indicator -side right""" script = [] for layout_elem in layout: elem, opts = layout_elem opts = opts or {} fopts = ' '.join(_format_optdict(opts, True, ("children",))) head = "%s%s%s" % (' ' * indent, elem, (" %s" % fopts) if fopts else '') if "children" in opts: script.append(head + " -children {") indent += indent_size newscript, indent = _format_layoutlist(opts['children'], indent, indent_size) script.append(newscript) indent -= indent_size script.append('%s}' % (' ' * indent)) else: script.append(head) return '\n'.join(script), indent def _script_from_settings(settings): """Returns an appropriate script, based on settings, according to theme_settings definition to be used by theme_settings and theme_create.""" script = [] # a script will be generated according to settings passed, which # will then be evaluated by Tcl for name, opts in settings.items(): # will format specific keys according to Tcl code if opts.get('configure'): # format 'configure' s = ' '.join(_format_optdict(opts['configure'], True)) script.append("ttk::style configure %s %s;" % (name, s)) if opts.get('map'): # format 'map' s = ' '.join(_format_mapdict(opts['map'], True)) script.append("ttk::style map %s %s;" % (name, s)) if 'layout' in opts: # format 'layout' which may be empty if not opts['layout']: s = 'null' # could be any other word, but this one makes sense else: s, _ = _format_layoutlist(opts['layout']) script.append("ttk::style layout %s {\n%s\n}" % (name, s)) if opts.get('element create'): # format 'element create' eopts = opts['element create'] etype = eopts[0] # find where args end, and where kwargs start argc = 1 # etype was the first one while argc < len(eopts) and not hasattr(eopts[argc], 'items'): argc += 1 elemargs = eopts[1:argc] elemkw = eopts[argc] if argc < len(eopts) and eopts[argc] else {} spec, opts = _format_elemcreate(etype, True, *elemargs, **elemkw) script.append("ttk::style element create %s %s %s %s" % ( name, etype, spec, opts)) return '\n'.join(script) def _list_from_statespec(stuple): """Construct a list from the given statespec tuple according to the accepted statespec accepted by _format_mapdict.""" if isinstance(stuple, str): return stuple result = [] it = iter(stuple) for state, val in zip(it, it): if hasattr(state, 'typename'): # this is a Tcl object state = str(state).split() elif isinstance(state, str): state = state.split() elif not isinstance(state, (tuple, list)): state = (state,) if hasattr(val, 'typename'): val = str(val) result.append((*state, val)) return result def _list_from_layouttuple(tk, ltuple): """Construct a list from the tuple returned by ttk::layout, this is somewhat the reverse of _format_layoutlist.""" ltuple = tk.splitlist(ltuple) res = [] indx = 0 while indx < len(ltuple): name = ltuple[indx] opts = {} res.append((name, opts)) indx += 1 while indx < len(ltuple): # grab name's options opt, val = ltuple[indx:indx + 2] if not opt.startswith('-'): # found next name break opt = opt[1:] # remove the '-' from the option indx += 2 if opt == 'children': val = _list_from_layouttuple(tk, val) opts[opt] = val return res def _val_or_dict(tk, options, *args): """Format options then call Tk command with args and options and return the appropriate result. If no option is specified, a dict is returned. If an option is specified with the None value, the value for that option is returned. Otherwise, the function just sets the passed options and the caller shouldn't be expecting a return value anyway.""" options = _format_optdict(options) res = tk.call(*(args + options)) if len(options) % 2: # option specified without a value, return its value return res return _splitdict(tk, res, conv=_tclobj_to_py) def _convert_stringval(value): """Converts a value to, hopefully, a more appropriate Python object.""" value = str(value) try: value = int(value) except (ValueError, TypeError): pass return value def _to_number(x): if isinstance(x, str): if '.' in x: x = float(x) else: x = int(x) return x def _tclobj_to_py(val): """Return value converted from Tcl object to Python object.""" if val and hasattr(val, '__len__') and not isinstance(val, str): if getattr(val[0], 'typename', None) == 'StateSpec': val = _list_from_statespec(val) else: val = list(map(_convert_stringval, val)) elif hasattr(val, 'typename'): # some other (single) Tcl object val = _convert_stringval(val) return val def tclobjs_to_py(adict): """Returns adict with its values converted from Tcl objects to Python objects.""" for opt, val in adict.items(): adict[opt] = _tclobj_to_py(val) return adict def setup_master(master=None): """If master is not None, itself is returned. If master is None, the default master is returned if there is one, otherwise a new master is created and returned. If it is not allowed to use the default root and master is None, RuntimeError is raised.""" if master is None: master = tkinter._get_default_root() return master class Style(object): """Manipulate style database.""" _name = "ttk::style" def __init__(self, master=None): master = setup_master(master) self.master = master self.tk = self.master.tk def configure(self, style, query_opt=None, **kw): """Query or sets the default value of the specified option(s) in style. Each key in kw is an option and each value is either a string or a sequence identifying the value for that option.""" if query_opt is not None: kw[query_opt] = None result = _val_or_dict(self.tk, kw, self._name, "configure", style) if result or query_opt: return result def map(self, style, query_opt=None, **kw): """Query or sets dynamic values of the specified option(s) in style. Each key in kw is an option and each value should be a list or a tuple (usually) containing statespecs grouped in tuples, or list, or something else of your preference. A statespec is compound of one or more states and then a value.""" if query_opt is not None: result = self.tk.call(self._name, "map", style, '-%s' % query_opt) return _list_from_statespec(self.tk.splitlist(result)) result = self.tk.call(self._name, "map", style, *_format_mapdict(kw)) return {k: _list_from_statespec(self.tk.splitlist(v)) for k, v in _splitdict(self.tk, result).items()} def lookup(self, style, option, state=None, default=None): """Returns the value specified for option in style. If state is specified it is expected to be a sequence of one or more states. If the default argument is set, it is used as a fallback value in case no specification for option is found.""" state = ' '.join(state) if state else '' return self.tk.call(self._name, "lookup", style, '-%s' % option, state, default) def layout(self, style, layoutspec=None): """Define the widget layout for given style. If layoutspec is omitted, return the layout specification for given style. layoutspec is expected to be a list or an object different than None that evaluates to False if you want to "turn off" that style. If it is a list (or tuple, or something else), each item should be a tuple where the first item is the layout name and the second item should have the format described below: LAYOUTS A layout can contain the value None, if takes no options, or a dict of options specifying how to arrange the element. The layout mechanism uses a simplified version of the pack geometry manager: given an initial cavity, each element is allocated a parcel. Valid options/values are: side: whichside Specifies which side of the cavity to place the element; one of top, right, bottom or left. If omitted, the element occupies the entire cavity. sticky: nswe Specifies where the element is placed inside its allocated parcel. children: [sublayout... ] Specifies a list of elements to place inside the element. Each element is a tuple (or other sequence) where the first item is the layout name, and the other is a LAYOUT.""" lspec = None if layoutspec: lspec = _format_layoutlist(layoutspec)[0] elif layoutspec is not None: # will disable the layout ({}, '', etc) lspec = "null" # could be any other word, but this may make sense # when calling layout(style) later return _list_from_layouttuple(self.tk, self.tk.call(self._name, "layout", style, lspec)) def element_create(self, elementname, etype, *args, **kw): """Create a new element in the current theme of given etype.""" spec, opts = _format_elemcreate(etype, False, *args, **kw) self.tk.call(self._name, "element", "create", elementname, etype, spec, *opts) def element_names(self): """Returns the list of elements defined in the current theme.""" return tuple(n.lstrip('-') for n in self.tk.splitlist( self.tk.call(self._name, "element", "names"))) def element_options(self, elementname): """Return the list of elementname's options.""" return tuple(o.lstrip('-') for o in self.tk.splitlist( self.tk.call(self._name, "element", "options", elementname))) def theme_create(self, themename, parent=None, settings=None): """Creates a new theme. It is an error if themename already exists. If parent is specified, the new theme will inherit styles, elements and layouts from the specified parent theme. If settings are present, they are expected to have the same syntax used for theme_settings.""" script = _script_from_settings(settings) if settings else '' if parent: self.tk.call(self._name, "theme", "create", themename, "-parent", parent, "-settings", script) else: self.tk.call(self._name, "theme", "create", themename, "-settings", script) def theme_settings(self, themename, settings): """Temporarily sets the current theme to themename, apply specified settings and then restore the previous theme. Each key in settings is a style and each value may contain the keys 'configure', 'map', 'layout' and 'element create' and they are expected to have the same format as specified by the methods configure, map, layout and element_create respectively.""" script = _script_from_settings(settings) self.tk.call(self._name, "theme", "settings", themename, script) def theme_names(self): """Returns a list of all known themes.""" return self.tk.splitlist(self.tk.call(self._name, "theme", "names")) def theme_use(self, themename=None): """If themename is None, returns the theme in use, otherwise, set the current theme to themename, refreshes all widgets and emits a <> event.""" if themename is None: # Starting on Tk 8.6, checking this global is no longer needed # since it allows doing self.tk.call(self._name, "theme", "use") return self.tk.eval("return $ttk::currentTheme") # using "ttk::setTheme" instead of "ttk::style theme use" causes # the variable currentTheme to be updated, also, ttk::setTheme calls # "ttk::style theme use" in order to change theme. self.tk.call("ttk::setTheme", themename) class Widget(tkinter.Widget): """Base class for Tk themed widgets.""" def __init__(self, master, widgetname, kw=None): """Constructs a Ttk Widget with the parent master. STANDARD OPTIONS class, cursor, takefocus, style SCROLLABLE WIDGET OPTIONS xscrollcommand, yscrollcommand LABEL WIDGET OPTIONS text, textvariable, underline, image, compound, width WIDGET STATES active, disabled, focus, pressed, selected, background, readonly, alternate, invalid """ master = setup_master(master) tkinter.Widget.__init__(self, master, widgetname, kw=kw) def identify(self, x, y): """Returns the name of the element at position x, y, or the empty string if the point does not lie within any element. x and y are pixel coordinates relative to the widget.""" return self.tk.call(self._w, "identify", x, y) def instate(self, statespec, callback=None, *args, **kw): """Test the widget's state. If callback is not specified, returns True if the widget state matches statespec and False otherwise. If callback is specified, then it will be invoked with *args, **kw if the widget state matches statespec. statespec is expected to be a sequence.""" ret = self.tk.getboolean( self.tk.call(self._w, "instate", ' '.join(statespec))) if ret and callback is not None: return callback(*args, **kw) return ret def state(self, statespec=None): """Modify or inquire widget state. Widget state is returned if statespec is None, otherwise it is set according to the statespec flags and then a new state spec is returned indicating which flags were changed. statespec is expected to be a sequence.""" if statespec is not None: statespec = ' '.join(statespec) return self.tk.splitlist(str(self.tk.call(self._w, "state", statespec))) class Button(Widget): """Ttk Button widget, displays a textual label and/or image, and evaluates a command when pressed.""" def __init__(self, master=None, **kw): """Construct a Ttk Button widget with the parent master. STANDARD OPTIONS class, compound, cursor, image, state, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS command, default, width """ Widget.__init__(self, master, "ttk::button", kw) def invoke(self): """Invokes the command associated with the button.""" return self.tk.call(self._w, "invoke") class Checkbutton(Widget): """Ttk Checkbutton widget which is either in on- or off-state.""" def __init__(self, master=None, **kw): """Construct a Ttk Checkbutton widget with the parent master. STANDARD OPTIONS class, compound, cursor, image, state, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS command, offvalue, onvalue, variable """ Widget.__init__(self, master, "ttk::checkbutton", kw) def invoke(self): """Toggles between the selected and deselected states and invokes the associated command. If the widget is currently selected, sets the option variable to the offvalue option and deselects the widget; otherwise, sets the option variable to the option onvalue. Returns the result of the associated command.""" return self.tk.call(self._w, "invoke") class Entry(Widget, tkinter.Entry): """Ttk Entry widget displays a one-line text string and allows that string to be edited by the user.""" def __init__(self, master=None, widget=None, **kw): """Constructs a Ttk Entry widget with the parent master. STANDARD OPTIONS class, cursor, style, takefocus, xscrollcommand WIDGET-SPECIFIC OPTIONS exportselection, invalidcommand, justify, show, state, textvariable, validate, validatecommand, width VALIDATION MODES none, key, focus, focusin, focusout, all """ Widget.__init__(self, master, widget or "ttk::entry", kw) def bbox(self, index): """Return a tuple of (x, y, width, height) which describes the bounding box of the character given by index.""" return self._getints(self.tk.call(self._w, "bbox", index)) def identify(self, x, y): """Returns the name of the element at position x, y, or the empty string if the coordinates are outside the window.""" return self.tk.call(self._w, "identify", x, y) def validate(self): """Force revalidation, independent of the conditions specified by the validate option. Returns False if validation fails, True if it succeeds. Sets or clears the invalid state accordingly.""" return self.tk.getboolean(self.tk.call(self._w, "validate")) class Combobox(Entry): """Ttk Combobox widget combines a text field with a pop-down list of values.""" def __init__(self, master=None, **kw): """Construct a Ttk Combobox widget with the parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS exportselection, justify, height, postcommand, state, textvariable, values, width """ Entry.__init__(self, master, "ttk::combobox", **kw) def current(self, newindex=None): """If newindex is supplied, sets the combobox value to the element at position newindex in the list of values. Otherwise, returns the index of the current value in the list of values or -1 if the current value does not appear in the list.""" if newindex is None: res = self.tk.call(self._w, "current") if res == '': return -1 return self.tk.getint(res) return self.tk.call(self._w, "current", newindex) def set(self, value): """Sets the value of the combobox to value.""" self.tk.call(self._w, "set", value) class Frame(Widget): """Ttk Frame widget is a container, used to group other widgets together.""" def __init__(self, master=None, **kw): """Construct a Ttk Frame with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS borderwidth, relief, padding, width, height """ Widget.__init__(self, master, "ttk::frame", kw) class Label(Widget): """Ttk Label widget displays a textual label and/or image.""" def __init__(self, master=None, **kw): """Construct a Ttk Label with parent master. STANDARD OPTIONS class, compound, cursor, image, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS anchor, background, font, foreground, justify, padding, relief, text, wraplength """ Widget.__init__(self, master, "ttk::label", kw) class Labelframe(Widget): """Ttk Labelframe widget is a container used to group other widgets together. It has an optional label, which may be a plain text string or another widget.""" def __init__(self, master=None, **kw): """Construct a Ttk Labelframe with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS labelanchor, text, underline, padding, labelwidget, width, height """ Widget.__init__(self, master, "ttk::labelframe", kw) LabelFrame = Labelframe # tkinter name compatibility class Menubutton(Widget): """Ttk Menubutton widget displays a textual label and/or image, and displays a menu when pressed.""" def __init__(self, master=None, **kw): """Construct a Ttk Menubutton with parent master. STANDARD OPTIONS class, compound, cursor, image, state, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS direction, menu """ Widget.__init__(self, master, "ttk::menubutton", kw) class Notebook(Widget): """Ttk Notebook widget manages a collection of windows and displays a single one at a time. Each child window is associated with a tab, which the user may select to change the currently-displayed window.""" def __init__(self, master=None, **kw): """Construct a Ttk Notebook with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS height, padding, width TAB OPTIONS state, sticky, padding, text, image, compound, underline TAB IDENTIFIERS (tab_id) The tab_id argument found in several methods may take any of the following forms: * An integer between zero and the number of tabs * The name of a child window * A positional specification of the form "@x,y", which defines the tab * The string "current", which identifies the currently-selected tab * The string "end", which returns the number of tabs (only valid for method index) """ Widget.__init__(self, master, "ttk::notebook", kw) def add(self, child, **kw): """Adds a new tab to the notebook. If window is currently managed by the notebook but hidden, it is restored to its previous position.""" self.tk.call(self._w, "add", child, *(_format_optdict(kw))) def forget(self, tab_id): """Removes the tab specified by tab_id, unmaps and unmanages the associated window.""" self.tk.call(self._w, "forget", tab_id) def hide(self, tab_id): """Hides the tab specified by tab_id. The tab will not be displayed, but the associated window remains managed by the notebook and its configuration remembered. Hidden tabs may be restored with the add command.""" self.tk.call(self._w, "hide", tab_id) def identify(self, x, y): """Returns the name of the tab element at position x, y, or the empty string if none.""" return self.tk.call(self._w, "identify", x, y) def index(self, tab_id): """Returns the numeric index of the tab specified by tab_id, or the total number of tabs if tab_id is the string "end".""" return self.tk.getint(self.tk.call(self._w, "index", tab_id)) def insert(self, pos, child, **kw): """Inserts a pane at the specified position. pos is either the string end, an integer index, or the name of a managed child. If child is already managed by the notebook, moves it to the specified position.""" self.tk.call(self._w, "insert", pos, child, *(_format_optdict(kw))) def select(self, tab_id=None): """Selects the specified tab. The associated child window will be displayed, and the previously-selected window (if different) is unmapped. If tab_id is omitted, returns the widget name of the currently selected pane.""" return self.tk.call(self._w, "select", tab_id) def tab(self, tab_id, option=None, **kw): """Query or modify the options of the specific tab_id. If kw is not given, returns a dict of the tab option values. If option is specified, returns the value of that option. Otherwise, sets the options to the corresponding values.""" if option is not None: kw[option] = None return _val_or_dict(self.tk, kw, self._w, "tab", tab_id) def tabs(self): """Returns a list of windows managed by the notebook.""" return self.tk.splitlist(self.tk.call(self._w, "tabs") or ()) def enable_traversal(self): """Enable keyboard traversal for a toplevel window containing this notebook. This will extend the bindings for the toplevel window containing this notebook as follows: Control-Tab: selects the tab following the currently selected one Shift-Control-Tab: selects the tab preceding the currently selected one Alt-K: where K is the mnemonic (underlined) character of any tab, will select that tab. Multiple notebooks in a single toplevel may be enabled for traversal, including nested notebooks. However, notebook traversal only works properly if all panes are direct children of the notebook.""" # The only, and good, difference I see is about mnemonics, which works # after calling this method. Control-Tab and Shift-Control-Tab always # works (here at least). self.tk.call("ttk::notebook::enableTraversal", self._w) class Panedwindow(Widget, tkinter.PanedWindow): """Ttk Panedwindow widget displays a number of subwindows, stacked either vertically or horizontally.""" def __init__(self, master=None, **kw): """Construct a Ttk Panedwindow with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS orient, width, height PANE OPTIONS weight """ Widget.__init__(self, master, "ttk::panedwindow", kw) forget = tkinter.PanedWindow.forget # overrides Pack.forget def insert(self, pos, child, **kw): """Inserts a pane at the specified positions. pos is either the string end, and integer index, or the name of a child. If child is already managed by the paned window, moves it to the specified position.""" self.tk.call(self._w, "insert", pos, child, *(_format_optdict(kw))) def pane(self, pane, option=None, **kw): """Query or modify the options of the specified pane. pane is either an integer index or the name of a managed subwindow. If kw is not given, returns a dict of the pane option values. If option is specified then the value for that option is returned. Otherwise, sets the options to the corresponding values.""" if option is not None: kw[option] = None return _val_or_dict(self.tk, kw, self._w, "pane", pane) def sashpos(self, index, newpos=None): """If newpos is specified, sets the position of sash number index. May adjust the positions of adjacent sashes to ensure that positions are monotonically increasing. Sash positions are further constrained to be between 0 and the total size of the widget. Returns the new position of sash number index.""" return self.tk.getint(self.tk.call(self._w, "sashpos", index, newpos)) PanedWindow = Panedwindow # tkinter name compatibility class Progressbar(Widget): """Ttk Progressbar widget shows the status of a long-running operation. They can operate in two modes: determinate mode shows the amount completed relative to the total amount of work to be done, and indeterminate mode provides an animated display to let the user know that something is happening.""" def __init__(self, master=None, **kw): """Construct a Ttk Progressbar with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS orient, length, mode, maximum, value, variable, phase """ Widget.__init__(self, master, "ttk::progressbar", kw) def start(self, interval=None): """Begin autoincrement mode: schedules a recurring timer event that calls method step every interval milliseconds. interval defaults to 50 milliseconds (20 steps/second) if omitted.""" self.tk.call(self._w, "start", interval) def step(self, amount=None): """Increments the value option by amount. amount defaults to 1.0 if omitted.""" self.tk.call(self._w, "step", amount) def stop(self): """Stop autoincrement mode: cancels any recurring timer event initiated by start.""" self.tk.call(self._w, "stop") class Radiobutton(Widget): """Ttk Radiobutton widgets are used in groups to show or change a set of mutually-exclusive options.""" def __init__(self, master=None, **kw): """Construct a Ttk Radiobutton with parent master. STANDARD OPTIONS class, compound, cursor, image, state, style, takefocus, text, textvariable, underline, width WIDGET-SPECIFIC OPTIONS command, value, variable """ Widget.__init__(self, master, "ttk::radiobutton", kw) def invoke(self): """Sets the option variable to the option value, selects the widget, and invokes the associated command. Returns the result of the command, or an empty string if no command is specified.""" return self.tk.call(self._w, "invoke") class Scale(Widget, tkinter.Scale): """Ttk Scale widget is typically used to control the numeric value of a linked variable that varies uniformly over some range.""" def __init__(self, master=None, **kw): """Construct a Ttk Scale with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS command, from, length, orient, to, value, variable """ Widget.__init__(self, master, "ttk::scale", kw) def configure(self, cnf=None, **kw): """Modify or query scale options. Setting a value for any of the "from", "from_" or "to" options generates a <> event.""" retval = Widget.configure(self, cnf, **kw) if not isinstance(cnf, (type(None), str)): kw.update(cnf) if any(['from' in kw, 'from_' in kw, 'to' in kw]): self.event_generate('<>') return retval def get(self, x=None, y=None): """Get the current value of the value option, or the value corresponding to the coordinates x, y if they are specified. x and y are pixel coordinates relative to the scale widget origin.""" return self.tk.call(self._w, 'get', x, y) class Scrollbar(Widget, tkinter.Scrollbar): """Ttk Scrollbar controls the viewport of a scrollable widget.""" def __init__(self, master=None, **kw): """Construct a Ttk Scrollbar with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS command, orient """ Widget.__init__(self, master, "ttk::scrollbar", kw) class Separator(Widget): """Ttk Separator widget displays a horizontal or vertical separator bar.""" def __init__(self, master=None, **kw): """Construct a Ttk Separator with parent master. STANDARD OPTIONS class, cursor, style, takefocus WIDGET-SPECIFIC OPTIONS orient """ Widget.__init__(self, master, "ttk::separator", kw) class Sizegrip(Widget): """Ttk Sizegrip allows the user to resize the containing toplevel window by pressing and dragging the grip.""" def __init__(self, master=None, **kw): """Construct a Ttk Sizegrip with parent master. STANDARD OPTIONS class, cursor, state, style, takefocus """ Widget.__init__(self, master, "ttk::sizegrip", kw) class Spinbox(Entry): """Ttk Spinbox is an Entry with increment and decrement arrows It is commonly used for number entry or to select from a list of string values. """ def __init__(self, master=None, **kw): """Construct a Ttk Spinbox widget with the parent master. STANDARD OPTIONS class, cursor, style, takefocus, validate, validatecommand, xscrollcommand, invalidcommand WIDGET-SPECIFIC OPTIONS to, from_, increment, values, wrap, format, command """ Entry.__init__(self, master, "ttk::spinbox", **kw) def set(self, value): """Sets the value of the Spinbox to value.""" self.tk.call(self._w, "set", value) class Treeview(Widget, tkinter.XView, tkinter.YView): """Ttk Treeview widget displays a hierarchical collection of items. Each item has a textual label, an optional image, and an optional list of data values. The data values are displayed in successive columns after the tree label.""" def __init__(self, master=None, **kw): """Construct a Ttk Treeview with parent master. STANDARD OPTIONS class, cursor, style, takefocus, xscrollcommand, yscrollcommand WIDGET-SPECIFIC OPTIONS columns, displaycolumns, height, padding, selectmode, show ITEM OPTIONS text, image, values, open, tags TAG OPTIONS foreground, background, font, image """ Widget.__init__(self, master, "ttk::treeview", kw) def bbox(self, item, column=None): """Returns the bounding box (relative to the treeview widget's window) of the specified item in the form x y width height. If column is specified, returns the bounding box of that cell. If the item is not visible (i.e., if it is a descendant of a closed item or is scrolled offscreen), returns an empty string.""" return self._getints(self.tk.call(self._w, "bbox", item, column)) or '' def get_children(self, item=None): """Returns a tuple of children belonging to item. If item is not specified, returns root children.""" return self.tk.splitlist( self.tk.call(self._w, "children", item or '') or ()) def set_children(self, item, *newchildren): """Replaces item's child with newchildren. Children present in item that are not present in newchildren are detached from tree. No items in newchildren may be an ancestor of item.""" self.tk.call(self._w, "children", item, newchildren) def column(self, column, option=None, **kw): """Query or modify the options for the specified column. If kw is not given, returns a dict of the column option values. If option is specified then the value for that option is returned. Otherwise, sets the options to the corresponding values.""" if option is not None: kw[option] = None return _val_or_dict(self.tk, kw, self._w, "column", column) def delete(self, *items): """Delete all specified items and all their descendants. The root item may not be deleted.""" self.tk.call(self._w, "delete", items) def detach(self, *items): """Unlinks all of the specified items from the tree. The items and all of their descendants are still present, and may be reinserted at another point in the tree, but will not be displayed. The root item may not be detached.""" self.tk.call(self._w, "detach", items) def exists(self, item): """Returns True if the specified item is present in the tree, False otherwise.""" return self.tk.getboolean(self.tk.call(self._w, "exists", item)) def focus(self, item=None): """If item is specified, sets the focus item to item. Otherwise, returns the current focus item, or '' if there is none.""" return self.tk.call(self._w, "focus", item) def heading(self, column, option=None, **kw): """Query or modify the heading options for the specified column. If kw is not given, returns a dict of the heading option values. If option is specified then the value for that option is returned. Otherwise, sets the options to the corresponding values. Valid options/values are: text: text The text to display in the column heading image: image_name Specifies an image to display to the right of the column heading anchor: anchor Specifies how the heading text should be aligned. One of the standard Tk anchor values command: callback A callback to be invoked when the heading label is pressed. To configure the tree column heading, call this with column = "#0" """ cmd = kw.get('command') if cmd and not isinstance(cmd, str): # callback not registered yet, do it now kw['command'] = self.master.register(cmd, self._substitute) if option is not None: kw[option] = None return _val_or_dict(self.tk, kw, self._w, 'heading', column) def identify(self, component, x, y): """Returns a description of the specified component under the point given by x and y, or the empty string if no such component is present at that position.""" return self.tk.call(self._w, "identify", component, x, y) def identify_row(self, y): """Returns the item ID of the item at position y.""" return self.identify("row", 0, y) def identify_column(self, x): """Returns the data column identifier of the cell at position x. The tree column has ID #0.""" return self.identify("column", x, 0) def identify_region(self, x, y): """Returns one of: heading: Tree heading area. separator: Space between two columns headings; tree: The tree area. cell: A data cell. * Availability: Tk 8.6""" return self.identify("region", x, y) def identify_element(self, x, y): """Returns the element at position x, y. * Availability: Tk 8.6""" return self.identify("element", x, y) def index(self, item): """Returns the integer index of item within its parent's list of children.""" return self.tk.getint(self.tk.call(self._w, "index", item)) def insert(self, parent, index, iid=None, **kw): """Creates a new item and return the item identifier of the newly created item. parent is the item ID of the parent item, or the empty string to create a new top-level item. index is an integer, or the value end, specifying where in the list of parent's children to insert the new item. If index is less than or equal to zero, the new node is inserted at the beginning, if index is greater than or equal to the current number of children, it is inserted at the end. If iid is specified, it is used as the item identifier, iid must not already exist in the tree. Otherwise, a new unique identifier is generated.""" opts = _format_optdict(kw) if iid is not None: res = self.tk.call(self._w, "insert", parent, index, "-id", iid, *opts) else: res = self.tk.call(self._w, "insert", parent, index, *opts) return res def item(self, item, option=None, **kw): """Query or modify the options for the specified item. If no options are given, a dict with options/values for the item is returned. If option is specified then the value for that option is returned. Otherwise, sets the options to the corresponding values as given by kw.""" if option is not None: kw[option] = None return _val_or_dict(self.tk, kw, self._w, "item", item) def move(self, item, parent, index): """Moves item to position index in parent's list of children. It is illegal to move an item under one of its descendants. If index is less than or equal to zero, item is moved to the beginning, if greater than or equal to the number of children, it is moved to the end. If item was detached it is reattached.""" self.tk.call(self._w, "move", item, parent, index) reattach = move # A sensible method name for reattaching detached items def next(self, item): """Returns the identifier of item's next sibling, or '' if item is the last child of its parent.""" return self.tk.call(self._w, "next", item) def parent(self, item): """Returns the ID of the parent of item, or '' if item is at the top level of the hierarchy.""" return self.tk.call(self._w, "parent", item) def prev(self, item): """Returns the identifier of item's previous sibling, or '' if item is the first child of its parent.""" return self.tk.call(self._w, "prev", item) def see(self, item): """Ensure that item is visible. Sets all of item's ancestors open option to True, and scrolls the widget if necessary so that item is within the visible portion of the tree.""" self.tk.call(self._w, "see", item) def selection(self): """Returns the tuple of selected items.""" return self.tk.splitlist(self.tk.call(self._w, "selection")) def _selection(self, selop, items): if len(items) == 1 and isinstance(items[0], (tuple, list)): items = items[0] self.tk.call(self._w, "selection", selop, items) def selection_set(self, *items): """The specified items becomes the new selection.""" self._selection("set", items) def selection_add(self, *items): """Add all of the specified items to the selection.""" self._selection("add", items) def selection_remove(self, *items): """Remove all of the specified items from the selection.""" self._selection("remove", items) def selection_toggle(self, *items): """Toggle the selection state of each specified item.""" self._selection("toggle", items) def set(self, item, column=None, value=None): """Query or set the value of given item. With one argument, return a dictionary of column/value pairs for the specified item. With two arguments, return the current value of the specified column. With three arguments, set the value of given column in given item to the specified value.""" res = self.tk.call(self._w, "set", item, column, value) if column is None and value is None: return _splitdict(self.tk, res, cut_minus=False, conv=_tclobj_to_py) else: return res def tag_bind(self, tagname, sequence=None, callback=None): """Bind a callback for the given event sequence to the tag tagname. When an event is delivered to an item, the callbacks for each of the item's tags option are called.""" self._bind((self._w, "tag", "bind", tagname), sequence, callback, add=0) def tag_configure(self, tagname, option=None, **kw): """Query or modify the options for the specified tagname. If kw is not given, returns a dict of the option settings for tagname. If option is specified, returns the value for that option for the specified tagname. Otherwise, sets the options to the corresponding values for the given tagname.""" if option is not None: kw[option] = None return _val_or_dict(self.tk, kw, self._w, "tag", "configure", tagname) def tag_has(self, tagname, item=None): """If item is specified, returns 1 or 0 depending on whether the specified item has the given tagname. Otherwise, returns a list of all items which have the specified tag. * Availability: Tk 8.6""" if item is None: return self.tk.splitlist( self.tk.call(self._w, "tag", "has", tagname)) else: return self.tk.getboolean( self.tk.call(self._w, "tag", "has", tagname, item)) # Extensions class LabeledScale(Frame): """A Ttk Scale widget with a Ttk Label widget indicating its current value. The Ttk Scale can be accessed through instance.scale, and Ttk Label can be accessed through instance.label""" def __init__(self, master=None, variable=None, from_=0, to=10, **kw): """Construct a horizontal LabeledScale with parent master, a variable to be associated with the Ttk Scale widget and its range. If variable is not specified, a tkinter.IntVar is created. WIDGET-SPECIFIC OPTIONS compound: 'top' or 'bottom' Specifies how to display the label relative to the scale. Defaults to 'top'. """ self._label_top = kw.pop('compound', 'top') == 'top' Frame.__init__(self, master, **kw) self._variable = variable or tkinter.IntVar(master) self._variable.set(from_) self._last_valid = from_ self.label = Label(self) self.scale = Scale(self, variable=self._variable, from_=from_, to=to) self.scale.bind('<>', self._adjust) # position scale and label according to the compound option scale_side = 'bottom' if self._label_top else 'top' label_side = 'top' if scale_side == 'bottom' else 'bottom' self.scale.pack(side=scale_side, fill='x') # Dummy required to make frame correct height dummy = Label(self) dummy.pack(side=label_side) dummy.lower() self.label.place(anchor='n' if label_side == 'top' else 's') # update the label as scale or variable changes self.__tracecb = self._variable.trace_add('write', self._adjust) self.bind('', self._adjust) self.bind('', self._adjust) def destroy(self): """Destroy this widget and possibly its associated variable.""" try: self._variable.trace_remove('write', self.__tracecb) except AttributeError: pass else: del self._variable super().destroy() self.label = None self.scale = None def _adjust(self, *args): """Adjust the label position according to the scale.""" def adjust_label(): self.update_idletasks() # "force" scale redraw x, y = self.scale.coords() if self._label_top: y = self.scale.winfo_y() - self.label.winfo_reqheight() else: y = self.scale.winfo_reqheight() + self.label.winfo_reqheight() self.label.place_configure(x=x, y=y) from_ = _to_number(self.scale['from']) to = _to_number(self.scale['to']) if to < from_: from_, to = to, from_ newval = self._variable.get() if not from_ <= newval <= to: # value outside range, set value back to the last valid one self.value = self._last_valid return self._last_valid = newval self.label['text'] = newval self.after_idle(adjust_label) @property def value(self): """Return current scale value.""" return self._variable.get() @value.setter def value(self, val): """Set new scale value.""" self._variable.set(val) class OptionMenu(Menubutton): """Themed OptionMenu, based after tkinter's OptionMenu, which allows the user to select a value from a menu.""" def __init__(self, master, variable, default=None, *values, **kwargs): """Construct a themed OptionMenu widget with master as the parent, the resource textvariable set to variable, the initially selected value specified by the default parameter, the menu values given by *values and additional keywords. WIDGET-SPECIFIC OPTIONS style: stylename Menubutton style. direction: 'above', 'below', 'left', 'right', or 'flush' Menubutton direction. command: callback A callback that will be invoked after selecting an item. """ kw = {'textvariable': variable, 'style': kwargs.pop('style', None), 'direction': kwargs.pop('direction', None)} Menubutton.__init__(self, master, **kw) self['menu'] = tkinter.Menu(self, tearoff=False) self._variable = variable self._callback = kwargs.pop('command', None) if kwargs: raise tkinter.TclError('unknown option -%s' % ( next(iter(kwargs.keys())))) self.set_menu(default, *values) def __getitem__(self, item): if item == 'menu': return self.nametowidget(Menubutton.__getitem__(self, item)) return Menubutton.__getitem__(self, item) def set_menu(self, default=None, *values): """Build a new menu of radiobuttons with *values and optionally a default value.""" menu = self['menu'] menu.delete(0, 'end') for val in values: menu.add_radiobutton(label=val, command=( None if self._callback is None else lambda val=val: self._callback(val) ), variable=self._variable) if default: self._variable.set(default) def destroy(self): """Destroy this widget and its associated variable.""" try: del self._variable except AttributeError: pass super().destroy() tkinter/simpledialog.py000064400000026751152342670510011267 0ustar00# # An Introduction to Tkinter # # Copyright (c) 1997 by Fredrik Lundh # # This copyright applies to Dialog, askinteger, askfloat and asktring # # fredrik@pythonware.com # http://www.pythonware.com # """This modules handles dialog boxes. It contains the following public symbols: SimpleDialog -- A simple but flexible modal dialog box Dialog -- a base class for dialogs askinteger -- get an integer from the user askfloat -- get a float from the user askstring -- get a string from the user """ from tkinter import * from tkinter import _get_temp_root, _destroy_temp_root from tkinter import messagebox class SimpleDialog: def __init__(self, master, text='', buttons=[], default=None, cancel=None, title=None, class_=None): if class_: self.root = Toplevel(master, class_=class_) else: self.root = Toplevel(master) if title: self.root.title(title) self.root.iconname(title) _setup_dialog(self.root) self.message = Message(self.root, text=text, aspect=400) self.message.pack(expand=1, fill=BOTH) self.frame = Frame(self.root) self.frame.pack() self.num = default self.cancel = cancel self.default = default self.root.bind('', self.return_event) for num in range(len(buttons)): s = buttons[num] b = Button(self.frame, text=s, command=(lambda self=self, num=num: self.done(num))) if num == default: b.config(relief=RIDGE, borderwidth=8) b.pack(side=LEFT, fill=BOTH, expand=1) self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window) self.root.transient(master) _place_window(self.root, master) def go(self): self.root.wait_visibility() self.root.grab_set() self.root.mainloop() self.root.destroy() return self.num def return_event(self, event): if self.default is None: self.root.bell() else: self.done(self.default) def wm_delete_window(self): if self.cancel is None: self.root.bell() else: self.done(self.cancel) def done(self, num): self.num = num self.root.quit() class Dialog(Toplevel): '''Class to open dialogs. This class is intended as a base class for custom dialogs ''' def __init__(self, parent, title = None): '''Initialize a dialog. Arguments: parent -- a parent window (the application window) title -- the dialog title ''' master = parent if master is None: master = _get_temp_root() Toplevel.__init__(self, master) self.withdraw() # remain invisible for now # If the parent is not viewable, don't # make the child transient, or else it # would be opened withdrawn if parent is not None and parent.winfo_viewable(): self.transient(parent) if title: self.title(title) _setup_dialog(self) self.parent = parent self.result = None body = Frame(self) self.initial_focus = self.body(body) body.pack(padx=5, pady=5) self.buttonbox() if self.initial_focus is None: self.initial_focus = self self.protocol("WM_DELETE_WINDOW", self.cancel) _place_window(self, parent) self.initial_focus.focus_set() # wait for window to appear on screen before calling grab_set self.wait_visibility() self.grab_set() self.wait_window(self) def destroy(self): '''Destroy the window''' self.initial_focus = None Toplevel.destroy(self) _destroy_temp_root(self.master) # # construction hooks def body(self, master): '''create dialog body. return widget that should have initial focus. This method should be overridden, and is called by the __init__ method. ''' pass def buttonbox(self): '''add standard button box. override if you do not want the standard buttons ''' box = Frame(self) w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE) w.pack(side=LEFT, padx=5, pady=5) w = Button(box, text="Cancel", width=10, command=self.cancel) w.pack(side=LEFT, padx=5, pady=5) self.bind("", self.ok) self.bind("", self.cancel) box.pack() # # standard button semantics def ok(self, event=None): if not self.validate(): self.initial_focus.focus_set() # put focus back return self.withdraw() self.update_idletasks() try: self.apply() finally: self.cancel() def cancel(self, event=None): # put focus back to the parent window if self.parent is not None: self.parent.focus_set() self.destroy() # # command hooks def validate(self): '''validate the data This method is called automatically to validate the data before the dialog is destroyed. By default, it always validates OK. ''' return 1 # override def apply(self): '''process the data This method is called automatically to process the data, *after* the dialog is destroyed. By default, it does nothing. ''' pass # override # Place a toplevel window at the center of parent or screen # It is a Python implementation of ::tk::PlaceWindow. def _place_window(w, parent=None): w.wm_withdraw() # Remain invisible while we figure out the geometry w.update_idletasks() # Actualize geometry information minwidth = w.winfo_reqwidth() minheight = w.winfo_reqheight() maxwidth = w.winfo_vrootwidth() maxheight = w.winfo_vrootheight() if parent is not None and parent.winfo_ismapped(): x = parent.winfo_rootx() + (parent.winfo_width() - minwidth) // 2 y = parent.winfo_rooty() + (parent.winfo_height() - minheight) // 2 vrootx = w.winfo_vrootx() vrooty = w.winfo_vrooty() x = min(x, vrootx + maxwidth - minwidth) x = max(x, vrootx) y = min(y, vrooty + maxheight - minheight) y = max(y, vrooty) if w._windowingsystem == 'aqua': # Avoid the native menu bar which sits on top of everything. y = max(y, 22) else: x = (w.winfo_screenwidth() - minwidth) // 2 y = (w.winfo_screenheight() - minheight) // 2 w.wm_maxsize(maxwidth, maxheight) w.wm_geometry('+%d+%d' % (x, y)) w.wm_deiconify() # Become visible at the desired location def _setup_dialog(w): if w._windowingsystem == "aqua": w.tk.call("::tk::unsupported::MacWindowStyle", "style", w, "moveableModal", "") elif w._windowingsystem == "x11": w.wm_attributes("-type", "dialog") # -------------------------------------------------------------------- # convenience dialogues class _QueryDialog(Dialog): def __init__(self, title, prompt, initialvalue=None, minvalue = None, maxvalue = None, parent = None): self.prompt = prompt self.minvalue = minvalue self.maxvalue = maxvalue self.initialvalue = initialvalue Dialog.__init__(self, parent, title) def destroy(self): self.entry = None Dialog.destroy(self) def body(self, master): w = Label(master, text=self.prompt, justify=LEFT) w.grid(row=0, padx=5, sticky=W) self.entry = Entry(master, name="entry") self.entry.grid(row=1, padx=5, sticky=W+E) if self.initialvalue is not None: self.entry.insert(0, self.initialvalue) self.entry.select_range(0, END) return self.entry def validate(self): try: result = self.getresult() except ValueError: messagebox.showwarning( "Illegal value", self.errormessage + "\nPlease try again", parent = self ) return 0 if self.minvalue is not None and result < self.minvalue: messagebox.showwarning( "Too small", "The allowed minimum value is %s. " "Please try again." % self.minvalue, parent = self ) return 0 if self.maxvalue is not None and result > self.maxvalue: messagebox.showwarning( "Too large", "The allowed maximum value is %s. " "Please try again." % self.maxvalue, parent = self ) return 0 self.result = result return 1 class _QueryInteger(_QueryDialog): errormessage = "Not an integer." def getresult(self): return self.getint(self.entry.get()) def askinteger(title, prompt, **kw): '''get an integer from the user Arguments: title -- the dialog title prompt -- the label text **kw -- see SimpleDialog class Return value is an integer ''' d = _QueryInteger(title, prompt, **kw) return d.result class _QueryFloat(_QueryDialog): errormessage = "Not a floating-point value." def getresult(self): return self.getdouble(self.entry.get()) def askfloat(title, prompt, **kw): '''get a float from the user Arguments: title -- the dialog title prompt -- the label text **kw -- see SimpleDialog class Return value is a float ''' d = _QueryFloat(title, prompt, **kw) return d.result class _QueryString(_QueryDialog): def __init__(self, *args, **kw): if "show" in kw: self.__show = kw["show"] del kw["show"] else: self.__show = None _QueryDialog.__init__(self, *args, **kw) def body(self, master): entry = _QueryDialog.body(self, master) if self.__show is not None: entry.configure(show=self.__show) return entry def getresult(self): return self.entry.get() def askstring(title, prompt, **kw): '''get a string from the user Arguments: title -- the dialog title prompt -- the label text **kw -- see SimpleDialog class Return value is a string ''' d = _QueryString(title, prompt, **kw) return d.result if __name__ == '__main__': def test(): root = Tk() def doit(root=root): d = SimpleDialog(root, text="This is a test dialog. " "Would this have been an actual dialog, " "the buttons below would have been glowing " "in soft pink light.\n" "Do you believe this?", buttons=["Yes", "No", "Cancel"], default=0, cancel=2, title="Test Dialog") print(d.go()) print(askinteger("Spam", "Egg count", initialvalue=12*12)) print(askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100)) print(askstring("Spam", "Egg label")) t = Button(root, text='Test', command=doit) t.pack() q = Button(root, text='Quit', command=t.quit) q.pack() t.mainloop() test() tkinter/messagebox.py000064400000007425152342670510010750 0ustar00# tk common message boxes # # this module provides an interface to the native message boxes # available in Tk 4.2 and newer. # # written by Fredrik Lundh, May 1997 # # # options (all have default values): # # - default: which button to make default (one of the reply codes) # # - icon: which icon to display (see below) # # - message: the message to display # # - parent: which window to place the dialog on top of # # - title: dialog title # # - type: dialog type; that is, which buttons to display (see below) # from tkinter.commondialog import Dialog __all__ = ["showinfo", "showwarning", "showerror", "askquestion", "askokcancel", "askyesno", "askyesnocancel", "askretrycancel"] # # constants # icons ERROR = "error" INFO = "info" QUESTION = "question" WARNING = "warning" # types ABORTRETRYIGNORE = "abortretryignore" OK = "ok" OKCANCEL = "okcancel" RETRYCANCEL = "retrycancel" YESNO = "yesno" YESNOCANCEL = "yesnocancel" # replies ABORT = "abort" RETRY = "retry" IGNORE = "ignore" OK = "ok" CANCEL = "cancel" YES = "yes" NO = "no" # # message dialog class class Message(Dialog): "A message box" command = "tk_messageBox" # # convenience stuff # Rename _icon and _type options to allow overriding them in options def _show(title=None, message=None, _icon=None, _type=None, **options): if _icon and "icon" not in options: options["icon"] = _icon if _type and "type" not in options: options["type"] = _type if title: options["title"] = title if message: options["message"] = message res = Message(**options).show() # In some Tcl installations, yes/no is converted into a boolean. if isinstance(res, bool): if res: return YES return NO # In others we get a Tcl_Obj. return str(res) def showinfo(title=None, message=None, **options): "Show an info message" return _show(title, message, INFO, OK, **options) def showwarning(title=None, message=None, **options): "Show a warning message" return _show(title, message, WARNING, OK, **options) def showerror(title=None, message=None, **options): "Show an error message" return _show(title, message, ERROR, OK, **options) def askquestion(title=None, message=None, **options): "Ask a question" return _show(title, message, QUESTION, YESNO, **options) def askokcancel(title=None, message=None, **options): "Ask if operation should proceed; return true if the answer is ok" s = _show(title, message, QUESTION, OKCANCEL, **options) return s == OK def askyesno(title=None, message=None, **options): "Ask a question; return true if the answer is yes" s = _show(title, message, QUESTION, YESNO, **options) return s == YES def askyesnocancel(title=None, message=None, **options): "Ask a question; return true if the answer is yes, None if cancelled." s = _show(title, message, QUESTION, YESNOCANCEL, **options) # s might be a Tcl index object, so convert it to a string s = str(s) if s == CANCEL: return None return s == YES def askretrycancel(title=None, message=None, **options): "Ask if operation should be retried; return true if the answer is yes" s = _show(title, message, WARNING, RETRYCANCEL, **options) return s == RETRY # -------------------------------------------------------------------- # test stuff if __name__ == "__main__": print("info", showinfo("Spam", "Egg Information")) print("warning", showwarning("Spam", "Egg Warning")) print("error", showerror("Spam", "Egg Alert")) print("question", askquestion("Spam", "Question?")) print("proceed", askokcancel("Spam", "Proceed?")) print("yes/no", askyesno("Spam", "Got it?")) print("yes/no/cancel", askyesnocancel("Spam", "Want it?")) print("try again", askretrycancel("Spam", "Try again?")) tkinter/commondialog.py000064400000002411152342670510011251 0ustar00# base class for tk common dialogues # # this module provides a base class for accessing the common # dialogues available in Tk 4.2 and newer. use filedialog, # colorchooser, and messagebox to access the individual # dialogs. # # written by Fredrik Lundh, May 1997 # __all__ = ["Dialog"] from tkinter import _get_temp_root, _destroy_temp_root class Dialog: command = None def __init__(self, master=None, **options): if master is None: master = options.get('parent') self.master = master self.options = options def _fixoptions(self): pass # hook def _fixresult(self, widget, result): return result # hook def show(self, **options): # update instance options for k, v in options.items(): self.options[k] = v self._fixoptions() master = self.master if master is None: master = _get_temp_root() try: self._test_callback(master) # The function below is replaced for some tests. s = master.tk.call(self.command, *master._options(self.options)) s = self._fixresult(master, s) finally: _destroy_temp_root(master) return s def _test_callback(self, master): pass tkinter/scrolledtext.py000064400000003430152342670510011317 0ustar00"""A ScrolledText widget feels like a text widget but also has a vertical scroll bar on its right. (Later, options may be added to add a horizontal bar as well, to make the bars disappear automatically when not needed, to move them to the other side of the window, etc.) Configuration options are passed to the Text widget. A Frame widget is inserted between the master and the text, to hold the Scrollbar widget. Most methods calls are inherited from the Text widget; Pack, Grid and Place methods are redirected to the Frame widget however. """ from tkinter import Frame, Text, Scrollbar, Pack, Grid, Place from tkinter.constants import RIGHT, LEFT, Y, BOTH __all__ = ['ScrolledText'] class ScrolledText(Text): def __init__(self, master=None, **kw): self.frame = Frame(master) self.vbar = Scrollbar(self.frame) self.vbar.pack(side=RIGHT, fill=Y) kw.update({'yscrollcommand': self.vbar.set}) Text.__init__(self, self.frame, **kw) self.pack(side=LEFT, fill=BOTH, expand=True) self.vbar['command'] = self.yview # Copy geometry methods of self.frame without overriding Text # methods -- hack! text_meths = vars(Text).keys() methods = vars(Pack).keys() | vars(Grid).keys() | vars(Place).keys() methods = methods.difference(text_meths) for m in methods: if m[0] != '_' and m != 'config' and m != 'configure': setattr(self, m, getattr(self.frame, m)) def __str__(self): return str(self.frame) def example(): from tkinter.constants import END stext = ScrolledText(bg='white', height=10) stext.insert(END, __doc__) stext.pack(fill=BOTH, side=LEFT, expand=True) stext.focus_set() stext.mainloop() if __name__ == "__main__": example() tkinter/tix.py000064400000226350152342670510007417 0ustar00# Tix.py -- Tix widget wrappers. # # For Tix, see http://tix.sourceforge.net # # - Sudhir Shenoy (sshenoy@gol.com), Dec. 1995. # based on an idea of Jean-Marc Lugrin (lugrin@ms.com) # # NOTE: In order to minimize changes to Tkinter.py, some of the code here # (TixWidget.__init__) has been taken from Tkinter (Widget.__init__) # and will break if there are major changes in Tkinter. # # The Tix widgets are represented by a class hierarchy in python with proper # inheritance of base classes. # # As a result after creating a 'w = StdButtonBox', I can write # w.ok['text'] = 'Who Cares' # or w.ok['bg'] = w['bg'] # or even w.ok.invoke() # etc. # # Compare the demo tixwidgets.py to the original Tcl program and you will # appreciate the advantages. # # NOTE: This module is deprecated since Python 3.6. import os import warnings import tkinter from tkinter import * from tkinter import _cnfmerge warnings.warn( 'The Tix Tk extension is unmaintained, and the tkinter.tix wrapper module' ' is deprecated in favor of tkinter.ttk', DeprecationWarning, stacklevel=2, ) # Some more constants (for consistency with Tkinter) WINDOW = 'window' TEXT = 'text' STATUS = 'status' IMMEDIATE = 'immediate' IMAGE = 'image' IMAGETEXT = 'imagetext' BALLOON = 'balloon' AUTO = 'auto' ACROSSTOP = 'acrosstop' # A few useful constants for the Grid widget ASCII = 'ascii' CELL = 'cell' COLUMN = 'column' DECREASING = 'decreasing' INCREASING = 'increasing' INTEGER = 'integer' MAIN = 'main' MAX = 'max' REAL = 'real' ROW = 'row' S_REGION = 's-region' X_REGION = 'x-region' Y_REGION = 'y-region' # Some constants used by Tkinter dooneevent() TCL_DONT_WAIT = 1 << 1 TCL_WINDOW_EVENTS = 1 << 2 TCL_FILE_EVENTS = 1 << 3 TCL_TIMER_EVENTS = 1 << 4 TCL_IDLE_EVENTS = 1 << 5 TCL_ALL_EVENTS = 0 # BEWARE - this is implemented by copying some code from the Widget class # in Tkinter (to override Widget initialization) and is therefore # liable to break. # Could probably add this to Tkinter.Misc class tixCommand: """The tix commands provide access to miscellaneous elements of Tix's internal state and the Tix application context. Most of the information manipulated by these commands pertains to the application as a whole, or to a screen or display, rather than to a particular window. This is a mixin class, assumed to be mixed to Tkinter.Tk that supports the self.tk.call method. """ def tix_addbitmapdir(self, directory): """Tix maintains a list of directories under which the tix_getimage and tix_getbitmap commands will search for image files. The standard bitmap directory is $TIX_LIBRARY/bitmaps. The addbitmapdir command adds directory into this list. By using this command, the image files of an applications can also be located using the tix_getimage or tix_getbitmap command. """ return self.tk.call('tix', 'addbitmapdir', directory) def tix_cget(self, option): """Returns the current value of the configuration option given by option. Option may be any of the options described in the CONFIGURATION OPTIONS section. """ return self.tk.call('tix', 'cget', option) def tix_configure(self, cnf=None, **kw): """Query or modify the configuration options of the Tix application context. If no option is specified, returns a dictionary all of the available options. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given option(s) to have the given value(s); in this case the command returns an empty string. Option may be any of the configuration options. """ # Copied from Tkinter.py if kw: cnf = _cnfmerge((cnf, kw)) elif cnf: cnf = _cnfmerge(cnf) if cnf is None: return self._getconfigure('tix', 'configure') if isinstance(cnf, str): return self._getconfigure1('tix', 'configure', '-'+cnf) return self.tk.call(('tix', 'configure') + self._options(cnf)) def tix_filedialog(self, dlgclass=None): """Returns the file selection dialog that may be shared among different calls from this application. This command will create a file selection dialog widget when it is called the first time. This dialog will be returned by all subsequent calls to tix_filedialog. An optional dlgclass parameter can be passed to specified what type of file selection dialog widget is desired. Possible options are tix FileSelectDialog or tixExFileSelectDialog. """ if dlgclass is not None: return self.tk.call('tix', 'filedialog', dlgclass) else: return self.tk.call('tix', 'filedialog') def tix_getbitmap(self, name): """Locates a bitmap file of the name name.xpm or name in one of the bitmap directories (see the tix_addbitmapdir command above). By using tix_getbitmap, you can avoid hard coding the pathnames of the bitmap files in your application. When successful, it returns the complete pathname of the bitmap file, prefixed with the character '@'. The returned value can be used to configure the -bitmap option of the TK and Tix widgets. """ return self.tk.call('tix', 'getbitmap', name) def tix_getimage(self, name): """Locates an image file of the name name.xpm, name.xbm or name.ppm in one of the bitmap directories (see the addbitmapdir command above). If more than one file with the same name (but different extensions) exist, then the image type is chosen according to the depth of the X display: xbm images are chosen on monochrome displays and color images are chosen on color displays. By using tix_ getimage, you can avoid hard coding the pathnames of the image files in your application. When successful, this command returns the name of the newly created image, which can be used to configure the -image option of the Tk and Tix widgets. """ return self.tk.call('tix', 'getimage', name) def tix_option_get(self, name): """Gets the options maintained by the Tix scheme mechanism. Available options include: active_bg active_fg bg bold_font dark1_bg dark1_fg dark2_bg dark2_fg disabled_fg fg fixed_font font inactive_bg inactive_fg input1_bg input2_bg italic_font light1_bg light1_fg light2_bg light2_fg menu_font output1_bg output2_bg select_bg select_fg selector """ # could use self.tk.globalgetvar('tixOption', name) return self.tk.call('tix', 'option', 'get', name) def tix_resetoptions(self, newScheme, newFontSet, newScmPrio=None): """Resets the scheme and fontset of the Tix application to newScheme and newFontSet, respectively. This affects only those widgets created after this call. Therefore, it is best to call the resetoptions command before the creation of any widgets in a Tix application. The optional parameter newScmPrio can be given to reset the priority level of the Tk options set by the Tix schemes. Because of the way Tk handles the X option database, after Tix has been has imported and inited, it is not possible to reset the color schemes and font sets using the tix config command. Instead, the tix_resetoptions command must be used. """ if newScmPrio is not None: return self.tk.call('tix', 'resetoptions', newScheme, newFontSet, newScmPrio) else: return self.tk.call('tix', 'resetoptions', newScheme, newFontSet) class Tk(tkinter.Tk, tixCommand): """Toplevel widget of Tix which represents mostly the main window of an application. It has an associated Tcl interpreter.""" def __init__(self, screenName=None, baseName=None, className='Tix'): tkinter.Tk.__init__(self, screenName, baseName, className) tixlib = os.environ.get('TIX_LIBRARY') self.tk.eval('global auto_path; lappend auto_path [file dir [info nameof]]') if tixlib is not None: self.tk.eval('global auto_path; lappend auto_path {%s}' % tixlib) self.tk.eval('global tcl_pkgPath; lappend tcl_pkgPath {%s}' % tixlib) # Load Tix - this should work dynamically or statically # If it's static, tcl/tix8.1/pkgIndex.tcl should have # 'load {} Tix' # If it's dynamic under Unix, tcl/tix8.1/pkgIndex.tcl should have # 'load libtix8.1.8.3.so Tix' self.tk.eval('package require Tix') def destroy(self): # For safety, remove the delete_window binding before destroy self.protocol("WM_DELETE_WINDOW", "") tkinter.Tk.destroy(self) # The Tix 'tixForm' geometry manager class Form: """The Tix Form geometry manager Widgets can be arranged by specifying attachments to other widgets. See Tix documentation for complete details""" def config(self, cnf={}, **kw): self.tk.call('tixForm', self._w, *self._options(cnf, kw)) form = config def __setitem__(self, key, value): Form.form(self, {key: value}) def check(self): return self.tk.call('tixForm', 'check', self._w) def forget(self): self.tk.call('tixForm', 'forget', self._w) def grid(self, xsize=0, ysize=0): if (not xsize) and (not ysize): x = self.tk.call('tixForm', 'grid', self._w) y = self.tk.splitlist(x) z = () for x in y: z = z + (self.tk.getint(x),) return z return self.tk.call('tixForm', 'grid', self._w, xsize, ysize) def info(self, option=None): if not option: return self.tk.call('tixForm', 'info', self._w) if option[0] != '-': option = '-' + option return self.tk.call('tixForm', 'info', self._w, option) def slaves(self): return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call( 'tixForm', 'slaves', self._w))] tkinter.Widget.__bases__ = tkinter.Widget.__bases__ + (Form,) class TixWidget(tkinter.Widget): """A TixWidget class is used to package all (or most) Tix widgets. Widget initialization is extended in two ways: 1) It is possible to give a list of options which must be part of the creation command (so called Tix 'static' options). These cannot be given as a 'config' command later. 2) It is possible to give the name of an existing TK widget. These are child widgets created automatically by a Tix mega-widget. The Tk call to create these widgets is therefore bypassed in TixWidget.__init__ Both options are for use by subclasses only. """ def __init__ (self, master=None, widgetName=None, static_options=None, cnf={}, kw={}): # Merge keywords and dictionary arguments if kw: cnf = _cnfmerge((cnf, kw)) else: cnf = _cnfmerge(cnf) # Move static options into extra. static_options must be # a list of keywords (or None). extra=() # 'options' is always a static option if static_options: static_options.append('options') else: static_options = ['options'] for k,v in list(cnf.items()): if k in static_options: extra = extra + ('-' + k, v) del cnf[k] self.widgetName = widgetName self._setup(master, cnf) # If widgetName is None, this is a dummy creation call where the # corresponding Tk widget has already been created by Tix if widgetName: self.tk.call(widgetName, self._w, *extra) # Non-static options - to be done via a 'config' command if cnf: Widget.config(self, cnf) # Dictionary to hold subwidget names for easier access. We can't # use the children list because the public Tix names may not be the # same as the pathname component self.subwidget_list = {} # We set up an attribute access function so that it is possible to # do w.ok['text'] = 'Hello' rather than w.subwidget('ok')['text'] = 'Hello' # when w is a StdButtonBox. # We can even do w.ok.invoke() because w.ok is subclassed from the # Button class if you go through the proper constructors def __getattr__(self, name): if name in self.subwidget_list: return self.subwidget_list[name] raise AttributeError(name) def set_silent(self, value): """Set a variable without calling its action routine""" self.tk.call('tixSetSilent', self._w, value) def subwidget(self, name): """Return the named subwidget (which must have been created by the sub-class).""" n = self._subwidget_name(name) if not n: raise TclError("Subwidget " + name + " not child of " + self._name) # Remove header of name and leading dot n = n[len(self._w)+1:] return self._nametowidget(n) def subwidgets_all(self): """Return all subwidgets.""" names = self._subwidget_names() if not names: return [] retlist = [] for name in names: name = name[len(self._w)+1:] try: retlist.append(self._nametowidget(name)) except: # some of the widgets are unknown e.g. border in LabelFrame pass return retlist def _subwidget_name(self,name): """Get a subwidget name (returns a String, not a Widget !)""" try: return self.tk.call(self._w, 'subwidget', name) except TclError: return None def _subwidget_names(self): """Return the name of all subwidgets.""" try: x = self.tk.call(self._w, 'subwidgets', '-all') return self.tk.splitlist(x) except TclError: return None def config_all(self, option, value): """Set configuration options for all subwidgets (and self).""" if option == '': return elif not isinstance(option, str): option = repr(option) if not isinstance(value, str): value = repr(value) names = self._subwidget_names() for name in names: self.tk.call(name, 'configure', '-' + option, value) # These are missing from Tkinter def image_create(self, imgtype, cnf={}, master=None, **kw): if master is None: master = self if kw and cnf: cnf = _cnfmerge((cnf, kw)) elif kw: cnf = kw options = () for k, v in cnf.items(): if callable(v): v = self._register(v) options = options + ('-'+k, v) return master.tk.call(('image', 'create', imgtype,) + options) def image_delete(self, imgname): try: self.tk.call('image', 'delete', imgname) except TclError: # May happen if the root was destroyed pass # Subwidgets are child widgets created automatically by mega-widgets. # In python, we have to create these subwidgets manually to mirror their # existence in Tk/Tix. class TixSubWidget(TixWidget): """Subwidget class. This is used to mirror child widgets automatically created by Tix/Tk as part of a mega-widget in Python (which is not informed of this)""" def __init__(self, master, name, destroy_physically=1, check_intermediate=1): if check_intermediate: path = master._subwidget_name(name) try: path = path[len(master._w)+1:] plist = path.split('.') except: plist = [] if not check_intermediate: # immediate descendant TixWidget.__init__(self, master, None, None, {'name' : name}) else: # Ensure that the intermediate widgets exist parent = master for i in range(len(plist) - 1): n = '.'.join(plist[:i+1]) try: w = master._nametowidget(n) parent = w except KeyError: # Create the intermediate widget parent = TixSubWidget(parent, plist[i], destroy_physically=0, check_intermediate=0) # The Tk widget name is in plist, not in name if plist: name = plist[-1] TixWidget.__init__(self, parent, None, None, {'name' : name}) self.destroy_physically = destroy_physically def destroy(self): # For some widgets e.g., a NoteBook, when we call destructors, # we must be careful not to destroy the frame widget since this # also destroys the parent NoteBook thus leading to an exception # in Tkinter when it finally calls Tcl to destroy the NoteBook for c in list(self.children.values()): c.destroy() if self._name in self.master.children: del self.master.children[self._name] if self._name in self.master.subwidget_list: del self.master.subwidget_list[self._name] if self.destroy_physically: # This is bypassed only for a few widgets self.tk.call('destroy', self._w) # Useful class to create a display style - later shared by many items. # Contributed by Steffen Kremser class DisplayStyle: """DisplayStyle - handle configuration options shared by (multiple) Display Items""" def __init__(self, itemtype, cnf={}, *, master=None, **kw): if master is None: if 'refwindow' in kw: master = kw['refwindow'] elif 'refwindow' in cnf: master = cnf['refwindow'] else: master = tkinter._get_default_root('create display style') self.tk = master.tk self.stylename = self.tk.call('tixDisplayStyle', itemtype, *self._options(cnf,kw) ) def __str__(self): return self.stylename def _options(self, cnf, kw): if kw and cnf: cnf = _cnfmerge((cnf, kw)) elif kw: cnf = kw opts = () for k, v in cnf.items(): opts = opts + ('-'+k, v) return opts def delete(self): self.tk.call(self.stylename, 'delete') def __setitem__(self,key,value): self.tk.call(self.stylename, 'configure', '-%s'%key, value) def config(self, cnf={}, **kw): return self._getconfigure( self.stylename, 'configure', *self._options(cnf,kw)) def __getitem__(self,key): return self.tk.call(self.stylename, 'cget', '-%s'%key) ###################################################### ### The Tix Widget classes - in alphabetical order ### ###################################################### class Balloon(TixWidget): """Balloon help widget. Subwidget Class --------- ----- label Label message Message""" # FIXME: It should inherit -superclass tixShell def __init__(self, master=None, cnf={}, **kw): # static seem to be -installcolormap -initwait -statusbar -cursor static = ['options', 'installcolormap', 'initwait', 'statusbar', 'cursor'] TixWidget.__init__(self, master, 'tixBalloon', static, cnf, kw) self.subwidget_list['label'] = _dummyLabel(self, 'label', destroy_physically=0) self.subwidget_list['message'] = _dummyLabel(self, 'message', destroy_physically=0) def bind_widget(self, widget, cnf={}, **kw): """Bind balloon widget to another. One balloon widget may be bound to several widgets at the same time""" self.tk.call(self._w, 'bind', widget._w, *self._options(cnf, kw)) def unbind_widget(self, widget): self.tk.call(self._w, 'unbind', widget._w) class ButtonBox(TixWidget): """ButtonBox - A container for pushbuttons. Subwidgets are the buttons added with the add method. """ def __init__(self, master=None, cnf={}, **kw): TixWidget.__init__(self, master, 'tixButtonBox', ['orientation', 'options'], cnf, kw) def add(self, name, cnf={}, **kw): """Add a button with given name to box.""" btn = self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) self.subwidget_list[name] = _dummyButton(self, name) return btn def invoke(self, name): if name in self.subwidget_list: self.tk.call(self._w, 'invoke', name) class ComboBox(TixWidget): """ComboBox - an Entry field with a dropdown menu. The user can select a choice by either typing in the entry subwidget or selecting from the listbox subwidget. Subwidget Class --------- ----- entry Entry arrow Button slistbox ScrolledListBox tick Button cross Button : present if created with the fancy option""" # FIXME: It should inherit -superclass tixLabelWidget def __init__ (self, master=None, cnf={}, **kw): TixWidget.__init__(self, master, 'tixComboBox', ['editable', 'dropdown', 'fancy', 'options'], cnf, kw) self.subwidget_list['label'] = _dummyLabel(self, 'label') self.subwidget_list['entry'] = _dummyEntry(self, 'entry') self.subwidget_list['arrow'] = _dummyButton(self, 'arrow') self.subwidget_list['slistbox'] = _dummyScrolledListBox(self, 'slistbox') try: self.subwidget_list['tick'] = _dummyButton(self, 'tick') self.subwidget_list['cross'] = _dummyButton(self, 'cross') except TypeError: # unavailable when -fancy not specified pass # align def add_history(self, str): self.tk.call(self._w, 'addhistory', str) def append_history(self, str): self.tk.call(self._w, 'appendhistory', str) def insert(self, index, str): self.tk.call(self._w, 'insert', index, str) def pick(self, index): self.tk.call(self._w, 'pick', index) class Control(TixWidget): """Control - An entry field with value change arrows. The user can adjust the value by pressing the two arrow buttons or by entering the value directly into the entry. The new value will be checked against the user-defined upper and lower limits. Subwidget Class --------- ----- incr Button decr Button entry Entry label Label""" # FIXME: It should inherit -superclass tixLabelWidget def __init__ (self, master=None, cnf={}, **kw): TixWidget.__init__(self, master, 'tixControl', ['options'], cnf, kw) self.subwidget_list['incr'] = _dummyButton(self, 'incr') self.subwidget_list['decr'] = _dummyButton(self, 'decr') self.subwidget_list['label'] = _dummyLabel(self, 'label') self.subwidget_list['entry'] = _dummyEntry(self, 'entry') def decrement(self): self.tk.call(self._w, 'decr') def increment(self): self.tk.call(self._w, 'incr') def invoke(self): self.tk.call(self._w, 'invoke') def update(self): self.tk.call(self._w, 'update') class DirList(TixWidget): """DirList - displays a list view of a directory, its previous directories and its sub-directories. The user can choose one of the directories displayed in the list or change to another directory. Subwidget Class --------- ----- hlist HList hsb Scrollbar vsb Scrollbar""" # FIXME: It should inherit -superclass tixScrolledHList def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixDirList', ['options'], cnf, kw) self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') def chdir(self, dir): self.tk.call(self._w, 'chdir', dir) class DirTree(TixWidget): """DirTree - Directory Listing in a hierarchical view. Displays a tree view of a directory, its previous directories and its sub-directories. The user can choose one of the directories displayed in the list or change to another directory. Subwidget Class --------- ----- hlist HList hsb Scrollbar vsb Scrollbar""" # FIXME: It should inherit -superclass tixScrolledHList def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixDirTree', ['options'], cnf, kw) self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') def chdir(self, dir): self.tk.call(self._w, 'chdir', dir) class DirSelectBox(TixWidget): """DirSelectBox - Motif style file select box. It is generally used for the user to choose a file. FileSelectBox stores the files mostly recently selected into a ComboBox widget so that they can be quickly selected again. Subwidget Class --------- ----- selection ComboBox filter ComboBox dirlist ScrolledListBox filelist ScrolledListBox""" def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixDirSelectBox', ['options'], cnf, kw) self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx') class ExFileSelectBox(TixWidget): """ExFileSelectBox - MS Windows style file select box. It provides a convenient method for the user to select files. Subwidget Class --------- ----- cancel Button ok Button hidden Checkbutton types ComboBox dir ComboBox file ComboBox dirlist ScrolledListBox filelist ScrolledListBox""" def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixExFileSelectBox', ['options'], cnf, kw) self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') self.subwidget_list['ok'] = _dummyButton(self, 'ok') self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden') self.subwidget_list['types'] = _dummyComboBox(self, 'types') self.subwidget_list['dir'] = _dummyComboBox(self, 'dir') self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') self.subwidget_list['file'] = _dummyComboBox(self, 'file') self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') def filter(self): self.tk.call(self._w, 'filter') def invoke(self): self.tk.call(self._w, 'invoke') # Should inherit from a Dialog class class DirSelectDialog(TixWidget): """The DirSelectDialog widget presents the directories in the file system in a dialog window. The user can use this dialog window to navigate through the file system to select the desired directory. Subwidgets Class ---------- ----- dirbox DirSelectDialog""" # FIXME: It should inherit -superclass tixDialogShell def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixDirSelectDialog', ['options'], cnf, kw) self.subwidget_list['dirbox'] = _dummyDirSelectBox(self, 'dirbox') # cancel and ok buttons are missing def popup(self): self.tk.call(self._w, 'popup') def popdown(self): self.tk.call(self._w, 'popdown') # Should inherit from a Dialog class class ExFileSelectDialog(TixWidget): """ExFileSelectDialog - MS Windows style file select dialog. It provides a convenient method for the user to select files. Subwidgets Class ---------- ----- fsbox ExFileSelectBox""" # FIXME: It should inherit -superclass tixDialogShell def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixExFileSelectDialog', ['options'], cnf, kw) self.subwidget_list['fsbox'] = _dummyExFileSelectBox(self, 'fsbox') def popup(self): self.tk.call(self._w, 'popup') def popdown(self): self.tk.call(self._w, 'popdown') class FileSelectBox(TixWidget): """ExFileSelectBox - Motif style file select box. It is generally used for the user to choose a file. FileSelectBox stores the files mostly recently selected into a ComboBox widget so that they can be quickly selected again. Subwidget Class --------- ----- selection ComboBox filter ComboBox dirlist ScrolledListBox filelist ScrolledListBox""" def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixFileSelectBox', ['options'], cnf, kw) self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') self.subwidget_list['filter'] = _dummyComboBox(self, 'filter') self.subwidget_list['selection'] = _dummyComboBox(self, 'selection') def apply_filter(self): # name of subwidget is same as command self.tk.call(self._w, 'filter') def invoke(self): self.tk.call(self._w, 'invoke') # Should inherit from a Dialog class class FileSelectDialog(TixWidget): """FileSelectDialog - Motif style file select dialog. Subwidgets Class ---------- ----- btns StdButtonBox fsbox FileSelectBox""" # FIXME: It should inherit -superclass tixStdDialogShell def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixFileSelectDialog', ['options'], cnf, kw) self.subwidget_list['btns'] = _dummyStdButtonBox(self, 'btns') self.subwidget_list['fsbox'] = _dummyFileSelectBox(self, 'fsbox') def popup(self): self.tk.call(self._w, 'popup') def popdown(self): self.tk.call(self._w, 'popdown') class FileEntry(TixWidget): """FileEntry - Entry field with button that invokes a FileSelectDialog. The user can type in the filename manually. Alternatively, the user can press the button widget that sits next to the entry, which will bring up a file selection dialog. Subwidgets Class ---------- ----- button Button entry Entry""" # FIXME: It should inherit -superclass tixLabelWidget def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixFileEntry', ['dialogtype', 'options'], cnf, kw) self.subwidget_list['button'] = _dummyButton(self, 'button') self.subwidget_list['entry'] = _dummyEntry(self, 'entry') def invoke(self): self.tk.call(self._w, 'invoke') def file_dialog(self): # FIXME: return python object pass class HList(TixWidget, XView, YView): """HList - Hierarchy display widget can be used to display any data that have a hierarchical structure, for example, file system directory trees. The list entries are indented and connected by branch lines according to their places in the hierarchy. Subwidgets - None""" def __init__ (self,master=None,cnf={}, **kw): TixWidget.__init__(self, master, 'tixHList', ['columns', 'options'], cnf, kw) def add(self, entry, cnf={}, **kw): return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw)) def add_child(self, parent=None, cnf={}, **kw): if parent is None: parent = '' return self.tk.call( self._w, 'addchild', parent, *self._options(cnf, kw)) def anchor_set(self, entry): self.tk.call(self._w, 'anchor', 'set', entry) def anchor_clear(self): self.tk.call(self._w, 'anchor', 'clear') def column_width(self, col=0, width=None, chars=None): if not chars: return self.tk.call(self._w, 'column', 'width', col, width) else: return self.tk.call(self._w, 'column', 'width', col, '-char', chars) def delete_all(self): self.tk.call(self._w, 'delete', 'all') def delete_entry(self, entry): self.tk.call(self._w, 'delete', 'entry', entry) def delete_offsprings(self, entry): self.tk.call(self._w, 'delete', 'offsprings', entry) def delete_siblings(self, entry): self.tk.call(self._w, 'delete', 'siblings', entry) def dragsite_set(self, index): self.tk.call(self._w, 'dragsite', 'set', index) def dragsite_clear(self): self.tk.call(self._w, 'dragsite', 'clear') def dropsite_set(self, index): self.tk.call(self._w, 'dropsite', 'set', index) def dropsite_clear(self): self.tk.call(self._w, 'dropsite', 'clear') def header_create(self, col, cnf={}, **kw): self.tk.call(self._w, 'header', 'create', col, *self._options(cnf, kw)) def header_configure(self, col, cnf={}, **kw): if cnf is None: return self._getconfigure(self._w, 'header', 'configure', col) self.tk.call(self._w, 'header', 'configure', col, *self._options(cnf, kw)) def header_cget(self, col, opt): return self.tk.call(self._w, 'header', 'cget', col, opt) def header_exists(self, col): # A workaround to Tix library bug (issue #25464). # The documented command is "exists", but only erroneous "exist" is # accepted. return self.tk.getboolean(self.tk.call(self._w, 'header', 'exist', col)) header_exist = header_exists def header_delete(self, col): self.tk.call(self._w, 'header', 'delete', col) def header_size(self, col): return self.tk.call(self._w, 'header', 'size', col) def hide_entry(self, entry): self.tk.call(self._w, 'hide', 'entry', entry) def indicator_create(self, entry, cnf={}, **kw): self.tk.call( self._w, 'indicator', 'create', entry, *self._options(cnf, kw)) def indicator_configure(self, entry, cnf={}, **kw): if cnf is None: return self._getconfigure( self._w, 'indicator', 'configure', entry) self.tk.call( self._w, 'indicator', 'configure', entry, *self._options(cnf, kw)) def indicator_cget(self, entry, opt): return self.tk.call(self._w, 'indicator', 'cget', entry, opt) def indicator_exists(self, entry): return self.tk.call (self._w, 'indicator', 'exists', entry) def indicator_delete(self, entry): self.tk.call(self._w, 'indicator', 'delete', entry) def indicator_size(self, entry): return self.tk.call(self._w, 'indicator', 'size', entry) def info_anchor(self): return self.tk.call(self._w, 'info', 'anchor') def info_bbox(self, entry): return self._getints( self.tk.call(self._w, 'info', 'bbox', entry)) or None def info_children(self, entry=None): c = self.tk.call(self._w, 'info', 'children', entry) return self.tk.splitlist(c) def info_data(self, entry): return self.tk.call(self._w, 'info', 'data', entry) def info_dragsite(self): return self.tk.call(self._w, 'info', 'dragsite') def info_dropsite(self): return self.tk.call(self._w, 'info', 'dropsite') def info_exists(self, entry): return self.tk.call(self._w, 'info', 'exists', entry) def info_hidden(self, entry): return self.tk.call(self._w, 'info', 'hidden', entry) def info_next(self, entry): return self.tk.call(self._w, 'info', 'next', entry) def info_parent(self, entry): return self.tk.call(self._w, 'info', 'parent', entry) def info_prev(self, entry): return self.tk.call(self._w, 'info', 'prev', entry) def info_selection(self): c = self.tk.call(self._w, 'info', 'selection') return self.tk.splitlist(c) def item_cget(self, entry, col, opt): return self.tk.call(self._w, 'item', 'cget', entry, col, opt) def item_configure(self, entry, col, cnf={}, **kw): if cnf is None: return self._getconfigure(self._w, 'item', 'configure', entry, col) self.tk.call(self._w, 'item', 'configure', entry, col, *self._options(cnf, kw)) def item_create(self, entry, col, cnf={}, **kw): self.tk.call( self._w, 'item', 'create', entry, col, *self._options(cnf, kw)) def item_exists(self, entry, col): return self.tk.call(self._w, 'item', 'exists', entry, col) def item_delete(self, entry, col): self.tk.call(self._w, 'item', 'delete', entry, col) def entrycget(self, entry, opt): return self.tk.call(self._w, 'entrycget', entry, opt) def entryconfigure(self, entry, cnf={}, **kw): if cnf is None: return self._getconfigure(self._w, 'entryconfigure', entry) self.tk.call(self._w, 'entryconfigure', entry, *self._options(cnf, kw)) def nearest(self, y): return self.tk.call(self._w, 'nearest', y) def see(self, entry): self.tk.call(self._w, 'see', entry) def selection_clear(self, cnf={}, **kw): self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw)) def selection_includes(self, entry): return self.tk.call(self._w, 'selection', 'includes', entry) def selection_set(self, first, last=None): self.tk.call(self._w, 'selection', 'set', first, last) def show_entry(self, entry): return self.tk.call(self._w, 'show', 'entry', entry) class InputOnly(TixWidget): """InputOnly - Invisible widget. Unix only. Subwidgets - None""" def __init__ (self,master=None,cnf={}, **kw): TixWidget.__init__(self, master, 'tixInputOnly', None, cnf, kw) class LabelEntry(TixWidget): """LabelEntry - Entry field with label. Packages an entry widget and a label into one mega widget. It can be used to simplify the creation of ``entry-form'' type of interface. Subwidgets Class ---------- ----- label Label entry Entry""" def __init__ (self,master=None,cnf={}, **kw): TixWidget.__init__(self, master, 'tixLabelEntry', ['labelside','options'], cnf, kw) self.subwidget_list['label'] = _dummyLabel(self, 'label') self.subwidget_list['entry'] = _dummyEntry(self, 'entry') class LabelFrame(TixWidget): """LabelFrame - Labelled Frame container. Packages a frame widget and a label into one mega widget. To create widgets inside a LabelFrame widget, one creates the new widgets relative to the frame subwidget and manage them inside the frame subwidget. Subwidgets Class ---------- ----- label Label frame Frame""" def __init__ (self,master=None,cnf={}, **kw): TixWidget.__init__(self, master, 'tixLabelFrame', ['labelside','options'], cnf, kw) self.subwidget_list['label'] = _dummyLabel(self, 'label') self.subwidget_list['frame'] = _dummyFrame(self, 'frame') class ListNoteBook(TixWidget): """A ListNoteBook widget is very similar to the TixNoteBook widget: it can be used to display many windows in a limited space using a notebook metaphor. The notebook is divided into a stack of pages (windows). At one time only one of these pages can be shown. The user can navigate through these pages by choosing the name of the desired page in the hlist subwidget.""" def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixListNoteBook', ['options'], cnf, kw) # Is this necessary? It's not an exposed subwidget in Tix. self.subwidget_list['pane'] = _dummyPanedWindow(self, 'pane', destroy_physically=0) self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') self.subwidget_list['shlist'] = _dummyScrolledHList(self, 'shlist') def add(self, name, cnf={}, **kw): self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) self.subwidget_list[name] = TixSubWidget(self, name) return self.subwidget_list[name] def page(self, name): return self.subwidget(name) def pages(self): # Can't call subwidgets_all directly because we don't want .nbframe names = self.tk.splitlist(self.tk.call(self._w, 'pages')) ret = [] for x in names: ret.append(self.subwidget(x)) return ret def raise_page(self, name): # raise is a python keyword self.tk.call(self._w, 'raise', name) class Meter(TixWidget): """The Meter widget can be used to show the progress of a background job which may take a long time to execute. """ def __init__(self, master=None, cnf={}, **kw): TixWidget.__init__(self, master, 'tixMeter', ['options'], cnf, kw) class NoteBook(TixWidget): """NoteBook - Multi-page container widget (tabbed notebook metaphor). Subwidgets Class ---------- ----- nbframe NoteBookFrame page widgets added dynamically with the add method""" def __init__ (self,master=None,cnf={}, **kw): TixWidget.__init__(self,master,'tixNoteBook', ['options'], cnf, kw) self.subwidget_list['nbframe'] = TixSubWidget(self, 'nbframe', destroy_physically=0) def add(self, name, cnf={}, **kw): self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) self.subwidget_list[name] = TixSubWidget(self, name) return self.subwidget_list[name] def delete(self, name): self.tk.call(self._w, 'delete', name) self.subwidget_list[name].destroy() del self.subwidget_list[name] def page(self, name): return self.subwidget(name) def pages(self): # Can't call subwidgets_all directly because we don't want .nbframe names = self.tk.splitlist(self.tk.call(self._w, 'pages')) ret = [] for x in names: ret.append(self.subwidget(x)) return ret def raise_page(self, name): # raise is a python keyword self.tk.call(self._w, 'raise', name) def raised(self): return self.tk.call(self._w, 'raised') class NoteBookFrame(TixWidget): # FIXME: This is dangerous to expose to be called on its own. pass class OptionMenu(TixWidget): """OptionMenu - creates a menu button of options. Subwidget Class --------- ----- menubutton Menubutton menu Menu""" def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixOptionMenu', ['options'], cnf, kw) self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton') self.subwidget_list['menu'] = _dummyMenu(self, 'menu') def add_command(self, name, cnf={}, **kw): self.tk.call(self._w, 'add', 'command', name, *self._options(cnf, kw)) def add_separator(self, name, cnf={}, **kw): self.tk.call(self._w, 'add', 'separator', name, *self._options(cnf, kw)) def delete(self, name): self.tk.call(self._w, 'delete', name) def disable(self, name): self.tk.call(self._w, 'disable', name) def enable(self, name): self.tk.call(self._w, 'enable', name) class PanedWindow(TixWidget): """PanedWindow - Multi-pane container widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally.The user changes the sizes of the panes by dragging the resize handle between two panes. Subwidgets Class ---------- ----- g/p widgets added dynamically with the add method.""" def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixPanedWindow', ['orientation', 'options'], cnf, kw) # add delete forget panecget paneconfigure panes setsize def add(self, name, cnf={}, **kw): self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) self.subwidget_list[name] = TixSubWidget(self, name, check_intermediate=0) return self.subwidget_list[name] def delete(self, name): self.tk.call(self._w, 'delete', name) self.subwidget_list[name].destroy() del self.subwidget_list[name] def forget(self, name): self.tk.call(self._w, 'forget', name) def panecget(self, entry, opt): return self.tk.call(self._w, 'panecget', entry, opt) def paneconfigure(self, entry, cnf={}, **kw): if cnf is None: return self._getconfigure(self._w, 'paneconfigure', entry) self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw)) def panes(self): names = self.tk.splitlist(self.tk.call(self._w, 'panes')) return [self.subwidget(x) for x in names] class PopupMenu(TixWidget): """PopupMenu widget can be used as a replacement of the tk_popup command. The advantage of the Tix PopupMenu widget is it requires less application code to manipulate. Subwidgets Class ---------- ----- menubutton Menubutton menu Menu""" # FIXME: It should inherit -superclass tixShell def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixPopupMenu', ['options'], cnf, kw) self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton') self.subwidget_list['menu'] = _dummyMenu(self, 'menu') def bind_widget(self, widget): self.tk.call(self._w, 'bind', widget._w) def unbind_widget(self, widget): self.tk.call(self._w, 'unbind', widget._w) def post_widget(self, widget, x, y): self.tk.call(self._w, 'post', widget._w, x, y) class ResizeHandle(TixWidget): """Internal widget to draw resize handles on Scrolled widgets.""" def __init__(self, master, cnf={}, **kw): # There seems to be a Tix bug rejecting the configure method # Let's try making the flags -static flags = ['options', 'command', 'cursorfg', 'cursorbg', 'handlesize', 'hintcolor', 'hintwidth', 'x', 'y'] # In fact, x y height width are configurable TixWidget.__init__(self, master, 'tixResizeHandle', flags, cnf, kw) def attach_widget(self, widget): self.tk.call(self._w, 'attachwidget', widget._w) def detach_widget(self, widget): self.tk.call(self._w, 'detachwidget', widget._w) def hide(self, widget): self.tk.call(self._w, 'hide', widget._w) def show(self, widget): self.tk.call(self._w, 'show', widget._w) class ScrolledHList(TixWidget): """ScrolledHList - HList with automatic scrollbars.""" # FIXME: It should inherit -superclass tixScrolledWidget def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixScrolledHList', ['options'], cnf, kw) self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') class ScrolledListBox(TixWidget): """ScrolledListBox - Listbox with automatic scrollbars.""" # FIXME: It should inherit -superclass tixScrolledWidget def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixScrolledListBox', ['options'], cnf, kw) self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') class ScrolledText(TixWidget): """ScrolledText - Text with automatic scrollbars.""" # FIXME: It should inherit -superclass tixScrolledWidget def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixScrolledText', ['options'], cnf, kw) self.subwidget_list['text'] = _dummyText(self, 'text') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') class ScrolledTList(TixWidget): """ScrolledTList - TList with automatic scrollbars.""" # FIXME: It should inherit -superclass tixScrolledWidget def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixScrolledTList', ['options'], cnf, kw) self.subwidget_list['tlist'] = _dummyTList(self, 'tlist') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') class ScrolledWindow(TixWidget): """ScrolledWindow - Window with automatic scrollbars.""" # FIXME: It should inherit -superclass tixScrolledWidget def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixScrolledWindow', ['options'], cnf, kw) self.subwidget_list['window'] = _dummyFrame(self, 'window') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') class Select(TixWidget): """Select - Container of button subwidgets. It can be used to provide radio-box or check-box style of selection options for the user. Subwidgets are buttons added dynamically using the add method.""" # FIXME: It should inherit -superclass tixLabelWidget def __init__(self, master, cnf={}, **kw): TixWidget.__init__(self, master, 'tixSelect', ['allowzero', 'radio', 'orientation', 'labelside', 'options'], cnf, kw) self.subwidget_list['label'] = _dummyLabel(self, 'label') def add(self, name, cnf={}, **kw): self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) self.subwidget_list[name] = _dummyButton(self, name) return self.subwidget_list[name] def invoke(self, name): self.tk.call(self._w, 'invoke', name) class Shell(TixWidget): """Toplevel window. Subwidgets - None""" def __init__ (self,master=None,cnf={}, **kw): TixWidget.__init__(self, master, 'tixShell', ['options', 'title'], cnf, kw) class DialogShell(TixWidget): """Toplevel window, with popup popdown and center methods. It tells the window manager that it is a dialog window and should be treated specially. The exact treatment depends on the treatment of the window manager. Subwidgets - None""" # FIXME: It should inherit from Shell def __init__ (self,master=None,cnf={}, **kw): TixWidget.__init__(self, master, 'tixDialogShell', ['options', 'title', 'mapped', 'minheight', 'minwidth', 'parent', 'transient'], cnf, kw) def popdown(self): self.tk.call(self._w, 'popdown') def popup(self): self.tk.call(self._w, 'popup') def center(self): self.tk.call(self._w, 'center') class StdButtonBox(TixWidget): """StdButtonBox - Standard Button Box (OK, Apply, Cancel and Help) """ def __init__(self, master=None, cnf={}, **kw): TixWidget.__init__(self, master, 'tixStdButtonBox', ['orientation', 'options'], cnf, kw) self.subwidget_list['ok'] = _dummyButton(self, 'ok') self.subwidget_list['apply'] = _dummyButton(self, 'apply') self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') self.subwidget_list['help'] = _dummyButton(self, 'help') def invoke(self, name): if name in self.subwidget_list: self.tk.call(self._w, 'invoke', name) class TList(TixWidget, XView, YView): """TList - Hierarchy display widget which can be used to display data in a tabular format. The list entries of a TList widget are similar to the entries in the Tk listbox widget. The main differences are (1) the TList widget can display the list entries in a two dimensional format and (2) you can use graphical images as well as multiple colors and fonts for the list entries. Subwidgets - None""" def __init__ (self,master=None,cnf={}, **kw): TixWidget.__init__(self, master, 'tixTList', ['options'], cnf, kw) def active_set(self, index): self.tk.call(self._w, 'active', 'set', index) def active_clear(self): self.tk.call(self._w, 'active', 'clear') def anchor_set(self, index): self.tk.call(self._w, 'anchor', 'set', index) def anchor_clear(self): self.tk.call(self._w, 'anchor', 'clear') def delete(self, from_, to=None): self.tk.call(self._w, 'delete', from_, to) def dragsite_set(self, index): self.tk.call(self._w, 'dragsite', 'set', index) def dragsite_clear(self): self.tk.call(self._w, 'dragsite', 'clear') def dropsite_set(self, index): self.tk.call(self._w, 'dropsite', 'set', index) def dropsite_clear(self): self.tk.call(self._w, 'dropsite', 'clear') def insert(self, index, cnf={}, **kw): self.tk.call(self._w, 'insert', index, *self._options(cnf, kw)) def info_active(self): return self.tk.call(self._w, 'info', 'active') def info_anchor(self): return self.tk.call(self._w, 'info', 'anchor') def info_down(self, index): return self.tk.call(self._w, 'info', 'down', index) def info_left(self, index): return self.tk.call(self._w, 'info', 'left', index) def info_right(self, index): return self.tk.call(self._w, 'info', 'right', index) def info_selection(self): c = self.tk.call(self._w, 'info', 'selection') return self.tk.splitlist(c) def info_size(self): return self.tk.call(self._w, 'info', 'size') def info_up(self, index): return self.tk.call(self._w, 'info', 'up', index) def nearest(self, x, y): return self.tk.call(self._w, 'nearest', x, y) def see(self, index): self.tk.call(self._w, 'see', index) def selection_clear(self, cnf={}, **kw): self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw)) def selection_includes(self, index): return self.tk.call(self._w, 'selection', 'includes', index) def selection_set(self, first, last=None): self.tk.call(self._w, 'selection', 'set', first, last) class Tree(TixWidget): """Tree - The tixTree widget can be used to display hierarchical data in a tree form. The user can adjust the view of the tree by opening or closing parts of the tree.""" # FIXME: It should inherit -superclass tixScrolledWidget def __init__(self, master=None, cnf={}, **kw): TixWidget.__init__(self, master, 'tixTree', ['options'], cnf, kw) self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') def autosetmode(self): '''This command calls the setmode method for all the entries in this Tree widget: if an entry has no child entries, its mode is set to none. Otherwise, if the entry has any hidden child entries, its mode is set to open; otherwise its mode is set to close.''' self.tk.call(self._w, 'autosetmode') def close(self, entrypath): '''Close the entry given by entryPath if its mode is close.''' self.tk.call(self._w, 'close', entrypath) def getmode(self, entrypath): '''Returns the current mode of the entry given by entryPath.''' return self.tk.call(self._w, 'getmode', entrypath) def open(self, entrypath): '''Open the entry given by entryPath if its mode is open.''' self.tk.call(self._w, 'open', entrypath) def setmode(self, entrypath, mode='none'): '''This command is used to indicate whether the entry given by entryPath has children entries and whether the children are visible. mode must be one of open, close or none. If mode is set to open, a (+) indicator is drawn next the entry. If mode is set to close, a (-) indicator is drawn next the entry. If mode is set to none, no indicators will be drawn for this entry. The default mode is none. The open mode indicates the entry has hidden children and this entry can be opened by the user. The close mode indicates that all the children of the entry are now visible and the entry can be closed by the user.''' self.tk.call(self._w, 'setmode', entrypath, mode) # Could try subclassing Tree for CheckList - would need another arg to init class CheckList(TixWidget): """The CheckList widget displays a list of items to be selected by the user. CheckList acts similarly to the Tk checkbutton or radiobutton widgets, except it is capable of handling many more items than checkbuttons or radiobuttons. """ # FIXME: It should inherit -superclass tixTree def __init__(self, master=None, cnf={}, **kw): TixWidget.__init__(self, master, 'tixCheckList', ['options', 'radio'], cnf, kw) self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') def autosetmode(self): '''This command calls the setmode method for all the entries in this Tree widget: if an entry has no child entries, its mode is set to none. Otherwise, if the entry has any hidden child entries, its mode is set to open; otherwise its mode is set to close.''' self.tk.call(self._w, 'autosetmode') def close(self, entrypath): '''Close the entry given by entryPath if its mode is close.''' self.tk.call(self._w, 'close', entrypath) def getmode(self, entrypath): '''Returns the current mode of the entry given by entryPath.''' return self.tk.call(self._w, 'getmode', entrypath) def open(self, entrypath): '''Open the entry given by entryPath if its mode is open.''' self.tk.call(self._w, 'open', entrypath) def getselection(self, mode='on'): '''Returns a list of items whose status matches status. If status is not specified, the list of items in the "on" status will be returned. Mode can be on, off, default''' return self.tk.splitlist(self.tk.call(self._w, 'getselection', mode)) def getstatus(self, entrypath): '''Returns the current status of entryPath.''' return self.tk.call(self._w, 'getstatus', entrypath) def setstatus(self, entrypath, mode='on'): '''Sets the status of entryPath to be status. A bitmap will be displayed next to the entry its status is on, off or default.''' self.tk.call(self._w, 'setstatus', entrypath, mode) ########################################################################### ### The subclassing below is used to instantiate the subwidgets in each ### ### mega widget. This allows us to access their methods directly. ### ########################################################################### class _dummyButton(Button, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyCheckbutton(Checkbutton, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyEntry(Entry, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyFrame(Frame, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyLabel(Label, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyListbox(Listbox, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyMenu(Menu, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyMenubutton(Menubutton, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyScrollbar(Scrollbar, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyText(Text, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyScrolledListBox(ScrolledListBox, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') class _dummyHList(HList, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyScrolledHList(ScrolledHList, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') class _dummyTList(TList, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyComboBox(ComboBox, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, ['fancy',destroy_physically]) self.subwidget_list['label'] = _dummyLabel(self, 'label') self.subwidget_list['entry'] = _dummyEntry(self, 'entry') self.subwidget_list['arrow'] = _dummyButton(self, 'arrow') self.subwidget_list['slistbox'] = _dummyScrolledListBox(self, 'slistbox') try: self.subwidget_list['tick'] = _dummyButton(self, 'tick') #cross Button : present if created with the fancy option self.subwidget_list['cross'] = _dummyButton(self, 'cross') except TypeError: # unavailable when -fancy not specified pass class _dummyDirList(DirList, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') class _dummyDirSelectBox(DirSelectBox, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx') class _dummyExFileSelectBox(ExFileSelectBox, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') self.subwidget_list['ok'] = _dummyButton(self, 'ok') self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden') self.subwidget_list['types'] = _dummyComboBox(self, 'types') self.subwidget_list['dir'] = _dummyComboBox(self, 'dir') self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') self.subwidget_list['file'] = _dummyComboBox(self, 'file') self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') class _dummyFileSelectBox(FileSelectBox, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') self.subwidget_list['filter'] = _dummyComboBox(self, 'filter') self.subwidget_list['selection'] = _dummyComboBox(self, 'selection') class _dummyFileComboBox(ComboBox, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) self.subwidget_list['dircbx'] = _dummyComboBox(self, 'dircbx') class _dummyStdButtonBox(StdButtonBox, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) self.subwidget_list['ok'] = _dummyButton(self, 'ok') self.subwidget_list['apply'] = _dummyButton(self, 'apply') self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') self.subwidget_list['help'] = _dummyButton(self, 'help') class _dummyNoteBookFrame(NoteBookFrame, TixSubWidget): def __init__(self, master, name, destroy_physically=0): TixSubWidget.__init__(self, master, name, destroy_physically) class _dummyPanedWindow(PanedWindow, TixSubWidget): def __init__(self, master, name, destroy_physically=1): TixSubWidget.__init__(self, master, name, destroy_physically) ######################## ### Utility Routines ### ######################## #mike Should tixDestroy be exposed as a wrapper? - but not for widgets. def OptionName(widget): '''Returns the qualified path name for the widget. Normally used to set default options for subwidgets. See tixwidgets.py''' return widget.tk.call('tixOptionName', widget._w) # Called with a dictionary argument of the form # {'*.c':'C source files', '*.txt':'Text Files', '*':'All files'} # returns a string which can be used to configure the fsbox file types # in an ExFileSelectBox. i.e., # '{{*} {* - All files}} {{*.c} {*.c - C source files}} {{*.txt} {*.txt - Text Files}}' def FileTypeList(dict): s = '' for type in dict.keys(): s = s + '{{' + type + '} {' + type + ' - ' + dict[type] + '}} ' return s # Still to be done: # tixIconView class CObjView(TixWidget): """This file implements the Canvas Object View widget. This is a base class of IconView. It implements automatic placement/adjustment of the scrollbars according to the canvas objects inside the canvas subwidget. The scrollbars are adjusted so that the canvas is just large enough to see all the objects. """ # FIXME: It should inherit -superclass tixScrolledWidget pass class Grid(TixWidget, XView, YView): '''The Tix Grid command creates a new window and makes it into a tixGrid widget. Additional options, may be specified on the command line or in the option database to configure aspects such as its cursor and relief. A Grid widget displays its contents in a two dimensional grid of cells. Each cell may contain one Tix display item, which may be in text, graphics or other formats. See the DisplayStyle class for more information about Tix display items. Individual cells, or groups of cells, can be formatted with a wide range of attributes, such as its color, relief and border. Subwidgets - None''' # valid specific resources as of Tk 8.4 # editdonecmd, editnotifycmd, floatingcols, floatingrows, formatcmd, # highlightbackground, highlightcolor, leftmargin, itemtype, selectmode, # selectunit, topmargin, def __init__(self, master=None, cnf={}, **kw): static= [] self.cnf= cnf TixWidget.__init__(self, master, 'tixGrid', static, cnf, kw) # valid options as of Tk 8.4 # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget, # edit, entryconfigure, format, geometryinfo, info, index, move, nearest, # selection, set, size, unset, xview, yview def anchor_clear(self): """Removes the selection anchor.""" self.tk.call(self, 'anchor', 'clear') def anchor_get(self): "Get the (x,y) coordinate of the current anchor cell" return self._getints(self.tk.call(self, 'anchor', 'get')) def anchor_set(self, x, y): """Set the selection anchor to the cell at (x, y).""" self.tk.call(self, 'anchor', 'set', x, y) def delete_row(self, from_, to=None): """Delete rows between from_ and to inclusive. If to is not provided, delete only row at from_""" if to is None: self.tk.call(self, 'delete', 'row', from_) else: self.tk.call(self, 'delete', 'row', from_, to) def delete_column(self, from_, to=None): """Delete columns between from_ and to inclusive. If to is not provided, delete only column at from_""" if to is None: self.tk.call(self, 'delete', 'column', from_) else: self.tk.call(self, 'delete', 'column', from_, to) def edit_apply(self): """If any cell is being edited, de-highlight the cell and applies the changes.""" self.tk.call(self, 'edit', 'apply') def edit_set(self, x, y): """Highlights the cell at (x, y) for editing, if the -editnotify command returns True for this cell.""" self.tk.call(self, 'edit', 'set', x, y) def entrycget(self, x, y, option): "Get the option value for cell at (x,y)" if option and option[0] != '-': option = '-' + option return self.tk.call(self, 'entrycget', x, y, option) def entryconfigure(self, x, y, cnf=None, **kw): return self._configure(('entryconfigure', x, y), cnf, kw) # def format # def index def info_exists(self, x, y): "Return True if display item exists at (x,y)" return self._getboolean(self.tk.call(self, 'info', 'exists', x, y)) def info_bbox(self, x, y): # This seems to always return '', at least for 'text' displayitems return self.tk.call(self, 'info', 'bbox', x, y) def move_column(self, from_, to, offset): """Moves the range of columns from position FROM through TO by the distance indicated by OFFSET. For example, move_column(2, 4, 1) moves the columns 2,3,4 to columns 3,4,5.""" self.tk.call(self, 'move', 'column', from_, to, offset) def move_row(self, from_, to, offset): """Moves the range of rows from position FROM through TO by the distance indicated by OFFSET. For example, move_row(2, 4, 1) moves the rows 2,3,4 to rows 3,4,5.""" self.tk.call(self, 'move', 'row', from_, to, offset) def nearest(self, x, y): "Return coordinate of cell nearest pixel coordinate (x,y)" return self._getints(self.tk.call(self, 'nearest', x, y)) # def selection adjust # def selection clear # def selection includes # def selection set # def selection toggle def set(self, x, y, itemtype=None, **kw): args= self._options(self.cnf, kw) if itemtype is not None: args= ('-itemtype', itemtype) + args self.tk.call(self, 'set', x, y, *args) def size_column(self, index, **kw): """Queries or sets the size of the column given by INDEX. INDEX may be any non-negative integer that gives the position of a given column. INDEX can also be the string "default"; in this case, this command queries or sets the default size of all columns. When no option-value pair is given, this command returns a tuple containing the current size setting of the given column. When option-value pairs are given, the corresponding options of the size setting of the given column are changed. Options may be one of the following: pad0 pixels Specifies the paddings to the left of a column. pad1 pixels Specifies the paddings to the right of a column. size val Specifies the width of a column. Val may be: "auto" -- the width of the column is set to the width of the widest cell in the column; a valid Tk screen distance unit; or a real number following by the word chars (e.g. 3.4chars) that sets the width of the column to the given number of characters.""" return self.tk.splitlist(self.tk.call(self._w, 'size', 'column', index, *self._options({}, kw))) def size_row(self, index, **kw): """Queries or sets the size of the row given by INDEX. INDEX may be any non-negative integer that gives the position of a given row . INDEX can also be the string "default"; in this case, this command queries or sets the default size of all rows. When no option-value pair is given, this command returns a list con- taining the current size setting of the given row . When option-value pairs are given, the corresponding options of the size setting of the given row are changed. Options may be one of the following: pad0 pixels Specifies the paddings to the top of a row. pad1 pixels Specifies the paddings to the bottom of a row. size val Specifies the height of a row. Val may be: "auto" -- the height of the row is set to the height of the highest cell in the row; a valid Tk screen distance unit; or a real number following by the word chars (e.g. 3.4chars) that sets the height of the row to the given number of characters.""" return self.tk.splitlist(self.tk.call( self, 'size', 'row', index, *self._options({}, kw))) def unset(self, x, y): """Clears the cell at (x, y) by removing its display item.""" self.tk.call(self._w, 'unset', x, y) class ScrolledGrid(Grid): '''Scrolled Grid widgets''' # FIXME: It should inherit -superclass tixScrolledWidget def __init__(self, master=None, cnf={}, **kw): static= [] self.cnf= cnf TixWidget.__init__(self, master, 'tixScrolledGrid', static, cnf, kw) tkinter/colorchooser.py000064400000005144152342670510011310 0ustar00# tk common color chooser dialogue # # this module provides an interface to the native color dialogue # available in Tk 4.2 and newer. # # written by Fredrik Lundh, May 1997 # # fixed initialcolor handling in August 1998 # from tkinter.commondialog import Dialog __all__ = ["Chooser", "askcolor"] class Chooser(Dialog): """Create a dialog for the tk_chooseColor command. Args: master: The master widget for this dialog. If not provided, defaults to options['parent'] (if defined). options: Dictionary of options for the tk_chooseColor call. initialcolor: Specifies the selected color when the dialog is first displayed. This can be a tk color string or a 3-tuple of ints in the range (0, 255) for an RGB triplet. parent: The parent window of the color dialog. The color dialog is displayed on top of this. title: A string for the title of the dialog box. """ command = "tk_chooseColor" def _fixoptions(self): """Ensure initialcolor is a tk color string. Convert initialcolor from a RGB triplet to a color string. """ try: color = self.options["initialcolor"] if isinstance(color, tuple): # Assume an RGB triplet. self.options["initialcolor"] = "#%02x%02x%02x" % color except KeyError: pass def _fixresult(self, widget, result): """Adjust result returned from call to tk_chooseColor. Return both an RGB tuple of ints in the range (0, 255) and the tk color string in the form #rrggbb. """ # Result can be many things: an empty tuple, an empty string, or # a _tkinter.Tcl_Obj, so this somewhat weird check handles that. if not result or not str(result): return None, None # canceled # To simplify application code, the color chooser returns # an RGB tuple together with the Tk color string. r, g, b = widget.winfo_rgb(result) return (r//256, g//256, b//256), str(result) # # convenience stuff def askcolor(color=None, **options): """Display dialog window for selection of a color. Convenience wrapper for the Chooser class. Displays the color chooser dialog with color as the initial value. """ if color: options = options.copy() options["initialcolor"] = color return Chooser(**options).show() # -------------------------------------------------------------------- # test stuff if __name__ == "__main__": print("color", askcolor()) tkinter/font.py000064400000015530152342670510007555 0ustar00# Tkinter font wrapper # # written by Fredrik Lundh, February 1998 # import itertools import tkinter __version__ = "0.9" __all__ = ["NORMAL", "ROMAN", "BOLD", "ITALIC", "nametofont", "Font", "families", "names"] # weight/slant NORMAL = "normal" ROMAN = "roman" BOLD = "bold" ITALIC = "italic" def nametofont(name, root=None): """Given the name of a tk named font, returns a Font representation. """ return Font(name=name, exists=True, root=root) class Font: """Represents a named font. Constructor options are: font -- font specifier (name, system font, or (family, size, style)-tuple) name -- name to use for this font configuration (defaults to a unique name) exists -- does a named font by this name already exist? Creates a new named font if False, points to the existing font if True. Raises _tkinter.TclError if the assertion is false. the following are ignored if font is specified: family -- font 'family', e.g. Courier, Times, Helvetica size -- font size in points weight -- font thickness: NORMAL, BOLD slant -- font slant: ROMAN, ITALIC underline -- font underlining: false (0), true (1) overstrike -- font strikeout: false (0), true (1) """ counter = itertools.count(1) def _set(self, kw): options = [] for k, v in kw.items(): options.append("-"+k) options.append(str(v)) return tuple(options) def _get(self, args): options = [] for k in args: options.append("-"+k) return tuple(options) def _mkdict(self, args): options = {} for i in range(0, len(args), 2): options[args[i][1:]] = args[i+1] return options def __init__(self, root=None, font=None, name=None, exists=False, **options): if root is None: root = tkinter._get_default_root('use font') tk = getattr(root, 'tk', root) if font: # get actual settings corresponding to the given font font = tk.splitlist(tk.call("font", "actual", font)) else: font = self._set(options) if not name: name = "font" + str(next(self.counter)) self.name = name if exists: self.delete_font = False # confirm font exists if self.name not in tk.splitlist(tk.call("font", "names")): raise tkinter._tkinter.TclError( "named font %s does not already exist" % (self.name,)) # if font config info supplied, apply it if font: tk.call("font", "configure", self.name, *font) else: # create new font (raises TclError if the font exists) tk.call("font", "create", self.name, *font) self.delete_font = True self._tk = tk self._split = tk.splitlist self._call = tk.call def __str__(self): return self.name def __repr__(self): return f"<{self.__class__.__module__}.{self.__class__.__qualname__}" \ f" object {self.name!r}>" def __eq__(self, other): if not isinstance(other, Font): return NotImplemented return self.name == other.name and self._tk == other._tk def __getitem__(self, key): return self.cget(key) def __setitem__(self, key, value): self.configure(**{key: value}) def __del__(self): try: if self.delete_font: self._call("font", "delete", self.name) except Exception: pass def copy(self): "Return a distinct copy of the current font" return Font(self._tk, **self.actual()) def actual(self, option=None, displayof=None): "Return actual font attributes" args = () if displayof: args = ('-displayof', displayof) if option: args = args + ('-' + option, ) return self._call("font", "actual", self.name, *args) else: return self._mkdict( self._split(self._call("font", "actual", self.name, *args))) def cget(self, option): "Get font attribute" return self._call("font", "config", self.name, "-"+option) def config(self, **options): "Modify font attributes" if options: self._call("font", "config", self.name, *self._set(options)) else: return self._mkdict( self._split(self._call("font", "config", self.name))) configure = config def measure(self, text, displayof=None): "Return text width" args = (text,) if displayof: args = ('-displayof', displayof, text) return self._tk.getint(self._call("font", "measure", self.name, *args)) def metrics(self, *options, **kw): """Return font metrics. For best performance, create a dummy widget using this font before calling this method.""" args = () displayof = kw.pop('displayof', None) if displayof: args = ('-displayof', displayof) if options: args = args + self._get(options) return self._tk.getint( self._call("font", "metrics", self.name, *args)) else: res = self._split(self._call("font", "metrics", self.name, *args)) options = {} for i in range(0, len(res), 2): options[res[i][1:]] = self._tk.getint(res[i+1]) return options def families(root=None, displayof=None): "Get font families (as a tuple)" if root is None: root = tkinter._get_default_root('use font.families()') args = () if displayof: args = ('-displayof', displayof) return root.tk.splitlist(root.tk.call("font", "families", *args)) def names(root=None): "Get names of defined fonts (as a tuple)" if root is None: root = tkinter._get_default_root('use font.names()') return root.tk.splitlist(root.tk.call("font", "names")) # -------------------------------------------------------------------- # test stuff if __name__ == "__main__": root = tkinter.Tk() # create a font f = Font(family="times", size=30, weight=NORMAL) print(f.actual()) print(f.actual("family")) print(f.actual("weight")) print(f.config()) print(f.cget("family")) print(f.cget("weight")) print(names()) print(f.measure("hello"), f.metrics("linespace")) print(f.metrics(displayof=root)) f = Font(font=("Courier", 20, "bold")) print(f.measure("hello"), f.metrics("linespace", displayof=root)) w = tkinter.Label(root, text="Hello, world", font=f) w.pack() w = tkinter.Button(root, text="Quit!", command=root.destroy) w.pack() fb = Font(font=w["font"]).copy() fb.config(weight=BOLD) w.config(font=fb) tkinter.mainloop() tkinter/__init__.py000064400000522160152342670510010350 0ustar00"""Wrapper functions for Tcl/Tk. Tkinter provides classes which allow the display, positioning and control of widgets. Toplevel widgets are Tk and Toplevel. Other widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox LabelFrame and PanedWindow. Properties of the widgets are specified with keyword arguments. Keyword arguments have the same name as the corresponding resource under Tk. Widgets are positioned with one of the geometry managers Place, Pack or Grid. These managers can be called with methods place, pack, grid available in every Widget. Actions are bound to events by resources (e.g. keyword argument command) or with the method bind. Example (Hello, World): import tkinter from tkinter.constants import * tk = tkinter.Tk() frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2) frame.pack(fill=BOTH,expand=1) label = tkinter.Label(frame, text="Hello, World") label.pack(fill=X, expand=1) button = tkinter.Button(frame,text="Exit",command=tk.destroy) button.pack(side=BOTTOM) tk.mainloop() """ import collections import enum import sys import types import _tkinter # If this fails your Python may not be configured for Tk TclError = _tkinter.TclError from tkinter.constants import * import re wantobjects = 1 _debug = False # set to True to print executed Tcl/Tk commands TkVersion = float(_tkinter.TK_VERSION) TclVersion = float(_tkinter.TCL_VERSION) READABLE = _tkinter.READABLE WRITABLE = _tkinter.WRITABLE EXCEPTION = _tkinter.EXCEPTION _magic_re = re.compile(r'([\\{}])') _space_re = re.compile(r'([\s])', re.ASCII) def _join(value): """Internal function.""" return ' '.join(map(_stringify, value)) def _stringify(value): """Internal function.""" if isinstance(value, (list, tuple)): if len(value) == 1: value = _stringify(value[0]) if _magic_re.search(value): value = '{%s}' % value else: value = '{%s}' % _join(value) else: if isinstance(value, bytes): value = str(value, 'latin1') else: value = str(value) if not value: value = '{}' elif _magic_re.search(value): # add '\' before special characters and spaces value = _magic_re.sub(r'\\\1', value) value = value.replace('\n', r'\n') value = _space_re.sub(r'\\\1', value) if value[0] == '"': value = '\\' + value elif value[0] == '"' or _space_re.search(value): value = '{%s}' % value return value def _flatten(seq): """Internal function.""" res = () for item in seq: if isinstance(item, (tuple, list)): res = res + _flatten(item) elif item is not None: res = res + (item,) return res try: _flatten = _tkinter._flatten except AttributeError: pass def _cnfmerge(cnfs): """Internal function.""" if isinstance(cnfs, dict): return cnfs elif isinstance(cnfs, (type(None), str)): return cnfs else: cnf = {} for c in _flatten(cnfs): try: cnf.update(c) except (AttributeError, TypeError) as msg: print("_cnfmerge: fallback due to:", msg) for k, v in c.items(): cnf[k] = v return cnf try: _cnfmerge = _tkinter._cnfmerge except AttributeError: pass def _splitdict(tk, v, cut_minus=True, conv=None): """Return a properly formatted dict built from Tcl list pairs. If cut_minus is True, the supposed '-' prefix will be removed from keys. If conv is specified, it is used to convert values. Tcl list is expected to contain an even number of elements. """ t = tk.splitlist(v) if len(t) % 2: raise RuntimeError('Tcl list representing a dict is expected ' 'to contain an even number of elements') it = iter(t) dict = {} for key, value in zip(it, it): key = str(key) if cut_minus and key[0] == '-': key = key[1:] if conv: value = conv(value) dict[key] = value return dict class _VersionInfoType(collections.namedtuple('_VersionInfoType', ('major', 'minor', 'micro', 'releaselevel', 'serial'))): def __str__(self): if self.releaselevel == 'final': return f'{self.major}.{self.minor}.{self.micro}' else: return f'{self.major}.{self.minor}{self.releaselevel[0]}{self.serial}' def _parse_version(version): import re m = re.fullmatch(r'(\d+)\.(\d+)([ab.])(\d+)', version) major, minor, releaselevel, serial = m.groups() major, minor, serial = int(major), int(minor), int(serial) if releaselevel == '.': micro = serial serial = 0 releaselevel = 'final' else: micro = 0 releaselevel = {'a': 'alpha', 'b': 'beta'}[releaselevel] return _VersionInfoType(major, minor, micro, releaselevel, serial) @enum._simple_enum(enum.StrEnum) class EventType: KeyPress = '2' Key = KeyPress KeyRelease = '3' ButtonPress = '4' Button = ButtonPress ButtonRelease = '5' Motion = '6' Enter = '7' Leave = '8' FocusIn = '9' FocusOut = '10' Keymap = '11' # undocumented Expose = '12' GraphicsExpose = '13' # undocumented NoExpose = '14' # undocumented Visibility = '15' Create = '16' Destroy = '17' Unmap = '18' Map = '19' MapRequest = '20' Reparent = '21' Configure = '22' ConfigureRequest = '23' Gravity = '24' ResizeRequest = '25' Circulate = '26' CirculateRequest = '27' Property = '28' SelectionClear = '29' # undocumented SelectionRequest = '30' # undocumented Selection = '31' # undocumented Colormap = '32' ClientMessage = '33' # undocumented Mapping = '34' # undocumented VirtualEvent = '35' # undocumented Activate = '36' Deactivate = '37' MouseWheel = '38' class Event: """Container for the properties of an event. Instances of this type are generated if one of the following events occurs: KeyPress, KeyRelease - for keyboard events ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, Colormap, Gravity, Reparent, Property, Destroy, Activate, Deactivate - for window events. If a callback function for one of these events is registered using bind, bind_all, bind_class, or tag_bind, the callback is called with an Event as first argument. It will have the following attributes (in braces are the event types for which the attribute is valid): serial - serial number of event num - mouse button pressed (ButtonPress, ButtonRelease) focus - whether the window has the focus (Enter, Leave) height - height of the exposed window (Configure, Expose) width - width of the exposed window (Configure, Expose) keycode - keycode of the pressed key (KeyPress, KeyRelease) state - state of the event as a number (ButtonPress, ButtonRelease, Enter, KeyPress, KeyRelease, Leave, Motion) state - state as a string (Visibility) time - when the event occurred x - x-position of the mouse y - y-position of the mouse x_root - x-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) y_root - y-position of the mouse on the screen (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) char - pressed character (KeyPress, KeyRelease) send_event - see X/Windows documentation keysym - keysym of the event as a string (KeyPress, KeyRelease) keysym_num - keysym of the event as a number (KeyPress, KeyRelease) type - type of the event as a number widget - widget in which the event occurred delta - delta of wheel movement (MouseWheel) """ def __repr__(self): attrs = {k: v for k, v in self.__dict__.items() if v != '??'} if not self.char: del attrs['char'] elif self.char != '??': attrs['char'] = repr(self.char) if not getattr(self, 'send_event', True): del attrs['send_event'] if self.state == 0: del attrs['state'] elif isinstance(self.state, int): state = self.state mods = ('Shift', 'Lock', 'Control', 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Button1', 'Button2', 'Button3', 'Button4', 'Button5') s = [] for i, n in enumerate(mods): if state & (1 << i): s.append(n) state = state & ~((1<< len(mods)) - 1) if state or not s: s.append(hex(state)) attrs['state'] = '|'.join(s) if self.delta == 0: del attrs['delta'] # widget usually is known # serial and time are not very interesting # keysym_num duplicates keysym # x_root and y_root mostly duplicate x and y keys = ('send_event', 'state', 'keysym', 'keycode', 'char', 'num', 'delta', 'focus', 'x', 'y', 'width', 'height') return '<%s event%s>' % ( getattr(self.type, 'name', self.type), ''.join(' %s=%s' % (k, attrs[k]) for k in keys if k in attrs) ) _support_default_root = True _default_root = None def NoDefaultRoot(): """Inhibit setting of default root window. Call this function to inhibit that the first instance of Tk is used for windows without an explicit parent window. """ global _support_default_root, _default_root _support_default_root = False # Delete, so any use of _default_root will immediately raise an exception. # Rebind before deletion, so repeated calls will not fail. _default_root = None del _default_root def _get_default_root(what=None): if not _support_default_root: raise RuntimeError("No master specified and tkinter is " "configured to not support default root") if _default_root is None: if what: raise RuntimeError(f"Too early to {what}: no default root window") root = Tk() assert _default_root is root return _default_root def _get_temp_root(): global _support_default_root if not _support_default_root: raise RuntimeError("No master specified and tkinter is " "configured to not support default root") root = _default_root if root is None: assert _support_default_root _support_default_root = False root = Tk() _support_default_root = True assert _default_root is None root.withdraw() root._temporary = True return root def _destroy_temp_root(master): if getattr(master, '_temporary', False): try: master.destroy() except TclError: pass def _tkerror(err): """Internal function.""" pass def _exit(code=0): """Internal function. Calling it will raise the exception SystemExit.""" try: code = int(code) except ValueError: pass raise SystemExit(code) _varnum = 0 class Variable: """Class to define value holders for e.g. buttons. Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations that constrain the type of the value returned from get().""" _default = "" _tk = None _tclCommands = None def __init__(self, master=None, value=None, name=None): """Construct a variable MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ # check for type of NAME parameter to override weird error message # raised from Modules/_tkinter.c:SetVar like: # TypeError: setvar() takes exactly 3 arguments (2 given) if name is not None and not isinstance(name, str): raise TypeError("name must be a string") global _varnum if master is None: master = _get_default_root('create variable') self._root = master._root() self._tk = master.tk if name: self._name = name else: self._name = 'PY_VAR' + repr(_varnum) _varnum += 1 if value is not None: self.initialize(value) elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)): self.initialize(self._default) def __del__(self): """Unset the variable in Tcl.""" if self._tk is None: return if self._tk.getboolean(self._tk.call("info", "exists", self._name)): self._tk.globalunsetvar(self._name) if self._tclCommands is not None: for name in self._tclCommands: self._tk.deletecommand(name) self._tclCommands = None def __str__(self): """Return the name of the variable in Tcl.""" return self._name def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, value) initialize = set def get(self): """Return value of variable.""" return self._tk.globalgetvar(self._name) def _register(self, callback): f = CallWrapper(callback, None, self._root).__call__ cbname = repr(id(f)) try: callback = callback.__func__ except AttributeError: pass try: cbname = cbname + callback.__name__ except AttributeError: pass self._tk.createcommand(cbname, f) if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(cbname) return cbname def trace_add(self, mode, callback): """Define a trace callback for the variable. Mode is one of "read", "write", "unset", or a list or tuple of such strings. Callback must be a function which is called when the variable is read, written or unset. Return the name of the callback. """ cbname = self._register(callback) self._tk.call('trace', 'add', 'variable', self._name, mode, (cbname,)) return cbname def trace_remove(self, mode, cbname): """Delete the trace callback for a variable. Mode is one of "read", "write", "unset" or a list or tuple of such strings. Must be same as were specified in trace_add(). cbname is the name of the callback returned from trace_add(). """ self._tk.call('trace', 'remove', 'variable', self._name, mode, cbname) for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_info(self): """Return all trace callback information.""" splitlist = self._tk.splitlist return [(splitlist(k), v) for k, v in map(splitlist, splitlist(self._tk.call('trace', 'info', 'variable', self._name)))] def trace_variable(self, mode, callback): """Define a trace callback for the variable. MODE is one of "r", "w", "u" for read, write, undefine. CALLBACK must be a function which is called when the variable is read, written or undefined. Return the name of the callback. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_add() instead. """ # TODO: Add deprecation warning cbname = self._register(callback) self._tk.call("trace", "variable", self._name, mode, cbname) return cbname trace = trace_variable def trace_vdelete(self, mode, cbname): """Delete the trace callback for a variable. MODE is one of "r", "w", "u" for read, write, undefine. CBNAME is the name of the callback returned from trace_variable or trace. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_remove() instead. """ # TODO: Add deprecation warning self._tk.call("trace", "vdelete", self._name, mode, cbname) cbname = self._tk.splitlist(cbname)[0] for m, ca in self.trace_info(): if self._tk.splitlist(ca)[0] == cbname: break else: self._tk.deletecommand(cbname) try: self._tclCommands.remove(cbname) except ValueError: pass def trace_vinfo(self): """Return all trace callback information. This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_info() instead. """ # TODO: Add deprecation warning return [self._tk.splitlist(x) for x in self._tk.splitlist( self._tk.call("trace", "vinfo", self._name))] def __eq__(self, other): if not isinstance(other, Variable): return NotImplemented return (self._name == other._name and self.__class__.__name__ == other.__class__.__name__ and self._tk == other._tk) class StringVar(Variable): """Value holder for strings variables.""" _default = "" def __init__(self, master=None, value=None, name=None): """Construct a string variable. MASTER can be given as master widget. VALUE is an optional value (defaults to "") NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return value of variable as string.""" value = self._tk.globalgetvar(self._name) if isinstance(value, str): return value return str(value) class IntVar(Variable): """Value holder for integer variables.""" _default = 0 def __init__(self, master=None, value=None, name=None): """Construct an integer variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as an integer.""" value = self._tk.globalgetvar(self._name) try: return self._tk.getint(value) except (TypeError, TclError): return int(self._tk.getdouble(value)) class DoubleVar(Variable): """Value holder for float variables.""" _default = 0.0 def __init__(self, master=None, value=None, name=None): """Construct a float variable. MASTER can be given as master widget. VALUE is an optional value (defaults to 0.0) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def get(self): """Return the value of the variable as a float.""" return self._tk.getdouble(self._tk.globalgetvar(self._name)) class BooleanVar(Variable): """Value holder for boolean variables.""" _default = False def __init__(self, master=None, value=None, name=None): """Construct a boolean variable. MASTER can be given as master widget. VALUE is an optional value (defaults to False) NAME is an optional Tcl name (defaults to PY_VARnum). If NAME matches an existing variable and VALUE is omitted then the existing value is retained. """ Variable.__init__(self, master, value, name) def set(self, value): """Set the variable to VALUE.""" return self._tk.globalsetvar(self._name, self._tk.getboolean(value)) initialize = set def get(self): """Return the value of the variable as a bool.""" try: return self._tk.getboolean(self._tk.globalgetvar(self._name)) except TclError: raise ValueError("invalid literal for getboolean()") def mainloop(n=0): """Run the main loop of Tcl.""" _get_default_root('run the main loop').tk.mainloop(n) getint = int getdouble = float def getboolean(s): """Convert Tcl object to True or False.""" try: return _get_default_root('use getboolean()').tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") # Methods defined on both toplevel and interior widgets class Misc: """Internal class. Base class which defines methods common for interior widgets.""" # used for generating child widget names _last_child_ids = None # XXX font command? _tclCommands = None def destroy(self): """Internal function. Delete all Tcl commands created for this widget in the Tcl interpreter.""" if self._tclCommands is not None: for name in self._tclCommands: self.tk.deletecommand(name) self._tclCommands = None def deletecommand(self, name): """Internal function. Delete the Tcl command provided in NAME.""" self.tk.deletecommand(name) try: self._tclCommands.remove(name) except ValueError: pass def tk_strictMotif(self, boolean=None): """Set Tcl internal variable, whether the look and feel should adhere to Motif. A parameter of 1 means adhere to Motif (e.g. no color change if mouse passes over slider). Returns the set value.""" return self.tk.getboolean(self.tk.call( 'set', 'tk_strictMotif', boolean)) def tk_bisque(self): """Change the color scheme to light brown as used in Tk 3.6 and before.""" self.tk.call('tk_bisque') def tk_setPalette(self, *args, **kw): """Set a new color scheme for all widget elements. A single color as argument will cause that all colors of Tk widget elements are derived from this. Alternatively several keyword parameters and its associated colors can be given. The following keywords are valid: activeBackground, foreground, selectColor, activeForeground, highlightBackground, selectBackground, background, highlightColor, selectForeground, disabledForeground, insertBackground, troughColor.""" self.tk.call(('tk_setPalette',) + _flatten(args) + _flatten(list(kw.items()))) def wait_variable(self, name='PY_VAR'): """Wait until the variable is modified. A parameter of type IntVar, StringVar, DoubleVar or BooleanVar must be given.""" self.tk.call('tkwait', 'variable', name) waitvar = wait_variable # XXX b/w compat def wait_window(self, window=None): """Wait until a WIDGET is destroyed. If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'window', window._w) def wait_visibility(self, window=None): """Wait until the visibility of a WIDGET changes (e.g. it appears). If no parameter is given self is used.""" if window is None: window = self self.tk.call('tkwait', 'visibility', window._w) def setvar(self, name='PY_VAR', value='1'): """Set Tcl variable NAME to VALUE.""" self.tk.setvar(name, value) def getvar(self, name='PY_VAR'): """Return value of Tcl variable NAME.""" return self.tk.getvar(name) def getint(self, s): try: return self.tk.getint(s) except TclError as exc: raise ValueError(str(exc)) def getdouble(self, s): try: return self.tk.getdouble(s) except TclError as exc: raise ValueError(str(exc)) def getboolean(self, s): """Return a boolean value for Tcl boolean values true and false given as parameter.""" try: return self.tk.getboolean(s) except TclError: raise ValueError("invalid literal for getboolean()") def focus_set(self): """Direct input focus to this widget. If the application currently does not have the focus this widget will get the focus if the application gets the focus through the window manager.""" self.tk.call('focus', self._w) focus = focus_set # XXX b/w compat? def focus_force(self): """Direct input focus to this widget even if the application does not have the focus. Use with caution!""" self.tk.call('focus', '-force', self._w) def focus_get(self): """Return the widget which has currently the focus in the application. Use focus_displayof to allow working with several displays. Return None if application does not have the focus.""" name = self.tk.call('focus') if name == 'none' or not name: return None return self._nametowidget(name) def focus_displayof(self): """Return the widget which has currently the focus on the display where this widget is located. Return None if the application does not have the focus.""" name = self.tk.call('focus', '-displayof', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def focus_lastfor(self): """Return the widget which would have the focus if top level for this widget gets the focus from the window manager.""" name = self.tk.call('focus', '-lastfor', self._w) if name == 'none' or not name: return None return self._nametowidget(name) def tk_focusFollowsMouse(self): """The widget under mouse will get automatically focus. Can not be disabled easily.""" self.tk.call('tk_focusFollowsMouse') def tk_focusNext(self): """Return the next widget in the focus order which follows widget which has currently the focus. The focus order first goes to the next child, then to the children of the child recursively and then to the next sibling which is higher in the stacking order. A widget is omitted if it has the takefocus resource set to 0.""" name = self.tk.call('tk_focusNext', self._w) if not name: return None return self._nametowidget(name) def tk_focusPrev(self): """Return previous widget in the focus order. See tk_focusNext for details.""" name = self.tk.call('tk_focusPrev', self._w) if not name: return None return self._nametowidget(name) def after(self, ms, func=None, *args): """Call function once after given time. MS specifies the time in milliseconds. FUNC gives the function which shall be called. Additional parameters are given as parameters to the function call. Return identifier to cancel scheduling with after_cancel.""" if func is None: # I'd rather use time.sleep(ms*0.001) self.tk.call('after', ms) return None else: def callit(): try: func(*args) finally: try: self.deletecommand(name) except TclError: pass try: callit.__name__ = func.__name__ except AttributeError: # Required for callable classes (bpo-44404) callit.__name__ = type(func).__name__ name = self._register(callit) return self.tk.call('after', ms, name) def after_idle(self, func, *args): """Call FUNC once if the Tcl main loop has no event to process. Return an identifier to cancel the scheduling with after_cancel.""" return self.after('idle', func, *args) def after_cancel(self, id): """Cancel scheduling of function identified with ID. Identifier returned by after or after_idle must be given as first parameter. """ if not id: raise ValueError('id must be a valid identifier returned from ' 'after or after_idle') try: data = self.tk.call('after', 'info', id) script = self.tk.splitlist(data)[0] self.deletecommand(script) except TclError: pass self.tk.call('after', 'cancel', id) def bell(self, displayof=0): """Ring a display's bell.""" self.tk.call(('bell',) + self._displayof(displayof)) # Clipboard handling: def clipboard_get(self, **kw): """Retrieve data from the clipboard on window's display. The window keyword defaults to the root window of the Tkinter application. The type keyword specifies the form in which the data is to be returned and should be an atom name such as STRING or FILE_NAME. Type defaults to STRING, except on X11, where the default is to try UTF8_STRING and fall back to STRING. This command is equivalent to: selection_get(CLIPBOARD) """ if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('clipboard', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('clipboard', 'get') + self._options(kw)) def clipboard_clear(self, **kw): """Clear the data in the Tk clipboard. A widget specified for the optional displayof keyword argument specifies the target display.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'clear') + self._options(kw)) def clipboard_append(self, string, **kw): """Append STRING to the Tk clipboard. A widget specified at the optional displayof keyword argument specifies the target display. The clipboard can be retrieved with selection_get.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('clipboard', 'append') + self._options(kw) + ('--', string)) # XXX grab current w/o window argument def grab_current(self): """Return widget which has currently the grab in this application or None.""" name = self.tk.call('grab', 'current', self._w) if not name: return None return self._nametowidget(name) def grab_release(self): """Release grab for this widget if currently set.""" self.tk.call('grab', 'release', self._w) def grab_set(self): """Set grab for this widget. A grab directs all events to this and descendant widgets in the application.""" self.tk.call('grab', 'set', self._w) def grab_set_global(self): """Set global grab for this widget. A global grab directs all events to this and descendant widgets on the display. Use with caution - other applications do not get events anymore.""" self.tk.call('grab', 'set', '-global', self._w) def grab_status(self): """Return None, "local" or "global" if this widget has no, a local or a global grab.""" status = self.tk.call('grab', 'status', self._w) if status == 'none': status = None return status def option_add(self, pattern, value, priority = None): """Set a VALUE (second parameter) for an option PATTERN (first parameter). An optional third parameter gives the numeric priority (defaults to 80).""" self.tk.call('option', 'add', pattern, value, priority) def option_clear(self): """Clear the option database. It will be reloaded if option_add is called.""" self.tk.call('option', 'clear') def option_get(self, name, className): """Return the value for an option NAME for this widget with CLASSNAME. Values with higher priority override lower values.""" return self.tk.call('option', 'get', self._w, name, className) def option_readfile(self, fileName, priority = None): """Read file FILENAME into the option database. An optional second parameter gives the numeric priority.""" self.tk.call('option', 'readfile', fileName, priority) def selection_clear(self, **kw): """Clear the current X selection.""" if 'displayof' not in kw: kw['displayof'] = self._w self.tk.call(('selection', 'clear') + self._options(kw)) def selection_get(self, **kw): """Return the contents of the current X selection. A keyword parameter selection specifies the name of the selection and defaults to PRIMARY. A keyword parameter displayof specifies a widget on the display to use. A keyword parameter type specifies the form of data to be fetched, defaulting to STRING except on X11, where UTF8_STRING is tried before STRING.""" if 'displayof' not in kw: kw['displayof'] = self._w if 'type' not in kw and self._windowingsystem == 'x11': try: kw['type'] = 'UTF8_STRING' return self.tk.call(('selection', 'get') + self._options(kw)) except TclError: del kw['type'] return self.tk.call(('selection', 'get') + self._options(kw)) def selection_handle(self, command, **kw): """Specify a function COMMAND to call if the X selection owned by this widget is queried by another application. This function must return the contents of the selection. The function will be called with the arguments OFFSET and LENGTH which allows the chunking of very long selections. The following keyword parameters can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" name = self._register(command) self.tk.call(('selection', 'handle') + self._options(kw) + (self._w, name)) def selection_own(self, **kw): """Become owner of X selection. A keyword parameter selection specifies the name of the selection (default PRIMARY).""" self.tk.call(('selection', 'own') + self._options(kw) + (self._w,)) def selection_own_get(self, **kw): """Return owner of X selection. The following keyword parameter can be provided: selection - name of the selection (default PRIMARY), type - type of the selection (e.g. STRING, FILE_NAME).""" if 'displayof' not in kw: kw['displayof'] = self._w name = self.tk.call(('selection', 'own') + self._options(kw)) if not name: return None return self._nametowidget(name) def send(self, interp, cmd, *args): """Send Tcl command CMD to different interpreter INTERP to be executed.""" return self.tk.call(('send', interp, cmd) + args) def lower(self, belowThis=None): """Lower this widget in the stacking order.""" self.tk.call('lower', self._w, belowThis) def tkraise(self, aboveThis=None): """Raise this widget in the stacking order.""" self.tk.call('raise', self._w, aboveThis) lift = tkraise def info_patchlevel(self): """Returns the exact version of the Tcl library.""" patchlevel = self.tk.call('info', 'patchlevel') return _parse_version(patchlevel) def winfo_atom(self, name, displayof=0): """Return integer which represents atom NAME.""" args = ('winfo', 'atom') + self._displayof(displayof) + (name,) return self.tk.getint(self.tk.call(args)) def winfo_atomname(self, id, displayof=0): """Return name of atom with identifier ID.""" args = ('winfo', 'atomname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_cells(self): """Return number of cells in the colormap for this widget.""" return self.tk.getint( self.tk.call('winfo', 'cells', self._w)) def winfo_children(self): """Return a list of all widgets which are children of this widget.""" result = [] for child in self.tk.splitlist( self.tk.call('winfo', 'children', self._w)): try: # Tcl sometimes returns extra windows, e.g. for # menus; those need to be skipped result.append(self._nametowidget(child)) except KeyError: pass return result def winfo_class(self): """Return window class name of this widget.""" return self.tk.call('winfo', 'class', self._w) def winfo_colormapfull(self): """Return True if at the last color request the colormap was full.""" return self.tk.getboolean( self.tk.call('winfo', 'colormapfull', self._w)) def winfo_containing(self, rootX, rootY, displayof=0): """Return the widget which is at the root coordinates ROOTX, ROOTY.""" args = ('winfo', 'containing') \ + self._displayof(displayof) + (rootX, rootY) name = self.tk.call(args) if not name: return None return self._nametowidget(name) def winfo_depth(self): """Return the number of bits per pixel.""" return self.tk.getint(self.tk.call('winfo', 'depth', self._w)) def winfo_exists(self): """Return true if this widget exists.""" return self.tk.getint( self.tk.call('winfo', 'exists', self._w)) def winfo_fpixels(self, number): """Return the number of pixels for the given distance NUMBER (e.g. "3c") as float.""" return self.tk.getdouble(self.tk.call( 'winfo', 'fpixels', self._w, number)) def winfo_geometry(self): """Return geometry string for this widget in the form "widthxheight+X+Y".""" return self.tk.call('winfo', 'geometry', self._w) def winfo_height(self): """Return height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'height', self._w)) def winfo_id(self): """Return identifier ID for this widget.""" return int(self.tk.call('winfo', 'id', self._w), 0) def winfo_interps(self, displayof=0): """Return the name of all Tcl interpreters for this display.""" args = ('winfo', 'interps') + self._displayof(displayof) return self.tk.splitlist(self.tk.call(args)) def winfo_ismapped(self): """Return true if this widget is mapped.""" return self.tk.getint( self.tk.call('winfo', 'ismapped', self._w)) def winfo_manager(self): """Return the window manager name for this widget.""" return self.tk.call('winfo', 'manager', self._w) def winfo_name(self): """Return the name of this widget.""" return self.tk.call('winfo', 'name', self._w) def winfo_parent(self): """Return the name of the parent of this widget.""" return self.tk.call('winfo', 'parent', self._w) def winfo_pathname(self, id, displayof=0): """Return the pathname of the widget given by ID.""" if isinstance(id, int): id = hex(id) args = ('winfo', 'pathname') \ + self._displayof(displayof) + (id,) return self.tk.call(args) def winfo_pixels(self, number): """Rounded integer value of winfo_fpixels.""" return self.tk.getint( self.tk.call('winfo', 'pixels', self._w, number)) def winfo_pointerx(self): """Return the x coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointerx', self._w)) def winfo_pointerxy(self): """Return a tuple of x and y coordinates of the pointer on the root window.""" return self._getints( self.tk.call('winfo', 'pointerxy', self._w)) def winfo_pointery(self): """Return the y coordinate of the pointer on the root window.""" return self.tk.getint( self.tk.call('winfo', 'pointery', self._w)) def winfo_reqheight(self): """Return requested height of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqheight', self._w)) def winfo_reqwidth(self): """Return requested width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'reqwidth', self._w)) def winfo_rgb(self, color): """Return a tuple of integer RGB values in range(65536) for color in this widget.""" return self._getints( self.tk.call('winfo', 'rgb', self._w, color)) def winfo_rootx(self): """Return x coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rootx', self._w)) def winfo_rooty(self): """Return y coordinate of upper left corner of this widget on the root window.""" return self.tk.getint( self.tk.call('winfo', 'rooty', self._w)) def winfo_screen(self): """Return the screen name of this widget.""" return self.tk.call('winfo', 'screen', self._w) def winfo_screencells(self): """Return the number of the cells in the colormap of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screencells', self._w)) def winfo_screendepth(self): """Return the number of bits per pixel of the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'screendepth', self._w)) def winfo_screenheight(self): """Return the number of pixels of the height of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenheight', self._w)) def winfo_screenmmheight(self): """Return the number of pixels of the height of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmheight', self._w)) def winfo_screenmmwidth(self): """Return the number of pixels of the width of the screen of this widget in mm.""" return self.tk.getint( self.tk.call('winfo', 'screenmmwidth', self._w)) def winfo_screenvisual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the default colormodel of this screen.""" return self.tk.call('winfo', 'screenvisual', self._w) def winfo_screenwidth(self): """Return the number of pixels of the width of the screen of this widget in pixel.""" return self.tk.getint( self.tk.call('winfo', 'screenwidth', self._w)) def winfo_server(self): """Return information of the X-Server of the screen of this widget in the form "XmajorRminor vendor vendorVersion".""" return self.tk.call('winfo', 'server', self._w) def winfo_toplevel(self): """Return the toplevel widget of this widget.""" return self._nametowidget(self.tk.call( 'winfo', 'toplevel', self._w)) def winfo_viewable(self): """Return true if the widget and all its higher ancestors are mapped.""" return self.tk.getint( self.tk.call('winfo', 'viewable', self._w)) def winfo_visual(self): """Return one of the strings directcolor, grayscale, pseudocolor, staticcolor, staticgray, or truecolor for the colormodel of this widget.""" return self.tk.call('winfo', 'visual', self._w) def winfo_visualid(self): """Return the X identifier for the visual for this widget.""" return self.tk.call('winfo', 'visualid', self._w) def winfo_visualsavailable(self, includeids=False): """Return a list of all visuals available for the screen of this widget. Each item in the list consists of a visual name (see winfo_visual), a depth and if includeids is true is given also the X identifier.""" data = self.tk.call('winfo', 'visualsavailable', self._w, 'includeids' if includeids else None) data = [self.tk.splitlist(x) for x in self.tk.splitlist(data)] return [self.__winfo_parseitem(x) for x in data] def __winfo_parseitem(self, t): """Internal function.""" return t[:1] + tuple(map(self.__winfo_getint, t[1:])) def __winfo_getint(self, x): """Internal function.""" return int(x, 0) def winfo_vrootheight(self): """Return the height of the virtual root window associated with this widget in pixels. If there is no virtual root window return the height of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootheight', self._w)) def winfo_vrootwidth(self): """Return the width of the virtual root window associated with this widget in pixel. If there is no virtual root window return the width of the screen.""" return self.tk.getint( self.tk.call('winfo', 'vrootwidth', self._w)) def winfo_vrootx(self): """Return the x offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrootx', self._w)) def winfo_vrooty(self): """Return the y offset of the virtual root relative to the root window of the screen of this widget.""" return self.tk.getint( self.tk.call('winfo', 'vrooty', self._w)) def winfo_width(self): """Return the width of this widget.""" return self.tk.getint( self.tk.call('winfo', 'width', self._w)) def winfo_x(self): """Return the x coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'x', self._w)) def winfo_y(self): """Return the y coordinate of the upper left corner of this widget in the parent.""" return self.tk.getint( self.tk.call('winfo', 'y', self._w)) def update(self): """Enter event loop until all pending events have been processed by Tcl.""" self.tk.call('update') def update_idletasks(self): """Enter event loop until all idle callbacks have been called. This will update the display of windows but not process events caused by the user.""" self.tk.call('update', 'idletasks') def bindtags(self, tagList=None): """Set or get the list of bindtags for this widget. With no argument return the list of all bindtags associated with this widget. With a list of strings as argument the bindtags are set to this list. The bindtags determine in which order events are processed (see bind).""" if tagList is None: return self.tk.splitlist( self.tk.call('bindtags', self._w)) else: self.tk.call('bindtags', self._w, tagList) def _bind(self, what, sequence, func, add, needcleanup=1): """Internal function.""" if isinstance(func, str): self.tk.call(what + (sequence, func)) elif func: funcid = self._register(func, self._substitute, needcleanup) cmd = ('%sif {"[%s %s]" == "break"} break\n' % (add and '+' or '', funcid, self._subst_format_str)) self.tk.call(what + (sequence, cmd)) return funcid elif sequence: return self.tk.call(what + (sequence,)) else: return self.tk.splitlist(self.tk.call(what)) def bind(self, sequence=None, func=None, add=None): """Bind to this widget at event SEQUENCE a call to function FUNC. SEQUENCE is a string of concatenated event patterns. An event pattern is of the form where MODIFIER is one of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, B3, Alt, Button4, B4, Double, Button5, B5 Triple, Mod1, M1. TYPE is one of Activate, Enter, Map, ButtonPress, Button, Expose, Motion, ButtonRelease FocusIn, MouseWheel, Circulate, FocusOut, Property, Colormap, Gravity Reparent, Configure, KeyPress, Key, Unmap, Deactivate, KeyRelease Visibility, Destroy, Leave and DETAIL is the button number for ButtonPress, ButtonRelease and DETAIL is the Keysym for KeyPress and KeyRelease. Examples are for pressing Control and mouse button 1 or for pressing A and the Alt key (KeyPress can be omitted). An event pattern can also be a virtual event of the form <> where AString can be arbitrary. This event can be generated by event_generate. If events are concatenated they must appear shortly after each other. FUNC will be called if the event sequence occurs with an instance of Event as argument. If the return value of FUNC is "break" no further bound function is invoked. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. Bind will return an identifier to allow deletion of the bound function with unbind without memory leak. If FUNC or SEQUENCE is omitted the bound function or list of bound events are returned.""" return self._bind(('bind', self._w), sequence, func, add) def unbind(self, sequence, funcid=None): """Unbind for this widget the event SEQUENCE. If FUNCID is given, only unbind the function identified with FUNCID and also delete the corresponding Tcl command. Otherwise destroy the current binding for SEQUENCE, leaving SEQUENCE unbound. """ self._unbind(('bind', self._w, sequence), funcid) def _unbind(self, what, funcid=None): if funcid is None: self.tk.call(*what, '') else: lines = self.tk.call(what).split('\n') prefix = f'if {{"[{funcid} ' keep = '\n'.join(line for line in lines if not line.startswith(prefix)) if not keep.strip(): keep = '' self.tk.call(*what, keep) self.deletecommand(funcid) def bind_all(self, sequence=None, func=None, add=None): """Bind to all widgets at an event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._root()._bind(('bind', 'all'), sequence, func, add, True) def unbind_all(self, sequence): """Unbind for all widgets for event SEQUENCE all functions.""" self._root()._unbind(('bind', 'all', sequence)) def bind_class(self, className, sequence=None, func=None, add=None): """Bind to widgets with bindtag CLASSNAME at event SEQUENCE a call of function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._root()._bind(('bind', className), sequence, func, add, True) def unbind_class(self, className, sequence): """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self._root()._unbind(('bind', className, sequence)) def mainloop(self, n=0): """Call the mainloop of Tk.""" self.tk.mainloop(n) def quit(self): """Quit the Tcl interpreter. All widgets will be destroyed.""" self.tk.quit() def _getints(self, string): """Internal function.""" if string: return tuple(map(self.tk.getint, self.tk.splitlist(string))) def _getdoubles(self, string): """Internal function.""" if string: return tuple(map(self.tk.getdouble, self.tk.splitlist(string))) def _getboolean(self, string): """Internal function.""" if string: return self.tk.getboolean(string) def _displayof(self, displayof): """Internal function.""" if displayof: return ('-displayof', displayof) if displayof is None: return ('-displayof', self._w) return () @property def _windowingsystem(self): """Internal function.""" try: return self._root()._windowingsystem_cached except AttributeError: ws = self._root()._windowingsystem_cached = \ self.tk.call('tk', 'windowingsystem') return ws def _options(self, cnf, kw = None): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) else: cnf = _cnfmerge(cnf) res = () for k, v in cnf.items(): if v is not None: if k[-1] == '_': k = k[:-1] if callable(v): v = self._register(v) elif isinstance(v, (tuple, list)): nv = [] for item in v: if isinstance(item, int): nv.append(str(item)) elif isinstance(item, str): nv.append(_stringify(item)) else: break else: v = ' '.join(nv) res = res + ('-'+k, v) return res def nametowidget(self, name): """Return the Tkinter instance of a widget identified by its Tcl name NAME.""" name = str(name).split('.') w = self if not name[0]: w = w._root() name = name[1:] for n in name: if not n: break w = w.children[n] return w _nametowidget = nametowidget def _register(self, func, subst=None, needcleanup=1): """Return a newly created Tcl function. If this function is called, the Python function FUNC will be executed. An optional function SUBST can be given which will be executed before FUNC.""" f = CallWrapper(func, subst, self).__call__ name = repr(id(f)) try: func = func.__func__ except AttributeError: pass try: name = name + func.__name__ except AttributeError: pass self.tk.createcommand(name, f) if needcleanup: if self._tclCommands is None: self._tclCommands = [] self._tclCommands.append(name) return name register = _register def _root(self): """Internal function.""" w = self while w.master is not None: w = w.master return w _subst_format = ('%#', '%b', '%f', '%h', '%k', '%s', '%t', '%w', '%x', '%y', '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') _subst_format_str = " ".join(_subst_format) def _substitute(self, *args): """Internal function.""" if len(args) != len(self._subst_format): return args getboolean = self.tk.getboolean getint = self.tk.getint def getint_event(s): """Tk changed behavior in 8.4.2, returning "??" rather more often.""" try: return getint(s) except (ValueError, TclError): return s nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args # Missing: (a, c, d, m, o, v, B, R) e = Event() # serial field: valid for all events # number of button: ButtonPress and ButtonRelease events only # height field: Configure, ConfigureRequest, Create, # ResizeRequest, and Expose events only # keycode field: KeyPress and KeyRelease events only # time field: "valid for events that contain a time field" # width field: Configure, ConfigureRequest, Create, ResizeRequest, # and Expose events only # x field: "valid for events that contain an x field" # y field: "valid for events that contain a y field" # keysym as decimal: KeyPress and KeyRelease events only # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, # KeyRelease, and Motion events e.serial = getint(nsign) e.num = getint_event(b) try: e.focus = getboolean(f) except TclError: pass e.height = getint_event(h) e.keycode = getint_event(k) e.state = getint_event(s) e.time = getint_event(t) e.width = getint_event(w) e.x = getint_event(x) e.y = getint_event(y) e.char = A try: e.send_event = getboolean(E) except TclError: pass e.keysym = K e.keysym_num = getint_event(N) try: e.type = EventType(T) except ValueError: e.type = T try: e.widget = self._nametowidget(W) except KeyError: e.widget = W e.x_root = getint_event(X) e.y_root = getint_event(Y) try: e.delta = getint(D) except (ValueError, TclError): e.delta = 0 return (e,) def _report_exception(self): """Internal function.""" exc, val, tb = sys.exc_info() root = self._root() root.report_callback_exception(exc, val, tb) def _getconfigure(self, *args): """Call Tcl configure command and return the result as a dict.""" cnf = {} for x in self.tk.splitlist(self.tk.call(*args)): x = self.tk.splitlist(x) cnf[x[0][1:]] = (x[0][1:],) + x[1:] return cnf def _getconfigure1(self, *args): x = self.tk.splitlist(self.tk.call(*args)) return (x[0][1:],) + x[1:] def _configure(self, cmd, cnf, kw): """Internal function.""" if kw: cnf = _cnfmerge((cnf, kw)) elif cnf: cnf = _cnfmerge(cnf) if cnf is None: return self._getconfigure(_flatten((self._w, cmd))) if isinstance(cnf, str): return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) # These used to be defined in Widget: def configure(self, cnf=None, **kw): """Configure resources of a widget. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method keys. """ return self._configure('configure', cnf, kw) config = configure def cget(self, key): """Return the resource value for a KEY given as string.""" return self.tk.call(self._w, 'cget', '-' + key) __getitem__ = cget def __setitem__(self, key, value): self.configure({key: value}) def keys(self): """Return a list of all resource names of this widget.""" splitlist = self.tk.splitlist return [splitlist(x)[0][1:] for x in splitlist(self.tk.call(self._w, 'configure'))] def __str__(self): """Return the window path name of this widget.""" return self._w def __repr__(self): return '<%s.%s object %s>' % ( self.__class__.__module__, self.__class__.__qualname__, self._w) # Pack methods that apply to the master _noarg_ = ['_noarg_'] def pack_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'pack', 'propagate', self._w)) else: self.tk.call('pack', 'propagate', self._w, flag) propagate = pack_propagate def pack_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call('pack', 'slaves', self._w))] slaves = pack_slaves # Place method that applies to the master def place_slaves(self): """Return a list of all slaves of this widget in its packing order.""" return [self._nametowidget(x) for x in self.tk.splitlist( self.tk.call( 'place', 'slaves', self._w))] # Grid methods that apply to the master def grid_anchor(self, anchor=None): # new in Tk 8.5 """The anchor value controls how to place the grid within the master when no row/column has any weight. The default anchor is nw.""" self.tk.call('grid', 'anchor', self._w, anchor) anchor = grid_anchor def grid_bbox(self, column=None, row=None, col2=None, row2=None): """Return a tuple of integer coordinates for the bounding box of this widget controlled by the geometry manager grid. If COLUMN, ROW is given the bounding box applies from the cell with row and column 0 to the specified cell. If COL2 and ROW2 are given the bounding box starts at that cell. The returned integers specify the offset of the upper left corner in the master widget and the width and height. """ args = ('grid', 'bbox', self._w) if column is not None and row is not None: args = args + (column, row) if col2 is not None and row2 is not None: args = args + (col2, row2) return self._getints(self.tk.call(*args)) or None bbox = grid_bbox def _gridconvvalue(self, value): if isinstance(value, (str, _tkinter.Tcl_Obj)): try: svalue = str(value) if not svalue: return None elif '.' in svalue: return self.tk.getdouble(svalue) else: return self.tk.getint(svalue) except (ValueError, TclError): pass return value def _grid_configure(self, command, index, cnf, kw): """Internal function.""" if isinstance(cnf, str) and not kw: if cnf[-1:] == '_': cnf = cnf[:-1] if cnf[:1] != '-': cnf = '-'+cnf options = (cnf,) else: options = self._options(cnf, kw) if not options: return _splitdict( self.tk, self.tk.call('grid', command, self._w, index), conv=self._gridconvvalue) res = self.tk.call( ('grid', command, self._w, index) + options) if len(options) == 1: return self._gridconvvalue(res) def grid_columnconfigure(self, index, cnf={}, **kw): """Configure column INDEX of a grid. Valid resources are minsize (minimum size of the column), weight (how much does additional space propagate to this column) and pad (how much space to let additionally).""" return self._grid_configure('columnconfigure', index, cnf, kw) columnconfigure = grid_columnconfigure def grid_location(self, x, y): """Return a tuple of column and row which identify the cell at which the pixel at position X and Y inside the master widget is located.""" return self._getints( self.tk.call( 'grid', 'location', self._w, x, y)) or None def grid_propagate(self, flag=_noarg_): """Set or get the status for propagation of geometry information. A boolean argument specifies whether the geometry information of the slaves will determine the size of this widget. If no argument is given, the current setting will be returned. """ if flag is Misc._noarg_: return self._getboolean(self.tk.call( 'grid', 'propagate', self._w)) else: self.tk.call('grid', 'propagate', self._w, flag) def grid_rowconfigure(self, index, cnf={}, **kw): """Configure row INDEX of a grid. Valid resources are minsize (minimum size of the row), weight (how much does additional space propagate to this row) and pad (how much space to let additionally).""" return self._grid_configure('rowconfigure', index, cnf, kw) rowconfigure = grid_rowconfigure def grid_size(self): """Return a tuple of the number of column and rows in the grid.""" return self._getints( self.tk.call('grid', 'size', self._w)) or None size = grid_size def grid_slaves(self, row=None, column=None): """Return a list of all slaves of this widget in its packing order.""" args = () if row is not None: args = args + ('-row', row) if column is not None: args = args + ('-column', column) return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call( ('grid', 'slaves', self._w) + args))] # Support for the "event" command, new in Tk 4.2. # By Case Roole. def event_add(self, virtual, *sequences): """Bind a virtual event VIRTUAL (of the form <>) to an event SEQUENCE such that the virtual event is triggered whenever SEQUENCE occurs.""" args = ('event', 'add', virtual) + sequences self.tk.call(args) def event_delete(self, virtual, *sequences): """Unbind a virtual event VIRTUAL from SEQUENCE.""" args = ('event', 'delete', virtual) + sequences self.tk.call(args) def event_generate(self, sequence, **kw): """Generate an event SEQUENCE. Additional keyword arguments specify parameter of the event (e.g. x, y, rootx, rooty).""" args = ('event', 'generate', self._w, sequence) for k, v in kw.items(): args = args + ('-%s' % k, str(v)) self.tk.call(args) def event_info(self, virtual=None): """Return a list of all virtual events or the information about the SEQUENCE bound to the virtual event VIRTUAL.""" return self.tk.splitlist( self.tk.call('event', 'info', virtual)) # Image related commands def image_names(self): """Return a list of all existing image names.""" return self.tk.splitlist(self.tk.call('image', 'names')) def image_types(self): """Return a list of all available image types (e.g. photo bitmap).""" return self.tk.splitlist(self.tk.call('image', 'types')) class CallWrapper: """Internal class. Stores function to call when some user defined Tcl function is called e.g. after an event occurred.""" def __init__(self, func, subst, widget): """Store FUNC, SUBST and WIDGET as members.""" self.func = func self.subst = subst self.widget = widget def __call__(self, *args): """Apply first function SUBST to arguments, than FUNC.""" try: if self.subst: args = self.subst(*args) return self.func(*args) except SystemExit: raise except: self.widget._report_exception() class XView: """Mix-in class for querying and changing the horizontal position of a widget's window.""" def xview(self, *args): """Query and change the horizontal position of the view.""" res = self.tk.call(self._w, 'xview', *args) if not args: return self._getdoubles(res) def xview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total width of the canvas is off-screen to the left.""" self.tk.call(self._w, 'xview', 'moveto', fraction) def xview_scroll(self, number, what): """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'xview', 'scroll', number, what) class YView: """Mix-in class for querying and changing the vertical position of a widget's window.""" def yview(self, *args): """Query and change the vertical position of the view.""" res = self.tk.call(self._w, 'yview', *args) if not args: return self._getdoubles(res) def yview_moveto(self, fraction): """Adjusts the view in the window so that FRACTION of the total height of the canvas is off-screen to the top.""" self.tk.call(self._w, 'yview', 'moveto', fraction) def yview_scroll(self, number, what): """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'yview', 'scroll', number, what) class Wm: """Provides functions for the communication with the window manager.""" def wm_aspect(self, minNumer=None, minDenom=None, maxNumer=None, maxDenom=None): """Instruct the window manager to set the aspect ratio (width/height) of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple of the actual values if no argument is given.""" return self._getints( self.tk.call('wm', 'aspect', self._w, minNumer, minDenom, maxNumer, maxDenom)) aspect = wm_aspect def wm_attributes(self, *args): """This subcommand returns or sets platform specific attributes The first form returns a list of the platform specific flags and their values. The second form returns the value for the specific option. The third form sets one or more of the values. The values are as follows: On Windows, -disabled gets or sets whether the window is in a disabled state. -toolwindow gets or sets the style of the window to toolwindow (as defined in the MSDN). -topmost gets or sets whether this is a topmost window (displays above all other windows). On Macintosh, XXXXX On Unix, there are currently no special attribute values. """ args = ('wm', 'attributes', self._w) + args return self.tk.call(args) attributes = wm_attributes def wm_client(self, name=None): """Store NAME in WM_CLIENT_MACHINE property of this widget. Return current value.""" return self.tk.call('wm', 'client', self._w, name) client = wm_client def wm_colormapwindows(self, *wlist): """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property of this widget. This list contains windows whose colormaps differ from their parents. Return current list of widgets if WLIST is empty.""" if len(wlist) > 1: wlist = (wlist,) # Tk needs a list of windows here args = ('wm', 'colormapwindows', self._w) + wlist if wlist: self.tk.call(args) else: return [self._nametowidget(x) for x in self.tk.splitlist(self.tk.call(args))] colormapwindows = wm_colormapwindows def wm_command(self, value=None): """Store VALUE in WM_COMMAND property. It is the command which shall be used to invoke the application. Return current command if VALUE is None.""" return self.tk.call('wm', 'command', self._w, value) command = wm_command def wm_deiconify(self): """Deiconify this widget. If it was never mapped it will not be mapped. On Windows it will raise this widget and give it the focus.""" return self.tk.call('wm', 'deiconify', self._w) deiconify = wm_deiconify def wm_focusmodel(self, model=None): """Set focus model to MODEL. "active" means that this widget will claim the focus itself, "passive" means that the window manager shall give the focus. Return current focus model if MODEL is None.""" return self.tk.call('wm', 'focusmodel', self._w, model) focusmodel = wm_focusmodel def wm_forget(self, window): # new in Tk 8.5 """The window will be unmapped from the screen and will no longer be managed by wm. toplevel windows will be treated like frame windows once they are no longer managed by wm, however, the menu option configuration will be remembered and the menus will return once the widget is managed again.""" self.tk.call('wm', 'forget', window) forget = wm_forget def wm_frame(self): """Return identifier for decorative frame of this widget if present.""" return self.tk.call('wm', 'frame', self._w) frame = wm_frame def wm_geometry(self, newGeometry=None): """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return current value if None is given.""" return self.tk.call('wm', 'geometry', self._w, newGeometry) geometry = wm_geometry def wm_grid(self, baseWidth=None, baseHeight=None, widthInc=None, heightInc=None): """Instruct the window manager that this widget shall only be resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the number of grid units requested in Tk_GeometryRequest.""" return self._getints(self.tk.call( 'wm', 'grid', self._w, baseWidth, baseHeight, widthInc, heightInc)) grid = wm_grid def wm_group(self, pathName=None): """Set the group leader widgets for related widgets to PATHNAME. Return the group leader of this widget if None is given.""" return self.tk.call('wm', 'group', self._w, pathName) group = wm_group def wm_iconbitmap(self, bitmap=None, default=None): """Set bitmap for the iconified widget to BITMAP. Return the bitmap if None is given. Under Windows, the DEFAULT parameter can be used to set the icon for the widget and any descendants that don't have an icon set explicitly. DEFAULT can be the relative path to a .ico file (example: root.iconbitmap(default='myicon.ico') ). See Tk documentation for more information.""" if default is not None: return self.tk.call('wm', 'iconbitmap', self._w, '-default', default) else: return self.tk.call('wm', 'iconbitmap', self._w, bitmap) iconbitmap = wm_iconbitmap def wm_iconify(self): """Display widget as icon.""" return self.tk.call('wm', 'iconify', self._w) iconify = wm_iconify def wm_iconmask(self, bitmap=None): """Set mask for the icon bitmap of this widget. Return the mask if None is given.""" return self.tk.call('wm', 'iconmask', self._w, bitmap) iconmask = wm_iconmask def wm_iconname(self, newName=None): """Set the name of the icon for this widget. Return the name if None is given.""" return self.tk.call('wm', 'iconname', self._w, newName) iconname = wm_iconname def wm_iconphoto(self, default=False, *args): # new in Tk 8.5 """Sets the titlebar icon for this window based on the named photo images passed through args. If default is True, this is applied to all future created toplevels as well. The data in the images is taken as a snapshot at the time of invocation. If the images are later changed, this is not reflected to the titlebar icons. Multiple images are accepted to allow different images sizes to be provided. The window manager may scale provided icons to an appropriate size. On Windows, the images are packed into a Windows icon structure. This will override an icon specified to wm_iconbitmap, and vice versa. On X, the images are arranged into the _NET_WM_ICON X property, which most modern window managers support. An icon specified by wm_iconbitmap may exist simultaneously. On Macintosh, this currently does nothing.""" if default: self.tk.call('wm', 'iconphoto', self._w, "-default", *args) else: self.tk.call('wm', 'iconphoto', self._w, *args) iconphoto = wm_iconphoto def wm_iconposition(self, x=None, y=None): """Set the position of the icon of this widget to X and Y. Return a tuple of the current values of X and X if None is given.""" return self._getints(self.tk.call( 'wm', 'iconposition', self._w, x, y)) iconposition = wm_iconposition def wm_iconwindow(self, pathName=None): """Set widget PATHNAME to be displayed instead of icon. Return the current value if None is given.""" return self.tk.call('wm', 'iconwindow', self._w, pathName) iconwindow = wm_iconwindow def wm_manage(self, widget): # new in Tk 8.5 """The widget specified will become a stand alone top-level window. The window will be decorated with the window managers title bar, etc.""" self.tk.call('wm', 'manage', widget) manage = wm_manage def wm_maxsize(self, width=None, height=None): """Set max WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'maxsize', self._w, width, height)) maxsize = wm_maxsize def wm_minsize(self, width=None, height=None): """Set min WIDTH and HEIGHT for this widget. If the window is gridded the values are given in grid units. Return the current values if None is given.""" return self._getints(self.tk.call( 'wm', 'minsize', self._w, width, height)) minsize = wm_minsize def wm_overrideredirect(self, boolean=None): """Instruct the window manager to ignore this widget if BOOLEAN is given with 1. Return the current value if None is given.""" return self._getboolean(self.tk.call( 'wm', 'overrideredirect', self._w, boolean)) overrideredirect = wm_overrideredirect def wm_positionfrom(self, who=None): """Instruct the window manager that the position of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'positionfrom', self._w, who) positionfrom = wm_positionfrom def wm_protocol(self, name=None, func=None): """Bind function FUNC to command NAME for this widget. Return the function bound to NAME if None is given. NAME could be e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" if callable(func): command = self._register(func) else: command = func return self.tk.call( 'wm', 'protocol', self._w, name, command) protocol = wm_protocol def wm_resizable(self, width=None, height=None): """Instruct the window manager whether this width can be resized in WIDTH or HEIGHT. Both values are boolean values.""" return self.tk.call('wm', 'resizable', self._w, width, height) resizable = wm_resizable def wm_sizefrom(self, who=None): """Instruct the window manager that the size of this widget shall be defined by the user if WHO is "user", and by its own policy if WHO is "program".""" return self.tk.call('wm', 'sizefrom', self._w, who) sizefrom = wm_sizefrom def wm_state(self, newstate=None): """Query or set the state of this widget as one of normal, icon, iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" return self.tk.call('wm', 'state', self._w, newstate) state = wm_state def wm_title(self, string=None): """Set the title of this widget.""" return self.tk.call('wm', 'title', self._w, string) title = wm_title def wm_transient(self, master=None): """Instruct the window manager that this widget is transient with regard to widget MASTER.""" return self.tk.call('wm', 'transient', self._w, master) transient = wm_transient def wm_withdraw(self): """Withdraw this widget from the screen such that it is unmapped and forgotten by the window manager. Re-draw it with wm_deiconify.""" return self.tk.call('wm', 'withdraw', self._w) withdraw = wm_withdraw class Tk(Misc, Wm): """Toplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.""" _w = '.' def __init__(self, screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None): """Return a new top level widget on screen SCREENNAME. A new Tcl interpreter will be created. BASENAME will be used for the identification of the profile file (see readprofile). It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME is the name of the widget class.""" self.master = None self.children = {} self._tkloaded = False # to avoid recursions in the getattr code in case of failure, we # ensure that self.tk is always _something_. self.tk = None if baseName is None: import os baseName = os.path.basename(sys.argv[0]) baseName, ext = os.path.splitext(baseName) if ext not in ('.py', '.pyc'): baseName = baseName + ext interactive = False self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) if _debug: self.tk.settrace(_print_command) if useTk: self._loadtk() if not sys.flags.ignore_environment: # Issue #16248: Honor the -E flag to avoid code injection. self.readprofile(baseName, className) def loadtk(self): if not self._tkloaded: self.tk.loadtk() self._loadtk() def _loadtk(self): self._tkloaded = True global _default_root # Version sanity checks tk_version = self.tk.getvar('tk_version') if tk_version != _tkinter.TK_VERSION: raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)" % (_tkinter.TK_VERSION, tk_version)) # Under unknown circumstances, tcl_version gets coerced to float tcl_version = str(self.tk.getvar('tcl_version')) if tcl_version != _tkinter.TCL_VERSION: raise RuntimeError("tcl.h version (%s) doesn't match libtcl.a version (%s)" \ % (_tkinter.TCL_VERSION, tcl_version)) # Create and register the tkerror and exit commands # We need to inline parts of _register here, _ register # would register differently-named commands. if self._tclCommands is None: self._tclCommands = [] self.tk.createcommand('tkerror', _tkerror) self.tk.createcommand('exit', _exit) self._tclCommands.append('tkerror') self._tclCommands.append('exit') if _support_default_root and _default_root is None: _default_root = self self.protocol("WM_DELETE_WINDOW", self.destroy) def destroy(self): """Destroy this and all descendants widgets. This will end the application of this Tcl interpreter.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) Misc.destroy(self) global _default_root if _support_default_root and _default_root is self: _default_root = None def readprofile(self, baseName, className): """Internal function. It reads .BASENAME.tcl and .CLASSNAME.tcl into the Tcl Interpreter and calls exec on the contents of .BASENAME.py and .CLASSNAME.py if such a file exists in the home directory.""" import os if 'HOME' in os.environ: home = os.environ['HOME'] else: home = os.curdir class_tcl = os.path.join(home, '.%s.tcl' % className) class_py = os.path.join(home, '.%s.py' % className) base_tcl = os.path.join(home, '.%s.tcl' % baseName) base_py = os.path.join(home, '.%s.py' % baseName) dir = {'self': self} exec('from tkinter import *', dir) if os.path.isfile(class_tcl): self.tk.call('source', class_tcl) if os.path.isfile(class_py): exec(open(class_py).read(), dir) if os.path.isfile(base_tcl): self.tk.call('source', base_tcl) if os.path.isfile(base_py): exec(open(base_py).read(), dir) def report_callback_exception(self, exc, val, tb): """Report callback exception on sys.stderr. Applications may want to override this internal function, and should when sys.stderr is None.""" import traceback print("Exception in Tkinter callback", file=sys.stderr) sys.last_exc = val sys.last_type = exc sys.last_value = val sys.last_traceback = tb traceback.print_exception(exc, val, tb) def __getattr__(self, attr): "Delegate attribute access to the interpreter object" return getattr(self.tk, attr) def _print_command(cmd, *, file=sys.stderr): # Print executed Tcl/Tk commands. assert isinstance(cmd, tuple) cmd = _join(cmd) print(cmd, file=file) # Ideally, the classes Pack, Place and Grid disappear, the # pack/place/grid methods are defined on the Widget class, and # everybody uses w.pack_whatever(...) instead of Pack.whatever(w, # ...), with pack(), place() and grid() being short for # pack_configure(), place_configure() and grid_columnconfigure(), and # forget() being short for pack_forget(). As a practical matter, I'm # afraid that there is too much code out there that may be using the # Pack, Place or Grid class, so I leave them intact -- but only as # backwards compatibility features. Also note that those methods that # take a master as argument (e.g. pack_propagate) have been moved to # the Misc class (which now incorporates all methods common between # toplevel and interior widgets). Again, for compatibility, these are # copied into the Pack, Place or Grid class. def Tcl(screenName=None, baseName=None, className='Tk', useTk=False): return Tk(screenName, baseName, className, useTk) class Pack: """Geometry manager Pack. Base class to use the methods pack_* in every widget.""" def pack_configure(self, cnf={}, **kw): """Pack a widget in the parent widget. Use as options: after=widget - pack it after you have packed widget anchor=NSEW (or subset) - position widget according to given direction before=widget - pack it before you will pack widget expand=bool - expand widget if parent size grows fill=NONE or X or Y or BOTH - fill widget if widget grows in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. """ self.tk.call( ('pack', 'configure', self._w) + self._options(cnf, kw)) pack = configure = config = pack_configure def pack_forget(self): """Unmap this widget and do not use it for the packing order.""" self.tk.call('pack', 'forget', self._w) forget = pack_forget def pack_info(self): """Return information about the packing options for this widget.""" d = _splitdict(self.tk, self.tk.call('pack', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = pack_info propagate = pack_propagate = Misc.pack_propagate slaves = pack_slaves = Misc.pack_slaves class Place: """Geometry manager Place. Base class to use the methods place_* in every widget.""" def place_configure(self, cnf={}, **kw): """Place a widget in the parent widget. Use as options: in=master - master relative to which the widget is placed in_=master - see 'in' option description x=amount - locate anchor of this widget at position x of master y=amount - locate anchor of this widget at position y of master relx=amount - locate anchor of this widget between 0.0 and 1.0 relative to width of master (1.0 is right edge) rely=amount - locate anchor of this widget between 0.0 and 1.0 relative to height of master (1.0 is bottom edge) anchor=NSEW (or subset) - position anchor according to given direction width=amount - width of this widget in pixel height=amount - height of this widget in pixel relwidth=amount - width of this widget between 0.0 and 1.0 relative to width of master (1.0 is the same width as the master) relheight=amount - height of this widget between 0.0 and 1.0 relative to height of master (1.0 is the same height as the master) bordermode="inside" or "outside" - whether to take border width of master widget into account """ self.tk.call( ('place', 'configure', self._w) + self._options(cnf, kw)) place = configure = config = place_configure def place_forget(self): """Unmap this widget.""" self.tk.call('place', 'forget', self._w) forget = place_forget def place_info(self): """Return information about the placing options for this widget.""" d = _splitdict(self.tk, self.tk.call('place', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = place_info slaves = place_slaves = Misc.place_slaves class Grid: """Geometry manager Grid. Base class to use the methods grid_* in every widget.""" # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) def grid_configure(self, cnf={}, **kw): """Position a widget in the parent widget in a grid. Use as options: column=number - use cell identified with given column (starting with 0) columnspan=number - this widget will span several columns in=master - use master to contain this widget in_=master - see 'in' option description ipadx=amount - add internal padding in x direction ipady=amount - add internal padding in y direction padx=amount - add padding in x direction pady=amount - add padding in y direction row=number - use cell identified with given row (starting with 0) rowspan=number - this widget will span several rows sticky=NSEW - if cell is larger on which sides will this widget stick to the cell boundary """ self.tk.call( ('grid', 'configure', self._w) + self._options(cnf, kw)) grid = configure = config = grid_configure bbox = grid_bbox = Misc.grid_bbox columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure def grid_forget(self): """Unmap this widget.""" self.tk.call('grid', 'forget', self._w) forget = grid_forget def grid_remove(self): """Unmap this widget but remember the grid options.""" self.tk.call('grid', 'remove', self._w) def grid_info(self): """Return information about the options for positioning this widget in a grid.""" d = _splitdict(self.tk, self.tk.call('grid', 'info', self._w)) if 'in' in d: d['in'] = self.nametowidget(d['in']) return d info = grid_info location = grid_location = Misc.grid_location propagate = grid_propagate = Misc.grid_propagate rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure size = grid_size = Misc.grid_size slaves = grid_slaves = Misc.grid_slaves class BaseWidget(Misc): """Internal class.""" def _setup(self, master, cnf): """Internal function. Sets up information about children.""" if master is None: master = _get_default_root() self.master = master self.tk = master.tk name = None if 'name' in cnf: name = cnf['name'] del cnf['name'] if not name: name = self.__class__.__name__.lower() if name[-1].isdigit(): name += "!" # Avoid duplication when calculating names below if master._last_child_ids is None: master._last_child_ids = {} count = master._last_child_ids.get(name, 0) + 1 master._last_child_ids[name] = count if count == 1: name = '!%s' % (name,) else: name = '!%s%d' % (name, count) self._name = name if master._w=='.': self._w = '.' + name else: self._w = master._w + '.' + name self.children = {} if self._name in self.master.children: self.master.children[self._name].destroy() self.master.children[self._name] = self def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): """Construct a widget with the parent widget MASTER, a name WIDGETNAME and appropriate options.""" if kw: cnf = _cnfmerge((cnf, kw)) self.widgetName = widgetName self._setup(master, cnf) if self._tclCommands is None: self._tclCommands = [] classes = [(k, v) for k, v in cnf.items() if isinstance(k, type)] for k, v in classes: del cnf[k] self.tk.call( (widgetName, self._w) + extra + self._options(cnf)) for k, v in classes: k.configure(self, v) def destroy(self): """Destroy this and all descendants widgets.""" for c in list(self.children.values()): c.destroy() self.tk.call('destroy', self._w) if self._name in self.master.children: del self.master.children[self._name] Misc.destroy(self) def _do(self, name, args=()): # XXX Obsolete -- better use self.tk.call directly! return self.tk.call((self._w, name) + args) class Widget(BaseWidget, Pack, Place, Grid): """Internal class. Base class for a widget which can be positioned with the geometry managers Pack, Place or Grid.""" pass class Toplevel(BaseWidget, Wm): """Toplevel widget, e.g. for dialogs.""" def __init__(self, master=None, cnf={}, **kw): """Construct a toplevel widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, menu, relief, screen, takefocus, use, visual, width.""" if kw: cnf = _cnfmerge((cnf, kw)) extra = () for wmkey in ['screen', 'class_', 'class', 'visual', 'colormap']: if wmkey in cnf: val = cnf[wmkey] # TBD: a hack needed because some keys # are not valid as keyword arguments if wmkey[-1] == '_': opt = '-'+wmkey[:-1] else: opt = '-'+wmkey extra = extra + (opt, val) del cnf[wmkey] BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) root = self._root() self.iconname(root.iconname()) self.title(root.title()) self.protocol("WM_DELETE_WINDOW", self.destroy) class Button(Widget): """Button widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a button widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, repeatdelay, repeatinterval, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS command, compound, default, height, overrelief, state, width """ Widget.__init__(self, master, 'button', cnf, kw) def flash(self): """Flash the button. This is accomplished by redisplaying the button several times, alternating between active and normal colors. At the end of the flash the button is left in the same normal/active state as when the command was invoked. This command is ignored if the button's state is disabled. """ self.tk.call(self._w, 'flash') def invoke(self): """Invoke the command associated with the button. The return value is the return value from the command, or an empty string if there is no command associated with the button. This command is ignored if the button's state is disabled. """ return self.tk.call(self._w, 'invoke') class Canvas(Widget, XView, YView): """Canvas widget to display graphical elements like lines or text.""" def __init__(self, master=None, cnf={}, **kw): """Construct a canvas widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, closeenough, confine, cursor, height, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, offset, relief, scrollregion, selectbackground, selectborderwidth, selectforeground, state, takefocus, width, xscrollcommand, xscrollincrement, yscrollcommand, yscrollincrement.""" Widget.__init__(self, master, 'canvas', cnf, kw) def addtag(self, *args): """Internal function.""" self.tk.call((self._w, 'addtag') + args) def addtag_above(self, newtag, tagOrId): """Add tag NEWTAG to all items above TAGORID.""" self.addtag(newtag, 'above', tagOrId) def addtag_all(self, newtag): """Add tag NEWTAG to all items.""" self.addtag(newtag, 'all') def addtag_below(self, newtag, tagOrId): """Add tag NEWTAG to all items below TAGORID.""" self.addtag(newtag, 'below', tagOrId) def addtag_closest(self, newtag, x, y, halo=None, start=None): """Add tag NEWTAG to item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.""" self.addtag(newtag, 'closest', x, y, halo, start) def addtag_enclosed(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items in the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'enclosed', x1, y1, x2, y2) def addtag_overlapping(self, newtag, x1, y1, x2, y2): """Add tag NEWTAG to all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" self.addtag(newtag, 'overlapping', x1, y1, x2, y2) def addtag_withtag(self, newtag, tagOrId): """Add tag NEWTAG to all items with TAGORID.""" self.addtag(newtag, 'withtag', tagOrId) def bbox(self, *args): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses all items with tags specified as arguments.""" return self._getints( self.tk.call((self._w, 'bbox') + args)) or None def tag_unbind(self, tagOrId, sequence, funcid=None): """Unbind for all items with TAGORID for event SEQUENCE the function identified with FUNCID.""" self._unbind((self._w, 'bind', tagOrId, sequence), funcid) def tag_bind(self, tagOrId, sequence=None, func=None, add=None): """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'bind', tagOrId), sequence, func, add) def canvasx(self, screenx, gridspacing=None): """Return the canvas x coordinate of pixel position SCREENX rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasx', screenx, gridspacing)) def canvasy(self, screeny, gridspacing=None): """Return the canvas y coordinate of pixel position SCREENY rounded to nearest multiple of GRIDSPACING units.""" return self.tk.getdouble(self.tk.call( self._w, 'canvasy', screeny, gridspacing)) def coords(self, *args): """Return a list of coordinates for the item given in ARGS.""" args = _flatten(args) return [self.tk.getdouble(x) for x in self.tk.splitlist( self.tk.call((self._w, 'coords') + args))] def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) """Internal function.""" args = _flatten(args) cnf = args[-1] if isinstance(cnf, (dict, tuple)): args = args[:-1] else: cnf = {} return self.tk.getint(self.tk.call( self._w, 'create', itemType, *(args + self._options(cnf, kw)))) def create_arc(self, *args, **kw): """Create arc shaped region with coordinates x1,y1,x2,y2.""" return self._create('arc', args, kw) def create_bitmap(self, *args, **kw): """Create bitmap with coordinates x1,y1.""" return self._create('bitmap', args, kw) def create_image(self, *args, **kw): """Create image item with coordinates x1,y1.""" return self._create('image', args, kw) def create_line(self, *args, **kw): """Create line with coordinates x1,y1,...,xn,yn.""" return self._create('line', args, kw) def create_oval(self, *args, **kw): """Create oval with coordinates x1,y1,x2,y2.""" return self._create('oval', args, kw) def create_polygon(self, *args, **kw): """Create polygon with coordinates x1,y1,...,xn,yn.""" return self._create('polygon', args, kw) def create_rectangle(self, *args, **kw): """Create rectangle with coordinates x1,y1,x2,y2.""" return self._create('rectangle', args, kw) def create_text(self, *args, **kw): """Create text with coordinates x1,y1.""" return self._create('text', args, kw) def create_window(self, *args, **kw): """Create window with coordinates x1,y1,x2,y2.""" return self._create('window', args, kw) def dchars(self, *args): """Delete characters of text items identified by tag or id in ARGS (possibly several times) from FIRST to LAST character (including).""" self.tk.call((self._w, 'dchars') + args) def delete(self, *args): """Delete items identified by all tag or ids contained in ARGS.""" self.tk.call((self._w, 'delete') + args) def dtag(self, *args): """Delete tag or id given as last arguments in ARGS from items identified by first argument in ARGS.""" self.tk.call((self._w, 'dtag') + args) def find(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'find') + args)) or () def find_above(self, tagOrId): """Return items above TAGORID.""" return self.find('above', tagOrId) def find_all(self): """Return all items.""" return self.find('all') def find_below(self, tagOrId): """Return all items below TAGORID.""" return self.find('below', tagOrId) def find_closest(self, x, y, halo=None, start=None): """Return item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are closest). If START is specified the next below this tag is taken.""" return self.find('closest', x, y, halo, start) def find_enclosed(self, x1, y1, x2, y2): """Return all items in rectangle defined by X1,Y1,X2,Y2.""" return self.find('enclosed', x1, y1, x2, y2) def find_overlapping(self, x1, y1, x2, y2): """Return all items which overlap the rectangle defined by X1,Y1,X2,Y2.""" return self.find('overlapping', x1, y1, x2, y2) def find_withtag(self, tagOrId): """Return all items with TAGORID.""" return self.find('withtag', tagOrId) def focus(self, *args): """Set focus to the first item specified in ARGS.""" return self.tk.call((self._w, 'focus') + args) def gettags(self, *args): """Return tags associated with the first item specified in ARGS.""" return self.tk.splitlist( self.tk.call((self._w, 'gettags') + args)) def icursor(self, *args): """Set cursor at position POS in the item identified by TAGORID. In ARGS TAGORID must be first.""" self.tk.call((self._w, 'icursor') + args) def index(self, *args): """Return position of cursor as integer in item specified in ARGS.""" return self.tk.getint(self.tk.call((self._w, 'index') + args)) def insert(self, *args): """Insert TEXT in item TAGORID at position POS. ARGS must be TAGORID POS TEXT.""" self.tk.call((self._w, 'insert') + args) def itemcget(self, tagOrId, option): """Return the resource value for an OPTION for item TAGORID.""" return self.tk.call( (self._w, 'itemcget') + (tagOrId, '-'+option)) def itemconfigure(self, tagOrId, cnf=None, **kw): """Configure resources of an item TAGORID. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. """ return self._configure(('itemconfigure', tagOrId), cnf, kw) itemconfig = itemconfigure # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, # so the preferred name for them is tag_lower, tag_raise # (similar to tag_bind, and similar to the Text widget); # unfortunately can't delete the old ones yet (maybe in 1.6) def tag_lower(self, *args): """Lower an item TAGORID given in ARGS (optional below another item).""" self.tk.call((self._w, 'lower') + args) lower = tag_lower def move(self, *args): """Move an item TAGORID given in ARGS.""" self.tk.call((self._w, 'move') + args) def moveto(self, tagOrId, x='', y=''): """Move the items given by TAGORID in the canvas coordinate space so that the first coordinate pair of the bottommost item with tag TAGORID is located at position (X,Y). X and Y may be the empty string, in which case the corresponding coordinate will be unchanged. All items matching TAGORID remain in the same positions relative to each other.""" self.tk.call(self._w, 'moveto', tagOrId, x, y) def postscript(self, cnf={}, **kw): """Print the contents of the canvas to a postscript file. Valid options: colormap, colormode, file, fontmap, height, pageanchor, pageheight, pagewidth, pagex, pagey, rotate, width, x, y.""" return self.tk.call((self._w, 'postscript') + self._options(cnf, kw)) def tag_raise(self, *args): """Raise an item TAGORID given in ARGS (optional above another item).""" self.tk.call((self._w, 'raise') + args) lift = tkraise = tag_raise def scale(self, *args): """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" self.tk.call((self._w, 'scale') + args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y, gain=10): """Adjust the view of the canvas to GAIN times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y, gain) def select_adjust(self, tagOrId, index): """Adjust the end of the selection near the cursor of an item TAGORID to index.""" self.tk.call(self._w, 'select', 'adjust', tagOrId, index) def select_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'select', 'clear') def select_from(self, tagOrId, index): """Set the fixed end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'from', tagOrId, index) def select_item(self): """Return the item which has the selection.""" return self.tk.call(self._w, 'select', 'item') or None def select_to(self, tagOrId, index): """Set the variable end of a selection in item TAGORID to INDEX.""" self.tk.call(self._w, 'select', 'to', tagOrId, index) def type(self, tagOrId): """Return the type of the item TAGORID.""" return self.tk.call(self._w, 'type', tagOrId) or None _checkbutton_count = 0 class Checkbutton(Widget): """Checkbutton widget which is either in on- or off-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a checkbutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, offvalue, onvalue, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, variable, width, wraplength.""" Widget.__init__(self, master, 'checkbutton', cnf, kw) def _setup(self, master, cnf): # Because Checkbutton defaults to a variable with the same name as # the widget, Checkbutton default names must be globally unique, # not just unique within the parent widget. if not cnf.get('name'): global _checkbutton_count name = self.__class__.__name__.lower() _checkbutton_count += 1 # To avoid collisions with ttk.Checkbutton, use the different # name template. cnf['name'] = f'!{name}-{_checkbutton_count}' super()._setup(master, cnf) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') def toggle(self): """Toggle the button.""" self.tk.call(self._w, 'toggle') class Entry(Widget, XView): """Entry widget which allows displaying simple text.""" def __init__(self, master=None, cnf={}, **kw): """Construct an entry widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, invalidcommand, invcmd, justify, relief, selectbackground, selectborderwidth, selectforeground, show, state, takefocus, textvariable, validate, validatecommand, vcmd, width, xscrollcommand.""" Widget.__init__(self, master, 'entry', cnf, kw) def delete(self, first, last=None): """Delete text from FIRST to LAST (not included).""" self.tk.call(self._w, 'delete', first, last) def get(self): """Return the text.""" return self.tk.call(self._w, 'get') def icursor(self, index): """Insert cursor at INDEX.""" self.tk.call(self._w, 'icursor', index) def index(self, index): """Return position of cursor.""" return self.tk.getint(self.tk.call( self._w, 'index', index)) def insert(self, index, string): """Insert STRING at INDEX.""" self.tk.call(self._w, 'insert', index, string) def scan_mark(self, x): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x) def scan_dragto(self, x): """Adjust the view of the canvas to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x) def selection_adjust(self, index): """Adjust the end of the selection near the cursor to INDEX.""" self.tk.call(self._w, 'selection', 'adjust', index) select_adjust = selection_adjust def selection_clear(self): """Clear the selection if it is in this widget.""" self.tk.call(self._w, 'selection', 'clear') select_clear = selection_clear def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'from', index) select_from = selection_from def selection_present(self): """Return True if there are characters selected in the entry, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) select_present = selection_present def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.tk.call(self._w, 'selection', 'range', start, end) select_range = selection_range def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.tk.call(self._w, 'selection', 'to', index) select_to = selection_to class Frame(Widget): """Frame widget which may contain other widgets and can have a 3D border.""" def __init__(self, master=None, cnf={}, **kw): """Construct a frame widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, class, colormap, container, cursor, height, highlightbackground, highlightcolor, highlightthickness, relief, takefocus, visual, width.""" cnf = _cnfmerge((cnf, kw)) extra = () if 'class_' in cnf: extra = ('-class', cnf['class_']) del cnf['class_'] elif 'class' in cnf: extra = ('-class', cnf['class']) del cnf['class'] Widget.__init__(self, master, 'frame', cnf, {}, extra) class Label(Widget): """Label widget which can display text and bitmaps.""" def __init__(self, master=None, cnf={}, **kw): """Construct a label widget with the parent MASTER. STANDARD OPTIONS activebackground, activeforeground, anchor, background, bitmap, borderwidth, cursor, disabledforeground, font, foreground, highlightbackground, highlightcolor, highlightthickness, image, justify, padx, pady, relief, takefocus, text, textvariable, underline, wraplength WIDGET-SPECIFIC OPTIONS height, state, width """ Widget.__init__(self, master, 'label', cnf, kw) class Listbox(Widget, XView, YView): """Listbox widget which can display a list of strings.""" def __init__(self, master=None, cnf={}, **kw): """Construct a listbox widget with the parent MASTER. Valid resource names: background, bd, bg, borderwidth, cursor, exportselection, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, relief, selectbackground, selectborderwidth, selectforeground, selectmode, setgrid, takefocus, width, xscrollcommand, yscrollcommand, listvariable.""" Widget.__init__(self, master, 'listbox', cnf, kw) def activate(self, index): """Activate item identified by INDEX.""" self.tk.call(self._w, 'activate', index) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the item identified by the given index.""" return self._getints(self.tk.call(self._w, 'bbox', index)) or None def curselection(self): """Return the indices of currently selected item.""" return self._getints(self.tk.call(self._w, 'curselection')) or () def delete(self, first, last=None): """Delete items from FIRST to LAST (included).""" self.tk.call(self._w, 'delete', first, last) def get(self, first, last=None): """Get list of items from FIRST to LAST (included).""" if last is not None: return self.tk.splitlist(self.tk.call( self._w, 'get', first, last)) else: return self.tk.call(self._w, 'get', first) def index(self, index): """Return index of item identified with INDEX.""" i = self.tk.call(self._w, 'index', index) if i == 'none': return None return self.tk.getint(i) def insert(self, index, *elements): """Insert ELEMENTS at INDEX.""" self.tk.call((self._w, 'insert', index) + elements) def nearest(self, y): """Get index of item which is nearest to y coordinate Y.""" return self.tk.getint(self.tk.call( self._w, 'nearest', y)) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the listbox to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def see(self, index): """Scroll such that INDEX is visible.""" self.tk.call(self._w, 'see', index) def selection_anchor(self, index): """Set the fixed end oft the selection to INDEX.""" self.tk.call(self._w, 'selection', 'anchor', index) select_anchor = selection_anchor def selection_clear(self, first, last=None): """Clear the selection from FIRST to LAST (included).""" self.tk.call(self._w, 'selection', 'clear', first, last) select_clear = selection_clear def selection_includes(self, index): """Return True if INDEX is part of the selection.""" return self.tk.getboolean(self.tk.call( self._w, 'selection', 'includes', index)) select_includes = selection_includes def selection_set(self, first, last=None): """Set the selection from FIRST to LAST (included) without changing the currently selected elements.""" self.tk.call(self._w, 'selection', 'set', first, last) select_set = selection_set def size(self): """Return the number of elements in the listbox.""" return self.tk.getint(self.tk.call(self._w, 'size')) def itemcget(self, index, option): """Return the resource value for an ITEM and an OPTION.""" return self.tk.call( (self._w, 'itemcget') + (index, '-'+option)) def itemconfigure(self, index, cnf=None, **kw): """Configure resources of an ITEM. The values for resources are specified as keyword arguments. To get an overview about the allowed keyword arguments call the method without arguments. Valid resource names: background, bg, foreground, fg, selectbackground, selectforeground.""" return self._configure(('itemconfigure', index), cnf, kw) itemconfig = itemconfigure class Menu(Widget): """Menu widget which allows displaying menu bars, pull-down menus and pop-up menus.""" def __init__(self, master=None, cnf={}, **kw): """Construct menu widget with the parent MASTER. Valid resource names: activebackground, activeborderwidth, activeforeground, background, bd, bg, borderwidth, cursor, disabledforeground, fg, font, foreground, postcommand, relief, selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" Widget.__init__(self, master, 'menu', cnf, kw) def tk_popup(self, x, y, entry=""): """Post the menu at position X,Y with entry ENTRY.""" self.tk.call('tk_popup', self._w, x, y, entry) def activate(self, index): """Activate entry at INDEX.""" self.tk.call(self._w, 'activate', index) def add(self, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'add', itemType) + self._options(cnf, kw)) def add_cascade(self, cnf={}, **kw): """Add hierarchical menu item.""" self.add('cascade', cnf or kw) def add_checkbutton(self, cnf={}, **kw): """Add checkbutton menu item.""" self.add('checkbutton', cnf or kw) def add_command(self, cnf={}, **kw): """Add command menu item.""" self.add('command', cnf or kw) def add_radiobutton(self, cnf={}, **kw): """Add radio menu item.""" self.add('radiobutton', cnf or kw) def add_separator(self, cnf={}, **kw): """Add separator.""" self.add('separator', cnf or kw) def insert(self, index, itemType, cnf={}, **kw): """Internal function.""" self.tk.call((self._w, 'insert', index, itemType) + self._options(cnf, kw)) def insert_cascade(self, index, cnf={}, **kw): """Add hierarchical menu item at INDEX.""" self.insert(index, 'cascade', cnf or kw) def insert_checkbutton(self, index, cnf={}, **kw): """Add checkbutton menu item at INDEX.""" self.insert(index, 'checkbutton', cnf or kw) def insert_command(self, index, cnf={}, **kw): """Add command menu item at INDEX.""" self.insert(index, 'command', cnf or kw) def insert_radiobutton(self, index, cnf={}, **kw): """Add radio menu item at INDEX.""" self.insert(index, 'radiobutton', cnf or kw) def insert_separator(self, index, cnf={}, **kw): """Add separator at INDEX.""" self.insert(index, 'separator', cnf or kw) def delete(self, index1, index2=None): """Delete menu items between INDEX1 and INDEX2 (included).""" if index2 is None: index2 = index1 num_index1, num_index2 = self.index(index1), self.index(index2) if (num_index1 is None) or (num_index2 is None): num_index1, num_index2 = 0, -1 for i in range(num_index1, num_index2 + 1): if 'command' in self.entryconfig(i): c = str(self.entrycget(i, 'command')) if c: self.deletecommand(c) self.tk.call(self._w, 'delete', index1, index2) def entrycget(self, index, option): """Return the resource value of a menu item for OPTION at INDEX.""" return self.tk.call(self._w, 'entrycget', index, '-' + option) def entryconfigure(self, index, cnf=None, **kw): """Configure a menu item at INDEX.""" return self._configure(('entryconfigure', index), cnf, kw) entryconfig = entryconfigure def index(self, index): """Return the index of a menu item identified by INDEX.""" i = self.tk.call(self._w, 'index', index) return None if i in ('', 'none') else self.tk.getint(i) # GH-103685. def invoke(self, index): """Invoke a menu item identified by INDEX and execute the associated command.""" return self.tk.call(self._w, 'invoke', index) def post(self, x, y): """Display a menu at position X,Y.""" self.tk.call(self._w, 'post', x, y) def type(self, index): """Return the type of the menu item at INDEX.""" return self.tk.call(self._w, 'type', index) def unpost(self): """Unmap a menu.""" self.tk.call(self._w, 'unpost') def xposition(self, index): # new in Tk 8.5 """Return the x-position of the leftmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call(self._w, 'xposition', index)) def yposition(self, index): """Return the y-position of the topmost pixel of the menu item at INDEX.""" return self.tk.getint(self.tk.call( self._w, 'yposition', index)) class Menubutton(Widget): """Menubutton widget, obsolete since Tk8.0.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'menubutton', cnf, kw) class Message(Widget): """Message widget to display multiline text. Obsolete since Label does it too.""" def __init__(self, master=None, cnf={}, **kw): Widget.__init__(self, master, 'message', cnf, kw) class Radiobutton(Widget): """Radiobutton widget which shows only one of several buttons in on-state.""" def __init__(self, master=None, cnf={}, **kw): """Construct a radiobutton widget with the parent MASTER. Valid resource names: activebackground, activeforeground, anchor, background, bd, bg, bitmap, borderwidth, command, cursor, disabledforeground, fg, font, foreground, height, highlightbackground, highlightcolor, highlightthickness, image, indicatoron, justify, padx, pady, relief, selectcolor, selectimage, state, takefocus, text, textvariable, underline, value, variable, width, wraplength.""" Widget.__init__(self, master, 'radiobutton', cnf, kw) def deselect(self): """Put the button in off-state.""" self.tk.call(self._w, 'deselect') def flash(self): """Flash the button.""" self.tk.call(self._w, 'flash') def invoke(self): """Toggle the button and invoke a command if given as resource.""" return self.tk.call(self._w, 'invoke') def select(self): """Put the button in on-state.""" self.tk.call(self._w, 'select') class Scale(Widget): """Scale widget which can display a numerical scale.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scale widget with the parent MASTER. Valid resource names: activebackground, background, bigincrement, bd, bg, borderwidth, command, cursor, digits, fg, font, foreground, from, highlightbackground, highlightcolor, highlightthickness, label, length, orient, relief, repeatdelay, repeatinterval, resolution, showvalue, sliderlength, sliderrelief, state, takefocus, tickinterval, to, troughcolor, variable, width.""" Widget.__init__(self, master, 'scale', cnf, kw) def get(self): """Get the current value as integer or float.""" value = self.tk.call(self._w, 'get') try: return self.tk.getint(value) except (ValueError, TypeError, TclError): return self.tk.getdouble(value) def set(self, value): """Set the value to VALUE.""" self.tk.call(self._w, 'set', value) def coords(self, value=None): """Return a tuple (X,Y) of the point along the centerline of the trough that corresponds to VALUE or the current value if None is given.""" return self._getints(self.tk.call(self._w, 'coords', value)) def identify(self, x, y): """Return where the point X,Y lies. Valid return values are "slider", "though1" and "though2".""" return self.tk.call(self._w, 'identify', x, y) class Scrollbar(Widget): """Scrollbar widget which displays a slider at a certain position.""" def __init__(self, master=None, cnf={}, **kw): """Construct a scrollbar widget with the parent MASTER. Valid resource names: activebackground, activerelief, background, bd, bg, borderwidth, command, cursor, elementborderwidth, highlightbackground, highlightcolor, highlightthickness, jump, orient, relief, repeatdelay, repeatinterval, takefocus, troughcolor, width.""" Widget.__init__(self, master, 'scrollbar', cnf, kw) def activate(self, index=None): """Marks the element indicated by index as active. The only index values understood by this method are "arrow1", "slider", or "arrow2". If any other value is specified then no element of the scrollbar will be active. If index is not specified, the method returns the name of the element that is currently active, or None if no element is active.""" return self.tk.call(self._w, 'activate', index) or None def delta(self, deltax, deltay): """Return the fractional change of the scrollbar setting if it would be moved by DELTAX or DELTAY pixels.""" return self.tk.getdouble( self.tk.call(self._w, 'delta', deltax, deltay)) def fraction(self, x, y): """Return the fractional value which corresponds to a slider position of X,Y.""" return self.tk.getdouble(self.tk.call(self._w, 'fraction', x, y)) def identify(self, x, y): """Return the element under position X,Y as one of "arrow1","slider","arrow2" or "".""" return self.tk.call(self._w, 'identify', x, y) def get(self): """Return the current fractional values (upper and lower end) of the slider position.""" return self._getdoubles(self.tk.call(self._w, 'get')) def set(self, first, last): """Set the fractional values of the slider position (upper and lower ends as value between 0 and 1).""" self.tk.call(self._w, 'set', first, last) class Text(Widget, XView, YView): """Text widget which can display text in various forms.""" def __init__(self, master=None, cnf={}, **kw): """Construct a text widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, padx, pady, relief, selectbackground, selectborderwidth, selectforeground, setgrid, takefocus, xscrollcommand, yscrollcommand, WIDGET-SPECIFIC OPTIONS autoseparators, height, maxundo, spacing1, spacing2, spacing3, state, tabs, undo, width, wrap, """ Widget.__init__(self, master, 'text', cnf, kw) def bbox(self, index): """Return a tuple of (x,y,width,height) which gives the bounding box of the visible part of the character at the given index.""" return self._getints( self.tk.call(self._w, 'bbox', index)) or None def compare(self, index1, op, index2): """Return whether between index INDEX1 and index INDEX2 the relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" return self.tk.getboolean(self.tk.call( self._w, 'compare', index1, op, index2)) def count(self, index1, index2, *args): # new in Tk 8.5 """Counts the number of relevant things between the two indices. If index1 is after index2, the result will be a negative number (and this holds for each of the possible options). The actual items which are counted depends on the options given by args. The result is a list of integers, one for the result of each counting option given. Valid counting options are "chars", "displaychars", "displayindices", "displaylines", "indices", "lines", "xpixels" and "ypixels". There is an additional possible option "update", which if given then all subsequent options ensure that any possible out of date information is recalculated.""" args = ['-%s' % arg for arg in args] args += [index1, index2] res = self.tk.call(self._w, 'count', *args) or None if res is not None and len(args) <= 3: return (res, ) else: return res def debug(self, boolean=None): """Turn on the internal consistency checks of the B-Tree inside the text widget according to BOOLEAN.""" if boolean is None: return self.tk.getboolean(self.tk.call(self._w, 'debug')) self.tk.call(self._w, 'debug', boolean) def delete(self, index1, index2=None): """Delete the characters between INDEX1 and INDEX2 (not included).""" self.tk.call(self._w, 'delete', index1, index2) def dlineinfo(self, index): """Return tuple (x,y,width,height,baseline) giving the bounding box and baseline position of the visible part of the line containing the character at INDEX.""" return self._getints(self.tk.call(self._w, 'dlineinfo', index)) def dump(self, index1, index2=None, command=None, **kw): """Return the contents of the widget between index1 and index2. The type of contents returned in filtered based on the keyword parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are given and true, then the corresponding items are returned. The result is a list of triples of the form (key, value, index). If none of the keywords are true then 'all' is used by default. If the 'command' argument is given, it is called once for each element of the list of triples, with the values of each triple serving as the arguments to the function. In this case the list is not returned.""" args = [] func_name = None result = None if not command: # Never call the dump command without the -command flag, since the # output could involve Tcl quoting and would be a pain to parse # right. Instead just set the command to build a list of triples # as if we had done the parsing. result = [] def append_triple(key, value, index, result=result): result.append((key, value, index)) command = append_triple try: if not isinstance(command, str): func_name = command = self._register(command) args += ["-command", command] for key in kw: if kw[key]: args.append("-" + key) args.append(index1) if index2: args.append(index2) self.tk.call(self._w, "dump", *args) return result finally: if func_name: self.deletecommand(func_name) ## new in tk8.4 def edit(self, *args): """Internal method This method controls the undo mechanism and the modified flag. The exact behavior of the command depends on the option argument that follows the edit argument. The following forms of the command are currently supported: edit_modified, edit_redo, edit_reset, edit_separator and edit_undo """ return self.tk.call(self._w, 'edit', *args) def edit_modified(self, arg=None): """Get or Set the modified flag If arg is not specified, returns the modified flag of the widget. The insert, delete, edit undo and edit redo commands or the user can set or clear the modified flag. If boolean is specified, sets the modified flag of the widget to arg. """ return self.edit("modified", arg) def edit_redo(self): """Redo the last undone edit When the undo option is true, reapplies the last undone edits provided no other edits were done since then. Generates an error when the redo stack is empty. Does nothing when the undo option is false. """ return self.edit("redo") def edit_reset(self): """Clears the undo and redo stacks """ return self.edit("reset") def edit_separator(self): """Inserts a separator (boundary) on the undo stack. Does nothing when the undo option is false """ return self.edit("separator") def edit_undo(self): """Undoes the last edit action If the undo option is true. An edit action is defined as all the insert and delete commands that are recorded on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the undo option is false """ return self.edit("undo") def get(self, index1, index2=None): """Return the text from INDEX1 to INDEX2 (not included).""" return self.tk.call(self._w, 'get', index1, index2) # (Image commands are new in 8.0) def image_cget(self, index, option): """Return the value of OPTION of an embedded image at INDEX.""" if option[:1] != "-": option = "-" + option if option[-1:] == "_": option = option[:-1] return self.tk.call(self._w, "image", "cget", index, option) def image_configure(self, index, cnf=None, **kw): """Configure an embedded image at INDEX.""" return self._configure(('image', 'configure', index), cnf, kw) def image_create(self, index, cnf={}, **kw): """Create an embedded image at INDEX.""" return self.tk.call( self._w, "image", "create", index, *self._options(cnf, kw)) def image_names(self): """Return all names of embedded images in this widget.""" return self.tk.call(self._w, "image", "names") def index(self, index): """Return the index in the form line.char for INDEX.""" return str(self.tk.call(self._w, 'index', index)) def insert(self, index, chars, *args): """Insert CHARS before the characters at INDEX. An additional tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" self.tk.call((self._w, 'insert', index, chars) + args) def mark_gravity(self, markName, direction=None): """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). Return the current value if None is given for DIRECTION.""" return self.tk.call( (self._w, 'mark', 'gravity', markName, direction)) def mark_names(self): """Return all mark names.""" return self.tk.splitlist(self.tk.call( self._w, 'mark', 'names')) def mark_set(self, markName, index): """Set mark MARKNAME before the character at INDEX.""" self.tk.call(self._w, 'mark', 'set', markName, index) def mark_unset(self, *markNames): """Delete all marks in MARKNAMES.""" self.tk.call((self._w, 'mark', 'unset') + markNames) def mark_next(self, index): """Return the name of the next mark after INDEX.""" return self.tk.call(self._w, 'mark', 'next', index) or None def mark_previous(self, index): """Return the name of the previous mark before INDEX.""" return self.tk.call(self._w, 'mark', 'previous', index) or None def peer_create(self, newPathName, cnf={}, **kw): # new in Tk 8.5 """Creates a peer text widget with the given newPathName, and any optional standard configuration options. By default the peer will have the same start and end line as the parent widget, but these can be overridden with the standard configuration options.""" self.tk.call(self._w, 'peer', 'create', newPathName, *self._options(cnf, kw)) def peer_names(self): # new in Tk 8.5 """Returns a list of peers of this widget (this does not include the widget itself).""" return self.tk.splitlist(self.tk.call(self._w, 'peer', 'names')) def replace(self, index1, index2, chars, *args): # new in Tk 8.5 """Replaces the range of characters between index1 and index2 with the given characters and tags specified by args. See the method insert for some more information about args, and the method delete for information about the indices.""" self.tk.call(self._w, 'replace', index1, index2, chars, *args) def scan_mark(self, x, y): """Remember the current X, Y coordinates.""" self.tk.call(self._w, 'scan', 'mark', x, y) def scan_dragto(self, x, y): """Adjust the view of the text to 10 times the difference between X and Y and the coordinates given in scan_mark.""" self.tk.call(self._w, 'scan', 'dragto', x, y) def search(self, pattern, index, stopindex=None, forwards=None, backwards=None, exact=None, regexp=None, nocase=None, count=None, elide=None): """Search PATTERN beginning from INDEX until STOPINDEX. Return the index of the first character of a match or an empty string.""" args = [self._w, 'search'] if forwards: args.append('-forwards') if backwards: args.append('-backwards') if exact: args.append('-exact') if regexp: args.append('-regexp') if nocase: args.append('-nocase') if elide: args.append('-elide') if count: args.append('-count'); args.append(count) if pattern and pattern[0] == '-': args.append('--') args.append(pattern) args.append(index) if stopindex: args.append(stopindex) return str(self.tk.call(tuple(args))) def see(self, index): """Scroll such that the character at INDEX is visible.""" self.tk.call(self._w, 'see', index) def tag_add(self, tagName, index1, *args): """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. Additional pairs of indices may follow in ARGS.""" self.tk.call( (self._w, 'tag', 'add', tagName, index1) + args) def tag_unbind(self, tagName, sequence, funcid=None): """Unbind for all characters with TAGNAME for event SEQUENCE the function identified with FUNCID.""" return self._unbind((self._w, 'tag', 'bind', tagName, sequence), funcid) def tag_bind(self, tagName, sequence, func, add=None): """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. An additional boolean parameter ADD specifies whether FUNC will be called additionally to the other bound function or whether it will replace the previous function. See bind for the return value.""" return self._bind((self._w, 'tag', 'bind', tagName), sequence, func, add) def _tag_bind(self, tagName, sequence=None, func=None, add=None): # For tests only return self._bind((self._w, 'tag', 'bind', tagName), sequence, func, add) def tag_cget(self, tagName, option): """Return the value of OPTION for tag TAGNAME.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'tag', 'cget', tagName, option) def tag_configure(self, tagName, cnf=None, **kw): """Configure a tag TAGNAME.""" return self._configure(('tag', 'configure', tagName), cnf, kw) tag_config = tag_configure def tag_delete(self, *tagNames): """Delete all tags in TAGNAMES.""" self.tk.call((self._w, 'tag', 'delete') + tagNames) def tag_lower(self, tagName, belowThis=None): """Change the priority of tag TAGNAME such that it is lower than the priority of BELOWTHIS.""" self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) def tag_names(self, index=None): """Return a list of all tag names.""" return self.tk.splitlist( self.tk.call(self._w, 'tag', 'names', index)) def tag_nextrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched forward from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'nextrange', tagName, index1, index2)) def tag_prevrange(self, tagName, index1, index2=None): """Return a list of start and end index for the first sequence of characters between INDEX1 and INDEX2 which all have tag TAGNAME. The text is searched backwards from INDEX1.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'prevrange', tagName, index1, index2)) def tag_raise(self, tagName, aboveThis=None): """Change the priority of tag TAGNAME such that it is higher than the priority of ABOVETHIS.""" self.tk.call( self._w, 'tag', 'raise', tagName, aboveThis) def tag_ranges(self, tagName): """Return a list of ranges of text which have tag TAGNAME.""" return self.tk.splitlist(self.tk.call( self._w, 'tag', 'ranges', tagName)) def tag_remove(self, tagName, index1, index2=None): """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" self.tk.call( self._w, 'tag', 'remove', tagName, index1, index2) def window_cget(self, index, option): """Return the value of OPTION of an embedded window at INDEX.""" if option[:1] != '-': option = '-' + option if option[-1:] == '_': option = option[:-1] return self.tk.call(self._w, 'window', 'cget', index, option) def window_configure(self, index, cnf=None, **kw): """Configure an embedded window at INDEX.""" return self._configure(('window', 'configure', index), cnf, kw) window_config = window_configure def window_create(self, index, cnf={}, **kw): """Create a window at INDEX.""" self.tk.call( (self._w, 'window', 'create', index) + self._options(cnf, kw)) def window_names(self): """Return all names of embedded windows in this widget.""" return self.tk.splitlist( self.tk.call(self._w, 'window', 'names')) def yview_pickplace(self, *what): """Obsolete function, use see.""" self.tk.call((self._w, 'yview', '-pickplace') + what) class _setit: """Internal class. It wraps the command in the widget OptionMenu.""" def __init__(self, var, value, callback=None): self.__value = value self.__var = var self.__callback = callback def __call__(self, *args): self.__var.set(self.__value) if self.__callback is not None: self.__callback(self.__value, *args) class OptionMenu(Menubutton): """OptionMenu which allows the user to select a value from a menu.""" def __init__(self, master, variable, value, *values, **kwargs): """Construct an optionmenu widget with the parent MASTER, with the resource textvariable set to VARIABLE, the initially selected value VALUE, the other menu values VALUES and an additional keyword argument command.""" kw = {"borderwidth": 2, "textvariable": variable, "indicatoron": 1, "relief": RAISED, "anchor": "c", "highlightthickness": 2} Widget.__init__(self, master, "menubutton", kw) self.widgetName = 'tk_optionMenu' menu = self.__menu = Menu(self, name="menu", tearoff=0) self.menuname = menu._w # 'command' is the only supported keyword callback = kwargs.get('command') if 'command' in kwargs: del kwargs['command'] if kwargs: raise TclError('unknown option -'+next(iter(kwargs))) menu.add_command(label=value, command=_setit(variable, value, callback)) for v in values: menu.add_command(label=v, command=_setit(variable, v, callback)) self["menu"] = menu def __getitem__(self, name): if name == 'menu': return self.__menu return Widget.__getitem__(self, name) def destroy(self): """Destroy this widget and the associated menu.""" Menubutton.destroy(self) self.__menu = None class Image: """Base class for images.""" _last_id = 0 def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): self.name = None if master is None: master = _get_default_root('create image') self.tk = getattr(master, 'tk', master) if not name: Image._last_id += 1 name = "pyimage%r" % (Image._last_id,) # tk itself would use image if kw and cnf: cnf = _cnfmerge((cnf, kw)) elif kw: cnf = kw options = () for k, v in cnf.items(): options = options + ('-'+k, v) self.tk.call(('image', 'create', imgtype, name,) + options) self.name = name def __str__(self): return self.name def __del__(self): if self.name: try: self.tk.call('image', 'delete', self.name) except TclError: # May happen if the root was destroyed pass def __setitem__(self, key, value): self.tk.call(self.name, 'configure', '-'+key, value) def __getitem__(self, key): return self.tk.call(self.name, 'configure', '-'+key) def configure(self, **kw): """Configure the image.""" res = () for k, v in _cnfmerge(kw).items(): if v is not None: if k[-1] == '_': k = k[:-1] res = res + ('-'+k, v) self.tk.call((self.name, 'config') + res) config = configure def height(self): """Return the height of the image.""" return self.tk.getint( self.tk.call('image', 'height', self.name)) def type(self): """Return the type of the image, e.g. "photo" or "bitmap".""" return self.tk.call('image', 'type', self.name) def width(self): """Return the width of the image.""" return self.tk.getint( self.tk.call('image', 'width', self.name)) class PhotoImage(Image): """Widget which can display images in PGM, PPM, GIF, PNG format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create an image with NAME. Valid resource names: data, format, file, gamma, height, palette, width.""" Image.__init__(self, 'photo', name, cnf, master, **kw) def blank(self): """Display a transparent image.""" self.tk.call(self.name, 'blank') def cget(self, option): """Return the value of OPTION.""" return self.tk.call(self.name, 'cget', '-' + option) # XXX config def __getitem__(self, key): return self.tk.call(self.name, 'cget', '-' + key) # XXX copy -from, -to, ...? def copy(self): """Return a new PhotoImage with the same image as this widget.""" destImage = PhotoImage(master=self.tk) self.tk.call(destImage, 'copy', self.name) return destImage def zoom(self, x, y=''): """Return a new PhotoImage with the same image as this widget but zoom it with a factor of x in the X direction and y in the Y direction. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) return destImage def subsample(self, x, y=''): """Return a new PhotoImage based on the same image as this widget but use only every Xth or Yth pixel. If y is not given, the default value is the same as x. """ destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) return destImage def get(self, x, y): """Return the color (red, green, blue) of the pixel at X,Y.""" return self.tk.call(self.name, 'get', x, y) def put(self, data, to=None): """Put row formatted colors to image starting from position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" args = (self.name, 'put', data) if to: if to[0] == '-to': to = to[1:] args = args + ('-to',) + tuple(to) self.tk.call(args) # XXX read def write(self, filename, format=None, from_coords=None): """Write image to file FILENAME in FORMAT starting from position FROM_COORDS.""" args = (self.name, 'write', filename) if format: args = args + ('-format', format) if from_coords: args = args + ('-from',) + tuple(from_coords) self.tk.call(args) def transparency_get(self, x, y): """Return True if the pixel at x,y is transparent.""" return self.tk.getboolean(self.tk.call( self.name, 'transparency', 'get', x, y)) def transparency_set(self, x, y, boolean): """Set the transparency of the pixel at x,y.""" self.tk.call(self.name, 'transparency', 'set', x, y, boolean) class BitmapImage(Image): """Widget which can display images in XBM format.""" def __init__(self, name=None, cnf={}, master=None, **kw): """Create a bitmap with NAME. Valid resource names: background, data, file, foreground, maskdata, maskfile.""" Image.__init__(self, 'bitmap', name, cnf, master, **kw) def image_names(): tk = _get_default_root('use image_names()').tk return tk.splitlist(tk.call('image', 'names')) def image_types(): tk = _get_default_root('use image_types()').tk return tk.splitlist(tk.call('image', 'types')) class Spinbox(Widget, XView): """spinbox widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a spinbox widget with the parent MASTER. STANDARD OPTIONS activebackground, background, borderwidth, cursor, exportselection, font, foreground, highlightbackground, highlightcolor, highlightthickness, insertbackground, insertborderwidth, insertofftime, insertontime, insertwidth, justify, relief, repeatdelay, repeatinterval, selectbackground, selectborderwidth selectforeground, takefocus, textvariable xscrollcommand. WIDGET-SPECIFIC OPTIONS buttonbackground, buttoncursor, buttondownrelief, buttonuprelief, command, disabledbackground, disabledforeground, format, from, invalidcommand, increment, readonlybackground, state, to, validate, validatecommand values, width, wrap, """ Widget.__init__(self, master, 'spinbox', cnf, kw) def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle which encloses the character given by index. The first two elements of the list give the x and y coordinates of the upper-left corner of the screen area covered by the character (in pixels relative to the widget) and the last two elements give the width and height of the character, in pixels. The bounding box may refer to a region outside the visible area of the window. """ return self._getints(self.tk.call(self._w, 'bbox', index)) or None def delete(self, first, last=None): """Delete one or more elements of the spinbox. First is the index of the first character to delete, and last is the index of the character just after the last one to delete. If last isn't specified it defaults to first+1, i.e. a single character is deleted. This command returns an empty string. """ return self.tk.call(self._w, 'delete', first, last) def get(self): """Returns the spinbox's string""" return self.tk.call(self._w, 'get') def icursor(self, index): """Alter the position of the insertion cursor. The insertion cursor will be displayed just before the character given by index. Returns an empty string """ return self.tk.call(self._w, 'icursor', index) def identify(self, x, y): """Returns the name of the widget at position x, y Return value is one of: none, buttondown, buttonup, entry """ return self.tk.call(self._w, 'identify', x, y) def index(self, index): """Returns the numerical index corresponding to index """ return self.tk.call(self._w, 'index', index) def insert(self, index, s): """Insert string s at index Returns an empty string. """ return self.tk.call(self._w, 'insert', index, s) def invoke(self, element): """Causes the specified element to be invoked The element could be buttondown or buttonup triggering the action associated with it. """ return self.tk.call(self._w, 'invoke', element) def scan(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'scan') + args)) or () def scan_mark(self, x): """Records x and the current view in the spinbox window; used in conjunction with later scan dragto commands. Typically this command is associated with a mouse button press in the widget. It returns an empty string. """ return self.scan("mark", x) def scan_dragto(self, x): """Compute the difference between the given x argument and the x argument to the last scan mark command It then adjusts the view left or right by 10 times the difference in x-coordinates. This command is typically associated with mouse motion events in the widget, to produce the effect of dragging the spinbox at high speed through the window. The return value is an empty string. """ return self.scan("dragto", x) def selection(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'selection') + args)) or () def selection_adjust(self, index): """Locate the end of the selection nearest to the character given by index, Then adjust that end of the selection to be at index (i.e including but not going beyond index). The other end of the selection is made the anchor point for future select to commands. If the selection isn't currently in the spinbox, then a new selection is created to include the characters between index and the most recent selection anchor point, inclusive. """ return self.selection("adjust", index) def selection_clear(self): """Clear the selection If the selection isn't in this widget then the command has no effect. """ return self.selection("clear") def selection_element(self, element=None): """Sets or gets the currently selected element. If a spinbutton element is specified, it will be displayed depressed. """ return self.tk.call(self._w, 'selection', 'element', element) def selection_from(self, index): """Set the fixed end of a selection to INDEX.""" self.selection('from', index) def selection_present(self): """Return True if there are characters selected in the spinbox, False otherwise.""" return self.tk.getboolean( self.tk.call(self._w, 'selection', 'present')) def selection_range(self, start, end): """Set the selection from START to END (not included).""" self.selection('range', start, end) def selection_to(self, index): """Set the variable end of a selection to INDEX.""" self.selection('to', index) ########################################################################### class LabelFrame(Widget): """labelframe widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a labelframe widget with the parent MASTER. STANDARD OPTIONS borderwidth, cursor, font, foreground, highlightbackground, highlightcolor, highlightthickness, padx, pady, relief, takefocus, text WIDGET-SPECIFIC OPTIONS background, class, colormap, container, height, labelanchor, labelwidget, visual, width """ Widget.__init__(self, master, 'labelframe', cnf, kw) ######################################################################## class PanedWindow(Widget): """panedwindow widget.""" def __init__(self, master=None, cnf={}, **kw): """Construct a panedwindow widget with the parent MASTER. STANDARD OPTIONS background, borderwidth, cursor, height, orient, relief, width WIDGET-SPECIFIC OPTIONS handlepad, handlesize, opaqueresize, sashcursor, sashpad, sashrelief, sashwidth, showhandle, """ Widget.__init__(self, master, 'panedwindow', cnf, kw) def add(self, child, **kw): """Add a child widget to the panedwindow in a new pane. The child argument is the name of the child widget followed by pairs of arguments that specify how to manage the windows. The possible options and values are the ones accepted by the paneconfigure method. """ self.tk.call((self._w, 'add', child) + self._options(kw)) def remove(self, child): """Remove the pane containing child from the panedwindow All geometry management options for child will be forgotten. """ self.tk.call(self._w, 'forget', child) forget = remove def identify(self, x, y): """Identify the panedwindow component at point x, y If the point is over a sash or a sash handle, the result is a two element list containing the index of the sash or handle, and a word indicating whether it is over a sash or a handle, such as {0 sash} or {2 handle}. If the point is over any other part of the panedwindow, the result is an empty list. """ return self.tk.call(self._w, 'identify', x, y) def proxy(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'proxy') + args)) or () def proxy_coord(self): """Return the x and y pair of the most recent proxy location """ return self.proxy("coord") def proxy_forget(self): """Remove the proxy from the display. """ return self.proxy("forget") def proxy_place(self, x, y): """Place the proxy at the given x and y coordinates. """ return self.proxy("place", x, y) def sash(self, *args): """Internal function.""" return self._getints( self.tk.call((self._w, 'sash') + args)) or () def sash_coord(self, index): """Return the current x and y pair for the sash given by index. Index must be an integer between 0 and 1 less than the number of panes in the panedwindow. The coordinates given are those of the top left corner of the region containing the sash. pathName sash dragto index x y This command computes the difference between the given coordinates and the coordinates given to the last sash coord command for the given sash. It then moves that sash the computed difference. The return value is the empty string. """ return self.sash("coord", index) def sash_mark(self, index): """Records x and y for the sash given by index; Used in conjunction with later dragto commands to move the sash. """ return self.sash("mark", index) def sash_place(self, index, x, y): """Place the sash given by index at the given coordinates """ return self.sash("place", index, x, y) def panecget(self, child, option): """Query a management option for window. Option may be any value allowed by the paneconfigure subcommand """ return self.tk.call( (self._w, 'panecget') + (child, '-'+option)) def paneconfigure(self, tagOrId, cnf=None, **kw): """Query or modify the management options for window. If no option is specified, returns a list describing all of the available options for pathName. If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. The following options are supported: after window Insert the window after the window specified. window should be the name of a window already managed by pathName. before window Insert the window before the window specified. window should be the name of a window already managed by pathName. height size Specify a height for the window. The height will be the outer dimension of the window including its border, if any. If size is an empty string, or if -height is not specified, then the height requested internally by the window will be used initially; the height may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. minsize n Specifies that the size of the window cannot be made less than n. This constraint only affects the size of the widget in the paned dimension -- the x dimension for horizontal panedwindows, the y dimension for vertical panedwindows. May be any value accepted by Tk_GetPixels. padx n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the X-direction. The value may have any of the forms accepted by Tk_GetPixels. pady n Specifies a non-negative value indicating how much extra space to leave on each side of the window in the Y-direction. The value may have any of the forms accepted by Tk_GetPixels. sticky style If a window's pane is larger than the requested dimensions of the window, this option may be used to position (or stretch) the window within its pane. Style is a string that contains zero or more of the characters n, s, e or w. The string can optionally contains spaces or commas, but they are ignored. Each letter refers to a side (north, south, east, or west) that the window will "stick" to. If both n and s (or e and w) are specified, the window will be stretched to fill the entire height (or width) of its cavity. width size Specify a width for the window. The width will be the outer dimension of the window including its border, if any. If size is an empty string, or if -width is not specified, then the width requested internally by the window will be used initially; the width may later be adjusted by the movement of sashes in the panedwindow. Size may be any value accepted by Tk_GetPixels. """ if cnf is None and not kw: return self._getconfigure(self._w, 'paneconfigure', tagOrId) if isinstance(cnf, str) and not kw: return self._getconfigure1( self._w, 'paneconfigure', tagOrId, '-'+cnf) self.tk.call((self._w, 'paneconfigure', tagOrId) + self._options(cnf, kw)) paneconfig = paneconfigure def panes(self): """Returns an ordered list of the child panes.""" return self.tk.splitlist(self.tk.call(self._w, 'panes')) # Test: def _test(): root = Tk() text = "This is Tcl/Tk %s" % root.globalgetvar('tk_patchLevel') text += "\nThis should be a cedilla: \xe7" label = Label(root, text=text) label.pack() test = Button(root, text="Click me!", command=lambda root=root: root.test.configure( text="[%s]" % root.test['text'])) test.pack() root.test = test quit = Button(root, text="QUIT", command=root.destroy) quit.pack() # The following three commands are needed so the window pops # up on top on Windows... root.iconify() root.update() root.deiconify() root.mainloop() __all__ = [name for name, obj in globals().items() if not name.startswith('_') and not isinstance(obj, types.ModuleType) and name not in {'wantobjects'}] if __name__ == '__main__': _test() tkinter/filedialog.py000064400000035133152342670510010707 0ustar00"""File selection dialog classes. Classes: - FileDialog - LoadFileDialog - SaveFileDialog This module also presents tk common file dialogues, it provides interfaces to the native file dialogues available in Tk 4.2 and newer, and the directory dialogue available in Tk 8.3 and newer. These interfaces were written by Fredrik Lundh, May 1997. """ __all__ = ["FileDialog", "LoadFileDialog", "SaveFileDialog", "Open", "SaveAs", "Directory", "askopenfilename", "asksaveasfilename", "askopenfilenames", "askopenfile", "askopenfiles", "asksaveasfile", "askdirectory"] import fnmatch import os from tkinter import ( Frame, LEFT, YES, BOTTOM, Entry, TOP, Button, Tk, X, Toplevel, RIGHT, Y, END, Listbox, BOTH, Scrollbar, ) from tkinter.dialog import Dialog from tkinter import commondialog from tkinter.simpledialog import _setup_dialog dialogstates = {} class FileDialog: """Standard file selection dialog -- no checks on selected file. Usage: d = FileDialog(master) fname = d.go(dir_or_file, pattern, default, key) if fname is None: ...canceled... else: ...open file... All arguments to go() are optional. The 'key' argument specifies a key in the global dictionary 'dialogstates', which keeps track of the values for the directory and pattern arguments, overriding the values passed in (it does not keep track of the default argument!). If no key is specified, the dialog keeps no memory of previous state. Note that memory is kept even when the dialog is canceled. (All this emulates the behavior of the Macintosh file selection dialogs.) """ title = "File Selection Dialog" def __init__(self, master, title=None): if title is None: title = self.title self.master = master self.directory = None self.top = Toplevel(master) self.top.title(title) self.top.iconname(title) _setup_dialog(self.top) self.botframe = Frame(self.top) self.botframe.pack(side=BOTTOM, fill=X) self.selection = Entry(self.top) self.selection.pack(side=BOTTOM, fill=X) self.selection.bind('', self.ok_event) self.filter = Entry(self.top) self.filter.pack(side=TOP, fill=X) self.filter.bind('', self.filter_command) self.midframe = Frame(self.top) self.midframe.pack(expand=YES, fill=BOTH) self.filesbar = Scrollbar(self.midframe) self.filesbar.pack(side=RIGHT, fill=Y) self.files = Listbox(self.midframe, exportselection=0, yscrollcommand=(self.filesbar, 'set')) self.files.pack(side=RIGHT, expand=YES, fill=BOTH) btags = self.files.bindtags() self.files.bindtags(btags[1:] + btags[:1]) self.files.bind('', self.files_select_event) self.files.bind('', self.files_double_event) self.filesbar.config(command=(self.files, 'yview')) self.dirsbar = Scrollbar(self.midframe) self.dirsbar.pack(side=LEFT, fill=Y) self.dirs = Listbox(self.midframe, exportselection=0, yscrollcommand=(self.dirsbar, 'set')) self.dirs.pack(side=LEFT, expand=YES, fill=BOTH) self.dirsbar.config(command=(self.dirs, 'yview')) btags = self.dirs.bindtags() self.dirs.bindtags(btags[1:] + btags[:1]) self.dirs.bind('', self.dirs_select_event) self.dirs.bind('', self.dirs_double_event) self.ok_button = Button(self.botframe, text="OK", command=self.ok_command) self.ok_button.pack(side=LEFT) self.filter_button = Button(self.botframe, text="Filter", command=self.filter_command) self.filter_button.pack(side=LEFT, expand=YES) self.cancel_button = Button(self.botframe, text="Cancel", command=self.cancel_command) self.cancel_button.pack(side=RIGHT) self.top.protocol('WM_DELETE_WINDOW', self.cancel_command) # XXX Are the following okay for a general audience? self.top.bind('', self.cancel_command) self.top.bind('', self.cancel_command) def go(self, dir_or_file=os.curdir, pattern="*", default="", key=None): if key and key in dialogstates: self.directory, pattern = dialogstates[key] else: dir_or_file = os.path.expanduser(dir_or_file) if os.path.isdir(dir_or_file): self.directory = dir_or_file else: self.directory, default = os.path.split(dir_or_file) self.set_filter(self.directory, pattern) self.set_selection(default) self.filter_command() self.selection.focus_set() self.top.wait_visibility() # window needs to be visible for the grab self.top.grab_set() self.how = None self.master.mainloop() # Exited by self.quit(how) if key: directory, pattern = self.get_filter() if self.how: directory = os.path.dirname(self.how) dialogstates[key] = directory, pattern self.top.destroy() return self.how def quit(self, how=None): self.how = how self.master.quit() # Exit mainloop() def dirs_double_event(self, event): self.filter_command() def dirs_select_event(self, event): dir, pat = self.get_filter() subdir = self.dirs.get('active') dir = os.path.normpath(os.path.join(self.directory, subdir)) self.set_filter(dir, pat) def files_double_event(self, event): self.ok_command() def files_select_event(self, event): file = self.files.get('active') self.set_selection(file) def ok_event(self, event): self.ok_command() def ok_command(self): self.quit(self.get_selection()) def filter_command(self, event=None): dir, pat = self.get_filter() try: names = os.listdir(dir) except OSError: self.master.bell() return self.directory = dir self.set_filter(dir, pat) names.sort() subdirs = [os.pardir] matchingfiles = [] for name in names: fullname = os.path.join(dir, name) if os.path.isdir(fullname): subdirs.append(name) elif fnmatch.fnmatch(name, pat): matchingfiles.append(name) self.dirs.delete(0, END) for name in subdirs: self.dirs.insert(END, name) self.files.delete(0, END) for name in matchingfiles: self.files.insert(END, name) head, tail = os.path.split(self.get_selection()) if tail == os.curdir: tail = '' self.set_selection(tail) def get_filter(self): filter = self.filter.get() filter = os.path.expanduser(filter) if filter[-1:] == os.sep or os.path.isdir(filter): filter = os.path.join(filter, "*") return os.path.split(filter) def get_selection(self): file = self.selection.get() file = os.path.expanduser(file) return file def cancel_command(self, event=None): self.quit() def set_filter(self, dir, pat): if not os.path.isabs(dir): try: pwd = os.getcwd() except OSError: pwd = None if pwd: dir = os.path.join(pwd, dir) dir = os.path.normpath(dir) self.filter.delete(0, END) self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*")) def set_selection(self, file): self.selection.delete(0, END) self.selection.insert(END, os.path.join(self.directory, file)) class LoadFileDialog(FileDialog): """File selection dialog which checks that the file exists.""" title = "Load File Selection Dialog" def ok_command(self): file = self.get_selection() if not os.path.isfile(file): self.master.bell() else: self.quit(file) class SaveFileDialog(FileDialog): """File selection dialog which checks that the file may be created.""" title = "Save File Selection Dialog" def ok_command(self): file = self.get_selection() if os.path.exists(file): if os.path.isdir(file): self.master.bell() return d = Dialog(self.top, title="Overwrite Existing File Question", text="Overwrite existing file %r?" % (file,), bitmap='questhead', default=1, strings=("Yes", "Cancel")) if d.num != 0: return else: head, tail = os.path.split(file) if not os.path.isdir(head): self.master.bell() return self.quit(file) # For the following classes and modules: # # options (all have default values): # # - defaultextension: added to filename if not explicitly given # # - filetypes: sequence of (label, pattern) tuples. the same pattern # may occur with several patterns. use "*" as pattern to indicate # all files. # # - initialdir: initial directory. preserved by dialog instance. # # - initialfile: initial file (ignored by the open dialog). preserved # by dialog instance. # # - parent: which window to place the dialog on top of # # - title: dialog title # # - multiple: if true user may select more than one file # # options for the directory chooser: # # - initialdir, parent, title: see above # # - mustexist: if true, user must pick an existing directory # class _Dialog(commondialog.Dialog): def _fixoptions(self): try: # make sure "filetypes" is a tuple self.options["filetypes"] = tuple(self.options["filetypes"]) except KeyError: pass def _fixresult(self, widget, result): if result: # keep directory and filename until next time # convert Tcl path objects to strings try: result = result.string except AttributeError: # it already is a string pass path, file = os.path.split(result) self.options["initialdir"] = path self.options["initialfile"] = file self.filename = result # compatibility return result # # file dialogs class Open(_Dialog): "Ask for a filename to open" command = "tk_getOpenFile" def _fixresult(self, widget, result): if isinstance(result, tuple): # multiple results: result = tuple([getattr(r, "string", r) for r in result]) if result: path, file = os.path.split(result[0]) self.options["initialdir"] = path # don't set initialfile or filename, as we have multiple of these return result if not widget.tk.wantobjects() and "multiple" in self.options: # Need to split result explicitly return self._fixresult(widget, widget.tk.splitlist(result)) return _Dialog._fixresult(self, widget, result) class SaveAs(_Dialog): "Ask for a filename to save as" command = "tk_getSaveFile" # the directory dialog has its own _fix routines. class Directory(commondialog.Dialog): "Ask for a directory" command = "tk_chooseDirectory" def _fixresult(self, widget, result): if result: # convert Tcl path objects to strings try: result = result.string except AttributeError: # it already is a string pass # keep directory until next time self.options["initialdir"] = result self.directory = result # compatibility return result # # convenience stuff def askopenfilename(**options): "Ask for a filename to open" return Open(**options).show() def asksaveasfilename(**options): "Ask for a filename to save as" return SaveAs(**options).show() def askopenfilenames(**options): """Ask for multiple filenames to open Returns a list of filenames or empty list if cancel button selected """ options["multiple"]=1 return Open(**options).show() # FIXME: are the following perhaps a bit too convenient? def askopenfile(mode = "r", **options): "Ask for a filename to open, and returned the opened file" filename = Open(**options).show() if filename: return open(filename, mode) return None def askopenfiles(mode = "r", **options): """Ask for multiple filenames and return the open file objects returns a list of open file objects or an empty list if cancel selected """ files = askopenfilenames(**options) if files: ofiles=[] for filename in files: ofiles.append(open(filename, mode)) files=ofiles return files def asksaveasfile(mode = "w", **options): "Ask for a filename to save as, and returned the opened file" filename = SaveAs(**options).show() if filename: return open(filename, mode) return None def askdirectory (**options): "Ask for a directory, and return the file name" return Directory(**options).show() # -------------------------------------------------------------------- # test stuff def test(): """Simple test program.""" root = Tk() root.withdraw() fd = LoadFileDialog(root) loadfile = fd.go(key="test") fd = SaveFileDialog(root) savefile = fd.go(key="test") print(loadfile, savefile) # Since the file name may contain non-ASCII characters, we need # to find an encoding that likely supports the file name, and # displays correctly on the terminal. # Start off with UTF-8 enc = "utf-8" # See whether CODESET is defined try: import locale locale.setlocale(locale.LC_ALL,'') enc = locale.nl_langinfo(locale.CODESET) except (ImportError, AttributeError): pass # dialog for opening files openfilename=askopenfilename(filetypes=[("all files", "*")]) try: fp=open(openfilename,"r") fp.close() except BaseException as exc: print("Could not open File: ") print(exc) print("open", openfilename.encode(enc)) # dialog for saving files saveasfilename=asksaveasfilename() print("saveas", saveasfilename.encode(enc)) if __name__ == '__main__': test() socketserver.py000064400000066641152342670510007657 0ustar00"""Generic socket server classes. This module tries to capture the various aspects of defining a server: For socket-based servers: - address family: - AF_INET{,6}: IP (Internet Protocol) sockets (default) - AF_UNIX: Unix domain sockets - others, e.g. AF_DECNET are conceivable (see - socket type: - SOCK_STREAM (reliable stream, e.g. TCP) - SOCK_DGRAM (datagrams, e.g. UDP) For request-based servers (including socket-based): - client address verification before further looking at the request (This is actually a hook for any processing that needs to look at the request before anything else, e.g. logging) - how to handle multiple requests: - synchronous (one request is handled at a time) - forking (each request is handled by a new process) - threading (each request is handled by a new thread) The classes in this module favor the server type that is simplest to write: a synchronous TCP/IP server. This is bad class design, but saves some typing. (There's also the issue that a deep class hierarchy slows down method lookups.) There are five classes in an inheritance diagram, four of which represent synchronous servers of four types: +------------+ | BaseServer | +------------+ | v +-----------+ +------------------+ | TCPServer |------->| UnixStreamServer | +-----------+ +------------------+ | v +-----------+ +--------------------+ | UDPServer |------->| UnixDatagramServer | +-----------+ +--------------------+ Note that UnixDatagramServer derives from UDPServer, not from UnixStreamServer -- the only difference between an IP and a Unix stream server is the address family, which is simply repeated in both unix server classes. Forking and threading versions of each type of server can be created using the ForkingMixIn and ThreadingMixIn mix-in classes. For instance, a threading UDP server class is created as follows: class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass The Mix-in class must come first, since it overrides a method defined in UDPServer! Setting the various member variables also changes the behavior of the underlying server mechanism. To implement a service, you must derive a class from BaseRequestHandler and redefine its handle() method. You can then run various versions of the service by combining one of the server classes with your request handler class. The request handler class must be different for datagram or stream services. This can be hidden by using the request handler subclasses StreamRequestHandler or DatagramRequestHandler. Of course, you still have to use your head! For instance, it makes no sense to use a forking server if the service contains state in memory that can be modified by requests (since the modifications in the child process would never reach the initial state kept in the parent process and passed to each child). In this case, you can use a threading server, but you will probably have to use locks to avoid two requests that come in nearly simultaneous to apply conflicting changes to the server state. On the other hand, if you are building e.g. an HTTP server, where all data is stored externally (e.g. in the file system), a synchronous class will essentially render the service "deaf" while one request is being handled -- which may be for a very long time if a client is slow to read all the data it has requested. Here a threading or forking server is appropriate. In some cases, it may be appropriate to process part of a request synchronously, but to finish processing in a forked child depending on the request data. This can be implemented by using a synchronous server and doing an explicit fork in the request handler class handle() method. Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor fork (or where these are too expensive or inappropriate for the service) is to maintain an explicit table of partially finished requests and to use a selector to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be connected for a long time (if threads or subprocesses cannot be used). Future work: - Standard classes for Sun RPC (which uses either UDP or TCP) - Standard mix-in classes to implement various authentication and encryption schemes XXX Open problems: - What to do with out-of-band data? BaseServer: - split generic "request" functionality out into BaseServer class. Copyright (C) 2000 Luke Kenneth Casson Leighton example: read entries from a SQL database (requires overriding get_request() to return a table entry from the database). entry is processed by a RequestHandlerClass. """ # Author of the BaseServer patch: Luke Kenneth Casson Leighton __version__ = "0.4" import socket import selectors import os import sys import threading from io import BufferedIOBase from time import monotonic as time __all__ = ["BaseServer", "TCPServer", "UDPServer", "ThreadingUDPServer", "ThreadingTCPServer", "BaseRequestHandler", "StreamRequestHandler", "DatagramRequestHandler", "ThreadingMixIn"] if hasattr(os, "fork"): __all__.extend(["ForkingUDPServer","ForkingTCPServer", "ForkingMixIn"]) if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", "ThreadingUnixStreamServer", "ThreadingUnixDatagramServer"]) if hasattr(os, "fork"): __all__.extend(["ForkingUnixStreamServer", "ForkingUnixDatagramServer"]) # poll/select have the advantage of not requiring any extra file descriptor, # contrarily to epoll/kqueue (also, they require a single syscall). if hasattr(selectors, 'PollSelector'): _ServerSelector = selectors.PollSelector else: _ServerSelector = selectors.SelectSelector class BaseServer: """Base class for server classes. Methods for the caller: - __init__(server_address, RequestHandlerClass) - serve_forever(poll_interval=0.5) - shutdown() - handle_request() # if you do not use serve_forever() - fileno() -> int # for selector Methods that may be overridden: - server_bind() - server_activate() - get_request() -> request, client_address - handle_timeout() - verify_request(request, client_address) - server_close() - process_request(request, client_address) - shutdown_request(request) - close_request(request) - service_actions() - handle_error() Methods for derived classes: - finish_request(request, client_address) Class variables that may be overridden by derived classes or instances: - timeout - address_family - socket_type - allow_reuse_address - allow_reuse_port Instance variables: - RequestHandlerClass - socket """ timeout = None def __init__(self, server_address, RequestHandlerClass): """Constructor. May be extended, do not override.""" self.server_address = server_address self.RequestHandlerClass = RequestHandlerClass self.__is_shut_down = threading.Event() self.__shutdown_request = False def server_activate(self): """Called by constructor to activate the server. May be overridden. """ pass def serve_forever(self, poll_interval=0.5): """Handle one request at a time until shutdown. Polls for shutdown every poll_interval seconds. Ignores self.timeout. If you need to do periodic tasks, do them in another thread. """ self.__is_shut_down.clear() try: # XXX: Consider using another file descriptor or connecting to the # socket to wake this up instead of polling. Polling reduces our # responsiveness to a shutdown request and wastes cpu at all other # times. with _ServerSelector() as selector: selector.register(self, selectors.EVENT_READ) while not self.__shutdown_request: ready = selector.select(poll_interval) # bpo-35017: shutdown() called during select(), exit immediately. if self.__shutdown_request: break if ready: self._handle_request_noblock() self.service_actions() finally: self.__shutdown_request = False self.__is_shut_down.set() def shutdown(self): """Stops the serve_forever loop. Blocks until the loop has finished. This must be called while serve_forever() is running in another thread, or it will deadlock. """ self.__shutdown_request = True self.__is_shut_down.wait() def service_actions(self): """Called by the serve_forever() loop. May be overridden by a subclass / Mixin to implement any code that needs to be run during the loop. """ pass # The distinction between handling, getting, processing and finishing a # request is fairly arbitrary. Remember: # # - handle_request() is the top-level call. It calls selector.select(), # get_request(), verify_request() and process_request() # - get_request() is different for stream or datagram sockets # - process_request() is the place that may fork a new process or create a # new thread to finish the request # - finish_request() instantiates the request handler class; this # constructor will handle the request all by itself def handle_request(self): """Handle one request, possibly blocking. Respects self.timeout. """ # Support people who used socket.settimeout() to escape # handle_request before self.timeout was available. timeout = self.socket.gettimeout() if timeout is None: timeout = self.timeout elif self.timeout is not None: timeout = min(timeout, self.timeout) if timeout is not None: deadline = time() + timeout # Wait until a request arrives or the timeout expires - the loop is # necessary to accommodate early wakeups due to EINTR. with _ServerSelector() as selector: selector.register(self, selectors.EVENT_READ) while True: if selector.select(timeout): return self._handle_request_noblock() else: if timeout is not None: timeout = deadline - time() if timeout < 0: return self.handle_timeout() def _handle_request_noblock(self): """Handle one request, without blocking. I assume that selector.select() has returned that the socket is readable before this function was called, so there should be no risk of blocking in get_request(). """ try: request, client_address = self.get_request() except OSError: return if self.verify_request(request, client_address): try: self.process_request(request, client_address) except Exception: self.handle_error(request, client_address) self.shutdown_request(request) except: self.shutdown_request(request) raise else: self.shutdown_request(request) def handle_timeout(self): """Called if no new request arrives within self.timeout. Overridden by ForkingMixIn. """ pass def verify_request(self, request, client_address): """Verify the request. May be overridden. Return True if we should proceed with this request. """ return True def process_request(self, request, client_address): """Call finish_request. Overridden by ForkingMixIn and ThreadingMixIn. """ self.finish_request(request, client_address) self.shutdown_request(request) def server_close(self): """Called to clean-up the server. May be overridden. """ pass def finish_request(self, request, client_address): """Finish one request by instantiating RequestHandlerClass.""" self.RequestHandlerClass(request, client_address, self) def shutdown_request(self, request): """Called to shutdown and close an individual request.""" self.close_request(request) def close_request(self, request): """Called to clean up an individual request.""" pass def handle_error(self, request, client_address): """Handle an error gracefully. May be overridden. The default is to print a traceback and continue. """ print('-'*40, file=sys.stderr) print('Exception occurred during processing of request from', client_address, file=sys.stderr) import traceback traceback.print_exc() print('-'*40, file=sys.stderr) def __enter__(self): return self def __exit__(self, *args): self.server_close() class TCPServer(BaseServer): """Base class for various socket-based server classes. Defaults to synchronous IP stream (i.e., TCP). Methods for the caller: - __init__(server_address, RequestHandlerClass, bind_and_activate=True) - serve_forever(poll_interval=0.5) - shutdown() - handle_request() # if you don't use serve_forever() - fileno() -> int # for selector Methods that may be overridden: - server_bind() - server_activate() - get_request() -> request, client_address - handle_timeout() - verify_request(request, client_address) - process_request(request, client_address) - shutdown_request(request) - close_request(request) - handle_error() Methods for derived classes: - finish_request(request, client_address) Class variables that may be overridden by derived classes or instances: - timeout - address_family - socket_type - request_queue_size (only for stream sockets) - allow_reuse_address - allow_reuse_port Instance variables: - server_address - RequestHandlerClass - socket """ address_family = socket.AF_INET socket_type = socket.SOCK_STREAM request_queue_size = 5 allow_reuse_address = False allow_reuse_port = False def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): """Constructor. May be extended, do not override.""" BaseServer.__init__(self, server_address, RequestHandlerClass) self.socket = socket.socket(self.address_family, self.socket_type) if bind_and_activate: try: self.server_bind() self.server_activate() except: self.server_close() raise def server_bind(self): """Called by constructor to bind the socket. May be overridden. """ if self.allow_reuse_address and hasattr(socket, "SO_REUSEADDR"): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # Since Linux 6.12.9, SO_REUSEPORT is not allowed # on other address families than AF_INET/AF_INET6. if ( self.allow_reuse_port and hasattr(socket, "SO_REUSEPORT") and self.address_family in (socket.AF_INET, socket.AF_INET6) ): self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) self.socket.bind(self.server_address) self.server_address = self.socket.getsockname() def server_activate(self): """Called by constructor to activate the server. May be overridden. """ self.socket.listen(self.request_queue_size) def server_close(self): """Called to clean-up the server. May be overridden. """ self.socket.close() def fileno(self): """Return socket file number. Interface required by selector. """ return self.socket.fileno() def get_request(self): """Get the request and client address from the socket. May be overridden. """ return self.socket.accept() def shutdown_request(self, request): """Called to shutdown and close an individual request.""" try: #explicitly shutdown. socket.close() merely releases #the socket and waits for GC to perform the actual close. request.shutdown(socket.SHUT_WR) except OSError: pass #some platforms may raise ENOTCONN here self.close_request(request) def close_request(self, request): """Called to clean up an individual request.""" request.close() class UDPServer(TCPServer): """UDP server class.""" allow_reuse_address = False allow_reuse_port = False socket_type = socket.SOCK_DGRAM max_packet_size = 8192 def get_request(self): data, client_addr = self.socket.recvfrom(self.max_packet_size) return (data, self.socket), client_addr def server_activate(self): # No need to call listen() for UDP. pass def shutdown_request(self, request): # No need to shutdown anything. self.close_request(request) def close_request(self, request): # No need to close anything. pass if hasattr(os, "fork"): class ForkingMixIn: """Mix-in class to handle each request in a new process.""" timeout = 300 active_children = None max_children = 40 # If true, server_close() waits until all child processes complete. block_on_close = True def collect_children(self, *, blocking=False): """Internal routine to wait for children that have exited.""" if self.active_children is None: return # If we're above the max number of children, wait and reap them until # we go back below threshold. Note that we use waitpid(-1) below to be # able to collect children in size() syscalls instead # of size(): the downside is that this might reap children # which we didn't spawn, which is why we only resort to this when we're # above max_children. while len(self.active_children) >= self.max_children: try: pid, _ = os.waitpid(-1, 0) self.active_children.discard(pid) except ChildProcessError: # we don't have any children, we're done self.active_children.clear() except OSError: break # Now reap all defunct children. for pid in self.active_children.copy(): try: flags = 0 if blocking else os.WNOHANG pid, _ = os.waitpid(pid, flags) # if the child hasn't exited yet, pid will be 0 and ignored by # discard() below self.active_children.discard(pid) except ChildProcessError: # someone else reaped it self.active_children.discard(pid) except OSError: pass def handle_timeout(self): """Wait for zombies after self.timeout seconds of inactivity. May be extended, do not override. """ self.collect_children() def service_actions(self): """Collect the zombie child processes regularly in the ForkingMixIn. service_actions is called in the BaseServer's serve_forever loop. """ self.collect_children() def process_request(self, request, client_address): """Fork a new subprocess to process the request.""" pid = os.fork() if pid: # Parent process if self.active_children is None: self.active_children = set() self.active_children.add(pid) self.close_request(request) return else: # Child process. # This must never return, hence os._exit()! status = 1 try: self.finish_request(request, client_address) status = 0 except Exception: self.handle_error(request, client_address) finally: try: self.shutdown_request(request) finally: os._exit(status) def server_close(self): super().server_close() self.collect_children(blocking=self.block_on_close) class _Threads(list): """ Joinable list of all non-daemon threads. """ def append(self, thread): self.reap() if thread.daemon: return super().append(thread) def pop_all(self): self[:], result = [], self[:] return result def join(self): for thread in self.pop_all(): thread.join() def reap(self): self[:] = (thread for thread in self if thread.is_alive()) class _NoThreads: """ Degenerate version of _Threads. """ def append(self, thread): pass def join(self): pass class ThreadingMixIn: """Mix-in class to handle each request in a new thread.""" # Decides how threads will act upon termination of the # main process daemon_threads = False # If true, server_close() waits until all non-daemonic threads terminate. block_on_close = True # Threads object # used by server_close() to wait for all threads completion. _threads = _NoThreads() def process_request_thread(self, request, client_address): """Same as in BaseServer but as a thread. In addition, exception handling is done here. """ try: self.finish_request(request, client_address) except Exception: self.handle_error(request, client_address) finally: self.shutdown_request(request) def process_request(self, request, client_address): """Start a new thread to process the request.""" if self.block_on_close: vars(self).setdefault('_threads', _Threads()) t = threading.Thread(target = self.process_request_thread, args = (request, client_address)) t.daemon = self.daemon_threads self._threads.append(t) t.start() def server_close(self): super().server_close() self._threads.join() if hasattr(os, "fork"): class ForkingUDPServer(ForkingMixIn, UDPServer): pass class ForkingTCPServer(ForkingMixIn, TCPServer): pass class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass if hasattr(socket, 'AF_UNIX'): class UnixStreamServer(TCPServer): address_family = socket.AF_UNIX class UnixDatagramServer(UDPServer): address_family = socket.AF_UNIX class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass if hasattr(os, "fork"): class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass class BaseRequestHandler: """Base class for request handler classes. This class is instantiated for each request to be handled. The constructor sets the instance variables request, client_address and server, and then calls the handle() method. To implement a specific service, all you need to do is to derive a class which defines a handle() method. The handle() method can find the request as self.request, the client address as self.client_address, and the server (in case it needs access to per-server information) as self.server. Since a separate instance is created for each request, the handle() method can define other arbitrary instance variables. """ def __init__(self, request, client_address, server): self.request = request self.client_address = client_address self.server = server self.setup() try: self.handle() finally: self.finish() def setup(self): pass def handle(self): pass def finish(self): pass # The following two classes make it possible to use the same service # class for stream or datagram servers. # Each class sets up these instance variables: # - rfile: a file object from which receives the request is read # - wfile: a file object to which the reply is written # When the handle() method returns, wfile is flushed properly class StreamRequestHandler(BaseRequestHandler): """Define self.rfile and self.wfile for stream sockets.""" # Default buffer sizes for rfile, wfile. # We default rfile to buffered because otherwise it could be # really slow for large data (a getc() call per byte); we make # wfile unbuffered because (a) often after a write() we want to # read and we need to flush the line; (b) big writes to unbuffered # files are typically optimized by stdio even when big reads # aren't. rbufsize = -1 wbufsize = 0 # A timeout to apply to the request socket, if not None. timeout = None # Disable nagle algorithm for this socket, if True. # Use only when wbufsize != 0, to avoid small packets. disable_nagle_algorithm = False def setup(self): self.connection = self.request if self.timeout is not None: self.connection.settimeout(self.timeout) if self.disable_nagle_algorithm: self.connection.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True) self.rfile = self.connection.makefile('rb', self.rbufsize) if self.wbufsize == 0: self.wfile = _SocketWriter(self.connection) else: self.wfile = self.connection.makefile('wb', self.wbufsize) def finish(self): if not self.wfile.closed: try: self.wfile.flush() except socket.error: # A final socket error may have occurred here, such as # the local error ECONNABORTED. pass self.wfile.close() self.rfile.close() class _SocketWriter(BufferedIOBase): """Simple writable BufferedIOBase implementation for a socket Does not hold data in a buffer, avoiding any need to call flush().""" def __init__(self, sock): self._sock = sock def writable(self): return True def write(self, b): self._sock.sendall(b) with memoryview(b) as view: return view.nbytes def fileno(self): return self._sock.fileno() class DatagramRequestHandler(BaseRequestHandler): """Define self.rfile and self.wfile for datagram sockets.""" def setup(self): from io import BytesIO self.packet, self.socket = self.request self.rfile = BytesIO(self.packet) self.wfile = BytesIO() def finish(self): self.socket.sendto(self.wfile.getvalue(), self.client_address) sysconfig.py000064400000101755152342670510007140 0ustar00"""Access to Python's configuration information.""" import os import sys import threading from os.path import realpath __all__ = [ 'get_config_h_filename', 'get_config_var', 'get_config_vars', 'get_makefile_filename', 'get_path', 'get_path_names', 'get_paths', 'get_platform', 'get_python_version', 'get_scheme_names', 'parse_config_h', ] # Keys for get_config_var() that are never converted to Python integers. _ALWAYS_STR = { 'MACOSX_DEPLOYMENT_TARGET', } _INSTALL_SCHEMES = { 'posix_prefix': { 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', 'purelib': '{base}/lib/python{py_version_short}/site-packages', 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', 'include': '{installed_base}/include/python{py_version_short}{abiflags}', 'platinclude': '{installed_platbase}/include/python{py_version_short}{abiflags}', 'scripts': '{base}/bin', 'data': '{base}', }, 'posix_home': { 'stdlib': '{installed_base}/lib/python', 'platstdlib': '{base}/lib/python', 'purelib': '{base}/lib/python', 'platlib': '{base}/lib/python', 'include': '{installed_base}/include/python', 'platinclude': '{installed_base}/include/python', 'scripts': '{base}/bin', 'data': '{base}', }, 'nt': { 'stdlib': '{installed_base}/Lib', 'platstdlib': '{base}/Lib', 'purelib': '{base}/Lib/site-packages', 'platlib': '{base}/Lib/site-packages', 'include': '{installed_base}/Include', 'platinclude': '{installed_base}/Include', 'scripts': '{base}/Scripts', 'data': '{base}', }, # Downstream distributors can overwrite the default install scheme. # This is done to support downstream modifications where distributors change # the installation layout (eg. different site-packages directory). # So, distributors will change the default scheme to one that correctly # represents their layout. # This presents an issue for projects/people that need to bootstrap virtual # environments, like virtualenv. As distributors might now be customizing # the default install scheme, there is no guarantee that the information # returned by sysconfig.get_default_scheme/get_paths is correct for # a virtual environment, the only guarantee we have is that it is correct # for the *current* environment. When bootstrapping a virtual environment, # we need to know its layout, so that we can place the files in the # correct locations. # The "*_venv" install scheme is a scheme to bootstrap virtual environments, # essentially identical to the default posix_prefix/nt schemes. # Downstream distributors who patch posix_prefix/nt scheme are encouraged to # leave the following schemes unchanged 'posix_venv': { 'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}', 'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}', 'purelib': '{base}/lib/python{py_version_short}/site-packages', 'platlib': '{platbase}/{platlibdir}/python{py_version_short}/site-packages', 'include': '{installed_base}/include/python{py_version_short}{abiflags}', 'platinclude': '{installed_platbase}/include/python{py_version_short}{abiflags}', 'scripts': '{base}/bin', 'data': '{base}', }, 'nt_venv': { 'stdlib': '{installed_base}/Lib', 'platstdlib': '{base}/Lib', 'purelib': '{base}/Lib/site-packages', 'platlib': '{base}/Lib/site-packages', 'include': '{installed_base}/Include', 'platinclude': '{installed_base}/Include', 'scripts': '{base}/Scripts', 'data': '{base}', }, } # For the OS-native venv scheme, we essentially provide an alias: if os.name == 'nt': _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['nt_venv'] else: _INSTALL_SCHEMES['venv'] = _INSTALL_SCHEMES['posix_venv'] # For a brief period of time in the Fedora 36 life cycle, # this installation scheme existed and was documented in the release notes. # For backwards compatibility, we keep it here (at least on 3.10 and 3.11). _INSTALL_SCHEMES['rpm_prefix'] = _INSTALL_SCHEMES['posix_prefix'] # NOTE: site.py has copy of this function. # Sync it when modify this function. def _getuserbase(): env_base = os.environ.get("PYTHONUSERBASE", None) if env_base: return env_base # Emscripten, VxWorks, and WASI have no home directories if sys.platform in {"emscripten", "vxworks", "wasi"}: return None def joinuser(*args): return os.path.expanduser(os.path.join(*args)) if os.name == "nt": base = os.environ.get("APPDATA") or "~" return joinuser(base, "Python") if sys.platform == "darwin" and sys._framework: return joinuser("~", "Library", sys._framework, f"{sys.version_info[0]}.{sys.version_info[1]}") return joinuser("~", ".local") _HAS_USER_BASE = (_getuserbase() is not None) if _HAS_USER_BASE: _INSTALL_SCHEMES |= { # NOTE: When modifying "purelib" scheme, update site._get_path() too. 'nt_user': { 'stdlib': '{userbase}/Python{py_version_nodot_plat}', 'platstdlib': '{userbase}/Python{py_version_nodot_plat}', 'purelib': '{userbase}/Python{py_version_nodot_plat}/site-packages', 'platlib': '{userbase}/Python{py_version_nodot_plat}/site-packages', 'include': '{userbase}/Python{py_version_nodot_plat}/Include', 'scripts': '{userbase}/Python{py_version_nodot_plat}/Scripts', 'data': '{userbase}', }, 'posix_user': { 'stdlib': '{userbase}/{platlibdir}/python{py_version_short}', 'platstdlib': '{userbase}/{platlibdir}/python{py_version_short}', 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', 'include': '{userbase}/include/python{py_version_short}', 'scripts': '{userbase}/bin', 'data': '{userbase}', }, 'osx_framework_user': { 'stdlib': '{userbase}/lib/python', 'platstdlib': '{userbase}/lib/python', 'purelib': '{userbase}/lib/python/site-packages', 'platlib': '{userbase}/lib/python/site-packages', 'include': '{userbase}/include/python{py_version_short}', 'scripts': '{userbase}/bin', 'data': '{userbase}', }, } # This is used by distutils.command.install in the stdlib # as well as pypa/distutils (e.g. bundled in setuptools). # The self.prefix value is set to sys.prefix + /local/ # if neither RPM build nor virtual environment is # detected to make distutils install packages # into the separate location. # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe if (not (hasattr(sys, 'real_prefix') or sys.prefix != sys.base_prefix) and 'RPM_BUILD_ROOT' not in os.environ): _prefix_addition = '/local' _SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', 'scripts', 'data') _PY_VERSION = sys.version.split()[0] _PY_VERSION_SHORT = f'{sys.version_info[0]}.{sys.version_info[1]}' _PY_VERSION_SHORT_NO_DOT = f'{sys.version_info[0]}{sys.version_info[1]}' _BASE_PREFIX = os.path.normpath(sys.base_prefix) _BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) # Mutex guarding initialization of _CONFIG_VARS. _CONFIG_VARS_LOCK = threading.RLock() _CONFIG_VARS = None # True iff _CONFIG_VARS has been fully initialized. _CONFIG_VARS_INITIALIZED = False _USER_BASE = None # Regexes needed for parsing Makefile (and similar syntaxes, # like old-style Setup files). _variable_rx = r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)" _findvar1_rx = r"\$\(([A-Za-z][A-Za-z0-9_]*)\)" _findvar2_rx = r"\${([A-Za-z][A-Za-z0-9_]*)}" def _safe_realpath(path): try: return realpath(path) except OSError: return path if sys.executable: _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) else: # sys.executable can be empty if argv[0] has been changed and Python is # unable to retrieve the real program name _PROJECT_BASE = _safe_realpath(os.getcwd()) # In a virtual environment, `sys._home` gives us the target directory # `_PROJECT_BASE` for the executable that created it when the virtual # python is an actual executable ('venv --copies' or Windows). _sys_home = getattr(sys, '_home', None) if _sys_home: _PROJECT_BASE = _sys_home if os.name == 'nt': # In a source build, the executable is in a subdirectory of the root # that we want (\PCbuild\). # `_BASE_PREFIX` is used as the base installation is where the source # will be. The realpath is needed to prevent mount point confusion # that can occur with just string comparisons. if _safe_realpath(_PROJECT_BASE).startswith( _safe_realpath(f'{_BASE_PREFIX}\\PCbuild')): _PROJECT_BASE = _BASE_PREFIX # set for cross builds if "_PYTHON_PROJECT_BASE" in os.environ: _PROJECT_BASE = _safe_realpath(os.environ["_PYTHON_PROJECT_BASE"]) def is_python_build(check_home=None): if check_home is not None: import warnings warnings.warn( ( 'The check_home argument of sysconfig.is_python_build is ' 'deprecated and its value is ignored. ' 'It will be removed in Python 3.15.' ), DeprecationWarning, stacklevel=2, ) for fn in ("Setup", "Setup.local"): if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): return True return False _PYTHON_BUILD = is_python_build() if _PYTHON_BUILD: for scheme in ('posix_prefix', 'posix_home'): # On POSIX-y platforms, Python will: # - Build from .h files in 'headers' (which is only added to the # scheme when building CPython) # - Install .h files to 'include' scheme = _INSTALL_SCHEMES[scheme] scheme['headers'] = scheme['include'] scheme['include'] = '{srcdir}/Include' scheme['platinclude'] = '{projectbase}/.' del scheme def _subst_vars(s, local_vars): try: return s.format(**local_vars) except KeyError as var: try: return s.format(**os.environ) except KeyError: raise AttributeError(f'{var}') from None def _extend_dict(target_dict, other_dict): target_keys = target_dict.keys() for key, value in other_dict.items(): if key in target_keys: continue target_dict[key] = value _CONFIG_VARS_LOCAL = None def _config_vars_local(): # This function returns the config vars with prefixes amended to /usr/local # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe global _CONFIG_VARS_LOCAL if _CONFIG_VARS_LOCAL is None: _CONFIG_VARS_LOCAL = dict(get_config_vars()) _CONFIG_VARS_LOCAL['base'] = '/usr/local' _CONFIG_VARS_LOCAL['platbase'] = '/usr/local' return _CONFIG_VARS_LOCAL def _expand_vars(scheme, vars): res = {} if vars is None: vars = {} # when we are not in a virtual environment or an RPM build # we change '/usr' to '/usr/local' # to avoid surprises, we explicitly check for the /usr/ prefix # Python virtual environments have different prefixes # we only do this for posix_prefix, not to mangle the venv scheme # posix_prefix is used by sudo pip install # we only change the defaults here, so explicit --prefix will take precedence # https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe if (scheme == 'posix_prefix' and sys.prefix == '/usr' and 'RPM_BUILD_ROOT' not in os.environ): _extend_dict(vars, _config_vars_local()) else: _extend_dict(vars, get_config_vars()) if os.name == 'nt': # On Windows we want to substitute 'lib' for schemes rather # than the native value (without modifying vars, in case it # was passed in) vars = vars | {'platlibdir': 'lib'} for key, value in _INSTALL_SCHEMES[scheme].items(): if os.name in ('posix', 'nt'): value = os.path.expanduser(value) res[key] = os.path.normpath(_subst_vars(value, vars)) return res def _get_preferred_schemes(): if os.name == 'nt': return { 'prefix': 'nt', 'home': 'posix_home', 'user': 'nt_user', } if sys.platform == 'darwin' and sys._framework: return { 'prefix': 'posix_prefix', 'home': 'posix_home', 'user': 'osx_framework_user', } return { 'prefix': 'posix_prefix', 'home': 'posix_home', 'user': 'posix_user', } def get_preferred_scheme(key): if key == 'prefix' and sys.prefix != sys.base_prefix: return 'venv' scheme = _get_preferred_schemes()[key] if scheme not in _INSTALL_SCHEMES: raise ValueError( f"{key!r} returned {scheme!r}, which is not a valid scheme " f"on this platform" ) return scheme def get_default_scheme(): return get_preferred_scheme('prefix') def _parse_makefile(filename, vars=None, keep_unresolved=True): """Parse a Makefile-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ import re if vars is None: vars = {} done = {} notdone = {} with open(filename, encoding=sys.getfilesystemencoding(), errors="surrogateescape") as f: lines = f.readlines() for line in lines: if line.startswith('#') or line.strip() == '': continue m = re.match(_variable_rx, line) if m: n, v = m.group(1, 2) v = v.strip() # `$$' is a literal `$' in make tmpv = v.replace('$$', '') if "$" in tmpv: notdone[n] = v else: try: if n in _ALWAYS_STR: raise ValueError v = int(v) except ValueError: # insert literal `$' done[n] = v.replace('$$', '$') else: done[n] = v # do variable interpolation here variables = list(notdone.keys()) # Variables with a 'PY_' prefix in the makefile. These need to # be made available without that prefix through sysconfig. # Special care is needed to ensure that variable expansion works, even # if the expansion uses the name without a prefix. renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') while len(variables) > 0: for name in tuple(variables): value = notdone[name] m1 = re.search(_findvar1_rx, value) m2 = re.search(_findvar2_rx, value) if m1 and m2: m = m1 if m1.start() < m2.start() else m2 else: m = m1 if m1 else m2 if m is not None: n = m.group(1) found = True if n in done: item = str(done[n]) elif n in notdone: # get it on a subsequent round found = False elif n in os.environ: # do it like make: fall back to environment item = os.environ[n] elif n in renamed_variables: if (name.startswith('PY_') and name[3:] in renamed_variables): item = "" elif 'PY_' + n in notdone: found = False else: item = str(done['PY_' + n]) else: done[n] = item = "" if found: after = value[m.end():] value = value[:m.start()] + item + after if "$" in after: notdone[name] = value else: try: if name in _ALWAYS_STR: raise ValueError value = int(value) except ValueError: done[name] = value.strip() else: done[name] = value variables.remove(name) if name.startswith('PY_') \ and name[3:] in renamed_variables: name = name[3:] if name not in done: done[name] = value else: # Adds unresolved variables to the done dict. # This is disabled when called from distutils.sysconfig if keep_unresolved: done[name] = value # bogus variable reference (e.g. "prefix=$/opt/python"); # just drop it since we can't deal variables.remove(name) # strip spurious spaces for k, v in done.items(): if isinstance(v, str): done[k] = v.strip() # save the results in the global dictionary vars.update(done) return vars def get_makefile_filename(): """Return the path of the Makefile.""" if _PYTHON_BUILD: return os.path.join(_PROJECT_BASE, "Makefile") if hasattr(sys, 'abiflags'): config_dir_name = f'config-{_PY_VERSION_SHORT}{sys.abiflags}' else: config_dir_name = 'config' if hasattr(sys.implementation, '_multiarch'): config_dir_name += f'-{sys.implementation._multiarch}' return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') def _get_sysconfigdata_name(): multiarch = getattr(sys.implementation, '_multiarch', '') return os.environ.get( '_PYTHON_SYSCONFIGDATA_NAME', f'_sysconfigdata_{sys.abiflags}_{sys.platform}_{multiarch}', ) def _generate_posix_vars(): """Generate the Python module containing build-time variables.""" import pprint vars = {} # load the installed Makefile: makefile = get_makefile_filename() try: _parse_makefile(makefile, vars) except OSError as e: msg = f"invalid Python installation: unable to open {makefile}" if hasattr(e, "strerror"): msg = f"{msg} ({e.strerror})" raise OSError(msg) # load the installed pyconfig.h: config_h = get_config_h_filename() try: with open(config_h, encoding="utf-8") as f: parse_config_h(f, vars) except OSError as e: msg = f"invalid Python installation: unable to open {config_h}" if hasattr(e, "strerror"): msg = f"{msg} ({e.strerror})" raise OSError(msg) # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. if _PYTHON_BUILD: vars['BLDSHARED'] = vars['LDSHARED'] # There's a chicken-and-egg situation on OS X with regards to the # _sysconfigdata module after the changes introduced by #15298: # get_config_vars() is called by get_platform() as part of the # `make pybuilddir.txt` target -- which is a precursor to the # _sysconfigdata.py module being constructed. Unfortunately, # get_config_vars() eventually calls _init_posix(), which attempts # to import _sysconfigdata, which we won't have built yet. In order # for _init_posix() to work, if we're on Darwin, just mock up the # _sysconfigdata module manually and populate it with the build vars. # This is more than sufficient for ensuring the subsequent call to # get_platform() succeeds. name = _get_sysconfigdata_name() if 'darwin' in sys.platform: import types module = types.ModuleType(name) module.build_time_vars = vars sys.modules[name] = module pybuilddir = f'build/lib.{get_platform()}-{_PY_VERSION_SHORT}' if hasattr(sys, "gettotalrefcount"): pybuilddir += '-pydebug' os.makedirs(pybuilddir, exist_ok=True) destfile = os.path.join(pybuilddir, name + '.py') with open(destfile, 'w', encoding='utf8') as f: f.write('# system configuration generated and used by' ' the sysconfig module\n') f.write('build_time_vars = ') pprint.pprint(vars, stream=f) # Create file used for sys.path fixup -- see Modules/getpath.c with open('pybuilddir.txt', 'w', encoding='utf8') as f: f.write(pybuilddir) def _init_posix(vars): """Initialize the module as appropriate for POSIX systems.""" # _sysconfigdata is generated at build time, see _generate_posix_vars() name = _get_sysconfigdata_name() _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0) build_time_vars = _temp.build_time_vars vars.update(build_time_vars) def _init_non_posix(vars): """Initialize the module as appropriate for NT""" # set basic install directories import _imp vars['LIBDEST'] = get_path('stdlib') vars['BINLIBDEST'] = get_path('platstdlib') vars['INCLUDEPY'] = get_path('include') try: # GH-99201: _imp.extension_suffixes may be empty when # HAVE_DYNAMIC_LOADING is not set. In this case, don't set EXT_SUFFIX. vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] except IndexError: pass vars['EXE'] = '.exe' vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) vars['TZPATH'] = '' # # public APIs # def parse_config_h(fp, vars=None): """Parse a config.h-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ if vars is None: vars = {} import re define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") while True: line = fp.readline() if not line: break m = define_rx.match(line) if m: n, v = m.group(1, 2) try: if n in _ALWAYS_STR: raise ValueError v = int(v) except ValueError: pass vars[n] = v else: m = undef_rx.match(line) if m: vars[m.group(1)] = 0 return vars def get_config_h_filename(): """Return the path of pyconfig.h.""" if _PYTHON_BUILD: if os.name == "nt": inc_dir = os.path.join(_PROJECT_BASE, "PC") else: inc_dir = _PROJECT_BASE else: inc_dir = get_path('platinclude') return os.path.join(inc_dir, 'pyconfig-64.h') def get_scheme_names(): """Return a tuple containing the schemes names.""" return tuple(sorted(_INSTALL_SCHEMES)) def get_path_names(): """Return a tuple containing the paths names.""" return _SCHEME_KEYS def get_paths(scheme=get_default_scheme(), vars=None, expand=True): """Return a mapping containing an install scheme. ``scheme`` is the install scheme name. If not provided, it will return the default scheme for the current platform. """ if expand: return _expand_vars(scheme, vars) else: return _INSTALL_SCHEMES[scheme] def get_path(name, scheme=get_default_scheme(), vars=None, expand=True): """Return a path corresponding to the scheme. ``scheme`` is the install scheme name. """ return get_paths(scheme, vars, expand)[name] def _init_config_vars(): global _CONFIG_VARS _CONFIG_VARS = {} # Normalized versions of prefix and exec_prefix are handy to have; # in fact, these are the standard versions used most places in the # Distutils. _PREFIX = os.path.normpath(sys.prefix) _EXEC_PREFIX = os.path.normpath(sys.exec_prefix) _CONFIG_VARS['prefix'] = _PREFIX # FIXME: This gets overwriten by _init_posix. _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX # FIXME: This gets overwriten by _init_posix. _CONFIG_VARS['py_version'] = _PY_VERSION _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT _CONFIG_VARS['installed_base'] = _BASE_PREFIX _CONFIG_VARS['base'] = _PREFIX _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX _CONFIG_VARS['platbase'] = _EXEC_PREFIX _CONFIG_VARS['projectbase'] = _PROJECT_BASE _CONFIG_VARS['platlibdir'] = sys.platlibdir try: _CONFIG_VARS['abiflags'] = sys.abiflags except AttributeError: # sys.abiflags may not be defined on all platforms. _CONFIG_VARS['abiflags'] = '' try: _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') except AttributeError: _CONFIG_VARS['py_version_nodot_plat'] = '' if os.name == 'nt': _init_non_posix(_CONFIG_VARS) _CONFIG_VARS['VPATH'] = sys._vpath if os.name == 'posix': _init_posix(_CONFIG_VARS) if _HAS_USER_BASE: # Setting 'userbase' is done below the call to the # init function to enable using 'get_config_var' in # the init-function. _CONFIG_VARS['userbase'] = _getuserbase() # Always convert srcdir to an absolute path srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) if os.name == 'posix': if _PYTHON_BUILD: # If srcdir is a relative path (typically '.' or '..') # then it should be interpreted relative to the directory # containing Makefile. base = os.path.dirname(get_makefile_filename()) srcdir = os.path.join(base, srcdir) else: # srcdir is not meaningful since the installation is # spread about the filesystem. We choose the # directory containing the Makefile since we know it # exists. srcdir = os.path.dirname(get_makefile_filename()) _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) # OS X platforms require special customization to handle # multi-architecture, multi-os-version installers if sys.platform == 'darwin': import _osx_support _osx_support.customize_config_vars(_CONFIG_VARS) global _CONFIG_VARS_INITIALIZED _CONFIG_VARS_INITIALIZED = True def get_config_vars(*args): """With no arguments, return a dictionary of all configuration variables relevant for the current platform. On Unix, this means every variable defined in Python's installed Makefile; On Windows it's a much smaller set. With arguments, return a list of values that result from looking up each argument in the configuration variable dictionary. """ global _CONFIG_VARS_INITIALIZED # Avoid claiming the lock once initialization is complete. if not _CONFIG_VARS_INITIALIZED: with _CONFIG_VARS_LOCK: # Test again with the lock held to avoid races. Note that # we test _CONFIG_VARS here, not _CONFIG_VARS_INITIALIZED, # to ensure that recursive calls to get_config_vars() # don't re-enter init_config_vars(). if _CONFIG_VARS is None: _init_config_vars() else: # If the site module initialization happened after _CONFIG_VARS was # initialized, a virtual environment might have been activated, resulting in # variables like sys.prefix changing their value, so we need to re-init the # config vars (see GH-126789). if _CONFIG_VARS['base'] != os.path.normpath(sys.prefix): with _CONFIG_VARS_LOCK: _CONFIG_VARS_INITIALIZED = False _init_config_vars() if args: vals = [] for name in args: vals.append(_CONFIG_VARS.get(name)) return vals else: return _CONFIG_VARS def get_config_var(name): """Return the value of a single variable using the dictionary returned by 'get_config_vars()'. Equivalent to get_config_vars().get(name) """ return get_config_vars().get(name) def get_platform(): """Return a string that identifies the current platform. This is used mainly to distinguish platform-specific build directories and platform-specific built distributions. Typically includes the OS name and version and the architecture (as supplied by 'os.uname()'), although the exact information included depends on the OS; on Linux, the kernel version isn't particularly important. Examples of returned values: linux-i586 linux-alpha (?) solaris-2.6-sun4u Windows will return one of: win-amd64 (64-bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) win-arm64 (64-bit Windows on ARM64 (aka AArch64) win32 (all others - specifically, sys.platform is returned) For other non-POSIX platforms, currently just returns 'sys.platform'. """ if os.name == 'nt': if 'amd64' in sys.version.lower(): return 'win-amd64' if '(arm)' in sys.version.lower(): return 'win-arm32' if '(arm64)' in sys.version.lower(): return 'win-arm64' return sys.platform if os.name != "posix" or not hasattr(os, 'uname'): # XXX what about the architecture? NT is Intel or Alpha return sys.platform # Set for cross builds explicitly if "_PYTHON_HOST_PLATFORM" in os.environ: return os.environ["_PYTHON_HOST_PLATFORM"] # Try to distinguish various flavours of Unix osname, host, release, version, machine = os.uname() # Convert the OS name to lowercase, remove '/' characters, and translate # spaces (for "Power Macintosh") osname = osname.lower().replace('/', '') machine = machine.replace(' ', '_') machine = machine.replace('/', '-') if osname[:5] == "linux": # At least on Linux/Intel, 'machine' is the processor -- # i386, etc. # XXX what about Alpha, SPARC, etc? return f"{osname}-{machine}" elif osname[:5] == "sunos": if release[0] >= "5": # SunOS 5 == Solaris 2 osname = "solaris" release = f"{int(release[0]) - 3}.{release[2:]}" # We can't use "platform.architecture()[0]" because a # bootstrap problem. We use a dict to get an error # if some suspicious happens. bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} machine += f".{bitness[sys.maxsize]}" # fall through to standard osname-release-machine representation elif osname[:3] == "aix": from _aix_support import aix_platform return aix_platform() elif osname[:6] == "cygwin": osname = "cygwin" import re rel_re = re.compile(r'[\d.]+') m = rel_re.match(release) if m: release = m.group() elif osname[:6] == "darwin": import _osx_support osname, release, machine = _osx_support.get_platform_osx( get_config_vars(), osname, release, machine) return f"{osname}-{release}-{machine}" def get_python_version(): return _PY_VERSION_SHORT def expand_makefile_vars(s, vars): """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in 'string' according to 'vars' (a dictionary mapping variable names to values). Variables not present in 'vars' are silently expanded to the empty string. The variable values in 'vars' should not contain further variable expansions; if 'vars' is the output of 'parse_makefile()', you're fine. Returns a variable-expanded version of 's'. """ import re # This algorithm does multiple expansion, so if vars['foo'] contains # "${bar}", it will expand ${foo} to ${bar}, and then expand # ${bar}... and so forth. This is fine as long as 'vars' comes from # 'parse_makefile()', which takes care of such expansions eagerly, # according to make's variable expansion semantics. while True: m = re.search(_findvar1_rx, s) or re.search(_findvar2_rx, s) if m: (beg, end) = m.span() s = s[0:beg] + vars.get(m.group(1)) + s[end:] else: break return s def _print_dict(title, data): for index, (key, value) in enumerate(sorted(data.items())): if index == 0: print(f'{title}: ') print(f'\t{key} = "{value}"') def _main(): """Display all information sysconfig detains.""" if '--generate-posix-vars' in sys.argv: _generate_posix_vars() return print(f'Platform: "{get_platform()}"') print(f'Python version: "{get_python_version()}"') print(f'Current installation scheme: "{get_default_scheme()}"') print() _print_dict('Paths', get_paths()) print() _print_dict('Variables', get_config_vars()) if __name__ == '__main__': _main() __pycache__/sndhdr.cpython-312.opt-1.pyc000064400000024674152342670510013722 0ustar00 ֦idZddlZejedddgZddlmZedd Zd ej_d ej_d ej_d ej_dej_dZ dZgZdZej#edZej#edZej#edZej#edZej#edZej#edZej#edZej#edZdZdZdZdZdZedk(reyy) aRoutines to help recognizing sound files. Function whathdr() recognizes various types of sound file headers. It understands almost all headers that SOX can decode. The return tuple contains the following items, in this order: - file type (as SOX understands it) - sampling rate (0 if unknown or hard to decode) - number of channels (0 if unknown or hard to decode) - number of frames in the file (-1 if unknown or hard to decode) - number of bits/sample, or 'U' for U-LAW, or 'A' for A-LAW If the file doesn't have a recognizable type, it returns None. If the file can't be opened, OSError is raised. To compute the total time, divide the number of frames by the sampling rate (a frame contains a sample for each channel). Function what() calls whathdr(). (It used to also use some heuristics for raw data, but this doesn't work very well.) Finally, the function test() is a simple main program that calls what() for all files mentioned on the argument list. For directory arguments it calls what() for all files in that directory. Default argument is "." (testing all files in the current directory). The option -r tells it to recurse down directories found inside explicitly given directories. N) )removewhatwhathdr) namedtuple SndHeadersz.filetype framerate nchannels nframes sampwidthzThe value for type indicates the data type and will be one of the strings 'aifc', 'aiff', 'au','hcom', 'sndr', 'sndt', 'voc', 'wav', '8svx', 'sb', 'ub', or 'ul'.zYThe sampling_rate will be either the actual value or 0 if unknown or difficult to decode.z^The number of channels or 0 if it cannot be determined or if the value is difficult to decode.z?The value for frames will be either the number of frames or -1.zAEither the sample size in bits or 'A' for A-LAW or 'U' for u-LAW.ct|}|S)zGuess the type of a sound file.)r)filenameress /usr/lib64/python3.12/sndhdr.pyrr8s ( C Jct|d5}|jd}tD] }|||}|st|ccdddS dddy#1swYyxYw)zRecognize sound headers.rbiN)openreadtestsr )r fhtfr s r rr>sU h  FF3KBQ(C!3''     s&A AAActj5tjdtddl}ddd|j dsy|dddk(rd }n |ddd k(rd }ny|j d j|d }||j|j|jd|jzfS#1swYxYw#tjf$rYywxYw) zAIFC and AIFF filesignore)categoryrNFORM sAIFCaifcsAIFFaiffr)warningscatch_warnings simplefilterDeprecationWarningr startswithseekrEOFErrorError getframerate getnchannels getnframes getsampwidth)rrrfmtas r test_aifcr.Os  "h1CD # << 2w' 1RG FF1I IIa  !1>>#3 LLNA 00 22! # " djj !s C 8C CC0/C0c*|jdrt}n|dddvrt}nyd}||dd}||dd}||dd}||dd }||d d }d } |d k(rd } n|d k(rd} n |dk(rd} d } nd} | |z} | r|| z } nd} |||| | fS)zAU and SND filess.sndN)sds.sdns.aurrUr?)r$ get_long_be get_long_le) rrfuncfiletypehdr_size data_sizeencodingrate nchannels sample_size sample_bits frame_sizenframes r test_aurGgs||G 2A% %HAaF|HQqW IAbH~H "R>DQr"XIK1} Q Q   y(JZ' T9fk 99rcb|dddk7s|dddk7ryt|dd }|rd |z }nd }d |d ddfS)z HCOM fileAEsFSSDsHCOMNi"Vrhcomr5r9r)r:)rrdivisorrAs r test_hcomrQsRBx7aCjG3!C*%Gw 4B !!rc|jdsyt|dd}d}d|cxkrdkr&nn#||dk(rd||d zz }|rtd |z }d |dd d fS)zVOC filesCreative Voice FileNr3rir5r0g.Avocr9r)r$ get_short_leint)rrsbseekrAratecodes r test_vocrZss <<2 3 !Br( #F DFSQvY!^6!8$ y8+,D $2q  rcPddl}|jdr|dddk7s|dddk7ry|jd |j|d }d |j |j|jd|jzfS#t|j f$rYywxYw) zWAV filerNsRIFFrrsWAVEr2sfmt rwav) waver$r%rr&r'r(r)r*r+)rrr]ws r test_wavr_s << AaGw$6!Br(g:MFF1I IIa  1>>#Q^^%5<<>1Q^^%5#5 77 djj !sB B%$B%c8|jdr|dddk7ryy)z 8SVX filerrrs8SVXN)8svxrr5rr)r$)rrs r test_8svxrbs! << AaGw$6 rcl|jdr#t|dd}t|dd}d|d|dfSy) z SNDT filesSOUNDrrr3rSsndtr5N)r$r;rV)rrnsamplesrAs r test_sndtrfsD||Hq2w'AbH%tQ!++rcn|jdr$t|dd}d|cxkrdkr ny d|ddd fSy y ) z SNDR filesr7r0iiasndrr5r9rN)r$rV)rrrAs r test_sndrrisF||GAaF# 4 5 4B) ) !rcB|ddz|ddzz|ddzz|dzS)Nrr4r5r2r7rrbs r r:r:3 aDBJ1Q42: &!A$!) 4qt ;;rcB|ddz|ddzz|ddzz|dzS)Nrr4r7r2r5rrrkrls r r;r;rnrc|ddz|dzS)Nrrr5rkrls r get_short_berq aDAI1 rc|ddz|dzS)Nr5rrrkrls r rVrVrrrc\ddl}d}|jddr#|jddk(r|jdd=d} |jddrt|jdd|dytdg|dy#t$r/|jj d|j dYywxYw)Nrr5z-rr7.z [Interrupted] )sysargvtestallKeyboardInterruptstderrwriteexit)rv recursives r testr~sI xx| t+ HHQqSM  88AB< CHHQRL)Q / SE9a (  ,-  s)A3$A335B+*B+cddl}ddl}|D]}|jj|rwt |dzd|s|rWt dddl}|j |jj |j|d}t||dt dt |dzd|jj t t|y#t$rt d YwxYw) Nrz/: )endzrecursing down:*z*** directory (use -r) ***:z*** not found ***) rvospathisdirprintglobjoinescaperxstdoutflushrOSError)listr}toplevelrvrr rnamess r rxrxs  77== " (T/s +H'( "'',,t{{8/Dc"JKy!,23 (S.c * JJ    +d8n% +)* +s C""C98C9__main__)__doc__r _deprecated__name____all__ collectionsrr r= frameraterBnframes sampwidthrrrr.appendrGrQrZr_rbrfrir:r;rqrVr~rxrkrr rsk:Xg. 9 "  HJ  > !1 !6  !#   2* Y:> W " Y ! X 7 X Y, Y* Y<< +* zFr__pycache__/contextvars.cpython-312.pyc000064400000000407152342670510014045 0ustar00 ֦i ddlmZmZmZmZdZy))Context ContextVarToken copy_contextN) _contextvarsrrrr__all__$/usr/lib64/python3.12/contextvars.pyr sAA =r __pycache__/_pydatetime.cpython-312.opt-1.pyc000064400000263025152342670510014737 0ustar00 ֦ig ldZdZddlZddlZddlZddlmZ dZ dZ dZ dZ d Zgd Zd gZdZeddD]Zej'eeez Z[[d Zd ZdZdZdZedZedZedZdZgdZgdZdZdEdZ dFdZ!dZ"dZ#dZ$dZ%gdZ&dZ'd Z(d!Z)d"Z*d#Z+d$Z,d%Z-d&Z.d'Z/d(Z0Gd)d*Z1e1d+e1_2e1d,d-d.d.d/0e1_3e1d1e1_4Gd2d3Z5e5Z6e5ddde5_2e5dd4d5e5_3e1d6e5_4Gd7d8Z7Gd9d:e8Z9e9Z:[9e7Z;Gd;d<ZeZ<eddde_2ed-d.d.d/e_3e1d1e_4Gd=d>e5Z=e=ddde=_2e=dd4d5d-d.d.d/e=_3e1d1e=_4d?Z>Gd@dAe7Z?e?je1dxZAe?_Be?je1d-d.B e?_2e?je1d-d.Be?_3e=dCdde?jDZCy)GzConcrete date/time and related types. See http://www.iana.org/time-zones/repository/tz-link.html for time zone and DST data sources. ) datedatetimetime timedeltatimezonetzinfoMINYEARMAXYEARUTCN)indexc"||k(rdS||kDrdSdS)Nr xys $/usr/lib64/python3.12/_pydatetime.py_cmprsQ1.QA.B.c>|jj}|dk(ry|S)N _pydatetimer) __class__ __module__)self module_names r_get_class_modulers"..++Km#rri'i۹7) rrrr rrr rr rrc:|dzdk(xr|dzdk7xs|dzdk(S)zyear -> 1 if leap year, else 0.r dr)years r_is_leapr&1s* !8q= AdSjAo@qArc:|dz }|dz|dzz|dzz |dzzS)z2year -> number of days before January 1st of year.rmr"r#r$r)r%rs r_days_before_yearr)5s/ qA S51a4 number of days in that month in that year.)r&_DAYS_IN_MONTHr%months r_days_in_monthr0:s zhtn %  rc:t||dkDxr t|zS)zCyear, month -> number of days in year preceding first day of month.r+)_DAYS_BEFORE_MONTHr&r.s r_days_before_monthr3As! e $ (Dhtn EErcPt||}t|t||z|zS)z>year, month, day -> ordinal, considering 01-Jan-0001 as day 1.)r0r)r3r%r/daydims r_ymd2ordr8Fs4 u %C d # tU + ,  riec|dz}t|t\}}|dzdz}t|t\}}t|t\}}t|d\}}||dz|dzz|zz }|dk(s|dk(r|dz ddfS|dk(xr |d k7xs|dk(}|d zd z }t||d kDxr|z}||kDr|dz}|t ||d k(xr|zz}||z}|||dzfS) z@ordinal -> (year, month, day), considering 01-Jan-0001 as day 1.rr$r(r#r" r2r:r+)divmod_DI400Y_DI100Y_DI4Yr2r-) nn400r%n100n4n1leapyearr/ precedings r_ord2ymdrK_s#.FAQ GD! #:>DQ GD! 1e EB 1cNEBD3Ja " $$D Qw$!)Avr2~Qw2B"H1 H VME"5)UQY-C8DI1}  ^E*eqj.EXFF NA ! r) NJanFebMarAprMayJunJulAugSepOctNovDec)NMonTueWedThuFriSatSunc t|||dzdz}t|||z}tj|||||||||f S)N)r8r3_time struct_time) rmdhhmmssdstflagwdaydnums r_build_struct_timerlsO Q1  !Q &D a #a 'D   aAr2r4wG HHrcdddddd}|dk(r|rdnd }n |d k(r|d z} ||}|j||||S#t$r td wxYw) Nz{:02d}z {:02d}:{:02d}z{:02d}:{:02d}:{:02d}z{:02d}:{:02d}:{:02d}.{:03d}z{:02d}:{:02d}:{:02d}.{:06d})hoursminutesseconds milliseconds microsecondsautorrrprqzUnknown timespec value)formatKeyError ValueError)rfrgrhustimespecspecsfmts r _format_timer|s~")55  E6%'>Y ^ # t *Hozz"b"b)) 31223s 9Ac8d}||jdkrd}| }nd}t|td\}}t|td\}}|d||||fzz }|s |jr2|d ||jfzz }|jr|d |jzz }|S) Nr -+rrnroz %s%02d%s%02dz%s%02d.%06d)daysr@rrrrp)offsepssignrfrgrhs r_format_offsetrs A  88a<D$CDYQ/0BIa01B ^tRb1 11  S"**-- -AWr.. Hrcd}d}d}d}g}|j}dt|} } | | krq|| } | dz } | dk(rR| | krC|| } | dz } | dk(r%|dt|ddz}|j|n | dk(r>|*t|drt |j d }nd }|j|n| d k(rk| | kr|| } | dz } | dk(r>|*t|drt |j d }nd }|j|n|d|| || nm| d k(rF|2d }t|d r$|j } | | jdd}|j|n"|d|| n|dn|| | | krqd j|}tj||S)Nr r%fz%06d microsecondz utcoffsetr~r:Ztznamez%%) appendlengetattrhasattrrrrreplacejoinrbstrftime)objectru timetuplefreplacezreplace colonzreplaceZreplace newformatpushirDchch2rs r_wrap_strftimersHHMHI   D c&kqA a% AY Q 91uAYQ9'#)GF4A1-F$F$$X.3Y'"6;7'5f6F6F6Hb'QH')H$$X.3Y1u$QiQ#:,4#*6;#?4B6CSCSCU[^4_M46M%,,]; I H I3Y'#%"684 & A }+,99S$+?$$X.IHS Hg a%h "I >>)Y //rc |dvS)N 0123456789r)cs r_is_ascii_digitrs rcJt|}|dk(ryd}d}|d|k(rL|d|k(rC|dkr td|dkDr-|d|k(r%|dk(r td|d kDrt|d ryy yy |d|k(r2d}||krt||sn |d z }||kr|dkr|S|d zd k(ryyy) NrarWr"r:zInvalid ISO string rr+r )rrwr)dtstr len_dtstrdate_separatorweek_indicatoridxs r"_find_isoformat_datetime_separatorrsE IA~NN Qx>! 8~ %1} !5661}q^!;>$%9::r>oeBi&@ 8~ %C /&uSz2q / Qw Qw!|rct|dd}|ddk(}d|z}|||dzdk(rp|dz }t|||dz}|dz }d}t||kDr/|||dzdk(|k7r td||z }t|||dz}tt |||St|||dz}|dz }|||dzdk(|k7r td||z }t|||dz}|||gS)Nr r"rrrr+z"Inconsistent use of dash separator)intrrwlist_isoweek_to_gregorian)rr%has_sepposweeknodaynor/r6s r_parse_isoformat_daterOs8 uQqz?DAh#oG g+C SqS  qU3sQw'( q u: c#'"c)g5 !EFF 7NCc#'*+E)$>??E#cAg&' q #cAg # %' 1AB B w%C!G$%eS!!r)ii'rtr#rct|}gd}d}tddD]c}||z dkr tdt|||dz||<|dz }|||dz}|dk(r|dk(}|r|dk\rnr|dk7rtd|z||z }e||kr}||d vr td |dz }t t t ||ds td ||z }|d k\rd }n|}t||||z|d<|d kr|dxxt|dz zcc<|S) N)r r r r r r=r+zIncomplete time componentrrzInvalid time separator: %cz.,zInvalid microsecond componentzNon-digit values in fractionr`)rrangerwrallmapr_FRACTION_CORRECTION) tstrlen_str time_compsrcomp next_charr len_remainderto_parses r_parse_hh_mm_ss_ffrvsS$iGJ Ca  cMQ 89 9tCA/ 4 qSUO 193&GDAI  yC'9IEF F w%( W} 9D <= = 1HCs?DJ78 !?@@#cMM!(S#h, 89JqM!|1 !5hqj!AA rcbt|}|dkr td|jddzxs*|jddzxs|jddz}|dkDr|d|dz n|}t|}d}||k(r|ddk(rtj }n|dkDr||d}t|d vr td t|}t d |Drtj }n8||dz dk(rdnd}t|d|d|d|d  } t || z}|j||S)Nr+zIsoformat time too shortrrrrr r)r rr=zMalformed time zone stringc3&K|] }|dk( yw)r Nr).0rs r z(_parse_isoformat_time..s(x!qAvxsr=rnrorprr) rrwfindrrutcrrr) rrtz_postimestrrtzitzstrtz_compstzsigntds r_parse_isoformat_timersC$iG{344iinq LDIIcNQ$6L$))C.1:LF!'!d9F1HoG#G,J C T"X_ll !VW  u: "9: :%e, (x( (,,C +s2RF!hqk#+A;Xa[JB6B;'Cc rcht|cxkr tksntd|d|cxkrdks@nd}|dk(r't|dddz}|dk(s|dk(r t |rd }|rtd |d|cxkrd ksntd |d |dz dz|dz z}t |}||z}t |S)NzYear is out of range: r 5Trrar"r=FzInvalid week: rzInvalid weekday: z (range is [1, 7]))rr rwr8r&_isoweek1mondayrK)r%weekr6 out_of_range first_weekday day_offsetday_1ord_days rrrs d %g %1$899 t=b= 2:%T1a014M"}'9'/~$ ~dV45 5 s;Q;,SE1CDEE(a37+J D !Ej G G rcX|(t|tstdt|zyy)Nz4tzinfo.tzname() must return None or string, not '%s') isinstancestr TypeErrortype)names r _check_tznamers7  4 5#%)$Z01 1!6rc|yt|tstd|dt|dtd |cxkrtdksnt |d|dy)Nztzinfo.z'() must return None or timedelta, not ''rz()=zG, must be strictly between -timedelta(hours=24) and timedelta(hours=24))rrrrrw)roffsets r_check_utc_offsetrse ~ fi (48$v,HI I aL=6 0IaL 0() ) 1rc,t|}t|}t|}t|cxkr tksntdttfz|d|cxkrdksntd|t ||}d|cxkr|ksntd|z||||fS)Nzyear must be in %d..%drr<zmonth must be in 1..12zday must be in 1..%d)_indexrr rwr0r5s r_check_date_fieldsr s $ )K)K w0 g T  S\ $ lE * !89L$*<$A !G\"7G4MD' IA LA|,L$*<$A !G\"7G4MD' IA LA !89L\73  W G$a T  q6I  F JK K~~c"   rcg}|jr|jd|jz|jr|jd|jz|jr|jd|jz|s|jdt |d|j j ddj|dS) Nzdays=%dz seconds=%dzmicroseconds=%d0.(, ))r rr r rr __qualname__r)rargss r__repr__ztimedelta.__repr__s :: KK DJJ. / == KK t}}4 5    KK)D,>,>> ? KK /5"nn99"iio/ /rct|jd\}}t|d\}}d|||fz}|jrd}d||jz|z}|jr|d|jzz}|S)Nrz %d:%02d:%02dc2|t|dk7xrdxsdfS)Nrrr~)r)rDs rpluralz!timedelta.__str__..plurals#a&A+-#333rz %d day%s, r)r@r r r )rrgrhrfrr-s r__str__ztimedelta.__str__s| r*BBB b"b\ ) :: 4tzz 22a7A   Gd0000Arc`|jdz|jzdz|jzdz S)zTotal seconds in the duration.rr)rrprrrs r total_secondsztimedelta.total_secondss7U"T\\1U:!!"%*+ +rc|jSrr r0s rrztimedelta.dayszzrc|jSrp)r r0s rrpztimedelta.secondss}}rc|jSrr)r r0s rrrztimedelta.microsecondss!!!rct|trRt|j|jz|j|jz|j|jzSt SNrrr r r NotImplementedrothers r__add__ztimedelta.__add__X eY 'TZZ%++5!]]U^^;!//%2E2EEG Grct|trRt|j|jz |j|jz |j|jz St Sr;r<r>s r__sub__ztimedelta.__sub__rArc:t|tr| |zStSr;)rrr=r>s r__rsub__ztimedelta.__rsub__s eY '55= rc^t|j |j |j Sr;)rr r r r0s r__neg__ztimedelta.__neg__ s.$**--,,,. .rc|Sr;rr0s r__pos__ztimedelta.__pos__s rc*|jdkr| S|SNr r4r0s r__abs__ztimedelta.__abs__s ::>5LKrc0t|tr4t|j|z|j|z|j |zSt|t r=|j}|j\}}tddt||z|StSrK) rrrr r r r_to_microsecondsas_integer_ratiorr=rr?usecrrs r__mul__ztimedelta.__mul__s eS !TZZ%/!]]U2!//%79 9 eU #((*D))+DAqQ#4TAXq#AB BrcZ|jdz|jzdz|jzS)Nrrr r r r0s rrNztimedelta._to_microseconds(s/w'$--77B""# $rct|ttfstS|j }t|tr||j zSt|trtdd||zSyrK)rrrr=rN)rr?rQs r __floordiv__ztimedelta.__floordiv__,se%#y!12! !$$& eY '51133 3 eS !Q45=1 1 "rctt|tttfstS|j }t|tr||j z St|trtddt ||St|tr-|j\}}tddt ||z|SyrK)rrrrr=rNrrOrPs r __truediv__ztimedelta.__truediv__5s%#ui!89! !$$& eY '%0022 2 eS !Q#4T5#AB B eU #))+DAqQ#4QXq#AB B $rct|tr.|j|jz}tdd|StSrK)rrrNr=)rr?rs r__mod__ztimedelta.__mod__As= eY '%%'%*@*@*BBAQ1% %rct|tr:t|j|j\}}|tdd|fStSrK)rrr@rNr=)rr?rrs r __divmod__ztimedelta.__divmod__GsK eY '$//10024DAqi1a(( (rcVt|tr|j|dk(StSrKrrrr=r>s r__eq__ztimedelta.__eq__P& eY '99U#q( (! !rcVt|tr|j|dkStSrKr^r>s r__le__ztimedelta.__le__Vr`rcVt|tr|j|dkStSrKr^r>s r__lt__ztimedelta.__lt__\& eY '99U#a' '! !rcVt|tr|j|dk\StSrKr^r>s r__ge__ztimedelta.__ge__br`rcVt|tr|j|dkDStSrKr^r>s r__gt__ztimedelta.__gt__hrercRt|j|jSr;)r _getstater>s rrztimedelta._cmpnsDNN$eoo&788rct|jdk(rt|j|_|jS)Nrr hashrkr0s r__hash__ztimedelta.__hash__rs+ >>R !$.."23DN~~rcd|jdk7xs |jdk7xs|jdk7SrKrTr0s r__bool__ztimedelta.__bool__ws6 a( "(""a' )rcH|j|j|jfSr;rTr0s rrkztimedelta._getstate~s DMM4+=+=>>rc:|j|jfSr;rrkr0s r __reduce__ztimedelta.__reduce__ 011rN)r r r r r r r )%rrr(__doc__ __slots__rr*r.r1propertyrrprrr@__radd__rCrErGrIrLrR__rmul__rNrVrXrZr\r_rbrdrgrirrorqrkrurrrrrFs&BI56:;cJ / + ""H . H$2 C " " " " " 9 )?2rri6errrr)rrnrorprrr9c0eZdZdZdZd$dZedZedZedZ edZ ed Z d Z d Z d Zd ZdZeZedZedZedZdZdZd%dZdZdZdZdZdZdZdZdZ e Z!dZ"dZ#dZ$d Z%d!Z&d"Z'd#Z(y)&raConcrete date type. Constructors: __new__() fromtimestamp() today() fromordinal() Operators: __repr__, __str__ __eq__, __le__, __lt__, __ge__, __gt__, __hash__ __add__, __radd__, __sub__ (add/radd only with timedelta arg) Methods: timetuple() toordinal() weekday() isoweekday(), isocalendar(), isoformat() ctime() strftime() Properties (readonly): year, month, day )_year_month_dayr Nc|t|ttfryt|dk(rkdt |ddcxkrdkrTnnQt|tr |j d}tj|}|j|d|_ |St|||\}}}tj|}||_ ||_||_d|_ |S#t $r tdwxYw) zVConstructor. Arguments: year, month, day (required, base 1) r"rr+r=r<latin1znFailed to encode latin1 string when unpickling a date object. pickle.load(data, encoding='latin1') is assumed.r)rbytesrrordencodeUnicodeEncodeErrorrwrr_date__setstater rr}r~r)rr%r/r6rs rrz date.__new__s M teS\ *s4yA~ T!AY %2 %$$L;;x0D>>#&D OOD !DNK-dE3?eS~~c"    !*L$KLLLs CC+c n| tdtj|\ }}}}}}}} } ||||S)z;Construct a date from a POSIX timestamp (like time.time()).z5'NoneType' object cannot be interpreted as an integer)rrb localtime) rtrrdrerfrgrhweekdayjdaydsts r fromtimestampzdate.fromtimestampsD 9ST T27//!2D/1aRWdC1a|rcLtj}|j|S)z"Construct a date from time.time().rbrr)rrs rtodayz date.todays  JJL  ##rc4t|\}}}||||S)zConstruct a date from a proleptic Gregorian ordinal. January 1 of year 1 is day 1. Only the year, month and day are non-zero in the result. )rK)rrDrrdres r fromordinalzdate.fromordinals!1+1a1a|rct|ts tdt|dvrt d| |t |S#t $rt d|wxYw)z2Construct a date from a string in ISO 8601 format.#fromisoformat: argument must be str)rarrInvalid isoformat string: )rrrrrwr Exception)r date_strings r fromisoformatzdate.fromisoformatsu+s+AB B { : -9+IJ J K-k:; ; K9+IJ J Ks AAc"|t|||S)z|Construct a date from the ISO year, week number and weekday. This is the inverse of the date.isocalendar() function)r)rr%rr6s rfromisocalendarzdate.fromisocalendars )$c:;;rcdt||jj|j|j|j fzS)zConvert to formal string, for repr(). >>> d = date(2010, 1, 1) >>> repr(d) 'datetime.date(2010, 1, 1)' z%s.%s(%d, %d, %d))rrr(r}r~rr0s rr*z date.__repr__s@#&7&=&*nn&A&A&*jj&*kk&*ii &11 1rc|jdzxsd}dt|t|j|j|j fzS)Return ctime() style string.raz%s %s %2d 00:00:00 %04d) toordinal _DAYNAMES _MONTHNAMESr~rr}rrs rctimez date.ctime sK.."Q&+!( g   $ IItzz,## #rc8t|||jS)zQ Format using strftime(). Example: "%d/%m/%Y, %H:%M:%S" )rr)rrus rrz date.strftimes dFDNN,<==rct|ts!tdt|jzt |dk7r|j |St|SNzmust be str, not %sr rrrrrrrrr{s r __format__zdate.__format__K#s#1DI4F4FFG G s8q===% %4yrcNd|j|j|jfzS)zReturn the date formatted according to ISO. This is 'YYYY-MM-DD'. References: - http://www.w3.org/TR/NOTE-datetime - http://www.cl.cam.ac.uk/~mgk25/iso-time.html z%04d-%02d-%02d)r}r~rr0s r isoformatzdate.isoformat!s" 4::t{{DII"FFFrc|jS)z year (1-9999))r}r0s rr%z date.year/r5rc|jS)z month (1-12))r~r0s rr/z date.month4s{{rc|jS)z day (1-31))rr0s rr6zdate.day9syyrc `t|j|j|jddddS)9Return local time tuple compatible with time.localtime().r r)rlr}r~rr0s rrzdate.timetupleAs*!$**dkk499"#Q2/ /rcXt|j|j|jS)zReturn proleptic Gregorian ordinal for the year, month and day. January 1 of year 1 is day 1. Only the year, month and day values contribute to the result. )r8r}r~rr0s rrzdate.toordinalFs  DKK;;rc|| |j}| |j}| |j}t||||S)z;Return a new date with new values for the specified fields.)r}r~rr)rr%r/r6s rrz date.replaceNsA <::D =KKE ;))CtDz$s++rcVt|tr|j|dk(StSrKrrrr=r>s rr_z date.__eq__Z& eT "99U#q( (rcVt|tr|j|dkStSrKrr>s rrbz date.__le___rrcVt|tr|j|dkStSrKrr>s rrdz date.__lt__d& eT "99U#a' 'rcVt|tr|j|dk\StSrKrr>s rrgz date.__ge__irrcVt|tr|j|dkDStSrKrr>s rriz date.__gt__nrrc|j|j|j}}}|j|j|j}}}t|||f|||fSr;)r}r~rr)rr?rrdrey2m2d2s rrz date._cmpssM**dkk499a1[[%,, BQ1IB|,,rct|jdk(rt|j|_|jS)Hash.rrmr0s rroz date.__hash__ys+ >>R !$.."23DN~~rct|tr^|j|jz}d|cxkr tkr'n tdt |j |StdtS)zAdd a date to a timedelta.r result out of range) rrrr _MAXORDINALrrrr=)rr?os rr@z date.__add__sc eY ' 5::-A1# # 56 6Dz--a00 56 6rct|tr|t|j zSt|tr.|j }|j }t||z St S)z.Subtract two dates, or a date and a timedelta.)rrrrrr=)rr?days1days2s rrCz date.__sub__sY eY ')UZZK00 0 eT "NN$EOO%EUU]+ +rc.|jdzdzS)z:Return day of the week, where Monday == 0 ... Sunday == 6.r`rarr0s rrz date.weekdays 1$))rc0|jdzxsdS)z:Return day of the week, where Monday == 1 ... Sunday == 7.rarr0s r isoweekdayzdate.isoweekdays~~!#(q(rcZ|j}t|}t|j|j|j}t ||z d\}}|dkr#|dz}t|}t ||z d\}}n|dk\r|t|dzk\r|dz }d}t ||dz|dzS)aReturn a named tuple containing ISO year, week number, and weekday. The first ISO week of the year is the (Mon-Sun) week containing the year's first Thursday; everything else derives from that. The first week is 1; Monday is 1 ... Sunday is 7. ISO calendar algorithm taken from http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm (used with permission) rar r4)r}rr8r~rr@_IsoCalendarDate)rr% week1mondayrrr6s r isocalendarzdate.isocalendarszz%d+ T[[$))<5;.2 c !8 AID)$/Ku{2A6ID# RZQ// d1fc!e44rc|t|jd\}}t|||j|jgfSN)r@r}rr~r)ryhiylos rrkzdate._getstates5$**c*Sc3 TYY7899rc@|\}}|_|_|dz|z|_yr)r~rr})rstringrrs r __setstatezdate.__setstates#+1(S$+ty3Y_ rc:|j|jfSr;rtr0s rruzdate.__reduce__rvr)NN)NNN))rrr(rwrxr classmethodrrrrrr*rrrrr.ryr%r/r6rrrr_rbrdrgrirror@rzrCrrrrkrrurrrrrs867ID$$  K K<< 1$#> GG/ <,     - H* ) 5<:%2rrr<rr3c2eZdZdZdZdZdZdZdZdZ y) rzAbstract base class for time zone info classes. Subclasses must override the tzname(), utcoffset() and dst() methods. rctd)z%datetime -> string name of time zone.z&tzinfo subclass must override tzname()NotImplementedErrorrdts rrz tzinfo.tznames!"JKKrctd)zIdatetime -> timedelta, positive for east of UTC, negative for west of UTCz)tzinfo subclass must override utcoffset()rrs rrztzinfo.utcoffsets!"MNNrctd)zdatetime -> DST offset as timedelta, positive for east of UTC. Return 0 if DST not in effect. utcoffset() must include the DST offset. z#tzinfo subclass must override dst()rrs rrz tzinfo.dsts ""GHHrc:t|ts td|j|ur t d|j }| t d|j }| t d||z }|r"||z }|j }| t d||zS)z*datetime in UTC -> datetime in local time.z&fromutc() requires a datetime argumentzdt.tzinfo is not selfz0fromutc() requires a non-None utcoffset() resultz*fromutc() requires a non-None dst() resultz;fromutc(): dt.dst gave inconsistent results; cannot convert)rrrrrwrr)rrdtoffdtdstdeltas rfromutcztzinfo.fromutcs"h'DE E 99D 45 5  =&' '  =IJ J   %KBFFHE} ";<<Ezrcnt|dd}|r|}nd}|j||jfS)N__getinitargs__r)rr __getstate__)r getinitargsr)s rruztzinfo.__reduce__s:d$5t< =DDd&7&7&9::rN) rrr(rwrxrrrrrurrrrrs*ILOI:;rrcZeZdZfdZedZedZedZdZdZ xZ S)IsoCalendarDatec*t|||||fSr;)superr)rr%rrrs rrzIsoCalendarDate.__new__swsT4$9::rc |dSrKrr0s rr%zIsoCalendarDate.year Awrc |dS)Nrrr0s rrzIsoCalendarDate.weekrrc |dSNr+rr0s rrzIsoCalendarDate.weekdayrrc&tt|ffSr;)tupler0s rruzIsoCalendarDate.__reduce__sd ~&&rcX|jjd|dd|dd|ddS)Nz(year=r z, week=rz , weekday=r+r')rrr0s rr*zIsoCalendarDate.__repr__$s?>>**+a a DG9AG Hr) rrr(rryr%rrrur* __classcell__)rs@rrrsO;' Hrrc eZdZdZdZd"dddZedZedZed Z ed Z ed Z ed Z d Z dZdZdZdZd#dZdZdZdZd$dZeZedZdZdZdZdZdZ d%dddZd&dZ dZ!d Z"d!Z#y)'ra<Time with time zone. Constructors: __new__() Operators: __repr__, __str__ __eq__, __le__, __lt__, __ge__, __gt__, __hash__ Methods: strftime() isoformat() utcoffset() tzname() dst() Properties (readonly): hour, minute, second, microsecond, tzinfo, fold )_hour_minute_second _microsecond_tzinfor _foldr Nrct|ttfrxt|dk(rjt |dddzdkrVt|tr |j d}tj|}|j||xsdd |_ |St|||||\}}}}}t|tj|}||_||_||_||_||_d |_ ||_|S#t $r tdwxYw) zConstructor. Arguments: hour, minute (required) second, microsecond (default to zero) tzinfo (default to None) fold (keyword only, default to zero) r`r rr>rznFailed to encode latin1 string when unpickling a time object. pickle.load(data, encoding='latin1') is assumed.Nr)rrrrrrrrwrr_time__setstater rrrrrrrr)rrrrrrrrs rrz time.__new__Fs teS\ *s4yA~ Qq N4 " $$$L;;x0D>>#&D OOD&.D 1DNK2D &&+t35/ffk4&!~~c"   '   +*L$KLLLs C77D c|jSz hour (0-23)rr0s rrz time.hournr5rc|jSz minute (0-59)rr0s rrz time.minutes||rc|jSz second (0-59)rr0s rrz time.secondxr rc|jSzmicrosecond (0-999999)rr0s rrztime.microsecond}   rc|jSztimezone info objectrr0s rrz time.tzinfor rc|jSr;rr0s rrz time.fold zzrcZt|tr|j|ddk(StS)NT allow_mixedr rrrr=r>s rr_z time.__eq__s* eT "99U95: :! !rcVt|tr|j|dkStSrKrr>s rrbz time.__le__& eT "99U#q( (! !rcVt|tr|j|dkStSrKrr>s rrdz time.__lt__& eT "99U#a' '! !rcVt|tr|j|dk\StSrKrr>s rrgz time.__ge__rrcVt|tr|j|dkDStSrKrr>s rriz time.__gt__rrc|j}|j}dx}}||urd}n%|j}|j}||k(}|rdt|j|j|j |j f|j|j|j |j fS|||rytd|jdz|jz|tdzz }|jdz|jz|tdzz } t||j |j f| |j |j fS)NTr+z$cannot compare naive and aware timesrrr) rrrrrrrrr) rr?rmytzottzmyoffotoff base_comparemyhhmmothhmms rrz time._cmps:||}} 4<LNN$EOO%E E>L T\\4<<**,emmU]]++-. . =EM FGGb4<</%19M2MMr!EMM1E9Q;O4OOVT\\4+<+<=U]]E,>,>?A Arcr|jdk(r|jr|jd}n|}|j}|s-t |j d|_|jSt t|j|j|z td\}}|tdz}d|cxkrdkr?nn) r rrrrnrkr@rrrrrr)rrtzoffhrds rroz time.__hash__s >>R yyLLaL(KKME!%akkmA&6!7~~idiiMPUU'a021i**;B;%)$q!T[[$BRBR*S%TDN~~&*1ad>N>N*O%PDN~~rc8|j}t|S)z=Return formatted timezone offset (+xx:xx) or an empty string.)rr)rrs r_tzstrz time._tzstrsnnc""rc|jdk7rd|j|jfz}n!|jdk7rd|jz}nd}dt||jj|j |j |fz}|j|ddd|jzzd z}|jr|ddd z}|S) %Convert to formal string, for repr().r z, %d, %dz, %dr~z%s.%s(%d, %d%s)Nr , tzinfo=%rr' , fold=1)) rrrrr(rrrrrrs rr*z time.__repr__s    !dllD,=,=>>A \\Q %AA  1$ 7 $ ; ; $ DLL! = = << ##255;A ::#2$Arct|j|j|j|j|}|j }|r||z }|S)aReturn the time formatted according to ISO. The full format is 'HH:MM:SS.mmmmmm+zz:zz'. By default, the fractional part is omitted if self.microsecond == 0. The optional argument timespec specifies the number of additional terms of the time to include. Valid options are 'auto', 'hours', 'minutes', 'seconds', 'milliseconds' and 'microseconds'. )r|rrrrr/)rryrrs rrztime.isoformatsG T\\4<<++X 7 [[] GArct|ts td|jd} |t |S#t $rt d|wxYw)z>Construct a time from a string in one of the ISO 8601 formats.rTr)rrr removeprefixrrrw)r time_strings rrztime.fromisoformat sg+s+AB B "..s3  K-k:; ; K9+IJ J Ks <Ac nddd|j|j|jdddf }t|||S)z{Format using strftime(). The date part of the timestamp passed to underlying strftime should not be used. ilrr r)rrrr)rrurs rrz time.strftimes= 1aZZt||2 dFI66rct|ts!tdt|jzt |dk7r|j |St|Srrrs rrztime.__format__&rrcn|jy|jjd}td||S)z^Return the timezone offset as timedelta, positive east of UTC (negative west of UTC).Nrrrrrrs rrztime.utcoffset/4 << ''-+v. rcl|jy|jjd}t||SaReturn the timezone name. Note that the name is 100% informational -- there's no requirement that it mean anything in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. Nrrrrrs rrz time.tzname82 << ||""4(d rcn|jy|jjd}td||SaqReturn 0 if DST is not in effect, or the DST offset (as timedelta positive eastward) if DST is in effect. This is purely informational; the DST offset has already been added to the UTC offset returned by utcoffset() if applicable, so there's no need to consult dst() unless you're interested in displaying the DST info. Nrrrrr>s rrztime.dstE4 << !!$'%( rc| |j}| |j}| |j}| |j}|dur |j}| |j }t |||||||S)z;Return a new time with new values for the specified fields.Tr)rrrrrrr)rrrrrrrs rrz time.replaceTsx <99D >[[F >[[F  **K T>[[F <::DtDz$ V$OOrct|jd\}}t|d\}}|j}|jr |dkDr|dz }t ||j |j |||g}|j|fS||jfSNrr=)r@rrrrrrr)rprotocolus2us3us1r- basestates rrkztime._getstategs$++S1S#s#S JJ ::(Q, HA1dllDLLS*+ << < t||, ,rc|t|ts td|\}|_|_}}}|dkDrd|_|dz |_nd|_||_|dz|zdz|z|_||_y)Nbad tzinfo state argrrrLr r) r _tzinfo_classrrrrrrr)rrrr-rPrNrOs rrztime.__setstatets|  j&G23 37=44<sC s7DJSDJDJDJ"ax3.14; rc<|j|j|fSr;rtrrMs r __reduce_ex__ztime.__reduce_ex__x 899rc$|jdSrrWr0s rruztime.__reduce__!!!$$rr r r r NFrs)NNNNTr=)$rrr(rwrxrryrrrrrrr_rbrdrgrirror/r*rr.rrrrrrrrrkrrWrurrrrr-s),_I%UV%P!!" " " " " A8.# &"G K K 7  HLP%)P& - :%rrceZdZdZej ej zZ d2dddZedZ edZ edZ ed Z ed Z ed Zed Zed3d ZedZed3dZedZed4dZedZdZdZdZdZdZdZdZ d5dddZdZd3dZdZd6dZ dZ!d Z"ed!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d7d*Z,d+Z-e-Z.d,Z/d-Z0d8d.Z1d/Z2d0Z3d1Z4y)9rzdatetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]]) The year, month and day arguments are required. tzinfo may be None, or an instance of a tzinfo subclass. The remaining arguments may be ints. Nr rc jt|ttfrxt|dk(rjdt |dddzcxkrdkrPnnMt|tr t|d}tj|} | j||d | _ | St|||\}}}t||||| \}}}}} t|tj|} || _|| _|| _|| _|| _|| _|| _|| _d | _ | | _| S#t $r t dwxYw) Nrrr+r=rr<rzrFailed to encode latin1 string when unpickling a datetime object. pickle.load(data, encoding='latin1') is assumed.r)rrrrrrrwrr_datetime__setstater rrrr}r~rrrrrrr) rr%r/r6rrrrrrrs rrzdatetime.__new__s; teS\ *s4yB T!AY$ * *$$L x0D>>#&D OOD% (DNK-dE3?eS2D &&+t35/ffk4&!~~c"      '   3*L$KLLLs  DD2c|jSrrr0s rrz datetime.hourr5rc|jSrr r0s rrzdatetime.minuter rc|jSr r r0s rrzdatetime.secondr rc|jSrrr0s rrzdatetime.microsecondrrc|jSrrr0s rrzdatetime.tzinfor rc|jSr;rr0s rrz datetime.foldrrc tj|\}}t|dz}|dk\r |dz }|dz}n|dkr |dz}|dz }|rtjntj }||\ }}} } } } } }}t | d} |||| | | | ||}||sd}||kr!tjjdr|S|||z dd \}}} } } } |||| | | | ||}||z td|z }|jdkr=|||tddzzdd \}}} } } } |||| | | | ||}||k(rd|_ |S||j|}|S) Construct a datetime from a POSIX timestamp (like time.time()). A timezone info object may be passed in as well. rrrr rNrwinr`)rrrrbgmtimerminsysplatform startswithrrrr)rrrrfracrx converterrrdrerfrgrhrrrresultmax_fold_secondsprobe1transprobe2s r_fromtimestampzdatetime._fromtimestamps **Q-a 4#:  = FA 'MB !V FA 'MB$'ELLU__ 2;A,/1aRWdC R[Q1b"b"b1 :c )  ## (?(?(F "+A0@,@"A"1"E Aq!RRAq"b"b"5FVOi3C&DDEzzA~&/EYq!_4L0L&Mbq&Q#1aRQ1b"b"b9V##$FL ^ZZ'F rcBt||j||du|S)rjN)rrx)r timestamprs rrzdatetime.fromtimestamps% "!!)Rt^R@@rc`ddl}|jdtd|j|ddS)z6Construct a naive UTC datetime from a POSIX timestamp.r Nzdatetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.fromtimestamp(t, datetime.UTC).r+ stacklevelT)warningswarnDeprecationWarningrx)rrr~s rutcfromtimestampzdatetime.utcfromtimestamp s=  J)!"  $ !!!T400rcNtj}|j||S)zBConstruct a datetime from time.time() and optional time zone info.r)rrrs rnowz datetime.nows" JJL  B''rcddl}|jdtdtj}|j |ddS)z*Construct a UTC datetime from time.time().r Nzdatetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).r+r|T)r~rrrbrrx)rr~rs rutcnowzdatetime.utcnowsG  =)!"  $ JJL!!!T400rc Pt|ts tdt|ts td|dur |j}||j |j |j|j|j|j|j||j S)z8Construct a datetime from a given date and a given time.z%date argument must be a date instancez%time argument must be a time instanceTr) r _date_classr _time_classrr%r/r6rrrrr)rrrrs rcombinezdatetime.combine,s$ ,CD D$ ,CD D T>[[F499djj$((99dkk4;;8H8H + +rc^t|ts tdt|dkrt d| t |}|d|}||dzd}t |}|r t|}ngd}|||zS#t$rt d|dwxYw#t$rt d|dwxYw)zBConstruct a datetime from a string in one of the ISO 8601 formats.rrarr rNr\)rrrrrwrrr)rrseparator_locationdstrrdate_componentstime_componentss rrzdatetime.fromisoformat9s+s+AB B { a 9+IJ J H!CK!P q!34D 21 467D3D9O  L"7"= 1O_688 H,[O<>CG H H L 0@BGKL Ls#A7 B7BB,c |j}|d}n|rd}nd}t|j|j|j|j |j |j|S)rrrr )rrlr%r/r6rrr)rrs rrzdatetime.timetupleXsYhhj ;C CC!$))TZZ"&))T[[$++"%' 'rcV tddd d}| z tddz} fd}|||z }||z }||}||k(r'|| |f|jz}|||z }||k(r|S||z }||z }||} | |k(r|S||k(r|Sttf|j||S)zReturn integer POSIX timestamp.rrr ctj|dd\}}}}}}t||||||z tddzS)Nr`r r)rbrrr)urrdrerfrgrhepochs rlocalzdatetime._mktime..localjsJ"'//!"4Ra"8 Aq!RRQ1b"b1E9i1oM Mr)rrrmaxrm) rrtrrru1t1u2rt2rs @r_mktimezdatetime._mktimeesq!$$ E\i1o - N !HqL U 2Y 7((*:;DIIFFBb BAAv RA U 2Y 7I 7ISz$))$R,,rc|j"|j}||jdz zS|tz j S)zReturn POSIX timestamp as floatr)rrr_EPOCHr1r4s rrzzdatetime.timestamps@ <<  At''#-- -6M002 2rc |j}|r||z}|j|j|j}}}|j|j |j }}}t||||||dS)z4Return UTC time tuple compatible with time.gmtime().r )rr%r/r6rrrrl)rrrrdrerfrgrhs r utctimetuplezdatetime.utctimetuplesc!  FND))TZZa1YY T[[B!!Q2r2q99rcXt|j|j|jS)zReturn the date part.)rr}r~rr0s rrz datetime.datesDJJ TYY77rct|j|j|j|j|j S)z'Return the time part, with tzinfo None.r)rrrrrrr0s rrz datetime.times.DIIt{{DKK9I9IPTPYPYZZrct|j|j|j|j|j |j S)z'Return the time part, with same tzinfo.r)rrrrrrrr0s rtimetzzdatetime.timetzs6DIIt{{DKK9I9ILLtyy2 2rc  6| |j}| |j}| |j}| |j}| |j}| |j }| |j }|dur |j}| |j} t||||||||||  S)z?Return a new datetime with new values for the specified fields.Tr) r%r/r6rrrrrrr) rr%r/r6rrrrrrs rrzdatetime.replaces <99D =JJE ;((C <99D >[[F >[[F  **K T>[[F <99DtDz$sD&&%vD: :rc|jW|j}|jd|jz j}||k7r+||kD|jk(r|}n|tz t dz}t j|}t|dd}|j}|j}tt ||S)Nrrr7r`) rrrrrrrbrr tm_gmtofftm_zoner)rtsts2localtmrgmtoffzones r_local_timezonezdatetime._local_timezones ;; B,,AdiiK,088:Cby"H*B-Ia$88B//"%'"1+&"" &1488rc||j}nt|ts td|j}|"|j}|j |}nD|j |}|1|j dj}|j |}||ur|S||z j |}|j |S)Nz)tz argument must be an instance of tzinfor)rrrrrrr)rrr#myoffsetrs r astimezonezdatetime.astimezones :%%'BB'GH H{{ <'')D~~d+H~~d+H||4|0@@B>>$/ :Kh''r'2zz#rc|jdzxsd}dt|t|j|j|j |j |j|jfzS)rraz%s %s %2d %02d:%02d:%02d %04d) rrrr~rrrrr}rs rrzdatetime.ctimes_.."Q&+!. g   $ II JJ dll JJ 2 rcd|j|j|j|fzt|j|j |j |j|z}|j}t|}|r||z }|S)aReturn the time formatted according to ISO. The full format looks like 'YYYY-MM-DD HH:MM:SS.mmmmmm'. By default, the fractional part is omitted if self.microsecond == 0. If self.tzinfo is not None, the UTC offset is also attached, giving giving a full format of 'YYYY-MM-DD HH:MM:SS.mmmmmm+HH:MM'. Optional argument sep specifies the separator between date and time, default 'T'. The optional argument timespec specifies the number of additional terms of the time to include. Valid options are 'auto', 'hours', 'minutes', 'seconds', 'milliseconds' and 'microseconds'. z%04d-%02d-%02d%c) r}r~rr|rrrrrr)rrryrrrs rrzdatetime.isoformatsv  4::t{{DIIs"K K $**dllDLL++X77nn C  GArc |j|j|j|j|j|j |j g}|ddk(r|d=|ddk(r|d=t|d|jjddjtt|d}|j|ddd|jzzdz}|jr|ddd z}|S) r1rr r$r%r&r'Nr2r3)r}r~rrrrrrrr(rrrrr)rLrs rr*zdatetime.__repr__s ZZdii ZZt||T5F5F H R5A:" R5A:",T2>>6699Sa[1 3 << ##255;A ::#2$Arc&|jdS)zConvert to string, for str(). r)rr0s rr.zdatetime.__str__#s~~#~&&rc0ddl}|j|||S)zKstring, format -> new datetime parsed from a string (like time.strptime()).r N) _strptime_strptime_datetime)rrrurs rstrptimezdatetime.strptime's ++CfEErcn|jy|jj|}td||S)z\Return the timezone offset as timedelta positive east of UTC (negative west of UTC).Nrr=r>s rrzdatetime.utcoffset-r?rcl|jy|jj|}t||SrArBrCs rrzdatetime.tzname6rDrcn|jy|jj|}td||SrFrGr>s rrz datetime.dstCrHrc|t|tr|j|ddk(St|tstSy)NTrr F)rrrrr=r>s rr_zdatetime.__eq__Ts7 eX &99U95: :E4(! !rct|tr|j|dkSt|tstSt ||yrKrrrrr=rr>s rrbzdatetime.__le__\: eX &99U#q( (E4(! ! dE "rct|tr|j|dkSt|tstSt ||yrKrr>s rrdzdatetime.__lt__d: eX &99U#a' 'E4(! ! dE "rct|tr|j|dk\St|tstSt ||yrKrr>s rrgzdatetime.__ge__lrrct|tr|j|dkDSt|tstSt ||yrKrr>s rrizdatetime.__gt__trrc |j}|j}dx}}||urd}n|j}|j}|r^||j|j jk7ry||j|j jk7ry||k(}|rt |j |j |j|j|j|j|jf|j |j |j|j|j|j|jfS|||rytd||z }|jdkry|xrdxsdS)NTrr+z(cannot compare naive and aware datetimesr rr)rrrrrr}r~rrrrrrr) rr?rr#r$r%r&r'diffs rrz datetime._cmp|sS||}} 4<LNN$EOO%EDLL$))mL<FFHHEMM5::~M>HHJJ E>L T[[$))T\\4<<**,ellEJJemmU]]++-. . =EM JKKe| 99q=zQrc *t|tstSt|j|j|j |j |j}||z }t|jd\}}t|d\}}d|jcxkr tkrgn t'dt|jtj|jt!||||j"|j$St'd)zAdd a datetime and a timedelta.rrrr rr)rrr=rrrrrr@rprrrrrrrrrrr)rr?rrremrrs rr@zdatetime.__add__s%+! !$..* $ "&,,"&,,'+'8'8 : 5==$/ cR uzz ([ ( 122 :%%d&6&6uzz&B&*4+0+=+=26,,'@A A122rcNt|tst|tr|| zStS|j }|j }|j |j dzz|jdzz}|j |j dzz|jdzz}t||z ||z |j|jz }|j|jur|S|j}|j}||k(r|S|| td||z|z S)z6Subtract two datetimes, or a datetime and a timedelta.rrz(cannot mix naive and timezone-aware time) rrrr=rrrrrrrr) rr?rrsecs1secs2baser%r&s rrCzdatetime.__sub__s%*%+uf}$! ! ! t||b004::3DD   22U[[45GG**U-?-??A <<5== (K ! E>K =EMFG Ge|e##rc|jdk(r|jr|jd}n|}|j}|-t |j d|_|jSt |j|j|j}|jdz|jdzz|jz}t t|||j|z |_|jS)Nrr rrr)r rrrrnrkr8r%r/r6rrrrr)rrr,rrps rrozdatetime.__hash__s >>R yyLLaL(KKME}!%akkmA&6!7 ~~  4::txx@))d*T[[2-== K!%igt?O?O&PSX&X!Y~~rc |t|jd\}}t|jd\}}t|d\}}|j}|jr |dkDr|dz }t ||||j |j|j|j|||g }|j|fS||jfSrK) r@r}rr~rrrrrrr) rrMrrrNrOrPrdrQs rrkzdatetime._getstates$**c*S$++S1S#s#S KK ::(Q, HA3Q ::t||T\\S*+  << < t||, ,rc |t|ts td|\ }}}|_|_|_|_}}}|dkDrd|_|dz |_nd|_||_|dz|z|_ |dz|zdz|z|_ ||_ y)NrSrrrLr rr) rrTrrrrrrr~r}rr) rrrrrrdrPrNrOs rrzdatetime.__setstates  j&G23 36< 4c1di t|S#s s7DJc'DKDJDK3Y_ "ax3.14; rc<|j|j|fSr;rtrVs rrWzdatetime.__reduce_ex__rXrc$|jdSrrZr0s rruzdatetime.__reduce__ r[r)NNr r r r Nr;)T)NNNNNNNT)r7rsr]r_)5rrr(rwrrxrrryrrrrrrrrxrrrrrrrrrzrrrrrrrr*r.rrrrr_rbrdrgrirr@rzrCrorkrbrWrurrrrrs /IJK&*!45!H!!))VAA 1 1((  1 1 + +99< ' -F3:8[2 =ACG::29"66&'FF   "#####J3&H$0 " - :%rrcRd}t|dd}|dzdz}||z }||kDr|dz }|S)Nr=rr`ra)r8)r%THURSDAYfirstday firstweekdayrs rrr sEHa#HqLA%L\)Khq rceZdZdZeZefdZeddZdZ dZ dZ dZ d Z d Zd Zd Zd ZeddZe ZedZy)r)_offset_namec<t|ts td||jur|s |jSd}nt|t s td|j |cxkr|jkstdtd|j||S)Nzoffset must be a timedeltazname must be a stringzYoffset must be a timedelta strictly between -timedelta(hours=24) and timedelta(hours=24).) rrr_Omittedrr _minoffset _maxoffsetrw_create)rrrs rrztimezone.__new__ s&),89 9 3<< wwDD#&34 4~~93>>945 5:45 5{{64((rNcLtj|}||_||_|Sr;)rrrr)rrrrs rrztimezone._create( s#~~c"   rcd|j |jfS|j|jfS)zpickle support)rrr0s rrztimezone.__getinitargs__/ s+ :: LL? " djj))rc`t|tr|j|jk(StSr;)rrrr=r>s rr_ztimezone.__eq__5 s% eX &<<5==0 0rc,t|jSr;)rnrr0s rroztimezone.__hash__: sDLL!!rc||jury|j2t|d|jjd|j dSt|d|jjd|j d|jdS)aConvert to formal string, for repr(). >>> tz = timezone.utc >>> repr(tz) 'datetime.timezone.utc' >>> tz = timezone(timedelta(hours=-5), 'EST') >>> repr(tz) "datetime.timezone(datetime.timedelta(-1, 68400), 'EST')" zdatetime.timezone.utcr$r%r'r&)rrrrr(rr0s rr*ztimezone.__repr__= sq 488 * :: "3D"9"&.."="="&,,0 0#4D"9"&.."="="&,, < t|ts|ytd)Nz2dst() argument must be a datetime instance or None)rrrrs rrz timezone.dstb s% b( #rz#$ $rct|tr(|j|ur td||jzSt d)Nzfromutc: dt.tzinfo is not selfz6fromutc() argument must be a datetime instance or None)rrrrwrrrs rrztimezone.fromutch sK b( #yy$ "/00 $ $#$ $rr>r)rnrrc 0|sy|tdkrd}| }nd}t|td\}}t|td\}}|j}|j}|rd||dd |dd |dd |d  S|rd||dd |dd |dSd||dd |dS) Nr r rrrrr02drr$06d)rr@rprr)rrrnrestrorprrs rrztimezone._name_from_offsett s 9Q< DFEDUIA$67 ttYq%9: ,,(( $c{!GC='# S)+ , uSk73-q F FTF5+Qwsm44rr;)rrr(rxrrrrrrr_ror*r.rrrrrrr staticmethodrrrrrr s"IxH"* ) *  "<(!$ $$ $"5JJ55rrr+rrr^)r)Drw__all__rrbmathrrnoperatorr rrrrr rr-r2dbmr7rr&r)r0r3r8rArBrCrKrrrlr|rrrrrrrrrrrrrrrrrrmr resolutionrrrrrrrTrrrrrr rrrrrrs  ( $/   FT !" Cc"3JC B* !F  C  C  A <~? C I ** &@0F6r!"H6-^,^B1 ) 3"P9 (|2|2| *% yB'-/  a0 22B  1a= b" #:;:;zHeH6# X%X%t  1a= BF #+s %ts %l1a  b"b"b&9 Q/r5vr5h%%il33hl R!@ @A  B ?@ $1X\\ 2r__pycache__/pstats.cpython-312.opt-2.pyc000064400000104073152342670510013747 0ustar00 ֦iir ddlZddlZddlZddlZddlZddlmZmZddlm Z ddl m Z ddl m Z gdZeeGddZe d Gd d Ze d Gd dZGddZGddZdZdZdZdZdZdZdZedk(rddlZ ddlZGddej>Z e!ejDdkDrejDdZ#ndZ# e e#Z$ejDddD]Z%e$jMe%e'de$jP e$jSe'd!e$jP yy#e$rYwxYw#e*$rYywxYw)"N)StrEnum _simple_enum) cmp_to_key) dataclass)Dict)StatsSortKeyFunctionProfile StatsProfilec6eZdZdZdZdZdZdZdZdZ dZ d Z d Z y ) r )callsncalls) cumulativecumtime)filenamemodulelinenamenflpcallsstdname)timetottimec|d}tj||}||_|ddD]}||j|<||_|SNr)str__new___value__value2member_map_ _all_values)clsvaluesvalueobj other_values /usr/lib64/python3.12/pstats.pyrzSortKey.__new__0sNq kk#u% !!":K25C " "; /&  N) __name__ __module__ __qualname__CALLS CUMULATIVEFILENAMELINENAMENFLPCALLSSTDNAMETIMErr(r'r r $s4 E(J#H D D C FG Dr(r T) unsafe_hashcTeZdZUeed<eed<eed<eed<eed<eed<eed<y) r rrpercall_tottimerpercall_cumtime file_name line_numberN)r)r*r+r__annotations__floatintr5r(r'r r :s( K N NNr(r c.eZdZU eed<eeefed<y)r total_tt func_profilesN)r)r*r+r=r<rrr r5r(r'r r Ds:O_,--r(r ceZdZ dddZdZdZdZdZdZd d d d d d d d dddddd Z dZ dZ dZ dZ dZdZdZdZdZdZdZdZd"dZd Zd!Zy)#rN)streamc|xstj|_t|sd}n |d}|dd}|j ||j |yr)sysstdoutrCleninitadd)selfrCargsargs r'__init__zStats.__init__lsJ*  4yCq'C8D #$r(cjd|_g|_d|_d|_d|_d|_d|_t|_i|_ i|_ |j| |jy#t$r7td|jr|jdndz|jwxYw)NrzInvalid timing data %sfile) all_calleesfilesfcn_listr@ total_calls prim_calls max_name_lenset top_levelstats sort_arg_dict load_statsget_top_level_stats ExceptionprintrC)rJrLs r'rHz Stats.initvs        $ $ &  *%)ZZ4::b>R9?C{{ L  s !A22AB2c|i|_yt|trst|d5}t j ||_ddd t j|}tj|jdz|z}|g|_ n4t|dr(|j|j|_i|_|jstd|jd|y#1swYxYw#YuxYw)Nrbz create_statszCannot create or construct a z object from )r[ isinstanceropenmarshalloadosstatrctimest_mtimerThasattrrc TypeError __class__)rJrLf file_statss r'r]zStats.load_statss ;DJ  S !c4A$\\!_ ! WWS\ jj!4!45>DDJ S. )    DJCIzz#~~s45 5!  sC* :C6*C36C:c|jjD]\}\}}}}}|xj|z c_|xj|z c_|xj|z c_d|vr|j j |tt||jkDstt||_ y)N)jprofilerprofiler) r[itemsrVrWr@rZrIrGfunc_std_stringrX)rJfuncccncttctcallerss r'r^zStats.get_top_level_statss/3zz/?/?/A +D+2r2r7    "  OO "O MM "M*g5""4(?4()D,=,==$'(=$>!0Br(c|s|St|D]^}t|t|k7r t|}|xj|jz c_|xj|jz c_|xj |j z c_|xj |j z c_|jD]}|jj||j|jkr|j|_ d|_ |jjD]C\}}||jvr|j|}nddddif}t|||j|<Ea|SNr)reversedtyperrTrVrWr@rZrIrXrUr[rtadd_func_stats)rJarg_listitemrvri old_func_stats r'rIz Stats.adds+KX&DDzT$Z'T{ JJ$** $J    0 0 0  OOt .O MMT]] *M""4('  4#4#44$($5$5! DM"jj..0 d4::%$(JJt$4M%&1a$5M#1-#F 4 1'* r(c t|d5}tj|j|dddy#1swYyxYw)Nwb)rerfdumpr[)rJrros r' dump_statszStats.dump_statss/H (D !Q LLQ '" ! !s !8A)))rrOz call count)))rOzcumulative time))rz file name))rz line number))rz function name))rrrzname/file/line)))rrOzprimitive call count)))rz standard name)))rOz internal time) r rrrrrrrrrrrrc |jsSix|_}i}|jjD]!\}}|}|s ||vrd||<|||<|dd}|r#|D]}||=|jS)NrrO)r\sort_arg_dict_defaultrt)rJdictbad_listwordtupfragments r'get_sort_arg_defszStats.get_sort_arg_defss7!!(* *D H!77==? c4'-.*%(DN'}H @!J!!!!r(c |s d|_|St|dk(r"t|dtrddddd|dg}n=t|dk\r/|ddD]'}t |t |dk7st d |j }d }d |_d }|D]I}t|tr |j}|||dz}|xj|||dzz c_d }Kg}|jjD]1\}\} } } } } |j| | | | f|zt||fz3|jtt!|j" gx|_}|D]}|j|d|S)Nrrrr rr)rOrrrrzCan't have mixed argument typer5rPz, )keyrO)rUrGrdr>rrmr sort_typer r$r[rtappendrusortr TupleCompcompare)rJfieldrL sort_arg_defs sort_tuple connectorr stats_listrvrwrxryrzr{rUtuples r' sort_statszStats.sort_statssDMK u:?z%(C8$"!')*/q35EZ1_QRy9U1X.#$DEE!..0   D$(zz#mD&9!&< gg?g?rz List reduced from z to z due to restriction ) rdrrecompileerrorsearchrurrGr=r>)rJsellistmsgnew_listrexrvcounts r'eval_print_amountzStats.eval_print_amountGs c3  %jjoH::od34OOD)IE#u%#*:s*:ECK",-<C%!s*:U*:< t9H % D 3x=#/ /C}'88 %=CC}$ %sDD"!D"c  |jr|jddn"t|jj}|s t diSt t |j}i}t ||}|D]}|j|\}}}} } |\} } } ||k(r t|nt|dzt|z}t t |}|dk(rdnt t ||z }t t | }|dk(rdnt t | |z }t|||||| | }||| <|S)Nr/rO) rUrr[keysr r=f8r@rr )rJ func_listr@rA stats_profilervrwrxryrzr{r:r; func_namerrr8rr9 func_profiles r'get_stats_profilezStats.get_stats_profileas5 )- DMM!$4 @Q;R 2& &DMM*+ $X}= D&*jj&6 #BBG04 -I{I "bSWs2w}s2w/FFBrFmG$&!Gbr"R%y1AOBrFmG$&!Gbr"R%y1AO*L(4M) $#&r(c|j}|jr"|jdd}d|jzdz}n%t|jj }d}|D]}|j |||\}}t|}|sd|fSt||j|t|jkr5d}|D].}tt||kDstt|}0|dz|fS)Nz Ordered by:  z! Random listing order was used rrQr) rXrUrrr[rrrGr`rCru)rJsel_listwidth stat_listr selectionrrvs r'get_print_listzStats.get_print_lists!! == a(I#dnn4t;CTZZ__./I6C!I!33Iy#NNIs"Ii<  c $ 3tzz? "E!-.6 56E"Qw !!r(c|jD]}t||j|jrt|jd}|jD]#}t|t ||j%t||j dd|j|j |j k7r%td|j zd|jtd|jz|jt|j|j|\}}|rT|j|D]}|j|t|jt|j|S)NrQ zfunction calls endrRz(%d primitive calls)zin %.3f seconds) rTr`rCrZfunc_get_function_namerVrWr@r print_title print_line)rJamountrindentrvrrs r' print_statszStats.print_statss H ( -# :: t{{ #NND &06T[[ I# fd&&(8c T   t . (4??:$++ V $--/dkkB 4;;))&1 t     % t{{ # t{{ # r(c`|j|\}}|r|j|j|d|D]D}||jvr!|j |||j|2|j ||iFt |j t |j |S)Nz called...rQ)rrprint_call_headingrSprint_call_liner`rC)rJrrrrvs r' print_calleeszStats.print_calleess))&1 t       # #E; 74+++((d6F6Ft6LM((b9  t{{ # t{{ # r(c|j|\}}|rn|j|d|D]+}|j|\}}}}} |j||| d-t |j t |j |S)Nzwas called by...z<-rQ)rrr[rr`rC) rJrrrrvrwrxryrzr{s r' print_callerszStats.print_callerss))&1 t   # #E+= >*.**T*:'BB$$UD'4@ t{{ # t{{ # r(cPtdj||z|jd}|jj D]>\}}}}}|s t t |j } t| t}n|rtd|zdz|jyy)Nz Function rQFrz ncalls tottime cumtime) r`ljustrCr[r#nextiterrdr) rJ name_size column_title subheaderrwrxryrzr{r$s r'rzStats.print_call_headings k *\9 L '+zz'8'8': #BBGT'.."234&ue4  (;  #i-"@@t{{ S r(c htt|j||zd|j|st|jyt |j }d}|D]}t|}||} t | tr]| \} } } } | | k7rd| | fz}nd| fz}|jddt|zzdt| dt| d |}|d z}n(|d | d t|j|d }|d z}t||z|z|jd}y)NrrrQrPz%d/%dz%drrz r(z) r) r`rurrCsortedrrdrrjustrGrr[)rJrsource call_dictarrowclistrrvrr$rxrwryrzsubstats left_widths r'rzStats.print_call_lines  of%++I6>CdkkZ t{{ # y~~'(D"4(DdOE%'!&BB8&"b1H#re|H-5^^AaF mO-L-/VRVTC&] *.r$**T:J1:M7NO&] &#h.T[[ AF!r(cbtdd|jtd|jy)Nz- ncalls tottime percall cumtime percallrrzfilename:lineno(function)rQr`rCrs r'rzStats.print_titles" =3T[[Y ) )r)r*r+rMrHr]r^rIrrrrrrrrrrrrrrrrrr5r(r'rrJsB&*&,?4(DCHHBDBFGMFFF ""%N : &4!F"0.   T2=7r(rceZdZ dZdZy)rc||_yrcomp_select_list)rJrs r'rMzTupleComp.__init__s 0r(cf|jD]"\}}||}||}||kr| cS||kDs |cSyr}r)rJleftrightindex directionlrs r'rzTupleComp.comparesJ $ 5 5 E9U Ae A1u!z!1u  !6r(N)r)r*r+rMrr5r(r'rrs&1r(rcR|\}}}tjj|||fSr)rhpathbasename)rrrrs r'rr!s*$HdD 77  H %tT 11r(c |dS)Nrr5)rvs r'rr%s 7Nr(c~|dddk(r1|d}|jdr|jdrd|ddzS|Sd|zS) Nr)~r<>z{%s}rrOz %s:%d(%s)) startswithendswith)rrs r'ruru(sQ!} | ??3 DMM#$6D2J& &KY&&r(c^ |\}}}}}|\}}} } } ||z||z|| z|| zt| |fSr) add_callers) targetrrwrxryrzr{t_cct_nct_ttt_ct t_callerss r'rr9sR=$BBG(.%D$dI tGRWbgr$w)W- //r(c   i}|jD] \}}|||< |jD]O\}}||vrAt|tr#tdt|||D||<=||xx|z cc<K|||<Q|S)Nc3,K|] \}}||zywrr5).0ijs r' zadd_callers..Is)[ ValueErrorr=r`rCr[getattr)rJfnrrK processedtermfracs r'genericzProfileBrowser.genericss::A?,C0C C Cctd|jtd|jtd|jtd|jtd|jtd|jy)NzArguments may be:rQz0* An integer maximum number of entries to print.z:* A decimal fractional number between 0 and 1, controllingz- what fraction of selected entries to print.z8* A regular expression; only entries with function namesz that match it are printed.rrs r' generic_helpzProfileBrowser.generic_helpsb %DKK 8 D4;; W NUYU`U` a A T LSWS^S^ _ 0t{{ Cr(c|jr |jj|ytd|jy#t$r'}td|d||jYd}~yd}~wwxYw)NzFailed to load statistics for z: rQr0r)r[rIOSErrorr`rC)rJres r'do_addzProfileBrowser.do_addsjzz`JJNN4( 7dkkJ `D!LSWS^S^__ `sA A2 A--A2c2td|jy)Nz>Add profile info from given file to current statistics object.rQrrs r'help_addzProfileBrowser.help_adds RY]YdYd er(c&|jd|S)Nrr8rJrs r' do_calleeszProfileBrowser.do_callees<<6 6r(cRtd|j|jy)Nz6Print callees statistics from the current stat object.rQr`rCr:rs r' help_calleeszProfileBrowser.help_callees JQUQ\Q\ ]    r(c&|jd|S)NrrBrCs r' do_callerszProfileBrowser.do_callersrEr(cRtd|j|jy)Nz6Print callers statistics from the current stat object.rQrGrs r' help_callerszProfileBrowser.help_callersrIr(c2td|jy)NrPrQrrrCs r'do_EOFzProfileBrowser.do_EOFs "4;; 'r(c2td|jyNzLeave the profile browser.rQrrs r'help_EOFzProfileBrowser.help_EOF .T[[ Ar(cy)Nrr5rCs r'do_quitzProfileBrowser.do_quitsr(c2td|jyrQrrs r' help_quitzProfileBrowser.help_quitrSr(c|r t||_|dz|_ yt|jdkDr!|jdd}|j|ytd|j y#t$r.}t|jd|j Yd}~yd}~wt $r9}t|jjdz||j Yd}~yd}~wwxYw) NrrQ:r)rz1No statistics object is current -- cannot reload.r) rr[r<r`rKrCr_rnr)r,rGr-)rJrerrs r'r-zProfileBrowser.do_reads!&tDJ#Tk  T[[!A%{{3B' T"IPTP[P[\#((1+DKK8 #--0036$++Ns#A00 C'9$B"" C'./C""C'c`td|jtd|jy)Nz+Read in profile data from a specified file.rQz*Without argument, reload the current file.rrs r' help_readzProfileBrowser.help_reads ?dkk R >T[[ Qr(c|jr|jjytd|jy)Nr0rQr)r[rr`rCrCs r' do_reversezProfileBrowser.do_reverses2zz ((*7dkkJr(c2td|jy)Nz/Reverse the sort order of the profiling report.rQrrs r' help_reversezProfileBrowser.help_reverses C$++ Vr(c|jstd|jy|jj|rJt fd|j Dr(|jj |j ytd|jtjjD]$\}}t|d|d|j&y)Nr0rQc3&K|]}|v ywrr5)rr$abbrevss r'rz)ProfileBrowser.do_sort..sALqQ'\Lsz/Valid sort keys (unique prefixes are accepted):z -- rr) r[r`rCrallr1rrrrt)rJrrr$rds @r'do_sortzProfileBrowser.do_sorts::7dkkJjj224GADJJLAA% %%tzz|4 GdkkZ$)$?$?$E$E$GLS%U1X6T[[I%Hr(c`td|jtd|jy)Nz.Sort profile data according to specified keys.rQz3(Typing `sort' without arguments lists valid keys.)rrs r' help_sortzProfileBrowser.help_sorts B U Gdkk Zr(cltjDcgc]}|j|s|c}Scc}wr)rrr)rJtextrKas r' complete_sortzProfileBrowser.complete_sorts-$::Q:!all4>PA:Q QQs11c&|jd|S)NrrBrCs r'do_statszProfileBrowser.do_statss<< t4 4r(cRtd|j|jy)Nz.Print statistics from the current stat object.rQrGrs r' help_statszProfileBrowser.help_statss B U    r(c|jr|jjytd|jy)Nr0rQ)r[rr`rCrCs r'do_stripzProfileBrowser.do_strips(zz %%'7dkkJr(c2td|jy)Nzr@rDrHrKrMrOrRrUrWr-r]r_rarfrhrlrnrprrrtrvryr5r(r'r'r'js & 0 D  f 7  7   B  B " R   W  [ R 5  K  d F r(r'rrz*Welcome to the profile statistics browser.rQzGoodbye.)+rErhrrfrenumrr functoolsr dataclassesrtypingr__all__r r r rrrrrurrr"rr)r*readline ImportErrorr+r'rGargv initprofilebrowserr.r>r`rCcmdloopKeyboardInterruptr5r(r'rs9,  & ! A g* t t... |7|7| 22 '"/" z PPd 388}qhhqk    -xx|G NN7 #$ :P jw~~.G    @    s%(E)A%EEEE#"E#__pycache__/operator.cpython-312.opt-1.pyc000064400000041712152342670510014263 0ustar00 ֦i*vdZgdZddlmZdZdZdZdZdZ d Z d Z d Z d Z d ZdZdZdZdZdZdZeZdZdZdZdZdZdZdZdZdZdZdZdZ d Z!d!Z"d"Z#d#Z$d$Z%d%Z&d&Z'd@d'Z(d(Z)Gd)d*Z*Gd+d,Z+Gd-d.Z,d/Z-d0Z.d1Z/d2Z0d3Z1d4Z2d5Z3d6Z4d7Z5d8Z6d9Z7d:Z8d;Z9d<Z: dd=l;dd>l;mZeZ=eZ>eZ?eZ@e ZAe ZBe ZCeZDeZEeZFe)ZGeZHeZIeZJeZKeZLeZMeZNeZOeZPeZQeZReZSeZTeZUeZVe ZWe!ZXe"ZYe$ZZe%Z[e'Z\e-Z]e.Z^e/Z_e0Z`e1Zae2Zbe3Zce4Zde5Zee6Zfe7Zge8Zhe9Zie:Zjy?#e<$rYdwxYw)Aas Operator Interface This module exports a set of functions corresponding to the intrinsic operators of Python. For example, operator.add(x, y) is equivalent to the expression x+y. The function names are those used for special methods; variants without leading and trailing '__' are also provided for convenience. This is the pure Python implementation of the module. )7absaddand_ attrgettercallconcatcontainscountOfdelitemeqfloordivgegetitemgtiaddiandiconcat ifloordivilshiftimatmulimodimulindexindexOfinvinvertioripowirshiftis_is_notisub itemgetteritruedivixorle length_hintlshiftltmatmul methodcallermodmulnenegnot_or_pospowrshiftsetitemsubtruedivtruthxor)rc ||kS)zSame as a < b.abs !/usr/lib64/python3.12/operator.pyr(r( q5Lc ||kS)zSame as a <= b.r;r<s r?r%r% 6MrAc ||k(S)zSame as a == b.r;r<s r?r r #rCrAc ||k7S)zSame as a != b.r;r<s r?r-r-'rCrAc ||k\S)zSame as a >= b.r;r<s r?r r +rCrAc ||kDS)zSame as a > b.r;r<s r?rr/r@rAc| S)zSame as not a.r;r=s r?r/r/5s 5LrAc|rdSdS)z*Return True if a is true, False otherwise.TFr;rIs r?r7r79s4%rAc ||uS)zSame as a is b.r;r<s r?rr= 6MrAc ||uS)zSame as a is not b.r;r<s r?r r As A:rAct|S)zSame as abs(a).)_absrIs r?rrGs 7NrAc ||zS)zSame as a + b.r;r<s r?rrKr@rAc ||zS)zSame as a & b.r;r<s r?rrOr@rAc ||zS)zSame as a // b.r;r<s r?r r SrCrAc"|jS)zSame as a.__index__().) __index__rIs r?rrWs ;;=rAc|S)z Same as ~a.r;rIs r?rr[ 2IrAc ||zS)zSame as a << b.r;r<s r?r'r'`rCrAc ||zS)zSame as a % b.r;r<s r?r+r+dr@rAc ||zS)zSame as a * b.r;r<s r?r,r,hr@rAc ||zS)zSame as a @ b.r;r<s r?r)r)lr@rAc| S)z Same as -a.r;rIs r?r.r.prVrAc ||zS)zSame as a | b.r;r<s r?r0r0tr@rAc|S)z Same as +a.r;rIs r?r1r1xrVrAc ||zS)zSame as a ** b.r;r<s r?r2r2|rCrAc ||z S)zSame as a >> b.r;r<s r?r3r3rCrAc ||z S)zSame as a - b.r;r<s r?r5r5r@rAc ||z S)zSame as a / b.r;r<s r?r6r6r@rAc ||z S)zSame as a ^ b.r;r<s r?r8r8r@rAcjt|ds#dt|jz}t|||zS)z%Same as a + b, for a and b sequences. __getitem__!'%s' object can't be concatenatedhasattrtype__name__ TypeErrorr=r>msgs r?rrs3 1m $1DG4D4DDn q5LrAc ||vS)z(Same as b in a (note reversed operands).r;r<s r?rrrLrAc6d}|D]}||us||k(s |dz }|S)z=Return the number of items in a which are, or which equal, b.r9r;)r=r>countis r?r r s. E  6Q!V QJE LrAc ||=y)zSame as del a[b].Nr;r<s r?r r s  !rAc ||S)z Same as a[b].r;r<s r?rrs Q4KrAcXt|D]\}}||us||k(s|cStd)z!Return the first index of b in a.z$sequence.index(x): x not in sequence) enumerate ValueError)r=r>rqjs r?rrs4! 1 6Q!VH?@@rAc|||<y)zSame as a[b] = c.Nr;)r=r>cs r?r4r4s AaDrAct|ts#dt|jz}t | t |S#t$rYnwxYw t|j }n#t$r|cYSwxYw ||}n#t$r|cYSwxYw|tur|St|ts#dt|jz}t ||dkr d}t||S)a2 Return an estimate of the number of items in obj. This is useful for presizing containers when building from an iterable. If the object supports len(), the result will be exact. Otherwise, it may over- or under-estimate by an arbitrary amount. The result will be an integer >= 0. z/'%s' object cannot be interpreted as an integerz'__length_hint__ must be integer, not %sr9z$__length_hint__() should return >= 0) isinstanceintrhrirjlen__length_hint__AttributeErrorNotImplementedrv)objdefaultrlhintvals r?r&r&s gs #@G}%%&n 3x    Cy(( 3i  n c3 8Cy!!"n Qw4o Js5 A A  A A&& A43A48B BBc||i|S)zSame as obj(*args, **kwargs).r;)rargskwargss r?rrs   rAc,eZdZdZdZdZdZdZdZy)raV Return a callable object that fetches the given attribute(s) from its operand. After f = attrgetter('name'), the call f(r) returns r.name. After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date). After h = attrgetter('name.first', 'name.last'), the call h(r) returns (r.name.first, r.name.last). )_attrs_callc|sAt|ts td|f|_|j dfd}||_y|f|z|_t tt|jfd}||_y)Nzattribute name must be a string.c.D]}t||}|SN)getattr)rnamenamess r?funcz!attrgetter.__init__..funcs!D!#t,C" rAc.tfdDS)Nc3.K|] }|ywrr;).0getterrs r? z4attrgetter.__init__..func..s?wVVC[wstuple)rgetterss`r?rz!attrgetter.__init__..funcs?w???rA) r{strrjrsplitrrmapr)selfattrattrsrrrs @@r?__init__zattrgetter.__init__sodC( ABB'DKJJsOE DJ'E/DKC DKK89G @DJrAc$|j|Srrrrs r?__call__zattrgetter.__call__zz#rAc |jjd|jjddjt t |j dSNr(, )) __class__ __module__ __qualname__joinrreprrrs r?__repr__zattrgetter.__repr__s?"nn77"nn99"iiD$++(>?A ArAc2|j|jfSr)rrrs r? __reduce__zattrgetter.__reduce__ ~~t{{**rAN rirr__doc__ __slots__rrrrr;rAr?rrs#$I$A +rArc,eZdZdZdZdZdZdZdZy)r"z Return a callable object that fetches the given item(s) from its operand. After f = itemgetter(2), the call f(r) returns r[2]. After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3]) _itemsrchsf|_fd}||_yfzx|_fd}||_y)Nc|Srr;)ritems r?rz!itemgetter.__init__..funcs 4y rAc.tfdDS)Nc3(K|] }| ywrr;)rrqrs r?rz4itemgetter.__init__..func.. s3USVUsr)ritemss`r?rz!itemgetter.__init__..funcs3U333rAr)rrrrs `` r?rzitemgetter.__init__s9'DK !DJ#''E/ 1DK% 4DJrAc$|j|Srrrs r?rzitemgetter.__call__#rrAc |jjd|jjddjt t |j dSr)rrrirrrrrs r?rzitemgetter.__repr__&s?"nn77"nn55"iiD$++(>?A ArAc2|j|jfSr)rrrs r?rzitemgetter.__reduce__+rrANrr;rAr?r"r"s# $I A +rAr"c,eZdZdZdZdZdZdZdZy)r*z Return a callable object that calls the given method on its operand. After f = methodcaller('name'), the call f(r) returns r.name(). After g = methodcaller('name', 'date', foo=1), the call g(r) returns r.name('date', foo=1). )_name_args_kwargscx||_t|jts td||_||_y)Nzmethod name must be a string)rr{rrjrr)rrrrs r?rzmethodcaller.__init__7s1 $**c*:; ;  rAcbt||j|ji|jSr)rrrrrs r?rzmethodcaller.__call__>s''wsDJJ'Dt||DDrAcdt|jg}|jtt|j|jd|j j D|jjd|jjddj|dS)Nc30K|]\}}|d|yw)=Nr;)rkvs r?rz(methodcaller.__repr__..DsF1EAq!$1Esrrrr) rrextendrrrrrrrir)rrs r?rzmethodcaller.__repr__AsxTZZ ! Cdjj)* F1C1C1EFF"nn77"nn55"iio/ /rAc|js&|j|jf|jzfSddlm}||j|jfi|j|jfS)Nr9)partial)rrrr functoolsr)rrs r?rzmethodcaller.__reduce__IsQ||>>DJJ=4::#== = )4>>4::FF R RrANrr;rAr?r*r*.s$ .IE/SrAr*c||z }|S)zSame as a += b.r;r<s r?rrSFA HrAc||z}|S)zSame as a &= b.r;r<s r?rrXrrAcnt|ds#dt|jz}t|||z }|S)z&Same as a += b, for a and b sequences.rdrerfrks r?rr]s8 1m $1DG4D4DDnFA HrAc||z}|S)zSame as a //= b.r;r<s r?rre!GA HrAc||z}|S)zSame as a <<= b.r;r<s r?rrjrrAc||z}|S)zSame as a %= b.r;r<s r?rrorrAc||z}|S)zSame as a *= b.r;r<s r?rrtrrAc||z}|S)zSame as a @= b.r;r<s r?rryrrAc||z}|S)zSame as a |= b.r;r<s r?rr~rrAc||z}|S)zSame as a **= b.r;r<s r?rrrrAc||z}|S)zSame as a >>= b.r;r<s r?rrrrAc||z}|S)zSame as a -= b.r;r<s r?r!r!rrAc||z}|S)zSame as a /= b.r;r<s r?r#r#rrAc||z}|S)zSame as a ^= b.r;r<s r?r$r$rrA)*)rN)r9)kr__all__builtinsrrOr(r%r r-r rr/r7rr rrr rrrr'r+r,r)r.r0r1r2r3r5r6r8rrr r rrr4r&rrr"r*rrrrrrrrrrrr!r#r$ _operator ImportError__lt____le____eq____ne____ge____gt____not____abs____add____and__r __floordiv__rT__inv__ __invert__ __lshift____mod____mul__ __matmul____neg____or____pos____pow__ __rshift____sub__ __truediv____xor__ __concat__ __contains__ __delitem__rd __setitem____iadd____iand__ __iconcat__ __ifloordiv__ __ilshift____imod____imul__ __imatmul____ior____ipow__ __irshift____isub__ __itruediv____ixor__r;rAr?rsJ  8!       A %R %+%+N++> S SJ              ""                                        i  sD00D87D8__pycache__/pydoc.cpython-312.opt-1.pyc000064400000426711152342670510013554 0ustar00 ֦iddZdgZdZdZdZddlZddlZddlZddlZ ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZddlmZdd lmZd Z d Z!d Z"d Z#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+ejXdejZZ.dZ/dZ0dZ1dZ2e3ejhZ5dPdZ6dZ7dZ8dZ9dZ:ifd Z;Gd!d"e<Z=d#Z>difd$Z?Gd%d&Z@Gd'd(eZAGd)d*e@ZBGd+d,eZCGd-d.e@ZDGd/d0eDZEd1aFd2ZGd3ZHd4ZId5ZJd6ZKd7ZLd8ZMd9ZNdQd:ZOeDZPeEZQeBZRdQd;ZS dRd<ZT dSd=ZUdQd>ZVdTd?ZWGd@dAZXeXZYGdBdCZZdDZ[dEZ\dUdFZ]dQdGdHdIdJZ^dKZ_dLZ`dMZadNZbecdOk(rebyy)VaGenerate Python documentation in HTML or text for interactive use. At the Python interactive prompt, calling help(thing) on a Python object documents the object, and calling help() starts up an interactive help session. Or, at the shell command line outside of Python: Run "pydoc " to show documentation on something. may be the name of a function, module, package, or a dotted reference to a class or function within a module or module in a package. If the argument contains a path segment delimiter (e.g. slash on Unix, backslash on Windows) it is treated as the path to a Python source file. Run "pydoc -k " to search for a keyword in the synopsis lines of all available modules. Run "pydoc -n " to start an HTTP server with the given hostname (default: localhost) on the local machine. Run "pydoc -p " to start an HTTP server on the given port on the local machine. Port number 0 can be used to get an arbitrary unused port. Run "pydoc -b" to start an HTTP server on an arbitrary unused port and open a web browser to interactively browse documentation. Combine with the -n and -p options to control the hostname and port used. Run "pydoc -w " to write out the HTML documentation for a module to a file named ".html". Module docs for core modules are assumed to be in https://docs.python.org/X.Y/library/ This can be overridden by setting the PYTHONDOCS environment variable to a different URL or to a local directory containing the Library Reference Manual pages. helpzKa-Ping Yee z26 February 2001zGuido van Rossum, for an excellent programming language. Tommy Burnette, the original creator of manpy. Paul Prescod, for all his work on onlinehelp. Richard Chamberlain, for the first implementation of textdoc. N)deque)Repr)format_exception_onlycJg}g}tjD]}tjj|xsd}tjj |}||vsJtjj |sj|j ||j ||S)zAConvert sys.path into a list of absolute, existing, unique paths..)syspathosabspathnormcaseisdirappend)dirsnormdirsdirnormdirs /usr/lib64/python3.12/pydoc.pypathdirsrSsz DHxxggoocjS)''""3' ( "rww}}S'9 KK  OOG $  Kctjj|j}|y|jj dddD]}t ||}tj|sy|S)Nr) r modulesget __module__ __qualname__splitgetattrinspectisclass)funcclsnames r _findclassr$_sb ++//$// *C {!!'',Sb1c4 2 ??3  Jrc~tj|rl|jj}|j}tj |r't t ||dd|jur|}n|j}ntj|r)|j}t|}|t |||urCytj|r\|j}|j}tj |r"|jdz|z|jk(r|}n|j}nt|tr4|j}|j}t|}|t |||urytj|stj |rb|j}|j"}t |||urytj$|r't |dd}t|t&r ||vr||Sy|j(D]} t+t ||}||cSy#t,$rY-wxYw)N__func__r __slots__)rismethodr&__name____self__r r __class__ isfunctionr$ isbuiltinr isinstancepropertyfgetismethoddescriptorisdatadescriptor __objclass__ismemberdescriptordict__mro__ _getowndocAttributeError)objr#selfr"r!slotsbasedocs r_finddocr>is||$$|| OOD ! GD$-z :cll JC..C   C ||o ;'#t,C7   3 |||| OOD !    #d *c.>.> >C..C C "xx}} ;'#t,C7  # #C (G,D,DS,I|| 3 S (  % %c *Cd3E%&45=T{"  WT401C ?J      sH00 H<;H<c tj|d}|y|tur+t|j}t |t r||k(ry|S#t $rYywxYw)zUGet the documentation string for an object if it is not inherited from its class.__doc__N)object__getattribute__typer@r.strr8)r9r=typedocs rr7r7sa %%c95 ; d?3i''G'3'GsN sA2AA AAct|}| t|}t |t syt j|S#ttf$rYywxYw)zGet the documentation string for an object. All tabs are expanded to spaces. To clean up docstrings that are indented to line up with blocks of code, any whitespace than can be uniformly removed from the second line onwards is removed.N)r7r>r8 TypeErrorr.rDrcleandoc)rAr=s r_getdocrIs[ V C { 6"C c3    C   *  s AAAct|xstj|}|xr%tjdd|j xsdS)z-Get the doc string or comments for an object.z^ * )rIr getcommentsresubrstrip)rAresults rgetdocrQs> V_ ; 3 3F ;F  :bffWb&--/: @b@rc|jjd}t|dk(r|ddfSt|dk\r,|djs|ddj |ddfSddj |fS)z>Split a doc string into a synopsis line (if any) and the rest. rrKN)striprlenrOjoin)r=liness rsplitdocrZs{ IIK  d #E 5zQQx| Uqq!2Qx59--- tyy rc`|j}|j|k7r|jdz|z}|S)z@Get a class name and qualify it with a module name if necessary.r)r)rrAmodnamer#s r classnamer^s3 ??D G#  3&- Krcd|jvrM|jjdd}|j|k7r|j|jdz|zS|S|j|k7r |jSy)z_Get a name of the enclosing class (qualified it with a module name if necessary) or module.rrN)r rpartitionrr\s r parentnameras f!!!""--c215    'F,=,=,I$$s*T1 1K    '$$ $ (rctj|xsqtj|xsZtj|xsCtj|xs,tj |xstj | S)z>Check if an object is of a type that probably means it's data.)rismoduler isroutineisframe istracebackiscode)rAs risdatarhsy  (FGOOF,CF!!&)F-4__V-DF##F+F/6~~f/E GGrcf|r.|dj|j|d}|dd}|r.|S)z/Do a series of global replacements on a string.rTrrUN)rXr)textpairss rreplacerls; Qx}}TZZa12ab   Krct||kDr>td|dz dz}td|dz |z }|d|dz|t||z dzS|S)zCOmit part of a string if needed to make it fit in a maximum length.rrUN...)rWmax)rjmaxlenpreposts rcramrts` 4y6!fQh]#1fQhsl#DSzE!DT4$999 Krz at 0x[0-9a-f]{6,16}(>+)$c.tjd|S)z>Remove the hexadecimal id from a Python object representation.z\1) _re_stripidrNrjs rstripidrxs ??5$ ''rctj|rytj|r)t|dd}tj|xs|du Sy)zo Returns True if fn is a bound method, regardless of whether fn was implemented in Python or in C. Tr*NF)rr(r-rrc)fnr:s r_is_bound_methodr{sQ r:t,$$T*->? U @ z$'(||~r3'  Nrcvg}g}|D]-}||r|j||j|/||fS)zSplit sequence s via predicate, and return pair ([true], [false]). The return value is a 2-tuple of lists, ([x for x in s if predicate(x)], [x for x in s if not predicate(x)]) r)s predicateyesnoxs r _split_listrs@ C B  Q< JJqM IIaL  7Nrc*|dvry|jdr|jdry|jdr t|dry|tur.|tvr&t t ||dtjry |||vS|jd S) z3Decide whether to show documentation on a variable.>r@__date____file__r)__path____spec__r' __author__ __cached__ __loader__r __credits__ __package__ __version__ __builtins__rr__rT__fieldsTNF) startswithendswithhasattr __future___future_feature_namesr.r_Feature)r#allr9s r visiblenamer"s HH tt!4Q sY 7 *)>!> gc4. 0C0C D s{??3'''rcg}tj|D]d\}}}}tj|r!d}t|tr!|j d}n|dk(r t |rd}|j||||ff|S)zUWrap inspect.classify_class_attrs, with fixup for data descriptors and bound methods.data descriptorreadonly propertymethod static method)rclassify_class_attrsr2r.r/fsetr{r)rAresultsr#kindr"rs rrr:sG$+$@$@$H tS%  # #E *$D%*uzz/A* X "25"9"DdC/0%I Nrc t|dg} t|Dcic]\}}||t|z c}}fd}|j |ycc}}w#t$riY+wxYw)zGSort the attrs list in-place by _fields and then alphabetically by namerc8j|dd|dfSNr)r)attr field_orders rz!sort_attributes..PsKOODGQ7aArrN)r enumeraterWrGsort)attrsrAfieldsir#keyfuncrs @rsort_attributesrGstVY +F=Fv=NO=N DtaF m+=NO BG JJ7J P  s!AAAA A'&A'ctjj|rIdD]D}tjjtjj |d|zsDyy)z3Guess whether a path refers to a package directory.)z.pyz.pyc__init__TF)r r risfilerX)r exts r ispackagerUsH ww}}T"Cww~~bggll4c1ABC# rcd} tj|j}|D]\}}}}}|tjk(r||z }#|tjk(rt j 5t jdttj|}dddttsy|jjddjcS|tjk(r |dvr||z }|tj tj"tj$fvsy y#1swYxYw#tj&t(t*f$rYywxYw)z8Return the one-line summary of a file object, if presentrKignoreNrSr)())tokenizegenerate_tokensreadlineSTRINGNEWLINEwarningscatch_warnings simplefilter SyntaxWarningast literal_evalr.rDrVrOPCOMMENTNLENCODING TokenErrorUnicodeDecodeError SyntaxError)filestringtokenstok_type tok_stringr docstrings rsource_synopsisr]s/F))$--8-3 )Hj!Q8??**$X---,,.))(MB # 0 0 8I/")S1 (..t4Q7==??X[[(Z:-E*$("2"2HKKARAR!SS.4" /.   !3[ AsCA+E /0EE 91E +AE ;E =E E E E-,E-cttj|j}|j|d\}}|||krY|j t t jjrt jj}nO|j t t jjrt jj}nd}|- tj|}|5t|}dddn|d|}t j j#d||} t j$j'|} t(j*d=| j,r| j,j/dnd}||f||<|S#t$rYywxYw#1swY!xYw#YyxYw)z.Get the one-line summary out of a module file.NNN__temp__loaderr)r statst_mtimerrtuple importlib machineryBYTECODE_SUFFIXESSourcelessFileLoaderEXTENSION_SUFFIXESExtensionFileLoaderropenOSErrorrutilspec_from_file_location _bootstrap_loadr rr@ splitlines) filenamecachemtime lastupdaterP loader_clsrrspecmodules rsynopsisrvsz GGH  & &E8\:JZ%/   U9#6#6#H#HI J",,AAJ   uY%8%8%K%KL M",,@@JJ   }}X. (. H5F>>99*hAG:ID "--33D9 J'7=~~V^^..034F &/h M)   s*F3 F'4F3 F$#F$'F03F7ceZdZdZdZdZy)ErrorDuringImportzEErrors that occurred while trying to import something to document it.ct|ts0t||_||_|j |_||_ ytjdt|\|_|_|_||_ y)NzCA tuple value for exc_info is deprecated, use an exception instance) r.rrCexcr __traceback__tbrwarnDeprecationWarningr)r:rexc_infos rrzErrorDuringImport.__init__sc(E*H~DH!DJ,,DG ! MM_, .-5 )DHdj$'  rcl|jj}d|jd|d|jS)Nz problem in  - z: )rr)rr)r:rs r__str__zErrorDuringImport.__str__s&hh+/==#tzzJJrN)r)rrr@rrrrrrsO !Krrcxtjj}t|d5}||j t |k(}dddt jj|}t jj|\}}r!tjj||}n tjj||}tjj|||} tjj|S#1swYxYw#t $r} t#|| d} ~ wwxYw)z> 1 1$V 1 LD+##))$//   +c**+s#D4DD D9( D44D9c |r|tjvrv|tjvrdtjDcgc]}|j|dzs|}}|g|zD])}tj|||<tj|=+t j |}|Scc}w#t $r}|tjvr'ttj|j|t|turt|j|t|tr|j|k(rYd}~yt||d}~wwxYw)aImport a module; handle errors; return None if the module isn't found. If the module *is* found but an exception occurs, it's wrapped in an ErrorDuringImport exception and reraised. Unlike __import__, if a package path is specified, the module at the end of the path is returned, not the package at the beginning. If the optional 'forceload' argument is 1, we reload the module from disk (unless it's a dynamic extension).rN)r rbuiltin_module_namesrr import_modulerrrrCrrr. ImportErrorr#)r forceloadrmsubsrrrs r safeimportrs/ ,3333 $';;K;a!,,tcz2J;K 6D=C!$S!1E#J C()((. M)L  / 3;; #CKK$5$>$>D D #Y+ %#CLL#6 6 [ )chh$.>$D#. . /s68B(B#B#A B(#B(( E1A?E5 EEceZdZejj ddejddzZd dZ d dZ e xZ xZ xZ xZxZZej$dfdZy) Doc PYTHONDOCSz%https://docs.python.org/%d.%d/libraryNrUcp||f|z} tj|r|j|Stj|r|j|Stj |r|j |S tj|r|j|S|j|S#t$rY>wxYw)z%Generate documentation for an object.) rrc docmoduler docclassrd docroutiner8r2docdatadocother)r:rAr#argss rdocumentz Doc.documents~$  '0E)Ev&}t}}d/C(C  ($1G*G(  # #F +LDLL$4G-Gt}}d##   s#B)#B)#B)) B54B5cnd|xrdt|zdt|j}t|)z+Raise an exception for unimplemented types.z!don't know how to document object z of type )reprrCr)rG)r:rAr#r'messages rfailzDoc.fails6  %S4:% %tF|'<'<>  rstdlibc tj|}tjj d|j }tjj|}t|ttr|jdvs@|j|r|jtjj|ds|jdvr|jdr;dj|jd|jj!}|Stjj||jj!d z}|Sd }|S#t$rd}YYwxYw) z*Return the location of module docs or None (built-in)r ) errno exceptionsgcmarshalposixsignalr _thread zipimportz site-packages)z xml.etreeztest.test_pydoc.pydoc_mod)zhttp://zhttps://z {}/{}.html/.htmlN)r getabsfilerGr environrr r r r.rCr)rrXformatrOlower)r:rAbasedirrdoclocs r getdoclocz Doc.getdocloc s) %%f-D doo>''""7+ vtBx ( __!99oog&//"'',,w"HI OO#M M  !89%,,V]]3-?AVAVAXY  ffoo.C.C.E.OP F ' D sE"" E10E1N)r)rrr r<rr version_infor r(r-r"r#r$r& docpropertyr% sysconfigget_pathrArrrrrso G"%"2"22A"6!78J$ ! LPOIOO:OO;(: (:(:8(Drrc<eZdZdZdZdZdZdZdZeZ dZ eZ y) HTMLReprzBClass for safely making an HTML representation of a Python object.cttj|dx|_|_d|_dx|_|_yN drrmaxlistmaxtuplemaxdict maxstringmaxotherr:s rrzHTMLRepr.__init__*1 d')) t} ),,rc $t|ddddddS)N&z&z>)rlr:rjs rescapezHTMLRepr.escape0stS'3VDDrc.tj||SrB)rr+r:rAs rr+z HTMLRepr.repr3syyv&&rc Btt|drTddjt|jj z}t||rt ||||S|j ttt||jSNr)repr_r) rrCrXr)rrr[rtrxr+rSr:rlevel methodnames rrepr1zHTMLRepr.repr16sy 47J ' 388DG,<,<,B,B,D#EEJtZ(0wtZ0E::{{4Q 0$--@AArct||j}t|}d|vr/dt|ddvr d|dz|j |z|dzSt j dd|j |S)N\\\rKrrz-((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)z\1)rtrRr+rlr[rMrNr:rrbtesttestreprs r repr_stringzHTMLRepr.repr_string=s}At~~&: 4)r[rtrxr+rRr+r)r:rrbs r repr_instancezHTMLRepr.repr_instanceJsQ G;;tGDG$4dnnEF F G;;1E1EEF Fs 69*A%N) r)rrr@rr[r+rdrlrepr_strrp repr_unicoderrrrHrH(s4L- E'B -HG LrrHc eZdZdZeZej ZejZdZddZ ddZ dZ dZ dZ d Zd Zd Zd Zd ZdZdZdiiifdZddZddZddiifdZdZddiiiddfdZddZeZddZddZy)HTMLDocz'Formatter class for HTML documentation.cd|d|dS)Format an HTML page.zN Python: z z r)r:titlecontentss rpagez HTMLDoc.page[sH& &rcd|d|xsddS)zFormat a page heading.zU
 
z
 z
r)r:rwextrass rheadingzHTMLDoc.headinggs &$H$ & &rNc | dd|zzdz}d|d|d}|r|d|d|d |d |d |d z}n|d|d |d|d z}|d|zzS)z Format a section with a heading.zr{zz-

z z-decor">z
 
z
z z
z. %s
r) r:rwr"rxwidthprelude marginaliagaprPs rsectionzHTMLDoc.sectionps{  .E1AAIMJ   :sGS::F 8;ZNNFIHTTTrc2d|z}|j|g|S)z$Format a section with a big heading.z&%s)r)r:rwr's r bigsectionzHTMLDoc.bigsections"85@t||E)D))rc f|j|j}t|dddddddd S)z!Format literal preformatted text. z r*r{rS
)r[ expandtabsrlrZs r preformatzHTMLDoc.preformats7{{4??,-tVWfg (D(< rrz%s
)rWrange)r:listr=rProwscolrs r multicolumnzHTMLDoc.multicolumnsD A !#8C88F48T#Xd]3s4y=#fT!Wo5@F4g%F  ,f44rc d|zS)Nz%srrZs rgreyz HTMLDoc.greys !?$!FFrc8|D]}||vsd||d|dcS|S)z:Make a link for an identifier, given name-to-URL mappings.
r)r:r#dictsr5s rnamelinkzHTMLDoc.namelinks)Dt|04T DAA rc |jtjj|j}}t ||r.t |||ur d|jd|dt||dSt||S)zMake a link for a class.r.html#rr)r)r rrrrrr^)r:rAr]r#rs r classlinkzHTMLDoc.classlinkse 8I8I(Jf 64 WVT%:f%Dy'AC C))rcd}|jtjj|j}}t ||rt |||urqd|jvrE|jjdd}|j|k7r|jd|}n$d|z}n|j|k7rd|jz}|rd|dt||d St||S) z.Make a link for the enclosing class or module.Nrrrz#%s%s.htmlrrr) r)r rrrrrrr`ra)r:rAr]linkr#rs r parentlinkzHTMLDoc.parentlinks 8I8I(Jf 64 WVT%:f%Df)))**55c:1=$$/+1??DAD 4r)r)r]s r modulelinkzHTMLDoc.modulelinks-3__fooNNrc||\}}}}|r|j|S|r |d|d}nd|z}|rd|z}n|}d|d|dS)z;Make a link for a module or package to display in an index.rr:rz"%s (package)rrr)r)r: modpkginfor#r rshadowedurlrjs r modpkglinkzHTMLDoc.modpkglinksV*4'dIx 99T? " "&-Cd"C 7$>DD(+T22rcd|d|dS)zMake a link to source file.z%sNrK) r[rMcompilesearchspanrgroupsrlintrrX)r:rjr[funcsclassesrrherepatternmatchstartendrschemerfcpepselfdotr#rs rmarkupzHTMLDoc.markups&4;;**34~~dD11e1JE3 NN6$tE"23 438<<> 0Cc7DSk))#x8SAB@3s8KVC[IJ9CHDVC[IJCE?c)NN7T]]4-I#IJNN#=#DEc#a%C't}}T7E7KLt}}T7;<D3~~dD11e14 vd45k*+wwwrctd}|D]}t|trq|\}}|dz}||j||z}|rJ||fk7rDg}|D]#} |j|j| |%|dzdj |zdz}|dz}t|t s|d|j ||zz}d|zS) zAProduce HTML for a class tree as given by inspect.getclasstree().rKz

r, rz
z
%s
z
%s
)r.rrrrXr formattree) r:treer]parentrPentrycbasesparentsr<s rrzHTMLDoc.formattreesE%' 5"==$..G"<<Uvi/ G %t~~dG'DE!&#c\DIIg,>>DF)+E4("3doo7A7'#''!6))rc  |j} |j}|jd}g}t t |dz D]2}|j ddj|d|dzd||d4dj||ddz} d| z} tj|} tjj| } j| | } g}t|d r[t!|j"}|dd d k(r|ddd k(r|d dj%}|j dj'|zt|dr3|j j't!|j(|r| ddj|zz} j+|}|dt-z}nd}j/| d| z|z}tj0|tj2}gi}}tj0|tj4D]Q\}}|tj6|xs||us$t9|||s2|j ||fd|zx||<||<S|D]\}}|j:D]s}|j|j<}}t>j@jC|}||k7s@|sCt||sPtE|||us_||vsd|dz|zx||<||<ugi}}tj0|tjFD]{\}}|-tjH|stj6||us5t9|||sC|j ||fd|z||<tjJ|st||||<}g}tj0|tLD]&\}}t9|||s|j ||f(jOtQ|jR||}|xrd|z}|d|zz}t|drg}tUjV|jXD]\}}} |j ||| df|j[j]|j^}!|jadd|!z}n-|r+j]|fd}!|jadd|!z}|r|Dcgc]\}}| }"}}jctjd|"d|g}!|D])\}}|!j jg|||||+|jad d!d"j|!z}|rUg}!|D])\}}|!j jg|||||+|jad#d$d"j|!z}|rRg}!|D]&\}}|!j jg||(|jad%d&d'j|!z}t|d(rEjOt!|jhjR}!|jad)d*|!z}t|d+rEjOt!|jjjR}!|jad,d-|!z}|S#t$rd}YwxYw#t$rd } YwxYwcc}}w).z/Produce HTML documentation for a module object.NrrTrz.html" class="white">rr!%sr0r $Revision: $z version %srz (%s)rz-
Module ReferencerKzindex
#rz#-z%sz

%s

rrzPackage Contentsz pkg-contentc,j|dSr})r)tr:s rrz#HTMLDoc.docmodule..gs4??1Q4#8rModulesClassesindexr* Functions functionsDatadatarrAuthorauthorrCreditscredits)6r)__all__r8rrrWrrXrr;urllibparsequoterrGrrDrrVr[rrAlocalsr}r~rcr getmodulerrrr rrrrdr-r,rhrrQrpkgutil iter_modulesrrrrrr getclasstreer(rr)#r:rAr#modignoredrpartslinksr linkednameheadr rrinfoversionr@rPrrcdictrrr<r]rrfdictrr=modpkgsimporterispkgrx classlists#` rr"zHTMLDoc.docmodules ..C 3s5z!|$A LL%1+&a2 3%XXeeBCj01 2Z? $%%f-D,,$$T*C}}S$/H 6= )&,,-Gs|11gbclc6I!"R...0 KK t{{7';; < 6: & KK C$89 : 'DIIdO33D'  DvxOFFd$?($JV$ST$$VW-=-=>R!,,VW__EJC""5)3V>sC0NNC<003c 9E#Ju F"JC#}}dooW1d?v'Fvs+t3"e|7>7IC7OOE#Jt ("2u!,,VW5F5FGJC!!%(G,=,=e,D,NsC0LL#u.!%E#J))%0s%,H!,,VV>F H" U eS 9:#doo h 799F 6< ({{3v'8'8#94>>JHdooh(KKF 6= ){{3v'9'9#:DNNKHdooiHMMF ] C  $#H $L.HorizontalRulecd|_yrneedonerTs rrz1HTMLDoc.docclass..HorizontalRule.__init__   rc<|jrdd|_y)Nz
rTrr:pushs rmaybez.HTMLDoc.docclass..HorizontalRule.maybe<<N  rNr)rrrrrsrHorizontalRuler  ! !rrrUz&
Method resolution order:
z
%s

c (t||\}}|rW j||D]:\}}}} t |}j||  |d<|S#t$rj || Y0wxYw)NrSrrrr( Exceptionr%)msgrrokr#rhomeclsrrrhrmdictrrArr:s rspillzHTMLDoc.docclass..spills#E95IB S 24.D$Q ' 5 T]]5$(-wvwPQJ35L%=T\\%s;<=s A,,"BBct||\}}|r=j ||D] \}}}} j|| "|SrBrrr% rrrrr#rrrr rrr:s rspilldescriptorsz*HTMLDoc.docclass..spilldescriptorsS#E95IB S 24.D$eT37835Lrcdt||\}}|r j||D]\}}}}jt||}t |} | s d|zn;j t |j } d| z} d|| dd|S)Nz
%s
z
%s
rrS)rrr&rrQrr)rrrrr#rrrr<r=rrr r rrArr:s r spilldataz#HTMLDoc.docclass..spilldatas#E95IB S 24.D$==)>cJD -C0478"kk&-*/%A@3FdC@AJ35Lrr9r-rc|duSNrUrr thisclasss rrz"HTMLDoc.docclass..AaDI z Methods %sc|ddk(SNrTrrrs rrz"HTMLDoc.docclass.. AaDH$4rzClass methods %sc|ddk(SNrTz class methodrrs rrz"HTMLDoc.docclass.. AaDN$:rzStatic methods %sc|ddk(SNrTrrrs rrz"HTMLDoc.docclass.. AaDO$;rzReadonly properties %sc|ddk(SNrTrrrs rrz"HTMLDoc.docclass..qt7J/JrzData descriptors %sc|ddk(SNrTrrrs rrz"HTMLDoc.docclass..qt7H/HrzData and other attributes %sc|ddk(SNrTrrrs rrz"HTMLDoc.docclass.. !rrK class zz = class r(%s)rN()rz&%s
 
rwrn)r)rrrrgetmrorWrrrrrrrrGpopleftrbuiltinsrArrX signature ValueErrorrDr[rQrrr)#r:rAr#rrrrrealnamerrxrmror<r rrrr"rrrranchor inheritedtagrwrdeclr7argspecr=r r rrs#`` ``` @@@@rr#zHTMLDoc.docclasss??x   ! ! GNN6*+ s8a< HHJ : ;_t~~d6<6G6G(IIJ O  $   &0DF/K3/K+T4e&1c5)/K 3). %Cw"%*s"2S"8 8E#J -   &e */KKM !!HQK *52MN E9X__,hoo1M!f$$)DNN9;A;L;L-NN 9 C E6 *,,e46E,s2E:D||E7Ha==k3    nI& I s<1L; 2 M?M(M# MM M M #M76M7cH|jd|j|zSz)Format an argument default value as text.=)rr+r]s r formatvaluezHTMLDoc.formatvalue*syytyy0011rc |j} |xs| }||}|dn |jdz|z} d} d} d} t|ri|j}||urt|dd} nt j |rd|j ||z} nd|j |j|z} nkt j|st j|r? |j}|d|j ||z} n||urd |j ||z} n|} t j| rS|Q| j|jk7s| j|jd z| zk7r|j| |}|rd |z} t j |st j"|rd }nd}|| k(r d | d| d}nW|Ht j$|| g|ur/d|jdz| zd| d}d} | j'd rd} n| }d | d|d|}d}t j(|r> t j*|}|r&t1|}| dk(rd|z}|j2s|dd}|sd}||z|j5|z| xr|j7d| zz}| rd|zS|j9t;||j<|||}|xrd|z}d|d|dS#t$rYwxYw#t,t.f$rd}YwxYw) z;Produce HTML documentation for a function or method object.NrKrFr& class method of %s method of %s instance unbound %s method from r from %sasync r0z ">r1z
%sz
%s
z%
%s
rzr)r)r{r*rrr rr+r1ismethodwrapperr3r8r,rrriscoroutinefunctionisasyncgenfunctiongetattr_staticrrdr7r8rGrD__annotations__r[rrrQr)r:rAr#rrrrrrr9r;noteskipdocsimfuncimselfobjclasspnameasyncqualifierrwreallinkr?r7r>r=s rr$zHTMLDoc.docroutine.s1??x ?G " s:TA F #__F| T:(,t~~fc/JJ/$..$$c3++((0%%f- D!..:/$..32OODW,#dnnXs&CCDF   f %'*=   !3!3 3   7#7#7##=#H HOOFC0E!E)  ' ' /**62%NN 8 >DhOE&&r8R8FBKK#%0(<??8,D#h(E   V $ !#--f5 i.z)BTIE"11")!B-G% G(<<AHyy?$FGI +d2 2++vwICGACGC15s; ;"  P * !  !s$ K'K) K&%K&)K=<K=cg}|j}|r |d|z|jt||j}|r |d|z|ddj |S)z1Produce html documentation for a data descriptor.z!
%s
z&
%s
rrK)rrrQrrX r:rAr#rrrrrr=s rr%zHTMLDoc.docdatas`~~  5< =kk&.$..9  :S@ A YwwwrcD|xrd|zxsd}||j|zS)z-Produce HTML documentation for a data object.z%s = rKr+)r:rAr#rrlhss rr&zHTMLDoc.docothers+6/$6<"TYYv&&&rc(g}|i}tj|gD]5\}}}td|Dr|j|d|||vfd||<7|j |j ||j }|j|d|S)z2Generate an HTML index for a directory of modules.c3NK|]}dt|cxkxrdkncyw)iiN)ord.0chs r z HTMLDoc.index..s"@4RFc"g///4s#%rKrTr)rranyrrrrr)r:rrrrr#rrxs rrz HTMLDoc.indexs  X%,%9%93%%@ !HdE@4@@ NND"eTX-=> ?HTN &A  ##GT__=sGX66rrK)rKNr{rBrNNN)r)rrr@rH_repr_instancer+r[ryr}rrrrrrrrrrrrrr"r#rCr$r%rDr&rrrrrtrtRs1ZN   D  " "F &&3419U** < 5G*/&O 38#'b"b% R*&sj%)d"b`>D2'+RdW.s5"rDy2~s)rXrZs rboldz TextDoc.boldsww5555rc|sy|jdDcgc]}||zj}}dj|Scc}w)z6Indent text by prepending a given prefix to each line.rKrS)rrOrX)r:rjprefixlinerYs rindentzTextDoc.indentsHB6:jj6FG6Fd&4-'')6FGyyHsAct|j|j}|j|dz|zdzS)z&Format a section with a given heading.rSr)rzrOrv)r:rwrxclean_contentss rrzTextDoc.sections7X.557yy$&7&@@rNc d}|D]}t|trG|\}}||zt|z}|r(||fk7r"fd|D} |ddj| zz}|dz}Zt|tsk||j ||dzz}|S)zBRender in text a class tree as returned by inspect.getclasstree().rKc36K|]}t|ywrBr^)rcrr]s rrez%TextDoc.formattree..sDeyG4esr2rrS )r.rr^rXrr) r:rr]rrxrPrrrrs ` rrzTextDoc.formattreesE%' 5&9Q+@@Uvi/DeDG#ftyy/A&AAF$E4($//7Av#88 rc  |j}tt|\}}|jd||xrd|zz}t |dd}|j |} | ||jd| dzz}|r||jd|z}g} t j|t jD]D\} } |t j| xs||us$t| ||s2| j| | fFg} t j|t jD]U\} } |-t j| st j| |us5t| ||sC| j| | fWg}t j|tD]&\} } t| ||s|j| | f(g}t}t!|drt#j$|j&D]?\}}}|j)||r|j|d z/|j|A|j+||jd d j-|z}g}t j|t j.D]:\} } | jj1|d zs%| |vs*|j| <|r4|j+||jd d j-|z}| r| D cgc]\} } |  }} } |j3t j4|d|g}| D]'\} } |j|j7| | |)||jdd j-|z}| rRg}| D]'\} } |j|j7| | |)||jdd j-|z}|rTg}|D])\} } |j|j9| | |d+||jdd j-|z}t!|drMt;|j<}|dddk(r|dddk(r|ddj?}||jd|z}t!|dr(||jdt;|j@z}t!|dr(||jdt;|jBz}t!|dr(||jdt;|jDz} t jF|}||jd!|z}|Scc} } w#tH$rd }Y*wxYw)"z5Produce text documentation for a given module object.NAMErrNzMODULE REFERENCEa. The following documentation is automatically generated from the Python source files. It may be incomplete, incorrect or include features that are considered implementation detail and may vary between Python implementations. When in doubt, consult the module reference at the location listed above. DESCRIPTIONr (package)zPACKAGE CONTENTSrSr SUBMODULESrTCLASSES FUNCTIONSF)rqDATArrrrrVERSIONrDATErAUTHORrCREDITSr0FILE)%r)rZrQrrrArr~r rrrrdr-rhsetrrrraddrrXrcrrrr(r&rDrrVrrrr;rG)r:rAr#rrsynopdescrPrr@rrrrrr modpkgs_namesrr]r submodulesrrxrrs rr"zTextDoc.docmodules vf~. tfde.E &FGfi.'  dll+=vI@F dll=$??F!,,VW__EJC%%e,66AsC0NNC<0 F !,,VW5F5FGJC!!%(G,=,=e,D,NsC0LL#u. H !,,VV>F 6: &dll63v3GHHF 6< (dll8S9J9J5KLLF 6= )dll9c&:L:L6MNNF %%f-D$,,vt44 G:@ D s U2U$$ U21U2c  j}|xs|}j}jfd}||k(rdj|z}nj|dz|z}|r#t ||} |ddj | zz}g} | j  tj} | r t| } | r| dk7r|| zdzt} | r | dzttj}t|d kDr(d |D]}d ||zd t!d t"j%Dtj&}t|}d}|rDd|d|D] }d |z||kDrdt||z zdzd Gfdd}|fd}fd}fd}t)Dcgc]\}}}}t+|r||||f}}}}}|r|r|j- n|dd  t/| fd\}}t0j2ur t0j2ur|}V urd}ndt5 jz}t7||d|z|d}|d|z|d }|d!|z|d"}|d#|z|d$}|d%|z|d&}|d'|z|d(}|}|rdj | } | s|dzS|dzj9| j;d)zdzS#ttf$rd} YwxYwcc}}}}w)*z4Produce text documentation for a given class object.ct||SrBr)rrs rmakenamez"TextDoc.docclass..makenameasQ? "rclass z = class r2rNr3rSrUzMethod resolution order:rrKc3K|]C}|jjds&|jdk(rt|jEyw)rr6N)r)rrrD)rcr"s rrez#TextDoc.docclass..s? S*E3LL++C0S^^z5Q *EsA A rrzBuilt-in subclasses:z ... and z other subclassesceZdZdZfdZy)(TextDoc.docclass..HorizontalRulecd|_yrrrTs rrz1TextDoc.docclass..HorizontalRule.__init__rrc<|jrdd|_y)NzF----------------------------------------------------------------------rTrrs rrz.TextDoc.docclass..HorizontalRule.mayberrNrrsrrrrrrc t||\}}|rLj ||D]/\}}}} t |} j|| |1|S#t$r j || YXwxYwrBr) rrrrr#rrrr rrArr:s rr zTextDoc.docclass..spills#E95IB S 24.D$E ' 5 T]]5(,c67DE35L%=T\\%s;<=s A!!"BBct||\}}|r=j ||D] \}}}} j|| "|SrBr rs rrz*TextDoc.docclass..spilldescriptorsrrc t||\}}|r[ j ||D]>\}}}}t|} t |}  j | | d|dz@|S#t$r|j |} Y=wxYw)Nrrqr=rS)rrrQrr8__dict__r&)rrrrr#rrrr=r9r rrArr:s rrz#TextDoc.docclass..spilldatas#E95IB S 24.D$ -C5%fd3sD#bcJ 35L *5%..t45s A00B  B rrc|duSrrrs rrz"TextDoc.docclass..rrrrz Methods %s: c|ddk(Srrrs rrz"TextDoc.docclass..r rzClass methods %s: c|ddk(Sr"rrs rrz"TextDoc.docclass..r#rzStatic methods %s: c|ddk(Sr%rrs rrz"TextDoc.docclass..r&rzReadonly properties %s: c|ddk(Sr(rrs rrz"TextDoc.docclass..r)rzData descriptors %s: c|ddk(Sr+rrs rrz"TextDoc.docclass..r,rzData and other attributes %s: c|ddk(Sr.rrs rrz"TextDoc.docclass..r/rz | )r)rrrvmaprXrrr7r8rGrDrQrr4rWsortedrC__subclasses__r>rrr5rr6rAr^rrzrO)!r:rAr#rrr9rrrwrrxr7r?r=r:r< subclassesno_of_subclassesMAX_SUBCLASSES_TO_DISPLAY subclassnamerr rrrr"rrr<r=r rrs!`` ` @@@rr#zTextDoc.docclass[s??x   ++ # 8 tyy22EIIdOk1Hr=s rr$zTextDoc.docroutines??x ?G F #__F| T:(,y/EE/)$$c3++((0%%f- ?!..:/)Hc2JJDW,#i#&>>DF   f %'*=   !3!3 3   7#7#7##=#H Hvs+E!E)  ' ' /**62%NN 8 IIh'E&&r8R8FB??8,DIIdOe+h6E   V $ !#--f5 i.z) IIdOj8E"11")!B-G%/$6 $; .&BC$;#"J$++c*:*A*A*Cd*JK Ko"  H * !  !s$0 J+J JJJ,+J,cg}|j}|r||j||dt|xsd}|r||j||ddj |S)z1Produce text documentation for a data descriptor.rSrK)rrvrQrzrXr[s rr%zTextDoc.docdataHsb~~  4 ! JVn"  S! " Jwwwrrc$|j|}|r+|xr|dzxsd|z} |t| z } | dkr|d| dz}|xr|j|dzxsd|z} |s t|}|r#| d|j t |zdzz } | S)z-Produce text documentation for a data object.rrKrNrorS)r+rWrvrQrzrD) r:rAr#rrrqr=rr+rychops rr&zTextDoc.docotherXsyy  )TE\/R47DCI%DaxUd e 304506B$>.C  D4;;s3x0047 7D r)r)NrKr)NNNNri)r)rrr@rlrjr+rvrzrrr"r#rCr$r%rDr&rrrrrrrse1ZN   D6 A cJXLt'ML^  K $ rrrceZdZdZdZy) _PlainTextDocz2Subclass of TextDoc which overrides string stylingc|SrBrrZs rrvz_PlainTextDoc.boldis rN)r)rrr@rvrrrrrgs <rrc.tat|y)zCThe first time this is called, determine what kind of pager to use.N)getpagerpagerrws rrrns JE $Krc^ttjdstSttjdstStjj rtjj stStj dk(rtStjjdxstjjdrCtj dk(rfdStjjddvrfd Sfd StjjddvrtStj dk(rd Sttd rtjd dk(rdSddl }|j\}}tj| ttd r3tjd|zdk(rdtj|Sttj|S#tj|wxYw)z2Decide what method to use for paging through text.isatty emscriptenMANPAGERPAGERwin32c.tt|SrB tempfilepagerplainrj use_pagers rrzgetpager..s eDk9 ErTERM)dumbemacsc.tt|SrB) pipepagerrrs rrzgetpager..s %+y Arct|SrBrrs rrzgetpager..s $ :rc,tt|dS)Nzmore .sM%+x@rsystemz(less) 2>/dev/nullrct|dS)Nlessrrws rrzgetpager..s IdF3rNz more "%s"ct|dS)Nmorerrws rrzgetpager..s $ 7r)rr stdin plainpagerstdoutrplatformr r<rrtempfilemkstempcloseunlinkttypager)rfdrrs @rrrts 399h ' 3::x ( 99   SZZ%6%6%8 |||# z*EbjjnnW.EI <<7 "E E ZZ^^F #'8 8A A: : zz~~f!22 ||w@@r8+?!@A!E33%%'NRHHRL 2x RYY{X/E%F!%K7 ( ( (s7-H:HH,c0tjdd|S)z%Remove boldface formatting from text.z.rK)rMrNrws rrrs 66%T ""rc2ddl}|j|d|jd} |j5} |j |ddd |jy#t $rY&wxYw#1swY+xYw#t $rY9wxYw#t $rYnwxYwL)z3Page through text by feeding it to another program.rNTbackslashreplace)shellrerrors) subprocessPopenPIPErwriteKeyboardInterruptrwait)rjcmdrprocpipes rrrs   Ct:??#5  7D  ZZ4  4    IIK %  Z    !    sW A:A.AA:B  A+(A.*A++A..A73A:: BB BBc ddl}|j5}tjj |d}t |ddt jdk(rtjdnd5}|j|dddtj|dz|zd zdddy#1swY0xYw#1swYyxYw) z.s#))..+rcJtjjddddS)NrrT)r rrrrrrzttypager..s#)),,.s3BQ7rLINESrTz -- more --)qQz ) rS)bB)rrrttyr rfileno tcgetattr setcbreakrr8ioUnsupportedOperationrr r<rr8rrrXflush tcsetattr TCSAFLUSH) rjrYrroldgetcharhrhincrs rrrs .& ' - -d 3E8 YY   mmB b+ 2 BJJNN7A./A 6Aa%C 5#;/$67ABi JJ  \ * JJ    AJ   !12l"   !1E!H!Simply print unformatted text. This is the ultimate fallback.N)r rrrrrws rrrsJJU>$/01rchtj|rU|jtjvrd|jzSt |drd|jzSd|jzStj |rd|jzStj|r=d|jjd|jjd|jStj|r=d|jjd|jjd|jStj|rd |jzStj|rd |jzStj|rd |jzSt|jS) z/Produce a short description of the given thing.zbuilt-in module rzpackage zmodule zbuilt-in function zgetset descriptor rzmember descriptor rz function zmethod )rrcr)r rrr-isgetsetdescriptorr3rr4r r,r(rC)things rdescribersW >>S55 5%6 6 5* %. .u~~- -#enn44!!%(    ) )5+=+=+F+F NN !!%(    ) )5+=+=+F+F NN u%..((% U^^++5>>)) ;  rcR|jdDcgc]}|s| }}d\}}|t|kr;tdj|d|dz|}|r||dz}}nn|t|kr;|r|}nt}||dD]} t ||}|Scc}w#t $rYywxYw)z@Locate an object by name or dotted path, importing as necessary.rrNrT)rrWrrXr6rr8)r rpartrrn nextmodulerAs rlocaters"jjo 6odToE 6IFA c%j.t! 5yA :q1uqv c%j.ab  VT*F M 7  sBB B B&%B&ct|tr t||}|td|z||fSt |dd}|t|tr|fSdfS)zDGiven an object or a path to an object, get the object and its name.Nz~No Python documentation found for %r. Use help() to get the interactive help utility. Use help(str) for help on the str class.r))r.rDrrr)rrrAr#s rresolver)so%y) >,/445 5u}uj$/js3d====rc(|t}t||\}}t|}tj|}|rd|vr|d|d|j dzz }n|r||ur|d|j zz }tj|sstj|s^tj|sItj|s4t|s)t|dr |j}nt|}|dz }||zdz|j||zS)zBRender text documentation, given an object or a path to an object.Nrz in z in module __origin__z objectr)rjrrrrrfindr)rcr rdr2rIrrrCr()rrwrrendererrAr#rrs r render_docr!7s5),LFD F D   v &F t  .tzz#/// F&( //   V $oof%'&&v.fo 6< (&&F&\F I D 4<& 8#4#4VT#B BBrc | tt|||y t|||t}|j |y#t$r}|rt|Yd}~yd}~wwxYw#t$r}t |}Yd}~Od}~wwxYw)zCDisplay text documentation, given an object or a path to an object.N)rr!rprint plaintextrDr)rrwroutputis_clirrs rr=r=Rs|~  *UE95 6  5%I>A  Q  #JJ  CA s.AA$ A! AA!$ B- A==Bct||\}}tjt|tj ||}t |dzdd5}|j |dddtd|dzy#1swYxYw)z" 5 4s A>>Bcb|i}tj|g|D]\}}}t|y)zAWrite out HTML documentation for all modules in a directory tree.N)r walk_packagesr*)rpkgpathdonerr]rs r writedocsr/ks7 |BT$+$9$93%$I '5%J rcTeZdZiddddddddddd d d d d dddddddddddddddddddid d!d"d#d$d%dd&d#d'd(d)d*d+d,d-d.d/d0dd1dd2d3d4d5d6d7dd8d9d:dd;dDcgc]}d?D]}||z c}}}Zd@dAdBdCgedDdEdFdGdHdIdJZdKdLdMdNdOdPdQdRdSdTdUdVdVdWdWdXZejD]/\ZZ e D]%Z eje eZ ee vre dYzezZ e ee <'1[[ [ [ idZd[dRd\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdZdxdZidydzdOd{d|d}d~ddddd#ddddddddddddddddddddddidddddddddddddddddddSdddddkdddddddndddidddddddddLddddddd“ddēd+dœddƓdd ddɓdd˓dddd6dd#ddddddӜZ ddՄZ edքZedׄZd؄ZeZefdلZdڄZdۄZdd܄Zd݄ZddބZd߄ZdZdZddZddZdZddZ ycc}}}w)HelperFalserKNoneTrueandBOOLEANaswithassert)r9rKasync)r:rKawait)r;rKbreak)r< while forclass)r>zCLASSES SPECIALMETHODScontinue)r?r=def)functionrKdel)rB BASICMETHODSelififelse)rFr=excepttryfinallyfor)rJzbreak continue whilefromimportglobal)rMznonlocal NAMESPACES)rE TRUTHVALUE)rLMODULESin)rPSEQUENCEMETHODSis COMPARISONlambda)rTrnonlocal)rUzglobal NAMESPACESnotorpass)rXrKraise)rY EXCEPTIONSreturn)r[r)rHrZwhile)r\zbreak continue if TRUTHVALUE)r8z CONTEXTMANAGERS EXCEPTIONS yieldyield)r]rK)rfrhu'rraz'''rz""")+r***r9z//%<<>>rW|^~rXrY<=>===!=<>)rXrYrkrlrmrnro)rrj) z+=z-=z*=z/=z%=z&=z|=z^=z<<=z>>=z**=z//=)rfrgrWrhrirj)jJ)STRINGS OPERATORSrSUNARYAUGMENTEDASSIGNMENTBITWISECOMPLEXzOPERATORS FORMATTINGPOWERzTUPLES LISTS FUNCTIONSz ATTRIBUTES FLOAT MODULES OBJECTSELLIPSISzSLICINGS DICTIONARYLITERALSz def classrr PRIVATENAMESzPRIVATENAMES SPECIALMETHODS BACKQUOTESzTUPLES FUNCTIONS CALLSzLISTS SUBSCRIPTS SLICINGS)rerd,rro:@rfrr`rr[]r*TYPES)typeszRSTRINGS UNICODE NUMBERS SEQUENCES MAPPINGS FUNCTIONS CLASSES MODULES FILES inspect)stringsz4str UNICODE SEQUENCES STRINGMETHODS FORMATTING TYPES STRINGMETHODS)zstring-methodszSTRINGS FORMATTING FORMATTING) formatstringsrsUNICODE)rz:encodings unicode SEQUENCES STRINGMETHODS FORMATTING TYPESNUMBERS)numberszINTEGER FLOAT COMPLEX TYPESINTEGER)integersz int rangeFLOAT)floatingz float mathrw) imaginaryz complex cmath SEQUENCES)typesseqz$STRINGMETHODS FORMATTING range LISTSMAPPINGS DICTIONARIESr)typesfunctionsz def TYPESMETHODS) typesmethodszclass def CLASSES TYPES CODEOBJECTS)zbltin-code-objectszcompile FUNCTIONS TYPES TYPEOBJECTS)zbltin-type-objectsz types TYPES FRAMEOBJECTS TRACEBACKSNONE)zbltin-null-objectrK)zbltin-ellipsis-objectSLICINGSSPECIALATTRIBUTES) specialattrsrKr)rz!class SPECIALMETHODS PRIVATENAMESrO) typesmodulesrLPACKAGES EXPRESSIONS)zoperator-summaryzlambda or and not in is BOOLEAN COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES LISTS DICTIONARIESrs PRECEDENCEOBJECTS)objectsrSPECIALMETHODS) specialnameszbBASICMETHODS ATTRIBUTEMETHODS CALLABLEMETHODS SEQUENCEMETHODS MAPPINGMETHODS NUMBERMETHODS CLASSESrC) customizationzhash repr str SPECIALMETHODSATTRIBUTEMETHODS)zattribute-accesszATTRIBUTES SPECIALMETHODSCALLABLEMETHODS)zcallable-typeszCALLS SPECIALMETHODSrQ)sequence-typesz(SEQUENCES SEQUENCEMETHODS SPECIALMETHODSMAPPINGMETHODS)rzMAPPINGS SPECIALMETHODS NUMBERMETHODS)z numeric-typesz*NUMBERS AUGMENTEDASSIGNMENT SPECIALMETHODS EXECUTION) execmodelz%NAMESPACES DYNAMICFEATURES EXCEPTIONS NAMESPACES)namingz3global nonlocal ASSIGNMENT DELETION DYNAMICFEATURESDYNAMICFEATURES)zdynamic-featuresrKSCOPINGFRAMESrZ)r2ztry except finally raise CONVERSIONS) conversionsrK IDENTIFIERS) identifierszkeywords SPECIALIDENTIFIERSSPECIALIDENTIFIERS)z id-classesrK)zatom-identifiersrKLITERALS)z atom-literalsz=STRINGS NUMBERS TUPLELITERALS LISTLITERALS DICTIONARYLITERALSTUPLES TUPLELITERALS) exprlistszTUPLES LITERALSLISTS)ztypesseq-mutable LISTLITERALSr)listszLISTS LITERALS) typesmappingDICTIONARYLITERALSr)r5zDICTIONARIES LITERALS ATTRIBUTES)zattribute-referencesz(getattr hasattr setattr ATTRIBUTEMETHODS SUBSCRIPTS) subscriptionsrQr)slicingsrQCALLS)callsr)powerrrt)unaryrBINARY)binaryrSHIFTING)shiftingrrv)bitwiser) comparisonszEXPRESSIONS BASICMETHODS)booleanszEXPRESSIONS TRUTHVALUE ASSERTION ASSIGNMENT) assignmentruru) augassignrDELETION RETURNING IMPORTING)compoundzfor while break continue)truthz if while and or not BASICMETHODS)debuggerpdb)zcontext-managersr8) CONDITIONALLOOPINGrN DEBUGGINGCONTEXTMANAGERSNc ||_||_yrB)_input_output)r:inputr%s rrzHelper.__init__"s  rc>|jxstjSrB)rr rrTs rrz Helper.input&s{{'cii'rc>|jxstjSrB)rr rrTs rr%z Helper.output*s||)szz)rctjdddk(r|yd|jjd|jjdS)NrTrn?rKrXrz instance>)rstackr+rrrTs r__repr__zHelper.__repr__.sO ==?1 a C ' F (&*^^%>%>%)^^%@%@B Brc$||jur |j|y|j |j |jj dy#t$r(}|jj |dYd}~yd}~wwxYw)NrSa You are now leaving help and returning to the Python interpreter. If you want to ask for help on a particular object directly from the interpreter, you can type "help(object)". Executing "help('string')" has the same effect as typing a particular string at the help> prompt. )_GoInteractiverrr%rintrointeract)r:requestrs r__call__zHelper.__call__6sy $-- - . '" JJL MMO KK     . !!SE*-- .sA B'B  Bc|jjd |jd}|sy |j }t |dkDr"|d|dcxk(rdvrnn|d|ddvr|dd}|jdvry|d k(r|jn|j|#ttf$rYywxYw) NrSzhelp> rUrrr`rT)rquitr) r%rgetlinerEOFErrorrVrWr>rr)r:rs rrzHelper.interactFs $ ,,x0wmmoGG q WQZ72;%L*%L '!B-7!!B-}}-/&   '"#&x0  sB..C?Cc|jtjur t|S|jj ||jj |jj S)z.Read one line, using input() when appropriate.)rr rr%rr r)r:prompts rrzHelper.getline[sQ :: "= KK  f % KK   ::&&( (rcnt|trX|j}|dk(r|jnb|dk(r|j nK|dk(r|j n4|dk(r|j n|dddk(r#|j |jdn||jvr|j|n|dvr#tt|d |j| n||jvr|j|n||jvr|j|nk|rt|d |j| nOttd |j| n1t|t r|nt|d |j| |j"j%d y) Nkeywordssymbolstopicsrzmodules rT)r4r2r3z Help on %s:)r%r&rS)r.rDrV listkeywords listsymbols listtopics listmodulesrr showsymbolr=evalrr showtopicrr1r%r)r:rr&s rrz Helper.helpdsE gs #mmoG*$d&7&7&9I%t'7'7'9H$doo&7I%t'7'7'9! *  !34DLL($//'*B55DM=fUDMM)4>>'+BDKK')@#g}T\\RXYc=fM  ($&'=fM $rc|jjdjdtjddzy)NaWelcome to Python {0}'s help utility! If this is your first time using Python, you should definitely check out the tutorial at https://docs.python.org/{0}/tutorial/. Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To get a list of available modules, keywords, symbols, or topics, enter "modules", "keywords", "symbols", or "topics". Each module also comes with a one-line summary of what it does; to list the modules whose name or summary contain a given string such as "spam", enter "modules spam". To quit this help utility and return to the interpreter, enter "q" or "quit". z%d.%drU)r%rr=r rCrTs rrz Helper.introys7   F7S%%bq) )*! ,rc tt|}||z}t||zdz |z}t|D]}t|D]s}||z|z}|t|ks|jj ||||dz ksA|jj dd|dz t||z zzu|jj dy)NrTr*rS)rrrWrr%r) r:itemscolumnsrcolwrrowrrs rrz Helper.listsVE]#E W$q(W4;CW~$J$s5z>KK%%eAh/Wq[( ))#tax#eAh-7O0P*PQ & KK  d #rc|jjd|j|jj y)NzN Here is a list of the Python keywords. Enter any keyword to get more help. )r%rrrrrTs rrzHelper.listkeywordss4   $--$$&'rc|jjd|j|jj y)Nzx Here is a list of the punctuation symbols which Python assigns special meaning to. Enter any symbol to get more help. )r%rrrrrTs rrzHelper.listsymbolss4   $,,##%&rc|jjd|j|jj y)NzN Here is a list of available topics. Enter any topic name to get more help. )r%rrrrrTs rrzHelper.listtopicss4   $++""$%rc^ ddl}|jj ||j j |}|s(|jjdt|zyt|tr|j||S|\}} |jj|}|jdz}|r |xsddz|z}|rRddl }ddj|jzdz} |j!| d } |d dj| zz }|j" t%|y|jj|y#t$r|jjdYywxYw#t$r*|jjdt|zYywxYw) Nrt Sorry, topic and keyword documentation is not available because the module "pydoc_data.topics" could not be found. zno documentation found for %s rSrKr*Related help topics: rHz %s )pydoc_data.topicsrr%rrrrr+r.rDrKeyErrorrVtextwraprXrwraprr) r:topic more_xrefs pydoc_datatargetlabelxrefsr=rrj wrapped_texts rrzHelper.showtopics  $ (9(9%(@A KK  ?$u+M N  fc ">>&*5 5 u ##**51CiikD  [bC'*4E  *TYYu{{}-EELD#==r2L 8dii 55 5C <<  #J KK  c "?  KK         KK  ?$u+M N  s#E E9$E65E690F,+F,cR ddl}|jj||jj|}|s t dt |tr|j||S|\}}|jj|}|r |xsddz|z}||fS#t$rYywxYw)a*Return unbuffered tuple of (topic, xrefs). If an error occurs here, the exception is caught and displayed by the url handler. This function duplicates the showtopic method but returns its result directly so it can be formatted for display in an html page. rN)r rKzcould not find topicrKr*) rrrrrr8r.rD _gettopic)r:rrrrrrr=s rrzHelper._gettopics $  (9(9%(@A34 4 fc ">>&*5 5 u&&u- [bC'*4EEz   sB B&%B&cp|j|}|jd\}}}|j||y)Nr*)r partitionr)r:symbolrrrrs rrzHelper.showsymbols4f% **3/q% ue$rcn|r6|jjdj|t|y|jjdi}|fdfd}t j ||j |j|jjdy)Nzy Here is a list of modules whose name or summary contains '{}'. If there are any, enter a module name to get more help. zI Please wait a moment while I gather a list of all available modules... c\|r|dddk(r|dddz}|jddkrd||<yy)N .__init__rrrrT)find)r r]rrs rcallbackz$Helper.listmodules..callback sBwrs|{:%crl\9G<<$q('(GG$)rcd|dyrBr)r]r$s ronerrorz#Helper.listmodules..onerror sw-rr&z Enter any module name to get more help. Or, type "modules spam" to search for modules whose name or summary contain the string "spam". )r%rr=apropos ModuleScannerrunrr)r:rrr&r$s @rrzHelper.listmoduless  KK   F3K   CL KK   G6= )  . O  '  : IIglln % KK   rr)F)rPrg)!r)rrr _strprefixes_symbols_inverserrrsymbols_rrrrr/rr%rrArrrrrrrrrrrrrr)rcprs000rr1r1rse$$$ $ y $ f $ . $ $ $ '$ 4$ -$ $ &$ $ %$ %!$" 5#$$ .%$& '$( 3)$* "+$, '-$. '/$0 l1$2 )3$4 55$6 y7$8 i9$:  ;$< (=$> )?$@ $A$B :C$D !U" H#U$ <%U& 'U( g)U* )+U, 9-U. 1/U0 A1U2 -3U4 H5U6 .7U> ]?U@ mAUB 'CUD 4EUJ IKUL MMUN EOUP /QUT GUUV ,WUZ K[U\ W]U^ 3_U` {U| ?}U~ ZU@ :AUB 3CUD )EUF )GUH )IUJ +KUL /MUN -OUP AQUR 9SUT XUUV ;WUX =YUZ E[U\ X]U^ X_U`;C(7iUFn((**BXN- #*) *,& $('&"#H6% [ Ms9H#r1ceZdZdZddZy)r)z7An interruptible scanner that searches module synopses.Nc|r|j}d|_i}tjD]|}|dk7s d||<| |d|dt |j xsd}|j dd}|dz|z}|jj|dk\ss|d||~tj|D]0\} }} |jrn| |d|d$ | j|} | j} t| d rU | j|} t!t#j$| xsd}t| d r| j'|}n[d}nX t(j*j-| }|j r|j j1dnd}t3|d d}|dz|z}|jj|dk\s'||||3|r|yy#t$rYKwxYw#t$r|r||YewxYw#t.$r|r||YwxYw) NF__main__rTrKrSrrr' get_source get_filenamer)r>rr r __import__r@rr#rr, find_specrrrr3rrrStringIOr4rrrrrr)r:r$r completerr&seenr]r#rrrrrsourcer rs rr*zModuleScanner.run s= ciik //G*$ !W ;T7B/%g.66<"D::d+A.D"U?T1Dzz|((-2 w50)0(=(=g(N(N $Hguyy{w+#--g6D6<0!!'!2!27!; +2;;v+>?E2Dv~6%227;#!!*!5!5!;!;D!A >D^^6>>446q9QSD"6*T:D-::<$$S)Q.T7D1I)OL  K ;#%!"#G, !'!"#G, !s6&HH%H* H  H H'&H'*IIri)r)rrr@r*rrrr)r) s A8rr)cd}d}tj5tjdtj |||dddy#1swYyxYw)zAPrint all the one-line module summaries that contain a substring.cJ|dddk(r|dddz}t||xrd|zyNr!r"rz- )r#)r r]rs rr$zapropos..callbackP s3 23<; &crl\1G gt+t ,rcyrBrr]s rr&zapropos..onerrorT s rrr'N)rrfilterwarningsr)r*)rr$r&s rr(r(N sI-  ")Hc7; # " "s 2AAc ddlddlddl ddl Gddjj G fddjj G fdd j}||||}|j|jsS|jr |js;tjd |js|js.|js;|S) aAStart an HTTP server thread on a specific port. Start an HTML/text server thread, so HTML or text documents can be browsed dynamically and interactively with a web browser. Example use: >>> import time >>> import pydoc Define a URL handler. To determine what the client is asking for, check the URL and content_type. Then get or generate some text or HTML code and return it. >>> def my_url_handler(url, content_type): ... text = 'the URL sent was: (%s, %s)' % (url, content_type) ... return text Start server thread on port 0. If you use port 0, the server will pick a random port number. You can then use serverthread.port to get the port number. >>> port = 0 >>> serverthread = pydoc._start_server(my_url_handler, port) Check that the server is really started. If it is, open browser and get first page. Use serverthread.url as the starting page. >>> if serverthread.serving: ... import webbrowser The next two lines are commented out so a browser doesn't open if doctest is run on this module. #... webbrowser.open(serverthread.url) #True Let the server do its thing. We just need to monitor its status. Use time.sleep so the loop doesn't hog the CPU. >>> starttime = time.monotonic() >>> timeout = 1 #seconds This is a short timeout for testing purposes. >>> while serverthread.serving: ... time.sleep(.01) ... if serverthread.serving and time.monotonic() - starttime > timeout: ... serverthread.stop() ... break Print any errors that may have occurred. >>> print(serverthread.error) None rNceZdZdZdZy)!_start_server..DocHandlerc8|jjdrd}nd}|jd|jdd|z|j |j j |j|j|jdy) zProcess a request from an HTML browser. The URL received is in self.path. Get an HTML page from self.urlhandler and send it. z.csstext/css text/htmlz Content-Typez%s; charset=UTF-8rN) r r send_response send_header end_headerswfiler urlhandlerr)r: content_types rdo_GETz(_start_server..DocHandler.do_GET s yy!!&)) *   s #   ^-@<-O P     JJ  T__ <))/ :rcyrBr)r:r's r log_messagez-_start_server..DocHandler.log_message s rN)r)rrrNrPrrr DocHandlerrC s  :  rrQc$eZdZdZfdZdZy) _start_server..DocServerc||_|j|f|_||_|jj ||j|j d|_yNF)hostaddressr$r<rhandlerr)r:rVportr$s rrz)_start_server..DocServer.__init__ sEDI IIt,DL$DM II  tT\\4<< @DIrc|jsPj|jjgggd\}}}|r|j |jsP|j yr})rselectsocketrhandle_request server_close)r:rdwrexr[s rserve_until_quitz1_start_server..DocServer.serve_until_quit sZii#]]DKK,>,>,@+A2r1M B'')ii    rcv|jj||jr|j|yyrB)r<server_activater$rTs rrdz0_start_server..DocServer.server_activate s, II % %d +}} d#rN)r)rrrrbrd)r[sr DocServerrS s   $rrec4eZdZfdZfdZdZdZy)#_start_server..ServerThreadc||_||_t||_jj |d|_d|_d|_yrU) rLrVrrYThreadrservingerror docserver)r:rLrVrY threadings rrz,_start_server..ServerThread.__init__ sE(DODID DI    % %d + DLDJ!DNrcn jj__jj _t|j_|j|j|j}||_ |jy#t$r}||_Yd}~yd}~wwxYw)zStart the server.N)server HTTPServerr<rXr,Message MessageClass staticmethodrLrVrYreadyrlrbrrk)r:docsvrrrQreemailhttps rr*z'_start_server..ServerThread.run s !!%!7!7 $. !*/--*?*? '(4T__(E %"499diiD!''') !   !sBB B4#B//B4cd|_|j|_|j|_d|j|jfz|_y)NTz http://%s:%d/)rjrV server_portrYr)r:ros rrtz)_start_server..ServerThread.ready s:DL DI**DI&$))TYY)??DHrcpd|j_|jd|_d|_d|_y)z&Stop the server and this thread nicelyTNF)rlrrXrjrrTs rstopz(_start_server..ServerThread.stop s."&DNN  IIK"DN DLDHrN)r)rrrr*rtr{)rQrervrwrmsr ServerThreadrg s " ! @  rr|g{Gz?) http.server email.messager[rmroBaseHTTPRequestHandlerrprirrkrjrltimesleep) rLhostnamerYr|threadrQrervrwr[rms @@@@@@r _start_serverr\ spT[[77,$DKK**$*&&y''&P*h 5F LLNllFNNv7G7G 3llFNNv7G7G Mrc^ G fddt}|fd fd fd fdfd fdfd  fd  fd }|jd r|d d}|dk(rtjj tjj t }tjj||}t|5}dj|jcdddS|dk(r||Std|d|#1swYxYw)aThe pydoc url handler for use with the pydoc server. If the content_type is 'text/css', the _pydoc.css style sheet is read and returned if it exits. If the content_type is 'text/html', then the result of get_html_page(url) is returned. ceZdZfdZy)_url_handler.._HTMLDocc :d}d|z}d|d|dd|d S)rvzpydoc_data/_pydoc.cssz1zH Pydoc: z z z*
z
r)r:rwrxcss_pathcss_link html_navbars rryz#_url_handler.._HTMLDoc.page s/.HC HkmX? ?rN)r)rrry)rsr_HTMLDocr s ?rrcjtjdtjddtjd}d|djtjdd S) Nz [rrrz=
Python 
T)tersea
)r[rpython_version python_buildpython_compiler)rr)s rrz!_url_handler..html_navbar sg++x/F/F/H/7/D/D/Fq/I/7/G/G/IKL0DKK(9(9(EF+H Hrcd}jd}tjDcgc] }|dk7r| }}j||}|dj dd|zg}i}tj D]#}|j j||%|j ddd j|fScc}w) zModule Index page.cd|d|dSNrrrrr#s r bltinlinkz3_url_handler..html_index..bltinlink0 15t< Index of Modules
r2z

zBuilt-in Modulesrzf

pydoc by Ka-Ping Yee<ping@lfw.org>

zIndex of ModulesrK) r}r rrrr rrrX)rr}r#namesrxr9rr)s r html_indexz _url_handler..html_index- s =,, = #&":":(":$J&":(##E95UT__ &33488C OODJJsD1 2  ' ("2778#444(sB>c g fd}tj5tjdd}tj |||dddd}g} j d} D]\}}|j |||z!| jd|zd d j|z}d |fS#1swYoxYw) zSearch results page.cZ|dddk(r|dddz}j||xrd|zfyr=r)r r]r search_results rr$z3_url_handler..html_search..callbackJ s=rs|{*!#2,5  '4+?D4K!@ ArrcyrBrr?s rr&z2_url_handler..html_search..onerrorQ srr'Ncd|d|dSrrrs rrz4_url_handler..html_search..bltinlinkV rrz-Search Resultszkey = %srrzSearch Results) rrr@r)r*r}rrrX) rr$r&rrr}r#rrxrr)s @r html_searchz!_url_handler..html_searchE s  B  $ $ &  # #H -  O  #w  ? ' =,, ; (JD$ NN9T?T1 2(T__  gv{{7';==))%' &s 5CC cd}jd}ttjj }j ||}|j dd|z}d|fS)zIndex of topic texts available.cd|d|dSNzINDEXTopicsr)r}rr1rrrr)rr}rrxr)s r html_topicsz!_url_handler..html_topicsc sn B,, 2 v}}))+,##E95T__ gx))!!rcjd}ttjj }d}j ||}|j dd|z}d|fS)zIndex of keywords.rcd|d|dSrrrs rrz6_url_handler..html_keywords..bltinlinkz rrKeywordsr)r}rr1rrrr)r}rrrxr)s r html_keywordsz#_url_handler..html_keywordss sn,, 2 v++-. B##E95T__ ++8##rctj}t||}|j|\}}||jvrd}nd}j d|z}dj |z}j|d|}|rAt|j}d}j||}jdd|}|d|d j|||ffS) zTopic or keyword help page.KEYWORDTOPICrz
%s
rcd|d|dSrrrs rrz7_url_handler..html_topicpage..bltinlink s :>EErr r*rK) rr7r1rrr}rrrrrrrX) rbufhtmlhelprxrrwr}rr)s rhtml_topicpagez$_url_handler..html_topicpage skkm#s#",,U3% H%% %EE,, /% 7 #T[[%::??57H= 5;;=)E F$$UI6ELL!8'5IE %((E235 5rct|d}||dk7r tdt|}j||}||fS)NrT)rr3zcould not find object)rr8rr()rr9rwcontentr)s r html_getobjz!_url_handler..html_getobj sISA& ;3&=45 5 --S)g~rcjd}djfdtt||D}|j |d|z}d|z|fS)Nz$Errorrc3@K|]}j|ywrB)r[)rcryr)s rrez3_url_handler..html_error.. s#FD6:t{{40Dsrkz Error - %s)r}rXrrCr)rrr}rxr)s r html_errorz _url_handler..html_error sf,, 2 ;;F4T#YDFFT__S'8DDc!8++rcJ|}|jdr|dd} |dvr  \}}n|dk(r \}}n|dk(r  \}}nsd|vrd|jd\}}}|dk(r  |\}}nI|d k(r  |\}}n7|d k(r|dvr  \}}n#  |\}}ntd  |\}}j ||S#t$r |\}}Y(wxYw#t$r |\}}YBwxYw#t$r}||\}}Yd}~`d}~wwxYw) zGenerate an HTML page for url.r:N)rKrrrrBz search?keyz topic?keyzget?keyz bad pydoc url)rrr8rry)r complete_urlrwroprrr)rrrrrrrs r get_html_pagez#_url_handler..get_html_page sf << cr(C ;m#!+w!,w "!.w ]]3/ As%%0%5NE7;&:)7)<w9_m+)3wA-8-=NE7%_55!,S!1wyy((%&:)4S)9w: *A-;C-@NE7A  ;' c:NE7 ;s`AD: CD C)&DC&#D%C&&D)D=D?DD D" DD"r9rTNrErKrFzunknown content type z for url ) rtrr r dirnamerealpathrrXr readlinesrG)rrMrr path_hererfpr)rrrrrrrrs @@@@@@@@@r _url_handlerr s?7?$ :DH650*<" $52,&)&)P ~~c!"gz!GGOOBGG$4$4X$>? 77<< 3/ (^r772<<>*^  $S!! L#N OO ^s D##D,T localhost) open_browserrcddl}tt||}|jrt |jy|j rd}|r|j |j t d|jt ||j rZtd}|j}|dk(rn9|dk(r|j |jn t ||j rZ|j r|jt dyyy#ttf$r t YEwxYw#|j r|jt dwwxYw) zStart the enhanced pydoc web server and open a web browser. Use port '0' to start the server on an arbitrary port. Set open_browser to False to suppress opening a browser. rNz"Server commands: [b]rowser, [q]uitzServer ready atzserver> rrzServer stopped) webbrowserrrrkr#rjrrrr>rrr{)rYrrr serverthreadserver_help_msgrs rbrowser s/  x>L l  !>  OOL,, - ( #\%5%5 6 / "&&J'iik#:CZOOL$4$45/*&&##!!#&'$' "8,  G ##!!#&'$s%$BDD1.D40D11D44*Ecjt|txr"|jtjdk\Sr)r.rDr#r sep)rs rispathr s% a  5!&&.A"55rcd|vs(tj|vstj|vrytjj t }tjj |}|j }||vr1tjj||s|j||jdtj|S)zEnsures current directory is on returned path, and argv0 directory is not Exception: argv0 dir is left alone if it's also pydoc's directory. Returns a new path entry list, or None if no adjustment is needed. rKNr) r curdirgetcwdr rrcopysamefileremoveinsert) given_pathargv0 stdlib_dir script_dir revised_paths r_get_revised_pathr s Z299 2biikZ6O*J'J??$LZ(8(8Z(PJ'299;' rcttjtjd}||tjddyy)zEnsures current directory is on sys.path, and __main__ directory is not. Exception: __main__ dir is left alone if it's also pydoc's directory. rN)rr r argv)rs r_adjust_cli_sys_pathr% s4 %SXXsxx{;L"  rcddl}Gddt}t |jtjddd\}}d}d}d}d}d}|D]:\} } | d k(rd }d }| d k(r t | y| d k(rd }| }| d k(rd }| dk(s7d }| }<|rt |||y|s||D]} t| rBtjj| s#td| ztjd t| r*tjj| r t| } |rBt| r+tjj| r t!| n#t#| nt$j%| d y#t&t(f$r+} t| tjdYd} ~ d} ~ wwxYw#|j*|f$r}tjj-tjj/tjdd} tdj1| tj2YywxYw)z@Command-line interface (looks at sys.argv to decide what to do).rNc eZdZy)cli..BadUsageN)r)rrrrrBadUsager2 srrrTzbk:n:p:wFrz-bTz-kz-pz-wz-n)rrzfile %r does not exist)r&apydoc - the Python documentation tool {cmd} ... Show text documentation on something. may be the name of a Python keyword, topic, function, module, or package, or a dotted reference to a class or function within a module or module in a package. If contains a '{sep}', it is used as the path to a Python source file to document. If name is 'keywords', 'topics', or 'modules', a listing of these things is displayed. {cmd} -k Search for a keyword in the synopsis lines of all available modules. {cmd} -n Start an HTTP server with the given hostname (default: localhost). {cmd} -p Start an HTTP server on the given port on the local machine. Port number 0 can be used to get an arbitrary unused port. {cmd} -b Start an HTTP server on an arbitrary unused port and open a web browser to interactively browse documentation. This option can be used in combination with -n and/or -p. {cmd} -w ... Write out the HTML documentation for a module to a file in the current directory. If contains a '{sep}', it is treated as a filename; if it names a directory, documentation is written for all the contents. )rr)getoptrrr rr(rrr r existsr#exitrrrr/r*rrrrkrr r=r)rroptsr'writing start_serverrrYroptvalargrrs rclir/ s#9#M!]]388AB<< d  HCd{# # d{ d{# d{d{#   4( F 8^Cc{277>>##6.45  #;277>>##6$S/Cc{rww}}S'9!#  IIc$I/ !23 e    LL( #!ggrww// <=a@ : FsF; !!sQAG2GGAG6BF G G F>8G>GGB IIr2r)r) Python Library Documentation: %srN)rrNF)rKN)rF)dr@rrrrrrr6importlib._bootstraprimportlib._bootstrap_externalimportlib.machineryimportlib.utilrrr rrrMr rErr urllib.parserr collectionsrreprlibr tracebackrrr$r>r7rIrQrZr^rarhrlrtr IGNORECASErvrxr{rrrall_feature_namesrrrrrrrrrrrrrHrtrlrrrrrrrrrrrrrrjr$r)rr!r=r*r/r1rr)r(rrrrrrrr)rrrrsc%L ( )   $   + 1f ! A   %G bjj5r}}E ( "J889(0  2 %NK K&+$ !(X66t(t(TW 7cW 7v:t:@XcXt G "H#0 /F *2X2 6*y O y >KLC6DE!"# [[z x;;z <VriPX (4+ (J68#T!l zEr__pycache__/pprint.cpython-312.opt-2.pyc000064400000065143152342670510013751 0ustar00 ֦i^^ ddlZddlZddlZddlZddlZddl m Z gdZ ddddddZ ddddddZdd d Zd Zd Zd ZGddZdZGddZeeeeeeeedhZdZdZ y)N)StringIO)pprintpformat isreadable isrecursivesaferepr PrettyPrinterppFTcompact sort_dictsunderscore_numbersc L t|||||||}|j|y)N)streamindentwidthdepthr r r)r r) objectrrrrr r rprinters /usr/lib64/python3.12/pprint.pyrr0s.KfEJ-/G NN6cD t||||||j|S)N)rrrr r r)r r)rrrrr r rs rrr9s+F e5!(Z,> @@GPr)r c( t|g|d|i|y)Nr )r)rr argskwargss rr r @s& 6:D:Z:6:rcB tj|idddSNrr _safe_reprrs rrrDs#G ? % %fb$ :1 ==rcB tj|idddSNrrr s rrrHs#> ? % %fb$ :1 ==rcB tj|idddSNrrr s rrrLs#B ? % %fb$ :1 ==rc eZdZ dgZdZdZy) _safe_keyobjc||_yN)r))selfr)s r__init__z_safe_key.__init__\s rc" |j|jkS#t$rjtt|jt |jftt|jt |jfkcYSwxYwr+)r) TypeErrorstrtypeid)r,others r__lt__z_safe_key.__lt___sm ;88eii' ' ;dhh("TXX,7eii)2eii=9: ; ;sA0B BN)__name__ __module__ __qualname__ __slots__r-r4rrr(r(PsI;rr(c< t|dt|dfSr")r()ts r _safe_tupler<fs , QqT?IadO ++rceZdZd#dddddZdZdZdZd Zd Zd Z iZ d Z e e e j<d Zee ej j<dZee ej<dZee ej<dZee ej<ee ej<dZee ej<dZee ej<dZee ej<dZee ej@j<dZ!e!e ejDj<dZ#dZ$dZ%dZ&dZ'dZ(e(e ejRj<dZ*e*e ejVj<dZ,e,e ejZj<dZ.e.e ej^j<dZ0e0e ejbj<d Z2e2e ejfj<d!Z4e4e ejjj<d"Z6y)$r NFTr c4 t|}t|}|dkr td||dkr td|s td||_||_||_|||_nt j|_t||_ ||_ ||_ y)Nrzindent must be >= 0zdepth must be > 0zwidth must be != 0) int ValueError_depth_indent_per_level_width_stream_sysstdoutbool_compact _sort_dicts_underscore_numbers)r,rrrrr r rs rr-zPrettyPrinter.__init__ks 4VE  A:23 3  !01 112 2 !'  !DL;;DLW  %#5 rc|j<|j||jddid|jjdyy)Nr )rD_formatwriter,rs rrzPrettyPrinter.pprints= << # LLq!R ; LL  t $ $rcbt}|j||ddid|jSr) _StringIOrMgetvalue)r,rsios rrzPrettyPrinter.pformats+k VS!QA.||~rc0|j|idddSr%formatrOs rrzPrettyPrinter.isrecursives{{62q!,Q//rc@|j|idd\}}}|xr| SrrU)r,rsreadable recursives rrzPrettyPrinter.isreadables*!%VRA!>8Y) M)rc t|}||vr)|jt|d|_d|_y|j |||}|j |z |z } t|| kDr|jjt|jd} | d||<| |||||||dz||=ytj|rt|tsp|jj rZt#|jdrDd|jj$j&vr"d||<|j)||||||dz||=y|j|y)NTFr# __wrapped__ __create_fn__)r2rN _recursion _recursive _readable_reprrClen _dispatchgetr1__repr__ _dataclasses is_dataclass isinstance__dataclass_params__reprhasattrr\r7_pprint_dataclass) r,rrr allowancecontextlevelobjidrep max_widthps rrMzPrettyPrinter._formatsA6  G  LLF+ ,"DO"DN jj%0KK&(94 s8i ""4<#8#8$?A}!"$ 7EAINEN++F3 .--22&//=9!V__%@%@%M%MM!"&&vvvy'SX[\S\]EN Srcp|jj}|t|dzz }tj|Dcgc]1}|j s|j t||j f3} }|j|dz|j| ||||||jdycc}w)Nr#()) __class__r5rbrffieldsrjnamegetattrrN_format_namespace_items) r,rrrrmrnrocls_namefitemss rrlzPrettyPrinter._pprint_dataclasss##,,#h-!## c rc|jd|j|j||dz|dz|||jdy)Nz mappingproxy( r#rv)rNrMcopyrs r_pprint_mappingproxyz"PrettyPrinter._pprint_mappingproxyesA _% V[[]FFRKQe % Src8t|tjurd}n|jj}|t |dzz }|j j}|j|dz|j|||||||jdy)N namespacer#rurv) r1_typesSimpleNamespacerwr5rb__dict__r~rNr{) r,rrrrmrnror|r~s r_pprint_simplenamespacez%PrettyPrinter._pprint_simplenamespacems <611 1#H''00H#h-!##%%' X^$ $$UFFIwPUV Src J|j}||jz }dd|zz}t|dz } t|D]d\} \} } | | k(} |j | ||}|||d|j | ||t|zdz| r|nd||| r]||fy)N, rr#: r&)rNrBrbrrarM)r,r~rrrmrnrorNdelimnl last_indexrrentlastrqs rrz PrettyPrinter._format_dict_items|s $(((#,&Z!^ &u-MAzS ?D**S'51C #J $K LLffs3x&7!&;&* % )g.rc 2|j}dd|zz}t|dz } t|D]g\} \} } | | k(} || |dt| |vr |dn)|j | ||t| zdz| r|nd||| r`||iy)Nrrr#=...)rNrbrr2rM)r,r~rrrmrnrorNrrrrrrs rr{z%PrettyPrinter._format_namespace_itemss #,&Z!^ &u-MAzS ?D #J #J#w'!e  S&&3s8*;a*?*.YA$e-g.rcd|j}||jz }|jdkDr||jdz dzdd|zz}d} |j|z dzx} } t|} t | } d}|s| } t | } |j rI|j|||}t|dz}| |kr| } | r|} | |k\r| |z} || d} ||e|| |} |j||||r|nd|||syy#t $rYywxYw#t $rd}| |z} | |z} YwxYw) Nr#rrrFTr&, ) rNrBrCiternext StopIterationrHrarbrM)r,r~rrrmrnrorNrrrrritnext_entrrrqws rrzPrettyPrinter._format_itemssn $(((  ! !A % 4))A-4 5#,& KK&0144 %[ BxHC #8 }}jjgu5HqL19%E 'A:QJE%L E#J %LE LLff&* % )/   ! #Y& " #s$- D? D DDD/.D/c|j||j|j|\}}}|sd|_|rd|_|S)NFT)rVrrAr`r_)r,rrnrorjrYrZs rrazPrettyPrinter._reprsD$(KK 04 U%D!h "DN "DO rc, |j||||Sr+)r)r,rrn maxlevelsros rrVzPrettyPrinter.formats vw 5AArcxt|s|jt|y|j|j||}|j }|t|j dzz }|j|j d|dd|z|j||||dz|||jdy)Nr#rurrrv)rbrNrjradefault_factoryrwr5r) r,rrrrmrnrordfrs r_pprint_default_dictz"PrettyPrinter._pprint_default_dicts6{ LLf & jj//%@#cll#a'' S\\3f EF &&&)a-%P Srct|s|jt|y|j}|j|jdz|j dkDr!|j|j dz dz|j }|j|||t|jzdz|dz|||jdy)Nrr#rr&r)rbrNrjrwr5rB most_commonr) r,rrrrmrnrorr~s r_pprint_counterzPrettyPrinter._pprint_counters6{ LLf &  S\\D()  ! !A % LL$0014; <""$ v &S\\): :Q > A ' 0  Trc t|js|jt|y|j}|j|j dz|t|j dzz }t |jD]x\}} |t|jdz k(r+|j| |||dz|||jdL|j| ||d|||jdd|zzzy)Nrur#rvrr)rbmapsrNrjrwr5rrM) r,rrrrmrnrorrms r_pprint_chain_mapzPrettyPrinter._pprint_chain_maps6;; LLf &  S\\C'(#cll#a''fkk*DAqC $q(( Q A wN S! Q7EB US6\12 +rct|s|jt|y|j}|j|jdz|t|jdzz }|jd|j +|j ||||dz|||jdy|j |||d|||j|j ||}|jdd|zd|d y) Nrur#rr&z])z], rzmaxlen=rv)rbrNrjrwr5maxlenrra) r,rrrrmrnrorrmls r _pprint_dequezPrettyPrinter._pprint_deques6{ LLf &  S\\C'(#cll#a'' S ==   vvvy1}& / LL    vvvq& /**V]]GU;C LLsV|SA Brc J|j|j|||||dz yNr#rMdatars r_pprint_user_dictzPrettyPrinter._pprint_user_dict  V[[&&)WeaiPrc J|j|j|||||dz yrrrs r_pprint_user_listzPrettyPrinter._pprint_user_list rrc J|j|j|||||dz yrrrs r_pprint_user_stringz!PrettyPrinter._pprint_user_string%rrcjt|}|tvrt|ddfSt|dd}t |t r3|t j ur!|jr|dddfSt|ddfSt |tr |tj ur|syt|}|r ||k\rdd||vfS||vrt|ddfSd||<d}d} g} | j} |dz }|jr t|jt} n|j} | D]S\} }|j!| |||\}}}|j!||||\}}}| |d ||xr|xr|}|s|sRd} U||=d d j#| z|| fSt |t$r|t$j us"t |t&r|t&j urt |t$r|sy d }nt)|dk(rd}n|syd}t|}|r||k\r |dzd||vfS||vrt|ddfSd||<d}d} g} | j} |dz }|D]+}|j!||||\}}}| ||sd}|s*d} -||=|d j#| z|| fSt|}||xr|j+d dfS)NTFre_d)z{}TFz{...}r#rrz{%s}r)z[]TFz[%s]z(%s,))z()TFz(%s)r<)r1_builtin_scalarsrjrz issubclassr?rerJdictr2r^rrIrr~r<rVjoinrtuplerb startswith)r,rrnrrorrrprYrZ componentsrr~kvkrepr kreadablekrecurvrepr vreadablevrecurrVoorepr oreadableorecurrqs rrzPrettyPrinter._safe_repr*s6l " "<u, , CT * c3 A$5'' tU22F|T500 c4 Q$--%7(vJEUi/u'777!&)5$66GENHIJ&&F QJEv||~;? 1+/;;w 5,2(y&+/;;w 5,2(y&5%01#? ?iV $IDIIj118YF F sD !a4==&8 sE "qENN':#t$,V! ,vJEUi/~uew.>>>!&)5$66GENHIJ&&F QJE+/;;w 5,2(y&u  $H $IDIIj118YF F6lS4!44u<)r1r5r2r s rr^r^~sF|$$bj 23rc# Kd}t|dzdz}tdt|dD]D}|||dz}||z}||k(r||z}tt||kDr|r t||}C|}F|rt|yyw)Nrrr)rbrangerj)rrrmrrrrrs rrrsG v;! a D 1c&k1 %a1~dN 9 Y E tI % '7m#GG&7msBB)Nr#r N)r#r N)! collectionsr  dataclassesrfrsysrEtypesriorrQ__all__rrr rrrr(r<r r r0rr floatcomplexrGr1rr^rr9rrr"s4#" $ "TePduP"';>>>;;,,O=O=bc5)UG"DJ013 r__pycache__/__future__.cpython-312.pyc000064400000011142152342670510013571 0ustar00 ֦ib dZgdZdgezZdZdZdZdZdZdZd Z d Z d Z d Z Gd dZ e ddeZe ddeZe ddeZe ddeZe ddeZe ddeZe dde Ze dde Ze dde Ze dde Zy)aRecord of phased-in incompatible language changes. Each line is of the form: FeatureName = "_Feature(" OptionalRelease "," MandatoryRelease "," CompilerFlag ")" where, normally, OptionalRelease < MandatoryRelease, and both are 5-tuples of the same form as sys.version_info: (PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int PY_MINOR_VERSION, # the 1; an int PY_MICRO_VERSION, # the 0; an int PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string PY_RELEASE_SERIAL # the 3; an int ) OptionalRelease records the first release in which from __future__ import FeatureName was accepted. In the case of MandatoryReleases that have not yet occurred, MandatoryRelease predicts the release in which the feature will become part of the language. Else MandatoryRelease records when the feature became part of the language; in releases at or after that, modules no longer need from __future__ import FeatureName to use the feature in question, but may continue to use such imports. MandatoryRelease may also be None, meaning that a planned feature got dropped or that the release version is undetermined. Instances of class _Feature have two corresponding methods, .getOptionalRelease() and .getMandatoryRelease(). CompilerFlag is the (bitfield) flag that should be passed in the fourth argument to the builtin function compile() to enable the feature in dynamically compiled code. This flag is stored in the .compiler_flag attribute on _Future instances. These values must match the appropriate #defines of CO_xxx flags in Include/cpython/compile.h. No feature line is ever to be deleted from this file. ) nested_scopes generatorsdivisionabsolute_importwith_statementprint_functionunicode_literalsbarry_as_FLUFLgenerator_stop annotationsall_feature_namesiiiii i@iic$eZdZdZdZdZdZy)_Featurec.||_||_||_y)N)optional mandatory compiler_flag)selfoptionalReleasemandatoryReleasers #/usr/lib64/python3.12/__future__.py__init__z_Feature.__init__Ss' )*c|jS)zReturn first release in which this feature was recognized. This is a 5-tuple, of the same form as sys.version_info. )rrs rgetOptionalReleasez_Feature.getOptionalReleaseXs }}rc|jS)zReturn release in which this feature will become mandatory. This is a 5-tuple, of the same form as sys.version_info, or, if the feature was dropped, or the release date is undetermined, is None. )rrs rgetMandatoryReleasez_Feature.getMandatoryRelease_s ~~rc`dt|j|j|jfzS)Nr)reprrrrrs r__repr__z_Feature.__repr__gs1D$--"&.."&"4"4"677 7rN)__name__ __module__ __qualname__rrrr"rrrrQs+ 7rr)rbetar()r'r'ralphar)r'r'rr*r()r'rfinalr)r'r'rr*r')r+rrr*r)r'rr*r()r'rr*r)r'r.rr*r')r+r(rr*r')rrr*r)r+r-rr)r()r+rr*r)r+r0rr)r(N)__doc__r __all__ CO_NESTEDCO_GENERATOR_ALLOWEDCO_FUTURE_DIVISIONCO_FUTURE_ABSOLUTE_IMPORTCO_FUTURE_WITH_STATEMENTCO_FUTURE_PRINT_FUNCTIONCO_FUTURE_UNICODE_LITERALSCO_FUTURE_BARRY_AS_BDFLCO_FUTURE_GENERATOR_STOPCO_FUTURE_ANNOTATIONSrrrrrrrrr r r r&rrr=s=/b   "3 3  #"#%"#!778.."$ ++*,  ))& (0046//24//241168//13./24+,. r__pycache__/_osx_support.cpython-312.opt-2.pyc000064400000035367152342670510015206 0ustar00 ֦iV ddlZddlZddlZgdZdZdZdZddZddZdZ da d Z da d Z d Zd Zdad ZdZdZdZdZdZdZdZdZdZdZdZy)N)compiler_fixupcustomize_config_varscustomize_compilerget_platform_osx) CFLAGSLDFLAGSCPPFLAGS BASECFLAGS BLDSHAREDLDSHAREDCCCXX PY_CFLAGS PY_LDFLAGS PY_CPPFLAGSPY_CORE_CFLAGSPY_CORE_LDFLAGS)r r r r_OSX_SUPPORT_INITIAL_c |tjd}|jtj}tjj |\}}t jdk(r |dk7r|dz}tjj|sK|D]E}tjj||}tjj|sC|cSy|S)NPATHwin32z.exe) osenvironsplitpathseppathsplitextsysplatformisfilejoin) executablerpathsbaseextpfs %/usr/lib64/python3.12/_osx_support.py_find_executabler)s  |zz&! JJrzz "E  ,ID# cVm&( 77>>* %A Q +Aww~~a   c ddl} ddl}|j}|j|5}|r|d|jd}n|d|jd}t j|s-|jjdjndcdddS#t$r$t dt j d}YwxYw#1swYyxYw) Nrz/tmp/_osx_support.zw+bz >'z' 2>&1z 2>/dev/null >''utf-8) contextlibtempfileNamedTemporaryFile ImportErroropenrgetpidclosingnamesystemreaddecodestrip) commandstringcapture_stderrr.r/fpcmds r( _read_outputr>7s: "  ( ( *   B 2 %2BGG)toolnames r(_find_build_toolrBMs*: X & X GH r*cl tda tdd} tjd|j }|j |2dj |jdjdddatStS#|j wxYw#t$rYtSwxYw) Nr@z0/System/Library/CoreServices/SystemVersion.plistr-)encodingz=ProductUserVisibleVersion\s*(.*?).) _SYSTEM_VERSIONr2researchr7closer!grouprOSError)r'ms r(_get_system_versionrOVs4 FGRYZA  II89:C }"%((1771:+;+;C+@!+D"E ?      s B"$B B" B32B3c t4t}|r( td|jdDatStS#t$r daYtSwxYw)Nc32K|]}t|ywNint.0is r( z,_get_system_version_tuple..s-U>Tc!f>TrE)_SYSTEM_VERSION_TUPLErOtupler ValueError osx_versions r(_get_system_version_tupler`usg$)+  +(--Uk>O>OPS>T-U(U% !   +(*%   +s!A AAcX t|D]}|jts||=yrR)list startswith_INITPRE) _config_varsks r(_remove_original_valuesrgs'7 ,  << !Q r*cl |j|d}||k7rt|z|vr ||t|z<|||<y)Nr@)getrd)recvnewvalueoldvalues r(_save_modified_valuermsBJB'HH8b= #D&. X]#Lr*c8 ttSt|dd}d}|jD]\}|jdrd}|jdrd}+|s.|j }|dk(rdaF|j dsX|dd a^tdatS) Nz -c -E -v - zEnd of search listz /usr/include/z.sdk/usr/includei)_cache_default_sysrootr> splitlinesrcr9endswith)cccontents in_incdirslines r(_default_sysrootrwsG)%%">EHJ##% ??+ ,J __1 2J ::replace SystemError_COMPILER_CONFIG_VARSrmr!)rersoldccdatarjcv_splits r(_find_appropriate_compilerrsA  rzzd#))+A..B B g &   "  ( ( / " 3 :=> J$&!'*B /1 1 U{(B\!b &:'+113$&%KbR$Y $\2sxx7IJ ( r*c tD]j}||vs|tjvs||}tjdd|tj }tjdd|}t |||l|S)N -arch\s+\w+\sr)flagsz-isysroot\s*\S+)_UNIVERSAL_CONFIG_VARSrrrIsubASCIIrm)rerjrs r(_remove_universal_flagsrsl?$  "BJJ"6 $EFF+S%rxxHEFF-sE:E r5 9 % r*cV dtjvr|Stjd|dztjd|dj ddd}|rLt D]C}||vs|tjvs||}tjdd |}t|||E|S) Nr z -arch\s+ppcrzecho 'int main{};' | 'r,rz6' -c -arch ppc -x c -o /dev/null /dev/null 2>/dev/nullz-arch\s+ppc\w*\sr) rrrIrJr6rrrrm)restatusrjrs r(_remove_unsupported_archsrs7 rzz yyh!78D4 ((i8 ;< -%"BJJ*>(,EFF#6UCE(r5A - r*c dtjvr\tjd}tD]@}||vsd||vs||}tjdd|}|dz|z}t |||B|S)N ARCHFLAGS-archrr)rrrrIrrm)rearchrjrs r(_override_all_archsr:s~<bjj zz+&(B\!gb1A&A$R(/e< d*$\2u= ) r*cT |jdd}tjd|}|||jd}tj j |sLtD]C}||vs|tjvs||}tjdd|}t|||E|S)Nrr@z-isysroot\s*(\S+)rFz-isysroot\s*\S+(?:\s|$)r) rirIrJrLrrexistsrrrrm)recflagsrNsdkrjrs r(_check_for_unavailable_sdkrKs5  h +F &/A}ggajww~~c",%"BJJ*>(,EFF#=sEJE(r5A - r*c dx}}t|}tsdx}}nd|v}td|D}|sdtjvr |j d}|||dz=ts?ttt|D]}||dk(s ||dzdk(s|||dz=!dtjvr&|s$|tjdjz}|rR t|Dcgc]\}}|jd s|}}}|sn|d }||d k(r |||dz=n|||dz=Qd} |} t|Dcgc]\}}|jd s|}}}|s1|} t|Dcgc]\}}|jd s|}}}|D]&}| |d k(r | |dz} n| |td d} n| rtjj| s`t j"j%d | d t j"j%d t j"j'|S#t $rYwxYwcc}}wcc}}wcc}}w)NFTrc3DK|]}|jds|yw) -isysrootN)rc)rVargs r(rXz!compiler_fixup..ysQ'3S^^K5P3's  rrGrFarm64rrz2Compiling with an SDK that doesn't seem to exist:  z%Please check your Xcode installation )rbr}anyrrindexr]rreversedrangelenr enumeratercrisdirrstderrwriteflush) compiler_socc_args stripArch stripSysrootridxrWxindicessysrootargvars r(rrfs %$I {#K % '$(' Lw& Q'QQ K2::- #))'2eAg . $ %E#k"234C37*{3q5/AW/LCE *5bjj "BJJ{$;$A$A$CC $-k$:X$:SQqall;>Wq$:GXAJE5![0eAg . eAg .G F%g.L.SQq!,,{2Kq.GL  )+ 6T 61!,,{:S1 6T #;+ %SUmG Sk#k"2"34G  rww}}W- MgYVXYZ AB  e   Y MUs6 I8II I%'I%I+I+ IIc^ ts t|t|t||SrR)r}rrrres r(rrs30 & ' - %|, r*cJ t|t|t||SrR)rrrrs r(rrs+|,l+ % r*c |jdd}|r d|vr|dz }txs|}|xs|}|r,|}d}|jtdz|jdd}|r& td|j ddd D}nd }|d k\rd |j vrd }tjd|}ttt|}t|dk(r|d}nu|dk(rd}nm|dk(rd }ne|dk(rd}n]|dk(rd}nU|dk(rd}nM|dk(rd}nEt d||dk(rtjdk\rd}n|dvrtjdk\rd }nd!}|||fS#t $rd }YwxYw)"NMACOSX_DEPLOYMENT_TARGETr@rEz.0macosxrc32K|]}t|ywrRrSrUs r(rXz#get_platform_osx..s"N3Ma3q63MrYrrG)rzryrfatz -arch\s+(\S+)rF)rx86_64 universal2)i386ppc)rrintel)rrrfat3)ppc64rfat64)rrrr universalz#Don't know machine value for archs=rlr)PowerPCPower_Macintoshrr)rirOrdr\rr]r9rIfindallsortedsetrrmaxsize)reosnamereleasemachinemacver macreleaserarchss r(rrs*  8" =F #V# $$&0&J  !zF  !!(8"3$0$4$4Xr$BD  %""N:3C3CC3H13M"NN !J ' !w&,,.'@GJJ/8E&U,-E5zQ(--&/),,!33 --!<<% >CEGG {{e#" 6 6{{e#! GW %%a %$  %s&$E'' E54E5rR)F)rrIr__all__rrrdr)r>rBrHrOr[r`rgrmrprwr}rrrrrrrrrrrZr*r(rs$  A ? #4Q,<!&  "2B<;| %P"6M`&R(P&r*__pycache__/_markupbase.cpython-312.opt-2.pyc000064400000026667152342670510014736 0ustar00 ֦i=9 ddlZejdjZejdjZejdZejdZejdZ[GddZy) Nz[a-zA-Z][-_.a-zA-Z0-9]*\s*z(\'[^\']*\'|"[^"]*")\s*z--\s*>z ]\s*]\s*>z]\s*>cjeZdZ dZdZdZdZdZdZddZ ddZ d Z d Z d Z d Zd ZdZdZy) ParserBasec>|jtur tdy)Nz)_markupbase.ParserBase must be subclassed) __class__r RuntimeErrorselfs $/usr/lib64/python3.12/_markupbase.py__init__zParserBase.__init__s# >>Z ';= = (c d|_d|_y)Nrlinenooffsetrs r resetzParserBase.reset s  r c4 |j|jfSNrrs r getposzParserBase.getpos$s4{{DKK''r c||k\r|S|j}|jd||}|r6|j|z|_|jd||}||dzz |_|S|j|z|z |_|S)N r)rawdatacountrrindexr)r ijrnlinesposs r updateposzParserBase.updatepos,s 6H,,tQ* ++.DK..q!,CSU)DK++/!+DKr c|j}|dz}|||dzdk(r|dzS|||dzdvryt|}|||dzdk(r|j|S||dk(r|j|S|j ||\}}|dkr|S|d k(rd |_||kr||}|dk(r9||dz|}|d k(r|j ||dzS|j||dzS|d vr t||}|sy|j}n||d vr|j ||\} }nb||j vr|dz}nN|dk(r8|d k(r|j|dz|}n.|d vrtd|ztdtd||z|dkr|S||kry)Nr>)-r z--[rdoctyper z"'4abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ>linkattlistelementlinktypez&unsupported '[' char in %s declarationz"unexpected '[' char in declarationz!unexpected %r char in declaration) rlen parse_commentparse_marked_section _scan_name_decl_otherchars handle_decl unknown_decl_declstringlit_matchend_parse_doctype_subsetAssertionError) r rrrndecltypecdatamnames r parse_declarationzParserBase.parse_declaration<s,, E 1QqS>S q5L 1QqS>Y & L 1QqS>T !%%a( ( QZ3  ,,Q/ ///!Q/KHa q5H y $&D !!e ACxqs1~y($$T*1u %%d+1u Ez(!4EEGLL//!Q/ad+++Ecy(221q5!tempcdataignorercdatainclude>ifelseendifz+unknown status keyword %r in marked sectionr%) rr0_markedsectionclosesearch_msmarkedsectioncloser7startr3r5)r rreportrsectNamermatchs r r/zParserBase.parse_marked_sectionsooqsA/ ! q5H G G&--gqs;E 0 0(//1=E =!AN   AA   gac1o .yy|r c|j}|||dzdk7r tdtj||dz}|sy|r(|j d}|j ||dz||j dS)N| UnixStreamServer | +-----------+ +------------------+ | v +-----------+ +--------------------+ | UDPServer |------->| UnixDatagramServer | +-----------+ +--------------------+ Note that UnixDatagramServer derives from UDPServer, not from UnixStreamServer -- the only difference between an IP and a Unix stream server is the address family, which is simply repeated in both unix server classes. Forking and threading versions of each type of server can be created using the ForkingMixIn and ThreadingMixIn mix-in classes. For instance, a threading UDP server class is created as follows: class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass The Mix-in class must come first, since it overrides a method defined in UDPServer! Setting the various member variables also changes the behavior of the underlying server mechanism. To implement a service, you must derive a class from BaseRequestHandler and redefine its handle() method. You can then run various versions of the service by combining one of the server classes with your request handler class. The request handler class must be different for datagram or stream services. This can be hidden by using the request handler subclasses StreamRequestHandler or DatagramRequestHandler. Of course, you still have to use your head! For instance, it makes no sense to use a forking server if the service contains state in memory that can be modified by requests (since the modifications in the child process would never reach the initial state kept in the parent process and passed to each child). In this case, you can use a threading server, but you will probably have to use locks to avoid two requests that come in nearly simultaneous to apply conflicting changes to the server state. On the other hand, if you are building e.g. an HTTP server, where all data is stored externally (e.g. in the file system), a synchronous class will essentially render the service "deaf" while one request is being handled -- which may be for a very long time if a client is slow to read all the data it has requested. Here a threading or forking server is appropriate. In some cases, it may be appropriate to process part of a request synchronously, but to finish processing in a forked child depending on the request data. This can be implemented by using a synchronous server and doing an explicit fork in the request handler class handle() method. Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor fork (or where these are too expensive or inappropriate for the service) is to maintain an explicit table of partially finished requests and to use a selector to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be connected for a long time (if threads or subprocesses cannot be used). Future work: - Standard classes for Sun RPC (which uses either UDP or TCP) - Standard mix-in classes to implement various authentication and encryption schemes XXX Open problems: - What to do with out-of-band data? BaseServer: - split generic "request" functionality out into BaseServer class. Copyright (C) 2000 Luke Kenneth Casson Leighton example: read entries from a SQL database (requires overriding get_request() to return a table entry from the database). entry is processed by a RequestHandlerClass. z0.4N)BufferedIOBase) monotonic) BaseServer TCPServer UDPServerThreadingUDPServerThreadingTCPServerBaseRequestHandlerStreamRequestHandlerDatagramRequestHandlerThreadingMixInfork)ForkingUDPServerForkingTCPServer ForkingMixInAF_UNIX)UnixStreamServerUnixDatagramServerThreadingUnixStreamServerThreadingUnixDatagramServerForkingUnixStreamServerForkingUnixDatagramServer PollSelectorc|eZdZdZdZdZdZddZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZy)raBase class for server classes. Methods for the caller: - __init__(server_address, RequestHandlerClass) - serve_forever(poll_interval=0.5) - shutdown() - handle_request() # if you do not use serve_forever() - fileno() -> int # for selector Methods that may be overridden: - server_bind() - server_activate() - get_request() -> request, client_address - handle_timeout() - verify_request(request, client_address) - server_close() - process_request(request, client_address) - shutdown_request(request) - close_request(request) - service_actions() - handle_error() Methods for derived classes: - finish_request(request, client_address) Class variables that may be overridden by derived classes or instances: - timeout - address_family - socket_type - allow_reuse_address - allow_reuse_port Instance variables: - RequestHandlerClass - socket Nc`||_||_tj|_d|_y)/Constructor. May be extended, do not override.FN)server_addressRequestHandlerClass threadingEvent_BaseServer__is_shut_down_BaseServer__shutdown_request)selfrrs %/usr/lib64/python3.12/socketserver.py__init__zBaseServer.__init__s),#6 'oo/"'cyzSCalled by constructor to activate the server. May be overridden. Nr#s r$server_activatezBaseServer.server_activate r&c|jj t5}|j|tj |j sM|j|}|j rn/|r|j|j|j sMdddd|_|jjy#1swY+xYw#d|_|jjwxYw)zHandle one request at a time until shutdown. Polls for shutdown every poll_interval seconds. Ignores self.timeout. If you need to do periodic tasks, do them in another thread. NF) r!clear_ServerSelectorregister selectors EVENT_READr"select_handle_request_noblockservice_actionsset)r# poll_intervalselectorreadys r$ serve_foreverzBaseServer.serve_forevers !!# & !"h!!$ (<(<=11$OOM:E..446((*11#',D #    # # %#"',D #    # # %s# CA9C  C CC#C9cFd|_|jjy)zStops the serve_forever loop. Blocks until the loop has finished. This must be called while serve_forever() is running in another thread, or it will deadlock. TN)r"r!waitr*s r$shutdownzBaseServer.shutdowns#'   "r&cy)zCalled by the serve_forever() loop. May be overridden by a subclass / Mixin to implement any code that needs to be run during the loop. Nr)r*s r$r5zBaseServer.service_actionsr,r&c|jj}| |j}n"|jt||j}| t |z}t 5}|j |tj |j|r|jcdddS|+t z }|dkr|jcdddSX#1swYyxYw)zOHandle one request, possibly blocking. Respects self.timeout. Nr) socket gettimeouttimeoutmintimer/r0r1r2r3r4handle_timeout)r#rBdeadliner8s r$handle_requestzBaseServer.handle_requests++((* ?llG \\ %'4<<0G  v'H (   dI$8$8 9??7+779  *"*TV"3"Q;#'#6#6#8  s%AC1#CCC(c@ |j\}}|j||r |j||y|j |y#t$rYywxYw#t$r&|j |||j |Yy|j |xYw)zHandle one request, without blocking. I assume that selector.select() has returned that the socket is readable before this function was called, so there should be no risk of blocking in get_request(). N) get_requestOSErrorverify_requestprocess_request Exception handle_errorshutdown_requestr#requestclient_addresss r$r4z"BaseServer._handle_request_noblock1s &*&6&6&8 #G^   w 7 $$Wn=  ! !' *     /!!'>:%%g. %%g.s"A A AA,B Bcy)zcCalled if no new request arrives within self.timeout. Overridden by ForkingMixIn. Nr)r*s r$rEzBaseServer.handle_timeoutHs r&cy)znVerify the request. May be overridden. Return True if we should proceed with this request. Tr)rPs r$rKzBaseServer.verify_requestOs r&cJ|j|||j|y)zVCall finish_request. Overridden by ForkingMixIn and ThreadingMixIn. N)finish_requestrOrPs r$rLzBaseServer.process_requestWs" G^4 g&r&cyzDCalled to clean-up the server. May be overridden. Nr)r*s r$ server_closezBaseServer.server_close`r,r&c*|j|||y)z8Finish one request by instantiating RequestHandlerClass.N)rrPs r$rVzBaseServer.finish_requesths   .$?r&c&|j|yz3Called to shutdown and close an individual request.N close_requestr#rQs r$rOzBaseServer.shutdown_requestl 7#r&cyz)Called to clean up an individual request.Nr)r_s r$r^zBaseServer.close_requestp r&ctdtjtd|tjddl}|j tdtjy)ztHandle an error gracefully. May be overridden. The default is to print a traceback and continue. z(----------------------------------------)filez4Exception occurred during processing of request fromrN)printsysstderr traceback print_exc)r#rQrRris r$rNzBaseServer.handle_errortsC f3::& D  - f3::&r&c|SNr)r*s r$ __enter__zBaseServer.__enter__s r&c$|jyrl)rY)r#argss r$__exit__zBaseServer.__exit__s r&)g?)__name__ __module__ __qualname____doc__rBr%r+r:r=r5rGr4rErKrLrYrVrOr^rNrmrpr)r&r$rrse*XG( &:# &9:+. ' @$  'r&rc~eZdZdZej ZejZdZ dZ dZ d dZ dZ dZdZdZd Zd Zd Zy )raJBase class for various socket-based server classes. Defaults to synchronous IP stream (i.e., TCP). Methods for the caller: - __init__(server_address, RequestHandlerClass, bind_and_activate=True) - serve_forever(poll_interval=0.5) - shutdown() - handle_request() # if you don't use serve_forever() - fileno() -> int # for selector Methods that may be overridden: - server_bind() - server_activate() - get_request() -> request, client_address - handle_timeout() - verify_request(request, client_address) - process_request(request, client_address) - shutdown_request(request) - close_request(request) - handle_error() Methods for derived classes: - finish_request(request, client_address) Class variables that may be overridden by derived classes or instances: - timeout - address_family - socket_type - request_queue_size (only for stream sockets) - allow_reuse_address - allow_reuse_port Instance variables: - server_address - RequestHandlerClass - socket Fctj|||tj|j|j|_|r" |j |j yy#|jxYw)rN)rr%r@address_family socket_type server_bindr+rY)r#rrbind_and_activates r$r%zTCPServer.__init__sqD.2EFmmD$7$7$($4$46    "$$&  !!#s A,,A?c8|jrIttdr9|jjtjtj d|j ruttdre|jtjtjfvr9|jjtjtjd|jj|j|jj|_ y)zOCalled by constructor to bind the socket. May be overridden. SO_REUSEADDR SO_REUSEPORTN)allow_reuse_addresshasattrr@ setsockopt SOL_SOCKETr}allow_reuse_portrxAF_INETAF_INET6rbindr getsocknamer*s r$rzzTCPServer.server_binds  # #(G KK " "6#4#4f6I6I1 M  ! !gfn&E##'HH KK " "6#4#4f6I6I1 M ,,-"kk557r&cN|jj|jyr()r@listenrequest_queue_sizer*s r$r+zTCPServer.server_activates 4223r&c8|jjyrX)r@closer*s r$rYzTCPServer.server_closes r&c6|jjS)zMReturn socket file number. Interface required by selector. )r@filenor*s r$rzTCPServer.fileno {{!!##r&c6|jjS)zYGet the request and client address from the socket. May be overridden. )r@acceptr*s r$rIzTCPServer.get_requestrr&c |jtj|j |y#t$rYwxYwr\)r=r@SHUT_WRrJr^r_s r$rOzTCPServer.shutdown_requests?    V^^ , 7#   s 3 ??c$|jyrb)rr_s r$r^zTCPServer.close_request s  r&N)T)rqrrrsrtr@rrx SOCK_STREAMryrrrr%rzr+rYrrIrOr^r)r&r$rrsX,\^^N$$K 8$4$$$r&rcLeZdZdZdZdZejZdZ dZ dZ dZ dZ y) rzUDP server class.Fi cr|jj|j\}}||jf|fSrl)r@recvfrommax_packet_size)r#data client_addrs r$rIzUDPServer.get_requests5 KK001E1EFkdkk"K//r&cyrlr)r*s r$r+zUDPServer.server_activate rcr&c&|j|yrlr]r_s r$rOzUDPServer.shutdown_request$r`r&cyrlr)r_s r$r^zUDPServer.close_request(rcr&N)rqrrrsrtrrr@ SOCK_DGRAMryrrIr+rOr^r)r&r$rrs5##KO0 $ r&rcPeZdZdZdZdZdZdZdddZd Z d Z d Z fd Z xZ S) rz5Mix-in class to handle each request in a new process.i,N(TFblockingc|jyt|j|jk\rX tjdd\}}|jj |t|j|jk\rX|jjD]K} |rdntj}tj||\}}|jj |My#t $r|jjYt$rYwxYw#t $r|jj |Yt$rYwxYw)z7Internal routine to wait for children that have exited.Nr) active_childrenlen max_childrenoswaitpiddiscardChildProcessErrorr.rJcopyWNOHANG)r#rpid_flagss r$collect_childrenzForkingMixIn.collect_children6s(##+d**+t/@/@@ZZA.FC((005d**+t/@/@@++002 !)ArzzEZZU3FC((005 3)1((..0)6((005s04C1&AD$1#D!D! D!$$E EEc$|jy)zvWait for zombies after self.timeout seconds of inactivity. May be extended, do not override. Nrr*s r$rEzForkingMixIn.handle_timeoutY  ! ! #r&c$|jy)zCollect the zombie child processes regularly in the ForkingMixIn. service_actions is called in the BaseServer's serve_forever loop. Nrr*s r$r5zForkingMixIn.service_actions`rr&c>tj}|rH|jt|_|jj ||j |yd} |j ||d} |j|tj|y#t$r|j||YEwxYw#tj|wxYw# |j|tj|w#tj|wxYwxYw)z-Fork a new subprocess to process the request.Nr~r) rrrr6addr^rVrMrNrO_exit)r#rQrRrstatuss r$rLzForkingMixIn.process_requestgs'')C''/+.5D($$((-""7+ )''@F)--g6( !?%%g~>? ()--g6((sH"B7B?B<9C;B<<C?CDD,DDDcZt||j|jy)Nr)superrYrblock_on_closer# __class__s r$rYzForkingMixIn.server_closes% G "  ! !4+>+> ! ?r&)rqrrrsrtrBrrrrrEr5rLrY __classcell__rs@r$rr-s>C /4! F $ $ )2 @ @r&rc4eZdZdZfdZdZdZdZxZS)_Threadsz2 Joinable list of all non-daemon threads. c^|j|jryt| |yrl)reapdaemonrappend)r#threadrs r$rz_Threads.appends" ==  vr&cg|ddc|dd}|Srlr))r#results r$pop_allz_Threads.pop_allsd1gQ r&cN|jD]}|jyrl)rjoinr#rs r$rz _Threads.joinsllnF KKM%r&cd|D|ddy)Nc3BK|]}|js|ywrl)is_alive).0rs r$ z _Threads.reap..sBf0A6sr)r*s r$rz _Threads.reapsBBQr&) rqrrrsrtrrrrrrs@r$rrs Cr&rceZdZdZdZdZy) _NoThreadsz) Degenerate version of _Threads. cyrlr)rs r$rz_NoThreads.append r&cyrlr)r*s r$rz_NoThreads.joinrr&N)rqrrrsrtrrr)r&r$rrs  r&rcDeZdZdZdZdZeZdZdZ fdZ xZ S)r z4Mix-in class to handle each request in a new thread.FTc |j|||j|y#t$r|j||Y/wxYw#|j|wxYw)zgSame as in BaseServer but as a thread. In addition, exception handling is done here. N)rVrMrNrOrPs r$process_request_threadz%ThreadingMixIn.process_request_threadsY  +    8  ! !' * 7   g~ 6 7  ! !' *s!&AAAAAc |jr#t|jdtt j |j ||f}|j|_|jj||jy)z*Start a new thread to process the request._threads)targetroN) rvars setdefaultrrThreadrdaemon_threadsrrrstart)r#rQrRts r$rLzThreadingMixIn.process_requestsi    J ! !*hj 9   d&A&A%,n$= ?&& Q  r&cVt||jjyrl)rrYrrrs r$rYzThreadingMixIn.server_closes  r&) rqrrrsrtrrrrrrLrYrrs@r$r r s/>NN|H +r&r c eZdZy)rNrqrrrsr)r&r$rrr&rc eZdZy)rNrr)r&r$rrrr&rc eZdZy)rNrr)r&r$rrrr&rc eZdZy)r Nrr)r&r$r r rr&r c$eZdZejZy)rNrqrrrsr@rrxr)r&r$rr r&rc$eZdZejZy)rNrr)r&r$rrrr&rc eZdZy)rNrr)r&r$rrrr&rc eZdZy)rNrr)r&r$rrrr&rc eZdZy)rNrr)r&r$rrrr&c eZdZy)rNrr)r&r$rrrr&c(eZdZdZdZdZdZdZy)r aBase class for request handler classes. This class is instantiated for each request to be handled. The constructor sets the instance variables request, client_address and server, and then calls the handle() method. To implement a specific service, all you need to do is to derive a class which defines a handle() method. The handle() method can find the request as self.request, the client address as self.client_address, and the server (in case it needs access to per-server information) as self.server. Since a separate instance is created for each request, the handle() method can define other arbitrary instance variables. c||_||_||_|j |j |j y#|j wxYwrl)rQrRserversetuphandlefinish)r#rQrRrs r$r%zBaseRequestHandler.__init__sB ,    KKM KKMDKKMs AAcyrlr)r*s r$rzBaseRequestHandler.setuprr&cyrlr)r*s r$rzBaseRequestHandler.handlerr&cyrlr)r*s r$rzBaseRequestHandler.finishrr&N)rqrrrsrtr%rrrr)r&r$r r s    r&r c,eZdZdZdZdZdZdZdZdZ y)r z4Define self.rfile and self.wfile for stream sockets.rrNFc|j|_|j%|jj|j|jr9|jj t jt jd|jjd|j|_ |jdk(rt|j|_y|jjd|j|_y)NTrbrwb)rQ connectionrB settimeoutdisable_nagle_algorithmrr@ IPPROTO_TCP TCP_NODELAYmakefilerbufsizerfilewbufsize _SocketWriterwfiler*s r$rzStreamRequestHandler.setup)s,, << # OO & &t|| 4  ' ' OO & &v'9'9'-'9'94 A__--dDMMB ==A &t7DJ11$ FDJr&c|jjs |jj|jj |j j y#tj$rYJwxYwrl)r closedflushr@errorrr r*s r$rzStreamRequestHandler.finish6s`zz      "   <<  sA''A=<A=) rqrrrsrtrr rBrrrr)r&r$r r s+>HHG$ G r&r c(eZdZdZdZdZdZdZy)r zSimple writable BufferedIOBase implementation for a socket Does not hold data in a buffer, avoiding any need to call flush().c||_yrl)_sock)r#socks r$r%z_SocketWriter.__init__Fs  r&cy)NTr)r*s r$writablez_SocketWriter.writableIsr&c|jj|t|5}|jcdddS#1swYyxYwrl)rsendall memoryviewnbytes)r#bviews r$writez_SocketWriter.writeLs. 1 ]d;;]]s =Ac6|jjSrl)rrr*s r$rz_SocketWriter.filenoQszz  ""r&N)rqrrrsrtr%rrrr)r&r$r r AsJ #r&r ceZdZdZdZdZy)r z6Define self.rfile and self.wfile for datagram sockets.cddlm}|j\|_|_||j|_||_y)Nr)BytesIO)ior!rQpacketr@r r )r#r!s r$rzDatagramRequestHandler.setupXs0#'<<  T[T[[) Y r&c|jj|jj|jyrl)r@sendtor getvaluerRr*s r$rzDatagramRequestHandler.finish^s) 4::..0$2E2EFr&N)rqrrrsrtrrr)r&r$r r Ts@ Gr&r )'rt __version__r@r1rrgrr"rrDr__all__rextendrr/SelectSelectorrrrrlistrrr rrrr rrrrrrr r r r r)r&r$r,svt  " 7 2v NNJK 69 NN34r613NOP 9n%,,O..OjjZE EP  8 2vU@U@pCtC,  %%P 2v9<99<99999 69(9((Y(LN4DKOn6HOr6Kl4DKO 6HO# # \+-+Z#N#& G/ Gr&__pycache__/random.cpython-312.opt-1.pyc000064400000100506152342670510013705 0ustar00 ֦i^dZddlmZddlmZmZm Z m Z m ZddlmZmZmZmZddlmZmZmZddlmZmZ m!Z"ddl#m$Z%ddl&m'Z(dd l)m*Z+dd l,m-Z.m/Z0dd l1m1Z2dd l#Z3dd l4Z4 dd l5m6Z7gdZ:dedzedz Z;edZde> zZ?dZ@Gdde4jZAGddeAZBeAZCeCjZDeCjZEeCjZFeCjZGeCjZHeCjZIeCjZJeCjZKeCjZLeCjZMeCjZNeCjZOeCjZPeCjZQeCjZReCjZSeCjZTeCjZUeCjZVeCjZWeCjZXeCjZYeCjZZeCjZ[dZ\d!dZ]e^e3dre3jeCje`d k(re]y y #e8$r dd l9m6Z7YwxYw)"aERandom variable generators. bytes ----- uniform bytes (values between 0 and 255) integers -------- uniform within range sequences --------- pick random element pick random sample pick weighted random sample generate random permutation distributions on the real line: ------------------------------ uniform triangular normal (Gaussian) lognormal negative exponential gamma beta pareto Weibull distributions on the circle (angles 0 to 2pi) --------------------------------------------- circular uniform von Mises discrete distributions ---------------------- binomial General notes on the underlying Mersenne Twister core generator: * The period is 2**19937-1. * It is one of the most extensively tested generators in existence. * The random() method is implemented in C, executes in a single Python step, and is, therefore, threadsafe. )warn)logexppieceil)sqrtacoscossin)taufloorisfinite)lgammafabslog2)urandom)Sequence)index) accumulaterepeat)bisectN)sha512)Random SystemRandom betavariatebinomialvariatechoicechoices expovariate gammavariategauss getrandbitsgetstatelognormvariate normalvariate paretovariate randbytesrandintrandom randrangesampleseedsetstateshuffle triangularuniformvonmisesvariateweibullvariateg@@?@5ceZdZdZdZd$dZd%fd ZfdZfdZdZ d Z d Z d Z d Z d ezfdZe ZdZdefdZdZdZdZdddZd$dd ddZdZd&dZd'dZd'dZdZd(dZdZdZ d Z!d!Z"d"Z#d)d#Z$xZ%S)*raRandom number generator base class used by bound module functions. Used to instantiate instances of Random to get generators that don't share state. Class Random can also be subclassed if you want to use a different basic generator of your own devising: in that case, override the following methods: random(), seed(), getstate(), and setstate(). Optionally, implement a getrandbits() method so that randrange() can cover arbitrarily large ranges. Nc4|j|d|_y)zeInitialize an instance. Optional argument x controls seeding, as for Random.seed(). N)r- gauss_next)selfxs /usr/lib64/python3.12/random.py__init__zRandom.__init__~s ! c |dk(rt|ttfrpt|tr|jdn|}|rt |ddznd}t t|D] }d|z|z dz}|t |z}|dk(rdn|}n|d k(rkt|tttfrPt|tr|j}tj|t|jz}n:t|td tttttfs td t |E|d |_y ) a\Initialize internal state from a seed. The only supported seed types are None, int, float, str, bytes, and bytearray. None or no argument seeds from current time or from an operating system specific randomness source if available. If *a* is an int, all bits are used. For version 2 (the default), all of the bits are used if *a* is a str, bytes, or bytearray. For version 1 (provided for reproducing random sequences from older versions of Python), the algorithm for str and bytes generates a narrower range of seeds. r;zlatin-1riCBlr:NzOThe only supported seed types are: None, int, float, str, bytes, and bytearray.) isinstancestrbytesdecodeordmaplen bytearrayencodeint from_bytes_sha512digesttypefloat TypeErrorsuperr-r?)r@aversionrAc __class__s rBr-z Random.seeds$ az"Random.setstate..s%K]a7m]sNzstate with version z( passed to Random.setstate() of version )r?rYr.tuple ValueErrorrXr_)r@stater[ internalstaterr]s rBr.zRandom.setstates( a<6; 3G]DO G ] + \6; 3G]DO  ' %%K]%K K  G ] +%t||56 6  'Q& 'sA55 B >BB c"|jSN)r$r@s rB __getstate__zRandom.__getstate__s}}rDc&|j|yrj)r.)r@rgs rB __setstate__zRandom.__setstate__s erDc<|jd|jfS)Nrb)r]r$rks rB __reduce__zRandom.__reduce__s~~r4==?22rDc |jD]T}d|jvryd|jvr|j|_yd|jvsC|j|_yy)aControl how subclasses generate random integers. The algorithm a subclass can use depends on the random() and/or getrandbits() implementation available to it and determines whether it can generate random integers from arbitrarily large ranges. _randbelowr#r*N)__mro____dict___randbelow_with_getrandbitsrr_randbelow_without_getrandbits)clskwargsr\s rB__init_subclass__zRandom.__init_subclass__sYAqzz) *!$!@!@1::%!$!C!CrDct|j}|j}||}||k\r||}||k\r|S)z;Return a random int in the range [0,n). Defined for n > 0.)r# bit_length)r@nr#krs rBruz"Random._randbelow_with_getrandbitssA&& LLN N1fAA1frDr;c|j}||k\rtdt||zS||z}||z |z }|}||k\r |}||k\r t||z|zS)zReturn a random int in the range [0,n). Defined for n > 0. The implementation does not use getrandbits, but only random. zUnderlying random() generator does not supply enough bits to choose from a population range this large. To remove the range limitation, add a getrandbits() method.)r*_warn_floor)r@r|maxsizer*remlimitr~s rBrvz%Random._randbelow_without_getrandbitss  < N O&(Q,' 'k3') H5jA5ja'k"Q&&rDcJ|j|dzj|dS)Generate n random bytes.little)r#to_bytesr@r|s rBr(zRandom.randbytess$A&//8<t |} t|D]#}| ||z }| || |<| ||z d z | |<%| St}|j }t|D]+}| |}||vr | |}||vr ||||| |<-| Scc} w)afChooses k unique random elements from a population sequence. Returns a new list containing elements from the population while leaving the original population unchanged. The resulting list is in selection order so that all sub-slices will also be valid random samples. This allows raffle winners (the sample) to be partitioned into grand prize and second place winners (the subslices). Members of the population need not be hashable or unique. If the population contains repeats, then each occurrence is a possible selection in the sample. Repeated elements can be specified one at a time or with the optional counts parameter. For example: sample(['red', 'blue'], counts=[4, 2], k=5) is equivalent to: sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5) To choose a sample from a range of integers, use range() for the population argument. This is especially fast and space efficient for sampling from a large population: sample(range(10000000), 60) zAPopulation must be a sequence. For dicts or sets, use sorted(d).Nz2The number of counts does not match the populationrzCounts must be integerszCounts must be non-negative)r}z,Sample larger than population or is negativer4r=r;)rI _SequencerXrOlist _accumulaterfpoprRr,r_bisectrr_ceil_logsetadd)r@ populationr}rr| cum_countstotal selectionsrsrresultsetsizepoolrrselected selected_adds rBr,z Random.samplegsj*i0@A A  O  k&12J:!# !UVV(2JNN$EeS) 9::qy !>??U5\Q7JF?IJz!Jvj!45zJ JOO A{{KL LKL L! q5 qE$q1ua.11 1G < #D1Xa!e$ Gq q1uqy/Q uH#<) cum_weightsr}c \|j}t|}|N|6t}|dz }td|Dcgc]}||||zc}S t t |}n | t dt||k7r td|ddz} | dkr tdt| s tdt} |d z } td|Dcgc]}|| ||| zd | c}Scc}w#t $r#t|ts|}t d|dwxYwcc}w) zReturn a k sized list of population elements chosen with replacement. If the relative weights or cumulative weights are not specified, the selections are made with equal probability. Nz4The number of choices must be a keyword argument: k=z2Cannot specify both weights and cumulative weightsz3The number of weights does not match the populationrGz*Total of weights must be greater than zerozTotal of weights must be finiter;r) r*rOr_repeatrrrXrIrRrf _isfiniter) r@rweightsrr}r*r|rrrrhis rBrzRandom.choicessf  O  SAHqAQRAQA 5A#67AQRR ";w#78  PQ Q { q RS SB#% C<IJ J>? ? U q)+)A6+vx%/?BGH)+ ++S !'3/KM  $+sC5C:D):,D&c4|||z |jzzS)zGet a random number in the range [a, b) or [a, b] depending on rounding. The mean (expected value) and variance of the random variable are: E[X] = (a + b) / 2 Var[X] = (b - a) ** 2 / 12 r*rs rBr1zRandom.uniformsAET[[]***rDc|j} |dn ||z ||z z }||kDrd|z }d|z }||}}|||z t||zzzS#t$r|cYSwxYw)aTriangular distribution. Continuous distribution bounded by given lower and upper limits, and having a given mode value in-between. http://en.wikipedia.org/wiki/Triangular_distribution The mean (expected value) and variance of the random variable are: E[X] = (low + high + mode) / 3 Var[X] = (low**2 + high**2 + mode**2 - low*high - low*mode - high*mode) / 18 ?r7)r*ZeroDivisionError_sqrt)r@lowhighmodeur\s rBr0zRandom.triangulars KKM |$*)DA q5aAaAcCdSjE!a%L000 ! J sA AAc|j} |}d|z }t|dz z|z }||zdz }|t| krn9|||zzS)z\Normal distribution. mu is the mean, and sigma is the standard deviation. r7rr6)r* NV_MAGICCONSTr)r@musigmar*u1u2zzzs rBr&zRandom.normalvariatesgBvxBc*R/AQBd2hY AI~rDc|j}|j}d|_|N|tz}tdt d|z z}t ||z}t ||z|_|||zzS)zGaussian distribution. mu is the mean, and sigma is the standard deviation. This is slightly faster than the normalvariate() function. Not thread-safe without a lock around calls. Ngr7)r*r?TWOPIrr_cos_sin)r@rrr*rx2pig2rads rBr"z Random.gauss'st6 OO 98e#D$cFHn!556ET U"A"4j50DOAI~rDc8t|j||S)zLog normal distribution. If you take the natural logarithm of this distribution, you'll get a normal distribution with mean mu and standard deviation sigma. mu can have any value, and sigma must be greater than zero. )_expr&)r@rrs rBr%zRandom.lognormvariateMsD&&r5122rDcBtd|jz  |z S)aExponential distribution. lambd is 1.0 divided by the desired mean. It should be nonzero. (The parameter would be called "lambda", but that is a reserved word in Python.) Returned values range from 0 to positive infinity if lambd is positive, and from negative infinity to 0 if lambd is negative. The mean (expected value) and variance of the random variable are: E[X] = 1 / lambd Var[X] = 1 / lambd ** 2 r7)rr*)r@lambds rBr zRandom.expovariateWs"$S4;;=())E11rDc|j}|dkrt|zSd|z }|td||zzz} |}tt|z}|||zz }|} | d||zz ks| d|z t |zkrnId|z } | |zd| |zzz } |} | dkDr|t | ztz} | S|t | z tz} | S)aFCircular data distribution. mu is the mean angle, expressed in radians between 0 and 2*pi, and kappa is the concentration parameter, which must be greater than or equal to zero. If kappa is equal to zero, this distribution reduces to a uniform random angle over the range 0 to 2*pi. gư>rr7)r*rrr_pir_acos)r@rkappar*rr~rrdrqfu3thetas rBr2zRandom.vonmisesvariateks  D=68# # %K cAEk" "BS2XAQU ABC!a%K2#'T!W)<#< !G UsQU{ # X 8%(]e+E %(]e+E rDc|dks|dkr td|j}|dkDrtd|zdz }|tz }||z} |}d|cxkrdksnd|z }t |d|z z |z } |t | z} ||z|z} ||| zz| z } | t zd| zz dk\s| t | k\r| |zSz|dk(rt d|z  |zS |} t|ztz }|| z}|dkr |d|z z} nt ||z |z  } |}|dkDr|| |dz zkr | |zS|t | kr | |zSo)aGamma distribution. Not the gamma function! Conditions on the parameters are alpha > 0 and beta > 0. The probability distribution function is: x ** (alpha - 1) * math.exp(-x / beta) pdf(x) = -------------------------------------- math.gamma(alpha) * beta ** alpha The mean (expected value) and variance of the random variable are: E[X] = alpha * beta Var[X] = alpha * beta ** 2 rz*gammavariate: alpha and beta must be > 0.0r7r5gHz>gP?r8)rfr*rLOG4rr SG_MAGICCONST_e)r@alphabetar*ainvbbbcccrrvrArr~rrps rBr!zRandom.gammavariates( C<43;IJ J 3; us*+D$,C$,CXb,9,68^sRx)D0DGOGbL#'MA%}$sQw.#5d1gt8Oc\vx((4/ / H%Z2%E8cEk*Aq1uo..AXs7Q53;//t8O48^t8OrDc\|j|d}|r|||j|dzz Sy)aQBeta distribution. Conditions on the parameters are alpha > 0 and beta > 0. Returned values range between 0 and 1. The mean (expected value) and variance of the random variable are: E[X] = alpha / (alpha + beta) Var[X] = alpha * beta / ((alpha + beta)**2 * (alpha + beta + 1)) r7r)r!)r@rrys rBrzRandom.betavariates96   eS ) D--dC889 9rDc8d|jz }|d|z zS)z3Pareto distribution. alpha is the shape parameter.r7gr)r@rrs rBr'zRandom.paretovariates# $++- TE\""rDcRd|jz }|t| d|z zzS)zfWeibull distribution. alpha is the scale parameter and beta is the shape parameter. r7)r*r)r@rrrs rBr3zRandom.weibullvariates. $++- acDj111rDc|dkr td|dks|dk\r|dk(ry|dk(r|Std|j}|dk(rt||kS|dkDr||j|d|z z S||zdkrFdx}}t d|z }|s|S |t t ||z dzz }||kDr|S|dz }/d }t ||zd|z z}d d |zz} d d| zzd|zz} ||zdz}dd| z z } |} | dz} dt| z } t d| z| z | z| z|z}|dks||kDr@|}| dk\r|| kr|S|sOdd| z z|z}t|d|z z }t |dz|z}t|dzt||z dzz}d }|| | | zz | zz z}t|t|dzz t||z dzz |z zzkr|S)aBinomial random variable. Gives the number of successes for *n* independent trials with the probability of success in each trial being *p*: sum(random() < p for i in range(n)) Returns an integer in the range: 0 <= X <= n The mean (expected value) and variance of the random variable are: E[X] = n * p Var[x] = n * p * (1 - p) rzn must be non-negativerr7z&p must be in the range 0.0 <= p <= 1.0r;rg$@TFgffffff?g= ףp=@gEJYga+e?{Gz?gq= ףp?g@r5gQ?gp= ף@gffffff@) rfr*rr_log2rr_fabsr_lgamma)r@r|rr*rArr\setup_completespqrrZvrrusr}rrlpqmhs rBrzRandom.binomialvariates{" q556 6 8qCxCxCxEF F 6&(Q,' ' s7t++AsQw77 7 q54<IAcAgAVE&(Oa/0144q5HQ AES1W%& 4#:  fqj 4!8 + ECK C!G^A HAuQxBa" q(A-12A1uAATza2g "a3.1a=)AEQ;'AENWQUQY%77!% !rBw-!+, ,AAw!ga!en,wq1uqy/AAQUcMQQ5rDrj)Nr:)rr7Nrr7)r7)r;r)&__name__ __module__ __qualname____doc__r_rCr-r$r.rlrnrpryruBPFrvrrr(rr+r)rr/r,rr1r0r&r"r%r r2r!rr'r3r __classcell__)r]s@rBrrns G$LA6B3 (9:3'&-J=%)t'3R&.$/3]~#+tq#+P +12*$L32((TCJ@# 2VrDrc6eZdZdZdZdZdZdZdZexZ Z y)rzAlternate random number generator using sources provided by the operating system (such as /dev/urandom on Unix or CryptGenRandom on Windows). Not available on all systems (see os.urandom() for details). cRtjtddz tzS)z7Get the next random number in the range 0.0 <= X < 1.0.rFr=)rRrS_urandom RECIP_BPFrks rBr*zSystemRandom.randomusx{+q0I==rDc|dkr td|dzdz}tjt|}||dz|z z S)z:getrandbits(k) -> x. Generates an int with k random bits.rz#number of bits must be non-negativerFr)rfrRrSr )r@r}numbytesrAs rBr#zSystemRandom.getrandbitsysI q5BC CEa< NN8H- .X\A%&&rDct|S)r)r rs rBr(zSystemRandom.randbytess{rDcy)z' P*)HxrDrc6ddlm}m}ddlm}|}t d|Dcgc]}|| }}|} ||} ||| } t |} t|} t| |z dd|d|j|td| | | | fzycc}w)Nr)stdevfmean) perf_counterz.3fz sec, z times z"avg %g, stddev %g, min %g, max %g ) statisticsrrtimerrminmaxprintr)r|funcrrmeanrt0rdatat1xbarrrrs rB_test_generatorr$s/! B!(q!1 2!1AD$K!1D 2 B :D $ E d)C t9D R"WSMs'$-- AB /4T2J JK 3s Bcht|tdt|tdt|tdt|tdt|t dt|t dt|t dt|t dt|t dt|t dt|t d t|t d t|t d t|t d t|t d t|tdt|tdt|tdy)Nrbr)g333333?)dg?)rr7)皙?r7)r(r5)rr7)g?r7)r7r7)r5r7)g4@r7)gi@r7)@r))rr7gUUUUUU?) r$r*r&r%r2rr!r"rr0)Ns rB_testr+sAvr"A}j1A~z2A 3A 3A 4A|[1A|Z0A|Z0A|Z0A|Z0A|Z0A|Z0A|[1A|\2Auj)A{J/Az#89rDfork)after_in_child__main__)i')arwarningsrrmathrrrrrrrrrrr rr rr rr rr rrrrrrrrrrrosrr _collections_abcrroperatorrr itertoolsrrrrrr_os_random_sha2rrT ImportErrorhashlib__all__rrrrr rrr_instr-r*r1r0r)rr+r,r/rr&r%r r2r!r"rrr'r3r$r.r#r(r$r+hasattrregister_at_forkrrbrDrBr>s.h#LLGGEE@@"2$B$*'  :DJs+  Cyd3i  #I w W^^w |"*6"*X  zz  --    --  OO  -- --## %% ''!!   ''## %% >> >> OO L":0 3C 3 z G}*))*s H H,+H,__pycache__/pdb.cpython-312.opt-2.pyc000064400000210220152342670510013166 0ustar00 ֦it ddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlmZGddeZgdZdZdZGdd eZGd d eZGd d eZdZGddej:ej<Ze PgdZ!e!D],Z"e e#ede"zj@jIdzz Z .e ejJj@z Z [!["d"dZ&d"dZ'dZ(dZ)dddZ*d#dZ+dZ,dZ-dZ.dZ/dZ0d Z1e2d!k(rddl3Z3e3jbyy)$N)UnionceZdZ y)RestartN)__name__ __module__ __qualname__/usr/lib64/python3.12/pdb.pyrr[sLr r) runpmPdbrunevalrunctxruncall set_trace post_mortemhelpc@tjdtj|z} tj|}|5t |dD]&\}}|j|s|||fccdddS dddy#t $rYywxYw#1swYyxYw)Nzdef\s+%s(\s*\[.+\])?\s*[(])start)recompileescapetokenizeopenOSError enumeratematch)funcnamefilenamecrefplinenolines r find_functionr&bs **2RYYx5HH IC ]]8 $ %b2LFDyy611 2     s)B%B*B:B BBBcttj|}|j|D]\}}||k\s |cSyNr)listdisfindlinestartsreverse)codelasti linestartsir$s r lasti2linenor1osBc((./J 6 A:M  r ceZdZ dZy)_rstrc|SNr selfs r __repr__z_rstr.__repr__zs r N)rrrr8r r r r3r3xs -r r3cTeZdZfdZdZedZedZedZxZ S) _ScriptTargetcpt||tjj |}||_|Sr5)super__new__ospathrealpathorig)clsvalres __class__s r r=z_ScriptTarget.__new__s0goc277#3#3C#89 r ctjj|s,td|jdt j dtjj|r,td|jdt j dtjj|t jd<y)NzError:zdoes not existrzis a directoryr) r>r?existsprintrAsysexitisdirdirnamer6s r checkz_ScriptTarget.checksvww~~d# (DII'7 8 HHQK 77==  (DII'7 8 HHQKggood+ r c|Sr5r r6s r r!z_ScriptTarget.filenames r c(td|tdS)N__main__)r__file__ __builtins____spec__)dictrRr6s r namespacez_ScriptTarget.namespaces%   r ctj|5}d|jd|dcdddS#1swYyxYw)Nz exec(compile(z, z , 'exec')))io open_coderead)r7r#s r r-z_ScriptTarget.codes4 \\$ 2"2779-r$D  s 7A) rrrr=rMpropertyr!rUr- __classcell__)rEs@r r:r:~sK ,  EEr r:cveZdZdZej dZedZedZ edZ edZ y) _ModuleTargetc |jy#t$r-}td|tjdYd}~yd}~wt $r,t jtjdYywxYw)Nz ImportError: r)_details ImportErrorrHrIrJ Exception traceback print_exc)r7es r rMz_ModuleTarget.checksY  MM  M!% & HHQKK     ! HHQK s  A8#A5A87A8c,ddl}|j|Sr()runpy_get_module_details)r7rfs r r_z_ModuleTarget._detailss((..r c.|jjSr5)r- co_filenamer6s r r!z_ModuleTarget.filenamesyy$$$r c&|j\}}}|Sr5r_r7namespecr-s r r-z_ModuleTarget.code==dD r c&|j\}}}|Sr5rkrls r _specz_ModuleTarget._specror ctdtjjtjj |j |j j|j j|j tS)NrP)rrQ __package__ __loader__rSrR) rTr>r?normcaseabspathr!rqparentloaderrRr6s r rUz_ModuleTarget.namespacesYWW%%bggoodmm&DE ))zz((ZZ%   r N) rrrrM functoolscached_propertyr_rZr!r-rqrUr r r r]r]sq//%%  r r]z -> ceZdZdZ dXdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZeZdYdZ dZ!e Z"eZ#eZ$dZ%eZ&d Z'd!Z(d"Z)eZ*d#Z+eZ,d$Z-eZ.d%Z/eZ0d&Z1e1Z2eZ3eZ4d'Z5e5Z6e5Z7d(Z8d)Z9e9Z:d*Z;e;Zd,Z?e?Z@d-ZAeAZBd.ZCeCZDd/ZEeEZFd0ZGeGxZHZId1ZJeJZKd2ZLeZMd3ZNeNZOeNZPd4ZQd5ZReRZSd6ZTeTZUd7ZVdZd8ZWd9ZXd:ZYd;ZZd<Z[d=Z\eZ]eZ^eZ_d>Z`e`Zad?ZbebZcd@ZdeZed[dAZfdBZgeZhdCZieZjdDZkdEZldFZmdGZndHZodIZpgdJZqdKZresfdLZtdMZueuZvdNZwdOZxdPZydQeze{e|ffdRZ}dSe~fdTZdUZdVZdWZy)\rNcFtjj||tjj||||t j d|rd|_d|_i|_ i|_ d|_ d|_ i|_ ddl}|jdd|_||_g|_|r t)t*j,j/dd 5}|j&j1|ddd t)d d 5}|j&j1|dddi|_i|_i|_d|_d|_y#t $rYwxYw#1swYnxYw#t2$rY|wxYw#1swYWxYw#t2$rYewxYw) N)skipzpdb.Pdbrz(Pdb) Fz `@#$%^&*()=+[{]}\|;:'",<>?z~/.pdbrczutf-8)encodingz.pdbrc)bdbBdb__init__cmdCmdrIaudit use_rawinputpromptaliases displaying mainpyfile_wait_for_mainpyfile tb_linenoreadlineset_completer_delimsr` allow_kbdintnosigintrcLinesrr>r? expanduserextendrcommandscommands_dopromptcommands_silentcommands_defining commands_bnum) r7 completekeystdinstdoutr}rreadrcrrcFiles r rz Pdb.__init__sy D) {E6: )  !D   $)!    ) )*M N"    "'',,Z87KvLL''/L (W5LL''/6  !#!!&!5   LK  65  sf E:*E9$E-E9 FF2F E*)E*-E62E99 FFF F F F c|jrt|jd|j|j |y)Nz- Program interrupted. (Use 'cont' to resume).)rKeyboardInterruptmessageset_stepr)r7signumframes r sigint_handlerzPdb.sigint_handler s3   # # EF  ur cbtjj||jyr5)rrresetforgetr6s r rz Pdb.resets  d r cd|_g|_d|_t|dr2|jr&|jj j ddd|_i|_|jjy)Nrcurframe__pdb_convenience_variables) r$stackcurindexhasattrr f_globalspopcurframe_localsrclearr6s r rz Pdb.forgetsa   4 $ MM # # ' '(Et L ! r c|j|j||\|_|_|rRt |j j |j}||j|j <|j}|rR|j|jd|_ |jj|_ |j|jd|j|jrV|jDcgc]3}|jr!|jj!ds|5c}|_g|_yycc}w)Nr_frame#)r get_stackrrr1tb_framef_codetb_lastirtb_nextrf_localsrset_convenience_variablerstrip startswithcmdqueue)r7ftbr$r%s r setupz Pdb.setups $(NN1b$9! DM""++"4"4bkkBF*0DNN2;; 'B  4==1!4  $}}55 %%dmmXt}}M <>% LL $   UD ) !r c |jr:|j|j|jjk7ryd|_|j |r|j |dyy)NF)rrcanonicrri bp_commandsr)r7rs r user_linez Pdb.user_lineBs[I  $ $4<< 0H0H#II(-D %   E "   UD ) #r c t|ddr|j|jvr|j}d|_|j}|j |d|j|D]}|j |||_|j |s(|j|j|j|j|r|j|jyy)N currentbpFrr) getattrrrlastcmdronecmdrprint_stack_entryrrr_cmdloopr)r7rr lastcmd_backr%s r rzPdb.bp_commandsKs  4e ,~~.IDN< tjtjtjdt_|j |||j jd|j|j r,|j ddk(r|j j|jy#t$rYwxYw)N_pdbcmd_print_frame_status) r_previous_sigint_handlersignalSIGINT ValueErrorrrappendrrr)r7rrbs r rzPdb.interactions  ' ' 4 fmmS-I-IJ04, 5)$ 9:  ==T]]2.2NN MM      s2C C! C!c@ ||jt|yyr5)rrepr)r7objs r displayhookzPdb.displayhooks#  ? LLc # r cV|dddk(r|ddj}|j}|jj} t |dzdd}t j }t j}t j} |jt _|j t _|jt _t||||t _|t _|t _y#|t _|t _|t _wxYw#|jYyxYw)Nr! single) rrrrrrIrrrexec _error_exc)r7r%localsglobalsr- save_stdout save_stdinsave_displayhooks r defaultz Pdb.defaults 8s?48>>#3D%%--)) 4$; 8 D d?K$&& z --bkk$.?.H.HI:;7 L%a)lc.A/4c*Lj(Z5::-E%,,l1os1v|-TU J!K 1 E3   tHU38UVZU[[]6^^ _H!2 4 ?+ww{##"" K sAC5/C5C55D  D cd |js|S|j}|d|jvr|j|d}d}|ddD]%}|jdt |z|}|dz }'|jddj |dd}|j}|d|jvr|ddk7r[|j d}|dk\rE||dzdj}|jjd||d|j}|j|}|S) Nrr%z%* aliasz;;) rsplitrreplacestrrfindlstriprinsertrstripr)r7r%argsiitmpArgmarkernexts r precmdz Pdb.precmds08zz|Kzz|1g%<<Q(DBqr(||C#b'M&,.a#<<chhtABx&89D::>$- -**40 0r c |j|\}}}|sy|dk(rd|j|j<y|dk(ry|j|j}|r|j |dz|zn|j | t |d|z}|j|jvrd|j|j<yy#t $r|j}YJwxYw)NFsilentTrr do_) r2rrrrrAttributeErrorr rcommands_resumingr)r7r%rr5cmdlistfuncs r r3zPdb.handle_command_defsF-S$ (?7;D !3!3 4 E\-- 2 23  NN3s73; ' NN3  4-D ==D22 29>D " "4#5#5 6  <r@rAs r errorz Pdb.error<s eSt{{+r cbd|jvri|jd<||jd|<y)Nr)r)r7rrmvalues r rzPdb.set_convenience_variableAs1 ( ?=?EOO9 :?D56tr?rKrisfilelower)r7textr%begidxendidxretglobsfns r _complete_locationzPdb._complete_locationIs ::<  ,I ++D$GC $++d+c12Bww}}R  28$# (;(;O(L 28$    C sC33 DDcttjjDcgc],\}}|%t |j |r t |.c}}Scc}}wr5)rr Breakpoint bpbynumberr%r)r7rRr%rSrTr0bps r _complete_bpnumberzPdb._complete_bpnumber\sV%.cnn.G.G$H?$H51b>c!f&7&7&=A$H? ??s1Ac|jsgSi|jj|j}d|vry|jd} ||d}|ddD]}t ||} dj|dddz} t|D cgc]} | j|ds| | zc} S|jD cgc]} | j|s| c} S#t t f$rgcYSwxYwcc} wcc} w)N.rrr) rrrr#rKeyErrorr9rdirrkeys) r7rRr%rSrTnsdottedrpartrns r rNzPdb._complete_expressioncs }}IA '' @4+?+? @ $;ZZ_F m"1RLD!#t,C)XXfSbk*S0F(+CM1ALL4LFQJM M "wwy?y!ALL,>Ay? ? n-   N@s* C C7&C7C<C< C43C4ct|j|j|j|jyr5)rrrrr7r5s r rzPdb._pdbcmd_print_frame_status~s) tzz$--89 r c |s'ttjjdz }n t |} |j |||_||jvr-|j||j||j|f}nd}g|j|<d|j|<d|j|<|j}d|_ d|_ |jd|_ ||_ y#|j dYyxYw#t$r}|j d|zYd}~yd}~wwxYw#t$rt|r7|d|j|<|d|j|<|d|j|<n'|j|=|j|=|j|=|j d YwxYw#d|_ ||_ wxYw) Nrz.Usage: commands [bnum] ... endzcannot set commands: %sTFz(com) rr"z1command definition aborted, old commands restored)lenrrZr[intrDget_bpbynumberrrrrrrrrr)r7r5bnumerrold_command_defs prompt_backs r do_commandszPdb.do_commandss# Hs~~001A5D 3x     % " 4== $ d 3 $ 6 6t < $ 4 4T : <  $   d'+t$%*T"kk  !% & LLN&+D "%DKO  MN  JJ036 7  *! L&6q&9 d#/?/B&&t,-=a-@$$T*MM$'**40((. JJJ K L&+D "%DKsG C4D D64D  D3D..D36A:F30F62F33F66Gc |s_|jrR|jdtjjD]$}|s|j|j &yd}d}d}|j d}|dkDrT||dzdj}|j|x}r|jd|d|y|d|j}|jd} d} | dk\r`|d| j}|j|} | s|jd|zy| }|| dzdj} t|}n t|}|s|j5}|j7||}|rt|j9||||| }|r|j|y|j;||d }|jd |j<|j>|j@fzyy#t$r|jd |zYywxYw#t$r t||j j"|j$} n #|} YnxYw t'| d r | j(} | j*} | j,} | j.}| j0}nB#|j3|\}}}|s|jd |zYYy|} t|}YnxYwYwxYw)Nz!Num Type Disp Enb WhererIrrInvalid condition rrHz%r not found from sys.pathzBad lineno: %s__func__zJThe specified object %r is not a function or was not found along sys.path.rzBreakpoint %d at %s:%d)!breaksrrrZr[bpformatr&r'_compile_error_messagerDr)rfind lookupmodulerkrevalrrrrrt__code__co_nameco_firstlinenorilineinfo defaultFile checkline set_break get_breaksnumberr?r%)r7r5 temporaryr\r!r$condcommarncolonr rr<r-oklnr%s r do_breakz Pdb.do_breaks {{ @A..33B R[[]34   19uQwx='')D11$77s7 sCDfu+$$&C # A:6E{))+H!!(+A 7(BCeAgh-&&(C S  %S4'')H~~h/ ..4D(KC 3__Xt4R8 5 ii"'':;< I  +c12  % $ 7 7 $ 4 46DD%tZ0#}}==D $||H!00F#//H%)-s);&R2 $FHK$LM!H WF1 %sa? G2 H2HH K$+I  K$ IK$AJK$-K K$ KK$#K$c |jjj}|dk(r|jr |j}|S)Nz)rrrir)r7r!s r rzPdb.defaultFile<s6+==''33 z !dooHr c* |j|dyNr)rrhs r do_tbreakz Pdb.do_tbreakHs c1r cd}|jd}t|dk(r|dj}n$t|dk(r|dj}n|S|dk(r|S|jd}|ddk(r|d=t|dk(r|S|j}t|dk(r|d}n|j |d}|r|}|d}t ||} | xs|S) N)NNN'rrr~r_r7)r#rjrrryr&) r7 identifierfailedidstringidpartsfnameitemranswers r r~z Pdb.lineinfoRs###C( x=A !""$B ]a !""$BM 8F]  8v a5zQ   " u:?8D!!%(+A8DtU+r c t|dd}|r |jnd}tj|||}|s|j dy|j }|r|ddk(s|dddk(s|dddk(r|j dy|S) Nrz End of filerrrz"""z'''zBlank or comment)rr linecachegetlinerrrD)r7r!r$rrVr%s r rz Pdb.checkliness j$/#(d  659 LL 'zz|aC2Ah%D!H$5 JJ) * r c |j}|D]8} |j|}|j|jd|z:y#t$r}|j |Yd}~[d}~wwxYw)Nz Enabled %s)r#rlenablerrrDr7r5r*r0r\rns r do_enablez Pdb.do_enablesn yy{A 0((+  \B./  3 A A4A//A4c |j}|D]8} |j|}|j|jd|z:y#t$r}|j |Yd}~[d}~wwxYw)Nz Disabled %s)r#rldisablerrrDrs r do_disablezPdb.do_disablesn yy{A 1((+  ]R/0  3 rc |jdd} |d}|j|x}r|jd|d|y |j |dj }||_|s|jd|jzy|jd|jzy#t$rd}YwwxYw#t$r|jdYyt$r}|j|Yd}~yd}~wwxYw) Nr rrsrrz#Breakpoint %d is now unconditional.z$New condition set for breakpoint %d.Breakpoint number expected) r#rwrD IndexErrorrlrrrrr)r7r5r*rrnr\s r do_conditionzPdb.do_conditions yya  7D11$77s7 sCD8 Q$$T!W]]_5B BG BRYYNO CbiiOP D  5 JJ3 4  JJsOO s//B0"C0 B>=B>DD%C;;Dc |j} t|dj} |j|dj}||_|dkDr.|dkDrd|z}nd}|j d||j fzy|j d|j zy#d}YxYw#t$r|jdYyt$r}|j|Yd}~yd}~wwxYw)Nrrz %d crossingsz 1 crossingz%Will ignore next %s of breakpoint %d.z-Will stop next time breakpoint %d is reached.r) r#rkrrlignorerrrrDr)r7r5r*countr\countstrrns r do_ignorez Pdb.do_ignores yy{ Q (E *$$T!W]]_5B BIqy19-5H+H D& 234 L!yy)*% E 5 JJ3 4  JJsOO s(B+"B4+B14C3C3C..C3c\ |s td}|jj}|dvrUtj j Dcgc]}|s| }}|j|D]}|jd|zyd|vr|jd}|d|}||dzd} t|}|j||dd}|j||}|r|j|yD]}|jd|zy|j} | D]9} |j!|}|j#||jd|z;y#t$rd}YZwxYwcc}w#t$rd|z}YwxYw#t$r}|j|Yd}~d}~wwxYw)NzClear all breaks? no)yyesz Deleted %srHrzInvalid line number (%s))inputEOFErrorrrQrrZr[clear_all_breaksrrxrkr clear_breakrrDr#rlclear_bpbynumber) r7r5replyr\bplistr0r!r$rn numberlists r do_clearz Pdb.do_clears  23KKM'')E $'*~~'@'@G'@B"'@G%%' BLL!23!  #: #A2AwHacd)C 9S6:1=&&x8 3 !BLL!23! YY[ A 0((+%%a( \B./9  H 7036 7  3 sG EE.E.+ E3#F E+*E+3FF F+F&&F+c& |jyr5)print_stack_tracerhs r do_wherez Pdb.do_where's  r c6||_|j|jd|_|jj|_|j |jd|j|j |j|jd|_y)Nrr)rrrrrrrr$)r7rs r _select_framezPdb._select_frame2sp  4==1!4 #}}55 %%dmmXt}}M tzz$--89 r c |jdk(r|jdy t|xsd}|dkrd}nt d|j|z }|j |y#t$r|jd|zYywxYw)Nrz Oldest framerInvalid frame count (%s))rrDrkrmaxrr7r5rnewframes r do_upz Pdb.do_up;s ==A  JJ~ &  qME 19H1dmme34H 8$  JJ1C7 8  sA&&BBc |jdzt|jk(r|jdy t |xsd}|dkrt|jdz }n/t t|jdz |j|z}|j|y#t $r|jd|zYywxYw)Nrz Newest framerr)rrjrrDrkrminrrs r do_downz Pdb.do_downPs ==1 DJJ / JJ~ &  qME 194::*H3tzz?Q. 0EFH 8$  JJ1C7 8  sB((CCc |r7 t|}||jjkr|jdyd}|j |j|y#t$r|jd|zYywxYw)NError in argument: %rz7"until" line number is smaller than current line numberr)rkrrDrf_lineno set_until)r7r5r$s r do_untilz Pdb.do_untiles   S/// )*F t}}f-  2S89 s AA:9A:c& |jyr)rrhs r do_stepz Pdb.do_step~s r c< |j|jyr)set_nextrrhs r do_nextz Pdb.do_nexts dmm$r c |rEddl}tjdd} |j|t_|tjddt #t$r!}|j d|d|Yd}~yd}~wwxYw)Nrrz Cannot run r)shlexrIargvr#rrDr)r7r5rargv0rds r do_runz Pdb.do_runso   HHQqME  ;;s+!CHHRaL   #q9: sA A9A44A9c< |j|jyr) set_returnrrhs r do_returnz Pdb.do_returns   &r c |js8 tjtj|jt_|jy#t $rYwxYwr)rrrrrrr set_continuerhs r do_continuezPdb.do_continues\ }} MM&--1D1DE,     s7A A#"A#c |jdzt|jk7r|jdy t |} ||j _|j|jd|f|j|j<|j|j|jy#t$r}|jd|zYd}~yd}~wwxYw#t$r|jdYywxYw)Nrz)You can only jump within the bottom framerzJump failed: %sz)The 'jump' command requires a line number) rrjrrDrkrrrr)r7r5rds r do_jumpz Pdb.do_jumps  ==1 DJJ / JJB C  2c(C 2*- &,0JJt}},Ea,H#,M 4==)&&tzz$--'@A 2 ,q011 2 D JJB C Ds* CA.B55 C>CCC<;C<c8 tjd|jj}|j}t |j |j|j}d|jjz|_ |jd tj|j|||f|jdtj|j |j"|_y#t$r|jY]wxYw)Nz(%s) zENTERING RECURSIVE DEBUGGERzLEAVING RECURSIVE DEBUGGER)rIsettracerrrrrrrrrr call_tracingr rartrace_dispatchr)r7r5rrps r do_debugz Pdb.do_debugs T--))%%   $**dkk :T[[..00 23    QUUS'6$: ; 12 T(()yy   OO  s#C==DDc4 d|_|jy)NTr)_user_requested_quitset_quitrhs r do_quitz Pdb.do_quits %)! r cV |jdd|_|jy)Nr~Tr)rrrrhs r do_EOFz Pdb.do_EOFs)  R$(! r c  |jj}|j}|j|jz}|j t jzr|dz}|j t jzr|dz}t|D]S}|j|}||vr*|j|d|j|||@|j|dUy)Nr = z = *** undefined ***) rrr co_argcountco_kwonlyargcountco_flagsinspect CO_VARARGSCO_VARKEYWORDSrange co_varnamesrr)r7r5corTrfr0rms r do_argsz Pdb.do_argss ]] ! !## NNR11 1 ;;++ +1Q ;;// /QqSqA>>!$Dt| $T D0QRS ?@ r c d|jvr/|j|j|jddy|jdy)NrretvalzNot yet returned!)rrrrDrhs r do_retvalz Pdb.do_retval"sF  4// / LL)=)=l)KXV W JJ* +r c t||jj|jS#|j xYwr5)rzrrrrrhs r _getvalz Pdb._getval-s: T]]44d6J6JK K  OO  s *-Ac |+t||jj|jSt||j|jS#t $r'}t d|j|zcYd}~Sd}~wwxYw)Nz** raised %s **)rzrrrr BaseExceptionr3r)r7r5rexcs r rzPdb._getval_except4sq D}C!8!8$:N:NOOC%..AA D*T-=-=c-BBC C Ds",A A BA;5B;Bcltj}|j|j|yr5)rI exceptionrDrr7rs r rzPdb._error_exc=s$mmo 4##C()r c |j|} |j||y#YyxYw#|jYyxYwr5)rrr)r7r5r<rCs r _msg_val_funczPdb._msg_val_funcAsD ,,s#C  LLc #    OO s,30Ac  t|S#t$r+}td|d|j|dcYd}~Sd}~wwxYw)Nz *** repr(z ) failed: z ***)rrar3r)r7rrrds r rzPdb._safe_reprKsJ P9  P9TF*T5E5Ea5H4INO O Ps A <AAc2 |j|tyr5)rrrhs r do_pzPdb.do_pQs  3%r cF |j|tjyr5)rpprintpformatrhs r do_ppz Pdb.do_ppXs  3/r c" d|_d}|r|dk7r d|vrQ|jd\}}t|j}t|j}||kr.||z}n(t|j}t d|dz }nD|j|dk(r$t d|jjdz }n|jdz}||dz}|jjj}|jdr7|jjjd }t|t r|}|j#|} t%j&||jj}|j)||dz ||||jt+|t-||_t-||kr|j/d yy#t $r|j d|zYywxYw#t0$rYywxYw) Nr)r_rIrr zG? H Hc0 |jjj}|j|} |j |j\}}|j||||jy#t $r}|j |Yd}~yd}~wwxYwr5)rrrir_getsourcelinesrrDr)r7r5r!rrr$rns r do_longlistzPdb.do_longlists ==''33((2   00?ME6 %DMMB  JJsO  sA11 B:BBc |j|} |j|\}}|j ||y#YyxYw#ttf$r}|j |Yd}~yd}~wwxYwr5)rrr TypeErrorrDr)r7r5rrr$rns r do_sourcez Pdb.do_sourcess  ,,s#C  005ME6 %(  #  JJsO  s <AAA-A((A-cx |r)|j}|jj|d}ndx}}t||D]{\}}t |j d} t | dkr| dz } ||vr| dz } n| dz } ||k(r| dz } n ||k(r| dz } |j| dz|jz}y) Nrrr Bz->z>> ) rrrrr%rjustrjrr)) r7rrrurcurrent_lineno exc_linenor$r%ss r rzPdb._print_liness% "^^N++E26J*, ,NZ%eU3LFDF !!!$A1vzSSS'T :%T  LLTDKKM1 24r c |j|}d} |jj}|r|j d|j zy |j}|r|j d|j zy|j tur,|j d|jd|jy|j t|y#YyxYw#t$rYwxYw#t$rYwxYw)Nz Method %sz Function %szClass r_) rrtr{rarr|rEtyperr)r7r5rFr-s r do_whatisz Pdb.do_whatiss  LL%E >>**D  LLt||3 4  >>D  LL5 6  ??d " LL%*:*:E$,,++-.D %e1DEF  t9>Aw$,,& $q'4<<Q3HIJ _T!WIQ78$'HHT!"X$6DLLa !r c |j}t|dk(ry|d|jvr|j|d=yyr()r#rjr)r7r5r*s r do_unaliaszPdb.do_unaliasRsF yy{ t9>6 7dll " T!W% #r cd|jDcgc]}|j|s|c}Scc}wr5)rr)r7rRr%rSrTas r complete_unaliaszPdb.complete_unalias\s)<<>>>s--)rrrrrrch |jD]}|j|y#t$rYywxYwr5)rrr)r7 frame_linenos r rzPdb.print_stack_traceks5  $ &&|4!+    s "% 11c||\}}||jurd}nd}|j||j||zy)Nz> z )rrformat_stack_entry)r7r? prompt_prefixrr$rs r rzPdb.print_stack_entryrsF$ v DMM !FF V,,\=IJ Kr c |s tjj||S t|d|z}|S#t$rt|d|z}YnwxYw t j jdk\r|jd|zy|j|jd|zy|j|j|jy#t$r|jd|zYywxYw)Nhelp_r8r"zJNo help for %r; please do not run Python with -OO if you need command helpz&No help for %r; __doc__ string missingzNo help for %r) rrdo_helprr9rIflagsoptimizerD__doc__r_help_message_from_doc)r7r5topicr4s r rEz Pdb.do_help}s 77??4- - G 5gm4w! 5!$ 4 5yy!!Q& 68;<=& CcIJ LL44W__E F / JJ'#- . /s'<ACACC98C9ct |j|jjxsdjy)Nr~)r help_execrHrr6s r rLz Pdb.help_execs-  dnn,,299;r?isabsrGrrIrrsplitextislinkreadlink)r7r!rrootextrLfullnames r ryzPdb.lookupmodules 77== "x(@O GGLL!h / GGNN1 $,,q/T__"DHGG$$X. c "9%'H 77== "OxxG''..)++g.''..)ww||GX6Hww~~h'  r targetcd|_d|_|j|j|_ddl}|j j|j j|j|j|jy)NTFr) rrrr!rrP__dict__rupdaterUr r-)r7rWrPs r _runzPdb._runsi %)!$)!,,v7 !  !1!12 r rcNtj|djS)Nr)rbformat_exception_onlyrrs r rzPdb._format_excs!..s3B7==??r c t|ddy#t$r$}t|j|cYd}~Sd}~wwxYw)Nrrzr~)r SyntaxErrorr3r)r7rrs r rwzPdb._compile_error_messagesCK 0 D)V , 0))#./ / 0s  >9>>cRtj|\}}td|}||fSr)rgetsourcelinesr)r7rrr$s r rzPdb._getsourceliness-  ..s3 vQf}r c|jjDcgc]}|j}}|syd|vr|jd}nd}g}dt |j z}t |D].\}}|dk(rd}n ||krd}nd}|j||z|z0dj|Scc}w) NzNo help message found.r~rr rzUsage: z r) r) splitlinesrindexrjrrrr) r7docr%r usage_end formattedindentr0rs r rIzPdb._help_message_from_docs*-**,*A*A*CD*C$*CD+ ; BII s4;;'' 'GAtAv"Y"   Vf_t3 4(yy###EsB<)tabNNNFT)rr5)r N)rrrrrrrrrrrrrrrrrrr rr/rr3rrDrrXr]rNrrqcomplete_commandsrrdo_bcomplete_break complete_brcomplete_tbreakr~rrcomplete_enablercomplete_disablercomplete_conditionrcomplete_ignorerdo_clcomplete_clear complete_clrdo_wdo_btrrdo_urdo_drdo_untrdo_srdo_nr do_restartrdo_rrdo_cdo_contrdo_jrcomplete_debugrdo_qdo_exitrrdo_ardo_rvrrrrrrr complete_print complete_p complete_pprdo_lrdo_llrcomplete_sourcerr)complete_whatisr-complete_displayr/r1r5r8r:r=r:r line_prefixrrEdo_hrLrNryrr]r:r[rrrwrrIr r r rrs#HL(,,"^4**0&/( 6 D,$*$B:1 8%, E&?@6Q&f+^(@}@$r r)"rwheredownupbreaktbreakrrrr conditionrstepr.untiljumpreturnrr continuer)longlistr*rppwhatissourcedisplay undisplayr4r!unaliasdebugquitr8z c< tj|||yr5)rr  statementrrs r r r s EIIi&)r c: tj|||Sr5)rr) expressionrrs r rr)s 5==Wf 55r ct|||yr5)r rs r rr2s 7F#r c8 tj|i|Sr5)rr)r*kwdss r rr6s! 35==$ '$ ''r )headerc t}||j||jtjj yr5)rrrrI _getframef_back)rpdbs r rr@s> %C  FCMM#--/(()r c |"tj}| |j}| tdt }|j |j d|y)NzAA valid traceback must be passed if no exception is being handled)rIr __traceback__rrrr)rrrs r rrOs` ymmo ?!!Ay67 7 AGGIMM$r c ttdrtjj}ntj}t |y)Nlast_exc)rrIrrlast_tracebackr)rs r r r ds0SsJ \\ ' '   Or zimport x; x.main()c"ttyr5)r TESTCMDr r r testrqs Lr c6ddl}|jtyr()pydocpagerrH)rs r rrus KKr ausage: pdb.py [-c command] ... [-m module | pyfile] [arg] ... Debug the Python program given by pyfile. Alternatively, an executable module or package to debug can be specified using the -m switch. Initial commands are read from .pdbrc files in your home directory and in the current directory, if they exist. Commands supplied with -c are executed after commands from .pdbrc files. To let the script run until an exception occurs, use "-c continue". To let the script run up to a given line X in the debugged file, use "-c 'until X'".c ddl}|jtjdddddg\}}|s$tttj dt d|Dr#tttj |Dcgc] \}}|dvs |}}}t d |D}|rtnt}||d}|j|tjddt} | jj| | j|| jrytd ,cc}}w#t$r>td |d td dj!tjddzYMt"$r"} tddt| Yd} ~ rd} ~ wt$$r,t'j(tj dYt*$re} t'j(tdtd| j,} | j.d| td|zdzYd} ~ d} ~ wwxYw)Nrrzmhc:rzcommand=r"c3*K|] \}}|dv yw))z-hz--helpNr .0optoptargs r zmain..s ;d{sF3" "d)z-cz --commandc3*K|] \}}|dv yw))z-mNr rs r rzmain..sAD[S&3&=Drz*The program finished and will be restarted Restartingzwith arguments:r"r z/The program exited via sys.exit(). Exit status:)rz2Uncaught exception. Entering post mortem debuggingz1Running 'cont' or 'step' will restart the programz#Post mortem debugger finished. The z will be restarted)getoptrIrrH_usagerJanyr]r:rMrrrr[rrr SystemExitr_rbrcrrr) roptsr*rrrmodule_indicatedrBrWrrdrs r mainrssxx|Vfj5IJJD$  f    ;d ;; f   *.M$;3#9L2L$HMADAA+-C a\F LLNCHHQK %CKKx  ( CHHV '' > ? !N, 1 ,(9 : $#((12,// 0  C M !HH     ! HHQK (    ! F G E FA COOD! $ 7&@&' ( (  (sD EEE6 EAIIF335I*I2AIIrP)NNr5)4r>rWrrIrrr*r-rOrr rrrryrbrtypingrrar__all__r&r1r%r3r:r]rrrrrH _help_order_commandrrrLr rrrrrr rrrrrrrr r r rsi?F  i  "  C %EC%EP' C' ^ l$#''377l$`1 K 73 0199??AFJJ  s}}$$$GX *6$( **   4(p z CHHJr __pycache__/sre_constants.cpython-312.pyc000064400000001172152342670510014352 0ustar00 ֦i ddlZejdededddlmZeje ejDcic]\}}|dddk7s||c}}ycc}}w)Nzmodule z is deprecated) stacklevel) _constants__) warningswarn__name__DeprecationWarningrer_globalsupdatevarsitems)kvs00&/usr/lib64/python3.12/sre_constants.pyrsl  |>2  47==?D?41aaetm!Q$?DEDs A, A, __pycache__/lzma.cpython-312.opt-1.pyc000064400000036761152342670510013403 0ustar00 ֦i3 dZgdZddlZddlZddlZddlddlmZmZddlZdZ dZ dZ Gdd ejZ ddd dddddd d Zed ddfd ZeddfdZy)aSInterface to the liblzma compression library. This module provides a class for reading and writing compressed files, classes for incremental (de)compression, and convenience functions for one-shot (de)compression. These classes and functions support both the XZ and legacy LZMA container formats, as well as raw compressed data streams. )$ CHECK_NONE CHECK_CRC32 CHECK_CRC64 CHECK_SHA256 CHECK_ID_MAX CHECK_UNKNOWN FILTER_LZMA1 FILTER_LZMA2 FILTER_DELTA FILTER_X86 FILTER_IA64 FILTER_ARMFILTER_ARMTHUMBFILTER_POWERPC FILTER_SPARC FORMAT_AUTO FORMAT_XZ FORMAT_ALONE FORMAT_RAWMF_HC3MF_HC4MF_BT2MF_BT3MF_BT4 MODE_FAST MODE_NORMALPRESET_DEFAULTPRESET_EXTREMELZMACompressorLZMADecompressorLZMAFile LZMAErroropencompress decompressis_check_supportedN)*)_encode_filter_properties_decode_filter_propertiesceZdZdZdddddddZdZedZdZd Z d Z d Z dd Z dd Z ddZddZdZej$fdZdZy)r a@A file object providing transparent LZMA (de)compression. An LZMAFile can act as a wrapper for an existing file object, or refer directly to a named file on disk. Note that LZMAFile provides a *binary* file interface - data read is returned as bytes, and data to be written must be given as bytes. Nformatcheckpresetfilterscd|_d|_t|_|dvr,|dk7r t d| t d|t }t }nH|dvr*|t}t}t|||||_ d |_ nt d j|t|ttt j"fr3d |vr|d z }t%j&|||_d |_||_n2t)|d s t)|dr||_||_n t+d|jt k(rGt-j.|jt0t2||}t5j6||_yy)aOpen an LZMA-compressed file in binary mode. filename can be either an actual file name (given as a str, bytes, or PathLike object), in which case the named file is opened, or it can be an existing file object to read from or write to. mode can be "r" for reading (default), "w" for (over)writing, "x" for creating exclusively, or "a" for appending. These can equivalently be given as "rb", "wb", "xb" and "ab" respectively. format specifies the container format to use for the file. If mode is "r", this defaults to FORMAT_AUTO. Otherwise, the default is FORMAT_XZ. check specifies the integrity check to use. This argument can only be used when opening a file for writing. For FORMAT_XZ, the default is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not support integrity checks - for these formats, check must be omitted, or be CHECK_NONE. When opening a file for reading, the *preset* argument is not meaningful, and should be omitted. The *filters* argument should also be omitted, except when format is FORMAT_RAW (in which case it is required). When opening a file for writing, the settings used by the compressor can be specified either as a preset compression level (with the *preset* argument), or in detail as a custom filter chain (with the *filters* argument). For FORMAT_XZ and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset level. For FORMAT_RAW, the caller must always specify a filter chain; the raw compressor does not support preset compression levels. preset (if provided) should be an integer in the range 0-9, optionally OR-ed with the constant PRESET_EXTREME. filters (if provided) should be a sequence of dicts. Each dict should have an entry for "id" indicating ID of the filter, plus additional entries for options to the filter. NF)rrbr-zACannot specify an integrity check when opening a file for readingzICannot specify a preset compression level when opening a file for reading)wwbaabxxbr.r&zInvalid mode: {!r}bTreadwritez6filename must be a str, bytes, file or PathLike object)trailing_errorr/r2)_fp_closefp _MODE_CLOSED_mode ValueErrorr _MODE_READr _MODE_WRITEr _compressor_posr/ isinstancestrbytesosPathLikebuiltinsr"hasattr TypeError _compressionDecompressReaderrr!ioBufferedReader_buffer) selffilenamemoder/r0r1r2 mode_coderaws /usr/lib64/python3.12/lzma.py__init__zLZMAFile.__init__1skX ! ; { "CDD! "IJJ~$"I 6 6~"#I-V55;W ND DI188>? ? heR[[ 9 :$ }}Xt4DH DM"DJ Xv &'(G*DDH"DJTU U :: #//:J(JC,,S1DL $c|jtk(ry |jtk(r"|jj d|_nM|jt k(r:|j j|jjd|_ |jr|j j d|_d|_ t|_y#d|_d|_ t|_wxYw# |jr|j j d|_d|_ t|_w#d|_d|_ t|_wxYwxYw)zFlush and close the file. May be called more than once without error. Once the file is closed, any other operation on it will raise a ValueError. NF) rCrBrErUcloserFr@r>rGflushrArVs r[r_zLZMAFile.closes :: %  *zzZ' ""$# {*t//5578#'  *==HHNN$ % )   % )  *==HHNN$ % )   % ) s0BC7&CC47E9&D9E9EEc(|jtk(S)zTrue if this file is closed.)rCrBras r[closedzLZMAFile.closedszz\))r]cV|j|jjS)z3Return the file descriptor for the underlying file.)_check_not_closedr@filenoras r[rfzLZMAFile.filenos  xx  r]cZ|jxr|jjS)z)Return whether the file supports seeking.)readablerUseekableras r[rizLZMAFile.seekables }}:4<<#8#8#::r]cH|j|jtk(S)z/Return whether the file was opened for reading.)rerCrEras r[rhzLZMAFile.readables  zzZ''r]cH|j|jtk(S)z/Return whether the file was opened for writing.)rerCrFras r[writablezLZMAFile.writables  zz[((r]cX|j|jj|S)zReturn buffered data without advancing the file position. Always returns at least one byte of data, unless at EOF. The exact number of bytes returned is unspecified. )_check_can_readrUpeekrVsizes r[roz LZMAFile.peeks' ||  &&r]cX|j|jj|S)zRead up to size uncompressed bytes from the file. If size is negative or omitted, read until EOF is reached. Returns b"" if the file is already at EOF. )rnrUr=rps r[r=z LZMAFile.reads% ||  &&r]c|j|dkrtj}|jj |S)zRead up to size uncompressed bytes, while trying to avoid making multiple reads from the underlying stream. Reads up to a buffer's worth of data if size is negative. Returns b"" if the file is at EOF. r&)rnrSDEFAULT_BUFFER_SIZErUread1rps r[ruzLZMAFile.read1s7  !8))D||!!$''r]cX|j|jj|S)a Read a line of uncompressed bytes from the file. The terminating newline (if present) is retained. If size is non-negative, no more than size bytes will be read (in which case the line may be incomplete). Returns b'' if already at EOF. )rnrUreadlinerps r[rwzLZMAFile.readlines% ||$$T**r]c.|jt|ttfr t |}nt |}|j }|jj|}|jj||xj|z c_ |S)aWrite a bytes object to the file. Returns the number of uncompressed bytes written, which is always the length of data in bytes. Note that due to buffering, the file on disk may not reflect the data written until close() is called. ) _check_can_writerIrK bytearraylen memoryviewnbytesrGr#r@r>rH)rVdatalength compresseds r[r>zLZMAFile.writesv  dUI. /YFd#D[[F%%..t4  z" V  r]cZ|j|jj||S)aChange the file position. The new position is specified by offset, relative to the position indicated by whence. Possible values for whence are: 0: start of stream (default): offset must not be negative 1: current stream position 2: end of stream; offset must not be positive Returns the new file position. Note that seeking is emulated, so depending on the parameters, this operation may be extremely slow. )_check_can_seekrUseek)rVoffsetwhences r[rz LZMAFile.seeks' ||  00r]c|j|jtk(r|jj S|j S)z!Return the current file position.)rerCrErUtellrHras r[rz LZMAFile.tells7  :: #<<$$& &yyr])Nr4)r-)__name__ __module__ __qualname____doc__r\r_propertyrcrfrirhrlror=rurwr>rSSEEK_SETrrr]r[r r &svS2BtTS2j*0**! ;( ) '' (+*#%++1$r]r r-)r/r0r1r2encodingerrorsnewlinec(d|vrd|vr5td|| td| td| td|jdd} t|| ||||} d|vr-tj|}tj | |||S| S) aOpen an LZMA-compressed file in binary or text mode. filename can be either an actual file name (given as a str, bytes, or PathLike object), in which case the named file is opened, or it can be an existing file object to read from or write to. The mode argument can be "r", "rb" (default), "w", "wb", "x", "xb", "a", or "ab" for binary mode, or "rt", "wt", "xt", or "at" for text mode. The format, check, preset and filters arguments specify the compression settings, as for LZMACompressor, LZMADecompressor and LZMAFile. For binary mode, this function is equivalent to the LZMAFile constructor: LZMAFile(filename, mode, ...). In this case, the encoding, errors and newline arguments must not be provided. For text mode, an LZMAFile object is created, and wrapped in an io.TextIOWrapper instance with the specified encoding, error handling behavior, and line ending(s). tr<zInvalid mode: z0Argument 'encoding' not supported in binary modez.Argument 'errors' not supported in binary modez/Argument 'newline' not supported in binary moder.)rDreplacer rS text_encoding TextIOWrapper) rWrXr/r0r1r2rrrlz_mode binary_files r[r"r"s4 d{ $;49: :  OP P  MN N  NO Oll3#G8WV5"(';K d{##H- XvwGGr]cbt||||}|j||jzS)zCompress a block of data. Refer to LZMACompressor's docstring for a description of the optional arguments *format*, *check*, *preset* and *filters*. For incremental compression, use an LZMACompressor instead. )rr#r`)r~r/r0r1r2comps r[r#r#?s. &% 9D ==  --r]cg} t|||} |j|}|j||js td|j }|snWdj |S#t$r|rYwxYw)zDecompress a block of data. Refer to LZMADecompressor's docstring for a description of the optional arguments *format*, *check* and *filters*. For incremental decompression, use an LZMADecompressor instead. zACompressed data ended before the end-of-stream marker was reachedr])rr$r!appendeof unused_datajoin)r~r/memlimitr2resultsdecompress r[r$r$KsG !&(G< ##D)C szz?@ @!!   88G    sA,, A;9A;)r5)r__all__rNrSrL_lzmar(r)rQrBrErF BaseStreamr r"rr#rr$rr]r[rs  F   f|&&fR-BtTtT-`$2dD .($r]__pycache__/numbers.cpython-312.pyc000064400000033221152342670510013140 0ustar00 ֦i,dZddlmZmZgdZGddeZGddeZejeGd d eZ e je Gd d e Z Gd de Z e je y)z~Abstract Base Classes (ABCs) for numbers, according to PEP 3141. TODO: Fill out more detailed documentation on the operators.)ABCMetaabstractmethod)NumberComplexRealRationalIntegralceZdZdZdZdZy)rzAll numbers inherit from this class. If you just want to check if an argument x is a number, without caring what kind, use isinstance(x, Number). N)__name__ __module__ __qualname____doc__ __slots____hash__r /usr/lib64/python3.12/numbers.pyrr%s IHrr) metaclassc:eZdZdZdZedZdZeedZ eedZ edZ edZ ed Z ed Zd Zd Zed ZedZedZedZedZedZedZedZedZy)rafComplex defines the operations that work on the builtin complex type. In short, those are: a conversion to complex, .real, .imag, +, -, *, /, **, abs(), .conjugate, ==, and !=. If it is given heterogeneous arguments, and doesn't have special knowledge about them, it should fall back to the builtin complex type as described below. r cy)z, and >=. Real also provides defaults for the derived operations. r ct)zTAny Real can be converted to a native float object. Called for float(self).rrs r __float__zReal.__float__ "!rct)aKtrunc(self): Truncates self to an Integral. Returns an Integral i such that: * i > 0 iff self > 0; * abs(i) <= abs(self); * for any Integral j satisfying the first two conditions, abs(i) >= abs(j) [i.e. i has "maximal" abs among those]. i.e. "truncate towards 0". rrs r __trunc__zReal.__trunc__s "!rct)z$Finds the greatest Integral <= self.rrs r __floor__zReal.__floor__r'rct)z!Finds the least Integral >= self.rrs r__ceil__z Real.__ceil__r'rNct)zRounds self to ndigits decimal places, defaulting to 0. If ndigits is omitted or None, returns an Integral, otherwise returns a Real. Rounds half toward even. r)rndigitss r __round__zReal.__round__r rc||z||zfS)zdivmod(self, other): The pair (self // other, self % other). Sometimes this can be computed faster than the pair of operations. r r$s r __divmod__zReal.__divmod__s  te|,,rc||z||zfS)zdivmod(other, self): The pair (other // self, other % self). Sometimes this can be computed faster than the pair of operations. r r$s r __rdivmod__zReal.__rdivmod__s  ut|,,rct)z)self // other: The floor() of self/other.rr$s r __floordiv__zReal.__floordiv__r'rct)z)other // self: The floor() of other/self.rr$s r __rfloordiv__zReal.__rfloordiv__r'rct)z self % otherrr$s r__mod__z Real.__mod__r'rct)z other % selfrr$s r__rmod__z Real.__rmod__r'rct)zRself < other < on Reals defines a total ordering, except perhaps for NaN.rr$s r__lt__z Real.__lt__rJrct)z self <= otherrr$s r__le__z Real.__le__ r'rc*tt|S)z(complex(self) == complex(float(self), 0))complexfloatrs rrzReal.__complex__suT{##rc|S)z&Real numbers are their real component.r rs rrz Real.real u rcy)z)Real numbers have no imaginary component.rr rs rr"z Real.imagrc|S)zConjugate is a no-op for Reals.r rs rrCzReal.conjugates u rN)r r rrrrrIrLrNrPrSrUrWrYr[r]r_rarcrrFrr"rCr rrrrs$I""  " """""""--"""""""""" "" $rrcNeZdZdZdZeedZeedZdZ y)rz6.numerator and .denominator should be in lowest terms.r ctrlrrs r numeratorzRational.numerator)r'rctrlrrs r denominatorzRational.denominator.r'rcXt|jt|jz S)a float(self) = self.numerator / self.denominator It's important that this conversion use the integer's "true" division rather than casting one side to float before dividing so that ratios of huge integers convert without overflowing. )introrqrs rrIzRational.__float__4s#4>>"S)9)9%:::rN) r r rrrrFrrorqrIr rrrr$sE@I """";rrceZdZdZdZedZdZeddZedZ edZ ed Z ed Z ed Z ed Zed ZedZedZedZedZdZedZedZy)r zIntegral adds methods that work on integral numbers. In short, these are conversion to int, pow with modulus, and the bit-string operations. r ct)z int(self)rrs r__int__zIntegral.__int__Hr'rct|S)z6Called whenever an index is needed, such as in slicing)rsrs r __index__zIntegral.__index__Ms 4yrNct)a4self ** exponent % modulus, but maybe faster. Accept the modulus argument if you want to support the 3-argument version of pow(). Raise a TypeError if exponent < 0 or any argument isn't Integral. Otherwise, just implement the 2-argument version described in Complex. r)rr;moduluss rr<zIntegral.__pow__Qs "!rct)z self << otherrr$s r __lshift__zIntegral.__lshift__\r'rct)z other << selfrr$s r __rlshift__zIntegral.__rlshift__ar'rct)z self >> otherrr$s r __rshift__zIntegral.__rshift__fr'rct)z other >> selfrr$s r __rrshift__zIntegral.__rrshift__kr'rct)z self & otherrr$s r__and__zIntegral.__and__pr'rct)z other & selfrr$s r__rand__zIntegral.__rand__ur'rct)z self ^ otherrr$s r__xor__zIntegral.__xor__zr'rct)z other ^ selfrr$s r__rxor__zIntegral.__rxor__r'rct)z self | otherrr$s r__or__zIntegral.__or__r'rct)z other | selfrr$s r__ror__zIntegral.__ror__r'rct)z~selfrrs r __invert__zIntegral.__invert__r'rc*tt|S)zfloat(self) == float(int(self)))rfrsrs rrIzIntegral.__float__sSYrc|S)z"Integers are their own numerators.r rs rrozIntegral.numeratorrhrcy)z!Integers have a denominator of 1.r rs rrqzIntegral.denominatorrjrrl)r r rrrrrvrxr<r|r~rrrrrrrrrrIrFrorqr rrr r ?sB I""""""""""""""""""""""""""  rr N)rabcrr__all__rrregisterrerrfrr rsr rrrs@:( ? w (n"fn"`s7sj e;t;6axaF #r__pycache__/ftplib.cpython-312.opt-2.pyc000064400000077271152342670510013722 0ustar00 ֦i ddlZddlZddlmZgdZdZdZdZGddeZGd d eZ Gd d eZ Gd deZ GddeZ ee efZdZdZGddZ ddlZej(ZGddeZej/dee eej0fZdadZdadZdZdZdZ ddZ!dZ"e#dk(re"yy#e$rdZY1wxYw) N)_GLOBAL_DEFAULT_TIMEOUT)FTP error_reply error_temp error_perm error_proto all_errors c eZdZy)ErrorN__name__ __module__ __qualname__/usr/lib64/python3.12/ftplib.pyrr9rrc eZdZy)rNrrrrrr:rrrc eZdZy)rNrrrrrr;rrrc eZdZy)rNrrrrrr<rrrc eZdZy)rNrrrrrr=rrr s cVeZdZ dZdZeZeZdZ dZ dZ dZ dZ ddddedfdddZd Zd Zd1d Zd Zd ZeZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$d2dZ%d2dZ&d3dZ'd4d Z(d2d!Z)d5d"Z*d2d#Z+d$Z,d%Z-d&Z.dgfd'Z/d(Z0d)Z1d*Z2d+Z3d,Z4d-Z5d.Z6d/Z7d0Z8y)6rrNTFutf-8encodingc ||_||_||_|r(|j||r|j |||yyyN)r source_addresstimeoutconnectlogin)selfhostuserpasswdacctr$r#r s r__init__z FTP.__init__msK ! ,  LL  4. rc|Sr"rr's r __enter__z FTP.__enter__}s rc|j/ |j|j|j yyy#ttf$rY0wxYw#|j|j wwxYwr")sockquitOSErrorEOFErrorclose)r'argss r__exit__z FTP.__exit__sm 99  ! 99(JJL) !X&  99(JJL)s!=A AAAA1cZ |dk7r||_|dkDr||_|dk7r||_|j|js td|||_t j d||j|jtj|j|jf|j|j|_ |jj|_ |jjd|j|_|j|_|j S) Nrrz0Non-blocking socket (timeout=0) is not supportedzftplib.connectr#rr)r(portr$ ValueErrorr#sysauditsocketcreate_connectionr1familyafmakefiler filegetrespwelcome)r'r(r<r$r#s rr%z FTP.connects  2:DI !8DI d?"DL << #DLLOP P  %"0D  "D$))TYY?,,dii-CT\\<@> +t}}T\\: ;||rc ||_yr")rI)r'levels rset_debuglevelzFTP.set_debuglevels H rc ||_yr") passiveserver)r'vals rset_pasvz FTP.set_pasvs 7!rc|dddvr.t|jd}|ddd|dz zz||dz}t|S)N>pass PASS r*)lenrstriprepr)r'sis rrKz FTP.sanitizesP Ra5& &AHHV$%A"1QqS !AabE)AAwrc&d|vsd|vr tdtjd|||tz}|jdkDrt d|j ||jj|j|jy)N  z4an illegal newline character should not be containedzftplib.sendcmdr z*put*) r=r>r?CRLFrIrJrKr1sendallencoder r'lines rputlinez FTP.putliness 4<44<ST T "D$/d{ >>A  '4==. / $++dmm45rct|jrtd|j||j|y)Nz*cmd*)rIrJrKrfrds rputcmdz FTP.putcmds' >>5$--*=> Trc`|jj|jdz}t||jkDrt d|jz|j dkDrt d|j||st|ddtk(r|dd}|S|ddtvr|dd}|S)Nr got more than %d bytesz*get*) rEreadlinemaxlinerYrrIrJrKr4rards rgetlinez FTP.getlinesyy!!$,,"23 t9t|| #04<<?@ @ >>A  '4==. /N 9 9D "#Y$ 9D rc|j}|dddk(r2|dd} |j}|d|zz}|dd|k(r |dddk7r |S,|S)N-r`)ro)r'recodenextlines r getmultilinezFTP.getmultilinesr||~ !9 8D<<>th/BQ<4' 1 ,   rc|j}|jrtd|j||dd|_|dd}|dvr|S|dk(r t ||dk(r t |t|)Nz*resp*rqr >12345)rvrIrJrKlastresprrr)r'respcs rrFz FTP.getresps~  " >> (DMM$/ 0Ra !H  K 8T" " 8T" "$rcN |j}|dddk7r t||S)Nr ry)rFrr'r~s rvoidrespz FTP.voidresps-3||~ 8s?d# # rc dtz}|jdkDrtd|j||jj |t |j}|dddvr t||S)NABORr z *put urgent*rq225226426) B_CRLFrIrJrKr1rbMSG_OOBrvrr'rer~s rabortz FTP.abortst D >>A  .$--"5 6 $(  " 80 0d# # rcF |j||jSr")rhrFr'cmds rsendcmdz FTP.sendcmds5 C||~rcF |j||jSr")rhrrs rvoidcmdz FTP.voidcmdsF C}}rc |jd}t|dzt|dzg}||z}ddj|z}|j|S)N.zPORT ,)splitr[joinr)r'r(r<hbytespbytesbytesrs rsendportz FTP.sendport sZ CtSy/4S>2'||C  rc  d}|jtjk(rd}|jtjk(rd}|dk(r t ddt ||t |dg}ddj |z}|j|S)Nrr zunsupported address familyrzEPRT |)rCr@AF_INETAF_INET6rr[rr)r'r(r<rCfieldsrs rsendeprtz FTP.sendeprt*sS  77fnn $B 77foo %B 7:; ;d2hd4j"5((||C  rc tjd|jd}|jd}|jjd}|jtj k(r|j ||}n|j||}|jtur|j|j|S)N)rrr )rBbacklogr) r@ create_serverrC getsocknamer1rrrr$r settimeout)r'r1r<r(r~s rmakeportz FTP.makeport7sA##GDGGQG!!$yy$$&q) 77fnn $==t,D==t,D <<6 6 OODLL ) rcR |jtjk(rPt|j d\}}|j r|}||fS|j jd}||fSt|j d|j j\}}||fS)NPASVrEPSV) rCr@rparse227rtrust_server_pasv_ipv4_addressr1 getpeernameparse229)r'untrusted_hostr<r(s rmakepasvz FTP.makepasvDsJ 77fnn $#+DLL,@#A ND22% Tzyy,,.q1Tz"$,,v"6 8M8M8OPJD$Tzrc d}|jr|j\}}tj||f|j|j } ||j d|z|j |}|ddk(r|j}|ddk7r t|n|j5}||j d|z|j |}|ddk(r|j}|ddk7r t||j\}} |jtur|j|jddddddk(r t|}|fS#|jxYw#1swY6xYw)Nr:zREST %srryrxrq150)rQrr@rAr$r#rrFrr5racceptrrparse150) r'rrestsizer(r<connr~r1sockaddrs r ntransfercmdzFTP.ntransfercmdPst    JD$++T4L$,,;?;N;NPD #LLT!12||C(7c><<>D7c>%d++" D#LLT!12||C(7c><<>D7c>%d++!%h<<'>>OODLL1! 8u D>DTz'   sAE'5BE='E:=Fc. |j||dS)Nr)r)r'rrs r transfercmdzFTP.transfercmds>  d+A..rc |sd}|sd}|sd}|dk(r |dvr|dz}|jd|z}|ddk(r|jd|z}|ddk(r|jd |z}|dd k7r t||S) N anonymousr>rrsz anonymous@zUSER rrzrWACCT ryrr)r'r)r*r+r~s rr&z FTP.logins'DFD ; 6Y#6l*F||GdN+ 7c><<& 01D 7c><<$/D 7c>d# # rc\ |jd|j||5}|j|x}r|||j|x}rt t |tr|j ddd|j S#1swY|j SxYwNzTYPE I)rrrecv _SSLSocket isinstanceunwrapr)r'rcallback blocksizerrdatas r retrbinaryzFTP.retrbinarys  X   c4 (D))I..$.))I..$.%*T:*F ) }} ) }}s/B&BB+c |t}|jd}|j|5}|jd|j5} |j |j dz}t||j kDrtd|j z|jdkDrtdt||sn(|ddtk(r|dd}n |d dd k(r|dd }||t t|tr|jdddddd|j!S#1swY!xYw#1swY|j!SxYw) NTYPE Ar;rr rjrz*retr*rkrlr`) print_linerrrDr rmrnrYrrIrJr[rarrrr)r'rrr~rfpres r retrlinesz FTP.retrliness4   !H||H%   c "dsT]];r{{4<>A%(DJ/9$9D"#Y$&9D%*T:*F !<#$}}#<;#$}}s$D; CD/D;/D8 4D;;Ec |jd|j||5}|j|x}r/|j||r|||j|x}r/t t |tr|j ddd|jS#1swY|jSxYwr)rrreadrbrrrr)r'rrrrrrbufs r storbinaryzFTP.storbinarys  X   c4 (D++#+ S!SM++#+ %*T:*F )}})}}sAB&(&B&&B>c" |jd|j|5} |j|jdz}t ||jkDrt d|jz|snA|ddt k7r|dt vr|dd}|t z}|j||r||t t|tr|jddd|jS#1swY|jSxYw)Nrr rjrkrl) rrrmrnrYrrrbrrrr)r'rrrrrs r storlinesz FTP.storliness  X   c "dkk$,,"23s8dll* 84<< GHHrs8v%2w&(CR#,C S!SM%*T:*F # }}!# }}s B:C66Dc0 d|z}|j|S)Nrr)r'passwordrs rr+zFTP.accts$ ||C  rcf d}|D] }|d|zz} g}|j||j|S)NNLST )rappend)r'r6rargfiless rnlstzFTP.nlsts>PCs#C sELL) rc d}d}|ddrt|dts |dd|d}}|D] }|s|d|zz}|j||y)NLISTrlr)rstrr)r'r6rfuncrs rdirzFTP.dir&sh G  9ZR#6crDH$DCS3Y' sD!rc#K |r&|jddj|zdz|rd|z}nd}g}|j||j|D]s}|j t j d\}}}i} |ddjdD]*} | j d\} }} | | | j<,|| fuyw)Nz OPTS MLST ;zMLSD %sMLSDrrl=) rrrrrZra partitionrlower) r'pathfactsrlinesre facts_found_nameentryfactkeyvalues rmlsdzFTP.mlsd5s   LL7#= > d"CC sELL)D#';;t#4#>#>s#C KDE#CR(..s3 $s 3 Q%*ciik"4-  sC C cz |jd|z}|ddk7r t||jd|zS)NzRNFR rrzzRNTO )rrr)r'fromnametonamer~s rrenamez FTP.renameQsB||Gh./ 7c>d# #||Gf,--rcT |jd|z}|dddvr|St|)NzDELE rq>200250r)r'filenamer~s rdeletez FTP.deleteXs6||Gh./ 8~ %Kd# #rc |dk(r |jdS|dk(rd}d|z}|j|S#t$r }|jddddk7rYd}~:d}~wwxYw) Nz..CDUPrrq500rrzCWD )rrr6)r'dirnamemsgrs rcwdzFTP.cwd`sw$ d? ||F++]Gw||C   88A;r?e+, s6 AAAcz |jd|z}|dddk(r|ddj}t|Sy)NzSIZE rq213)rstripint)r'rr~r\s rrzFTP.sizemsF*||Gh./ 8u QR Aq6M rcf |jd|z}|jdsyt|S)NzMKD 257rr startswithparse257)r'rr~s rmkdzFTP.mkdus39||FW,-u%~rc, |jd|zS)NzRMD r)r'rs rrmdzFTP.rmd~s!||FW,--rc` |jd}|jdsyt|S)NPWDr rr rs rpwdzFTP.pwds./||E"u%~rcJ |jd}|j|S)NQUIT)rr5rs rr2zFTP.quits!-||F#  rc |j}d|_||j|j}d|_||jyy#|j}d|_||jwwxYwr")rEr5r1)r'rEr1s rr5z FTP.closesuF 99DDI 99DDI  99DDI  s %A(A7)rrr9Nr")rrr)r N)r NN)9rrrrIr(FTP_PORTr<MAXLINErnr1rErGrQrrr,r/r7r%rLrOdebugrSrKrfrhrorvrFrrrrrrrrrrr&rrrrr+rrrrrrrrrrr2r5rrrrrJs*.I D DG D DGM%*"R0/!/ !4 E!6 $      ! !  5n/4.!F4>!  "" 8.$ !. rrcdeZdZ d dedddfd Zd fd ZdZdZdZd Z dfd Z d Z xZ S)FTP_TLSNr)contextr$r#r c z|tj}||_d|_t ||||||||y)NFr)ssl_create_stdlib_contextr_prot_psuperr,) r'r(r)r*r+rr$r#r __class__s rr,zFTP_TLS.__init__sH446"DL DL G T4$nx  Irc|r4t|jtjs|j t ||||Sr")rr1r SSLSocketauthr"r&)r'r)r*r+securer#s rr&z FTP_TLS.logins3jCMMB 7=vt4 4rc t|jtjr t d|j j tjk\r|jd}n|jd}|j j|j|j|_|jjd|j|_ |S)NzAlready using TLSzAUTH TLSzAUTH SSLserver_hostnamer;)moder )rr1rr%r=rprotocol PROTOCOL_TLSr wrap_socketr(rDr rErs rr&z FTP_TLS.auths D$))S]]3 !455||$$(8(88||J/||J/ 00DII0VDI **dmm*LDIKrc t|jtjs t d|j d}|jj |_|S)Nz not using TLSCCC)rr1rr%r=rrrs rcccz FTP_TLS.cccsI Adii7 11<<&D ((*DIKrcZ |jd|jd}d|_|S)NzPBSZ 0zPROT PTrr!rs rprot_pzFTP_TLS.prot_ps- 0 LL "<<)DDLKrc8 |jd}d|_|S)NzPROT CFr3rs rprot_czFTP_TLS.prot_cs 4<<)D DLKrct|||\}}|jr'|jj ||j }||fS)Nr))r"rr!rr.r()r'rrrrr#s rrzFTP_TLS.ntransfercmdsL-c48JD$||||//@D 0K: rcdtz}|jj||j}|dddvr t ||S)Nrrqr)rr1rbrvrrs rrz FTP_TLS.abort sKV#D II  d #$$&DBQx44!$''Kr)rrrr)rrrTr") rrrrr,r&r&r1r4r6rr __classcell__)r#s@rrrsC B I $.E$(7 I 5       rrc |dddk7r t|t-ddl}|jd|j|j zatj |}|syt|jdS)Nrqrrz150 .* \((\d+) bytes\)r ) r_150_rerecompile IGNORECASEASCIImatchr group)r~r<ms rrrsq BQx5$** %r}}rxx'?A dA  qwwqz?rcJ |dddk7r t|t ddl}|jd|jatj |}|s t ||j}dj|dd}t|ddzt|dz}||fS) Nrq227rz#(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)rrrrU) r_227_rer<r=r?searchrgroupsrr )r~r<rBnumbersr(r<s rrr,s5 BQx5$**CRXXNtA $hhjG 88GBQK D  Oq C O 3D :rc |dddk7r t||jd}|dkr t||jd|dz}|dkr t|||dz||dz k7r t|||dz|j||dz}t |dk7r t||d}t |d}||fS)Nrq229(r)r rU)rfindrrrYr )r~peerleftrightpartsr(r<s rrr?s5 BQx5$ 99S>D ax{4(( IIc4!8 $E qy$ D1H~eai($ % & &tDF| 4E 5zQ$ 7D uQx=D :rc |dddk7r t||dddk7ryd}d}t|}||kr/||}|dz}|dk(r||k\s||dk7r |S|dz}||z}||kr/|S)Nrqr rUz "rr ")rrY)r~rr]nrs rrrTs3 BQx5$ AayDG A D A a% G aC 8AvaC N!AA+ a% Nrc t|yr")rJ)res rrrjs 5 $Krc~ |s|}d|z}|j||j|t|jd\}}|j|||jd|z}|dddvrt|jd|z}|dddvrt|j |j y)NzTYPE rzSTOR rq>125rRETR )rrrrrr) source sourcenametarget targetnametype sourcehost sourceporttreplysreplys rftpcprcos5  T>D NN4 NN4%fnnV&<=J  OOJ +^^Gj0 1F bqz' ^^Gj0 1F bqz' OO OOrcn ttjdkr.ttj tj dddl}d}d}tjddk(r-|dz}tjd=tjddk(r-tjddddk(r'tjddd}tjd=tjd}t|}|j|dx}x}} |j|} |j|\}}}|j|||tjddD]} | ddd k(r|j!| ddn| dddk(r$d } | ddr | d z| ddz} |j#| } n| d k(r|j%|j& n`|j)d| ztj*j,j.dtj*j,j1tj*j1|j3y#ttf$rtdtjYRwxYw#t$r!|td tjYwxYw)Nrrr z-dz-rrz$No account -- using anonymous login.)rEz5Could not open account file -- using anonymous login.z-lCWDrz-prYi)rYr>argvrJtest__doc__exitnetrcrrOauthenticatorsKeyError TypeErrorstderrr3r&rrrSrQrstdoutbufferwriteflushr2) rjrIrcfiler(ftpuseridr*r+netrcobjrErr~s rrgrgsW  388}q dll  I F ((1+ aK HHQK ((1+  xx{2A$!QR HHQK 88A;D d)Cy!FVd K;;v&  K#+#:#:4#@ FD&IIffd#  8t  GGDH  "1X CABxsSy483;;s#D T\ LLS... / NN7T>::,,22D : JJ   # # % HHJ%)$ K 8szz J J K #   Izz ##s$ J I*JJ &J43J4__main__)rI)$r>r@r__all__rrr Exceptionrrrrrr3r4r rarrrr%rrrSSLError ImportErrorr;rrFrrrrrcrgrrrrr}s!L *    I%% Wh '  R R hu:Jk#kZ NN9(CLL9J $ &*, ,=@ zFK Js%C CC__pycache__/copyreg.cpython-312.opt-1.pyc000064400000016312152342670510014076 0ustar00 ֦idZgdZiZddZdZdZeeeedZeee e zedZ dZ ee jZd Zd Zd Zd ZiZiZiZd ZdZdZy)zHelper to provide extensibility for pickle. This is only useful to add pickle support for extension types defined in C, not for instances of user-defined classes. )pickle constructor add_extensionremove_extensionclear_extension_cacheNc^t|s td|t|<| t|yy)Nz$reduction functions must be callable)callable TypeErrordispatch_tabler)ob_typepickle_functionconstructor_obs /usr/lib64/python3.12/copyreg.pyrr s5 O $>??-N7!N#"c0t|s tdy)Nzconstructors must be callable)rr )objects rrrs F 788 rc>t|j|jffSN)complexrealimag)cs rpickle_complexrs QVVQVV$ $$rcZddl}ddl}|j|j|jffS)N) functoolsoperatorreduceor___args__)objrrs r pickle_unionr!!s#   hllCLL9 99rc|turtj|}|S|j||}|jtjk7r|j|||Sr)r__new____init__)clsbasestater s r_reconstructorr()sS v~nnS! Jll3& ==FOO + MM#u % Jric|j}|jD]P}t|dr|jtzsn5|j }t |tsA|j|usPnt}|turd}n%||urtd|jd||}|||f} |j}t|jtjurt|ddr td|}|r t"||fSt"|fS#t$rKt|ddrtd|jd|d |j }n#t$rd}YnwxYwYfwxYw)N __flags__zcannot pickle z object __slots__zNa class that defines __slots__ without defining __getstate__ cannot be pickledzf object: a class that defines __slots__ without defining __getstate__ cannot be pickled with protocol ) __class____mro__hasattrr* _HEAPTYPEr# isinstance _new_type__self__rr __name__ __getstate__typegetattrAttributeError__dict__r() selfprotor%r&newr'argsgetstatedicts r _reduce_exr?7sv ..C  4 %dnny.H ll c9 %#,,$*>   v~ 3;nS\\, E  E EEEEEc(|j|g|Srr#)r%r<s r __newobj__rBbs 3;;s "T ""rc.|j|g|i|S)zUsed by pickle protocol 4, instead of __newobj__ to allow classes with keyword-only arguments to be pickled correctly. rA)r%r<kwargss r __newobj_ex__rEes 3;;s ,T ,V ,,rc|jjd}||Sg}t|dsn|jD]}d|jvs|jd}t |t r|f}|D]}|dvr|j drW|jdsF|jjd}|r|jd||^|j|p|j| ||_ |S#Y|SxYw)aReturn a list of slot names for a given class. This needs to find slots defined by the class and its bases, so we can't simply return the __slots__ attribute. We must walk down the Method Resolution Order and concatenate the __slots__ of each class found there. (This assumes classes don't modify their __slots__ attribute to misrepresent their slots after the class is defined.) __slotnames__r+)r8 __weakref_____) r8getr.r-r0str startswithendswithr3lstripappendrG)r%namesrslotsnamestrippeds r _slotnamesrUks LL  _ -E   E 3 $ Aajj( ;/eS)"HE!D:: .t}}T7J#$::#4#4S#9#!LLHd)CD!LL. T*" * ! L  Ls 7DDclt|}d|cxkrdkstdtd||f}tj||k(rtj||k(ry|tvrtd|dt||tvrtd|dt||t|<|t|<y) zRegister an extension code.izcode out of rangeNkey z! is already registered with code zcode z is already in use for key )int ValueError_extension_registryrK_inverted_registrymodulerScodekeys rrrs t9D  " ",-- #,-- 4.C$,t$+ !!2379: : !! 24 8:; ;#"trc||f}tj||k7stj||k7rtd|d|t|=t|=|tvrt|=yy)z0Unregister an extension code. For testing only.rXz is not registered with code N)r[rKr\rZ_extension_cacher]s rrrsn 4.C$,t$+t%& &C 4   T " rc,tjyr)rbclearrrrrsrr)__doc____all__r rrrrr!r5rYrLr(r/r#r1r?rBrErUr[r\rbrrrrerrrhs  I$9 %w(:tC#I %    '$V#- 1x#$ #r__pycache__/symtable.cpython-312.opt-2.pyc000064400000041264152342670510014253 0ustar00 ֦i0l ddlZddlmZmZmZmZmZmZmZmZm Z m Z m Z m Z m Z mZmZddlZgdZdZGddZeZGddZGd d eZGd d eZGd dZedk(rddlZddlZeej:d5Zej?Z dddee ejBjEej:dddZ#e#jID]9Z%e#jMe%Z'e(e'e'jSe'jU;yy#1swYxYw)N)USE DEF_GLOBAL DEF_NONLOCAL DEF_LOCAL DEF_PARAM DEF_IMPORT DEF_BOUND DEF_ANNOT SCOPE_OFF SCOPE_MASKFREELOCALGLOBAL_IMPLICITGLOBAL_EXPLICITCELL)symtable SymbolTableClassFunctionSymbolcJ tj|||}t||SN) _symtabler_newSymbolTable)codefilename compile_typetops !/usr/lib64/python3.12/symtable.pyrr s*   T8\ :C 3 ))ceZdZdZdZdZy)SymbolTableFactoryc6tj|_yr)weakrefWeakValueDictionary_SymbolTableFactory__memoselfs r__init__zSymbolTableFactory.__init__s113 r c|jtjk(r t||S|jtjk(r t ||St ||Sr)typer TYPE_FUNCTIONr TYPE_CLASSrr)r(tablers rnewzSymbolTableFactory.newsM ::00 0E8, , ::-- -) )5(++r c||f}|jj|d}|!|j||x}|j|<|Sr)r&getr/)r(r.rkeyobjs r__call__zSymbolTableFactory.__call__ sGXokkooc4( ;%)XXeX%> >C$++c" r N)__name__ __module__ __qualname__r)r/r4r rr"r"s4,r r"c`eZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZy)rc.||_||_i|_yr)_table _filename_symbols)r( raw_tablers rr)zSymbolTable.__init__,s ! r c,|jtk(rd}nd|jjz}|jjdk(rdj ||j Sdj ||jj|j S)Nz%s rz<{0}SymbolTable for module {1}>z<{0}SymbolTable for {1} in {2}>) __class__rr5r;nameformatr<)r(kinds r__repr__zSymbolTable.__repr__1s{ >>[ (D4>>222D ;;  u $4;;D$..Q Q4;;D<@KKs ;;  y44 4 ;;  y66 6 ;;  y33 3 ;;  y88 8 ;;  y<< <" ;;  y88 8 ;;  y88 8# 9r c0 |jjSr)r;idr's rget_idzSymbolTable.get_idTs {{~~r c0 |jjSr)r;rBr's rget_namezSymbolTable.get_nameYs {{r c0 |jjSr)r;linenor's r get_linenozSymbolTable.get_linenobs {{!!!r cd t|jjtjk(Sr)boolr;r+rr,r's r is_optimizedzSymbolTable.is_optimizedhs) DKK$$ (?(??@@r cB t|jjSr)rZr;nestedr's r is_nestedzSymbolTable.is_nestedns DKK&&''r cB t|jjSr)rZr;childrenr's r has_childrenzSymbolTable.has_childrenss DKK(())r cL |jjjSr)r;symbolskeysr's rget_identifierszSymbolTable.get_identifiersxs  {{""''))r c |jj|}|a|jj|}|j |}|jj dk(}t ||||x}|j|<|S)Nr module_scope)r=r1r;rc_SymbolTable__check_childrenrBr)r(rBsymflags namespacesrhs rlookupzSymbolTable.lookup}s mm% ;KK''-E..t4J KK,,5L(.tUJz-Function.__idents_matching..s0?(>u!$++"5"5e"<=(>s+.)tuplere)r(rzs``r__idents_matchingzFunction.__idents_matchings%?(<(<(>?? ?r cb |j|jd|_|jS)Nc|tzSr)rxs rz)Function.get_parameters..sA Mr )_Function__params_Function__idents_matchingr's rget_parameterszFunction.get_parameterss. ==  223IJDM}}r c |j'ttffd}|j||_|jS)Nc(|tz tzvSrr r )rlocss rrz%Function.get_locals..sqI~;Dr )_Function__localsrrr)r(testrs @r get_localszFunction.get_localss< == 4=DDD 2248DM}}r c |j'ttffd}|j||_|jS)Nc(|tz tzvSrr)rglobs rrz&Function.get_globals..sa9n :tCr )_Function__globalsrrr)r(rrs @r get_globalszFunction.get_globalss= >> !#_5DCD!33D9DN~~r cb |j|jd|_|jS)Nc|tzSr)rrs rrz(Function.get_nonlocals..s q.si: =$Fr )_Function__freesr)r(is_frees r get_freeszFunction.get_freess2 << FG11':DL||r )r5r6r7rrrrrrrrrrrr8r rrrs;HHGIK? r rceZdZdZdZy)rNc" ji}fd}jjD]}||js|jxt j k(r/|jdk(rd|jvrSd||j<ct jk(sv|j}|jD]6}|j|k(s|jt j k(s1d||<t|_jS)Nc~jjj|d}|tz tzt k(S)Nr)r;rcr1r r r)rorkr(s ris_local_symbolz*Class.get_methods..is_local_symbols4 ++//q9)+z9eCCr genexprz.0) _Class__methodsr;r`rBr+rr,varnamesrOr|)r(drrr scope_namecs` r get_methodszClass.get_methodss >> !A Dkk**"277+''4Y44 "ww)3 8K ()*AbggJ&66*,J%'[[#$66Z#7AFFiF]F]<]56AjM$)&1+4#1XDN~~r )r5r6r7rrr8r rrrs I%r rcteZdZddddZdZdZdZdZd Zd Z d Z d Z d Z dZ dZdZdZdZdZy)rNFrgcn||_||_|tz tz|_|xsd|_||_y)Nr8) _Symbol__name_Symbol__flagsr r _Symbol__scope_Symbol__namespaces_Symbol__module_scope)r(rBrkrlrhs rr)zSymbol.__init__s6  *j8 &,"*r c8dj|jS)Nz)rCrr's rrEzSymbol.__repr__s&&t{{33r c |jSr)rr's rrUzSymbol.get_name s {{r cP t|jtjzSr)rZrrrr's r is_referencedzSymbol.is_referenceds! DLL9==011r c< t|jtzSr)rZrrr's r is_parameterzSymbol.is_parameter DLL9,--r c t|jttfvxs!|jxr|j t zSr)rZrrrrrr r's r is_globalzSymbol.is_globalsC DLL_o$FFJ++H y0HK Kr c< t|jtzSr)rZrrr's r is_nonlocalzSymbol.is_nonlocal!s6DLL</00r c< t|jtk(Sr)rZrrr's ris_declared_globalzSymbol.is_declared_global%s $DLLO344r c t|jttfvxs!|jxr|j t zSr)rZrrrrrr r's ris_localzSymbol.is_local*sB DLLUDM1J++H y0HK Kr c< t|jtzSr)rZrr r's r is_annotatedzSymbol.is_annotated0rr c< t|jtk(Sr)rZrr r's rrzSymbol.is_free5s DLLD())r c< t|jtzSr)rZrrr's r is_importedzSymbol.is_imported;s DLL:-..r c< t|jtzSr)rZrrr's r is_assignedzSymbol.is_assignedAs7DLL9,--r c. t|jSr)rZrr's r is_namespacezSymbol.is_namespaceEs D%%&&r c |jSr)rr's rget_namespaceszSymbol.get_namespacesRs<   r c t|jdk(r tdt|jdkDr td|jdS)Nrz#name is not bound to any namespacesrz$name is bound to multiple namespaces)lenr ValueErrorr's r get_namespacezSymbol.get_namespaceVsX t  !Q &BC C "" #a 'CD D$$Q' 'r r)r5r6r7r)rErUrrrrrrrrrrrrrr8r rrrs[+U+4 2 . K 15 K . * / . '! (r r__main__rexec)+rrrrrrrr r r r r rrrrr$__all__rr"rrrrrr5ossysopenargvfreadsrcpathsplitmodrerorminfoprintrrr8r rrs844444 D*$%&p0p0f3{3l)K)Xb(b(H z chhqk affh  3 chhqk215v >C$$&zz%  dDMMOT%6%6%89'   s D**D3__pycache__/_compat_pickle.cpython-312.opt-2.pyc000064400000015634152342670510015406 0ustar00 ֦i9"idddddddddd d d d d ddddddddddddddddddd d!id"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAdBdCdDdEdFdGdHdId2dJdKZidLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd[d\d]d^d_d`dadbdcdddedfdgdhdidjdkdldmidndodpdqdrdsdtdudvdwdxdydzd{d|d}d~dddddddddddddddZdZ eedz ZeD] Zdefedef< dZeD] Zdefedef< edejDZ edejDZ ejddd dd9dDdDdddd2ddd e jdd2dd4ddejdUddcdde jdNddddddddddddd dZ e D] Zde def< dZ e D] Zde def< [y#e$rYwxYw) __builtin__builtinscopy_regcopyregQueuequeue SocketServer socketserver ConfigParser configparserreprreprlib tkFileDialogtkinter.filedialogtkSimpleDialogtkinter.simpledialogtkColorChooserztkinter.colorchoosertkCommonDialogztkinter.commondialogDialogztkinter.dialogTkdndz tkinter.dndtkFontz tkinter.font tkMessageBoxztkinter.messagebox ScrolledTextztkinter.scrolledtext Tkconstantsztkinter.constantsTixz tkinter.tixttkz tkinter.ttkTkintertkinter markupbase _markupbase_winregwinregthread_thread dummy_thread _dummy_threaddbhashzdbm.bsddumbdbmzdbm.dumbdbmzdbm.ndbmgdbmzdbm.gnu xmlrpclibz xmlrpc.clientSimpleXMLRPCServer xmlrpc.serverhttplibz http.clienthtmlentitydefsz html.entities HTMLParserz html.parserCookiez http.cookies cookielibzhttp.cookiejar http.serverz test.support subprocess urllib.parsezurllib.robotparserurllib.requestzcollections.abc)BaseHTTPServerztest.test_supportcommandsurlparse robotparserurllib2anydbm_abcoll)rxrange)rrange)rreduce) functoolsr?)rintern)sysrA)runichr)rchr)runicode)rstr)rlong)rint) itertoolsizip)rzip)rIimap)rmap)rIifilter)rfilter)rI ifilterfalse)rI filterfalse)rI izip_longest)rI zip_longest)UserDictIterableUserDict) collectionsrT)UserListrW)rVrW) UserStringrX)rVrX)whichdbrY)r(rY)_socketfromfd)socketr[)_multiprocessing Connection)zmultiprocessing.connectionr^)zmultiprocessing.processProcess)multiprocessing.contextr_)zmultiprocessing.forkingPopen)zmultiprocessing.popen_forkra)urllibContentTooShortError) urllib.errorrc)rb getproxies)r5re)rb pathname2url)r5rf)rb quote_plus)r4rg)rbquote)r4rh)rb unquote_plus)r4ri)rbunquote)r4rj)rb url2pathname)r5rk)rb urlcleanup)r5rl)rb urlencode)r4rm)rburlopen)r5rn)rb urlretrieve)r5ro)r: HTTPError)rdrp)r:URLError)rdrq)/ArithmeticErrorAssertionErrorAttributeError BaseException BufferError BytesWarningDeprecationWarningEOFErrorEnvironmentError ExceptionFloatingPointError FutureWarning GeneratorExitIOError ImportError ImportWarningIndentationError IndexErrorKeyErrorKeyboardInterrupt LookupError MemoryError NameErrorNotImplementedErrorOSError OverflowErrorPendingDeprecationWarningReferenceError RuntimeErrorRuntimeWarning StopIteration SyntaxError SyntaxWarning SystemError SystemExitTabError TypeErrorUnboundLocalErrorUnicodeDecodeErrorUnicodeEncodeError UnicodeErrorUnicodeTranslateErrorUnicodeWarning UserWarning ValueErrorWarningZeroDivisionError) WindowsError exceptions)AuthenticationErrorBufferTooShort ProcessError TimeoutErrorr`multiprocessingc#*K|] \}}||f ywN.0kvs '/usr/lib64/python3.12/_compat_pickle.py rsJ3I!Qq!f3Ic#*K|] \}}||f ywrrrs rrrsF1Ev1QF1Erpicklezxml.etree.ElementTreerVio) cPickle _elementtree FileDialog SimpleDialogDocXMLRPCServerSimpleHTTPServer CGIHTTPServerrTrWrXrYStringIO cStringIObz2r@)_bz2_dbm _functools_gdbm_pickle)rr{)r\ SocketType))r basestring)r StandardError)rTrTr\ _socketobject)rr)rLoadFileDialog)rSaveFileDialog)rr)r ServerHTMLDoc)rXMLRPCDocGenerator)rDocXMLRPCRequestHandler)rr)rDocCGIXMLRPCRequestHandler)rSimpleHTTPRequestHandler)rCGIHTTPRequestHandlerr) )rr?)rr)rr)rr)rr)r,r)r,r)r,r)r,r)r,r)r2r)r2r)rZr\)BrokenPipeErrorChildProcessErrorConnectionAbortedErrorConnectionErrorConnectionRefusedErrorConnectionResetErrorFileExistsErrorFileNotFoundErrorInterruptedErrorIsADirectoryErrorNotADirectoryErrorPermissionErrorProcessLookupErrorr)rr)ModuleNotFoundError)rrN)IMPORT_MAPPING NAME_MAPPINGPYTHON2_EXCEPTIONSrrexcnameMULTIPROCESSING_EXCEPTIONSdictitemsREVERSE_IMPORT_MAPPINGREVERSE_NAME_MAPPINGupdatePYTHON3_OSERROR_EXCEPTIONSPYTHON3_IMPORTERROR_EXCEPTIONSrrrs?+J+ + W+N + N +  I +(+,+,+,+ + ]+ n+(+*+ &!+" =#+$ =%+&y'+(-)+*x++, i-+.O/+0 i1+2z3+4 :5+6 I7+89+:/;+<}=+>?+@=A+B nC+D!E+F$'(!U+b"#8"#:"#4"#6 " #6 " #6 "#6"#6"#9""#?""#?"%&A"9"!"?"." /!""'(T#"$+,R%"&)*Q'"('(P)"*>+", B-".9"::;"<8=">@?"@;A"B9C" H1f,++!G-7,AL,()"*G2KW1UL#W-.*J>3G3G3IJJF1C1C1EFF +&*&%""     #6%>9!9 7*F.N.N.N(L16.9826',"*G2K*g./*".G2O*g./. U  s GGG__pycache__/smtplib.cpython-312.pyc000064400000136115152342670510013145 0ustar00 ֦i dZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mZgdZdZdZdZdZd Zd Zej.d ej0ZGd d eZGddeZGddeZGddeZGddeZGddeZ GddeZ!GddeZ"GddeZ#GddeZ$d Z%d!Z&d"Z'd#Z(d$Z) ddl*Z*d%Z+Gd'd(Z-e+rGd)d*e-Z.ej_d*d+Z0Gd,d-e-Z1e2d.k(rd/Z3e3d0Z4e3d1jkd2Z6e7d3d4Z8e jrjuxZ;r"e8e;zZ8e jrjuxZ;r"e7d5e>> import smtplib >>> s=smtplib.SMTP("localhost") >>> print(s.help()) This is Sendmail version 8.8.4 Topics: HELO EHLO MAIL RCPT DATA RSET NOOP QUIT HELP VRFY EXPN VERB ETRN DSN For more info use "HELP ". To report bugs in the implementation send email to sendmail-bugs@sendmail.org. For local information send email to Postmaster at your site. End of HELP info >>> s.putcmd("vrfy","someone@here") >>> s.getreply() (250, "Somebody OverHere ") >>> s.quit() N) body_encode) SMTPExceptionSMTPNotSupportedErrorSMTPServerDisconnectedSMTPResponseExceptionSMTPSenderRefusedSMTPRecipientsRefused SMTPDataErrorSMTPConnectError SMTPHeloErrorSMTPAuthenticationError quoteaddr quotedataSMTPi s i z auth=(.*)ceZdZdZy)rz4Base class for all exceptions raised by this module.N__name__ __module__ __qualname____doc__ /usr/lib64/python3.12/smtplib.pyrrHs>rrceZdZdZy)rzThe command or option is not supported by the SMTP server. This exception is raised when an attempt is made to run a command or a command with an option which is not supported by the server. NrrrrrrKrrceZdZdZy)rzNot connected to any SMTP server. This exception is raised when the server unexpectedly disconnects, or when an attempt is made to use the SMTP instance before connecting it to a server. NrrrrrrRsrrceZdZdZdZy)ra2Base class for all exceptions that include an SMTP error code. These exceptions are generated in some instances when the SMTP server returns an error code. The error code is stored in the `smtp_code' attribute of the error, and the `smtp_error' attribute is set to the error message. c2||_||_||f|_yN) smtp_code smtp_errorargs)selfcodemsgs r__init__zSMTPResponseException.__init__cs3K rNrrrrr)rrrrrZs  rrceZdZdZdZy)rzSender address refused. In addition to the attributes set by on all SMTPResponseException exceptions, this sets `sender' to the string that the SMTP refused. cB||_||_||_|||f|_yr")r#r$senderr%)r&r'r(r-s rr)zSMTPSenderRefused.__init__os% 3' rNr*rrrrrhs  (rrceZdZdZdZy)r zAll recipient addresses refused. The errors for each recipient are accessible through the attribute 'recipients', which is a dictionary of exactly the same sort as SMTP.sendmail() returns. c"||_|f|_yr") recipientsr%)r&r0s rr)zSMTPRecipientsRefused.__init__}s$M rNr*rrrr r us "rr ceZdZdZy)r z'The SMTP server didn't accept the data.Nrrrrr r s1rr ceZdZdZy)r z&Error during connection establishment.Nrrrrr r s0rr ceZdZdZy)r z"The server refused our HELO reply.Nrrrrr r s,rr ceZdZdZy)r zvAuthentication error. Most probably the server didn't accept the username/password combination provided. Nrrrrr r rrr ctjj|\}}||fdk(r&|jj dr|Sd|zSd|zS)zQuote a subset of the email addresses defined by RFC 821. Should be able to handle anything email.utils.parseaddr can handle. r7)emailutils parseaddrstrip startswith addrstring displaynameaddrs rrrs\  --j9KTh&     ( ( -  "" D=rc\tjj|\}}||fdk(r|S|S)Nr6)r9r:r;r>s r _addr_onlyrCs3 --j9KTh& Krc btjddtjdt|S)zQuote data for email. Double leading '.', and change Unix newline '\n', or Mac '\r' into internet CRLF end-of-line. z(?m)^\.z..(?:\r\n|\n|\r(?!\n))resubCRLFdatas rrrs* 66*d &d3 55rc0tjdd|S)Ns(?m)^\.s..)rGrH)bindatas r_quote_periodsrNs 66+ug ..rc8tjdt|S)NrErFrJs r _fix_eolsrPs FF*D$ 77rTFcTeZdZdZdZdZdZdZdZdZ dZ e Z ddde jdfdZdZd Zd Zd Zd Zd,d ZdZd-dZdZd-dZd-dZd-dZdZd-dZdZdZdZ d.dZ!d.dZ"dZ#dZ$e$Z%dZ&dZ'dd d!Z(d/d"Z)d/d#Z*d/d$Z+dd d%Z,dd&d'Z- d0d(Z. d1d)Z/d*Z0d+Z1y)2raThis class manages a connection to an SMTP or ESMTP server. SMTP Objects: SMTP objects have the following attributes: helo_resp This is the message given by the server in response to the most recent HELO command. ehlo_resp This is the message given by the server in response to the most recent EHLO command. This is usually multiline. does_esmtp This is a True value _after you do an EHLO command_, if the server supports ESMTP. esmtp_features This is a dictionary, which, if the server supports ESMTP, will _after you do an EHLO command_, contain the names of the SMTP service extensions this server supports, and their parameters (if any). Note, all extension names are mapped to lower case in the dictionary. See each method's docstrings for details. In general, there is a method of the same name to perform each SMTP command. There is also a method called 'sendmail' that will do an entire mail transaction. rNehloFr7c||_||_i|_d|_||_d|_|r6|j ||\}}|dk7r|jt|||||_ ytj}d|vr||_ yd} tjtj} d| z|_ y#tj$rY wxYw)aInitialize a new instance. If specified, `host` is the name of the remote host to which to connect. If specified, `port` specifies the port to which to connect. By default, smtplib.SMTP_PORT is used. If a host is specified the connect method is called, and if it returns anything other than a success code an SMTPConnectError is raised. If specified, `local_hostname` is used as the FQDN of the local host in the HELO/EHLO command. Otherwise, the local hostname is found using socket.getfqdn(). The `source_address` parameter takes a 2-tuple (host, port) for the socket to bind to as its source address before connecting. If the host is '' and port is 0, the OS default behavior will be used. asciirN.z 127.0.0.1z[%s])_hosttimeoutesmtp_featurescommand_encodingsource_address_auth_challenge_countconnectcloser local_hostnamesocketgetfqdn gethostbyname gethostnamegaierror) r&hostportr_rXr[r'r(fqdnrAs rr)z SMTP.__init__s$    ',%&" ,,tT2KT3s{ &tS11  %"0D  >>#Dd{&*##!//0B0B0DED'-tm#s'CCCc|Sr"rr&s r __enter__zSMTP.__enter__s rc |jd\}}|dk7r t|| |jy#t$rYwxYw#|jwxYw)NQUIT)docmdrrr^)r&r%r'messages r__exit__z SMTP.__exit__s]  JJv.MD's{+D':: JJL&    JJLs&%9A AAAAAc||_y)zSet the debug output level. A non-false value results in debug messages for connection and for all messages sent to and received from the server. N) debuglevel)r&rrs rset_debuglevelzSMTP.set_debuglevel"s %rc|jdkDrHttjjj g|dt j iyt|dt j iy)Nfile)rrprintdatetimenowtimesysstderrr&r%s r _print_debugzSMTP._print_debug+sM ??Q  (##'')..0 I4 Icjj I 4 )cjj )rc| |s td|jdkDr|jd||f|jt j ||f||jS)N0Non-blocking socket (timeout=0) is not supportedrz connect: to) ValueErrorrrr~r[r`create_connection)r&rerfrXs r _get_socketzSMTP._get_socket1sd  wOP P ??Q    mdD\4;N;N O''t g(,(;(;= =rc |r||_|sR|jd|jdk(r/|jd}|dk\r|d|||dzd}} t|}|s |j }tjd||||j|||j|_ d|_ |j\}}|jdkDr|jdt!|||fS#t$r t dwxYw)apConnect to a host on a given port. If the hostname ends with a colon (`:') followed by a number, and there is no port specified, that suffix will be stripped off and the number interpreted as the port number to use. Note: This method is automatically invoked by __init__, if a host is specified during instantiation. :rNruznonnumeric portzsmtplib.connectconnect:)r[findrfindintrOSError default_portr{auditrrXsockrvgetreplyrrr~repr)r&rerfr[ir'r(s rr]z SMTP.connect;s "0D 34::c?: 3AAv!"1XtAEF|d5t9D$$D #T46$$T4>  mmo s ??Q    j$s) 4c{"5!"3445s  C..Dc|jdkDr|jdt||jr_t |t r|j |j}tjd|| |jj|ytd#t$r|jtdwxYw)zSend `s' to the server.rzsend:z smtplib.sendServer not connectedzplease run connect() firstN)rrr~rr isinstancestrencoderZr{rsendallrr^r)r&ss rsendz SMTP.send\s ??Q    gtAw / 99!S!HHT223 IIndA . E !!!$ ))EF F  E ,-CDD Es :B!!%Cc|dk(r|}n|d|}d|vsd|vr0|jddjdd}td||j|ty) zSend a command to the server.r7   z\nz\rz=command and arguments contain prohibited newline characters: N)replacerrrI)r&cmdr%rs rputcmdz SMTP.putcmdosu 2:A%qA 19  $&..tU;AOPQsS  QCv,rcg}|j |jjd|_ |jjtdz}|s|j td|jdkDr|jdt|t|tkDr|j tdd |j|d djd |dd } t!|}|d d dk7rndj%|}|jdkDr|jd|d|||fS#t $r,}|j tdt|zd}~wwxYw#t"$rd }YwxYw)aGet a reply from the server. Returns a tuple consisting of: - server response code (e.g. '250', or such, if all goes well) Note: returns -1 if it can't read response code. - server response string corresponding to response code (multiline responses are converted to a single, multiline string). Raises SMTPServerDisconnected if end-of-file is reached. Nrbruz Connection unexpectedly closed: zConnection unexpectedly closedrzreply:izLine too long.s - zreply: retcode (z); Msg: )rvrmakefilereadline_MAXLINErr^rrrrr~rlenrappendr<rrjoin)r&resplineer'errcodeerrmsgs rrz SMTP.getreply|sz 99  **40DI 7yy))(Q,7  ,-MNN"!!(DJ74y8# +C1ABB KKQRz2 38D d) AayD 58D! ??Q    P Q9 7 ,-O/21v.677 7$  s)"E1 E9 E6 'E11E69 FFcF|j|||jS)z-Send a command, and return its response code.rr)r&rr%s rrnz SMTP.docmds C}}rc~|jd|xs |j|j\}}||_||fS)zwSMTP 'helo' command. Hostname to send for this command defaults to the FQDN of the local host. helo)rr_r helo_resp)r&namer'r(s rrz SMTP.helos= FD7D$7$78mmo sc{rci|_|j|j|xs |j|j \}}|dk(r)t |dk(r|j td||_|dk7r||fSd|_ t|jtsJt|j|jjdjd}|d=|D]}tj!|}|rB|jj#dd d z|j%ddz|jd<]t'j d |}|sv|j)d j+}|j,|j/d d j1} |dk(r0|jj#|d d z| z|j|<| |j|<||fS)zx SMTP 'ehlo' command. Hostname to send for this command defaults to the FQDN of the local host. rrrTzlatin-1rauthr7rz((?P[A-Za-z0-9][A-Za-z0-9\-]*) ?featureN)rYrehlo_msgr_rrr^r ehlo_resp does_esmtprbytesrdecodesplit OLDSTYLE_AUTHmatchgetgroupsrGgrouplowerstringendr<) r&rr'r(reach auth_matchmrparamss rrRz SMTP.ehlos ! DMM4#>4+>+>?mmo s 2:#c(a- JJL()?@ @ 3;#; $..%0F$t~~2FF0~~$$Y/55d; GD',,T2J.2.A.A.E.Efb.Q/ * 1 1! 4Q 7/8##F+ DdKA''),224!%% "2"34::<f$373F3F3J3J7TV3W!4"$*4+D''04:D''056c{rc:|j|jvS)z7Does the server support a given SMTP service extension?)rrY)r&opts rhas_extnz SMTP.has_extnsyy{d1111rcL|jd||jdS)z;SMTP 'help' command. Returns help text from server.helprurr}s rrz SMTP.helps# FD!}}q!!rc2d|_|jdS)z&SMTP 'rset' command -- resets session.rTrset)rZrnris rrz SMTP.rsets 'zz&!!rcD |jy#t$rYywxYw)aInternal 'rset' command which ignores any SMTPServerDisconnected error. Used internally in the library, since the server disconnected error should appear to the application when the *next* command is issued, if we are doing an internal "safety" reset. N)rrris r_rsetz SMTP._rsets"  IIK%   s  c$|jdS)z-SMTP 'noop' command -- doesn't do anything :>noop)rnris rrz SMTP.noop szz&!!rcd}|rV|jrJtd|Dr$|jdrd|_n t dddj |z}|j ddt|||jS) a8SMTP 'mail' command -- begins mail xfer session. This method may raise the following exceptions: SMTPNotSupportedError The options parameter includes 'SMTPUTF8' but the SMTPUTF8 extension is not supported by the server. r7c3BK|]}|jdk(yw)smtputf8N)r).0xs r zSMTP.mail..s:'Q1779j('srzutf-8z SMTPUTF8 not supported by serverrmailzFROM:) ranyrrZrrrrr)r&r-options optionlists rrz SMTP.mails{ t:'::==,,3D)/:<<sxx00J F9V+> !dnn&<499;q>0S0#yy{ tt*s*'d33+1'= !rTinitial_response_okcH|j}|r|nd}|?t|jdd}|jd|dz|z\}}d|_n|jd|\}}d|_|d k(r|xjdz c_t j |}t||jdd}|j|\}}|jtkDrtd t||fz|d k(r|d vr||fSt||) aAuthentication command - requires response processing. 'mechanism' specifies which authentication mechanism is to be used - the valid values are those listed in the 'auth' element of 'esmtp_features'. 'authobject' must be a callable object taking a single argument: data = authobject(challenge) It will be called to process the server's challenge response; the challenge argument it is passed will be a bytes. It should return an ASCII string that will be base64 encoded and sent to the server. Keyword arguments: - initial_response_ok: Allow sending the RFC 4954 initial-response to the AUTH command, if the authentication methods supports it. NrTr7)eolAUTHrruriNz4Server AUTH mechanism infinite loop. Last response: i) upper encode_base64rrnr\base64 decodebytes _MAXCHALLENGErrr ) r& mechanism authobjectrinitial_responseresponser'r challenges rrz SMTP.authhs-,OO% ,?JLT  '$%5%<%99 == rc|j|jds td|jdj }gd}|Dcgc]}||vr| }}|s t d||c|_|_|D]Q}d|jjddz} |j|t|| |\} } | d vr| | fcSS cc}w#t$r } | } Yd } ~ kd } ~ wwxYw) awLog in on an SMTP server that requires authentication. The arguments are: - user: The user name to authenticate with. - password: The password for the authentication. Keyword arguments: - initial_response_ok: Allow sending the RFC 4954 initial-response to the AUTH command, if the authentication methods supports it. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. This method will return normally if the authentication was successful. This method may raise the following exceptions: SMTPHeloError The server didn't reply properly to the helo greeting. SMTPAuthenticationError The server didn't accept the username/ password combination. SMTPNotSupportedError The AUTH command is not supported by the server. SMTPException No suitable authentication method was found. rz,SMTP AUTH extension not supported by server.)zCRAM-MD5PLAINLOGINz(No suitable authentication method found.auth_-_rrN) rrrrYrrr rrrrgetattrr )r&r rradvertised_authlistpreferred_authsrauthlist authmethod method_namer'rrlast_exceptions rloginz SMTP.logins*8 ##%}}V$'>@ @#11&9??A9&54_T22_4 JK K $(  4="J!J$4$4$6$>$>sC$HHK ##yyk :(; ) = t :% $<'&#/4&+ #!" #s C&(C C/#C**C/)contextc|j|jds td|jd\}}|dk(rzts t d|t j}|j|j|j|_ d|_ d|_ d|_ i|_d|_||fSt!||) aPuts the connection to the SMTP server into TLS mode. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. If the server supports TLS, this will encrypt the rest of the SMTP session. If you provide the context parameter, the identity of the SMTP server and client can be checked. This, however, depends on whether the socket module really checks the certificates. This method may raise the following exceptions: SMTPHeloError The server didn't reply properly to the helo greeting. starttlsz+STARTTLS extension not supported by server.STARTTLSrUz&No SSL support included in this PythonNserver_hostnameF)rrrrn _have_ssl RuntimeErrorssl_create_stdlib_context wrap_socketrrWrvrrrYrr)r&r&rreplys rr(z SMTP.starttlss" ##%}}Z('=? ? :. u 3;"#KLL446++DII<@JJ,HDIDI "DN!DN"$D #DO e}(e4 4rcz|jg}t|trt|j d}|j rF|j dr|jdt|z|D]}|j||j||\}} |dk7r3|dk(r|jn|jt|| |i} t|tr|g}|D]H} |j| |\}} |dk7r |dk7r|| f| | <|dk(s/|jt| t| t|k(r|jt| |j|\}} |dk7r2|dk(r|jn|jt!|| | S)a| This command performs an entire mail transaction. The arguments are: - from_addr : The address sending this mail. - to_addrs : A list of addresses to send this mail to. A bare string will be treated as a list with 1 address. - msg : The message to send. - mail_options : List of ESMTP options (such as 8bitmime) for the mail command. - rcpt_options : List of ESMTP options (such as DSN commands) for all the rcpt commands. msg may be a string containing characters in the ASCII range, or a byte string. A string is encoded to bytes using the ascii codec, and lone \r and \n characters are converted to \r\n characters. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. If the server does ESMTP, message size and each of the specified options will be passed to it. If EHLO fails, HELO will be tried and ESMTP options suppressed. This method will return normally if the mail is accepted for at least one recipient. It returns a dictionary, with one entry for each recipient that was refused. Each entry contains a tuple of the SMTP error code and the accompanying error message sent by the server. This method may raise the following exceptions: SMTPHeloError The server didn't reply properly to the helo greeting. SMTPRecipientsRefused The server rejected ALL recipients (no mail was sent). SMTPSenderRefused The server didn't accept the from_addr. SMTPDataError The server replied with an unexpected error code (other than a refusal of a recipient). SMTPNotSupportedError The mail_options parameter includes 'SMTPUTF8' but the SMTPUTF8 extension is not supported by the server. Note: the connection will be open even after an exception is raised. Example: >>> import smtplib >>> s=smtplib.SMTP("localhost") >>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"] >>> msg = '''\ ... From: Me@my.org ... Subject: testin'... ... ... This is a test ''' >>> s.sendmail("me@my.org",tolist,msg) { "three@three.org" : ( 550 ,"User unknown" ) } >>> s.quit() In the above example, the message was accepted for delivery to three of the four addresses, and one was rejected, with the error code 550. If all addresses are accepted, then the method will return an empty dictionary. rTsizezsize=%dri)rrrrPrrrrrrr^rrrr rKr ) r& from_addrto_addrsr( mail_options rcpt_options esmtp_optsoptionr'rsenderrsrs rsendmailz SMTP.sendmails@ ##% c3 C.''0C ??}}V$!!)c#h"67&!!&)'yyJ7 t 3;s{  #D$ : : h $ zHD99T<8LT4 $#+"&s{ +H55  x=CM ) JJL'1 1yy~ t 3;s{  d+ +rc0|j|jd}|d}nt|dk(rd}n td|=|dz|vr||dzn||dz}tj j |gd d}|U||d z||d z||d zfDcgc]}||} }tj j | D cgc]} | d }} tj|} | d =| d =d} dj|g|jdtj5} | rEtjj!| |j"j%d}g|dd}ntjj!| }|j'| d| j)}ddd|j+||||Scc}wcc} w#t$r!|jds tdd} YwxYw#1swYUxYw)a~Converts message to a bytestring and passes it to sendmail. The arguments are as for sendmail, except that msg is an email.message.Message object. If from_addr is None or to_addrs is None, these arguments are taken from the headers of the Message as described in RFC 2822 (a ValueError is raised if there is more than one set of 'Resent-' headers). Regardless of the values of from_addr and to_addr, any Bcc field (or Resent-Bcc field, when the Message is a resent) of the Message object won't be transmitted. The Message object is then serialized using email.generator.BytesGenerator and sendmail is called to transmit the message. If the sender or any of the recipient addresses contain non-ASCII and the server advertises the SMTPUTF8 capability, the policy is cloned with utf8 set to True for the serialization, and SMTPUTF8 and BODY=8BITMIME are asserted on the send. If the server does not support SMTPUTF8, an SMTPNotSupported error is raised. Otherwise the generator is called without modifying the policy. z Resent-DateNr7ruzResent-z0message has more than one 'Resent-' header blockSenderFromrToBccCcz Resent-BccFrTrzOne or more source or delivery addresses require internationalized email support, but the server does not advertise the required SMTPUTF8 capabilityT)utf8)policySMTPUTF8z BODY=8BITMIMEr)linesep)rget_allrrr9r: getaddressescopyrrUnicodeEncodeErrorrrioBytesIO generatorBytesGeneratorrDcloneflattengetvaluer<)r&r(r5r6r7r8resent header_prefixf addr_fieldsamsg_copy internationalbytesmsggflatmsgs r send_messagezSMTP.send_messages]> ##%]+ >M [A %MOP P   -x7C?]X56 #MF$: ;  00)=a@CI  '*=4+?'@'*=5+@'A'*=4+?'@'B-'B m'BK-',kk&>&>{&KL&K!&KHL99S> UO \ "  ! GGY** + 2 27 ;ZZ\XOO22SZZ%5%54%5%@3BKKzK?K OO228< IIhI /'')G}}Y'<)+ +9-M" !==,+KLL!M  !\s+ G G7#G.B H 'H H  Hc |j}d|_|r|j|j}d|_|r|jyy#|j}d|_|r|jwwxYw)z(Close the connection to the SMTP server.N)rvr^r)r&rvrs rr^z SMTP.closesi 99DDI 99DDI 99DDI s %A(A6c|jd}dx|_|_i|_d|_|j |S)zTerminate the SMTP session.quitNF)rnrrrYrr^)r&ress rr_z SMTP.quits;jj *..   r localhostrN)r7)rr")rr)NNrr)2rrrrrrrrvrrrr SMTP_PORTrr`_GLOBAL_DEFAULT_TIMEOUTr)rjrprsr~rr]rrrrnrrRrrrrrrrrKrrrrrrrrr%r(r<r\r^r_rrrrrs& 8J D DIHIJLQt77 $.4`%* =BG&  /b 1f2" " "*: D4"BF.2`I7 !<@@D#'+Z?A fP:>35K+Z rrcLeZdZdZeZdejddddZfdZ xZ S)SMTP_SSLa This is a subclass derived from SMTP that connects over an SSL encrypted socket (to use this class you need a socket module that was compiled with SSL support). If host is not specified, '' (the local host) is used. If port is omitted, the standard SMTP-over-SSL port (465) is used. local_hostname and source_address have the same meaning as they do in the SMTP class. context also optional, can contain a SSLContext. N)rXr[r&cr|tj}||_tj ||||||yr")r.r/r&rr))r&rerfr_rXr[r&s rr)zSMTP_SSL.__init__s7446"DL MM$dNG( *rc|jdkDr|jd||ft| |||}|jj ||j }|S)Nrrr*)rrr~superrr&r0rW)r&rerfrX new_socket __class__s rrzSMTP_SSL._get_sockets_"!!*tTl;,T4AJ11*BF**2NJ r)r7rN) rrrr SMTP_SSL_PORTrr`rdr)r __classcell__rks@rrfrfs1 %  * & > >$($ *  rrficReZdZdZdZdeddejffd Zdfd Z xZ S)LMTPaLMTP - Local Mail Transfer Protocol The LMTP protocol, which is very similar to ESMTP, is heavily based on the standard SMTP client. It's common to use Unix sockets for LMTP, so our connect() method must support that as well as a regular host:port server. local_hostname and source_address have the same meaning as they do in the SMTP class. To specify a Unix socket, you must use an absolute path as the host, starting with a '/'. Authentication is supported, using the regular SMTP mechanism. When using a Unix socket, LMTP generally don't support or require any authentication, but your mileage might vary.lhlor7Nc.t||||||y)zInitialize a new instance.)r_r[rXN)rir))r&rerfr_r[rXrks rr)z LMTP.__init__ s# tN(6  Irc|ddk7rt||||S|j|js td t jtj tj |_|jtjur%|jj|jd|_ |jj||j\}}|jdkDr|jd|||fS#t$rP|jdkDr|jd||jr|jjd|_wxYw)z=Connect to the LMTP daemon, on either a Unix or a TCP socket.r/)r[Nrz connect fail:r)rir]rXrr`AF_UNIX SOCK_STREAMrrd settimeoutrvrrrr~r^r)r&rerfr[r'r(rks rr]z LMTP.connect&s$ 7c>7?4n?M M << #DLLOP P  fnnf6H6HIDI||6#A#AA $$T\\2DI II  d #mmo s ??Q    j# .c{ "!!/48yy !DI   sBDAE+ra) rrrrr LMTP_PORTr`rdr)r]rmrns@rrprps1 4HYt $f.L.LI rrp__main__ctjj|dztjjtjj j S)Nz: )r{stdoutwriteflushstdinrr<)prompts rrrEsD $' yy!!#))++rr?r@,zEnter message, end with ^D:r7zMessage length is %drbru)Arr`rKrG email.utilsr9 email.messageemail.generatorrr rIrxr{email.base64mimerr__all__rcrlrIrrrcompileIrrrrrrrr r r r r rrCrrNrPr.r, ImportErrorrrfrrxrprrfromaddrrtoaddrsrwr(r~rrrserverrsr<r_rrrrs)R   9 -       <. ?G?M]  M   (- ( "M "2)21,1-)-3 5/8Ii i V 4< NN:  /4/h z, f~HTl  %G '( C))$$& &$ &Dj))$$& &$ & 3s8 +, + F ! OOHgs+ KKM#YIs GG#"G#__pycache__/this.cpython-312.pyc000064400000002574152342670510012443 0ustar00 ֦i dZiZdD],ZedD]Zeedzdzezeeeez<!.edjeDcgc]}ej||c}ycc}w)aXGur Mra bs Clguba, ol Gvz Crgref Ornhgvshy vf orggre guna htyl. Rkcyvpvg vf orggre guna vzcyvpvg. Fvzcyr vf orggre guna pbzcyrk. Pbzcyrk vf orggre guna pbzcyvpngrq. Syng vf orggre guna arfgrq. Fcnefr vf orggre guna qrafr. Ernqnovyvgl pbhagf. Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf. Nygubhtu cenpgvpnyvgl orngf chevgl. Reebef fubhyq arire cnff fvyragyl. Hayrff rkcyvpvgyl fvyraprq. Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff. Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg. Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu. Abj vf orggre guna arire. Nygubhtu arire vf bsgra orggre guna *evtug* abj. Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn. Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn. Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!)Aa N) sdcrangeichrprintjoinget)r s0/usr/lib64/python3.12/this.pyrs}D, A 2Y1R42+/*#ac(  bggA&AqquuQ{A&'(&sA, __pycache__/imghdr.cpython-312.opt-1.pyc000064400000015430152342670510013700 0ustar00 ֦i.dZddlmZddlZdgZej edddZgZdZ eje d Z eje d Z eje d Z eje d Zejed ZejedZejedZejedZejedZejedZejedZejedZejedZdZedk(reyy)zrysJB (Xg.2  Y  X  X  Y  X  X  X  X  Y  X  X  Y  X +* zFr"__pycache__/genericpath.cpython-312.pyc000064400000015234152342670510013762 0ustar00 ֦idZddlZddlZgdZdZdZdZdZdZd Z d Z d Z d Z d Z dZdZdZdZej&GddZy)z Path operations common to more than one OS Do not use directly. The OS specific modules import the appropriate functions from this module themselves. N) commonprefixexistsgetatimegetctimegetmtimegetsizeisdirisfileislinksamefile sameopenfilesamestat ALLOW_MISSINGcZ tj|y#ttf$rYywxYw)zDTest whether a path exists. Returns False for broken symbolic linksFT)osstatOSError ValueError)paths $/usr/lib64/python3.12/genericpath.pyrrs0    Z s **c tj|}tj|j S#ttf$rYywxYw)z%Test whether a path is a regular fileF)rrrrS_ISREGst_modersts rr r sB WWT] << ## Z 6AAc tj|}tj|j S#ttf$rYywxYw)zrns}   ($$$% & & & $$. T'''r(__pycache__/compileall.cpython-312.opt-2.pyc000064400000041340152342670510014547 0ustar00 ֦iP ddlZddlZddlZddlZddlZddlZddlmZddl m Z gdZ d dZ dddddddZ ddddddd Z dd Zd Zed k(r!ee Zej(eyy)N)partial)Path) compile_dir compile_file compile_pathc#K|dkr/t|tjrtj|}|st dj | tj |}|j|D]}|dk(r tjj||}tjj|s|M|dkDsS|tjk7sg|tjk7s{tjj|stjj|rt||dz |Ed{y#t$r%|dkrt dj |g}YwxYw78w)NzListing {!r}...zCan't list {!r} __pycache__r) maxlevelsquiet) isinstanceosPathLikefspathprintformatlistdirOSErrorsortpathjoinisdircurdirpardirislink _walk_dir)dirr r namesnamefullnames #/usr/lib64/python3.12/compileall.pyrrs( qyZR[[1iin  &&s+, 3  JJL = 77<<T*ww}}X&N!m 1dbii6GggmmH%bggnnX.F Y]',. . .  19 #**3/ 0 .sUAFE)A$FF"F6FF6F F F*F<F?FFFstripdir prependdir limit_sl_desthardlink_dupesc d d}|| | td||} |} d}|dkr td|dk7rddlm} |ddlm}|t j}t|||}d}|dk7r|~ddl }|jd k(r|jd }nd}|xsd}||| 5}|jtt||||||| | | | | |}t|d }ddd|S|D]}t|||||||| | | | |  rd}|S#t $rd}YwxYw#1swY|SxYw)NPDestination dir (ddir) cannot be used in combination with stripdir or prependdirrz%workers must be greater or equal to 0r )_check_system_limits)ProcessPoolExecutor)r r Tfork forkserver) max_workers mp_context) ddirforcerxr legacyoptimizeinvalidation_moder$r%r&r')defaultr#F) ValueErrorconcurrent.futures.processr*concurrent.futuresr+NotImplementedErrorsysgetrecursionlimitrmultiprocessingget_start_method get_contextmaprrmin)rr r0r1r2r r3r4workersr5r$r%r&r'r+r*filessuccessr=r/executorresultsfiles r"rr0s0 X1Z5KGI I  {@AA!|C ? " ?))+ c) t%| j't%|j'j(vr| Si}tjj+|r|D]f}|r |dz||<|dk\r0|dk\r|nd}t,j.j1|| }|||<Ct,j.j1|}|||<h| dd | d d}}|d k(rU|s ttj2|j4}t7j8d t,j.j:d|d z}|j=D]/}t?|d5}|jAd}ddd|k7s/n| S |stEdjG| tI|D]}\}}||}tKjL|||d||} |dkDs,| s/|||dz }!tOjP||!dsStjR|tjT|!|  dk(rd} | S| S#1swYxYw#tB$rYwxYw#tJjV$r}"d} |dk\r| cYd}"~"S|rtEdjG|n tEddtXjZj\xstYj^}#|"j`jc|#dje|#}$tE|$Yd}"~"| Sd}"~"wtfthtBf$rf}%d} |dk\r| cYd}%~%S|rtEdjG|n tEddtE|%jjjldz|%Yd}%~%| Sd}%~%wwxYw)Nr)Tr zXHardlinking of duplicated bytecode makes sense only for more than one optimization levelcrr ) optimizationz.pyz<4sLLlrb zCompiling {!r}...)r4r5F)shallowz*** Error compiling {!r}...z*** )endbackslashreplace)errors:)7r7rrrbasenamersplitseplistzipremoverintsortedsetlensearchrrresolveparentsisfile importlibutilcache_from_sourcestatst_mtimestructpack MAGIC_NUMBERvaluesopenreadrrr enumerate py_compilecompilefilecmpcmpunlinklinkPyCompileErrorr;stdoutencodinggetdefaultencodingmsgencodedecode SyntaxError UnicodeError __class____name__)&r!r0r1r2r r3r4r5r$r%r&r'rDr dfilefullname_partsstripdir_parts ddir_partsspartopartmo opt_cfiles opt_leveloptcfileheadtailmtimeexpectchandleactualindexokprevious_cfileerrrvrxes& r"rrs. X1Z5KGI IGyy"H&.&:ryy"H 77  H %D E  T4(! 4! 4.) ?LE5~!!%(@ j) =GGLLX6EGGLLU3E(C :c(m$H#h-!+FG G ~ YYx  N RWW^^H%=   & & (X0F0F0H0P0P PNJ ww~~h!I(03 9%>'0A~)2C&^^==%C>9E,1Jy)%NN<>OQBqy^)3HUQY4G)H";;uneLIIe,GGNE:)<@7#G N7N[/. ,, A:"N7>>xHI&b)::..J#2H2H2JggnnX6HnIPPQYZc  N w7 5A:"N7>>xHI&b)akk**S0!44 N 5s A:P)P P)#P)6P8=P8#P8$-P8P& "P)) P54P58U- S0U-BS00U-U(U-A U((U-c  d}tjD]B}|r|tjk(r|r|dks t d,|xrt ||d|||||}D|S)NTr zSkipping current directory)r r3r4r5)r;rrrrr) skip_curdirr r1r r3r4r5rDrs r"rrsl Gxxsbii'[qy23 +!"3 #G  Nc ddl}|jd}|jdddddd|jd td d |jd ddd|jddddd|jdddd|jddddd|jdd d!dd"|jd#d$d%dd&|jd'd(d)dd*|jd+d,d-d./|jd0d1d2d34|jd5d6d7td89tj Dcgc],}|j jjd:d;.}}|jd|jd?d@tdAdBC|jdDdEdFdG/|jdHddIdJ|j}|j}|jr$ddl }|j|j|_ |jdKk(rd|_|j |j }n |j"}|j$dLg|_t'|j$d7k(r|j(r|j+dM|j,)|j. |j0|j+dN|j2rg |j2d;k(rt4j6nt9|j2dOP5}|D]!} |j;| j=# ddd|jFr>|jFjd;d:jI} tj | } nd} dT} |r4|D],} tJjLjO| rtQ| |j,|jR|j|j@|jT| |j.|j0|j$|j|j(U rdS} tW| ||j,|jR|j|j@|jT|jX| |j.|j0|j$|j|j(Vr+dS} /| St[|jT|jR|j@| WScc}w#1swYxYw#t>$r6|j@dQkr$tCdRjE|j2YySwxYw#t\$r|j@dQkr tCdXYySwxYw)YNrz1Utilities to support installing Python libraries.) descriptionz-l store_constr z!don't recurse into subdirectories)actionconstr6desthelpz-r recursionzhcontrol the maximum recursion level. if `-l` and `-r` options are specified, then `-r` takes precedence.)typerrz-f store_truer1z/force rebuild even if timestamps are up to date)rrrz-qcountr zIoutput only error messages; -qq will suppress the error messages as well.)rrr6rz-br3z0use legacy (pre-PEP3147) compiled file locationsz-dDESTDIRr0zdirectory to prepend to file paths for use in compile-time tracebacks and in runtime tracebacks in cases where the source file is unavailable)metavarrr6rz-sSTRIPDIRr$zpart of path to left-strip from path to source file - for example buildroot. `-d` and `-s` options cannot be specified together.z-p PREPENDDIRr%zpath to add as prefix to path to source file - for example / to make it absolute when some part is removed by `-s` option. `-d` and `-p` options cannot be specified together.z-xREGEXPr2zskip files matching the regular expression; the regexp is searched for in the full path of each file considered for compilationz-iFILEflistzzadd all the files and directories listed in FILE to the list considered for compilation; if "-", names are read from stdin)rrr compile_destzFILE|DIR*zrzero or more file and directory names to compile; if no arguments given, defaults to the equivalent of -l sys.path)rnargsrz-jz --workersr zRun compileall concurrently)r6rr_-z--invalidation-modezset .pyc invalidation mode; defaults to "checked-hash" if the SOURCE_DATE_EPOCH environment variable is set, and "timestamp" otherwise.)choicesrz-oappend opt_levelszOptimization levels to run compilation with. Default is -1 which uses the optimization level of the Python interpreter itself (see -O).)rrrrz-eDIRr&z+Ignore symlinks pointing outsite of the DIRz--hardlink-dupesr'zHardlink duplicated pyc filesrJzYHardlinking of duplicated bytecode makes sense only for more than one optimization level.z.-d cannot be used in combination with -s or -pzutf-8)rvr zError reading file list {}FT)r5r$r%r4r&r')rBr5r$r%r4r&r')r3r1r r5z [interrupted])/argparseArgumentParser add_argumentrZrnPycInvalidationModer lowerreplacer[ parse_argsrr2reror&rr rr]r'errorr0r$r%rr;stdinrkrstriprr rrr5upperrrrarr1r3rrBrKeyboardInterrupt)rparsermodeinvalidation_modesargs compile_destsrr flineivl_moder5rDrs r"mainr:sl  $ $G%IF ]! $;@B 3[<> \NP W7A;< \OQ ivt,.  j $46  l, $46 hT4HJ f7BD  #AC k1 'DF'1&D&DF&Dd))//+33C=&DF - &'9 :79  XClKM e/JL *<-<>    D%%M ww**TWW% R! ~~!NN NN  $ 4??q T%8%8 C E yy !T__%@ EF zz #zz3#))g67;<D!((67 ))11#s;AAC&::8D G  %77>>$''diiTWW(, DKK:K1537??156:6H6H7;7J7JL#(&tY '+zz477DJJ'+{{DLL9J04 26//04595G5G6:6I6IK#(+&,Nt{{$**&*jj2CE EuF`77 zzA~299$**EF R  ::> # $sV61S56T'S::TB#U 5B U U ,U :T?Trs    7..7Z ePgdZ!e!D],Z"ee#e de"zjjIdzz Z.ee jJjz Z[!["d#dZ&d#dZ'dZ(dZ)dddZ*d$dZ+dZ,dZ-dZ.dZ/d Z0d!Z1e2d"k(rddl3Z3e3jbyy)%a The Python Debugger Pdb ======================= To use the debugger in its simplest form: >>> import pdb >>> pdb.run('
') The debugger's prompt is '(Pdb) '. This will stop in the first function call in . Alternatively, if a statement terminated with an unhandled exception, you can use pdb's post-mortem facility to inspect the contents of the traceback: >>> >>> import pdb >>> pdb.pm() The commands recognized by the debugger are listed in the next section. Most can be abbreviated as indicated; e.g., h(elp) means that 'help' can be typed as 'h' or 'help' (but not as 'he' or 'hel', nor as 'H' or 'Help' or 'HELP'). Optional arguments are enclosed in square brackets. Alternatives in the command syntax are separated by a vertical bar (|). A blank line repeats the previous command literally, except for 'list', where it lists the next 11 lines. Commands that the debugger doesn't recognize are assumed to be Python statements and are executed in the context of the program being debugged. Python statements can also be prefixed with an exclamation point ('!'). This is a powerful way to inspect the program being debugged; it is even possible to change variables or call functions. When an exception occurs in such a statement, the exception name is printed but the debugger's state is not changed. The debugger supports aliases, which can save typing. And aliases can have parameters (see the alias help entry) which allows one a certain level of adaptability to the context under examination. Multiple commands may be entered on a single line, separated by the pair ';;'. No intelligence is applied to separating the commands; the input is split at the first ';;', even if it is in the middle of a quoted string. If a file ".pdbrc" exists in your home directory or in the current directory, it is read in and executed as if it had been typed at the debugger prompt. This is particularly useful for aliases. If both files exist, the one in the home directory is read first and aliases defined there can be overridden by the local file. This behavior can be disabled by passing the "readrc=False" argument to the Pdb constructor. Aside from aliases, the debugger is not directly programmable; but it is implemented as a class from which you can derive your own debugger class, which you can make as fancy as you like. Debugger commands ================= N)UnionceZdZdZy)RestartzBCauses a debugger to be restarted for the debugged python program.N)__name__ __module__ __qualname____doc__/usr/lib64/python3.12/pdb.pyrr[sLr r) runpmPdbrunevalrunctxruncall set_trace post_mortemhelpc@tjdtj|z} tj|}|5t |dD]&\}}|j|s|||fccdddS dddy#t $rYywxYw#1swYyxYw)Nzdef\s+%s(\s*\[.+\])?\s*[(])start)recompileescapetokenizeopenOSError enumeratematch)funcnamefilenamecrefplinenolines r find_functionr'bs **2RYYx5HH IC ]]8 $ %b2LFDyy611 2     s)B%B*B:B BBBcttj|}|j|D]\}}||k\s |cSyNr)listdisfindlinestartsreverse)codelasti linestartsir%s r lasti2linenor2osBc((./J 6 A:M  r ceZdZdZdZy)_rstrz#String that doesn't quote its repr.c|SNr selfs r __repr__z_rstr.__repr__zs r N)rrrr r9r r r r4r4xs -r r4cTeZdZfdZdZedZedZedZxZ S) _ScriptTargetcpt||tjj |}||_|Sr6)super__new__ospathrealpathorig)clsvalres __class__s r r>z_ScriptTarget.__new__s0goc277#3#3C#89 r ctjj|s,td|jdt j dtjj|r,td|jdt j dtjj|t jd<y)NzError:zdoes not existrzis a directoryr) r?r@existsprintrBsysexitisdirdirnamer7s r checkz_ScriptTarget.checksvww~~d# (DII'7 8 HHQK 77==  (DII'7 8 HHQKggood+ r c|Sr6r r7s r r"z_ScriptTarget.filenames r c(td|tdS)N__main__)r__file__ __builtins____spec__)dictrSr7s r namespacez_ScriptTarget.namespaces%   r ctj|5}d|jd|dcdddS#1swYyxYw)Nz exec(compile(z, z , 'exec')))io open_coderead)r8r$s r r.z_ScriptTarget.codes4 \\$ 2"2779-r$D  s 7A) rrrr>rNpropertyr"rVr. __classcell__)rFs@r r;r;~sK ,  EEr r;cveZdZdZej dZedZedZ edZ edZ y) _ModuleTargetc |jy#t$r-}td|tjdYd}~yd}~wt $r,t jtjdYywxYw)Nz ImportError: r)_details ImportErrorrIrJrK Exception traceback print_exc)r8es r rNz_ModuleTarget.checksY  MM  M!% & HHQKK     ! HHQK s  A8#A5A87A8c,ddl}|j|Sr))runpy_get_module_details)r8rgs r r`z_ModuleTarget._detailss((..r c.|jjSr6)r. co_filenamer7s r r"z_ModuleTarget.filenamesyy$$$r c&|j\}}}|Sr6r`r8namespecr.s r r.z_ModuleTarget.code==dD r c&|j\}}}|Sr6rlrms r _specz_ModuleTarget._specrpr ctdtjjtjj |j |j j|j j|j tS)NrQ)rrR __package__ __loader__rTrS) rUr?r@normcaseabspathr"rrparentloaderrSr7s r rVz_ModuleTarget.namespacesYWW%%bggoodmm&DE ))zz((ZZ%   r N) rrrrN functoolscached_propertyr`r[r"r.rrrVr r r r^r^sq//%%  r r^z -> ceZdZdZ dXdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZeZdYdZ dZ!e Z"eZ#eZ$dZ%eZ&d Z'd!Z(d"Z)eZ*d#Z+eZ,d$Z-eZ.d%Z/eZ0d&Z1e1Z2eZ3eZ4d'Z5e5Z6e5Z7d(Z8d)Z9e9Z:d*Z;e;Zd,Z?e?Z@d-ZAeAZBd.ZCeCZDd/ZEeEZFd0ZGeGxZHZId1ZJeJZKd2ZLeZMd3ZNeNZOeNZPd4ZQd5ZReRZSd6ZTeTZUd7ZVdZd8ZWd9ZXd:ZYd;ZZd<Z[d=Z\eZ]eZ^eZ_d>Z`e`Zad?ZbebZcd@ZdeZed[dAZfdBZgeZhdCZieZjdDZkdEZldFZmdGZndHZodIZpgdJZqdKZresfdLZtdMZueuZvdNZwdOZxdPZydQeze{e|ffdRZ}dSe~fdTZdUZdVZdWZy)\rNcFtjj||tjj||||t j d|rd|_d|_i|_ i|_ d|_ d|_ i|_ ddl}|jdd|_||_g|_|r t)t*j,j/dd 5}|j&j1|ddd t)d d 5}|j&j1|dddi|_i|_i|_d|_d|_y#t $rYwxYw#1swYnxYw#t2$rY|wxYw#1swYWxYw#t2$rYewxYw) N)skipzpdb.Pdbrz(Pdb) Fz `@#$%^&*()=+[{]}\|;:'",<>?z~/.pdbrczutf-8)encodingz.pdbrc)bdbBdb__init__cmdCmdrJaudit use_rawinputpromptaliases displaying mainpyfile_wait_for_mainpyfile tb_linenoreadlineset_completer_delimsra allow_kbdintnosigintrcLinesrr?r@ expanduserextendrcommandscommands_dopromptcommands_silentcommands_defining commands_bnum) r8 completekeystdinstdoutr~rreadrcrrcFiles r rz Pdb.__init__sy D) {E6: )  !D   $)!    ) )*M N"    "'',,Z87KvLL''/L (W5LL''/6  !#!!&!5   LK  65  sf E:*E9$E-E9 FF2F E*)E*-E62E99 FFF F F F c|jrt|jd|j|j |y)Nz- Program interrupted. (Use 'cont' to resume).)rKeyboardInterruptmessageset_stepr)r8signumframes r sigint_handlerzPdb.sigint_handler s3   # # EF  ur cbtjj||jyr6)rrresetforgetr7s r rz Pdb.resets  d r cd|_g|_d|_t|dr2|jr&|jj j ddd|_i|_|jjy)Nrcurframe__pdb_convenience_variables) r%stackcurindexhasattrr f_globalspopcurframe_localsrclearr7s r rz Pdb.forgetsa   4 $ MM # # ' '(Et L ! r c|j|j||\|_|_|rRt |j j |j}||j|j <|j}|rR|j|jd|_ |jj|_ |j|jd|j|jrV|jDcgc]3}|jr!|jj!ds|5c}|_g|_yycc}w)Nr_frame#)r get_stackrrr2tb_framef_codetb_lastirtb_nextrf_localsrset_convenience_variablerstrip startswithcmdqueue)r8ftbr%r&s r setupz Pdb.setups $(NN1b$9! DM""++"4"4bkkBF*0DNN2;; 'B  4==1!4  $}}55 %%dmmXt}}M <>% LL $   UD ) !r c|jr:|j|j|jjk7ryd|_|j |r|j |dyy)z;This function is called when we stop or break at this line.NF)rrcanonicrrj bp_commandsr)r8rs r user_linez Pdb.user_lineBsX  $ $4<< 0H0H#II(-D %   E "   UD ) #r ct|ddr|j|jvr|j}d|_|j}|j |d|j|D]}|j |||_|j |s(|j|j|j|j|r|j|jyy)zCall every command that was set for the current active breakpoint (if there is one). Returns True if the normal interaction function must be called, False otherwise. currentbpFrNr) getattrrrlastcmdronecmdrprint_stack_entryrrr_cmdloopr)r8rr lastcmd_backr&s r rzPdb.bp_commandsKs 4e ,~~.IDN< tjtjtjdt_|j |||j jd|j|j r,|j ddk(r|j j|jy#t$rYwxYw)N_pdbcmd_print_frame_status) r_previous_sigint_handlersignalSIGINT ValueErrorrrappendrrr)r8rrcs r rzPdb.interactions  ' ' 4 fmmS-I-IJ04, 5)$ 9:  ==T]]2.2NN MM      s2C C! C!c>||jt|yy)z{Custom displayhook for the exec in default(), which prevents assignment of the _ variable in the builtins. N)rrepr)r8objs r displayhookzPdb.displayhooks ? LLc # r cV|dddk(r|ddj}|j}|jj} t |dzdd}t j }t j}t j} |jt _|j t _|jt _t||||t _|t _|t _y#|t _|t _|t _wxYw#|jYyxYw)Nr! single) rrrrrrJrrrexec _error_exc)r8r&localsglobalsr. save_stdout save_stdinsave_displayhooks r defaultz Pdb.defaults 8s?48>>#3D%%--)) 4$; 8>$- -**40 0r c|j|\}}}|sy|dk(rd|j|j<y|dk(ry|j|j}|r|j |dz|zn|j | t |d|z}|j|jvrd|j|j<yy#t $r|j}YJwxYw)z8Handles one command line during command list definition.FsilentTrr!do_) r3rrrrrAttributeErrorr rcommands_resumingr)r8r&rr6cmdlistfuncs r r4zPdb.handle_command_defs-S$ (?7;D !3!3 4 E\-- 2 23  NN3s73; ' NN3  4-D ==D22 29>D " "4#5#5 6  <c!f&7&7&=A$H? ??s1Ac|jsgSi|jj|j}d|vry|jd} ||d}|ddD]}t ||} dj|dddz} t|D cgc]} | j|ds| | zc} S|jD cgc]} | j|s| c} S#t t f$rgcYSwxYwcc} wcc} w)N.rrr) rrrr$rKeyErrorr:rdirrkeys) r8rSr&rTrUnsdottedrpartrns r rOzPdb._complete_expressioncs }}IA '' @4+?+? @ $;ZZ_F m"1RLD!#t,C)XXfSbk*S0F(+CM1ALL4LFQJM M "wwy?y!ALL,>Ay? ? n-   N@s* C C7&C7C<C< C43C4ct|j|j|j|jyr6)rrrrr8r6s r rzPdb._pdbcmd_print_frame_status~s) tzz$--89 r c|s'ttjjdz }n t |} |j |||_||jvr-|j||j||j|f}nd}g|j|<d|j|<d|j|<|j}d|_ d|_ |jd|_ ||_ y#|j dYyxYw#t$r}|j d|zYd}~yd}~wwxYw#t$rt|r7|d|j|<|d|j|<|d |j|<n'|j|=|j|=|j|=|j d YwxYw#d|_ ||_ wxYw) a:(Pdb) commands [bpnumber] (com) ... (com) end (Pdb) Specify a list of commands for breakpoint number bpnumber. The commands themselves are entered on the following lines. Type a line containing just 'end' to terminate the commands. The commands are executed when the breakpoint is hit. To remove all commands from a breakpoint, type commands and follow it immediately with end; that is, give no commands. With no bpnumber argument, commands refers to the last breakpoint set. You can use breakpoint commands to start your program up again. Simply use the continue command, or step, or any other command that resumes execution. Specifying any command resuming execution (currently continue, step, next, return, jump, quit and their abbreviations) terminates the command list (as if that command was immediately followed by end). This is because any time you resume execution (even with a simple next or step), you may encounter another breakpoint -- which could have its own command list, leading to ambiguities about which list to execute. If you use the 'silent' command in the command list, the usual message about stopping at a breakpoint is not printed. This may be desirable for breakpoints that are to print a specific message and then continue. If none of the other commands print anything, you will see no sign that the breakpoint was reached. rz.Usage: commands [bnum] ... endNzcannot set commands: %sTFz(com) rr#z1command definition aborted, old commands restored)lenrr[r\intrEget_bpbynumberrrrrrrrrr)r8r6bnumerrold_command_defs prompt_backs r do_commandszPdb.do_commandssJs~~001A5D 3x     % " 4== $ d 3 $ 6 6t < $ 4 4T : <  $   d'+t$%*T"kk  !% & LLN&+D "%DKO  MN  JJ036 7  *! L&6q&9 d#/?/B&&t,-=a-@$$T*MM$'**40((. JJJ K L&+D "%DKsG C3D D53D D2D--D25A:F2/F51F22F55Gc|s_|jrR|jdtjjD]$}|s|j|j &yd}d}d}|j d}|dkDrT||dzdj}|j|x}r|jd|d|y|d|j}|jd} d} | dk\r`|d| j}|j|} | s|jd |zy| }|| dzdj} t|}n t|}|s|j5}|j7||}|rt|j9||||| }|r|j|y|j;||d }|jd|j<|j>|j@fzyy#t$r|jd |zYywxYw#t$r t||j j"|j$} n #|} YnxYw t'| d r | j(} | j*} | j,} | j.}| j0}nB#|j3|\}}}|s|jd |zYYy|} t|}YnxYwYwxYw)ab(reak) [ ([filename:]lineno | function) [, condition] ] Without argument, list all breaks. With a line number argument, set a break at this line in the current file. With a function name, set a break at the first executable line of that function. If a second argument is present, it is a string specifying an expression which must evaluate to true before the breakpoint is honored. The line number may be prefixed with a filename and a colon, to specify a breakpoint in another file (probably one that hasn't been loaded yet). The file is searched for on sys.path; the .py suffix may be omitted. z!Num Type Disp Enb WhereNrJrrInvalid condition rrIz%r not found from sys.pathzBad lineno: %s__func__zJThe specified object %r is not a function or was not found along sys.path.rzBreakpoint %d at %s:%d)!breaksrrr[r\bpformatr'r(_compile_error_messagerEr*rfind lookupmodulerlrevalrrrrru__code__co_nameco_firstlinenorjlineinfo defaultFile checkline set_break get_breaksnumberr@r&)r8r6 temporaryr]r"r%condcommarocolonr!rr=r.oklnr&s r do_breakz Pdb.do_breaks {{ @A..33B R[[]34   19uQwx='')D11$77s7 sCDfu+$$&C # A:6E{))+H!!(+A 7(BCeAgh-&&(C S  %S4'')H~~h/ ..4D(KC 3__Xt4R8 5 ii"'':;< I  +c12  % $ 7 7 $ 4 46DD%tZ0#}}==D $||H!00F#//H%)-s);&R2 $FHK$LM!H WF1 %sa> G1 H1HH K#+I  K# IK#AJK#-K K# KK#"K#c|jjj}|dk(r|jr |j}|S)zProduce a reasonable default.z)rrrjr)r8r"s r rzPdb.defaultFile<s3==''33 z !dooHr c(|j|dy)ztbreak [ ([filename:]lineno | function) [, condition] ] Same arguments as break, but sets a temporary breakpoint: it is automatically deleted when first hit. rN)rris r do_tbreakz Pdb.do_tbreakHs c1r cd}|jd}t|dk(r|dj}n$t|dk(r|dj}n|S|dk(r|S|jd}|ddk(r|d=t|dk(r|S|j}t|dk(r|d}n|j |d}|r|}|d}t ||} | xs|S) N)NNN'rrrr`r8)r$rkrrrzr') r8 identifierfailedidstringidpartsfnameitemranswers r rz Pdb.lineinfoRs###C( x=A !""$B ]a !""$BM 8F]  8v a5zQ   " u:?8D!!%(+A8DtU+r ct|dd}|r |jnd}tj|||}|s|j dy|j }|r|ddk(s|dddk(s|dddk(r|j d y|S) zCheck whether specified line seems to be executable. Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank line or EOF). Warning: testing is not comprehensive. rNz End of filerrrz"""z'''zBlank or comment)rr linecachegetlinerrrE)r8r"r%rrWr&s r rz Pdb.checklinessj$/#(d  659 LL 'zz|aC2Ah%D!H$5 JJ) * r c|j}|D]8} |j|}|j|jd|z:y#t$r}|j |Yd}~[d}~wwxYw)zenable bpnumber [bpnumber ...] Enables the breakpoints given as a space separated list of breakpoint numbers. z Enabled %sN)r$rmenablerrrEr8r6r+r1r]ros r do_enablez Pdb.do_enablesi yy{A 0((+  \B./  3 A A3A..A3c|j}|D]8} |j|}|j|jd|z:y#t$r}|j |Yd}~[d}~wwxYw)aOdisable bpnumber [bpnumber ...] Disables the breakpoints given as a space separated list of breakpoint numbers. Disabling a breakpoint means it cannot cause the program to stop execution, but unlike clearing a breakpoint, it remains in the list of breakpoints and can be (re-)enabled. z Disabled %sN)r$rmdisablerrrErs r do_disablezPdb.do_disablesiyy{A 1((+  ]R/0  3 rc|jdd} |d}|j|x}r|jd|d|y |j |dj }||_|s|jd|jzy|jd|jzy#t$rd}YwwxYw#t$r|jd Yyt$r}|j|Yd}~yd}~wwxYw) a$condition bpnumber [condition] Set a new condition for the breakpoint, an expression which must evaluate to true before the breakpoint is honored. If condition is absent, any existing condition is removed; i.e., the breakpoint is made unconditional. r!rrtrNrz#Breakpoint %d is now unconditional.z$New condition set for breakpoint %d.Breakpoint number expected) r$rxrE IndexErrorrmrrrrr)r8r6r+rror]s r do_conditionzPdb.do_conditionsyya  7D11$77s7 sCD8 Q$$T!W]]_5B BG BRYYNO CbiiOP D  5 JJ3 4  JJsOO s//B/"C/ B=<B=C?C?$C::C?c|j} t|dj} |j|dj}||_|dkDr.|dkDrd|z}nd}|j d||j fzy|j d|j zy#d}YxYw#t$r|jdYyt$r}|j|Yd}~yd}~wwxYw) aignore bpnumber [count] Set the ignore count for the given breakpoint number. If count is omitted, the ignore count is set to 0. A breakpoint becomes active when the ignore count is zero. When non-zero, the count is decremented each time the breakpoint is reached and the breakpoint is not disabled and any associated condition evaluates to true. rrz %d crossingsz 1 crossingz%Will ignore next %s of breakpoint %d.z-Will stop next time breakpoint %d is reached.rN) r$rlrrmignorerrrrEr)r8r6r+countr]countstrros r do_ignorez Pdb.do_ignoresyy{ Q (E *$$T!W]]_5B BIqy19-5H+H D& 234 L!yy)*% E 5 JJ3 4  JJsOO s(B*"B3*B03C2C2C--C2cZ|s td}|jj}|dvrUtj j Dcgc]}|s| }}|j|D]}|jd|zyd|vr|jd}|d|}||dzd} t|}|j||dd}|j||}|r|j|yD]}|jd|zy|j} | D]9} |j!|}|j#||jd|z;y#t$rd}YZwxYwcc}w#t$rd|z}YwxYw#t$r}|j|Yd}~d}~wwxYw) a.cl(ear) [filename:lineno | bpnumber ...] With a space separated list of breakpoint numbers, clear those breakpoints. Without argument, clear all breaks (but first ask confirmation). With a filename:lineno argument, clear all breaks at that line in that file. zClear all breaks? no)yyesz Deleted %sNrIrzInvalid line number (%s))inputEOFErrorrrRrr[r\clear_all_breaksrryrlr clear_breakrrEr$rmclear_bpbynumber) r8r6replyr]bplistr1r"r%ro numberlists r do_clearz Pdb.do_clears 23KKM'')E $'*~~'@'@G'@B"'@G%%' BLL!23!  #: #A2AwHacd)C 9S6:1=&&x8 3 !BLL!23! YY[ A 0((+%%a( \B./9  H 7036 7  3 sG E E-E-* E2"F E*)E*2FF F*F%%F*c$|jy)zw(here) Print a stack trace, with the most recent frame at the bottom. An arrow indicates the "current frame", which determines the context of most commands. 'bt' is an alias for this command. N)print_stack_traceris r do_wherez Pdb.do_where's  r c|d|cxkrt|jksJJ||_|j|jd|_|jj|_|j |jd|j|j|j|jd|_y)Nrr) rkrrrrrrrr%)r8rs r _select_framezPdb._select_frame2sF,S_,,,,,  4==1!4 #}}55 %%dmmXt}}M tzz$--89 r c|jdk(r|jdy t|xsd}|dkrd}nt d|j|z }|j |y#t$r|jd|zYywxYw)zu(p) [count] Move the current frame count (default one) levels up in the stack trace (to an older frame). rz Oldest frameNrInvalid frame count (%s))rrErlrmaxrr8r6rnewframes r do_upz Pdb.do_up;s ==A  JJ~ &  qME 19H1dmme34H 8$  JJ1C7 8  sA%%BBc|jdzt|jk(r|jdy t |xsd}|dkrt|jdz }n/t t|jdz |j|z}|j|y#t $r|jd|zYywxYw)zd(own) [count] Move the current frame count (default one) levels down in the stack trace (to a newer frame). rz Newest frameNrr)rrkrrErlrminrrs r do_downz Pdb.do_downPs ==1 DJJ / JJ~ &  qME 194::*H3tzz?Q. 0EFH 8$  JJ1C7 8  sB''CCc|r7 t|}||jjkr|jdyd}|j |j|y#t$r|jd|zYywxYw)aOunt(il) [lineno] Without argument, continue execution until the line with a number greater than the current one is reached. With a line number, continue execution until a line with a number greater or equal to that is reached. In both cases, also stop when the current frame returns. Error in argument: %rNz7"until" line number is smaller than current line numberr)rlrrErf_lineno set_until)r8r6r%s r do_untilz Pdb.do_untiles}  S/// )*F t}}f-  2S89 s AA98A9c$|jy)zs(tep) Execute the current line, stop at the first possible occasion (either in a function that is called or in the current function). r)rris r do_stepz Pdb.do_step~s r c:|j|jy)zyn(ext) Continue execution until the next line in the current function is reached or it returns. r)set_nextrris r do_nextz Pdb.do_nexts dmm$r c|rEddl}tjdd} |j|t_|tjddt #t$r!}|j d|d|Yd}~yd}~wwxYw)arun [args...] Restart the debugged python program. If a string is supplied it is split with "shlex", and the result is used as the new sys.argv. History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run". rNrz Cannot run r)shlexrJargvr$rrEr)r8r6rargv0res r do_runz Pdb.do_runsj  HHQqME  ;;s+!CHHRaL   #q9: sA A8A33A8c:|j|jy)zQr(eturn) Continue execution until the current function returns. r) set_returnrris r do_returnz Pdb.do_returns  &r c|js8 tjtj|jt_|jy#t $rYwxYw)z^c(ont(inue)) Continue execution, only stop when a breakpoint is encountered. r)rrrrrrr set_continueris r do_continuezPdb.do_continuesW }} MM&--1D1DE,     s7A A"!A"c|jdzt|jk7r|jdy t |} ||j _|j|jd|f|j|j<|j|j|jy#t$r}|jd|zYd}~yd}~wwxYw#t$r|jdYywxYw)aj(ump) lineno Set the next line that will be executed. Only available in the bottom-most frame. This lets you jump back and execute code again, or jump forward to skip code that you don't want to run. It should be noted that not all jumps are allowed -- for instance it is not possible to jump into the middle of a for loop or out of a finally clause. rz)You can only jump within the bottom frameNrzJump failed: %sz)The 'jump' command requires a line number) rrkrrErlrrrr)r8r6res r do_jumpz Pdb.do_jumps ==1 DJJ / JJB C  2c(C 2*- &,0JJt}},Ea,H#,M 4==)&&tzz$--'@A 2 ,q011 2 D JJB C Ds* CA.B44 C=CCC;:C;c6tjd|jj}|j}t |j |j|j}d|jjz|_ |jd tj|j|||f|jdtj|j |j"|_y#t$r|jY]wxYw)zdebug code Enter a recursive debugger that steps through the code argument (which is an arbitrary expression or statement to be executed in the current environment). Nz(%s) zENTERING RECURSIVE DEBUGGERzLEAVING RECURSIVE DEBUGGER)rJsettracerrrrrrrrrr call_tracingr rbrtrace_dispatchr)r8r6rrps r do_debugz Pdb.do_debugs T--))%%   $**dkk :T[[..00 23    QUUS'6$: ; 12 T(()yy   OO  s#C<<DDc2d|_|jy)z^q(uit) | exit Quit from the debugger. The program being executed is aborted. Tr)_user_requested_quitset_quitris r do_quitz Pdb.do_quits %)! r cT|jdd|_|jy)z>EOF Handles the receipt of EOF as a command. rTr)rrrris r do_EOFz Pdb.do_EOFs$ R$(! r c |jj}|j}|j|jz}|j t jzr|dz}|j t jzr|dz}t|D]S}|j|}||vr*|j|d|j|||@|j|dUy)zIa(rgs) Print the argument list of the current function. r = z = *** undefined ***N) rrr co_argcountco_kwonlyargcountco_flagsinspect CO_VARARGSCO_VARKEYWORDSrange co_varnamesrr)r8r6corUrgr1rns r do_argsz Pdb.do_argss ]] ! !## NNR11 1 ;;++ +1Q ;;// /QqSqA>>!$Dt| $T D0QRS ?@ r cd|jvr/|j|j|jddy|jdy)zRretval Print the return value for the last return of a function. rretvalzNot yet returned!N)rrrrEris r do_retvalz Pdb.do_retval"sA 4// / LL)=)=l)KXV W JJ* +r c t||jj|jS#|j xYwr6)r{rrrrris r _getvalz Pdb._getval-s: T]]44d6J6JK K  OO  s *-Ac |+t||jj|jSt||j|jS#t $r'}t d|j|zcYd}~Sd}~wwxYw)Nz** raised %s **)r{rrrr BaseExceptionr4r)r8r6rexcs r rzPdb._getval_except4sq D}C!8!8$:N:NOOC%..AA D*T-=-=c-BBC C Ds",A A BA;5B;Bcltj}|j|j|yr6)rJ exceptionrErr8rs r rzPdb._error_exc=s$mmo 4##C()r c |j|} |j||y#YyxYw#|jYyxYwr6)rrr)r8r6r=rDs r _msg_val_funczPdb._msg_val_funcAsD ,,s#C  LLc #    OO s,30Ac  t|S#t$r+}td|d|j|dcYd}~Sd}~wwxYw)Nz *** repr(z ) failed: z ***)rrbr4r)r8rrres r rzPdb._safe_reprKsJ P9  P9TF*T5E5Ea5H4INO O Ps A <AAc0|j|ty)zAp expression Print the value of the expression. N)rrris r do_pzPdb.do_pQs 3%r cD|j|tjy)zIpp expression Pretty-print the value of the expression. N)rpprintpformatris r do_ppz Pdb.do_ppXs 3/r c d|_d}|r|dk7r d|vrQ|jd\}}t|j}t|j}||kr.||z}n(t|j}t d|dz }nD|j|dk(r$t d|jjdz }n|jdz}||dz}|jjj}|jd r7|jjjd }t|t r|}|j#|} t%j&||jj}|j)||dz ||||jt+|t-||_t-||kr|j/d yy#t $r|j d|zYywxYw#t0$rYywxYw) al(ist) [first[, last] | .] List source code for the current file. Without arguments, list 11 lines around the current line or continue the previous listing. With . as argument, list 11 lines around the current line. With one argument, list 11 lines starting at that line. With two arguments, list the given range; if the second argument is less than the first, it is a count. The current line in the current frame is indicated by "->". If an exception is being debugged, the line where the exception was originally raised or propagated is indicated by ">>", if it differs from the current line. r*Nr`rJrr z=G> H  H c.|jjj}|j|} |j |j\}}|j||||jy#t $r}|j |Yd}~yd}~wwxYw)z]ll | longlist List the whole source code for the current function or frame. N)rrrjr_getsourcelinesrrEr)r8r6r"rrr%ros r do_longlistzPdb.do_longlists ==''33((2   00?ME6 %DMMB  JJsO  sA00 B9BBc |j|} |j|\}}|j ||y#YyxYw#ttf$r}|j |Yd}~yd}~wwxYw)z_source expression Try to get source code for the given object and display it. N)rrr TypeErrorrEr)r8r6rrr%ros r do_sourcez Pdb.do_sourcesn  ,,s#C  005ME6 %(  #  JJsO  s;A?A,A''A,cv|r)|j}|jj|d}ndx}}t||D]{\}}t |j d} t | dkr| dz } ||vr| dz } n| dz } ||k(r| dz } n ||k(r| dz } |j| dz|jz}y ) zPrint a range of lines.rrr!Bz->z>> N) rrrrr&rjustrkrr*) r8rrrvrcurrent_lineno exc_linenor%r&ss r rzPdb._print_liness "^^N++E26J*, ,NZ%eU3LFDF !!!$A1vzSSS'T :%T  LLTDKKM1 24r c |j|}d} |jj}|r|j d|j zy |j}|r|j d|j zy|j tur,|j d|jd|jy|j t|y#YyxYw#t$rYwxYw#t$rYwxYw)zCwhatis expression Print the type of the argument. Nz Method %sz Function %szClass r`) rrur|rbrr}rFtyperr)r8r6rGr.s r do_whatisz Pdb.do_whatiss  LL%E >>**D  LLt||3 4  >>D  LL5 6  ??d " LL%*:*:E