shadaj on v0.5.3
shadaj on main
Release v0.5.3 (compare)
shadaj on main
Add changelog item for #297 (compare)
__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
CPythonInterpreter.callGlobal
myself as a workaround right now…)