Skip to content

Commit 6e2c366

Browse files
committed
[PythonKit] Added function to explicitly load the Python load
1 parent b9ca9aa commit 6e2c366

File tree

1 file changed

+34
-14
lines changed

1 file changed

+34
-14
lines changed

PythonKit/PythonLibrary.swift

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,22 @@ import WinSDK
2828
//===----------------------------------------------------------------------===//
2929

3030
public struct PythonLibrary {
31+
public enum Error: Swift.Error, Equatable, CustomStringConvertible {
32+
case pythonLibraryNotFound
33+
34+
public var description: String {
35+
switch self {
36+
case .pythonLibraryNotFound:
37+
return """
38+
Python library not found. Set the \(Environment.library.key) \
39+
environment variable with the path to a Python library.
40+
"""
41+
}
42+
}
43+
}
44+
3145
private static let pythonInitializeSymbolName = "Py_Initialize"
3246
private static let pythonLegacySymbolName = "PyString_AsString"
33-
private static var isPythonLibraryLoaded = false
3447

3548
#if canImport(Darwin)
3649
private static let defaultLibraryHandle = UnsafeMutableRawPointer(bitPattern: -2) // RTLD_DEFAULT
@@ -40,21 +53,28 @@ public struct PythonLibrary {
4053
private static let defaultLibraryHandle: UnsafeMutableRawPointer? = nil // Unsupported
4154
#endif
4255

43-
private static let pythonLibraryHandle: UnsafeMutableRawPointer? = {
44-
let pythonLibraryHandle = Self.loadPythonLibrary()
45-
guard Self.isPythonLibraryLoaded(at: pythonLibraryHandle) else {
46-
fatalError("""
47-
Python library not found. Set the \(Environment.library.key) \
48-
environment variable with the path to a Python library.
49-
""")
56+
private static var isPythonLibraryLoaded = false
57+
private static var _pythonLibraryHandle: UnsafeMutableRawPointer?
58+
private static var pythonLibraryHandle: UnsafeMutableRawPointer? {
59+
try! PythonLibrary.loadLibrary()
60+
return self._pythonLibraryHandle
61+
}
62+
63+
/// Tries to load the Python library, will throw an error if no compatible library is found.
64+
public static func loadLibrary() throws {
65+
guard !self.isPythonLibraryLoaded else { return }
66+
let pythonLibraryHandle = self.loadPythonLibrary()
67+
guard self.isPythonLibraryLoaded(at: pythonLibraryHandle) else {
68+
throw Error.pythonLibraryNotFound
5069
}
51-
Self.isPythonLibraryLoaded = true
52-
return pythonLibraryHandle
53-
}()
70+
self.isPythonLibraryLoaded = true
71+
self._pythonLibraryHandle = pythonLibraryHandle
72+
}
73+
5474
private static let isLegacyPython: Bool = {
55-
let isLegacyPython = Self.loadSymbol(Self.pythonLibraryHandle, Self.pythonLegacySymbolName) != nil
75+
let isLegacyPython = PythonLibrary.loadSymbol(PythonLibrary.pythonLibraryHandle, PythonLibrary.pythonLegacySymbolName) != nil
5676
if isLegacyPython {
57-
Self.log("Loaded legacy Python library, using legacy symbols...")
77+
PythonLibrary.log("Loaded legacy Python library, using legacy symbols...")
5878
}
5979
return isLegacyPython
6080
}()
@@ -194,7 +214,7 @@ extension PythonLibrary {
194214
}
195215
}
196216

197-
// Methods of `PythonLibrary` required to set a given Python version.
217+
// Methods of `PythonLibrary` required to set a given Python version or library path.
198218
extension PythonLibrary {
199219
private static func enforceNonLoadedPythonLibrary(function: String = #function) {
200220
precondition(!self.isPythonLibraryLoaded, """

0 commit comments

Comments
 (0)