Strategies for finding binary dependencies
1# © 2016 Cecil Curry, StackOverflow community
2# SPDX-License-Identifier: CC-BY-SA-4.0
3
4import inspect, os
5from importlib.machinery import ExtensionFileLoader, EXTENSION_SUFFIXES
6from types import ModuleType
7
8def is_c_extension(module: ModuleType) -> bool:
9 '''
10 `True` only if the passed module is a C extension implemented as a
11 dynamically linked shared library specific to the current platform.
12
13 Parameters
14 ----------
15 module : ModuleType
16 Previously imported module object to be tested.
17
18 Returns
19 ----------
20 bool
21 `True` only if this module is a C extension.
22 '''
23 assert isinstance(module, ModuleType), '"{}" not a module.'.format(module)
24
25 # If this module was loaded by a PEP 302-compliant CPython-specific loader
26 # loading only C extensions, this module is a C extension.
27 if isinstance(getattr(module, '__loader__', None), ExtensionFileLoader):
28 return True
29
30 # Else, fallback to filetype matching heuristics.
31 #
32 # Absolute path of the file defining this module.
33 module_filename = inspect.getfile(module)
34
35 # "."-prefixed filetype of this path if any or the empty string otherwise.
36 module_filetype = os.path.splitext(module_filename)[1]
37
38 # This module is only a C extension if this path's filetype is that of a
39 # C extension specific to the current platform.
40 return module_filetype in EXTENSION_SUFFIXES
41