@@ -28,9 +28,22 @@ import WinSDK
2828//===----------------------------------------------------------------------===//
2929
3030public 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 .
198218extension PythonLibrary {
199219 private static func enforceNonLoadedPythonLibrary( function: String = #function) {
200220 precondition ( !self . isPythonLibraryLoaded, """
0 commit comments