Skip to content
Merged
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 src/Python/Inline/Eval.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module Python.Inline.Eval
, Module(..)
) where

import Data.ByteString.Unsafe qualified as BS
import Data.ByteString qualified as BS
import Data.Text (Text)
import Data.Text.Encoding qualified as T
import Language.C.Inline qualified as C
Expand All @@ -48,7 +48,7 @@ bindVar
-> a -- ^ Variable value
-> DictBinder
bindVar name a = DictBinder $ \p_dict -> runProgram $ do
p_key <- progIOBracket $ BS.unsafeUseAsCString (T.encodeUtf8 name)
p_key <- progIOBracket $ BS.useAsCString (T.encodeUtf8 name)
p_obj <- takeOwnership =<< progPy (throwOnNULL =<< basicToPy a)
progPy $ do
r <- Py [CU.block| int {
Expand Down
10 changes: 6 additions & 4 deletions src/Python/Internal/EvalQQ.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ module Python.Internal.EvalQQ
) where

import Control.Monad.IO.Class
import Control.Monad.Catch
import Data.Bits
import Data.Char
import Data.List (intercalate)
Expand All @@ -29,7 +28,6 @@ import Language.Haskell.TH.Syntax qualified as TH
import Python.Internal.Types
import Python.Internal.Program
import Python.Internal.Eval
import Python.Internal.CAPI
import Python.Inline.Literal


Expand All @@ -39,12 +37,16 @@ C.include "<inline-python.h>"
----------------------------------------------------------------

-- | Python's variable name encoded using UTF-8. It exists in order to
-- avoid working with @String@ at runtime.
-- avoid working with @String@ at runtime. Bytestring should be NULL
-- terminated manually
newtype PyVarName = PyVarName BS.ByteString
deriving stock (Show, TH.Lift)

-- | PyVarName is being consumed using 'BS.unsafeUseAsCString' which
-- doesn't NULL terminate underlying buffer and python's C API
-- require it. We have to add terminator ourselves
varName :: String -> PyVarName
varName = PyVarName . T.encodeUtf8 . T.pack
varName nm = PyVarName $ flip BS.snoc 0 $ T.encodeUtf8 (T.pack nm)

unsafeWithPyVarName :: PyVarName -> Program r (Ptr CChar)
unsafeWithPyVarName (PyVarName bs)
Expand Down
10 changes: 9 additions & 1 deletion src/Python/Internal/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ import Data.Coerce
import Data.Int
import Data.Word
import Data.ByteString qualified as BS
import Data.ByteString.Lazy qualified as BL
import Data.ByteString.Builder qualified as BB
import Data.Map.Strict qualified as Map
import Data.Text qualified as T
import Data.Text.Encoding qualified as T
Expand Down Expand Up @@ -171,7 +173,13 @@ newtype Code = Code BS.ByteString
--
-- @since 0.2@
codeFromText :: T.Text -> Code
codeFromText = Code . T.encodeUtf8
-- NOTE: We consume code with BS.useAsCString and python C API expect
-- NULL-terminated string. We have to add terminator manually
codeFromText code
= Code
$ BL.toStrict
$ BB.toLazyByteString
$ T.encodeUtf8Builder code <> BB.word8 0

-- | Create properly encoded @Code@. This function doesn't check
-- syntactic validity.
Expand Down
Loading