@@ -29,37 +29,30 @@ import WinSDK
29
29
30
30
public struct PythonLibrary {
31
31
private static let shared = PythonLibrary ( )
32
+ private static let pythonInitializeSymbolName = " Py_Initialize "
32
33
private static let pythonLegacySymbolName = " PyString_AsString "
33
34
private static var librarySymbolsLoaded = false
34
35
35
- private let pythonLibraryHandle : UnsafeMutableRawPointer
36
+ private let pythonLibraryHandle : UnsafeMutableRawPointer ?
36
37
private let isLegacyPython : Bool
37
38
38
39
private init ( ) {
39
- guard let pythonLibraryHandle = PythonLibrary . loadPythonLibrary ( ) else {
40
- fatalError ( """
41
- Python library not found. Set the \( Environment . library. key) \
42
- environment variable with the path to a Python library.
43
- """ )
44
- }
45
- self . pythonLibraryHandle = pythonLibraryHandle
40
+ self . pythonLibraryHandle = PythonLibrary . loadPythonLibrary ( )
46
41
47
42
// Check if Python is legacy (Python 2)
48
- isLegacyPython = PythonLibrary . loadSymbol (
49
- pythonLibraryHandle,
50
- PythonLibrary . pythonLegacySymbolName) != nil
43
+ self . isLegacyPython = Self . loadSymbol ( pythonLibraryHandle, PythonLibrary . pythonLegacySymbolName) != nil
51
44
if isLegacyPython {
52
- PythonLibrary . log (
53
- " Loaded legacy Python library, using legacy symbols... " )
45
+ PythonLibrary . log ( " Loaded legacy Python library, using legacy symbols... " )
54
46
}
55
47
PythonLibrary . librarySymbolsLoaded = true
56
48
}
57
49
58
50
static func loadSymbol(
59
- _ libraryHandle: UnsafeMutableRawPointer , _ name: String ) -> UnsafeMutableRawPointer ? {
51
+ _ libraryHandle: UnsafeMutableRawPointer ? , _ name: String ) -> UnsafeMutableRawPointer ? {
60
52
#if canImport(Darwin) || canImport(Glibc)
61
53
return dlsym ( libraryHandle, name)
62
54
#elseif os(Windows)
55
+ guard let libraryHandle = libraryHandle else { return nil }
63
56
let moduleHandle = libraryHandle
64
57
. assumingMemoryBound ( to: HINSTANCE__ . self)
65
58
let moduleSymbol = GetProcAddress ( moduleHandle, name)
@@ -75,10 +68,7 @@ public struct PythonLibrary {
75
68
}
76
69
77
70
log ( " Loading symbol ' \( name) ' from the Python library... " )
78
- return unsafeBitCast (
79
- loadSymbol ( PythonLibrary . shared. pythonLibraryHandle, name) ,
80
- to: type
81
- )
71
+ return unsafeBitCast ( loadSymbol ( PythonLibrary . shared. pythonLibraryHandle, name) , to: type)
82
72
}
83
73
}
84
74
@@ -184,11 +174,17 @@ private extension PythonLibrary {
184
174
return libraryPaths
185
175
} ( )
186
176
177
+ static var isPythonLibraryLoaded : Bool {
178
+ return self . loadSymbol ( nil , self . pythonInitializeSymbolName) != nil
179
+ }
180
+
187
181
static func loadPythonLibrary( ) -> UnsafeMutableRawPointer ? {
188
- if let pythonLibraryPath = Environment . library. value {
189
- return loadPythonLibrary ( at: pythonLibraryPath)
182
+ if self . isPythonLibraryLoaded {
183
+ return nil
184
+ }
185
+ else if let pythonLibraryPath = Environment . library. value {
186
+ return self . loadPythonLibrary ( at: pythonLibraryPath)
190
187
}
191
-
192
188
for majorVersion in supportedMajorVersions {
193
189
for minorVersion in supportedMinorVersions {
194
190
for libraryPath in libraryPaths {
@@ -201,7 +197,10 @@ private extension PythonLibrary {
201
197
}
202
198
}
203
199
}
204
- return nil
200
+ fatalError ( """
201
+ Python library not found. Set the \( Environment . library. key) \
202
+ environment variable with the path to a Python library.
203
+ """ )
205
204
}
206
205
207
206
static func loadPythonLibrary(
@@ -221,7 +220,7 @@ private extension PythonLibrary {
221
220
. joined ( separator: libraryVersionSeparator)
222
221
let path = path. split ( separator: libraryPathVersionCharacter)
223
222
. joined ( separator: libraryVersionString)
224
- return loadPythonLibrary ( at: path)
223
+ return self . loadPythonLibrary ( at: path)
225
224
}
226
225
227
226
static func loadPythonLibrary( at path: String ) -> UnsafeMutableRawPointer ? {
0 commit comments