-- GENERATED by C->Haskell Compiler, version 0.28.7 Switcheroo, 25 November 2017 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "lib/CPython/Types/Module.chs" #-}
{-# LANGUAGE ForeignFunctionInterface #-}

-- Copyright (C) 2009 John Millikin <jmillikin@gmail.com>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--

module CPython.Types.Module
  ( Module
  , moduleType
  , new
  , getDictionary
  , getName
  , getFilename
  , addObject
  , addIntegerConstant
  , addTextConstant
  , importModule
  , reload
  ) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Ptr as C2HSImp
import qualified System.IO.Unsafe as C2HSImp





import           Prelude hiding (toInteger)
import           Data.Text (Text)

import           CPython.Internal hiding (new)
import           CPython.Types.Integer (toInteger)
import           CPython.Types.Unicode (toUnicode)

newtype Module = Module (ForeignPtr Module)

instance Object Module where
  toObject :: Module -> SomeObject
toObject (Module x :: ForeignPtr Module
x) = ForeignPtr Module -> SomeObject
forall a. Object a => ForeignPtr a -> SomeObject
SomeObject ForeignPtr Module
x
  fromForeignPtr :: ForeignPtr Module -> Module
fromForeignPtr = ForeignPtr Module -> Module
Module

instance Concrete Module where
  concreteType :: Module -> Type
concreteType _ = Type
moduleType

moduleType :: (Type)
moduleType :: Type
moduleType =
  IO Type -> Type
forall a. IO a -> a
C2HSImp.unsafePerformIO (IO Type -> Type) -> IO Type -> Type
forall a b. (a -> b) -> a -> b
$
  IO (Ptr ())
moduleType'_ IO (Ptr ()) -> (Ptr () -> IO Type) -> IO Type
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res :: Ptr ()
res ->
  Ptr () -> IO Type
forall obj a. Object obj => Ptr a -> IO obj
peekStaticObject Ptr ()
res IO Type -> (Type -> IO Type) -> IO Type
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res' :: Type
res' ->
  Type -> IO Type
forall (m :: * -> *) a. Monad m => a -> m a
return (Type
res')

{-# LINE 52 "lib/CPython/Types/Module.chs" #-}


-- | Return a new module object with the @__name__@ attribute set. Only the
-- module&#x2019;s @__doc__@ and @__name__@ attributes are filled in; the
-- caller is responsible for providing a @__file__@ attribute.
new :: (Text) -> IO ((Module))
new a1 =
  withText a1 $ \a1' -> 
  new'_ a1' >>= \res ->
  stealObject res >>= \res' ->
  return (res')

{-# LINE 59 "lib/CPython/Types/Module.chs" #-}


-- | Return the dictionary object that implements a module&#x2019;s namespace;
-- this object is the same as the @__dict__@ attribute of the module. This
-- computation never fails. It is recommended extensions use other
-- computations rather than directly manipulate a module&#x2019;s @__dict__@.
getDictionary :: (Module) -> IO ((Dictionary))
getDictionary :: Module -> IO Dictionary
getDictionary a1 :: Module
a1 =
  Module -> (Ptr () -> IO Dictionary) -> IO Dictionary
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject Module
a1 ((Ptr () -> IO Dictionary) -> IO Dictionary)
-> (Ptr () -> IO Dictionary) -> IO Dictionary
forall a b. (a -> b) -> a -> b
$ \a1' :: Ptr ()
a1' -> 
  Ptr () -> IO (Ptr ())
getDictionary'_ Ptr ()
a1' IO (Ptr ()) -> (Ptr () -> IO Dictionary) -> IO Dictionary
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res :: Ptr ()
res ->
  Ptr () -> IO Dictionary
forall obj a. Object obj => Ptr a -> IO obj
peekObject Ptr ()
res IO Dictionary -> (Dictionary -> IO Dictionary) -> IO Dictionary
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res' :: Dictionary
res' ->
  Dictionary -> IO Dictionary
forall (m :: * -> *) a. Monad m => a -> m a
return (Dictionary
res')

{-# LINE 67 "lib/CPython/Types/Module.chs" #-}


-- | Returns a module&#x2019;s @__name__@ value. If the module does not
-- provide one, or if it is not a string, throws @SystemError@.
getName :: Module -> IO Text
getName py =
  withObject py $ \py' -> do
  raw <- pyModuleGetName py'
  exceptionIf $ raw == nullPtr
  peekText raw

-- | Returns the name of the file from which a module was loaded using the
-- module&#x2019;s @__file__@ attribute. If this is not defined, or if it is
-- not a string, throws @SystemError@.
getFilename :: Module -> IO Text
getFilename :: Module -> IO Text
getFilename py :: Module
py =
  Module -> (Ptr () -> IO Text) -> IO Text
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject Module
py ((Ptr () -> IO Text) -> IO Text) -> (Ptr () -> IO Text) -> IO Text
forall a b. (a -> b) -> a -> b
$ \py' :: Ptr ()
py' -> do
  Ptr CChar
raw <- Ptr () -> IO (Ptr CChar)
pyModuleGetFilename Ptr ()
py'
  Bool -> IO ()
exceptionIf (Bool -> IO ()) -> Bool -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr CChar
raw Ptr CChar -> Ptr CChar -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CChar
forall a. Ptr a
nullPtr
  Ptr CChar -> IO Text
peekText Ptr CChar
raw

-- | Add an object to a module with the given name. This is a convenience
-- computation which can be used from the module&#x2019;s initialization
-- computation.
addObject :: Object value => Module -> Text -> value -> IO ()
addObject :: Module -> Text -> value -> IO ()
addObject py :: Module
py name :: Text
name val :: value
val =
  Module -> (Ptr () -> IO ()) -> IO ()
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject Module
py ((Ptr () -> IO ()) -> IO ()) -> (Ptr () -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \py' :: Ptr ()
py' ->
  Text -> (Ptr CChar -> IO ()) -> IO ()
forall a. Text -> (Ptr CChar -> IO a) -> IO a
withText Text
name ((Ptr CChar -> IO ()) -> IO ()) -> (Ptr CChar -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \name' :: Ptr CChar
name' ->
  value -> (Ptr () -> IO ()) -> IO ()
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject value
val ((Ptr () -> IO ()) -> IO ()) -> (Ptr () -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \val' :: Ptr ()
val' ->
  Ptr () -> IO ()
forall a. Ptr a -> IO ()
incref Ptr ()
val' IO () -> IO CInt -> IO CInt
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  Ptr () -> Ptr CChar -> Ptr () -> IO CInt
pyModuleAddObject Ptr ()
py' Ptr CChar
name' Ptr ()
val'
  IO CInt -> (CInt -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CInt -> IO ()
checkStatusCode

-- | Add an integer constant to a module. This convenience computation can be
-- used from the module&#x2019;s initialization computation.
addIntegerConstant :: Module -> Text -> Integer -> IO ()
addIntegerConstant :: Module -> Text -> Integer -> IO ()
addIntegerConstant m :: Module
m name :: Text
name value :: Integer
value = Integer -> IO Integer
toInteger Integer
value IO Integer -> (Integer -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Module -> Text -> Integer -> IO ()
forall value. Object value => Module -> Text -> value -> IO ()
addObject Module
m Text
name

-- | Add a string constant to a module. This convenience computation can be
-- used from the module&#x2019;s initialization computation.
addTextConstant :: Module -> Text -> Text -> IO ()
addTextConstant :: Module -> Text -> Text -> IO ()
addTextConstant m :: Module
m name :: Text
name value :: Text
value = Text -> IO Unicode
toUnicode Text
value IO Unicode -> (Unicode -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Module -> Text -> Unicode -> IO ()
forall value. Object value => Module -> Text -> value -> IO ()
addObject Module
m Text
name

-- | This is a higher-level interface that calls the current &#x201c;import
-- hook&#x201d; (with an explicit level of @0@, meaning absolute import). It
-- invokes the @__import__()@ computation from the @__builtins__@ of the
-- current globals. This means that the import is done using whatever import
-- hooks are installed in the current environment.
--
-- This computation always uses absolute imports.
importModule :: Text -> IO Module
importModule :: Text -> IO Module
importModule name :: Text
name = do
  Unicode
pyName <- Text -> IO Unicode
toUnicode Text
name
  Unicode -> (Ptr () -> IO Module) -> IO Module
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject Unicode
pyName ((Ptr () -> IO Module) -> IO Module)
-> (Ptr () -> IO Module) -> IO Module
forall a b. (a -> b) -> a -> b
$ \namePtr :: Ptr ()
namePtr ->
    Ptr () -> IO (Ptr ())
pyImportImport Ptr ()
namePtr
    IO (Ptr ()) -> (Ptr () -> IO Module) -> IO Module
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr () -> IO Module
forall obj a. Object obj => Ptr a -> IO obj
stealObject

-- | Reload a module. If an error occurs, an exception is thrown and the old
-- module still exists.
reload :: (Module) -> IO ((Module))
reload :: Module -> IO Module
reload a1 :: Module
a1 =
  Module -> (Ptr () -> IO Module) -> IO Module
forall obj a b. Object obj => obj -> (Ptr a -> IO b) -> IO b
withObject Module
a1 ((Ptr () -> IO Module) -> IO Module)
-> (Ptr () -> IO Module) -> IO Module
forall a b. (a -> b) -> a -> b
$ \a1' :: Ptr ()
a1' -> 
  Ptr () -> IO (Ptr ())
reload'_ Ptr ()
a1' IO (Ptr ()) -> (Ptr () -> IO Module) -> IO Module
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res :: Ptr ()
res ->
  Ptr () -> IO Module
forall obj a. Object obj => Ptr a -> IO obj
stealObject Ptr ()
res IO Module -> (Module -> IO Module) -> IO Module
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \res' :: Module
res' ->
  Module -> IO Module
forall (m :: * -> *) a. Monad m => a -> m a
return (Module
res')

{-# LINE 128 "lib/CPython/Types/Module.chs" #-}


foreign import ccall unsafe "CPython/Types/Module.chs.h hscpython_PyModule_Type"
  moduleType'_ :: (IO (C2HSImp.Ptr ()))

foreign import ccall safe "CPython/Types/Module.chs.h PyModule_New"
  new'_ :: ((C2HSImp.Ptr C2HSImp.CChar) -> (IO (C2HSImp.Ptr ())))

foreign import ccall safe "CPython/Types/Module.chs.h PyModule_GetDict"
  getDictionary'_ :: ((C2HSImp.Ptr ()) -> (IO (C2HSImp.Ptr ())))

foreign import ccall safe "CPython/Types/Module.chs.h PyModule_GetName"
  pyModuleGetName :: ((C2HSImp.Ptr ()) -> (IO (C2HSImp.Ptr C2HSImp.CChar)))

foreign import ccall safe "CPython/Types/Module.chs.h PyModule_GetFilename"
  pyModuleGetFilename :: ((C2HSImp.Ptr ()) -> (IO (C2HSImp.Ptr C2HSImp.CChar)))

foreign import ccall safe "CPython/Types/Module.chs.h PyModule_AddObject"
  pyModuleAddObject :: ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr C2HSImp.CChar) -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))))

foreign import ccall safe "CPython/Types/Module.chs.h PyImport_Import"
  pyImportImport :: ((C2HSImp.Ptr ()) -> (IO (C2HSImp.Ptr ())))

foreign import ccall safe "CPython/Types/Module.chs.h PyImport_ReloadModule"
  reload'_ :: ((C2HSImp.Ptr ()) -> (IO (C2HSImp.Ptr ())))