packages feed

ipython-kernel 0.6.0.0 → 0.6.1.0

raw patch · 7 files changed

+58/−177 lines, 7 filesdep −unix

Dependencies removed: unix

Files

ipython-kernel.cabal view
@@ -1,5 +1,5 @@ name:                ipython-kernel-version:             0.6.0.0+version:             0.6.1.0 synopsis:            A library for creating kernels for IPython frontends  description:         ipython-kernel is a library for communicating with frontends for the interactive IPython framework. It is used extensively in IHaskell, the interactive Haskell environment.@@ -27,12 +27,10 @@   exposed-modules: IHaskell.IPython.Kernel                    IHaskell.IPython.Types                    IHaskell.IPython.ZeroMQ-                   IHaskell.IPython.Stdin                    IHaskell.IPython.Message.Writer                    IHaskell.IPython.Message.Parser                    IHaskell.IPython.Message.UUID                    IHaskell.IPython.EasyKernel-  -- other-modules:          other-extensions:    OverloadedStrings   hs-source-dirs:      src   default-language:    Haskell2010@@ -47,12 +45,10 @@                        tar             >=0.4.0.1,                        text            >=0.11,                        transformers    >=0.3,-                       unix            >=2.6,                        uuid            >=1.3,                        zeromq4-haskell >=0.1,                        SHA             >=1.6 - -- Example program executable simple-calc-example   hs-source-dirs: examples@@ -64,6 +60,6 @@                   parsec         >=3.1,                   text           >=0.11,                   transformers   >=0.3-                  +   if !flag(examples)     buildable: False
src/IHaskell/IPython/EasyKernel.hs view
@@ -56,6 +56,7 @@  import           IHaskell.IPython.Kernel import           IHaskell.IPython.Message.UUID as UUID+import           IHaskell.IPython.Types  import           System.Directory (createDirectoryIfMissing, doesDirectoryExist, doesFileExist,                                    getHomeDirectory)@@ -89,7 +90,7 @@          , completion :: T.Text -> T.Text -> Int -> Maybe ([T.Text], T.Text, T.Text)          -- | Return the information or documentation for its argument. The returned tuple consists of the          -- name, the documentation, and the type, respectively.-         , objectInfo :: T.Text -> Maybe (T.Text, T.Text, T.Text)+         , inspectInfo :: T.Text -> Maybe (T.Text, T.Text, T.Text)          -- | Execute a cell. The arguments are the contents of the cell, an IO action that will clear the          -- current intermediate output, and an IO action that will add a new item to the intermediate          -- output. The result consists of the actual result, the status to be sent to IPython, and the@@ -155,7 +156,7 @@  -- | Execute an IPython kernel for a config. Your 'main' action should call this as the last thing -- it does.-easyKernel :: (MonadIO m)+easyKernel :: MonadIO m            => FilePath -- ^ The connection file provided by the IPython frontend            -> KernelConfig m output result -- ^ The kernel configuration specifying how to react to                                            -- messages@@ -220,32 +221,17 @@   return     ExecuteReply       { header = replyHeader-      , pagerOutput = pagerOut+      , pagerOutput = [DisplayData PlainText $ T.pack pagerOut]       , executionCounter = fromIntegral counter       , status = replyStatus       }  replyTo config _ _ req@CompleteRequest{} replyHeader =   -- TODO: FIX-  error "Unimplemented in IPython 3.0"+  error "Completion: Unimplemented for IPython 3.0" -replyTo config _ _ ObjectInfoRequest { objectName = obj } replyHeader =-  return $-    case objectInfo config obj of-      Just (name, docs, ty) -> ObjectInfoReply-        { header = replyHeader-        , objectName = obj-        , objectFound = True-        , objectTypeString = ty-        , objectDocString = docs-        }-      Nothing -> ObjectInfoReply-        { header = replyHeader-        , objectName = obj-        , objectFound = False-        , objectTypeString = ""-        , objectDocString = ""-        }+replyTo _ _ _ InspectRequest{} _ = do+  error $ "Inspection: Unimplemented for IPython 3.0"  replyTo _ _ _ msg _ = do   liftIO $ putStrLn "Unknown message: "
src/IHaskell/IPython/Message/Parser.hs view
@@ -74,7 +74,7 @@ parser KernelInfoRequestMessage = kernelInfoRequestParser parser ExecuteRequestMessage = executeRequestParser parser CompleteRequestMessage = completeRequestParser-parser ObjectInfoRequestMessage = objectInfoRequestParser+parser InspectRequestMessage = inspectRequestParser parser ShutdownRequestMessage = shutdownRequestParser parser InputReplyMessage = inputReplyParser parser CommOpenMessage = commOpenParser@@ -139,11 +139,12 @@   pos <- obj .: "cursor_pos"   return $ CompleteRequest noHeader code pos -objectInfoRequestParser :: LByteString -> Message-objectInfoRequestParser = requestParser $ \obj -> do-  oname <- obj .: "oname"+inspectRequestParser :: LByteString -> Message+inspectRequestParser = requestParser $ \obj -> do+  code <- obj .: "code"+  pos <- obj .: "cursor_pos"   dlevel <- obj .: "detail_level"-  return $ ObjectInfoRequest noHeader oname dlevel+  return $ InspectRequest noHeader code pos dlevel  shutdownRequestParser :: LByteString -> Message shutdownRequestParser = requestParser $ \obj -> do
src/IHaskell/IPython/Message/Writer.hs view
@@ -29,25 +29,30 @@       , "payload" .=         if null pager           then []-          else [object ["source" .= string "page", "text" .= pager]]+          else map mkObj pager       , "user_variables" .= emptyMap       , "user_expressions" .= emptyMap       ]+    where+      mkObj o = object+                  [ "source" .= string "page"+                  , "line" .= Number 0+                  , "data" .= object [displayDataToJson o]+                  ]   toJSON PublishStatus { executionState = executionState } =     object ["execution_state" .= executionState]   toJSON PublishStream { streamType = streamType, streamContent = content } =     object ["data" .= content, "name" .= streamType]   toJSON PublishDisplayData { source = src, displayData = datas } =     object-      ["source" .= src, "metadata" .=-                        object [], "data" .=-                                   object (map displayDataToJson datas)]+      ["source" .= src, "metadata" .= object [], "data" .= object (map displayDataToJson datas)]    toJSON PublishOutput { executionCount = execCount, reprText = reprText } =     object-      ["data" .=-       object ["text/plain" .= reprText], "execution_count" .= execCount, "metadata" .=-                                                                          object []]+      [ "data" .= object ["text/plain" .= reprText]+      , "execution_count" .= execCount+      , "metadata" .= object []+      ]   toJSON PublishInput { executionCount = execCount, inCode = code } =     object ["execution_count" .= execCount, "code" .= code]   toJSON (CompleteReply _ matches start end metadata status) =@@ -60,15 +65,14 @@                       then string "ok"                       else "error"       ]-  toJSON o@ObjectInfoReply{} =+  toJSON i@InspectReply{} =     object-      [ "oname" .=-        objectName o-      , "found" .= objectFound o-      , "ismagic" .= False-      , "isalias" .= False-      , "type_name" .= objectTypeString o-      , "docstring" .= objectDocString o+      [ "status" .= if inspectStatus i+                      then string "ok"+                      else "error"+      , "data" .= object (map displayDataToJson . inspectData $ i)+      , "metadata" .= object []+      , "found" .= inspectStatus i       ]    toJSON ShutdownReply { restartPending = restart } =
− src/IHaskell/IPython/Stdin.hs
@@ -1,113 +0,0 @@-{-# LANGUAGE OverloadedStrings, DoAndIfThenElse #-}---- | This module provides a way in which the Haskell standard input may be forwarded to the IPython--- frontend and thus allows the notebook to use the standard input.------ This relies on the implementation of file handles in GHC, and is generally unsafe and terrible.--- However, it is difficult to find another way to do it, as file handles are generally meant to--- point to streams and files, and not networked communication protocols.------ In order to use this module, it must first be initialized with two things. First of all, in order--- to know how to communicate with the IPython frontend, it must know the kernel profile used for--- communication. For this, use @recordKernelProfile@ once the profile is known. Both this and--- @recordParentHeader@ take a directory name where they can store this data.------ Finally, the module must know what @execute_request@ message is currently being replied to (which--- will request the input). Thus, every time the language kernel receives an @execute_request@--- message, it should inform this module via @recordParentHeader@, so that the module may generate--- messages with an appropriate parent header set. If this is not done, the IPython frontends will--- not recognize the target of the communication.------ Finally, in order to activate this module, @fixStdin@ must be called once. It must be passed the--- same directory name as @recordParentHeader@ and @recordKernelProfile@. Note that if this is being--- used from within the GHC API, @fixStdin@ /must/ be called from within the GHC session not from--- the host code.-module IHaskell.IPython.Stdin (fixStdin, recordParentHeader, recordKernelProfile) where--import           Control.Concurrent-import           Control.Applicative ((<$>))-import           Control.Concurrent.Chan-import           Control.Monad-import           GHC.IO.Handle-import           GHC.IO.Handle.Types-import           System.IO-import           System.Posix.IO-import           System.IO.Unsafe-import qualified Data.Map as Map--import           IHaskell.IPython.Types-import           IHaskell.IPython.ZeroMQ-import           IHaskell.IPython.Message.UUID as UUID--stdinInterface :: MVar ZeroMQStdin-{-# NOINLINE stdinInterface #-}-stdinInterface = unsafePerformIO newEmptyMVar---- | Manipulate standard input so that it is sourced from the IPython frontend. This function is--- build on layers of deep magical hackery, so be careful modifying it.-fixStdin :: String -> IO ()-fixStdin dir = do-  -- Initialize the stdin interface.-  profile <- read <$> readFile (dir ++ "/.kernel-profile")-  interface <- serveStdin profile-  putMVar stdinInterface interface-  void $ forkIO $ stdinOnce dir--stdinOnce :: String -> IO ()-stdinOnce dir = do-  -- Create a pipe using and turn it into handles.-  (readEnd, writeEnd) <- createPipe-  newStdin <- fdToHandle readEnd-  stdinInput <- fdToHandle writeEnd-  hSetBuffering newStdin NoBuffering-  hSetBuffering stdinInput NoBuffering--  -- Store old stdin and swap in new stdin.-  oldStdin <- hDuplicate stdin-  hDuplicateTo newStdin stdin--  loop stdinInput oldStdin newStdin--  where-    loop stdinInput oldStdin newStdin = do-      let FileHandle _ mvar = stdin-      threadDelay $ 150 * 1000-      empty <- isEmptyMVar mvar-      if not empty-        then loop stdinInput oldStdin newStdin-        else do-          line <- getInputLine dir-          hPutStr stdinInput $ line ++ "\n"-          loop stdinInput oldStdin newStdin---- | Get a line of input from the IPython frontend.-getInputLine :: String -> IO String-getInputLine dir = do-  StdinChannel req rep <- readMVar stdinInterface--  -- Send a request for input.-  uuid <- UUID.random-  parentHeader <- read <$> readFile (dir ++ "/.last-req-header")-  let header = MessageHeader-        { username = username parentHeader-        , identifiers = identifiers parentHeader-        , parentHeader = Just parentHeader-        , messageId = uuid-        , sessionId = sessionId parentHeader-        , metadata = Map.fromList []-        , msgType = InputRequestMessage-        }-  let msg = RequestInput header ""-  writeChan req msg--  -- Get the reply.-  InputReply _ value <- readChan rep-  return value--recordParentHeader :: String -> MessageHeader -> IO ()-recordParentHeader dir header =-  writeFile (dir ++ "/.last-req-header") $ show header--recordKernelProfile :: String -> Profile -> IO ()-recordKernelProfile dir profile =-  writeFile (dir ++ "/.kernel-profile") $ show profile
src/IHaskell/IPython/Types.hs view
@@ -38,6 +38,7 @@ import qualified Data.Text as Text import qualified Data.Text.Encoding as Text import           Data.Text (Text)+import qualified Data.String as S import           Data.Serialize import           IHaskell.IPython.Message.UUID import           GHC.Generics (Generic)@@ -175,8 +176,8 @@                  | InputMessage                  | CompleteRequestMessage                  | CompleteReplyMessage-                 | ObjectInfoRequestMessage-                 | ObjectInfoReplyMessage+                 | InspectRequestMessage+                 | InspectReplyMessage                  | ShutdownRequestMessage                  | ShutdownReplyMessage                  | ClearOutputMessage@@ -201,8 +202,8 @@ showMessageType InputMessage = "pyin" showMessageType CompleteRequestMessage = "complete_request" showMessageType CompleteReplyMessage = "complete_reply"-showMessageType ObjectInfoRequestMessage = "object_info_request"-showMessageType ObjectInfoReplyMessage = "object_info_reply"+showMessageType InspectRequestMessage = "inspect_request"+showMessageType InspectReplyMessage = "inspect_reply" showMessageType ShutdownRequestMessage = "shutdown_request" showMessageType ShutdownReplyMessage = "shutdown_reply" showMessageType ClearOutputMessage = "clear_output"@@ -228,8 +229,8 @@       "pyin"                -> return InputMessage       "complete_request"    -> return CompleteRequestMessage       "complete_reply"      -> return CompleteReplyMessage-      "object_info_request" -> return ObjectInfoRequestMessage-      "object_info_reply"   -> return ObjectInfoReplyMessage+      "inspect_request"     -> return InspectRequestMessage+      "inspect_reply"       -> return InspectReplyMessage       "shutdown_request"    -> return ShutdownRequestMessage       "shutdown_reply"      -> return ShutdownReplyMessage       "clear_output"        -> return ClearOutputMessage@@ -272,7 +273,7 @@                ExecuteReply                  { header :: MessageHeader                  , status :: ExecuteReplyStatus          -- ^ The status of the output.-                 , pagerOutput :: String                 -- ^ The help string to show in the pager.+                 , pagerOutput :: [DisplayData]          -- ^ The mimebundles to display in the pager.                  , executionCounter :: Int               -- ^ The execution count, i.e. which output this is.                  }              |@@ -325,20 +326,22 @@                  , completionStatus :: Bool                  }              |-               ObjectInfoRequest+               InspectRequest                  { header :: MessageHeader-                 -- | Name of object being searched for.-                 , objectName :: Text+                 -- | The code context in which introspection is requested+                 , inspectCode :: Text+                 -- | Position of the cursor in unicode characters. json field @cursor_pos@+                 , inspectCursorPos :: Int                  -- | Level of detail desired (defaults to 0). 0 is equivalent to foo?, 1 is equivalent to foo??.                  , detailLevel :: Int                  }              |-               ObjectInfoReply+               InspectReply                  { header :: MessageHeader-                 , objectName :: Text           -- ^ Name of object which was searched for.-                 , objectFound :: Bool          -- ^ Whether the object was found.-                 , objectTypeString :: Text     -- ^ Object type.-                 , objectDocString :: Text+                 -- | whether the request succeeded or failed+                 , inspectStatus :: Bool+                 -- | @inspectData@ can be empty if nothing is found+                 , inspectData :: [DisplayData]                  }              |                ShutdownRequest@@ -421,7 +424,7 @@ replyType KernelInfoRequestMessage = Just KernelInfoReplyMessage replyType ExecuteRequestMessage = Just ExecuteReplyMessage replyType CompleteRequestMessage = Just CompleteReplyMessage-replyType ObjectInfoRequestMessage = Just ObjectInfoReplyMessage+replyType InspectRequestMessage = Just InspectReplyMessage replyType ShutdownRequestMessage = Just ShutdownReplyMessage replyType HistoryRequestMessage = Just HistoryReplyMessage replyType _ = Nothing
src/IHaskell/IPython/ZeroMQ.hs view
@@ -194,7 +194,11 @@ sendMessage :: Sender a => Bool -> ByteString -> Socket a -> Message -> IO () sendMessage _ _ _ SendNothing = return () sendMessage debug hmacKey socket message = do-  when debug $ print message+  when debug $ do+    putStr "Message: "+    print message+    putStr "Sent: "+    print content    -- Send all pieces of the message.   mapM_ sendPiece idents