aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
blob: 6564786b90087a2d6084e8f6b6478afb5615b701 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# 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, absolute_import

"""
loader.py

The loader has to load the signature module completely at startup,
to make sure that the functions are available when needed.
This is meanwhile necessary to make the '__doc__' attribute work correctly.

It does not mean that everything is initialized in advance. Only the modules
are loaded completely after 'import PySide2'.

This version uses both a normal directory, but has also an embedded ZIP file
as a fallback solution. The ZIP file is generated by 'embedding_generator.py'
and embedded into 'signature.cpp' as "embed/signature.inc".

Meanwhile, the ZIP file grew so much, that MSVC had problems
with it's 64k string limit, so we had to break the string up.
See 'zipped_string_sequence' in signature.cpp.
"""

import sys
import os
import traceback
import types

# 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

# 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)

# 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 pyside_type_init(type_key, sig_strings):
    return parser.pyside_type_init(type_key, sig_strings)

# 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)

# name used in signature.cpp
def finish_import(module):
    return importhandler.finish_import(module)


import signature_bootstrap
from shibokensupport import signature
signature.get_signature = signature_bootstrap.get_signature
del signature_bootstrap

def _get_modname(mod):
    return mod.__spec__.name if getattr(mod, "__spec__", None) else mod.__name__

def _set_modname(mod, name):
    if getattr(mod, "__spec__", None):
        mod.__spec__.name = name
    else:
        mod.__name__ = name


def put_into_package(package, module, override=None):
    # take the last component of the module name
    name = (override if override else _get_modname(module)).rsplit(".", 1)[-1]
    # allow access as {package}.typing
    if package:
        setattr(package, name, module)
    # put into sys.modules as a package to allow all import options
    fullname = "{}.{}".format(_get_modname(package), name) if package else name
    _set_modname(module, fullname)
    # publish new dotted name in sys.modules
    sys.modules[fullname] = module


# Debug: used to inspect what each step loads
def list_modules(message):
    ext_modules = {key:value for (key, value) in sys.modules.items()
                              if hasattr(value, "__file__")}
    print("SYS.MODULES", message, len(sys.modules), len(ext_modules))
    for (name, module) in sorted(ext_modules.items()):
        print("  {:23}".format(name), repr(module)[:70])


orig_typing = True
if sys.version_info >= (3,):
    import typing
    import inspect
    inspect.formatannotation = formatannotation
else:
    tp_name = "typing"
    if tp_name not in sys.modules:
        orig_typing = False
        from shibokensupport import typing27 as typing
        sys.modules[tp_name] = typing
        typing.__name__ = tp_name
    else:
        import typing
    import inspect
    namespace = inspect.__dict__
    from shibokensupport 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("_"))

# 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

import shibokensupport
put_into_package(shibokensupport.signature, typing, "typing")
put_into_package(shibokensupport.signature, inspect, "inspect")


def move_into_pyside_package():
    import PySide2
    try:
        import PySide2.support
    except ModuleNotFoundError:
        PySide2.support = types.ModuleType("PySide2.support")
    put_into_package(PySide2.support, signature)
    put_into_package(PySide2.support.signature, mapping)
    put_into_package(PySide2.support.signature, errorhandler)
    put_into_package(PySide2.support.signature, layout)
    put_into_package(PySide2.support.signature, lib)
    put_into_package(PySide2.support.signature, parser)
    put_into_package(PySide2.support.signature, importhandler)
    put_into_package(PySide2.support.signature.lib, enum_sig)

    put_into_package(None if orig_typing else PySide2.support.signature, typing)
    put_into_package(PySide2.support.signature, inspect)

from shibokensupport.signature import mapping
from shibokensupport.signature import errorhandler
from shibokensupport.signature import layout
from shibokensupport.signature import lib
from shibokensupport.signature import parser
from shibokensupport.signature import importhandler
from shibokensupport.signature.lib import enum_sig

if "PySide2" in sys.modules:
    # We publish everything under "PySide2.support.signature", again.
    move_into_pyside_package()

# end of file