-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pyclass #124
Comments
What's happening is that those methods you were defining are callable wrappers around Julia values, but are not proper Python functions, and only proper Python functions become class methods, everything else are just ordinary class members. The |
Possibly |
Wrapping functions in Person = pyclass("Person", ();
__init__ = pymethod((self) -> (self.state = 0; nothing)),
add = pymethod((self, n) -> (self.state += n)),
print = pymethod((self) -> print(self.state))
)
@pyexec (Person = Person) => """
p1 = Person()
p1.add(4)
p1.print() # prints 4
"""
Yeah, that would make it easier to use I think (could apply the wrapping automatically depending on the type of the arguments). But my main use case still segfaults: ENV["JULIA_PYTHONCALL_EXE"] = "/usr/bin/python3" # I have to include this due to https://github.com/cjdoris/PythonCall.jl/issues/120
using PythonCall
function finit(self)
self.i = 0
nothing # aparently, __init__ functions need to return "None"
end
function fwrite(self, s)
self.i += 1
println(self.i)
end
fflush(self) = print("Done")
SideEffect = pyclass("SideEffect", (),
__init__ = pymethod(finit),
write = pymethod(fwrite),
flush = pymethod(fflush)
)
@pyexec (SideEffect = SideEffect) => """
import picamera
with picamera.PiCamera() as camera:
camera.start_recording(SideEffect(), format='h264')
camera.wait_recording(5)
camera.stop_recording()
""" I realize this might be a bit hard to debug and outside this specific issue, but do you have any idea what might be going on...? The relevant documentation for |
I imagine the following is near impossible to replicate without an RPI + Pi Camera, but here is a leaned down example: @pyexec """
import picamera
class SideEffect(object):
def write(self, s):
print('a')
with picamera.PiCamera() as camera:
camera.start_recording(SideEffect(), format='h264')
camera.wait_recording(5)
camera.stop_recording()
""" while the following, which is nearly identical, segfaults: SideEffect = pyclass("SideEffect", (), write = pymethod((self, s) -> print("a")))
@pyexec (SideEffect = SideEffect) => """
import picamera
with picamera.PiCamera() as camera:
camera.start_recording(SideEffect(), format='h264')
camera.wait_recording(5)
camera.stop_recording()
""" |
I can't really help without a MWE that works on Windows, Mac or Linux I'm afraid. As a quick check, the following does work for me, so something non-trivial is going on: SideEffect = pyclass(....)
@pyexec SideEffect => "SideEffect().write(12)" |
If you want to hack it, you can dynamically add any function as a method to the class. >>> from types import MethodType
>>> class Foo:
... pass
...
>>> f = Foo()
>>> def method(self):
... print("hello world")
...
>>> Foo.method = MethodType(method, Foo)
>>> f.method()
hello world |
I really appreciate the ideas (and I'll see if there is some mechanism to test this on systems that are not an RPI+PiCam), but unfortunately, the following also segfaults: @pyexec """
global SideEffect
class SideEffect(object):
pass
"""
fun = pymethod((self, s) -> println("frame"))
@pyexec (write = fun) => """
from types import MethodType
import picamera
SideEffect.write = MethodType(write, SideEffect)
with picamera.PiCamera() as camera:
camera.start_recording(SideEffect(), format='h264')
camera.wait_recording(5)
camera.stop_recording()
""" Let me know @kdheepak if this implementation wasn't what you meant. |
I'm not particularly familiar with the Python C API but maybe you can try this instead: @pyexec """
global SideEffect
class SideEffect(object):
pass
"""
fun = pymethod((self, s) -> println("frame"))
@pyexec (write = fun) => """
from types import MethodType
import picamera
SideEffect.write = write
with picamera.PiCamera() as camera:
camera.start_recording(SideEffect(), format='h264')
camera.wait_recording(5)
camera.stop_recording()
"""
But my suggestion was for a Python function. I'm not seeing a Does it segfault when you try running the code without using the |
Try the version with |
Yeah, it segfaulted as well.
Segfault too.
Indeed, might a
Nope... |
The one constant is if the class was defined outside Python then it segfaults. |
How about if you add a pure python method to the class using |
Specifically @pyexec """
from types import MethodType
import picamera
class SideEffect(object):
pass
def write(self, s):
print("frame")
SideEffect.write = MethodType(write, SideEffect)
with picamera.PiCamera() as camera:
camera.start_recording(SideEffect(), format='h264')
camera.wait_recording(5)
camera.stop_recording()
""" Works. |
I found https://pypi.org/project/fake-rpi/ and while it does fake |
I meant to define the class from Julia but the method from Python. |
Also can you post the stack trace? |
This defeats the purpose a bit since the whole point is to define the
For sure, I didn't up to now cause it's so sparse: julia> include("tmp3.jl")
signal (11): Segmentation fault
in expression starting at /home/yakir/dance/tmp3.jl:29
Allocations: 9119279 (Pool: 9117777; Big: 1502); GC: 15
Segmentation fault Would me generating one of those |
I hadn't heard of rr before but it looks great, should be very helpful. |
Ooof, building Julia (which is required for running the |
I'll just update that while I don't know why the segfaults occur, I've managed to retrieve frames from the Raspberry Pi Camera in sufficient speeds and dimensions using https://www.raspberrypi.com/documentation/accessories/camera.html#libcamera-vid and thus avoiding Python's Another independent development that might solve this for future users is that Raspbian now comes in 64 bit (see news here https://www.raspberrypi.com/news/raspberry-pi-os-64-bit/). This is huge in and of itself, but it might also completely solve these kind of mysterious sefaults. I might be able to test this (in which case I'll be sure to report back here). |
Ok great, yeah let me know how that goes. I'll leave this ticket open for the small change to pyclass, but won't do anything on the segfaults in light of it being a tier 3 platform. |
I have actually gone and removed My rationale is that in the future I'd like a I have made |
I'm trying to implement a Python class using
PythonCall.pyclass
.The following works as expected:
But any attempt to include methods that accept arguments referencing the instance of the class itself:
fails:
More context
I'm trying to use the
picamera
Python module and process each frame in Julia. The following MWE however segfaults:The text was updated successfully, but these errors were encountered: