Commit 07f9430d authored by Kirill Smelkov's avatar Kirill Smelkov

golang: Provide way to wrap pyx/nogil-level chan[T] into pychan

This will be needed in Python-wrappers for C-level code which exposes
channels. For example in time package whose implementation will soon be
moved to nogil world fully.
parent 69b80926
......@@ -252,11 +252,12 @@ can be used to multiplex on several channels. For example::
# default case
...
Channels created from Python are represented by `pychan` cdef class. Python
Python channels are represented by `pychan` cdef class. Python
channels that carry non-Python elements (`pychan.dtype != DTYPE_PYOBJECT`) can
be converted to Cython/nogil `chan[T]` via `pychan.chan_*()`.
This provides interaction mechanism in between *nogil* and Python worlds.
For example::
Similarly Cython/nogil `chan[T]` can be wrapped into `pychan` via
`pychan.from_chan_*()`. This provides interaction mechanism
in between *nogil* and Python worlds. For example::
def myfunc(pychan pych):
if pych.dtype != DTYPE_INT:
......@@ -268,6 +269,17 @@ For example::
# send/receive on the channel simultaneously.
...
def mytick(): # -> pychan
cdef chan[int] ch
with nogil:
# create a channel that is connected to some nogil task of the program
ch = ...
# wrap the channel into pychan. Both Python and nogil parts can
# send/receive on the channel simultaneously.
cdef pychan pych = pychan.from_chan_int(ch) # pychan <- chan[int]
return pych
`panic` stops normal execution of current goroutine by throwing a C-level
exception. On Python/C boundaries C-level exceptions have to be converted to
......
......@@ -165,3 +165,14 @@ cdef class pychan:
chan[cbool] chan_bool (pychan pych)
chan[int] chan_int (pychan pych)
chan[double] chan_double (pychan pych)
# pychan.from_chan_X returns pychan wrapping pyx/nogil-level chan[X].
# X can be any C-level type, but not PyObject.
@staticmethod
cdef pychan from_chan_structZ (chan[structZ] ch)
@staticmethod
cdef pychan from_chan_bool (chan[cbool] ch)
@staticmethod
cdef pychan from_chan_int (chan[int] ch)
@staticmethod
cdef pychan from_chan_double (chan[double] ch)
......@@ -335,10 +335,33 @@ cdef class pychan:
pychan_asserttype(pych, DTYPE_DOUBLE)
return _wrapchan[double] (pych._ch)
# pychan <- chan[X]
@staticmethod
cdef pychan from_chan_structZ (chan[structZ] ch):
return pychan_from_raw(ch._rawchan(), DTYPE_STRUCTZ)
@staticmethod
cdef pychan from_chan_bool (chan[cbool] ch):
return pychan_from_raw(ch._rawchan(), DTYPE_BOOL)
@staticmethod
cdef pychan from_chan_int (chan[int] ch):
return pychan_from_raw(ch._rawchan(), DTYPE_INT)
@staticmethod
cdef pychan from_chan_double (chan[double] ch):
return pychan_from_raw(ch._rawchan(), DTYPE_DOUBLE)
cdef void pychan_asserttype(pychan pych, DType dtype) nogil:
if pych.dtype != dtype:
panic("pychan: channel type mismatch")
cdef pychan pychan_from_raw(_chan *_ch, DType dtype):
cdef pychan pych = pychan.__new__(pychan)
pych.dtype = dtype
pych._ch = _ch; _chanxincref(_ch)
return pych
# pydefault represents default case for pyselect.
pydefault = object()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment