aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/PySide6/__init__.py.in
blob: d8439985d0439534cbc9327a8ca39a9f9809fbe0 (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
import os
import sys
from pathlib import Path
from textwrap import dedent

# __all__ is also corrected below.
__all__ = list("Qt" + body for body in
    "@all_module_shortnames@"
    .split(";"))
__version__ = "@FINAL_PACKAGE_VERSION@"
__version_info__ = (@BINDING_API_MAJOR_VERSION@, @BINDING_API_MINOR_VERSION@, @BINDING_API_MICRO_VERSION@, "@BINDING_API_PRE_RELEASE_VERSION_TYPE@", "@BINDING_API_PRE_RELEASE_VERSION@")


def _additional_dll_directories(package_dir):
    # Find shiboken6 relative to the package directory.
    root = Path(package_dir).parent
    # Check for a flat .zip as deployed by cx_free(PYSIDE-1257)
    if root.suffix == '.zip':
        return []
    shiboken6 = root / 'shiboken6'
    if shiboken6.is_dir(): # Standard case, only shiboken6 is needed
        return [shiboken6]
    # The below code is for the build process when generate_pyi.py
    # is executed in the build directory. We need libpyside and Qt in addition.
    shiboken6 = Path(root).parent / 'shiboken6' / 'libshiboken'
    if not shiboken6.is_dir():
        raise ImportError(str(shiboken6) + ' does not exist')
    result = [shiboken6, root / 'libpyside']
    libpysideqml = root / 'libpysideqml'
    if libpysideqml.is_dir():
        result.append(libpysideqml)
    for path in os.environ.get('PATH').split(';'):
        if path:
             if (Path(path) / 'qmake.exe').exists():
                 result.append(path)
                 break
    return result


def _setupQtDirectories():
    # On Windows we need to explicitly import the shiboken6 module so
    # that the libshiboken.dll dependency is loaded by the time a
    # Qt module is imported. Otherwise due to PATH not containing
    # the shiboken6 module path, the Qt module import would fail
    # due to the missing libshiboken dll.
    # In addition, as of Python 3.8, the shiboken package directory
    # must be added to the DLL search paths so that shiboken6.dll
    # is found.
    # We need to do the same on Linux and macOS, because we do not
    # embed rpaths into the PySide6 libraries that would point to
    # the libshiboken library location. Importing the module
    # loads the libraries into the process memory beforehand, and
    # thus takes care of it for us.

    pyside_package_dir = Path(__file__).parent.resolve()

    if sys.platform == 'win32' and sys.version_info[0] == 3 and sys.version_info[1] >= 8:
        for dir in _additional_dll_directories(pyside_package_dir):
            os.add_dll_directory(os.fspath(dir))

    try:
        # PYSIDE-1497: we use the build dir or install dir or site-packages, whatever the path
        #              setting dictates. There is no longer a difference in path structure.
        from shiboken6 import Shiboken
    except Exception:
        paths = ', '.join(sys.path)
        print(f"PySide6/__init__.py: Unable to import Shiboken from {paths}",
              file=sys.stderr)
        raise

    #   Trigger signature initialization.
    try:
        # PYSIDE-829: Avoid non-existent attributes in compiled code (Nuitka).
        # We now use an explicit function instead of touching a signature.
        _init_pyside_extension()
    except (AttributeError, NameError):
        stars = 79 * "*"
        fname = Shiboken.__file__
        print(dedent(f'''\
            {stars}
            PySide6/__init__.py: The `signature` module was not initialized.
            This libshiboken module was loaded from

            "{fname}".

            Please make sure that this is the real Shiboken binary and not just a folder.
            {stars}
            '''), file=sys.stderr)
        raise

    if sys.platform == 'win32':
        # PATH has to contain the package directory, otherwise plugins
        # won't be able to find their required Qt libraries (e.g. the
        # svg image plugin won't find Qt5Svg.dll).
        os.environ['PATH'] = os.fspath(pyside_package_dir) + os.pathsep + os.environ['PATH']

        # On Windows, add the PySide6\openssl folder (created by setup.py's
        # --openssl option) to the PATH so that the SSL DLLs can be found
        # when Qt tries to dynamically load them. Tell Qt to load them and
        # then reset the PATH.
        openssl_dir = pyside_package_dir / 'openssl'
        if openssl_dir.exists():
            path = os.environ['PATH']
            try:
                os.environ['PATH'] = os.fspath(openssl_dir) + os.pathsep + path
                try:
                    from . import QtNetwork
                except ImportError:
                    pass
                else:
                    QtNetwork.QSslSocket.supportsSsl()
            finally:
                os.environ['PATH'] = path


def _find_all_qt_modules():
    # Since the wheel split, the __all__ variable cannot be computed statically,
    # because we don't know all modules in advance.

    # Instead, we look into the file system and quickly build a list of all
    # existing .pyi files, because importing is not desired and also impossible during import.
    # By using the initially created list, we can keep some order intact.
    location = Path(__file__).resolve().parent

    # Note: We should _not_ call this function while still building, but use the existing value!
    in_build = location.parents[1].name == "build"
    if in_build:
        return __all__

    files = os.listdir(location)
    unordered = set(name[:-4] for name in files if name.startswith("Qt") and name.endswith(".pyi"))
    ordered_part = __all__
    result = []
    for name in ordered_part:
        if name in unordered:
            result.append(name)
            unordered.remove(name)
    result.extend(unordered)
    return result


__all__ = _find_all_qt_modules()
_setupQtDirectories()