File: _ctypes.py

package info (click to toggle)
python-anyqt 0.2.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 560 kB
  • sloc: python: 4,087; makefile: 192; sh: 3
file content (87 lines) | stat: -rw-r--r-- 2,390 bytes parent folder | download | duplicates (2)
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
import os
from itertools import chain
from typing import Iterable

import glob
import sys
import sysconfig
import ctypes.util

from AnyQt.QtCore import QLibraryInfo, QT_VERSION


def shlib_ext():
    """
    Return possible platform shared library extension.
    """
    extensions = []
    if sys.platform == "win32":
        extensions += [".dll"]
    elif sys.platform == "darwin":
        extensions += ["", ".dylib"]
    else:
        extensions += [".so"]

    confv = sysconfig.get_config_vars()
    so_ext = confv.get("SO", None)
    if so_ext is not None and so_ext not in extensions:
        extensions += [so_ext]
    return extensions

#
# NOTE: posix dlsym resolves references over linked libs
# `LoadLibrary(QtGui.__file__)` is sufficient. Windows?
# No. Only referenced lib is searched (LoadLibrary and GetProcAddress).
# But LoadLibrary("Qt5Gui.dll") might just do the trick.
#


def find_library(name, path) -> Iterable[str]:
    if sys.platform == "darwin":
        test = [
            name,
            name + ".so",
            name + ".dylib"
            "{name}.framework/{name}".format(name=name),
            "{name}.framework/Versions/Current/{name}".format(name=name),
            "{name}.framework/Versions/*/{name}".format(name=name),
        ]

    elif sys.platform == "win32":
        test = [name, name + ".dll"]
    else:
        test = [
            name,
            name + ".so",
            "lib{name}.so".format(name=name),
            "lib{name}.so.*".format(name=name)
        ]

    for suffix in test:
        yield from glob.iglob(os.path.join(path, suffix))
        # try:
        #     return next(glob.iglob(os.path.join(path, suffix)))
        # except StopIteration:
        #     pass


def find_qtlib(name) -> Iterable[str]:
    qtlibpath = QLibraryInfo.path(QLibraryInfo.LibrariesPath)
    major_version = (QT_VERSION >> 16)
    paths = find_library(name, qtlibpath)
    if name.startswith("Qt"):
        # common case for Qt builds on windows
        name_extra = "Qt{}{}".format(major_version, name[2:])
        extra = find_library(name_extra, qtlibpath)
    else:
        extra = []
    return chain(paths, extra, (name, *((name_extra,) if extra else ())))


def load_qtlib(name):
    for path in find_qtlib(name):
        try:
            return ctypes.cdll.LoadLibrary(path)
        except OSError:
            pass
    return None