• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

trolldbois / ctypeslib / 4773970805

pending completion
4773970805

push

github

Loic Jaquemet
more linting

1274 of 1490 relevant lines covered (85.5%)

51.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

46.15
/ctypeslib/__init__.py
1
# -*- coding: utf-8 -*-
2
"""
3
ctypeslib2 package
4

5
ctypeslib2 helps generate Python-friendly interfaces to C libraries, such as automatically generating Python classes
6
that represent C data structures, simplifying the process of wrapping C functions with Python functions,
7
and providing tools for handling errors and exceptions that may occur when calling C functions.
8

9
"""
10

11
import ctypes
48✔
12
import os
48✔
13
import re
48✔
14
import sys
48✔
15
import warnings
48✔
16
from ctypes.util import find_library
48✔
17

18
from pkg_resources import get_distribution, DistributionNotFound
48✔
19

20
try:
48✔
21
    __dist = get_distribution('ctypeslib2')
48✔
22
    # Normalize case for Windows systems
23
    # if you are in a virtualenv, ./local/* are aliases to ./*
24
    __dist_loc = os.path.normcase(os.path.realpath(__dist.location))
48✔
25
    __here = os.path.normcase(os.path.realpath(__file__))
48✔
26
    if not __here.startswith(os.path.join(__dist_loc, 'ctypeslib')):
48✔
27
        # not installed, but there is another version that *is*
28
        raise DistributionNotFound
48✔
29
except DistributionNotFound:
48✔
30
    __version__ = 'Please install the latest version of this python package'
48✔
31
else:
32
    __version__ = __dist.version
33

34

35
def __find_clang_libraries():
48✔
36
    """ configure python-clang to use the local clang library """
37
    _libs = []
12✔
38
    # try for a file with a version match with the clang python package version
39
    version_major = __clang_py_version__.split('.')[0]
12✔
40
    # try default system name
41
    v_list = [f"clang-{__clang_py_version__}", f"clang-{version_major}", "libclang", "clang"]
12✔
42
    # tries clang version 16 to 7
43
    v_list += [f"clang-{_}" for _ in range(16, 6, -1)]
12✔
44
    # with the dotted form of clang 6.0 to 4.0
45
    v_list += [f"clang-{_:.1f}" for _ in range(6, 3, -1)]
12✔
46
    # clang 3 supported versions
47
    v_list += ["clang-3.9", "clang-3.8", "clang-3.7"]
12✔
48
    for _version in v_list:
12✔
49
        _filename = find_library(_version)
12✔
50
        if _filename:
12✔
51
            _libs.append(_filename)
12✔
52
    # On darwin, also consider either Xcode or CommandLineTools.
53
    if os.name == "posix" and sys.platform == "darwin":
12✔
54
        for _ in ['/Library/Developer/CommandLineTools/usr/lib/libclang.dylib',
55
                  '/Applications/Xcode.app/Contents/Frameworks/libclang.dylib',
56
                  ]:
57
            if os.path.exists(_):
58
                _libs.insert(0, _)
59
    return _libs
12✔
60

61

62
def clang_version():
12✔
63
    """Pull the clang C library version from the API"""
64
    # avoid loading the cindex API (cindex.conf.lib) to avoid version conflicts
65
    get_version = cindex.conf.get_cindex_library().clang_getClangVersion
48✔
66
    get_version.restype = ctypes.c_char_p
48✔
67
    version_string = get_version()
48✔
68
    version = 'Unknown'
48✔
69
    if version_string and len(version_string) > 0:
48✔
70
        version_groups = re.match(br'.+version ((\d+\.)?(\d+\.)?(\*|\d+))', version_string)
48✔
71
        if version_groups and len(version_groups.groups()) > 0:
48✔
72
            version = version_groups.group(1).decode()
48✔
73
    return version
48✔
74

75

76
def clang_py_version():
48✔
77
    """Return the python clang package version"""
78
    return __clang_py_version__
12✔
79

80

81
def __configure_clang_cindex():
12✔
82
    """
83
    First we attempt to configure clang with the library path set in environment variable
84
    Second we attempt to configure clang with a clang library version similar to the clang python package version
85
    Third we attempt to configure clang with any clang library we can find
86
    """
87
    # first, use environment variables set by user
88
    __libs = []
60✔
89
    __lib_path = os.environ.get('CLANG_LIBRARY_PATH')
60✔
90
    if __lib_path is not None:
60✔
91
        if not os.path.exists(__lib_path):
×
92
            warnings.warn("Filepath in CLANG_LIBRARY_PATH does not exist", RuntimeWarning)
×
93
        else:
×
94
            __libs.append(__lib_path)
×
95
    __libs.extend(__find_clang_libraries())
60✔
96
    for __library_path in __libs:
60✔
97
        try:
60✔
98
            if os.path.isdir(__library_path):
60✔
99
                cindex.Config.set_library_path(__library_path)
×
100
            else:
×
101
                cindex.Config.set_library_file(__library_path)
60✔
102
            # force-check that clang is configured properly
103
            clang_version()
60✔
104
        except cindex.LibclangError:
×
105
            warnings.warn(f"Could not configure clang with library_path={__library_path}", RuntimeWarning)
×
106
            continue
×
107
        return __library_path
60✔
108
    return None
×
109

110

111
# check which clang python module is available
112
# check which clang library is available
113
try:
60✔
114
    from clang import cindex
60✔
115
    from ctypeslib.codegen.codegenerator import translate, translate_files
60✔
116

117
    __clang_py_version__ = get_distribution('clang').version
60✔
118
    __clang_library_filename = __configure_clang_cindex()
60✔
119
    if __clang_library_filename is None:
60✔
120
        warnings.warn("Could not find the clang library. please install llvm libclang", RuntimeWarning)
×
121
        # do not fail - maybe the user has a plan
122
    else:
×
123
        # set a warning if major versions differs.
124
        if clang_version().split('.')[0] != clang_py_version().split('.')[0]:
60✔
125
            clang_major = clang_version().split('.')[0]
×
126
            warnings.warn(f"Version of python-clang ({clang_py_version()}) and "
×
127
                          f"clang C library ({clang_version()}) are different. "
×
128
                          f"Did you try pip install clang=={clang_major}.*", RuntimeWarning)
×
129
except ImportError as e:
×
130
    __clang_py_version__ = None
×
131
    warnings.warn("Could not find a version of python-clang installed. "
×
132
                  "Please pip install clang==<version>.*", RuntimeWarning)
×
133
    raise e
×
134

135

136
__all__ = ['translate', 'translate_files', 'clang_version', 'clang_py_version']
60✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc