aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature')
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/PSF-3.7.0.txt43
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/__init__.py44
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/backport_inspect.py956
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py140
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/fix-complaints.py91
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py246
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py40
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py168
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py195
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py683
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py314
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json13
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/typing27.py2293
13 files changed, 5226 insertions, 0 deletions
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/PSF-3.7.0.txt b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/PSF-3.7.0.txt
new file mode 100644
index 000000000..be42010dd
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/PSF-3.7.0.txt
@@ -0,0 +1,43 @@
+PSF LICENSE AGREEMENT FOR PYTHON 3.7.0
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and
+ the Individual or Organization ("Licensee") accessing and otherwise using Python
+ 3.7.0 software in source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+ grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+ analyze, test, perform and/or display publicly, prepare derivative works,
+ distribute, and otherwise use Python 3.7.0 alone or in any derivative
+ version, provided, however, that PSF's License Agreement and PSF's notice of
+ copyright, i.e., "Copyright © 2001-2018 Python Software Foundation; All Rights
+ Reserved" are retained in Python 3.7.0 alone or in any derivative version
+ prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on or
+ incorporates Python 3.7.0 or any part thereof, and wants to make the
+ derivative work available to others as provided herein, then Licensee hereby
+ agrees to include in any such work a brief summary of the changes made to Python
+ 3.7.0.
+
+4. PSF is making Python 3.7.0 available to Licensee on an "AS IS" basis.
+ PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF
+ EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
+ WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
+ USE OF PYTHON 3.7.0 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 3.7.0
+ FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
+ MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 3.7.0, OR ANY DERIVATIVE
+ THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material breach of
+ its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any relationship
+ of agency, partnership, or joint venture between PSF and Licensee. This License
+ Agreement does not grant permission to use PSF trademarks or trade name in a
+ trademark sense to endorse or promote products or services of Licensee, or any
+ third party.
+
+8. By copying, installing or otherwise using Python 3.7.0, Licensee agrees
+ to be bound by the terms and conditions of this License Agreement.
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/__init__.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/__init__.py
new file mode 100644
index 000000000..9447e9c25
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/__init__.py
@@ -0,0 +1,44 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+# from shibokensupport.signature import get_signature, inspect, typing
+# This gives a problem with Python 2. We do it in the loader, instead.
+__all__ = "get_signature inspect typing layout mapping lib".split()
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/backport_inspect.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/backport_inspect.py
new file mode 100644
index 000000000..fbd82cc53
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/backport_inspect.py
@@ -0,0 +1,956 @@
+# This Python file uses the following encoding: utf-8
+# It has been edited by fix-complaints.py .
+
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function
+
+"""
+PSF LICENSE AGREEMENT FOR PYTHON 3.7.0
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and
+ the Individual or Organization ("Licensee") accessing and otherwise using Python
+ 3.7.0 software in source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+ grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+ analyze, test, perform and/or display publicly, prepare derivative works,
+ distribute, and otherwise use Python 3.7.0 alone or in any derivative
+ version, provided, however, that PSF's License Agreement and PSF's notice of
+ copyright, i.e., "Copyright © 2001-2018 Python Software Foundation; All Rights
+ Reserved" are retained in Python 3.7.0 alone or in any derivative version
+ prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on or
+ incorporates Python 3.7.0 or any part thereof, and wants to make the
+ derivative work available to others as provided herein, then Licensee hereby
+ agrees to include in any such work a brief summary of the changes made to Python
+ 3.7.0.
+
+4. PSF is making Python 3.7.0 available to Licensee on an "AS IS" basis.
+ PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF
+ EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
+ WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
+ USE OF PYTHON 3.7.0 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 3.7.0
+ FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
+ MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 3.7.0, OR ANY DERIVATIVE
+ THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material breach of
+ its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any relationship
+ of agency, partnership, or joint venture between PSF and Licensee. This License
+ Agreement does not grant permission to use PSF trademarks or trade name in a
+ trademark sense to endorse or promote products or services of Licensee, or any
+ third party.
+
+8. By copying, installing or otherwise using Python 3.7.0, Licensee agrees
+ to be bound by the terms and conditions of this License Agreement.
+"""
+
+__doc__ = """
+ signature() - get a Signature object for the callable
+"""
+
+import sys
+from collections import OrderedDict
+
+CO_OPTIMIZED = 0x0001
+CO_NEWLOCALS = 0x0002
+CO_VARARGS = 0x0004
+CO_VARKEYWORDS = 0x0008
+CO_NESTED = 0x0010
+CO_GENERATOR = 0x0020
+CO_NOFREE = 0x0040
+
+
+###############################################################################
+### Function Signature Object (PEP 362)
+###############################################################################
+
+
+# This function was changed: 'builtins' and 'qualname' don't exist.
+# We use '__builtin__' and '__name__' instead.
+# It is further changed because we use a local copy of typing
+def formatannotation(annotation, base_module=None):
+ if getattr(annotation, '__module__', None) == 'support.signature.typing27':
+ return repr(annotation).replace('support.signature.typing27', 'typing')
+ if isinstance(annotation, type):
+ if annotation.__module__ in ('__builtin__', base_module):
+ return annotation.__name__
+ return annotation.__module__+'.'+annotation.__name__
+ return repr(annotation)
+
+
+def _signature_is_functionlike(obj):
+ """Private helper to test if `obj` is a duck type of FunctionType.
+ A good example of such objects are functions compiled with
+ Cython, which have all attributes that a pure Python function
+ would have, but have their code statically compiled.
+ """
+
+ if not callable(obj) or isclass(obj):
+ # All function-like objects are obviously callables,
+ # and not classes.
+ return False
+
+ name = getattr(obj, '__name__', None)
+ code = getattr(obj, '__code__', None)
+ defaults = getattr(obj, '__defaults__', _void) # Important to use _void ...
+ kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here
+ annotations = getattr(obj, '__annotations__', None)
+
+ return (isinstance(code, types.CodeType) and
+ isinstance(name, str) and
+ (defaults is None or isinstance(defaults, tuple)) and
+ (kwdefaults is None or isinstance(kwdefaults, dict)) and
+ isinstance(annotations, dict))
+
+
+
+def _signature_from_function(cls, func):
+ """Private helper: constructs Signature for the given python function."""
+
+ is_duck_function = False
+ if not isfunction(func):
+ if _signature_is_functionlike(func):
+ is_duck_function = True
+ else:
+ # If it's not a pure Python function, and not a duck type
+ # of pure function:
+ raise TypeError('{!r} is not a Python function'.format(func))
+
+ Parameter = cls._parameter_cls
+
+ # Parameter information.
+ func_code = func.__code__
+ pos_count = func_code.co_argcount
+ arg_names = func_code.co_varnames
+ positional = tuple(arg_names[:pos_count])
+ keyword_only_count = 0 # func_code.co_kwonlyargcount
+ keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)]
+ annotations = func.__annotations__
+ defaults = func.__defaults__
+ kwdefaults = func.__kwdefaults__
+
+ if defaults:
+ pos_default_count = len(defaults)
+ else:
+ pos_default_count = 0
+
+ parameters = []
+
+ # Non-keyword-only parameters w/o defaults.
+ non_default_count = pos_count - pos_default_count
+ for name in positional[:non_default_count]:
+ annotation = annotations.get(name, _empty)
+ parameters.append(Parameter(name, annotation=annotation,
+ kind=_POSITIONAL_OR_KEYWORD))
+
+ # ... w/ defaults.
+ for offset, name in enumerate(positional[non_default_count:]):
+ annotation = annotations.get(name, _empty)
+ parameters.append(Parameter(name, annotation=annotation,
+ kind=_POSITIONAL_OR_KEYWORD,
+ default=defaults[offset]))
+
+ # *args
+ if func_code.co_flags & CO_VARARGS:
+ name = arg_names[pos_count + keyword_only_count]
+ annotation = annotations.get(name, _empty)
+ parameters.append(Parameter(name, annotation=annotation,
+ kind=_VAR_POSITIONAL))
+
+ # Keyword-only parameters.
+ for name in keyword_only:
+ default = _empty
+ if kwdefaults is not None:
+ default = kwdefaults.get(name, _empty)
+
+ annotation = annotations.get(name, _empty)
+ parameters.append(Parameter(name, annotation=annotation,
+ kind=_KEYWORD_ONLY,
+ default=default))
+ # **kwargs
+ if func_code.co_flags & CO_VARKEYWORDS:
+ index = pos_count + keyword_only_count
+ if func_code.co_flags & CO_VARARGS:
+ index += 1
+
+ name = arg_names[index]
+ annotation = annotations.get(name, _empty)
+ parameters.append(Parameter(name, annotation=annotation,
+ kind=_VAR_KEYWORD))
+
+ # Is 'func' is a pure Python function - don't validate the
+ # parameters list (for correct order and defaults), it should be OK.
+ return cls(parameters,
+ return_annotation=annotations.get('return', _empty),
+ __validate_parameters__=is_duck_function)
+
+
+
+
+class _void(object):
+ """A private marker - used in Parameter & Signature."""
+
+
+class _empty(object):
+ """Marker object for Signature.empty and Parameter.empty."""
+
+
+class _ParameterKind(object): # (enum.IntEnum):
+ POSITIONAL_ONLY = 0
+ POSITIONAL_OR_KEYWORD = 1
+ VAR_POSITIONAL = 2
+ KEYWORD_ONLY = 3
+ VAR_KEYWORD = 4
+
+ def __str__(self):
+ return self._name_
+
+
+_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY
+_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD
+_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL
+_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY
+_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD
+
+
+class Parameter(object):
+ """Represents a parameter in a function signature.
+
+ Has the following public attributes:
+
+ * name : str
+ The name of the parameter as a string.
+ * default : object
+ The default value for the parameter if specified. If the
+ parameter has no default value, this attribute is set to
+ `Parameter.empty`.
+ * annotation
+ The annotation for the parameter if specified. If the
+ parameter has no annotation, this attribute is set to
+ `Parameter.empty`.
+ * kind : str
+ Describes how argument values are bound to the parameter.
+ Possible values: `Parameter.POSITIONAL_ONLY`,
+ `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`,
+ `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`.
+ """
+
+ __slots__ = ('_name', '_kind', '_default', '_annotation')
+
+ POSITIONAL_ONLY = _POSITIONAL_ONLY
+ POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD
+ VAR_POSITIONAL = _VAR_POSITIONAL
+ KEYWORD_ONLY = _KEYWORD_ONLY
+ VAR_KEYWORD = _VAR_KEYWORD
+
+ empty = _empty
+
+ def __init__(self, name, kind, default=_empty, annotation=_empty):
+
+ if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD,
+ _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD):
+ raise ValueError("invalid value for 'Parameter.kind' attribute")
+ self._kind = kind
+
+ if default is not _empty:
+ if kind in (_VAR_POSITIONAL, _VAR_KEYWORD):
+ msg = '{} parameters cannot have default values'.format(kind)
+ raise ValueError(msg)
+ self._default = default
+ self._annotation = annotation
+
+ if name is _empty:
+ raise ValueError('name is a required attribute for Parameter')
+
+ if not isinstance(name, str):
+ raise TypeError("name must be a str, not a {!r}".format(name))
+
+ if name[0] == '.' and name[1:].isdigit():
+ # These are implicit arguments generated by comprehensions. In
+ # order to provide a friendlier interface to users, we recast
+ # their name as "implicitN" and treat them as positional-only.
+ # See issue 19611.
+ if kind != _POSITIONAL_OR_KEYWORD:
+ raise ValueError(
+ 'implicit arguments must be passed in as {}'.format(
+ _POSITIONAL_OR_KEYWORD
+ )
+ )
+ self._kind = _POSITIONAL_ONLY
+ name = 'implicit{}'.format(name[1:])
+
+ if not True: # name.isidentifier():
+ raise ValueError('{!r} is not a valid parameter name'.format(name))
+
+ self._name = name
+
+ def __reduce__(self):
+ return (type(self),
+ (self._name, self._kind),
+ {'_default': self._default,
+ '_annotation': self._annotation})
+
+ def __setstate__(self, state):
+ self._default = state['_default']
+ self._annotation = state['_annotation']
+
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def default(self):
+ return self._default
+
+ @property
+ def annotation(self):
+ return self._annotation
+
+ @property
+ def kind(self):
+ return self._kind
+
+ def replace(self, name=_void, kind=_void,
+ annotation=_void, default=_void):
+ """Creates a customized copy of the Parameter."""
+
+ if name is _void:
+ name = self._name
+
+ if kind is _void:
+ kind = self._kind
+
+ if annotation is _void:
+ annotation = self._annotation
+
+ if default is _void:
+ default = self._default
+
+ return type(self)(name, kind, default=default, annotation=annotation)
+
+ def __str__(self):
+ kind = self.kind
+ formatted = self._name
+
+ # Add annotation and default value
+ if self._annotation is not _empty:
+ formatted = '{}:{}'.format(formatted,
+ formatannotation(self._annotation))
+
+ if self._default is not _empty:
+ formatted = '{}={}'.format(formatted, repr(self._default))
+
+ if kind == _VAR_POSITIONAL:
+ formatted = '*' + formatted
+ elif kind == _VAR_KEYWORD:
+ formatted = '**' + formatted
+
+ return formatted
+
+ def __repr__(self):
+ return '<{} "{}">'.format(self.__class__.__name__, self)
+
+ def __hash__(self):
+ return hash((self.name, self.kind, self.annotation, self.default))
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if not isinstance(other, Parameter):
+ return NotImplemented
+ return (self._name == other._name and
+ self._kind == other._kind and
+ self._default == other._default and
+ self._annotation == other._annotation)
+
+
+class BoundArguments(object):
+ """Result of `Signature.bind` call. Holds the mapping of arguments
+ to the function's parameters.
+
+ Has the following public attributes:
+
+ * arguments : OrderedDict
+ An ordered mutable mapping of parameters' names to arguments' values.
+ Does not contain arguments' default values.
+ * signature : Signature
+ The Signature object that created this instance.
+ * args : tuple
+ Tuple of positional arguments values.
+ * kwargs : dict
+ Dict of keyword arguments values.
+ """
+
+ __slots__ = ('arguments', '_signature', '__weakref__')
+
+ def __init__(self, signature, arguments):
+ self.arguments = arguments
+ self._signature = signature
+
+ @property
+ def signature(self):
+ return self._signature
+
+ @property
+ def args(self):
+ args = []
+ for param_name, param in self._signature.parameters.items():
+ if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
+ break
+
+ try:
+ arg = self.arguments[param_name]
+ except KeyError:
+ # We're done here. Other arguments
+ # will be mapped in 'BoundArguments.kwargs'
+ break
+ else:
+ if param.kind == _VAR_POSITIONAL:
+ # *args
+ args.extend(arg)
+ else:
+ # plain argument
+ args.append(arg)
+
+ return tuple(args)
+
+ @property
+ def kwargs(self):
+ kwargs = {}
+ kwargs_started = False
+ for param_name, param in self._signature.parameters.items():
+ if not kwargs_started:
+ if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
+ kwargs_started = True
+ else:
+ if param_name not in self.arguments:
+ kwargs_started = True
+ continue
+
+ if not kwargs_started:
+ continue
+
+ try:
+ arg = self.arguments[param_name]
+ except KeyError:
+ pass
+ else:
+ if param.kind == _VAR_KEYWORD:
+ # **kwargs
+ kwargs.update(arg)
+ else:
+ # plain keyword argument
+ kwargs[param_name] = arg
+
+ return kwargs
+
+ def apply_defaults(self):
+ """Set default values for missing arguments.
+
+ For variable-positional arguments (*args) the default is an
+ empty tuple.
+
+ For variable-keyword arguments (**kwargs) the default is an
+ empty dict.
+ """
+ arguments = self.arguments
+ new_arguments = []
+ for name, param in self._signature.parameters.items():
+ try:
+ new_arguments.append((name, arguments[name]))
+ except KeyError:
+ if param.default is not _empty:
+ val = param.default
+ elif param.kind is _VAR_POSITIONAL:
+ val = ()
+ elif param.kind is _VAR_KEYWORD:
+ val = {}
+ else:
+ # This BoundArguments was likely produced by
+ # Signature.bind_partial().
+ continue
+ new_arguments.append((name, val))
+ self.arguments = OrderedDict(new_arguments)
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if not isinstance(other, BoundArguments):
+ return NotImplemented
+ return (self.signature == other.signature and
+ self.arguments == other.arguments)
+
+ def __setstate__(self, state):
+ self._signature = state['_signature']
+ self.arguments = state['arguments']
+
+ def __getstate__(self):
+ return {'_signature': self._signature, 'arguments': self.arguments}
+
+ def __repr__(self):
+ args = []
+ for arg, value in self.arguments.items():
+ args.append('{}={!r}'.format(arg, value))
+ return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args))
+
+
+class Signature(object):
+ """A Signature object represents the overall signature of a function.
+ It stores a Parameter object for each parameter accepted by the
+ function, as well as information specific to the function itself.
+
+ A Signature object has the following public attributes and methods:
+
+ * parameters : OrderedDict
+ An ordered mapping of parameters' names to the corresponding
+ Parameter objects (keyword-only arguments are in the same order
+ as listed in `code.co_varnames`).
+ * return_annotation : object
+ The annotation for the return type of the function if specified.
+ If the function has no annotation for its return type, this
+ attribute is set to `Signature.empty`.
+ * bind(*args, **kwargs) -> BoundArguments
+ Creates a mapping from positional and keyword arguments to
+ parameters.
+ * bind_partial(*args, **kwargs) -> BoundArguments
+ Creates a partial mapping from positional and keyword arguments
+ to parameters (simulating 'functools.partial' behavior.)
+ """
+
+ __slots__ = ('_return_annotation', '_parameters')
+
+ _parameter_cls = Parameter
+ _bound_arguments_cls = BoundArguments
+
+ empty = _empty
+
+ def __init__(self, parameters=None, return_annotation=_empty,
+ __validate_parameters__=True):
+ """Constructs Signature from the given list of Parameter
+ objects and 'return_annotation'. All arguments are optional.
+ """
+
+ if parameters is None:
+ params = OrderedDict()
+ else:
+ if __validate_parameters__:
+ params = OrderedDict()
+ top_kind = _POSITIONAL_ONLY
+ kind_defaults = False
+
+ for idx, param in enumerate(parameters):
+ kind = param.kind
+ name = param.name
+
+ if kind < top_kind:
+ msg = 'wrong parameter order: {!r} before {!r}'
+ msg = msg.format(top_kind, kind)
+ raise ValueError(msg)
+ elif kind > top_kind:
+ kind_defaults = False
+ top_kind = kind
+
+ if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD):
+ if param.default is _empty:
+ if kind_defaults:
+ # No default for this parameter, but the
+ # previous parameter of the same kind had
+ # a default
+ msg = 'non-default argument follows default ' \
+ 'argument'
+ raise ValueError(msg)
+ else:
+ # There is a default for this parameter.
+ kind_defaults = True
+
+ if name in params:
+ msg = 'duplicate parameter name: {!r}'.format(name)
+ raise ValueError(msg)
+
+ params[name] = param
+ else:
+ params = OrderedDict(((param.name, param)
+ for param in parameters))
+
+ self._parameters = params # types.MappingProxyType(params)
+ self._return_annotation = return_annotation
+
+ @classmethod
+ def from_function(cls, func):
+ """Constructs Signature for the given python function."""
+
+ warnings.warn("inspect.Signature.from_function() is deprecated, "
+ "use Signature.from_callable()",
+ DeprecationWarning, stacklevel=2)
+ return _signature_from_function(cls, func)
+
+ @classmethod
+ def from_builtin(cls, func):
+ """Constructs Signature for the given builtin function."""
+
+ warnings.warn("inspect.Signature.from_builtin() is deprecated, "
+ "use Signature.from_callable()",
+ DeprecationWarning, stacklevel=2)
+ return _signature_from_builtin(cls, func)
+
+ @classmethod
+ def from_callable(cls, obj, follow_wrapped=True):
+ """Constructs Signature for the given callable object."""
+ return _signature_from_callable(obj, sigcls=cls,
+ follow_wrapper_chains=follow_wrapped)
+
+ @property
+ def parameters(self):
+ return self._parameters
+
+ @property
+ def return_annotation(self):
+ return self._return_annotation
+
+ def replace(self, parameters=_void, return_annotation=_void):
+ """Creates a customized copy of the Signature.
+ Pass 'parameters' and/or 'return_annotation' arguments
+ to override them in the new copy.
+ """
+
+ if parameters is _void:
+ parameters = self.parameters.values()
+
+ if return_annotation is _void:
+ return_annotation = self._return_annotation
+
+ return type(self)(parameters,
+ return_annotation=return_annotation)
+
+ def _hash_basis(self):
+ params = tuple(param for param in self.parameters.values()
+ if param.kind != _KEYWORD_ONLY)
+
+ kwo_params = {param.name: param for param in self.parameters.values()
+ if param.kind == _KEYWORD_ONLY}
+
+ return params, kwo_params, self.return_annotation
+
+ def __hash__(self):
+ params, kwo_params, return_annotation = self._hash_basis()
+ kwo_params = frozenset(kwo_params.values())
+ return hash((params, kwo_params, return_annotation))
+
+ def __eq__(self, other):
+ if self is other:
+ return True
+ if not isinstance(other, Signature):
+ return NotImplemented
+ return self._hash_basis() == other._hash_basis()
+
+ def _bind(self, args, kwargs, partial=False):
+ """Private method. Don't use directly."""
+
+ arguments = OrderedDict()
+
+ parameters = iter(self.parameters.values())
+ parameters_ex = ()
+ arg_vals = iter(args)
+
+ while True:
+ # Let's iterate through the positional arguments and corresponding
+ # parameters
+ try:
+ arg_val = next(arg_vals)
+ except StopIteration:
+ # No more positional arguments
+ try:
+ param = next(parameters)
+ except StopIteration:
+ # No more parameters. That's it. Just need to check that
+ # we have no `kwargs` after this while loop
+ break
+ else:
+ if param.kind == _VAR_POSITIONAL:
+ # That's OK, just empty *args. Let's start parsing
+ # kwargs
+ break
+ elif param.name in kwargs:
+ if param.kind == _POSITIONAL_ONLY:
+ msg = '{arg!r} parameter is positional only, ' \
+ 'but was passed as a keyword'
+ msg = msg.format(arg=param.name)
+ raise TypeError(msg)# from None
+ parameters_ex = (param,)
+ break
+ elif (param.kind == _VAR_KEYWORD or
+ param.default is not _empty):
+ # That's fine too - we have a default value for this
+ # parameter. So, lets start parsing `kwargs`, starting
+ # with the current parameter
+ parameters_ex = (param,)
+ break
+ else:
+ # No default, not VAR_KEYWORD, not VAR_POSITIONAL,
+ # not in `kwargs`
+ if partial:
+ parameters_ex = (param,)
+ break
+ else:
+ msg = 'missing a required argument: {arg!r}'
+ msg = msg.format(arg=param.name)
+ raise TypeError(msg)# from None
+ else:
+ # We have a positional argument to process
+ try:
+ param = next(parameters)
+ except StopIteration:
+ raise TypeError('too many positional arguments')# from None
+ else:
+ if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY):
+ # Looks like we have no parameter for this positional
+ # argument
+ raise TypeError(
+ 'too many positional arguments')# from None
+
+ if param.kind == _VAR_POSITIONAL:
+ # We have an '*args'-like argument, let's fill it with
+ # all positional arguments we have left and move on to
+ # the next phase
+ values = [arg_val]
+ values.extend(arg_vals)
+ arguments[param.name] = tuple(values)
+ break
+
+ if param.name in kwargs:
+ raise TypeError(
+ 'multiple values for argument {arg!r}'.format(
+ arg=param.name))# from None
+
+ arguments[param.name] = arg_val
+
+ # Now, we iterate through the remaining parameters to process
+ # keyword arguments
+ kwargs_param = None
+ for param in itertools.chain(parameters_ex, parameters):
+ if param.kind == _VAR_KEYWORD:
+ # Memorize that we have a '**kwargs'-like parameter
+ kwargs_param = param
+ continue
+
+ if param.kind == _VAR_POSITIONAL:
+ # Named arguments don't refer to '*args'-like parameters.
+ # We only arrive here if the positional arguments ended
+ # before reaching the last parameter before *args.
+ continue
+
+ param_name = param.name
+ try:
+ arg_val = kwargs.pop(param_name)
+ except KeyError:
+ # We have no value for this parameter. It's fine though,
+ # if it has a default value, or it is an '*args'-like
+ # parameter, left alone by the processing of positional
+ # arguments.
+ if (not partial and param.kind != _VAR_POSITIONAL and
+ param.default is _empty):
+ raise TypeError('missing a required argument: {arg!r}'. \
+ format(arg=param_name))# from None
+
+ else:
+ if param.kind == _POSITIONAL_ONLY:
+ # This should never happen in case of a properly built
+ # Signature object (but let's have this check here
+ # to ensure correct behavior just in case)
+ raise TypeError('{arg!r} parameter is positional only, '
+ 'but was passed as a keyword'. \
+ format(arg=param.name))
+
+ arguments[param_name] = arg_val
+
+ if kwargs:
+ if kwargs_param is not None:
+ # Process our '**kwargs'-like parameter
+ arguments[kwargs_param.name] = kwargs
+ else:
+ raise TypeError(
+ 'got an unexpected keyword argument {arg!r}'.format(
+ arg=next(iter(kwargs))))
+
+ return self._bound_arguments_cls(self, arguments)
+
+ def bind(*args, **kwargs):
+ """Get a BoundArguments object, that maps the passed `args`
+ and `kwargs` to the function's signature. Raises `TypeError`
+ if the passed arguments can not be bound.
+ """
+ return args[0]._bind(args[1:], kwargs)
+
+ def bind_partial(*args, **kwargs):
+ """Get a BoundArguments object, that partially maps the
+ passed `args` and `kwargs` to the function's signature.
+ Raises `TypeError` if the passed arguments can not be bound.
+ """
+ return args[0]._bind(args[1:], kwargs, partial=True)
+
+ def __reduce__(self):
+ return (type(self),
+ (tuple(self._parameters.values()),),
+ {'_return_annotation': self._return_annotation})
+
+ def __setstate__(self, state):
+ self._return_annotation = state['_return_annotation']
+
+ def __repr__(self):
+ return '<{} {}>'.format(self.__class__.__name__, self)
+
+ def __str__(self):
+ result = []
+ render_pos_only_separator = False
+ render_kw_only_separator = True
+ for param in self.parameters.values():
+ formatted = str(param)
+
+ kind = param.kind
+
+ if kind == _POSITIONAL_ONLY:
+ render_pos_only_separator = True
+ elif render_pos_only_separator:
+ # It's not a positional-only parameter, and the flag
+ # is set to 'True' (there were pos-only params before.)
+ result.append('/')
+ render_pos_only_separator = False
+
+ if kind == _VAR_POSITIONAL:
+ # OK, we have an '*args'-like parameter, so we won't need
+ # a '*' to separate keyword-only arguments
+ render_kw_only_separator = False
+ elif kind == _KEYWORD_ONLY and render_kw_only_separator:
+ # We have a keyword-only parameter to render and we haven't
+ # rendered an '*args'-like parameter before, so add a '*'
+ # separator to the parameters list ("foo(arg1, *, arg2)" case)
+ result.append('*')
+ # This condition should be only triggered once, so
+ # reset the flag
+ render_kw_only_separator = False
+
+ result.append(formatted)
+
+ if render_pos_only_separator:
+ # There were only positional-only parameters, hence the
+ # flag was not reset to 'False'
+ result.append('/')
+
+ rendered = '({})'.format(', '.join(result))
+
+ if self.return_annotation is not _empty:
+ anno = formatannotation(self.return_annotation)
+ rendered += ' -> {}'.format(anno)
+
+ return rendered
+
+
+def signature(obj, follow_wrapped=True):
+ """Get a signature object for the passed callable."""
+ return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
+
+
+def _main():
+ """ Logic for inspecting an object given at command line """
+ import argparse
+ import importlib
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ 'object',
+ help="The object to be analysed. "
+ "It supports the 'module:qualname' syntax")
+ parser.add_argument(
+ '-d', '--details', action='store_true',
+ help='Display info about the module rather than its source code')
+
+ args = parser.parse_args()
+
+ target = args.object
+ mod_name, has_attrs, attrs = target.partition(":")
+ try:
+ obj = module = importlib.import_module(mod_name)
+ except Exception as exc:
+ msg = "Failed to import {} ({}: {})".format(mod_name,
+ type(exc).__name__,
+ exc)
+ print(msg, file=sys.stderr)
+ exit(2)
+
+ if has_attrs:
+ parts = attrs.split(".")
+ obj = module
+ for part in parts:
+ obj = getattr(obj, part)
+
+ if module.__name__ in sys.builtin_module_names:
+ print("Can't get info for builtin modules.", file=sys.stderr)
+ exit(1)
+
+ if args.details:
+ print('Target: {}'.format(target))
+ print('Origin: {}'.format(getsourcefile(module)))
+ print('Cached: {}'.format(module.__cached__))
+ if obj is module:
+ print('Loader: {}'.format(repr(module.__loader__)))
+ if hasattr(module, '__path__'):
+ print('Submodule search path: {}'.format(module.__path__))
+ else:
+ try:
+ __, lineno = findsource(obj)
+ except Exception:
+ pass
+ else:
+ print('Line: {}'.format(lineno))
+
+ print('\n')
+ else:
+ print(getsource(obj))
+
+
+if __name__ == "__main__":
+ _main()
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
new file mode 100644
index 000000000..1443d7927
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
@@ -0,0 +1,140 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+errorhandler.py
+
+This module handles the TypeError messages which were previously
+produced by the generated C code.
+
+This version is at least consistent with the signatures, which
+are created by the same module.
+
+Experimentally, we are trying to guess those errors which are
+just the wrong number of elements in an iterator.
+At the moment, it is unclear whether the information given is
+enough to produce a useful ValueError.
+
+This matter will be improved in a later version.
+"""
+
+from shibokensupport.signature import get_signature, inspect
+from shibokensupport.signature.mapping import update_mapping, namespace
+from textwrap import dedent
+
+
+def qt_isinstance(inst, the_type):
+ if the_type == float:
+ return isinstance(inst, int) or isinstance(int, float)
+ try:
+ return isinstance(inst, the_type)
+ except TypeError as e:
+ print("FIXME", e)
+ return False
+
+
+def matched_type(args, sigs):
+ for sig in sigs:
+ params = list(sig.parameters.values())
+ if len(args) > len(params):
+ continue
+ if len(args) < len(params):
+ k = len(args)
+ if params[k].default is params[k].empty:
+ # this is a necessary parameter, so it fails.
+ continue
+ ok = True
+ for arg, param in zip(args, params):
+ ann = param.annotation
+ if qt_isinstance(arg, ann):
+ continue
+ ok = False
+ if ok:
+ return sig
+ return None
+
+
+def seterror_argument(args, func_name):
+ update_mapping()
+ func = eval(func_name, namespace)
+ sigs = get_signature(func, "typeerror")
+ if type(sigs) != list:
+ sigs = [sigs]
+ if type(args) != tuple:
+ args = (args,)
+ # temp!
+ found = matched_type(args, sigs)
+ if found:
+ msg = dedent("""
+ '{func_name}' called with wrong argument values:
+ {func_name}{args}
+ Found signature:
+ {func_name}{found}
+ """.format(**locals())).strip()
+ return ValueError, msg
+ type_str = ", ".join(type(arg).__name__ for arg in args)
+ msg = dedent("""
+ '{func_name}' called with wrong argument types:
+ {func_name}({type_str})
+ Supported signatures:
+ """.format(**locals())).strip()
+ for sig in sigs:
+ msg += "\n {func_name}{sig}".format(**locals())
+ # We don't raise the error here, to avoid the loader in the traceback.
+ return TypeError, msg
+
+
+def make_helptext(func):
+ existing_doc = func.__doc__
+ sigs = get_signature(func)
+ if not sigs:
+ return existing_doc
+ if type(sigs) != list:
+ sigs = [sigs]
+ try:
+ func_name = func.__name__
+ except AttribureError:
+ func_name = func.__func__.__name__
+ sigtext = "\n".join(func_name + str(sig) for sig in sigs)
+ msg = sigtext + "\n\n" + existing_doc if existing_doc else sigtext
+ return msg
+
+# end of file
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/fix-complaints.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/fix-complaints.py
new file mode 100644
index 000000000..cdd84f9be
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/fix-complaints.py
@@ -0,0 +1,91 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+fix-complaints.py
+
+This module fixes the buildbot messages of external python modules.
+Run it once after copying a new version. It is idem-potent, unless
+you are changing messages (what I did, of course :-) .
+"""
+
+import os
+
+patched_modules = "backport_inspect typing27"
+
+offending_words = {
+ "behavio""ur": "behavior",
+ "at""least": "at_least",
+ "reali""sed": "realized",
+}
+
+utf8_line = "# This Python file uses the following encoding: utf-8\n"
+marker_line = "# It has been edited by {} .\n".format(
+ os.path.basename(__file__))
+
+def patch_file(fname):
+ with open(fname) as f:
+ lines = f.readlines()
+ dup = lines[:]
+ for idx, line in enumerate(lines):
+ for word, repl in offending_words.items():
+ if word in line:
+ lines[idx] = line.replace(word, repl)
+ print("line:{!r} {!r}->{!r}".format(line, word, repl))
+ if lines[0].strip() != utf8_line.strip():
+ lines[:0] = [utf8_line, "\n"]
+ if lines[1] != marker_line:
+ lines[1:1] = marker_line
+ if lines != dup:
+ with open(fname, "w") as f:
+ f.write("".join(lines))
+
+def doit():
+ dir = os.path.dirname(__file__)
+ for name in patched_modules.split():
+ fname = os.path.join(dir, name + ".py")
+ print("Working on", fname)
+ patch_file(fname)
+
+if __name__ == "__main__":
+ doit()
+
+# end of file
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
new file mode 100644
index 000000000..c43d6d076
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
@@ -0,0 +1,246 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+layout.py
+
+The signature module now has the capability to configure
+differently formatted versions of signatures. The default
+layout is known from the "__signature__" attribute.
+
+The function "get_signature(ob, modifier=None)" produces the same
+signatures by default. By passing different modifiers, you
+can select different layouts.
+
+This module configures the different layouts which can be used.
+It also implements them in this file. The configurations are
+used literally as strings like "signature", "existence", etc.
+"""
+
+from textwrap import dedent
+from shibokensupport.signature import inspect
+from shibokensupport.signature.mapping import ellipsis
+
+
+class SimpleNamespace(object):
+ # From types.rst, because the builtin is implemented in Python 3, only.
+ def __init__(self, **kwargs):
+ self.__dict__.update(kwargs)
+
+ def __repr__(self):
+ keys = sorted(self.__dict__)
+ items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
+ return "{}({})".format(type(self).__name__, ", ".join(items))
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+
+class SignatureLayout(SimpleNamespace):
+ """
+ Configure a signature.
+
+ The layout of signatures can have different layouts which are
+ controlled by keyword arguments:
+
+ definition=True Determines if self will generated.
+ defaults=True
+ ellipsis=False Replaces defaults by "...".
+ return_annotation=True
+ parameter_names=True False removes names before ":".
+ """
+ allowed_keys = SimpleNamespace(definition=True,
+ defaults=True,
+ ellipsis=False,
+ return_annotation=True,
+ parameter_names=True)
+ allowed_values = True, False
+
+ def __init__(self, **kwds):
+ args = SimpleNamespace(**self.allowed_keys.__dict__)
+ args.__dict__.update(kwds)
+ self.__dict__.update(args.__dict__)
+ err_keys = list(set(self.__dict__) - set(self.allowed_keys.__dict__))
+ if err_keys:
+ self._attributeerror(err_keys)
+ err_values = list(set(self.__dict__.values()) - set(self.allowed_values))
+ if err_values:
+ self._valueerror(err_values)
+
+ def __setattr__(self, key, value):
+ if key not in self.allowed_keys.__dict__:
+ self._attributeerror([key])
+ if value not in self.allowed_values:
+ self._valueerror([value])
+ self.__dict__[key] = value
+
+ def _attributeerror(self, err_keys):
+ err_keys = ", ".join(err_keys)
+ allowed_keys = ", ".join(self.allowed_keys.__dict__.keys())
+ raise AttributeError(dedent("""\
+ Not allowed: '{err_keys}'.
+ The only allowed keywords are '{allowed_keys}'.
+ """.format(**locals())))
+
+ def _valueerror(self, err_values):
+ err_values = ", ".join(map(str, err_values))
+ allowed_values = ", ".join(map(str, self.allowed_values))
+ raise ValueError(dedent("""\
+ Not allowed: '{err_values}'.
+ The only allowed values are '{allowed_values}'.
+ """.format(**locals())))
+
+# The following names are used literally in this module.
+# This way, we avoid the dict hashing problem.
+signature = SignatureLayout()
+
+existence = SignatureLayout(definition=False,
+ defaults=False,
+ return_annotation=False,
+ parameter_names=False)
+
+hintingstub = SignatureLayout(ellipsis=True)
+
+typeerror = SignatureLayout(definition=False,
+ return_annotation=False,
+ parameter_names=False)
+
+
+def define_nameless_parameter():
+ """
+ Create Nameless Parameters
+
+ A nameless parameter has a reduced string representation.
+ This is done by cloning the parameter type and overwriting its
+ __str__ method. The inner structure is still a valid parameter.
+ """
+ def __str__(self):
+ # for Python 2, we must change self to be an instance of P
+ klass = self.__class__
+ self.__class__ = P
+ txt = P.__str__(self)
+ self.__class__ = klass
+ txt = txt[txt.index(":") + 1:].strip() if ":" in txt else txt
+ return txt
+
+ P = inspect.Parameter
+ newname = "NamelessParameter"
+ bases = P.__bases__
+ body = dict(P.__dict__) # get rid of mappingproxy
+ if "__slots__" in body:
+ # __slots__ would create duplicates
+ for name in body["__slots__"]:
+ del body[name]
+ body["__str__"] = __str__
+ return type(newname, bases, body)
+
+
+NamelessParameter = define_nameless_parameter()
+
+
+def make_signature_nameless(signature):
+ """
+ Make a Signature Nameless
+
+ We use an existing signature and change the type of its parameters.
+ The signature looks different, but is totally intact.
+ """
+ for key in signature.parameters.keys():
+ signature.parameters[key].__class__ = NamelessParameter
+
+
+def create_signature(props, key):
+ if not props:
+ # empty signatures string
+ return
+ if isinstance(props["multi"], list):
+ # multi sig: call recursively
+ return list(create_signature(elem, key)
+ for elem in props["multi"])
+ if type(key) is tuple:
+ sig_kind, modifier = key
+ else:
+ sig_kind, modifier = key, "signature"
+
+ layout = globals()[modifier] # lookup of the modifier in this module
+ if not isinstance(layout, SignatureLayout):
+ raise SystemError("Modifiers must be names of a SignatureLayout "
+ "instance")
+
+ # this is the basic layout of a signature
+ varnames = props["varnames"]
+ if layout.definition:
+ if sig_kind == "function":
+ pass
+ elif sig_kind == "method":
+ varnames = ("self",) + varnames
+ elif sig_kind == "staticmethod":
+ pass
+ elif sig_kind == "classmethod":
+ varnames = ("klass",) + varnames
+ else:
+ raise SystemError("Methods must be function, method, staticmethod or "
+ "classmethod")
+ # calculate the modifications
+ defaults = props["defaults"][:]
+ if not layout.defaults:
+ defaults = ()
+ if layout.ellipsis:
+ defaults = (ellipsis,) * len(defaults)
+ annotations = props["annotations"].copy()
+ if not layout.return_annotation and "return" in annotations:
+ del annotations["return"]
+
+ # attach parameters to a fake function and build a signature
+ argstr = ", ".join(varnames)
+ fakefunc = eval("lambda {}: None".format(argstr))
+ fakefunc.__name__ = props["name"]
+ fakefunc.__defaults__ = defaults
+ fakefunc.__kwdefaults__ = props["kwdefaults"]
+ fakefunc.__annotations__ = annotations
+ sig = inspect._signature_from_function(inspect.Signature, fakefunc)
+
+ # the special case of nameless parameters
+ if not layout.parameter_names:
+ make_signature_nameless(sig)
+ return sig
+
+# end of file
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py
new file mode 100644
index 000000000..2d640cb89
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py
@@ -0,0 +1,40 @@
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+# this file intentionally left blank
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
new file mode 100644
index 000000000..90affbcfd
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
@@ -0,0 +1,168 @@
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+enum_sig.py
+
+Enumerate all signatures of a class.
+
+This module separates the enumeration process from the formatting.
+It is not easy to adhere to this protocol, but in the end, it paid off
+by producing a lot of clarity.
+"""
+
+import sys
+from shibokensupport.signature import get_signature, inspect
+
+
+class ExactEnumerator(object):
+ """
+ ExactEnumerator enumerates all signatures in a module as they are.
+
+ This class is used for generating complete listings of all signatures.
+ An appropriate formatter should be supplied, if printable output
+ is desired.
+ """
+
+ def __init__(self, formatter, result_type=dict):
+ self.fmt = formatter
+ self.result_type = result_type
+
+ def module(self, mod_name):
+ __import__(mod_name)
+ with self.fmt.module(mod_name):
+ module = sys.modules[mod_name]
+ members = inspect.getmembers(module, inspect.isclass)
+ functions = inspect.getmembers(module, inspect.isroutine)
+ ret = self.result_type()
+ self.fmt.class_name = None
+ for func_name, func in functions:
+ ret.update(self.function(func_name, func))
+ for class_name, klass in members:
+ ret.update(self.klass(class_name, klass))
+ return ret
+
+ def klass(self, class_name, klass):
+ if not "Shiboken" in repr(klass.mro()):
+ # don't look into any foreign classes!
+ ret = self.result_type()
+ return ret
+ bases_list = []
+ for base in klass.__bases__:
+ name = base.__name__
+ if name == "object":
+ pass
+ else:
+ modname = base.__module__
+ name = modname + "." + base.__name__
+ bases_list.append(name)
+ class_str = "{}({})".format(class_name, ", ".join(bases_list))
+ with self.fmt.klass(class_name, class_str):
+ ret = self.function("__init__", klass)
+ # class_members = inspect.getmembers(klass)
+ # gives us also the inherited things.
+ class_members = sorted(list(klass.__dict__.items()))
+ subclasses = []
+ for thing_name, thing in class_members:
+ if inspect.isclass(thing):
+ subclass_name = ".".join((class_name, thing_name))
+ subclasses.append((subclass_name, thing))
+ else:
+ func_name = thing_name.split(".")[0] # remove ".overload"
+ ret.update(self.function(func_name, thing))
+ for subclass_name, subclass in subclasses:
+ ret.update(self.klass(subclass_name, subclass))
+ return ret
+
+ def function(self, func_name, func):
+ ret = self.result_type()
+ signature = getattr(func, '__signature__', None)
+ if signature is not None:
+ with self.fmt.function(func_name, signature) as key:
+ ret[key] = signature
+ return ret
+
+
+def stringify(signature):
+ if isinstance(signature, list):
+ # remove duplicates which still sometimes occour:
+ ret = set(stringify(sig) for sig in signature)
+ return sorted(ret) if len(ret) > 1 else list(ret)[0]
+ return tuple(str(pv) for pv in signature.parameters.values())
+
+
+class SimplifyingEnumerator(ExactEnumerator):
+ """
+ SimplifyingEnumerator enumerates all signatures in a module filtered.
+
+ There are no default values, no variable
+ names and no self parameter. Only types are present after simplification.
+ The functions 'next' resp. '__next__' are removed
+ to make the output identical for Python 2 and 3.
+ An appropriate formatter should be supplied, if printable output
+ is desired.
+ """
+
+ def function(self, func_name, func):
+ ret = self.result_type()
+ signature = get_signature(func, 'existence')
+ sig = stringify(signature) if signature is not None else None
+ if sig is not None and func_name not in ("next", "__next__", "__div__"):
+ with self.fmt.function(func_name, sig) as key:
+ ret[key] = sig
+ return ret
+
+class HintingEnumerator(ExactEnumerator):
+ """
+ HintingEnumerator enumerates all signatures in a module slightly changed.
+
+ This class is used for generating complete listings of all signatures for
+ hinting stubs. Only default values are replaced by "...".
+ """
+
+ def function(self, func_name, func):
+ ret = self.result_type()
+ signature = get_signature(func, 'hintingstub')
+ if signature is not None:
+ with self.fmt.function(func_name, signature) as key:
+ ret[key] = signature
+ return ret
+
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
new file mode 100644
index 000000000..3a8d614db
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -0,0 +1,195 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+loader.py
+
+The loader has to lazy-load the signature module and also provides a few
+Python modules to support Python 2.7 .
+
+This version uses both a normal directory, but has also an embedded zip file
+as a fallback solution.
+"""
+
+import sys
+import os
+import traceback
+import types
+from contextlib import contextmanager
+
+"""
+A note on the import problem (solved):
+
+During the tests, the shiboken build structure has the layout
+
+ shiboken2/shibokenmodule/shiboken2.abi3.so
+
+and the name "shiboken2" in sys.modules points directly to the binary
+file, hiding the outer shiboken2 module.
+
+To fix that, we temporarily remove the binary from sys.path,
+do the needed imports and then restore the binary.
+This action was put into a context manager for readability.
+"""
+
+# On Python 2, we only have ImportError, which is way too coarse.
+# When problems occour, please use Python 3, because it has the finer
+# ModuleNotFoundError.
+
+try:
+ ModuleNotFoundError
+except NameError:
+ ModuleNotFoundError = ImportError
+
+@contextmanager
+def ensure_import_shibokensupport():
+ # Make sure that we always have the shibokensupport containing package first.
+ # Also remove any prior loaded module of this name, just in case.
+ sbk_support_dir = os.path.abspath(os.path.join(__file__, "..", "..", ".."))
+ assert os.path.basename(sbk_support_dir) == "files.dir"
+ sys.path.insert(0, sbk_support_dir)
+
+ sbk = "shibokensupport"
+ if sbk in sys.modules:
+ del sys.modules[sbk]
+ for key in list(key for key in sys.modules if key.startswith(sbk + ".")):
+ del sys.modules[key]
+ try:
+ import shibokensupport
+ yield
+ except Exception as e:
+ print("Problem importing shibokensupport:")
+ print(e)
+ traceback.print_exc()
+ sys.stdout.flush()
+ sys.exit(-1)
+ sys.path.remove(sbk_support_dir)
+
+
+# patching inspect's formatting to keep the word "typing":
+def formatannotation(annotation, base_module=None):
+ # if getattr(annotation, '__module__', None) == 'typing':
+ # return repr(annotation).replace('typing.', '')
+ if isinstance(annotation, type):
+ if annotation.__module__ in ('builtins', base_module):
+ return annotation.__qualname__
+ return annotation.__module__ + '.' + annotation.__qualname__
+ return repr(annotation)
+
+# patching __repr__ to disable the __repr__ of typing.TypeVar:
+"""
+ def __repr__(self):
+ if self.__covariant__:
+ prefix = '+'
+ elif self.__contravariant__:
+ prefix = '-'
+ else:
+ prefix = '~'
+ return prefix + self.__name__
+"""
+def _typevar__repr__(self):
+ return "typing." + self.__name__
+
+# Note also that during the tests we have a different encoding that would
+# break the Python license decorated files without an encoding line.
+
+# name used in signature.cpp
+def create_signature(props, key):
+ return layout.create_signature(props, key)
+
+# name used in signature.cpp
+def seterror_argument(args, func_name):
+ return errorhandler.seterror_argument(args, func_name)
+
+# name used in signature.cpp
+def make_helptext(func):
+ return errorhandler.make_helptext(func)
+
+with ensure_import_shibokensupport():
+ import signature_loader
+ import shibokensupport.signature
+ shibokensupport.signature.get_signature = signature_loader.get_signature
+ del signature_loader # protect this dir, too?
+
+ if sys.version_info >= (3,):
+ import typing
+ import inspect
+ inspect.formatannotation = formatannotation
+ else:
+ import inspect
+ namespace = inspect.__dict__
+ from shibokensupport.signature import typing27 as typing
+ typing.__name__ = "typing"
+ # Fix the module names in typing if possible. This is important since
+ # the typing names should be I/O compatible, so that typing.Dict
+ # shows itself as "typing.Dict".
+ for name, obj in typing.__dict__.items():
+ if hasattr(obj, "__module__"):
+ try:
+ obj.__module__ = "typing"
+ except (TypeError, AttributeError):
+ pass
+ from shibokensupport.signature import backport_inspect as inspect
+ _doc = inspect.__doc__
+ inspect.__dict__.update(namespace)
+ inspect.__doc__ += _doc
+ # force inspect to find all attributes. See "heuristic" in pydoc.py!
+ inspect.__all__ = list(x for x in dir(inspect) if not x.startswith("_"))
+ typing.TypeVar.__repr__ = _typevar__repr__
+
+ def put_into_package(module, package):
+ # take the last component of the module name
+ name = module.__name__.rsplit(".", 1)[-1]
+ # allow access as {package}.typing
+ setattr(package, name, module)
+ # put into sys.modules as a package to allow all import options
+ fullname = "{}.{}".format(package.__name__, name)
+ sys.modules[fullname] = module
+
+ put_into_package(typing, shibokensupport.signature)
+ put_into_package(inspect, shibokensupport.signature)
+ from shibokensupport.signature import mapping
+ from shibokensupport.signature import errorhandler
+ from shibokensupport.signature import layout
+ from shibokensupport.signature.lib import enum_sig
+ from shibokensupport.signature.parser import pyside_type_init
+
+# end of file
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
new file mode 100644
index 000000000..470dd676b
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -0,0 +1,683 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+mapping.py
+
+This module has the mapping from the pyside C-modules view of signatures
+to the Python representation.
+
+The PySide modules are not loaded in advance, but only after they appear
+in sys.modules. This minimizes the loading overhead.
+"""
+
+import sys
+import struct
+import os
+import pkgutil
+
+from shibokensupport.signature import typing
+from shibokensupport.signature.typing import TypeVar, Generic
+
+class ellipsis(object):
+ def __repr__(self):
+ return "..."
+
+ellipsis = ellipsis()
+StringList = typing.List[str]
+IntList = typing.List[int]
+Point = typing.Tuple[float, float]
+PointList = typing.List[Point]
+IntMatrix = typing.List[IntList]
+Variant = typing.Any
+ModelIndexList = typing.List[int]
+QImageCleanupFunction = typing.Callable
+
+# First time installing our own Pair type into typing.
+T = TypeVar('T')
+S = TypeVar('S')
+
+class Pair(Generic[T, S]):
+ __module__ = "typing"
+
+typing.Pair = Pair
+
+
+# Building our own Char type, which is much nicer than
+# Char = typing.Union[str, int] # how do I model the limitation to 1 char?
+
+# Copied from the six module:
+def with_metaclass(meta, *bases):
+ """Create a base class with a metaclass."""
+ # This requires a bit of explanation: the basic idea is to make a dummy
+ # metaclass for one level of class instantiation that replaces itself with
+ # the actual metaclass.
+ class metaclass(type):
+
+ def __new__(cls, name, this_bases, d):
+ return meta(name, bases, d)
+
+ @classmethod
+ def __prepare__(cls, name, this_bases):
+ return meta.__prepare__(name, bases)
+ return type.__new__(metaclass, 'temporary_class', (), {})
+
+class _CharMeta(type):
+ def __repr__(self):
+ return '%s.%s' % (self.__module__, self.__name__)
+
+
+class Char(with_metaclass(_CharMeta)):
+ """
+ From http://doc.qt.io/qt-5/qchar.html :
+
+ In Qt, Unicode characters are 16-bit entities without any markup or
+ structure. This class represents such an entity. It is lightweight,
+ so it can be used everywhere. Most compilers treat it like an
+ unsigned short.
+
+ Here, we provide a simple implementation just to avoid long aliases.
+ """
+ __module__ = "typing"
+
+ def __init__(self, code):
+ if isinstance(code, int):
+ self.code = code & 0xffff
+ else:
+ self.code = ord(code)
+
+ def __add__(self, other):
+ return chr(self.code) + other
+
+ def __radd__(self, other):
+ return other + chr(self.code)
+
+ def __repr__(self):
+ return "typing.Char({})".format(self.code)
+
+typing.Char = Char
+
+
+MultiMap = typing.DefaultDict[str, typing.List[str]]
+
+# ulong_max is only 32 bit on windows.
+ulong_max = 2*sys.maxsize+1 if len(struct.pack("L", 1)) != 4 else 0xffffffff
+ushort_max = 0xffff
+
+GL_COLOR_BUFFER_BIT = 0x00004000
+GL_NEAREST = 0x2600
+
+WId = int
+
+# from 5.9
+GL_TEXTURE_2D = 0x0DE1
+GL_RGBA = 0x1908
+
+
+class _NotCalled(str):
+ """
+ Wrap some text with semantics
+
+ This class is wrapped around text in order to avoid calling it.
+ There are three reasons for this:
+
+ - some instances cannot be created since they are abstract,
+ - some can only be created after qApp was created,
+ - some have an ugly __repr__ with angle brackets in it.
+
+ By using derived classes, good looking instances can be created
+ which can be used to generate source code or .pyi files. When the
+ real object is needed, the wrapper can simply be called.
+ """
+ def __repr__(self):
+ suppress = "support.signature.typing27."
+ text = self[len(suppress):] if self.startswith(suppress) else self
+ return "{}({})".format(type(self).__name__, text)
+
+ def __call__(self):
+ from shibokensupport.signature.mapping import __dict__ as namespace
+ text = self if self.endswith(")") else self + "()"
+ return eval(text, namespace)
+
+USE_PEP563 = sys.version_info[:2] >= (3, 7)
+
+
+# Some types are abstract. They just show their name.
+class Virtual(_NotCalled):
+ pass
+
+# Other types I simply could not find.
+class Missing(_NotCalled):
+ if not USE_PEP563:
+ # The string must be quoted, because the object does not exist.
+ def __repr__(self):
+ return '{}("{}")'.format(type(self).__name__, self)
+
+
+class Invalid(_NotCalled):
+ pass
+
+# Helper types
+class Default(_NotCalled):
+ pass
+
+
+class Instance(_NotCalled):
+ pass
+
+
+class Reloader(object):
+ """
+ Reloder class
+
+ This is a singleton class which provides the update function for the
+ shiboken and PySide classes.
+ """
+ _uninitialized = "Shiboken minimal sample other smart".split()
+ _prefixes = [""]
+ try:
+ import PySide2
+ _uninitialized += PySide2.__all__ + ["testbinding"]
+ _prefixes += ["PySide2."]
+ except ImportError:
+ pass
+
+ def __init__(self):
+ self.sys_module_count = 0
+ self.uninitialized = self._uninitialized
+
+ def update(self):
+ """
+ update is responsible to import all modules from shiboken and PySide
+ which are already in sys.modules.
+ The purpose is to follow all user imports without introducing new
+ ones.
+ This function is called by pyside_type_init to adapt imports
+ when the number of imported modules has changed.
+ """
+ if self.sys_module_count == len(sys.modules):
+ return
+ self.sys_module_count = len(sys.modules)
+ g = globals()
+ for mod_name in self.uninitialized[:]:
+ for prefix in self._prefixes:
+ import_name = prefix + mod_name
+ if import_name in sys.modules:
+ # check if this is a real module
+ check_module(sys.modules[import_name])
+ # module is real
+ self.uninitialized.remove(mod_name)
+ proc_name = "init_" + mod_name
+ if proc_name in g:
+ # Do the 'import {import_name}' first.
+ # 'top' is PySide2 when we do 'import PySide.QtCore'
+ # or Shiboken if we do 'import Shiboken'.
+ # Convince yourself that these two lines below have the same
+ # global effect as "import Shiboken" or "import PySide2.QtCore".
+ top = __import__(import_name)
+ g[top.__name__] = top
+ # Modules are in place, we can update the type_map.
+ g.update(g[proc_name]())
+
+def check_module(mod):
+ # During a build, there exist the modules already as directories,
+ # although the '*.so' was not yet created. This causes a problem
+ # in Python 3, because it accepts folders as namespace modules
+ # without enforcing an '__init__.py'.
+ if not getattr(mod, "__file__", None) or os.path.isdir(mod.__file__):
+ mod_name = mod.__name__
+ raise ImportError("Module '{mod_name}' is at most a namespace!"
+ .format(**locals()))
+
+
+update_mapping = Reloader().update
+type_map = {}
+namespace = globals() # our module's __dict__
+
+type_map.update({
+ "QList": typing.List,
+ "QVector": typing.List,
+ "QSet": typing.Set,
+ "QPair": Pair,
+ })
+
+
+# The Shiboken Part
+def init_Shiboken():
+ type_map.update({
+ "shiboken2.bool": bool,
+ "size_t": int,
+ "PyType": type,
+ })
+ return locals()
+
+
+def init_minimal():
+ type_map.update({
+ "MinBool": bool,
+ })
+ return locals()
+
+
+def init_sample():
+ import datetime
+ type_map.update({
+ "double": float,
+ "sample.int": int,
+ "Complex": complex,
+ "sample.OddBool": bool,
+ "sample.bool": bool,
+ "sample.PStr": str,
+ "OddBool": bool,
+ "PStr": str,
+ "char": Char,
+ "sample.char": Char,
+ "sample.Point": Point,
+ "sample.ObjectType": object,
+ "std.string": str,
+ "HANDLE": int,
+ "Foo.HANDLE": int,
+ "sample.Photon.TemplateBase": Missing("sample.Photon.TemplateBase"),
+ "ObjectType.Identifier": Missing("sample.ObjectType.Identifier"),
+ "zero(HANDLE)": 0,
+ "Null": None,
+ "zero(sample.ObjectType)": None,
+ "std.size_t": int,
+ 'Str("<unknown>")': "<unknown>",
+ 'Str("<unk")': "<unk",
+ 'Str("nown>")': "nown>",
+ "zero(sample.ObjectModel)": None,
+ "sample.unsigned char": Char,
+ "sample.double": float,
+ "zero(sample.bool)": False,
+ "PyDate": datetime.date,
+ "ZeroIn": 0,
+ })
+ return locals()
+
+
+def init_other():
+ import numbers
+ type_map.update({
+ "other.Number": numbers.Number,
+ "other.ExtendsNoImplicitConversion": Missing("other.ExtendsNoImplicitConversion"),
+ })
+ return locals()
+
+
+def init_smart():
+ type_map.update({
+ "smart.SharedPtr": Missing("smart.SharedPtr"), # bad object "SharedPtr<Obj >"
+ })
+ return locals()
+
+# The PySide Part
+def init_QtCore():
+ from PySide2.QtCore import Qt, QUrl, QDir
+ from PySide2.QtCore import QRect, QSize, QPoint, QLocale, QByteArray
+ from PySide2.QtCore import QMarginsF # 5.9
+ try:
+ # seems to be not generated by 5.9 ATM.
+ from PySide2.QtCore import Connection
+ except ImportError:
+ pass
+ type_map.update({
+ "str": str,
+ "int": int,
+ "QString": str,
+ "bool": bool,
+ "PyObject": object,
+ "void": int, # be more specific?
+ "char": Char,
+ "'%'": "%",
+ "' '": " ",
+ "false": False,
+ "double": float,
+ "'g'": "g",
+ "long long": int,
+ "unsigned int": int, # should we define an unsigned type?
+ "Q_NULLPTR": None,
+ "long": int,
+ "float": float,
+ "short": int,
+ "unsigned long": int,
+ "unsigned long long": int,
+ "unsigned short": int,
+ "QStringList": StringList,
+ "QChar": Char,
+ "signed char": Char,
+ "QVariant": Variant,
+ "QVariant.Type": type, # not so sure here...
+ "QStringRef": str,
+ "QString()": "",
+ "QModelIndexList": ModelIndexList,
+ "unsigned char": Char,
+ "QJsonObject": typing.Dict[str, PySide2.QtCore.QJsonValue],
+ "QStringList()": [],
+ "ULONG_MAX": ulong_max,
+ "quintptr": int,
+ "PyCallable": typing.Callable,
+ "PyTypeObject": type,
+ "PySequence": typing.Iterable, # important for numpy
+ "qptrdiff": int,
+ "true": True,
+ "Qt.HANDLE": int, # be more explicit with some consts?
+ "list of QAbstractState": typing.List[PySide2.QtCore.QAbstractState],
+ "list of QAbstractAnimation": typing.List[PySide2.QtCore.QAbstractAnimation],
+ "QVariant()": Invalid(Variant),
+ "QMap": typing.Dict,
+ "PySide2.QtCore.bool": bool,
+ "QHash": typing.Dict,
+ "PySide2.QtCore.QChar": Char,
+ "PySide2.QtCore.qreal": float,
+ "PySide2.QtCore.float": float,
+ "PySide2.QtCore.qint16": int,
+ "PySide2.QtCore.qint32": int,
+ "PySide2.QtCore.qint64": int,
+ "PySide2.QtCore.qint8": int,
+ "PySide2.QtCore.QString": str,
+ "PySide2.QtCore.QStringList": StringList,
+ "PySide2.QtCore.QVariant": Variant,
+ "PySide2.QtCore.quint16": int,
+ "PySide2.QtCore.quint32": int,
+ "PySide2.QtCore.quint64": int,
+ "PySide2.QtCore.quint8": int,
+ "PySide2.QtCore.uchar": Char,
+ "PySide2.QtCore.unsigned char": Char, # 5.9
+ "PySide2.QtCore.long": int,
+ "PySide2.QtCore.QUrl.ComponentFormattingOptions":
+ PySide2.QtCore.QUrl.ComponentFormattingOption, # mismatch option/enum, why???
+ "QUrl.FormattingOptions(PrettyDecoded)": Instance(
+ "QUrl.FormattingOptions(QUrl.PrettyDecoded)"),
+ # from 5.9
+ "QDir.Filters(AllEntries | NoDotAndDotDot)": Instance(
+ "QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)"),
+ "NULL": None, # 5.6, MSVC
+ "QDir.SortFlags(Name | IgnoreCase)": Instance(
+ "QDir.SortFlags(QDir.Name | QDir.IgnoreCase)"),
+ "PyBytes": bytes,
+ "PyByteArray": bytearray,
+ "PyUnicode": typing.Text,
+ "signed long": int,
+ "PySide2.QtCore.int": int,
+ "PySide2.QtCore.char": StringList, # A 'char **' is a list of strings.
+ "unsigned long int": int, # 5.6, RHEL 6.6
+ "unsigned short int": int, # 5.6, RHEL 6.6
+ "4294967295UL": 4294967295, # 5.6, RHEL 6.6
+ "PySide2.QtCore.int32_t": int, # 5.9
+ "PySide2.QtCore.int64_t": int, # 5.9
+ "UnsignedShortType": int, # 5.9
+ "nullptr": None, # 5.9
+ "uint64_t": int, # 5.9
+ "PySide2.QtCore.uint32_t": int, # 5.9
+ "PySide2.QtCore.unsigned int": int, # 5.9 Ubuntu
+ "PySide2.QtCore.long long": int, # 5.9, MSVC 15
+ "QGenericArgument(nullptr)": ellipsis, # 5.10
+ "QModelIndex()": Invalid("PySide2.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
+ "QGenericArgument((0))": ellipsis, # 5.6, RHEL 6.6. Is that ok?
+ "QGenericArgument()": ellipsis,
+ "QGenericArgument(0)": ellipsis,
+ "QGenericArgument(NULL)": ellipsis, # 5.6, MSVC
+ "QGenericArgument(Q_NULLPTR)": ellipsis,
+ "zero(PySide2.QtCore.QObject)": None,
+ "zero(PySide2.QtCore.QThread)": None,
+ "zero(quintptr)": 0,
+ "zero(str)": "",
+ "zero(int)": 0,
+ "zero(PySide2.QtCore.QState)": None,
+ "zero(PySide2.QtCore.bool)": False,
+ "zero(PySide2.QtCore.int)": 0,
+ "zero(void)": None,
+ "zero(long long)": 0,
+ "zero(PySide2.QtCore.QAbstractItemModel)": None,
+ "zero(PySide2.QtCore.QJsonParseError)": None,
+ "zero(double)": 0.0,
+ "zero(PySide2.QtCore.qint64)": 0,
+ "zero(PySide2.QtCore.QTextCodec.ConverterState)": None,
+ "zero(long long)": 0,
+ "zero(QImageCleanupFunction)": None,
+ "zero(unsigned int)": 0,
+ "zero(PySide2.QtCore.QPoint)": Default("PySide2.QtCore.QPoint"),
+ "zero(unsigned char)": 0,
+ "zero(PySide2.QtCore.QEvent.Type)": None,
+ "CheckIndexOption.NoOption": Instance(
+ "PySide2.QtCore.QAbstractItemModel.CheckIndexOptions.NoOption"), # 5.11
+ "QVariantMap": typing.Dict[str, Variant],
+ "PySide2.QtCore.QCborStreamReader.StringResult": typing.AnyStr,
+ "PySide2.QtCore.double": float,
+ })
+ try:
+ type_map.update({
+ "PySide2.QtCore.QMetaObject.Connection": PySide2.QtCore.Connection, # wrong!
+ })
+ except AttributeError:
+ # this does not exist on 5.9 ATM.
+ pass
+ return locals()
+
+
+def init_QtGui():
+ from PySide2.QtGui import QPageLayout, QPageSize # 5.12 macOS
+ type_map.update({
+ "QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
+ "USHRT_MAX": ushort_max,
+ "0.0f": 0.0,
+ "1.0f": 1.0,
+ "uint32_t": int,
+ "uint8_t": int,
+ "int32_t": int,
+ "GL_COLOR_BUFFER_BIT": GL_COLOR_BUFFER_BIT,
+ "GL_NEAREST": GL_NEAREST,
+ "WId": WId,
+ "PySide2.QtGui.QPlatformSurface": int, # a handle
+ "QList< QTouchEvent.TouchPoint >()": [], # XXX improve?
+ "QPixmap()": Default("PySide2.QtGui.QPixmap"), # can't create without qApp
+ "PySide2.QtCore.uint8_t": int, # macOS 5.9
+ "zero(uint32_t)": 0,
+ "zero(PySide2.QtGui.QWindow)": None,
+ "zero(PySide2.QtGui.QOpenGLContext)": None,
+ "zero(PySide2.QtGui.QRegion)": None,
+ "zero(PySide2.QtGui.QPaintDevice)": None,
+ "zero(PySide2.QtGui.QTextLayout.FormatRange)": None,
+ "zero(PySide2.QtGui.QTouchDevice)": None,
+ "zero(PySide2.QtGui.QScreen)": None,
+ "PySide2.QtGui.QGenericMatrix": Missing("PySide2.QtGui.QGenericMatrix"),
+ })
+ return locals()
+
+
+def init_QtWidgets():
+ from PySide2.QtWidgets import QWidget, QMessageBox, QStyleOption, QStyleHintReturn, QStyleOptionComplex
+ from PySide2.QtWidgets import QGraphicsItem, QStyleOptionGraphicsItem # 5.9
+ type_map.update({
+ "QMessageBox.StandardButtons(Yes | No)": Instance(
+ "QMessageBox.StandardButtons(QMessageBox.Yes | QMessageBox.No)"),
+ "QWidget.RenderFlags(DrawWindowBackground | DrawChildren)": Instance(
+ "QWidget.RenderFlags(QWidget.DrawWindowBackground | QWidget.DrawChildren)"),
+ "static_cast<Qt.MatchFlags>(Qt.MatchExactly|Qt.MatchCaseSensitive)": Instance(
+ "Qt.MatchFlags(Qt.MatchExactly | Qt.MatchCaseSensitive)"),
+ "QVector< int >()": [],
+ "WId": WId,
+ # from 5.9
+ "Type": PySide2.QtWidgets.QListWidgetItem.Type,
+ "SO_Default": QStyleOption.SO_Default,
+ "SH_Default": QStyleHintReturn.SH_Default,
+ "SO_Complex": QStyleOptionComplex.SO_Complex,
+ "zero(PySide2.QtWidgets.QWidget)": None,
+ "zero(PySide2.QtWidgets.QGraphicsItem)": None,
+ "zero(PySide2.QtCore.QEvent)": None,
+ "zero(PySide2.QtWidgets.QStyleOption)": None,
+ "zero(PySide2.QtWidgets.QStyleHintReturn)": None,
+ "zero(PySide2.QtWidgets.QGraphicsLayoutItem)": None,
+ "zero(PySide2.QtWidgets.QListWidget)": None,
+ "zero(PySide2.QtGui.QKeySequence)": None,
+ "zero(PySide2.QtWidgets.QAction)": None,
+ "zero(PySide2.QtWidgets.QUndoCommand)": None,
+ "zero(WId)": 0,
+ })
+ return locals()
+
+
+def init_QtSql():
+ from PySide2.QtSql import QSqlDatabase
+ type_map.update({
+ "QLatin1String(defaultConnection)": QSqlDatabase.defaultConnection,
+ "QVariant.Invalid": Invalid("Variant"), # not sure what I should create, here...
+ })
+ return locals()
+
+
+def init_QtNetwork():
+ type_map.update({
+ "QMultiMap": MultiMap,
+ "zero(unsigned short)": 0,
+ "zero(PySide2.QtCore.QIODevice)": None,
+ "zero(QList)": [],
+ })
+ return locals()
+
+
+def init_QtXmlPatterns():
+ from PySide2.QtXmlPatterns import QXmlName
+ type_map.update({
+ "QXmlName.PrefixCode": Missing("PySide2.QtXmlPatterns.QXmlName.PrefixCode"),
+ "QXmlName.NamespaceCode": Missing("PySide2.QtXmlPatterns.QXmlName.NamespaceCode")
+ })
+ return locals()
+
+
+def init_QtMultimedia():
+ import PySide2.QtMultimediaWidgets
+ # Check if foreign import is valid. See mapping.py in shiboken2.
+ check_module(PySide2.QtMultimediaWidgets)
+ type_map.update({
+ "QGraphicsVideoItem": PySide2.QtMultimediaWidgets.QGraphicsVideoItem,
+ "QVideoWidget": PySide2.QtMultimediaWidgets.QVideoWidget,
+ })
+ return locals()
+
+
+def init_QtOpenGL():
+ type_map.update({
+ "GLuint": int,
+ "GLenum": int,
+ "GLint": int,
+ "GLbitfield": int,
+ "PySide2.QtOpenGL.GLint": int,
+ "PySide2.QtOpenGL.GLuint": int,
+ "GLfloat": float, # 5.6, MSVC 15
+ "zero(PySide2.QtOpenGL.QGLContext)": None,
+ "zero(GLenum)": 0,
+ "zero(PySide2.QtOpenGL.QGLWidget)": None,
+ })
+ return locals()
+
+
+def init_QtQml():
+ type_map.update({
+ "QJSValueList()": [],
+ "PySide2.QtQml.bool volatile": bool,
+ # from 5.9
+ "QVariantHash()": typing.Dict[str, Variant], # XXX sorted?
+ "zero(PySide2.QtQml.QQmlContext)": None,
+ "zero(PySide2.QtQml.QQmlEngine)": None,
+ })
+ return locals()
+
+
+def init_QtQuick():
+ type_map.update({
+ "PySide2.QtQuick.QSharedPointer": int,
+ "PySide2.QtCore.uint": int,
+ "T": int,
+ "zero(PySide2.QtQuick.QQuickItem)": None,
+ "zero(GLuint)": 0,
+ })
+ return locals()
+
+
+def init_QtScript():
+ type_map.update({
+ "QScriptValueList()": [],
+ })
+ return locals()
+
+
+def init_QtTest():
+ type_map.update({
+ "PySide2.QtTest.QTouchEventSequence": PySide2.QtTest.QTest.QTouchEventSequence,
+ })
+ return locals()
+
+# from 5.9
+def init_QtWebEngineWidgets():
+ type_map.update({
+ "zero(PySide2.QtWebEngineWidgets.QWebEnginePage.FindFlags)": 0,
+ })
+ return locals()
+
+# from 5.6, MSVC
+def init_QtWinExtras():
+ type_map.update({
+ "QList< QWinJumpListItem* >()": [],
+ })
+ return locals()
+
+# from 5.12, macOS
+def init_QtDataVisualization():
+ from PySide2.QtDataVisualization import QtDataVisualization
+ QtDataVisualization.QBarDataRow = typing.List[QtDataVisualization.QBarDataItem]
+ QtDataVisualization.QBarDataArray = typing.List[QtDataVisualization.QBarDataRow]
+ QtDataVisualization.QSurfaceDataRow = typing.List[QtDataVisualization.QSurfaceDataItem]
+ QtDataVisualization.QSurfaceDataArray = typing.List[QtDataVisualization.QSurfaceDataRow]
+ type_map.update({
+ "100.0f": 100.0,
+ })
+ return locals()
+
+
+def init_testbinding():
+ type_map.update({
+ "testbinding.PySideCPP2.TestObjectWithoutNamespace": testbinding.TestObjectWithoutNamespace,
+ })
+ return locals()
+
+# end of file
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
new file mode 100644
index 000000000..09e78f1b0
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -0,0 +1,314 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+import sys
+import re
+import warnings
+import types
+import keyword
+import functools
+from shibokensupport.signature.mapping import (type_map, update_mapping,
+ namespace, typing, _NotCalled)
+
+_DEBUG = False
+LIST_KEYWORDS = False
+
+"""
+parser.py
+
+This module parses the signature text and creates properties for the
+signature objects.
+
+PySide has a new function 'CppGenerator::writeSignatureInfo()'
+that extracts the gathered information about the function arguments
+and defaults as good as it can. But what PySide generates is still
+very C-ish and has many constants that Python doesn't understand.
+
+The function 'try_to_guess()' below understands a lot of PySide's
+peculiar way to assume local context. If it is able to do the guess,
+then the result is inserted into the dict, so the search happens
+not again. For everything that is not covered by these automatic
+guesses, we provide an entry in 'type_map' that resolves it.
+
+In effect, 'type_map' maps text to real Python objects.
+"""
+
+def dprint(*args, **kw):
+ if _DEBUG:
+ import pprint
+ for arg in args:
+ pprint.pprint(arg)
+ sys.stdout.flush()
+
+def _parse_line(line):
+ line_re = r"""
+ ((?P<multi> ([0-9]+)) : )? # the optional multi-index
+ (?P<funcname> \w+(\.\w+)*) # the function name
+ \( (?P<arglist> .*?) \) # the argument list
+ ( -> (?P<returntype> .*) )? # the optional return type
+ $
+ """
+ ret = re.match(line_re, line, re.VERBOSE).groupdict()
+ arglist = ret["arglist"]
+ # The following is a split re. The string is broken into pieces which are
+ # between the recognized strings. Because the re has groups, both the
+ # strings and the delimiters are returned, where the strings are not
+ # interesting at all: They are just the commata.
+ # Note that it is necessary to put the characters with special handling in
+ # the first group (comma, brace, angle bracket).
+ # Then they are not recognized there, and we can handle them differently
+ # in the following expressions.
+ arglist = list(x.strip() for x in re.split(r"""
+ (
+ (?: # inner group is not capturing
+ [^,()<>] # no commas or braces or angle brackets
+ |
+ \(
+ (?:
+ [^()]* # or one brace pair
+ |
+ \(
+ [^()]* # or doubls nested pair
+ \)
+ )*
+ \)
+ |
+ < # or one angle bracket pair
+ [^<>]*
+ >
+ )+ # longest possible span
+ ) # this list is interspersed with "," and surrounded by ""
+ """, arglist, flags=re.VERBOSE)
+ if x.strip() not in ("", ","))
+ args = []
+ for arg in arglist:
+ name, ann = arg.split(":")
+ if name in keyword.kwlist:
+ if LIST_KEYWORDS:
+ print("KEYWORD", ret)
+ name = name + "_"
+ if "=" in ann:
+ ann, default = ann.split("=")
+ tup = name, ann, default
+ else:
+ tup = name, ann
+ args.append(tup)
+ ret["arglist"] = args
+ multi = ret["multi"]
+ if multi is not None:
+ ret["multi"] = int(multi)
+ funcname = ret["funcname"]
+ parts = funcname.split(".")
+ if parts[-1] in keyword.kwlist:
+ ret["funcname"] = funcname + "_"
+ return ret
+
+def make_good_value(thing, valtype):
+ try:
+ if thing.endswith("()"):
+ thing = 'Default("{}")'.format(thing[:-2])
+ else:
+ ret = eval(thing, namespace)
+ if valtype and repr(ret).startswith("<"):
+ thing = 'Instance("{}")'.format(thing)
+ return eval(thing, namespace)
+ except Exception:
+ pass
+
+def try_to_guess(thing, valtype):
+ if "." not in thing and "(" not in thing:
+ text = "{}.{}".format(valtype, thing)
+ ret = make_good_value(text, valtype)
+ if ret is not None:
+ return ret
+ typewords = valtype.split(".")
+ valwords = thing.split(".")
+ braceless = valwords[0] # Yes, not -1. Relevant is the overlapped word.
+ if "(" in braceless:
+ braceless = braceless[:braceless.index("(")]
+ for idx, w in enumerate(typewords):
+ if w == braceless:
+ text = ".".join(typewords[:idx] + valwords)
+ ret = make_good_value(text, valtype)
+ if ret is not None:
+ return ret
+ return None
+
+def _resolve_value(thing, valtype, line):
+ if thing in ("0", "None") and valtype:
+ thing = "zero({})".format(valtype)
+ if thing in type_map:
+ return type_map[thing]
+ res = make_good_value(thing, valtype)
+ if res is not None:
+ type_map[thing] = res
+ return res
+ res = try_to_guess(thing, valtype) if valtype else None
+ if res is not None:
+ type_map[thing] = res
+ return res
+ warnings.warn("""pyside_type_init:
+
+ UNRECOGNIZED: {!r}
+ OFFENDING LINE: {!r}
+ """.format(thing, line), RuntimeWarning)
+ return thing
+
+def _resolve_arraytype(thing, line):
+ thing = thing[:-2]
+ if thing.endswith("[]"):
+ thing = _resolve_arraytype(thing, line)
+ # this mapping is in shiboken
+ thing = "QList[" + thing + "]"
+ return thing
+
+def to_string(thing):
+ if isinstance(thing, str):
+ return thing
+ if hasattr(thing, "__name__"):
+ dot = "." in str(type(thing))
+ return thing.__module__ + "." + thing.__name__ if dot else thing.__name__
+ # Note: This captures things from the typing module:
+ return str(thing)
+
+def _resolve_type(thing, line):
+ if thing.endswith("[]"):
+ thing = _resolve_arraytype(thing, line)
+ if "[" in thing:
+ # Handle a container return type. (see PYSIDE-921 in cppgenerator.cpp)
+ contr, thing = re.match(r"(.*?)\[(.*?)\]$", thing).groups()
+ contr = to_string(_resolve_type(contr, line))
+ thing = to_string(_resolve_type(thing, line))
+ result = "{contr}[{thing}]".format(**locals())
+ if not isinstance(thing, _NotCalled):
+ result = eval(result, namespace)
+ return result
+ return _resolve_value(thing, None, line)
+
+def calculate_props(line):
+ line = line.strip()
+ res = _parse_line(line)
+ arglist = res["arglist"]
+ annotations = {}
+ _defaults = []
+ for idx, tup in enumerate(arglist):
+ name, ann = tup[:2]
+ if ann == "...":
+ name = "*args"
+ # copy the fields back :()
+ ann = 'NULL' # maps to None
+ tup = name, ann
+ arglist[idx] = tup
+ annotations[name] = _resolve_type(ann, line)
+ if len(tup) == 3:
+ default = _resolve_value(tup[2], ann, line)
+ _defaults.append(default)
+ defaults = tuple(_defaults)
+ returntype = res["returntype"]
+ if returntype is not None:
+ annotations["return"] = _resolve_type(returntype, line)
+ props = {}
+ props["defaults"] = defaults
+ props["kwdefaults"] = {}
+ props["annotations"] = annotations
+ props["varnames"] = varnames = tuple(tup[0] for tup in arglist)
+ funcname = res["funcname"]
+ props["fullname"] = funcname
+ shortname = funcname[funcname.rindex(".")+1:]
+ props["name"] = shortname
+ props["multi"] = res["multi"]
+ return props
+
+def fixup_multilines(sig_str):
+ lines = list(line.strip() for line in sig_str.strip().splitlines())
+ res = []
+ multi_lines = []
+ for line in lines:
+ multi = re.match(r"([0-9]+):", line)
+ if multi:
+ idx, rest = int(multi.group(1)), line[multi.end():]
+ multi_lines.append(rest)
+ if idx > 0:
+ continue
+ # remove duplicates
+ multi_lines = sorted(set(multi_lines))
+ # renumber or return a single line
+ nmulti = len(multi_lines)
+ if nmulti > 1:
+ for idx, line in enumerate(multi_lines):
+ res.append("{}:{}".format(nmulti-idx-1, line))
+ else:
+ res.append(multi_lines[0])
+ multi_lines = []
+ else:
+ res.append(line)
+ return res
+
+def pyside_type_init(typemod, sig_str):
+ dprint()
+ if type(typemod) is types.ModuleType:
+ dprint("Initialization of module '{}'".format(typemod.__name__))
+ else:
+ dprint("Initialization of type '{}.{}'".format(typemod.__module__,
+ typemod.__name__))
+ update_mapping()
+ lines = fixup_multilines(sig_str)
+ ret = {}
+ multi_props = []
+ for line in lines:
+ props = calculate_props(line)
+ shortname = props["name"]
+ multi = props["multi"]
+ if multi is None:
+ ret[shortname] = props
+ dprint(props)
+ else:
+ multi_props.append(props)
+ if multi > 0:
+ continue
+ fullname = props.pop("fullname")
+ multi_props = {"multi": multi_props, "fullname": fullname}
+ ret[shortname] = multi_props
+ dprint(multi_props)
+ multi_props = []
+ return ret
+
+# end of file
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json
new file mode 100644
index 000000000..491ae8054
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json
@@ -0,0 +1,13 @@
+{
+ "Id": "python",
+ "Name": "Python",
+ "QDocModule": "QtForPython",
+ "QtUsage": "Used for Qt for Python in the signature extension.",
+ "Description": "Qt for Python is an add-on for Python. The signature packages of PySide uses certain copied and adapted source files (backport_inspect.py, typing27.py). See the folder sources/pyside2/PySide2/support/signature .",
+ "Homepage": "http://www.python.org/",
+ "Version": "3.7.0",
+ "LicenseId": "Python-2.0",
+ "License": "Python License 2.0",
+ "LicenseFile": "PSF-3.7.0.txt",
+ "Copyright": "© Copyright 2001-2018, Python Software Foundation."
+}
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/typing27.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/typing27.py
new file mode 100644
index 000000000..dba8f8c77
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/typing27.py
@@ -0,0 +1,2293 @@
+# This Python file uses the following encoding: utf-8
+# It has been edited by fix-complaints.py .
+
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+"""
+PSF LICENSE AGREEMENT FOR PYTHON 3.7.0
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and
+ the Individual or Organization ("Licensee") accessing and otherwise using Python
+ 3.7.0 software in source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+ grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+ analyze, test, perform and/or display publicly, prepare derivative works,
+ distribute, and otherwise use Python 3.7.0 alone or in any derivative
+ version, provided, however, that PSF's License Agreement and PSF's notice of
+ copyright, i.e., "Copyright © 2001-2018 Python Software Foundation; All Rights
+ Reserved" are retained in Python 3.7.0 alone or in any derivative version
+ prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on or
+ incorporates Python 3.7.0 or any part thereof, and wants to make the
+ derivative work available to others as provided herein, then Licensee hereby
+ agrees to include in any such work a brief summary of the changes made to Python
+ 3.7.0.
+
+4. PSF is making Python 3.7.0 available to Licensee on an "AS IS" basis.
+ PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF
+ EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
+ WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
+ USE OF PYTHON 3.7.0 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 3.7.0
+ FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
+ MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 3.7.0, OR ANY DERIVATIVE
+ THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material breach of
+ its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any relationship
+ of agency, partnership, or joint venture between PSF and Licensee. This License
+ Agreement does not grant permission to use PSF trademarks or trade name in a
+ trademark sense to endorse or promote products or services of Licensee, or any
+ third party.
+
+8. By copying, installing or otherwise using Python 3.7.0, Licensee agrees
+ to be bound by the terms and conditions of this License Agreement.
+"""
+
+from __future__ import absolute_import, unicode_literals
+
+import abc
+from abc import abstractmethod, abstractproperty
+import collections
+import functools
+import re as stdlib_re # Avoid confusion with the re we export.
+import sys
+import types
+import copy
+try:
+ import collections.abc as collections_abc
+except ImportError:
+ import collections as collections_abc # Fallback for PY3.2.
+
+
+# Please keep __all__ alphabetized within each category.
+__all__ = [
+ # Super-special typing primitives.
+ 'Any',
+ 'Callable',
+ 'ClassVar',
+ 'Generic',
+ 'Optional',
+ 'Tuple',
+ 'Type',
+ 'TypeVar',
+ 'Union',
+
+ # ABCs (from collections.abc).
+ 'AbstractSet', # collections.abc.Set.
+ 'GenericMeta', # subclass of abc.ABCMeta and a metaclass
+ # for 'Generic' and ABCs below.
+ 'ByteString',
+ 'Container',
+ 'ContextManager',
+ 'Hashable',
+ 'ItemsView',
+ 'Iterable',
+ 'Iterator',
+ 'KeysView',
+ 'Mapping',
+ 'MappingView',
+ 'MutableMapping',
+ 'MutableSequence',
+ 'MutableSet',
+ 'Sequence',
+ 'Sized',
+ 'ValuesView',
+
+ # Structural checks, a.k.a. protocols.
+ 'Reversible',
+ 'SupportsAbs',
+ 'SupportsComplex',
+ 'SupportsFloat',
+ 'SupportsInt',
+
+ # Concrete collection types.
+ 'Counter',
+ 'Deque',
+ 'Dict',
+ 'DefaultDict',
+ 'List',
+ 'Set',
+ 'FrozenSet',
+ 'NamedTuple', # Not really a type.
+ 'Generator',
+
+ # One-off things.
+ 'AnyStr',
+ 'cast',
+ 'get_type_hints',
+ 'NewType',
+ 'no_type_check',
+ 'no_type_check_decorator',
+ 'NoReturn',
+ 'overload',
+ 'Text',
+ 'TYPE_CHECKING',
+]
+
+# 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 _qualname(x):
+ if sys.version_info[:2] >= (3, 3):
+ return x.__qualname__
+ else:
+ # Fall back to just name.
+ return x.__name__
+
+
+def _trim_name(nm):
+ whitelist = ('_TypeAlias', '_ForwardRef', '_TypingBase', '_FinalTypingBase')
+ if nm.startswith('_') and nm not in whitelist:
+ nm = nm[1:]
+ return nm
+
+
+class TypingMeta(type):
+ """Metaclass for most types defined in typing module
+ (not a part of public API).
+
+ This also defines a dummy constructor (all the work for most typing
+ constructs is done in __new__) and a nicer repr().
+ """
+
+ _is_protocol = False
+
+ def __new__(cls, name, bases, namespace):
+ return super(TypingMeta, cls).__new__(cls, str(name), bases, namespace)
+
+ @classmethod
+ def assert_no_subclassing(cls, bases):
+ for base in bases:
+ if isinstance(base, cls):
+ raise TypeError("Cannot subclass %s" %
+ (', '.join(map(_type_repr, bases)) or '()'))
+
+ def __init__(self, *args, **kwds):
+ pass
+
+ def _eval_type(self, globalns, localns):
+ """Override this in subclasses to interpret forward references.
+
+ For example, List['C'] is internally stored as
+ List[_ForwardRef('C')], which should evaluate to List[C],
+ where C is an object found in globalns or localns (searching
+ localns first, of course).
+ """
+ return self
+
+ def _get_type_vars(self, tvars):
+ pass
+
+ def __repr__(self):
+ qname = _trim_name(_qualname(self))
+ return '%s.%s' % (self.__module__, qname)
+
+
+class _TypingBase(object):
+ """Internal indicator of special typing constructs."""
+ __metaclass__ = TypingMeta
+ __slots__ = ('__weakref__',)
+
+ def __init__(self, *args, **kwds):
+ pass
+
+ def __new__(cls, *args, **kwds):
+ """Constructor.
+
+ This only exists to give a better error message in case
+ someone tries to subclass a special typing object (not a good idea).
+ """
+ if (len(args) == 3 and
+ isinstance(args[0], str) and
+ isinstance(args[1], tuple)):
+ # Close enough.
+ raise TypeError("Cannot subclass %r" % cls)
+ return super(_TypingBase, cls).__new__(cls)
+
+ # Things that are not classes also need these.
+ def _eval_type(self, globalns, localns):
+ return self
+
+ def _get_type_vars(self, tvars):
+ pass
+
+ def __repr__(self):
+ cls = type(self)
+ qname = _trim_name(_qualname(cls))
+ return '%s.%s' % (cls.__module__, qname)
+
+ def __call__(self, *args, **kwds):
+ raise TypeError("Cannot instantiate %r" % type(self))
+
+
+class _FinalTypingBase(_TypingBase):
+ """Internal mix-in class to prevent instantiation.
+
+ Prevents instantiation unless _root=True is given in class call.
+ It is used to create pseudo-singleton instances Any, Union, Optional, etc.
+ """
+
+ __slots__ = ()
+
+ def __new__(cls, *args, **kwds):
+ self = super(_FinalTypingBase, cls).__new__(cls, *args, **kwds)
+ if '_root' in kwds and kwds['_root'] is True:
+ return self
+ raise TypeError("Cannot instantiate %r" % cls)
+
+ def __reduce__(self):
+ return _trim_name(type(self).__name__)
+
+
+class _ForwardRef(_TypingBase):
+ """Internal wrapper to hold a forward reference."""
+
+ __slots__ = ('__forward_arg__', '__forward_code__',
+ '__forward_evaluated__', '__forward_value__')
+
+ def __init__(self, arg):
+ super(_ForwardRef, self).__init__(arg)
+ if not isinstance(arg, basestring):
+ raise TypeError('Forward reference must be a string -- got %r' % (arg,))
+ try:
+ code = compile(arg, '<string>', 'eval')
+ except SyntaxError:
+ raise SyntaxError('Forward reference must be an expression -- got %r' %
+ (arg,))
+ self.__forward_arg__ = arg
+ self.__forward_code__ = code
+ self.__forward_evaluated__ = False
+ self.__forward_value__ = None
+
+ def _eval_type(self, globalns, localns):
+ 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
+ self.__forward_value__ = _type_check(
+ eval(self.__forward_code__, globalns, localns),
+ "Forward references must evaluate to types.")
+ self.__forward_evaluated__ = True
+ return self.__forward_value__
+
+ def __eq__(self, other):
+ if not isinstance(other, _ForwardRef):
+ return NotImplemented
+ return (self.__forward_arg__ == other.__forward_arg__ and
+ self.__forward_value__ == other.__forward_value__)
+
+ def __hash__(self):
+ return hash((self.__forward_arg__, self.__forward_value__))
+
+ def __instancecheck__(self, obj):
+ raise TypeError("Forward references cannot be used with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ raise TypeError("Forward references cannot be used with issubclass().")
+
+ def __repr__(self):
+ return '_ForwardRef(%r)' % (self.__forward_arg__,)
+
+
+class _TypeAlias(_TypingBase):
+ """Internal helper class for defining generic variants of concrete types.
+
+ Note that this is not a type; let's call it a pseudo-type. It cannot
+ be used in instance and subclass checks in parameterized form, i.e.
+ ``isinstance(42, Match[str])`` raises ``TypeError`` instead of returning
+ ``False``.
+ """
+
+ __slots__ = ('name', 'type_var', 'impl_type', 'type_checker')
+
+ def __init__(self, name, type_var, impl_type, type_checker):
+ """Initializer.
+
+ Args:
+ name: The name, e.g. 'Pattern'.
+ type_var: The type parameter, e.g. AnyStr, or the
+ specific type, e.g. str.
+ impl_type: The implementation type.
+ type_checker: Function that takes an impl_type instance.
+ and returns a value that should be a type_var instance.
+ """
+ assert isinstance(name, basestring), repr(name)
+ assert isinstance(impl_type, type), repr(impl_type)
+ assert not isinstance(impl_type, TypingMeta), repr(impl_type)
+ assert isinstance(type_var, (type, _TypingBase)), repr(type_var)
+ self.name = name
+ self.type_var = type_var
+ self.impl_type = impl_type
+ self.type_checker = type_checker
+
+ def __repr__(self):
+ return "%s[%s]" % (self.name, _type_repr(self.type_var))
+
+ def __getitem__(self, parameter):
+ if not isinstance(self.type_var, TypeVar):
+ raise TypeError("%s cannot be further parameterized." % self)
+ if self.type_var.__constraints__ and isinstance(parameter, type):
+ if not issubclass(parameter, self.type_var.__constraints__):
+ raise TypeError("%s is not a valid substitution for %s." %
+ (parameter, self.type_var))
+ if isinstance(parameter, TypeVar) and parameter is not self.type_var:
+ raise TypeError("%s cannot be re-parameterized." % self)
+ return self.__class__(self.name, parameter,
+ self.impl_type, self.type_checker)
+
+ def __eq__(self, other):
+ if not isinstance(other, _TypeAlias):
+ return NotImplemented
+ return self.name == other.name and self.type_var == other.type_var
+
+ def __hash__(self):
+ return hash((self.name, self.type_var))
+
+ def __instancecheck__(self, obj):
+ if not isinstance(self.type_var, TypeVar):
+ raise TypeError("Parameterized type aliases cannot be used "
+ "with isinstance().")
+ return isinstance(obj, self.impl_type)
+
+ def __subclasscheck__(self, cls):
+ if not isinstance(self.type_var, TypeVar):
+ raise TypeError("Parameterized type aliases cannot be used "
+ "with issubclass().")
+ return issubclass(cls, self.impl_type)
+
+
+def _get_type_vars(types, tvars):
+ for t in types:
+ if isinstance(t, TypingMeta) or isinstance(t, _TypingBase):
+ t._get_type_vars(tvars)
+
+
+def _type_vars(types):
+ tvars = []
+ _get_type_vars(types, tvars)
+ return tuple(tvars)
+
+
+def _eval_type(t, globalns, localns):
+ if isinstance(t, TypingMeta) or isinstance(t, _TypingBase):
+ return t._eval_type(globalns, localns)
+ return t
+
+
+def _type_check(arg, msg):
+ """Check that the argument is a type, and return it (internal helper).
+
+ As a special case, accept None and return type(None) instead.
+ Also, _TypeAlias instances (e.g. Match, Pattern) are acceptable.
+
+ 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).
+ """
+ if arg is None:
+ return type(None)
+ if isinstance(arg, basestring):
+ arg = _ForwardRef(arg)
+ if (
+ isinstance(arg, _TypingBase) and type(arg).__name__ == '_ClassVar' or
+ not isinstance(arg, (type, _TypingBase)) and not callable(arg)
+ ):
+ raise TypeError(msg + " Got %.100r." % (arg,))
+ # Bare Union etc. are not valid as type arguments
+ if (
+ type(arg).__name__ in ('_Union', '_Optional') and
+ not getattr(arg, '__origin__', None) or
+ isinstance(arg, TypingMeta) and arg._gorg in (Generic, _Protocol)
+ ):
+ raise TypeError("Plain %s is not valid as type argument" % arg)
+ return arg
+
+
+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).
+ """
+ if isinstance(obj, type) and not isinstance(obj, TypingMeta):
+ if obj.__module__ == '__builtin__':
+ return _qualname(obj)
+ return '%s.%s' % (obj.__module__, _qualname(obj))
+ if obj is Ellipsis:
+ return('...')
+ if isinstance(obj, types.FunctionType):
+ return obj.__name__
+ return repr(obj)
+
+
+class ClassVarMeta(TypingMeta):
+ """Metaclass for _ClassVar"""
+
+ def __new__(cls, name, bases, namespace):
+ cls.assert_no_subclassing(bases)
+ self = super(ClassVarMeta, cls).__new__(cls, name, bases, namespace)
+ return self
+
+
+class _ClassVar(_FinalTypingBase):
+ """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 = {} # type: ClassVar[Dict[str, int]] # class variable
+ damage = 10 # type: int # 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().
+ """
+
+ __metaclass__ = ClassVarMeta
+ __slots__ = ('__type__',)
+
+ def __init__(self, tp=None, _root=False):
+ self.__type__ = tp
+
+ def __getitem__(self, item):
+ cls = type(self)
+ if self.__type__ is None:
+ return cls(_type_check(item,
+ '{} accepts only types.'.format(cls.__name__[1:])),
+ _root=True)
+ raise TypeError('{} cannot be further subscripted'
+ .format(cls.__name__[1:]))
+
+ def _eval_type(self, globalns, localns):
+ return type(self)(_eval_type(self.__type__, globalns, localns),
+ _root=True)
+
+ def __repr__(self):
+ r = super(_ClassVar, self).__repr__()
+ if self.__type__ is not None:
+ r += '[{}]'.format(_type_repr(self.__type__))
+ return r
+
+ def __hash__(self):
+ return hash((type(self).__name__, self.__type__))
+
+ def __eq__(self, other):
+ if not isinstance(other, _ClassVar):
+ return NotImplemented
+ if self.__type__ is not None:
+ return self.__type__ == other.__type__
+ return self is other
+
+
+ClassVar = _ClassVar(_root=True)
+
+
+class AnyMeta(TypingMeta):
+ """Metaclass for Any."""
+
+ def __new__(cls, name, bases, namespace):
+ cls.assert_no_subclassing(bases)
+ self = super(AnyMeta, cls).__new__(cls, name, bases, namespace)
+ return self
+
+
+class _Any(_FinalTypingBase):
+ """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
+ or class checks.
+ """
+ __metaclass__ = AnyMeta
+ __slots__ = ()
+
+ def __instancecheck__(self, obj):
+ raise TypeError("Any cannot be used with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ raise TypeError("Any cannot be used with issubclass().")
+
+
+Any = _Any(_root=True)
+
+
+class NoReturnMeta(TypingMeta):
+ """Metaclass for NoReturn."""
+
+ def __new__(cls, name, bases, namespace):
+ cls.assert_no_subclassing(bases)
+ self = super(NoReturnMeta, cls).__new__(cls, name, bases, namespace)
+ return self
+
+
+class _NoReturn(_FinalTypingBase):
+ """Special type indicating functions that never return.
+ Example::
+
+ from typing import NoReturn
+
+ def stop() -> NoReturn:
+ raise Exception('no way')
+
+ This type is invalid in other positions, e.g., ``List[NoReturn]``
+ will fail in static type checkers.
+ """
+ __metaclass__ = NoReturnMeta
+ __slots__ = ()
+
+ def __instancecheck__(self, obj):
+ raise TypeError("NoReturn cannot be used with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ raise TypeError("NoReturn cannot be used with issubclass().")
+
+
+NoReturn = _NoReturn(_root=True)
+
+
+class TypeVarMeta(TypingMeta):
+ def __new__(cls, name, bases, namespace):
+ cls.assert_no_subclassing(bases)
+ return super(TypeVarMeta, cls).__new__(cls, name, bases, namespace)
+
+
+class TypeVar(_TypingBase):
+ """Type variable.
+
+ Usage::
+
+ T = TypeVar('T') # Can be anything
+ A = TypeVar('A', str, bytes) # Must be str or bytes
+
+ Type variables exist primarily for the benefit of static type
+ checkers. They serve as the parameters for generic types as well
+ as for generic function definitions. See class Generic for more
+ information on generic types. Generic functions work as follows:
+
+ def repeat(x: T, n: int) -> List[T]:
+ '''Return a list containing n references to x.'''
+ return [x]*n
+
+ def longest(x: A, y: A) -> A:
+ '''Return the longest of two strings.'''
+ return x if len(x) >= len(y) else y
+
+ The latter example's signature is essentially the overloading
+ of (str, str) -> str and (bytes, bytes) -> bytes. Also note
+ that if the arguments are instances of some subclass of str,
+ the return type is still plain str.
+
+ At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError.
+
+ Type variables defined with covariant=True or contravariant=True
+ can be used do declare covariant or contravariant generic types.
+ See PEP 484 for more details. By default generic types are invariant
+ in all type variables.
+
+ Type variables can be introspected. e.g.:
+
+ T.__name__ == 'T'
+ T.__constraints__ == ()
+ T.__covariant__ == False
+ T.__contravariant__ = False
+ A.__constraints__ == (str, bytes)
+ """
+
+ __metaclass__ = TypeVarMeta
+ __slots__ = ('__name__', '__bound__', '__constraints__',
+ '__covariant__', '__contravariant__')
+
+ def __init__(self, name, *constraints, **kwargs):
+ super(TypeVar, self).__init__(name, *constraints, **kwargs)
+ bound = kwargs.get('bound', None)
+ covariant = kwargs.get('covariant', False)
+ contravariant = kwargs.get('contravariant', False)
+ self.__name__ = name
+ if covariant and contravariant:
+ raise ValueError("Bivariant types are not supported.")
+ self.__covariant__ = bool(covariant)
+ self.__contravariant__ = bool(contravariant)
+ if constraints and bound is not None:
+ raise TypeError("Constraints cannot be combined with bound=...")
+ if constraints and len(constraints) == 1:
+ raise TypeError("A single constraint is not allowed")
+ msg = "TypeVar(name, constraint, ...): constraints must be types."
+ self.__constraints__ = tuple(_type_check(t, msg) for t in constraints)
+ if bound:
+ self.__bound__ = _type_check(bound, "Bound must be a type.")
+ else:
+ self.__bound__ = None
+
+ def _get_type_vars(self, tvars):
+ if self not in tvars:
+ tvars.append(self)
+
+ def __repr__(self):
+ if self.__covariant__:
+ prefix = '+'
+ elif self.__contravariant__:
+ prefix = '-'
+ else:
+ prefix = '~'
+ return prefix + self.__name__
+
+ def __instancecheck__(self, instance):
+ raise TypeError("Type variables cannot be used with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ raise TypeError("Type variables cannot be used with issubclass().")
+
+
+# Some unconstrained type variables. These are used by the container types.
+# (These are not for export.)
+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.
+
+# A useful type variable with constraints. This represents string types.
+# (This one *is* for export!)
+AnyStr = TypeVar('AnyStr', bytes, unicode)
+
+
+def _replace_arg(arg, tvars, args):
+ """An internal helper function: replace arg if it is a type variable
+ found in tvars with corresponding substitution from args or
+ with corresponding substitution sub-tree if arg is a generic type.
+ """
+
+ if tvars is None:
+ tvars = []
+ if hasattr(arg, '_subs_tree') and isinstance(arg, (GenericMeta, _TypingBase)):
+ return arg._subs_tree(tvars, args)
+ if isinstance(arg, TypeVar):
+ for i, tvar in enumerate(tvars):
+ if arg == tvar:
+ return args[i]
+ return arg
+
+
+# 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;
+# * __args__ is a tuple of all arguments used in subscripting,
+# e.g., Dict[T, int].__args__ == (T, int).
+
+
+def _subs_tree(cls, tvars=None, args=None):
+ """An internal helper function: calculate substitution tree
+ for generic cls after replacing its type parameters with
+ substitutions in tvars -> args (if any).
+ Repeat the same following __origin__'s.
+
+ Return a list of arguments with all possible substitutions
+ performed. Arguments that are generic classes themselves are represented
+ as tuples (so that no new classes are created by this function).
+ For example: _subs_tree(List[Tuple[int, T]][str]) == [(Tuple, int, str)]
+ """
+
+ if cls.__origin__ is None:
+ return cls
+ # Make of chain of origins (i.e. cls -> cls.__origin__)
+ current = cls.__origin__
+ orig_chain = []
+ while current.__origin__ is not None:
+ orig_chain.append(current)
+ current = current.__origin__
+ # Replace type variables in __args__ if asked ...
+ tree_args = []
+ for arg in cls.__args__:
+ tree_args.append(_replace_arg(arg, tvars, args))
+ # ... then continue replacing down the origin chain.
+ for ocls in orig_chain:
+ new_tree_args = []
+ for arg in ocls.__args__:
+ new_tree_args.append(_replace_arg(arg, ocls.__parameters__, tree_args))
+ tree_args = new_tree_args
+ return tree_args
+
+
+def _remove_dups_flatten(parameters):
+ """An internal helper for Union creation and substitution: flatten Union's
+ among parameters, then remove duplicates and strict subclasses.
+ """
+
+ # Flatten out Union[Union[...], ...].
+ params = []
+ for p in parameters:
+ if isinstance(p, _Union) and p.__origin__ is Union:
+ params.extend(p.__args__)
+ elif isinstance(p, tuple) and len(p) > 0 and p[0] is Union:
+ params.extend(p[1:])
+ else:
+ params.append(p)
+ # Weed out strict duplicates, preserving the first of each occurrence.
+ all_params = set(params)
+ if len(all_params) < len(params):
+ new_params = []
+ for t in params:
+ if t in all_params:
+ new_params.append(t)
+ all_params.remove(t)
+ params = new_params
+ assert not all_params, all_params
+ # Weed out subclasses.
+ # E.g. Union[int, Employee, Manager] == Union[int, Employee].
+ # If object is present it will be sole survivor among proper classes.
+ # Never discard type variables.
+ # (In particular, Union[str, AnyStr] != AnyStr.)
+ all_params = set(params)
+ for t1 in params:
+ if not isinstance(t1, type):
+ continue
+ if any(isinstance(t2, type) and issubclass(t1, t2)
+ for t2 in all_params - {t1}
+ if not (isinstance(t2, GenericMeta) and
+ t2.__origin__ is not None)):
+ all_params.remove(t1)
+ return tuple(t for t in params if t in all_params)
+
+
+def _check_generic(cls, parameters):
+ # Check correct count for parameters of a generic cls (internal helper).
+ if not cls.__parameters__:
+ raise TypeError("%s is not a generic class" % repr(cls))
+ alen = len(parameters)
+ elen = len(cls.__parameters__)
+ if alen != elen:
+ raise TypeError("Too %s parameters for %s; actual %s, expected %s" %
+ ("many" if alen > elen else "few", repr(cls), alen, elen))
+
+
+_cleanups = []
+
+
+def _tp_cache(func):
+ maxsize = 128
+ cache = {}
+ _cleanups.append(cache.clear)
+
+ @functools.wraps(func)
+ def inner(*args):
+ key = args
+ try:
+ return cache[key]
+ except TypeError:
+ # Assume it's an unhashable argument.
+ return func(*args)
+ except KeyError:
+ value = func(*args)
+ if len(cache) >= maxsize:
+ # If the cache grows too much, just start over.
+ cache.clear()
+ cache[key] = value
+ return value
+
+ return inner
+
+
+class UnionMeta(TypingMeta):
+ """Metaclass for Union."""
+
+ def __new__(cls, name, bases, namespace):
+ cls.assert_no_subclassing(bases)
+ return super(UnionMeta, cls).__new__(cls, name, bases, namespace)
+
+
+class _Union(_FinalTypingBase):
+ """Union type; Union[X, Y] means either X or 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.::
+
+ Union[Union[int, str], float] == Union[int, str, float]
+
+ - Unions of a single argument vanish, e.g.::
+
+ Union[int] == int # The constructor actually returns int
+
+ - Redundant arguments are skipped, e.g.::
+
+ Union[int, str, int] == Union[int, str]
+
+ - When comparing unions, the argument order is ignored, e.g.::
+
+ Union[int, str] == Union[str, int]
+
+ - When two arguments have a subclass relationship, the least
+ derived argument is kept, e.g.::
+
+ class Employee: pass
+ class Manager(Employee): pass
+ Union[int, Employee, Manager] == Union[int, Employee]
+ Union[Manager, int, Employee] == Union[int, Employee]
+ Union[Employee, Manager] == Employee
+
+ - Similar for object::
+
+ Union[int, object] == object
+
+ - You cannot subclass or instantiate a union.
+
+ - You can use Optional[X] as a shorthand for Union[X, None].
+ """
+
+ __metaclass__ = UnionMeta
+ __slots__ = ('__parameters__', '__args__', '__origin__', '__tree_hash__')
+
+ def __new__(cls, parameters=None, origin=None, *args, **kwds):
+ self = super(_Union, cls).__new__(cls, parameters, origin, *args, **kwds)
+ if origin is None:
+ self.__parameters__ = None
+ self.__args__ = None
+ self.__origin__ = None
+ self.__tree_hash__ = hash(frozenset(('Union',)))
+ return self
+ if not isinstance(parameters, tuple):
+ raise TypeError("Expected parameters=<tuple>")
+ if origin is Union:
+ parameters = _remove_dups_flatten(parameters)
+ # It's not a union if there's only one type left.
+ if len(parameters) == 1:
+ return parameters[0]
+ self.__parameters__ = _type_vars(parameters)
+ self.__args__ = parameters
+ self.__origin__ = origin
+ # Pre-calculate the __hash__ on instantiation.
+ # This improves speed for complex substitutions.
+ subs_tree = self._subs_tree()
+ if isinstance(subs_tree, tuple):
+ self.__tree_hash__ = hash(frozenset(subs_tree))
+ else:
+ self.__tree_hash__ = hash(subs_tree)
+ return self
+
+ def _eval_type(self, globalns, localns):
+ if self.__args__ is None:
+ return self
+ ev_args = tuple(_eval_type(t, globalns, localns) for t in self.__args__)
+ ev_origin = _eval_type(self.__origin__, globalns, localns)
+ if ev_args == self.__args__ and ev_origin == self.__origin__:
+ # Everything is already evaluated.
+ return self
+ return self.__class__(ev_args, ev_origin, _root=True)
+
+ def _get_type_vars(self, tvars):
+ if self.__origin__ and self.__parameters__:
+ _get_type_vars(self.__parameters__, tvars)
+
+ def __repr__(self):
+ if self.__origin__ is None:
+ return super(_Union, self).__repr__()
+ tree = self._subs_tree()
+ if not isinstance(tree, tuple):
+ return repr(tree)
+ return tree[0]._tree_repr(tree)
+
+ def _tree_repr(self, tree):
+ arg_list = []
+ for arg in tree[1:]:
+ if not isinstance(arg, tuple):
+ arg_list.append(_type_repr(arg))
+ else:
+ arg_list.append(arg[0]._tree_repr(arg))
+ return super(_Union, self).__repr__() + '[%s]' % ', '.join(arg_list)
+
+ @_tp_cache
+ def __getitem__(self, parameters):
+ if parameters == ():
+ raise TypeError("Cannot take a Union of no types.")
+ if not isinstance(parameters, tuple):
+ parameters = (parameters,)
+ if self.__origin__ is None:
+ msg = "Union[arg, ...]: each arg must be a type."
+ else:
+ msg = "Parameters to generic types must be types."
+ parameters = tuple(_type_check(p, msg) for p in parameters)
+ if self is not Union:
+ _check_generic(self, parameters)
+ return self.__class__(parameters, origin=self, _root=True)
+
+ def _subs_tree(self, tvars=None, args=None):
+ if self is Union:
+ return Union # Nothing to substitute
+ tree_args = _subs_tree(self, tvars, args)
+ tree_args = _remove_dups_flatten(tree_args)
+ if len(tree_args) == 1:
+ return tree_args[0] # Union of a single type is that type
+ return (Union,) + tree_args
+
+ def __eq__(self, other):
+ if isinstance(other, _Union):
+ return self.__tree_hash__ == other.__tree_hash__
+ elif self is not Union:
+ return self._subs_tree() == other
+ else:
+ return self is other
+
+ def __hash__(self):
+ return self.__tree_hash__
+
+ def __instancecheck__(self, obj):
+ raise TypeError("Unions cannot be used with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ raise TypeError("Unions cannot be used with issubclass().")
+
+
+Union = _Union(_root=True)
+
+
+class OptionalMeta(TypingMeta):
+ """Metaclass for Optional."""
+
+ def __new__(cls, name, bases, namespace):
+ cls.assert_no_subclassing(bases)
+ return super(OptionalMeta, cls).__new__(cls, name, bases, namespace)
+
+
+class _Optional(_FinalTypingBase):
+ """Optional type.
+
+ Optional[X] is equivalent to Union[X, None].
+ """
+
+ __metaclass__ = OptionalMeta
+ __slots__ = ()
+
+ @_tp_cache
+ def __getitem__(self, arg):
+ arg = _type_check(arg, "Optional[t] requires a single type.")
+ return Union[arg, type(None)]
+
+
+Optional = _Optional(_root=True)
+
+
+def _next_in_mro(cls):
+ """Helper for Generic.__new__.
+
+ Returns the class after the last occurrence of Generic or
+ Generic[...] in cls.__mro__.
+ """
+ next_in_mro = object
+ # Look for the last occurrence of Generic or Generic[...].
+ for i, c in enumerate(cls.__mro__[:-1]):
+ if isinstance(c, GenericMeta) and c._gorg is Generic:
+ next_in_mro = cls.__mro__[i + 1]
+ return next_in_mro
+
+
+def _make_subclasshook(cls):
+ """Construct a __subclasshook__ callable that incorporates
+ the associated __extra__ class in subclass checks performed
+ against cls.
+ """
+ if isinstance(cls.__extra__, abc.ABCMeta):
+ # The logic mirrors that of ABCMeta.__subclasscheck__.
+ # Registered classes need not be checked here because
+ # cls and its extra share the same _abc_registry.
+ def __extrahook__(cls, subclass):
+ res = cls.__extra__.__subclasshook__(subclass)
+ if res is not NotImplemented:
+ return res
+ if cls.__extra__ in getattr(subclass, '__mro__', ()):
+ return True
+ for scls in cls.__extra__.__subclasses__():
+ if isinstance(scls, GenericMeta):
+ continue
+ if issubclass(subclass, scls):
+ return True
+ return NotImplemented
+ else:
+ # For non-ABC extras we'll just call issubclass().
+ def __extrahook__(cls, subclass):
+ if cls.__extra__ and issubclass(subclass, cls.__extra__):
+ return True
+ return NotImplemented
+ return classmethod(__extrahook__)
+
+
+class GenericMeta(TypingMeta, abc.ABCMeta):
+ """Metaclass for generic types.
+
+ This is a metaclass for typing.Generic and generic ABCs defined in
+ typing module. User defined subclasses of GenericMeta can override
+ __new__ and invoke super().__new__. Note that GenericMeta.__new__
+ has strict rules on what is allowed in its bases argument:
+ * plain Generic is disallowed in bases;
+ * Generic[...] should appear in bases at most once;
+ * if Generic[...] is present, then it should list all type variables
+ that appear in other bases.
+ In addition, type of all generic bases is erased, e.g., C[int] is
+ stripped to plain C.
+ """
+
+ def __new__(cls, name, bases, namespace,
+ tvars=None, args=None, origin=None, extra=None, orig_bases=None):
+ """Create a new generic class. GenericMeta.__new__ accepts
+ keyword arguments that are used for internal bookkeeping, therefore
+ an override should pass unused keyword arguments to super().
+ """
+ if tvars is not None:
+ # Called from __getitem__() below.
+ assert origin is not None
+ assert all(isinstance(t, TypeVar) for t in tvars), tvars
+ else:
+ # Called from class statement.
+ assert tvars is None, tvars
+ assert args is None, args
+ assert origin is None, origin
+
+ # Get the full set of tvars from the bases.
+ tvars = _type_vars(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 bases:
+ if base is Generic:
+ raise TypeError("Cannot inherit from plain Generic")
+ if (isinstance(base, GenericMeta) and
+ base.__origin__ is Generic):
+ if gvars is not None:
+ raise TypeError(
+ "Cannot inherit from Generic[...] multiple types.")
+ gvars = base.__parameters__
+ if gvars is None:
+ gvars = tvars
+ else:
+ tvarset = set(tvars)
+ gvarset = set(gvars)
+ if not tvarset <= gvarset:
+ raise TypeError(
+ "Some type variables (%s) "
+ "are not listed in Generic[%s]" %
+ (", ".join(str(t) for t in tvars if t not in gvarset),
+ ", ".join(str(g) for g in gvars)))
+ tvars = gvars
+
+ initial_bases = bases
+ if extra is None:
+ extra = namespace.get('__extra__')
+ if extra is not None and type(extra) is abc.ABCMeta and extra not in bases:
+ bases = (extra,) + bases
+ bases = tuple(b._gorg if isinstance(b, GenericMeta) else b for b in bases)
+
+ # remove bare Generic from bases if there are other generic bases
+ if any(isinstance(b, GenericMeta) and b is not Generic for b in bases):
+ bases = tuple(b for b in bases if b is not Generic)
+ namespace.update({'__origin__': origin, '__extra__': extra})
+ self = super(GenericMeta, cls).__new__(cls, name, bases, namespace)
+ super(GenericMeta, self).__setattr__('_gorg',
+ self if not origin else origin._gorg)
+
+ self.__parameters__ = tvars
+ # Be prepared that GenericMeta will be subclassed by TupleMeta
+ # and CallableMeta, those two allow ..., (), or [] in __args___.
+ self.__args__ = tuple(Ellipsis if a is _TypingEllipsis else
+ () if a is _TypingEmpty else
+ a for a in args) if args else None
+ # Speed hack (https://github.com/python/typing/issues/196).
+ self.__next_in_mro__ = _next_in_mro(self)
+ # Preserve base classes on subclassing (__bases__ are type erased now).
+ if orig_bases is None:
+ self.__orig_bases__ = initial_bases
+
+ # This allows unparameterized generic collections to be used
+ # with issubclass() and isinstance() in the same way as their
+ # collections.abc counterparts (e.g., isinstance([], Iterable)).
+ if (
+ '__subclasshook__' not in namespace and extra or
+ # allow overriding
+ getattr(self.__subclasshook__, '__name__', '') == '__extrahook__'
+ ):
+ self.__subclasshook__ = _make_subclasshook(self)
+
+ if origin and hasattr(origin, '__qualname__'): # Fix for Python 3.2.
+ self.__qualname__ = origin.__qualname__
+ self.__tree_hash__ = (hash(self._subs_tree()) if origin else
+ super(GenericMeta, self).__hash__())
+ return self
+
+ def __init__(self, *args, **kwargs):
+ super(GenericMeta, self).__init__(*args, **kwargs)
+ if isinstance(self.__extra__, abc.ABCMeta):
+ self._abc_registry = self.__extra__._abc_registry
+ self._abc_cache = self.__extra__._abc_cache
+ elif self.__origin__ is not None:
+ self._abc_registry = self.__origin__._abc_registry
+ self._abc_cache = self.__origin__._abc_cache
+
+ # _abc_negative_cache and _abc_negative_cache_version
+ # realized as descriptors, since GenClass[t1, t2, ...] always
+ # share subclass info with GenClass.
+ # This is an important memory optimization.
+ @property
+ def _abc_negative_cache(self):
+ if isinstance(self.__extra__, abc.ABCMeta):
+ return self.__extra__._abc_negative_cache
+ return self._gorg._abc_generic_negative_cache
+
+ @_abc_negative_cache.setter
+ def _abc_negative_cache(self, value):
+ if self.__origin__ is None:
+ if isinstance(self.__extra__, abc.ABCMeta):
+ self.__extra__._abc_negative_cache = value
+ else:
+ self._abc_generic_negative_cache = value
+
+ @property
+ def _abc_negative_cache_version(self):
+ if isinstance(self.__extra__, abc.ABCMeta):
+ return self.__extra__._abc_negative_cache_version
+ return self._gorg._abc_generic_negative_cache_version
+
+ @_abc_negative_cache_version.setter
+ def _abc_negative_cache_version(self, value):
+ if self.__origin__ is None:
+ if isinstance(self.__extra__, abc.ABCMeta):
+ self.__extra__._abc_negative_cache_version = value
+ else:
+ self._abc_generic_negative_cache_version = value
+
+ def _get_type_vars(self, tvars):
+ if self.__origin__ and self.__parameters__:
+ _get_type_vars(self.__parameters__, tvars)
+
+ def _eval_type(self, globalns, localns):
+ ev_origin = (self.__origin__._eval_type(globalns, localns)
+ if self.__origin__ else None)
+ ev_args = tuple(_eval_type(a, globalns, localns) for a
+ in self.__args__) if self.__args__ else None
+ if ev_origin == self.__origin__ and ev_args == self.__args__:
+ return self
+ return self.__class__(self.__name__,
+ self.__bases__,
+ dict(self.__dict__),
+ tvars=_type_vars(ev_args) if ev_args else None,
+ args=ev_args,
+ origin=ev_origin,
+ extra=self.__extra__,
+ orig_bases=self.__orig_bases__)
+
+ def __repr__(self):
+ if self.__origin__ is None:
+ return super(GenericMeta, self).__repr__()
+ return self._tree_repr(self._subs_tree())
+
+ def _tree_repr(self, tree):
+ arg_list = []
+ for arg in tree[1:]:
+ if arg == ():
+ arg_list.append('()')
+ elif not isinstance(arg, tuple):
+ arg_list.append(_type_repr(arg))
+ else:
+ arg_list.append(arg[0]._tree_repr(arg))
+ return super(GenericMeta, self).__repr__() + '[%s]' % ', '.join(arg_list)
+
+ def _subs_tree(self, tvars=None, args=None):
+ if self.__origin__ is None:
+ return self
+ tree_args = _subs_tree(self, tvars, args)
+ return (self._gorg,) + tuple(tree_args)
+
+ def __eq__(self, other):
+ if not isinstance(other, GenericMeta):
+ return NotImplemented
+ if self.__origin__ is None or other.__origin__ is None:
+ return self is other
+ return self.__tree_hash__ == other.__tree_hash__
+
+ def __hash__(self):
+ return self.__tree_hash__
+
+ @_tp_cache
+ def __getitem__(self, params):
+ if not isinstance(params, tuple):
+ params = (params,)
+ if not params and self._gorg is not Tuple:
+ raise TypeError(
+ "Parameter list to %s[...] cannot be empty" % _qualname(self))
+ msg = "Parameters to generic types must be types."
+ params = tuple(_type_check(p, msg) for p in params)
+ if self is Generic:
+ # Generic can only be subscripted with unique type variables.
+ if not all(isinstance(p, TypeVar) for p in params):
+ raise TypeError(
+ "Parameters to Generic[...] must all be type variables")
+ if len(set(params)) != len(params):
+ raise TypeError(
+ "Parameters to Generic[...] must all be unique")
+ tvars = params
+ args = params
+ elif self in (Tuple, Callable):
+ tvars = _type_vars(params)
+ args = params
+ elif self is _Protocol:
+ # _Protocol is internal, don't check anything.
+ tvars = params
+ args = params
+ elif self.__origin__ in (Generic, _Protocol):
+ # Can't subscript Generic[...] or _Protocol[...].
+ raise TypeError("Cannot subscript already-subscripted %s" %
+ repr(self))
+ else:
+ # Subscripting a regular Generic subclass.
+ _check_generic(self, params)
+ tvars = _type_vars(params)
+ args = params
+
+ prepend = (self,) if self.__origin__ is None else ()
+ return self.__class__(self.__name__,
+ prepend + self.__bases__,
+ dict(self.__dict__),
+ tvars=tvars,
+ args=args,
+ origin=self,
+ extra=self.__extra__,
+ orig_bases=self.__orig_bases__)
+
+ def __subclasscheck__(self, cls):
+ if self.__origin__ is not None:
+ # This should only be modules within the standard
+ # library. singledispatch is the only exception, because
+ # it's a Python 2 backport of functools.singledispatch.
+ if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools',
+ 'singledispatch']:
+ raise TypeError("Parameterized generics cannot be used with class "
+ "or instance checks")
+ return False
+ if self is Generic:
+ raise TypeError("Class %r cannot be used with class "
+ "or instance checks" % self)
+ return super(GenericMeta, self).__subclasscheck__(cls)
+
+ def __instancecheck__(self, instance):
+ # Since we extend ABC.__subclasscheck__ and
+ # ABC.__instancecheck__ inlines the cache checking done by the
+ # latter, we must extend __instancecheck__ too. For simplicity
+ # we just skip the cache check -- instance checks for generic
+ # classes are supposed to be rare anyways.
+ if not isinstance(instance, type):
+ return issubclass(instance.__class__, self)
+ return False
+
+ def __setattr__(self, attr, value):
+ # We consider all the subscripted genrics as proxies for original class
+ if (
+ attr.startswith('__') and attr.endswith('__') or
+ attr.startswith('_abc_')
+ ):
+ super(GenericMeta, self).__setattr__(attr, value)
+ else:
+ super(GenericMeta, self._gorg).__setattr__(attr, value)
+
+
+def _copy_generic(self):
+ """Hack to work around https://bugs.python.org/issue11480 on Python 2"""
+ return self.__class__(self.__name__, self.__bases__, dict(self.__dict__),
+ self.__parameters__, self.__args__, self.__origin__,
+ self.__extra__, self.__orig_bases__)
+
+
+copy._copy_dispatch[GenericMeta] = _copy_generic
+
+
+# Prevent checks for Generic to crash when defining Generic.
+Generic = None
+
+
+def _generic_new(base_cls, cls, *args, **kwds):
+ # Assure type is erased on instantiation,
+ # but attempt to store it in __orig_class__
+ if cls.__origin__ is None:
+ if (base_cls.__new__ is object.__new__ and
+ cls.__init__ is not object.__init__):
+ return base_cls.__new__(cls)
+ else:
+ return base_cls.__new__(cls, *args, **kwds)
+ else:
+ origin = cls._gorg
+ if (base_cls.__new__ is object.__new__ and
+ cls.__init__ is not object.__init__):
+ obj = base_cls.__new__(origin)
+ else:
+ obj = base_cls.__new__(origin, *args, **kwds)
+ try:
+ obj.__orig_class__ = cls
+ except AttributeError:
+ pass
+ obj.__init__(*args, **kwds)
+ return obj
+
+
+class Generic(object):
+ """Abstract base class for generic types.
+
+ A generic type is typically declared by inheriting from
+ this class parameterized with one or more type variables.
+ For example, a generic mapping type might be defined as::
+
+ class Mapping(Generic[KT, VT]):
+ def __getitem__(self, key: KT) -> VT:
+ ...
+ # Etc.
+
+ This class can then be used as follows::
+
+ def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
+ try:
+ return mapping[key]
+ except KeyError:
+ return default
+ """
+
+ __metaclass__ = GenericMeta
+ __slots__ = ()
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is Generic:
+ raise TypeError("Type Generic cannot be instantiated; "
+ "it can be used only as a base class")
+ return _generic_new(cls.__next_in_mro__, cls, *args, **kwds)
+
+
+class _TypingEmpty(object):
+ """Internal placeholder for () or []. Used by TupleMeta and CallableMeta
+ to allow empty list/tuple in specific places, without allowing them
+ to sneak in where prohibited.
+ """
+
+
+class _TypingEllipsis(object):
+ """Internal placeholder for ... (ellipsis)."""
+
+
+class TupleMeta(GenericMeta):
+ """Metaclass for Tuple (internal)."""
+
+ @_tp_cache
+ def __getitem__(self, parameters):
+ if self.__origin__ is not None or self._gorg is not Tuple:
+ # Normal generic rules apply if this is not the first subscription
+ # or a subscription of a subclass.
+ return super(TupleMeta, self).__getitem__(parameters)
+ if parameters == ():
+ return super(TupleMeta, self).__getitem__((_TypingEmpty,))
+ if not isinstance(parameters, tuple):
+ parameters = (parameters,)
+ if len(parameters) == 2 and parameters[1] is Ellipsis:
+ msg = "Tuple[t, ...]: t must be a type."
+ p = _type_check(parameters[0], msg)
+ return super(TupleMeta, self).__getitem__((p, _TypingEllipsis))
+ msg = "Tuple[t0, t1, ...]: each t must be a type."
+ parameters = tuple(_type_check(p, msg) for p in parameters)
+ return super(TupleMeta, self).__getitem__(parameters)
+
+ def __instancecheck__(self, obj):
+ if self.__args__ is None:
+ return isinstance(obj, tuple)
+ raise TypeError("Parameterized Tuple cannot be used "
+ "with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ if self.__args__ is None:
+ return issubclass(cls, tuple)
+ raise TypeError("Parameterized Tuple cannot be used "
+ "with issubclass().")
+
+
+copy._copy_dispatch[TupleMeta] = _copy_generic
+
+
+class Tuple(tuple):
+ """Tuple type; 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, ...].
+ """
+
+ __metaclass__ = TupleMeta
+ __extra__ = tuple
+ __slots__ = ()
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is Tuple:
+ raise TypeError("Type Tuple cannot be instantiated; "
+ "use tuple() instead")
+ return _generic_new(tuple, cls, *args, **kwds)
+
+
+class CallableMeta(GenericMeta):
+ """ Metaclass for Callable."""
+
+ def __repr__(self):
+ if self.__origin__ is None:
+ return super(CallableMeta, self).__repr__()
+ return self._tree_repr(self._subs_tree())
+
+ def _tree_repr(self, tree):
+ if self._gorg is not Callable:
+ return super(CallableMeta, self)._tree_repr(tree)
+ # For actual Callable (not its subclass) we override
+ # super(CallableMeta, self)._tree_repr() for nice formatting.
+ arg_list = []
+ for arg in tree[1:]:
+ if not isinstance(arg, tuple):
+ arg_list.append(_type_repr(arg))
+ else:
+ arg_list.append(arg[0]._tree_repr(arg))
+ if arg_list[0] == '...':
+ return repr(tree[0]) + '[..., %s]' % arg_list[1]
+ return (repr(tree[0]) +
+ '[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1]))
+
+ def __getitem__(self, parameters):
+ """A thin wrapper around __getitem_inner__ to provide the latter
+ with hashable arguments to improve speed.
+ """
+
+ if self.__origin__ is not None or self._gorg is not Callable:
+ return super(CallableMeta, self).__getitem__(parameters)
+ if not isinstance(parameters, tuple) or len(parameters) != 2:
+ raise TypeError("Callable must be used as "
+ "Callable[[arg, ...], result].")
+ args, result = parameters
+ if args is Ellipsis:
+ parameters = (Ellipsis, result)
+ else:
+ if not isinstance(args, list):
+ raise TypeError("Callable[args, result]: args must be a list."
+ " Got %.100r." % (args,))
+ parameters = (tuple(args), result)
+ return self.__getitem_inner__(parameters)
+
+ @_tp_cache
+ def __getitem_inner__(self, parameters):
+ args, result = parameters
+ msg = "Callable[args, result]: result must be a type."
+ result = _type_check(result, msg)
+ if args is Ellipsis:
+ return super(CallableMeta, self).__getitem__((_TypingEllipsis, result))
+ msg = "Callable[[arg, ...], result]: each arg must be a type."
+ args = tuple(_type_check(arg, msg) for arg in args)
+ parameters = args + (result,)
+ return super(CallableMeta, self).__getitem__(parameters)
+
+
+copy._copy_dispatch[CallableMeta] = _copy_generic
+
+
+class Callable(object):
+ """Callable type; Callable[[int], str] is a function of (int) -> 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 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.
+ """
+
+ __metaclass__ = CallableMeta
+ __extra__ = collections_abc.Callable
+ __slots__ = ()
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is Callable:
+ raise TypeError("Type Callable cannot be instantiated; "
+ "use a non-abstract subclass instead")
+ return _generic_new(cls.__next_in_mro__, cls, *args, **kwds)
+
+
+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 _get_defaults(func):
+ """Internal helper to extract the default arguments, by name."""
+ code = func.__code__
+ pos_count = code.co_argcount
+ arg_names = code.co_varnames
+ arg_names = arg_names[:pos_count]
+ defaults = func.__defaults__ or ()
+ kwdefaults = func.__kwdefaults__
+ res = dict(kwdefaults) if kwdefaults else {}
+ pos_offset = pos_count - len(defaults)
+ for name, value in zip(arg_names[pos_offset:], defaults):
+ assert name not in res
+ res[name] = value
+ return res
+
+
+def get_type_hints(obj, globalns=None, localns=None):
+ """In Python 2 this is not supported and always returns None."""
+ return None
+
+
+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):
+ arg_attrs = arg.__dict__.copy()
+ for attr, val in arg.__dict__.items():
+ if val in arg.__bases__ + (arg,):
+ arg_attrs.pop(attr)
+ for obj in arg_attrs.values():
+ if isinstance(obj, types.FunctionType):
+ obj.__no_type_check__ = True
+ 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.")
+
+
+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. For example:
+
+ @overload
+ def utf8(value: None) -> None: ...
+ @overload
+ def utf8(value: bytes) -> bytes: ...
+ @overload
+ def utf8(value: str) -> bytes: ...
+ def utf8(value):
+ # implementation goes here
+ """
+ return _overload_dummy
+
+
+class _ProtocolMeta(GenericMeta):
+ """Internal metaclass for _Protocol.
+
+ This exists so _Protocol classes can be generic without deriving
+ from Generic.
+ """
+
+ def __instancecheck__(self, obj):
+ if _Protocol not in self.__bases__:
+ return super(_ProtocolMeta, self).__instancecheck__(obj)
+ raise TypeError("Protocols cannot be used with isinstance().")
+
+ def __subclasscheck__(self, cls):
+ if not self._is_protocol:
+ # No structural checks since this isn't a protocol.
+ return NotImplemented
+
+ if self is _Protocol:
+ # Every class is a subclass of the empty protocol.
+ return True
+
+ # Find all attributes defined in the protocol.
+ attrs = self._get_protocol_attrs()
+
+ for attr in attrs:
+ if not any(attr in d.__dict__ for d in cls.__mro__):
+ return False
+ return True
+
+ def _get_protocol_attrs(self):
+ # Get all Protocol base classes.
+ protocol_bases = []
+ for c in self.__mro__:
+ if getattr(c, '_is_protocol', False) and c.__name__ != '_Protocol':
+ protocol_bases.append(c)
+
+ # Get attributes included in protocol.
+ attrs = set()
+ for base in protocol_bases:
+ for attr in base.__dict__.keys():
+ # Include attributes not defined in any non-protocol bases.
+ for c in self.__mro__:
+ if (c is not base and attr in c.__dict__ and
+ not getattr(c, '_is_protocol', False)):
+ break
+ else:
+ if (not attr.startswith('_abc_') and
+ attr != '__abstractmethods__' and
+ attr != '_is_protocol' and
+ attr != '_gorg' and
+ attr != '__dict__' and
+ attr != '__args__' and
+ attr != '__slots__' and
+ attr != '_get_protocol_attrs' and
+ attr != '__next_in_mro__' and
+ attr != '__parameters__' and
+ attr != '__origin__' and
+ attr != '__orig_bases__' and
+ attr != '__extra__' and
+ attr != '__tree_hash__' and
+ attr != '__module__'):
+ attrs.add(attr)
+
+ return attrs
+
+
+class _Protocol(object):
+ """Internal base class for protocol classes.
+
+ This implements a simple-minded structural issubclass check
+ (similar but more general than the one-offs in collections.abc
+ such as Hashable).
+ """
+
+ __metaclass__ = _ProtocolMeta
+ __slots__ = ()
+
+ _is_protocol = True
+
+
+# Various ABCs mimicking those in collections.abc.
+# A few are simply re-exported for completeness.
+
+Hashable = collections_abc.Hashable # Not generic.
+
+
+class Iterable(Generic[T_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.Iterable
+
+
+class Iterator(Iterable[T_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.Iterator
+
+
+class SupportsInt(_Protocol):
+ __slots__ = ()
+
+ @abstractmethod
+ def __int__(self):
+ pass
+
+
+class SupportsFloat(_Protocol):
+ __slots__ = ()
+
+ @abstractmethod
+ def __float__(self):
+ pass
+
+
+class SupportsComplex(_Protocol):
+ __slots__ = ()
+
+ @abstractmethod
+ def __complex__(self):
+ pass
+
+
+class SupportsAbs(_Protocol[T_co]):
+ __slots__ = ()
+
+ @abstractmethod
+ def __abs__(self):
+ pass
+
+
+if hasattr(collections_abc, 'Reversible'):
+ class Reversible(Iterable[T_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.Reversible
+else:
+ class Reversible(_Protocol[T_co]):
+ __slots__ = ()
+
+ @abstractmethod
+ def __reversed__(self):
+ pass
+
+
+Sized = collections_abc.Sized # Not generic.
+
+
+class Container(Generic[T_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.Container
+
+
+# Callable was defined earlier.
+
+
+class AbstractSet(Sized, Iterable[T_co], Container[T_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.Set
+
+
+class MutableSet(AbstractSet[T]):
+ __slots__ = ()
+ __extra__ = collections_abc.MutableSet
+
+
+# NOTE: It is only covariant in the value type.
+class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.Mapping
+
+
+class MutableMapping(Mapping[KT, VT]):
+ __slots__ = ()
+ __extra__ = collections_abc.MutableMapping
+
+
+if hasattr(collections_abc, 'Reversible'):
+ class Sequence(Sized, Reversible[T_co], Container[T_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.Sequence
+else:
+ class Sequence(Sized, Iterable[T_co], Container[T_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.Sequence
+
+
+class MutableSequence(Sequence[T]):
+ __slots__ = ()
+ __extra__ = collections_abc.MutableSequence
+
+
+class ByteString(Sequence[int]):
+ pass
+
+
+ByteString.register(str)
+ByteString.register(bytearray)
+
+
+class List(list, MutableSequence[T]):
+ __slots__ = ()
+ __extra__ = list
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is List:
+ raise TypeError("Type List cannot be instantiated; "
+ "use list() instead")
+ return _generic_new(list, cls, *args, **kwds)
+
+
+class Deque(collections.deque, MutableSequence[T]):
+ __slots__ = ()
+ __extra__ = collections.deque
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is Deque:
+ return collections.deque(*args, **kwds)
+ return _generic_new(collections.deque, cls, *args, **kwds)
+
+
+class Set(set, MutableSet[T]):
+ __slots__ = ()
+ __extra__ = set
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is Set:
+ raise TypeError("Type Set cannot be instantiated; "
+ "use set() instead")
+ return _generic_new(set, cls, *args, **kwds)
+
+
+class FrozenSet(frozenset, AbstractSet[T_co]):
+ __slots__ = ()
+ __extra__ = frozenset
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is FrozenSet:
+ raise TypeError("Type FrozenSet cannot be instantiated; "
+ "use frozenset() instead")
+ return _generic_new(frozenset, cls, *args, **kwds)
+
+
+class MappingView(Sized, Iterable[T_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.MappingView
+
+
+class KeysView(MappingView[KT], AbstractSet[KT]):
+ __slots__ = ()
+ __extra__ = collections_abc.KeysView
+
+
+class ItemsView(MappingView[Tuple[KT, VT_co]],
+ AbstractSet[Tuple[KT, VT_co]],
+ Generic[KT, VT_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.ItemsView
+
+
+class ValuesView(MappingView[VT_co]):
+ __slots__ = ()
+ __extra__ = collections_abc.ValuesView
+
+
+class ContextManager(Generic[T_co]):
+ __slots__ = ()
+
+ def __enter__(self):
+ return self
+
+ @abc.abstractmethod
+ def __exit__(self, exc_type, exc_value, traceback):
+ return None
+
+ @classmethod
+ def __subclasshook__(cls, C):
+ if cls is ContextManager:
+ # In Python 3.6+, it is possible to set a method to None to
+ # explicitly indicate that the class does not implement an ABC
+ # (https://bugs.python.org/issue25958), but we do not support
+ # that pattern here because this fallback class is only used
+ # in Python 3.5 and earlier.
+ if (any("__enter__" in B.__dict__ for B in C.__mro__) and
+ any("__exit__" in B.__dict__ for B in C.__mro__)):
+ return True
+ return NotImplemented
+
+
+class Dict(dict, MutableMapping[KT, VT]):
+ __slots__ = ()
+ __extra__ = dict
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is Dict:
+ raise TypeError("Type Dict cannot be instantiated; "
+ "use dict() instead")
+ return _generic_new(dict, cls, *args, **kwds)
+
+
+class DefaultDict(collections.defaultdict, MutableMapping[KT, VT]):
+ __slots__ = ()
+ __extra__ = collections.defaultdict
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is DefaultDict:
+ return collections.defaultdict(*args, **kwds)
+ return _generic_new(collections.defaultdict, cls, *args, **kwds)
+
+
+class Counter(collections.Counter, Dict[T, int]):
+ __slots__ = ()
+ __extra__ = collections.Counter
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is Counter:
+ return collections.Counter(*args, **kwds)
+ return _generic_new(collections.Counter, cls, *args, **kwds)
+
+
+# Determine what base class to use for Generator.
+if hasattr(collections_abc, 'Generator'):
+ # Sufficiently recent versions of 3.5 have a Generator ABC.
+ _G_base = collections_abc.Generator
+else:
+ # Fall back on the exact type.
+ _G_base = types.GeneratorType
+
+
+class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co]):
+ __slots__ = ()
+ __extra__ = _G_base
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is Generator:
+ raise TypeError("Type Generator cannot be instantiated; "
+ "create a subclass instead")
+ return _generic_new(_G_base, cls, *args, **kwds)
+
+
+# Internal type variable used for Type[].
+CT_co = TypeVar('CT_co', covariant=True, bound=type)
+
+
+# This is not a real generic class. Don't use outside annotations.
+class Type(Generic[CT_co]):
+ """A special construct usable 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::
+
+ U = TypeVar('U', bound=User)
+ def new_user(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.
+ """
+ __slots__ = ()
+ __extra__ = type
+
+
+def NamedTuple(typename, fields):
+ """Typed version of namedtuple.
+
+ Usage::
+
+ Employee = typing.NamedTuple('Employee', [('name', str), ('id', int)])
+
+ This is equivalent to::
+
+ Employee = collections.namedtuple('Employee', ['name', 'id'])
+
+ The resulting class has one extra attribute: _field_types,
+ giving a dict mapping field names to types. (The field names
+ are in the _fields attribute, which is part of the namedtuple
+ API.)
+ """
+ fields = [(n, t) for n, t in fields]
+ cls = collections.namedtuple(typename, [n for n, t in fields])
+ cls._field_types = dict(fields)
+ # Set the module to the caller's module (otherwise it'd be 'typing').
+ try:
+ cls.__module__ = sys._getframe(1).f_globals.get('__name__', '__main__')
+ except (AttributeError, ValueError):
+ pass
+ return cls
+
+
+def NewType(name, tp):
+ """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 function that simply returns its argument. Usage::
+
+ UserId = NewType('UserId', int)
+
+ def name_by_id(user_id):
+ # type: (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
+ """
+
+ def new_type(x):
+ return x
+
+ # Some versions of Python 2 complain because of making all strings unicode
+ new_type.__name__ = str(name)
+ new_type.__supertype__ = tp
+ return new_type
+
+
+# Python-version-specific alias (Python 2: unicode; Python 3: str)
+Text = unicode
+
+
+# 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__ = ()
+
+ @abstractproperty
+ def mode(self):
+ pass
+
+ @abstractproperty
+ def name(self):
+ pass
+
+ @abstractmethod
+ def close(self):
+ pass
+
+ @abstractproperty
+ def closed(self):
+ pass
+
+ @abstractmethod
+ def fileno(self):
+ pass
+
+ @abstractmethod
+ def flush(self):
+ pass
+
+ @abstractmethod
+ def isatty(self):
+ pass
+
+ @abstractmethod
+ def read(self, n=-1):
+ pass
+
+ @abstractmethod
+ def readable(self):
+ pass
+
+ @abstractmethod
+ def readline(self, limit=-1):
+ pass
+
+ @abstractmethod
+ def readlines(self, hint=-1):
+ pass
+
+ @abstractmethod
+ def seek(self, offset, whence=0):
+ pass
+
+ @abstractmethod
+ def seekable(self):
+ pass
+
+ @abstractmethod
+ def tell(self):
+ pass
+
+ @abstractmethod
+ def truncate(self, size=None):
+ pass
+
+ @abstractmethod
+ def writable(self):
+ pass
+
+ @abstractmethod
+ def write(self, s):
+ pass
+
+ @abstractmethod
+ def writelines(self, lines):
+ pass
+
+ @abstractmethod
+ def __enter__(self):
+ pass
+
+ @abstractmethod
+ def __exit__(self, type, value, traceback):
+ pass
+
+
+class BinaryIO(IO[bytes]):
+ """Typed version of the return of open() in binary mode."""
+
+ __slots__ = ()
+
+ @abstractmethod
+ def write(self, s):
+ pass
+
+ @abstractmethod
+ def __enter__(self):
+ pass
+
+
+class TextIO(IO[unicode]):
+ """Typed version of the return of open() in text mode."""
+
+ __slots__ = ()
+
+ @abstractproperty
+ def buffer(self):
+ pass
+
+ @abstractproperty
+ def encoding(self):
+ pass
+
+ @abstractproperty
+ def errors(self):
+ pass
+
+ @abstractproperty
+ def line_buffering(self):
+ pass
+
+ @abstractproperty
+ def newlines(self):
+ pass
+
+ @abstractmethod
+ def __enter__(self):
+ pass
+
+
+class io(object):
+ """Wrapper namespace for IO generic classes."""
+
+ __all__ = ['IO', 'TextIO', 'BinaryIO']
+ IO = IO
+ TextIO = TextIO
+ BinaryIO = BinaryIO
+
+
+io.__name__ = __name__ + b'.io'
+sys.modules[io.__name__] = io
+
+
+Pattern = _TypeAlias('Pattern', AnyStr, type(stdlib_re.compile('')),
+ lambda p: p.pattern)
+Match = _TypeAlias('Match', AnyStr, type(stdlib_re.match('', '')),
+ lambda m: m.re.pattern)
+
+
+class re(object):
+ """Wrapper namespace for re type aliases."""
+
+ __all__ = ['Pattern', 'Match']
+ Pattern = Pattern
+ Match = Match
+
+
+re.__name__ = __name__ + b'.re'
+sys.modules[re.__name__] = re