File: __init__.py.in

package info (click to toggle)
vtk9 9.5.2%2Bdfsg3-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 205,916 kB
  • sloc: cpp: 2,336,565; ansic: 327,116; python: 111,200; yacc: 4,104; java: 3,977; sh: 3,032; xml: 2,771; perl: 2,189; lex: 1,787; makefile: 178; javascript: 165; objc: 153; tcl: 59
file content (156 lines) | stat: -rw-r--r-- 5,588 bytes parent folder | download | duplicates (3)
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
144
145
146
147
148
149
150
151
152
153
154
155
156
r"""
Currently, this package is experimental and may change in the future.
"""
from __future__ import absolute_import
import sys
import importlib.util

from pathlib import Path

from importlib.abc import MetaPathFinder
from importlib.machinery import ExtensionFileLoader

LOADING_STACK = []
LIB_EXTS = [".pyd", ".so"]

def find_lib_path(paths, vtk_module_name):
    for ext in LIB_EXTS:
        for base_path in paths:
            # vtk-wheel => vtkCommonCore.cpython-310-darwin.so
            # paraview  => vtkCommonCore.so
            # Caution: vtkIOXML vs vtkIOXMLParser
            for f in Path(base_path).glob(f"{vtk_module_name}[.-]*"):
                resolved_file = f.resolve()
                if resolved_file.is_file() and ext in resolved_file.suffixes:
                    return str(resolved_file)


class VTKMetaHook(MetaPathFinder):
    """Attach a custom  loaded for vtk native library loading to defer loading of pure python dependencies"""
    def find_spec(self, fullname, path, target=None):
        if fullname.startswith("vtkmodules.vtk"):
            vtk_module_name = fullname.split(".")[1]
            module_path = find_lib_path(path, vtk_module_name)
            if module_path is None:
                return None

            LOADING_STACK.append(fullname)
            return importlib.util.spec_from_file_location(fullname, module_path, loader=VTKLoader(fullname, module_path))

        return None


class VTKLoader(ExtensionFileLoader):
    """Flush any pending dependency load once initialize() phase is done"""
    def exec_module(self, module):
        super().exec_module(module)

        # Process pending dependencies only if the module match the first load request
        if len(LOADING_STACK) and LOADING_STACK[0] == module.__name__:
            LOADING_STACK.clear()
            on_vtk_module_init_completed()



# Register our hook for vtk library loader
sys.meta_path.insert(0, VTKMetaHook())


def _windows_dll_path():
    import os
    _vtk_python_path = '@VTK_PYTHON_SITE_PACKAGES_SUFFIX@/vtkmodules'
    _vtk_dll_path = '@CMAKE_INSTALL_BINDIR@'
    # Compute the DLL path based on the location of the file and traversing up
    # the installation prefix to append the DLL path.
    _vtk_dll_directory = os.path.dirname(os.path.abspath(__file__))
    # Loop while we have components to remove.
    while _vtk_python_path not in ('', '.', '/'):
        # Strip a directory away.
        _vtk_python_path = os.path.dirname(_vtk_python_path)
        _vtk_dll_directory = os.path.dirname(_vtk_dll_directory)
    _vtk_dll_directory = os.path.join(_vtk_dll_directory, _vtk_dll_path)
    if os.path.exists(_vtk_dll_directory):
        # We never remove this path; it is required for VTK to work and there's
        # no scope where we can easily remove the directory again.
        _ = os.add_dll_directory(_vtk_dll_directory)

    # Build tree support.
    try:
        from . import _build_paths

        # Add any paths needed for the build tree.
        for path in _build_paths.paths:
            if os.path.exists(path):
                _ = os.add_dll_directory(path)
    except ImportError:
        # Relocatable install tree (or non-Windows).
        pass


# CPython 3.8 added behaviors which modified the DLL search path on Windows to
# only search "blessed" paths. When importing SMTK, ensure that SMTK's DLLs are
# in this set of "blessed" paths.
if sys.version_info >= (3, 8) and sys.platform == 'win32':
    _windows_dll_path()


#------------------------------------------------------------------------------
# this little trick is for static builds of VTK. In such builds, if
# the user imports this Python package in a non-statically linked Python
# interpreter i.e. not of the of the VTK-python executables, then we import the
# static components importer module.
def _load_vtkmodules_static():
    if 'vtkmodules_vtkCommonCore' not in sys.builtin_module_names:
        import _vtkmodules_static

@_vtkmodules_static_import@


#------------------------------------------------------------------------------
# list the contents
__all__ = [
    @_vtkmodules_all@
]
#------------------------------------------------------------------------------
# get the version
__version__ = "@VTK_MAJOR_VERSION@.@VTK_MINOR_VERSION@.@VTK_BUILD_VERSION@"

#------------------------------------------------------------------------------
# describe import dependencies to properly define Python @override
MODULE_MAPPER = {
    "vtkCommonDataModel": [
        "vtkmodules.util.data_model",
    ],
    "vtkCommonExecutionModel": [
        "vtkmodules.util.execution_model",
    ],
}
LOADED_MODULES = set()
PENDING_LOADED_MODULES = set()

def register_vtk_module_dependencies(vtk_module_name, *import_names):
    """Method to call for registering external override on vtkmodule load"""
    MODULE_MAPPER.setdefault(vtk_module_name, []).extend(import_names)

    # If already loaded let's make sure we import it now
    if vtk_module_name in LOADED_MODULES:
        for import_name in import_names:
            importlib.import_module(import_name)


def on_vtk_module_init(module_name):
    """Automatically called by vtkmodule when they are loaded"""
    if module_name in LOADED_MODULES:
        return

    PENDING_LOADED_MODULES.add(module_name)


def on_vtk_module_init_completed():
    pending = list(PENDING_LOADED_MODULES)
    PENDING_LOADED_MODULES.clear()

    for module_name in pending:
        LOADED_MODULES.add(module_name)
        for import_name in MODULE_MAPPER.get(module_name, []):
            importlib.import_module(import_name)