shadaj on v0.5.3
shadaj on main
Release v0.5.3 (compare)
shadaj on main
Add changelog item for #297 (compare)
Wondering if anyone can shed some light here. I'm trying to integrate ScalaPy into our environment. We use the DockerPlugin, so I have added Python
to the environment like so:
Cmd("USER", "root")
Cmd("ENV", "PYTHONUNBUFFERED 1")
Cmd("RUN", "apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python")
Cmd("RUN", "python3 -m ensurepip")
Cmd("RUN", "pip3 install --no-cache --upgrade pip setuptools")
I then hit an endpoint that invokes a very simple piece of code:
def sum(acl: AccessControlSession, xs: Seq[Double]): Future[Either[SessionError, SumAnswer]] = {
import me.shadaj.scalapy.py
import me.shadaj.scalapy.py.SeqConverters
val pythonList = py.Dynamic.global.list(xs.toPythonProxy)
val sum = py.Dynamic.global.sum(pythonList).as[Double]
Future.successful(Right(SumAnswer(sum)))
}
And Boom!!! I've killed the container.
| Fatal Python error: create_gil: PyCOND_INIT(gil->cond) failed
| Python runtime state: preinitialized
|
| Current thread 0x00007f43614a7640 (most recent call first):
| <no Python frame>
| #
| # A fatal error has been detected by the Java Runtime Environment:
| #
| # SIGSEGV (0xb) at pc=0x00007f445cfe793b, pid=1, tid=224
| #
| # JRE version: OpenJDK Runtime Environment Temurin-11.0.13+8 (11.0.13+8) (build 11.0.13+8)
| # Java VM: OpenJDK 64-Bit Server VM Temurin-11.0.13+8 (11.0.13+8, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
| # Problematic frame:
| # C [libc.so.6+0x2693b] abort+0x1ed
| #
| # Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P %E" (or dumping to /opt/docker/core.1)
| #
| # An error report file with more information is saved as:
| # /tmp/hs_err_pid1.log
| #
| # If you would like to submit a bug report, please visit:
| # https://github.com/adoptium/adoptium-support/issues
| # The crash happened outside the Java Virtual Machine in native code.
| # See problematic frame for where to report the bug.
| #
Hello! I'm trying to implement a writer and reader for Option[A]
and not sure exactly how. I'll want to check for NoneType
in Python. What I have right now for the writer is:
implicit def optionWriter[A](implicit aWriter: Writer[A], anyWriter: Writer[py.Any]): Writer[Option[A]] = new Writer[Option[A]] {
override def write(opt: Option[A]) = {
opt match {
case Some(a) => aWriter.write(a)
case None => anyWriter.write(py.eval("None"))
}
}
}
The py.eval
part is a bit shady, and not sure if there is a better way. For the reader, not sure how to start checking if a Platform.Pointer
or PyValue
is None.
Hi all, I'm pointing SCALAPY_PYTHON_PROGRAMNAME
to a virtualenv's python3 path (e.g. /Users/foo/.virtualenvs/scalapy/bin/python3
). It's working if I do py.module("numpy")
as I have numpy
installed in the virtualenv. The directory of the actual virtualenv instance is at /Users/foo/python/venvs/scalapy
.
Now, I want to load a Python script (foo.py
) under a sub-directory test
in that virtualenv directory. (The full path is /Users/foo/python/venvs/scalapy/test/foo.py
) but I can't figure out how to load test.foo
successfully. The py.module("test.foo")
call is failing. How do I call py.module to load test.foo
module? Thanks in advance!
__init__.py
file in the test
folder? you'll need that so that Python recognizes it as a module
Not arbitrary objects at the moment. There have been discussions about making this possible through some type of annotation eventually, but it will be some time before it's available.
In the meantime, yeah passing maps is probably the way to go.
exec
function via ScalaPy, as in py.Dynamic.global.exec(...)
Thank you! IntelliJ wasn't showing that possibility. That brought is as far as "Exception in thread "main" me.shadaj.scalapy.py.PythonException: <class 'SystemError'> frame does not exist" for the test program
package org.clulab.pdf2txt.apps
import me.shadaj.scalapy.py
object PythonApp extends App {
{
val script = "3 + 4"
val pythonResult = py.eval(script)
val result = pythonResult.as[Int]
println(result)
}
{
val script = """print("Hello, world!")""" + "\n"
val pythonResult = py.Dynamic.global.exec(script)
println(pythonResult)
}
}
where eval() works, but exec() doesn't. The value for javaOptions seems to be reasonable: [debug] javaOptions: List(-Djna.library.path=/usr/lib/python3.8/config-3.8-x86_64-linux-gnu:/usr/lib, -Dscalapy.python.library=python3.8, -Dscalapy.python.programname=/bin/python3)
exec
working; execManyLines
is a reasonable fallback for now but we generally want to avoid people depending on CPythonInterpreter
val np = py.module("numpy").as[NumPy]
but the compiler does not know about NumPy
. There is a scala-numpy project, but it is not clear which version of that is required or whether to add the library dependency in the main build.sbt file or somewhere under project. So far nothing has worked.
__next__
py.module("modulename")
and then you can construct the class using Python-like syntax module.MyClass(params)
__init__.py
file to instruct Python to treat the local directory as a module; otherwise, imports should follow the regular rules
Hi,
perhaps I'm missing something obvious, but I can't figure out how to combine facades with sequence conversions.
I have a Python function that takes a list
def f(s: list[int]) -> str: ...
Then on the Scala side I have a corresponding facade:
@py.native
class PyService extends py.Object {
def f(s: Seq[Int]): String = py.native
}
Trying to compile it complains about the missing writer.
[error] 116 | def f(s: Seq[Int]): String = py.native
[error] | ^^^^^^^^^
[error] |There is no implicit for me.shadaj.scalapy.readwrite.Writer[scala.collection.immutable.Seq[scala.Int]]
So I looked at convertCopy
from SeqConverters
, to create a Writer
, but it wraps everthing in py.Any
so it's not directly usable.
SeqConverters
I was able to create a writer that seems to work:implicit def seqWriter[T](implicit elemConvertable: ConvertableToSeqElem[T]): Writer[Seq[T]] = new Writer[Seq[T]] {
override def write(seq: Seq[T]): PyValue = PyValue.fromNew(CPythonInterpreter.createListCopy(seq, elemConvertable.convertCopy))
}
Hey! :) first of all congrats for the library -- very interesting work :)
Am I just wondering: It is possible to define python classes in Scala? Consider for instance this example of PyTorch neural network definition:
## Simple network
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 1 input image channel, 6 output channels, 5x5 square convolution
# kernel
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
# an affine operation: y = Wx + b
self.fc1 = nn.Linear(16 * 5 * 5, 120) # 5*5 from image dimension
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# If the size is a square, you can specify with a single number
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = torch.flatten(x, 1) # flatten all dimensions except the batch dimension
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
How can I reach a similar result through scalapy?
type()
(https://www.geeksforgeeks.org/create-classes-dynamically-in-python/)
Reader[Option[T]]
implementation that can check if the value is None
and just recursively use the Reader[T]
if it is not