_findlib()   F
last analyzed

Complexity

Conditions 12

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
dl 0
loc 30
rs 2.7855
c 1
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like _findlib() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
"""OpenAL AL and ALC wrapper using ctypes"""
2
import os
3
import sys
4
import ctypes
5
import warnings
6
from ctypes.util import find_library
7
8
__all__ = ["get_dll_file", "version_info"]
9
10
11
def _findlib(libnames, path=None):
12
    """Internal helper function to find the requested DLL(s)."""
13
    platform = sys.platform
14
    if platform in ("win32", "cli"):
15
        suffix = ".dll"
16
    elif platform == "darwin":
17
        suffix = ".dylib"
18
    else:
19
        suffix = ".so"
20
21
    searchfor = libnames
22
    if type(libnames) is dict:
23
        # different library names for the platforms
24
        if platform == "cli" and platform not in libnames:
25
            # if not explicitly specified, use the Win32 libs for IronPython
26
            platform = "win32"
27
        if platform not in libnames:
28
            platform = "DEFAULT"
29
        searchfor = libnames[platform]
30
    results = []
31
    if path:
32
        for libname in searchfor:
33
            dllfile = os.path.join(path, "%s%s" % (libname, suffix))
34
            if os.path.exists(dllfile):
35
                results.append(dllfile)
36
    for libname in searchfor:
37
        dllfile = find_library(libname)
38
        if dllfile:
39
            results.append(dllfile)
40
    return results
41
42
43
class _DLL(object):
44
    """Function wrapper around the different DLL functions. Do not use or
45
    instantiate this one directly from your user code.
46
    """
47
    def __init__(self, libinfo, libnames, path=None):
48
        self._dll = None
49
        foundlibs = _findlib(libnames, path)
50
        if len(foundlibs) == 0:
51
            raise RuntimeError("could not find any library for %s" % libinfo)
52
        for libfile in foundlibs:
53
            try:
54
                self._dll = ctypes.CDLL(libfile)
55
                self._libfile = libfile
56
                break
57
            except Exception as exc:
58
                # Could not load it, silently ignore that issue and move
59
                # to the next one.
60
                warnings.warn(exc, ImportWarning)
61
        if self._dll is None:
62
            raise RuntimeError("could not load any library for %s" % libinfo)
63
        if path is not None and sys.platform in ("win32", "cli") and \
64
            path in self._libfile:
65
            os.environ["PATH"] += ";%s" % path
66
67
    def bind_function(self, funcname, args=None, returns=None):
68
        """Binds the passed argument and return value types to the specified
69
        function."""
70
        func = getattr(self._dll, funcname)
71
        func.argtypes = args
72
        func.restype = returns
73
        return func
74
75
    @property
76
    def libfile(self):
77
        """Gets the filename of the loaded library."""
78
        return self._libfile
79
80
81
dll = _DLL("OpenAL", {"win32": ["OpenAL", "OpenAL32"],
82
                      "darwin": ["OpenAL"],
83
                      "DEFAULT": ["openal", "OpenAL"]},
84
           os.getenv("PYAL_DLL_PATH"))
85
86
87
def get_dll_file():
88
    """Gets the file name of the loaded OpenAL library."""
89
    return dll.libfile
90
91
92
__version__ = "0.2.0"
93
version_info = (0, 2, 0, "")
94