@@ -5,22 +5,48 @@ import java.nio.file.{FileSystem, FileSystems, Files}
5
5
import scala .collection .compat .immutable .LazyList
6
6
import scala .util .{Properties , Success , Try }
7
7
8
+ /** A class for extracting the necessary configuration properties for embedding
9
+ * a specific Python interpreter into an appication
10
+ */
8
11
class Python private [python] (
9
12
interpreter : Option [String ] = None ,
10
13
callProcess : Seq [String ] => Try [String ] = Defaults .callProcess,
11
14
getEnv : String => Option [String ] = Defaults .getEnv,
12
15
fs : FileSystem = FileSystems .getDefault,
13
16
isWindows : Option [Boolean ] = None
14
17
) {
18
+
19
+ /** Provides a list of possible locations for the `libpython`
20
+ * corresponding to this Python interpreter
21
+ */
15
22
lazy val nativeLibraryPaths : Try [Seq [String ]] =
16
23
callPython(Python .libPathCmd)
17
24
.map(_.split(" ;" ))
18
25
.map(_.map(_.trim).distinct.filter(_.nonEmpty).toSeq)
19
26
27
+ /** Name of the `libpython` corresponding to this Python interpreter,
28
+ * ''e.g.'' `python3.8`, `python3.7m`
29
+ */
20
30
lazy val nativeLibrary : Try [String ] = ldversion.map(" python" + _)
21
31
32
+ /** Absolute path to the Python interpreter executable
33
+ */
22
34
lazy val executable : Try [String ] = callPython(Python .executableCmd)
23
35
36
+ /** Provides the system properties necessary for setting up
37
+ * [[https://scalapy.dev/ ScalaPy ]] with this Python interpreter
38
+ *
39
+ * @example
40
+ *
41
+ * {{{
42
+ * import me.shadaj.scalapy.py
43
+ *
44
+ * Python("/usr/local/bin/python3").scalapyProperties.get.foreach {
45
+ * case (k, v) => System.setProperty(k, v)
46
+ * }
47
+ * println(py.eval("'Hello from Python!'"))
48
+ * }}}
49
+ */
24
50
def scalapyProperties : Try [Map [String , String ]] = for {
25
51
nativeLibPaths <- nativeLibraryPaths
26
52
library <- nativeLibrary
@@ -46,6 +72,14 @@ class Python private[python] (
46
72
)
47
73
}
48
74
75
+ /** Provides the recommended linker options for embedding this
76
+ * Python interpreter into another application,
77
+ * mostly extracted from the outputs of
78
+ *
79
+ * `pythonX.Y-config --ldflags` for `python` 3.7 and
80
+ *
81
+ * `pythonX.Y-config --ldflags --embed` for `python` 3.8+
82
+ */
49
83
lazy val ldflags : Try [Seq [String ]] = for {
50
84
rawLdflags <- rawLdflags
51
85
nativeLibraryPaths <- nativeLibraryPaths
@@ -108,8 +142,46 @@ class Python private[python] (
108
142
}
109
143
110
144
object Python {
145
+
146
+ /** @param interpreter optional path to a Python interpreter executable,
147
+ * which defaults to `Some("python3")` if not provided
148
+ *
149
+ * @example
150
+ *
151
+ * {{{
152
+ * val python = Python()
153
+ * python.scalapyProperties.get.foreach {
154
+ * case (k, v) => System.setProperty(k, v)
155
+ * }
156
+ *
157
+ * import me.shadaj.scalapy.py
158
+ * println(py.eval("'Hello from Python!'"))
159
+ * }}}
160
+ *
161
+ * @return an instance of [[ai.kien.python.Python ]] which provides
162
+ * the necessary configuration properties for embedding a specific
163
+ * Python interpreter
164
+ */
111
165
def apply (interpreter : Option [String ] = None ): Python = new Python (interpreter)
112
166
167
+ /** @param interpreter path to a Python interpreter executable
168
+ *
169
+ * @example
170
+ *
171
+ * {{{
172
+ * val python = Python("/usr/local/bin/python3")
173
+ * python.scalapyProperties.get.foreach {
174
+ * case (k, v) => System.setProperty(k, v)
175
+ * }
176
+ *
177
+ * import me.shadaj.scalapy.py
178
+ * println(py.eval("'Hello from Python!'"))
179
+ * }}}
180
+ *
181
+ * @return an instance of [[ai.kien.python.Python ]] which provides
182
+ * the necessary configuration properties for embedding a specific
183
+ * Python interpreter
184
+ */
113
185
def apply (interpreter : String ): Python = apply(Some (interpreter))
114
186
115
187
private def executableCmd = " import sys;print(sys.executable)"
0 commit comments