Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions MissingPy.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: MissingPy
Version: 0.10.6
Version: 0.10.7
License: MIT
Maintainer: Matt Brown <matt@softmechanics.net>
Author: John Goerzen
Expand Down Expand Up @@ -44,7 +44,7 @@ Library
MissingPy.FileArchive.BZip2,
MissingPy.AnyDBM
Other-Modules: Python.ForeignImports
Build-Depends: base == 4.*, MissingH>=1.0.1, anydbm>=1.0.5
Build-Depends: base == 4.*, MissingH>=1.0.1, anydbm>=1.0.5, bytestring
C-Sources: glue/glue.c glue/excglue.c
Extensions: ForeignFunctionInterface, TypeSynonymInstances,
FlexibleInstances
11 changes: 6 additions & 5 deletions Python/Exceptions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,15 @@ import Python.Types (
)
import Data.Dynamic (fromDynamic)
import Python.ForeignImports (pyErr_GivenExceptionMatches)
import Control.OldException (throwDyn, catchDyn, dynExceptions, Exception)
import Control.Exception (throw, catch, fromException, SomeException)
import Prelude hiding ( catch )

{- | Execute the given IO action.

If it raises a 'PyException', then execute the supplied handler and return
its return value. Otherwise, process as normal. -}
catchPy :: IO a -> (PyException -> IO a) -> IO a
catchPy = catchDyn
catchPy = catch

{- | Like 'catchPy', with the order of arguments reversed. -}
handlePy :: (PyException -> IO a) -> IO a -> IO a
Expand All @@ -78,14 +79,14 @@ catchSpecificPy pyo action handlerfunc =
let handler e = do d <- doesExceptionMatch e pyo
if d
then handlerfunc e
else throwDyn e
else throw e
in catchPy action handler

{- | Useful as the first argument to catchJust, tryJust, or handleJust.
Return Nothing if the given exception is not a 'PyException', or
the exception otherwise. -}
pyExceptions :: Exception -> Maybe PyException
pyExceptions exc = dynExceptions exc >>= fromDynamic
pyExceptions :: SomeException -> Maybe PyException
pyExceptions = fromException

{- | When an exception is thrown, it is not immediately formatted.

Expand Down
10 changes: 10 additions & 0 deletions Python/ForeignImports.hsc
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,16 @@ foreign import ccall unsafe "glue.h PyImport_AddModule"
foreign import ccall unsafe "glue.h hspy_none"
cNone :: IO (Ptr CPyObject)

foreign import ccall unsafe "glue.h hspy_true"
cTrue :: IO (Ptr CPyObject)

foreign import ccall unsafe "glue.h hspy_false"
cFalse :: IO (Ptr CPyObject)

{-
foreign import ccall unsafe "glue.h PyBool_FromLong"
pyBool_FromLong :: CLong -> IO (Ptr CPyObject)
-}

foreign import ccall unsafe "glue.h PyEval_InitThreads"
cpy_InitThreads :: IO ()
Expand Down
38 changes: 38 additions & 0 deletions Python/Objects.hs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ import Foreign.C.String (
import Foreign.Ptr (nullPtr)
import Foreign.Storable (peek)
import Foreign.Marshal.Alloc (alloca)
import Foreign (newForeignPtr_)
import Data.ByteString (ByteString, useAsCStringLen, packCStringLen)
import Python.ForeignImports (
cpyList_AsTuple
, cpyObject_Call
Expand Down Expand Up @@ -107,6 +109,10 @@ import Python.ForeignImports (
, pyTuple_Check
, pyTuple_GetItem
, pyTuple_Size
, py_decref
, cNone
, cTrue
, cFalse
)


Expand Down Expand Up @@ -390,6 +396,10 @@ instance (FromPyObject a, FromPyObject b) => FromPyObject [(a, b)] where
in do pyodict <- ((fromPyObject pydict)::IO [(PyObject, PyObject)])
mapM conv pyodict

instance ToPyObject a => ToPyObject (Maybe a) where
toPyObject Nothing = PyObject `fmap` (cNone >>= newForeignPtr_)
toPyObject (Just x) = toPyObject x

--------------------------------------------------
-- Strings

Expand All @@ -415,6 +425,21 @@ instance FromPyObject String where
)
)

-- ByteString to PyObject
instance ToPyObject ByteString where
toPyObject bs = useAsCStringLen bs toPyObject

instance FromPyObject ByteString where
fromPyObject x = withPyObject x (\po ->
alloca (\lenptr ->
alloca (\strptr ->
do pyString_AsStringAndSize po strptr lenptr
len <- peek lenptr
cstr <- peek strptr
packCStringLen (cstr, fromIntegral len)
) ) )


--------------------------------------------------
-- Numbers, Python Ints

Expand Down Expand Up @@ -451,6 +476,19 @@ instance FromPyObject Integer where
return $ read longstr

--------------------------------------------------
-- Numbers, Python Bools

instance ToPyObject Bool where
toPyObject True = cTrue >>= fromCPyObject
toPyObject False = cFalse>>= fromCPyObject

instance FromPyObject Bool where
fromPyObject x = do
l <- fromPyObject x :: IO CLong
if l == 0
then return False
else return True
--------------------------------------------------
-- Numbers, anything else.
{- For these, we attempt to guess whether to handle it as an
int or a long. -}
Expand Down
2 changes: 2 additions & 0 deletions Python/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ module Python.Types (
)
where

import Control.Exception ( Exception )
import Foreign (ForeignPtr)
import Data.Typeable (
TyCon
Expand Down Expand Up @@ -76,6 +77,7 @@ data PyException = PyException {excType :: PyObject, -- ^ Exception type
}
instance Show PyException where
show x = excFormatted x
instance Exception PyException

pyExceptionTc :: TyCon
pyExceptionTc = mkTyCon "MissingPy.Python.Types.PyException"
Expand Down
4 changes: 2 additions & 2 deletions Python/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ import Python.ForeignImports (
import Foreign.C.Types (CInt)
import Foreign.C (withCString)
import Foreign (peek, Ptr, newForeignPtr, nullPtr, alloca, withForeignPtr)
import Control.OldException (throwDyn)
import Control.Exception (throw)

{- | Convert a Ptr 'CPyObject' to a 'PyObject'. -}
fromCPyObject :: Ptr CPyObject -> IO PyObject
Expand Down Expand Up @@ -110,7 +110,7 @@ raisePyException =
excTraceBack = otb,
excFormatted = ""}
pyErr_Clear
throwDyn exc
throw exc
)))
{-
do cpy <- getexc
Expand Down
10 changes: 10 additions & 0 deletions glue/glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ PyObject *hspy_none(void) {
return Py_None;
}

PyObject *hspy_true(void) {
Py_INCREF(Py_True);
return Py_True;
}

PyObject *hspy_false(void) {
Py_INCREF(Py_False);
return Py_False;
}

PyObject *glue_PyMapping_Keys(PyObject *o) {
return PyMapping_Keys(o);
}
Expand Down
2 changes: 2 additions & 0 deletions glue/glue.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ extern PyObject ** hspy_getexc();
extern int hspy_list_check(PyObject *o);
extern int hspy_tuple_check(PyObject *o);
extern PyObject *hspy_none(void);
extern PyObject *hspy_true(void);
extern PyObject *hspy_false(void);

/* These are now macros */
extern PyObject *glue_PyMapping_Keys(PyObject *o);
Expand Down