aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/shibokenmodule
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2018-07-14 15:10:56 +0200
committerChristian Tismer <tismer@stackless.com>2018-11-24 17:25:06 +0000
commitb86d72b9eac320044fde5642e0323be3ef80d62c (patch)
tree55e308075718467e77376587fcef2dc7beb82710 /sources/shiboken2/shibokenmodule
parent57e7c17b2b77740cf0be7620dd628584a369eb82 (diff)
Create hinting stubs for Python IDEs
This implementation formats all signatures in a way that is known as type hinting files (.pyi). Usage ----- The script is to be called by the same Python interpreter that was used to build PySide. It works with Python 2 and 3. On Python 3, it performs a self-test. python3 sources/pyside2/PySide2/support/generate_pyi.py run will generate .pyi files for all compiled PySide modules and places them into site packages to the binaries. An optional outpath can be specified. It is planned to call this script automatically after install. o Local constants are not included, yet. Maybe they never will, unless requested. o The keyword "from" appears 43 times in argument lists. It is fixed in Python, only which does not matter. o When using Python 3.7 or above, it respects Pep 563 and avoids imports which are deferred to runtime. Task-number: PYSIDE-735 Change-Id: I3bcd5d9284b853fe955376bf35c7897e3698da2b Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/shiboken2/shibokenmodule')
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/__init__.py2
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py4
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/layout.py3
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/lib/enum_sig.py33
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/loader.py27
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/mapping.py5
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/parser.py2
7 files changed, 67 insertions, 9 deletions
diff --git a/sources/shiboken2/shibokenmodule/support/signature/__init__.py b/sources/shiboken2/shibokenmodule/support/signature/__init__.py
index f639f1ad..253ba98d 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/__init__.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/__init__.py
@@ -41,4 +41,4 @@ from __future__ import print_function, absolute_import
# Trigger initialization phase 2.
_ = type.__signature__
-from signature_loader import get_signature, inspect
+from signature_loader import get_signature, inspect, typing
diff --git a/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py b/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py
index 0eafe9ca..6b97470e 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py
@@ -113,8 +113,8 @@ CO_NOFREE = 0x0040
# 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) == 'PySide2.support.signature.typing':
- return repr(annotation).replace('PySide2.support.signature.typing.', '')
+ if getattr(annotation, '__module__', None) == 'support.signature.typing':
+ return repr(annotation).replace('support.signature.typing', 'typing')
if isinstance(annotation, type):
if annotation.__module__ in ('__builtin__', base_module):
return annotation.__name__
diff --git a/sources/shiboken2/shibokenmodule/support/signature/layout.py b/sources/shiboken2/shibokenmodule/support/signature/layout.py
index 47f97fc2..cd3a5dc8 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/layout.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/layout.py
@@ -57,6 +57,7 @@ used literally as strings like "signature", "existence", etc.
from textwrap import dedent
from signature_loader import inspect
+from signature_loader.mapping import ellipsis
class SimpleNamespace(object):
@@ -223,7 +224,7 @@ def create_signature(props, key):
if not layout.defaults:
defaults = ()
if layout.ellipsis:
- defaults = ("...",) * len(defaults)
+ defaults = (ellipsis,) * len(defaults)
annotations = props["annotations"].copy()
if not layout.return_annotation and "return" in annotations:
del annotations["return"]
diff --git a/sources/shiboken2/shibokenmodule/support/signature/lib/enum_sig.py b/sources/shiboken2/shibokenmodule/support/signature/lib/enum_sig.py
index 2ec14d62..f79f3266 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/lib/enum_sig.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/lib/enum_sig.py
@@ -39,6 +39,16 @@
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 signature_loader import get_signature, inspect
@@ -51,6 +61,7 @@ class ExactEnumerator(object):
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
@@ -91,7 +102,8 @@ class ExactEnumerator(object):
subclass_name = ".".join((class_name, thing_name))
subclasses.append((subclass_name, thing))
else:
- ret.update(self.function(thing_name, thing))
+ 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
@@ -101,7 +113,7 @@ class ExactEnumerator(object):
signature = getattr(func, '__signature__', None)
if signature is not None:
with self.fmt.function(func_name, signature) as key:
- ret[key] = str(signature)
+ ret[key] = signature
return ret
@@ -133,3 +145,20 @@ class SimplifyingEnumerator(ExactEnumerator):
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/support/signature/loader.py b/sources/shiboken2/shibokenmodule/support/signature/loader.py
index 83493e51..170fb0a2 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/loader.py
@@ -59,7 +59,6 @@ import os
import traceback
import types
from contextlib import contextmanager
-from distutils.sysconfig import get_python_lib
"""
A note on the import problem (solved):
@@ -111,6 +110,30 @@ def ensure_import_support():
sys.path.pop(0)
+# 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__
+
with ensure_import_support():
# We store all needed modules in signature_loader.
# This way, they are always accessible.
@@ -119,6 +142,7 @@ with ensure_import_support():
if sys.version_info >= (3,):
import typing
import inspect
+ inspect.formatannotation = formatannotation
else:
import inspect
namespace = inspect.__dict__
@@ -129,6 +153,7 @@ with ensure_import_support():
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_loader_package(module, loader=signature_loader):
# Note: the "with" statement hides that we are no longer in a
diff --git a/sources/shiboken2/shibokenmodule/support/signature/mapping.py b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
index 724b0c75..bca1ce30 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
@@ -56,7 +56,10 @@ import pkgutil
from signature_loader import typing
-ellipsis = "..."
+class ellipsis(object):
+ def __repr__(self):
+ return "..."
+ellipsis = ellipsis()
Char = typing.Union[str, int] # how do I model the limitation to 1 char?
StringList = typing.List[str]
IntList = typing.List[int]
diff --git a/sources/shiboken2/shibokenmodule/support/signature/parser.py b/sources/shiboken2/shibokenmodule/support/signature/parser.py
index 82cd9aab..4bb1bf23 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/parser.py
@@ -240,7 +240,7 @@ def fixup_multilines(sig_str):
if idx > 0:
continue
# remove duplicates
- multi_lines = list(set(multi_lines))
+ multi_lines = sorted(set(multi_lines))
# renumber or return a single line
nmulti = len(multi_lines)
if nmulti > 1: