module Python.Utils (
fromCPyObject,
withPyObject,
maybeWithPyObject,
raisePyException,
checkCInt,
getDefaultGlobals,
pyImport_AddModule,
pyModule_GetDict,
py_incref
)
where
import Python.Types (
CPyObject(..)
, PyObject(..)
, PyException(excType, excValue, excTraceBack, excFormatted, PyException)
)
import Python.ForeignImports (
cNone
, cpyImport_AddModule
, cpyModule_GetDict
, pyErr_Clear
, pyErr_Fetch
, pyErr_NormalizeException
, py_decref
, py_incref
, py_incref
)
import Foreign.C.Types (CInt)
import Foreign.C (withCString)
import Foreign (peek, Ptr, newForeignPtr, nullPtr, alloca, withForeignPtr)
import Control.OldException (throwDyn)
fromCPyObject :: Ptr CPyObject -> IO PyObject
fromCPyObject po =
if po == nullPtr
then raisePyException
else do fp <- newForeignPtr py_decref po
return $ PyObject fp
checkCInt :: CInt -> IO CInt
checkCInt x =
if x == (1)
then raisePyException
else return x
raisePyException :: IO a
raisePyException =
let noneorptr cval = if cval == nullPtr
then do p <- cNone
fromCPyObject p
else fromCPyObject cval
in alloca (\typeptr -> alloca (\valptr -> alloca (\tbptr ->
do pyErr_Fetch typeptr valptr tbptr
pyErr_NormalizeException typeptr valptr tbptr
ctype <- peek typeptr
cval <- peek valptr
ctb <- peek tbptr
otype <- noneorptr ctype
oval <- noneorptr cval
otb <- noneorptr ctb
let exc = PyException {excType = otype, excValue = oval,
excTraceBack = otb,
excFormatted = ""}
pyErr_Clear
throwDyn exc
)))
withPyObject :: PyObject -> (Ptr CPyObject -> IO b) -> IO b
withPyObject (PyObject x) = withForeignPtr x
maybeWithPyObject :: Maybe PyObject -> (Ptr CPyObject -> IO b) -> IO b
maybeWithPyObject Nothing func = func nullPtr
maybeWithPyObject (Just x) y = withPyObject x y
getDefaultGlobals :: IO PyObject
getDefaultGlobals =
do m <- pyImport_AddModule "__main__"
pyModule_GetDict m
pyImport_AddModule :: String -> IO PyObject
pyImport_AddModule x =
withCString x (\cstr ->
do r <- cpyImport_AddModule cstr
py_incref r
fromCPyObject r
)
pyModule_GetDict :: PyObject -> IO PyObject
pyModule_GetDict x =
withPyObject x (\cpyo ->
do r <- cpyModule_GetDict cpyo
py_incref r
fromCPyObject r)