packages feed

ipython-kernel 0.8.2.0 → 0.8.3.0

raw patch · 6 files changed

+243/−27 lines, 6 filesdep +unordered-containers

Dependencies added: unordered-containers

Files

ipython-kernel.cabal view
@@ -1,5 +1,5 @@ name:                ipython-kernel-version:             0.8.2.0+version:             0.8.3.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.@@ -46,6 +46,7 @@                        mtl             >=2.1,                        text            >=0.11,                        transformers    >=0.3,+                       unordered-containers >= 0.2.5,                        uuid            >=1.3,                        zeromq4-haskell >=0.1,                        SHA             >=1.6
src/IHaskell/IPython/Message/Parser.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}+{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-name-shadowing #-}  -- | Description : Parsing messages received from IPython --@@ -7,13 +8,17 @@ -- the low-level 0MQ interface. module IHaskell.IPython.Message.Parser (parseMessage) where -import           Data.Aeson ((.:), (.:?), (.!=), decode, Result(..), Object) import           Control.Applicative ((<|>), (<$>), (<*>))-import           Data.Aeson.Types (parse)-import           Data.ByteString+import           Data.Aeson ((.:), (.:?), (.!=), decode, Result(..), Object, Value(..))+import           Data.Aeson.Types (parse, parseEither)+import           Data.ByteString hiding (unpack)+import qualified Data.ByteString.Lazy as Lazy+import           Data.HashMap.Strict as HM import           Data.Map (Map)+import           Data.Maybe (fromMaybe) import           Data.Text (Text)-import qualified Data.ByteString.Lazy as Lazy+import           Data.Text (Text, unpack)+import           Debug.Trace import           IHaskell.IPython.Types  type LByteString = Lazy.ByteString@@ -72,7 +77,13 @@        -> LByteString -> Message -- ^ The parser that converts the body into a message. This message                                  -- should have an undefined header. parser KernelInfoRequestMessage = kernelInfoRequestParser+parser ExecuteInputMessage = executeInputParser parser ExecuteRequestMessage = executeRequestParser+parser ExecuteReplyMessage = executeReplyParser+parser ExecuteErrorMessage = executeErrorParser+parser ExecuteResultMessage = executeResultParser+parser DisplayDataMessage = displayDataParser+parser IsCompleteRequestMessage = isCompleteRequestParser parser CompleteRequestMessage = completeRequestParser parser InspectRequestMessage = inspectRequestParser parser ShutdownRequestMessage = shutdownRequestParser@@ -81,6 +92,11 @@ parser CommDataMessage = commDataParser parser CommCloseMessage = commCloseParser parser HistoryRequestMessage = historyRequestParser+parser StatusMessage = statusMessageParser+parser StreamMessage = streamMessageParser+parser InputMessage = inputMessageParser+parser OutputMessage = outputMessageParser+parser ClearOutputMessage = clearOutputMessageParser parser other = error $ "Unknown message type " ++ show other  -- | Parse a kernel info request. A kernel info request has no auxiliary information, so ignore the@@ -88,6 +104,13 @@ kernelInfoRequestParser :: LByteString -> Message kernelInfoRequestParser _ = KernelInfoRequest { header = noHeader } +-- | Parse an execute_input response. Fields used are:+executeInputParser :: LByteString -> Message+executeInputParser = requestParser $ \obj -> do+  code <- obj .: "code"+  executionCount <- obj .: "execution_count"+  return $ ExecuteInput noHeader code executionCount+ -- | Parse an execute request. Fields used are: --  1. "code": the code to execute. --  2. "silent": whether to execute silently.@@ -114,9 +137,48 @@     , getUserExpressions = []     } -requestParser parser content = parsed+-- | Parse an execute reply+executeReplyParser :: LByteString -> Message+executeReplyParser = requestParser $ \obj -> do+  status <- obj .: "status"+  executionCount <- obj .: "execution_count"+  return $ ExecuteReply noHeader status [] executionCount++-- | Parse an execute reply+executeErrorParser :: LByteString -> Message+executeErrorParser = requestParser $ \obj -> do+  -- executionCount <- obj .: "execution_count"+  traceback <- obj .: "traceback"+  ename <- obj .: "ename"+  evalue <- obj .: "evalue"+  return $ ExecuteError noHeader [] traceback ename evalue++makeDisplayDatas :: Object -> [DisplayData]+makeDisplayDatas dataDict = [DisplayData (read $ unpack mimeType) content | (mimeType, String content) <- HM.toList+                                                                                                            dataDict]++-- | Parse an execute result+executeResultParser :: LByteString -> Message+executeResultParser = requestParser $ \obj -> do+  executionCount <- obj .: "execution_count"+  dataDict :: Object <- obj .: "data"+  let displayDatas = makeDisplayDatas dataDict+  metadataDict <- obj .: "metadata"+  return $ ExecuteResult noHeader displayDatas metadataDict executionCount++-- | Parse a display data message+displayDataParser :: LByteString -> Message+displayDataParser = requestParser $ \obj -> do+  dataDict :: Object <- obj .: "data"+  let displayDatas = makeDisplayDatas dataDict+  maybeSource <- obj .:? "source"+  return $ PublishDisplayData noHeader (fromMaybe "" maybeSource) displayDatas++requestParser parser content =+  case parseEither parser decoded of+    Right parsed -> parsed+    Left err     -> trace ("Parse error: " ++ show err) SendNothing   where-    Success parsed = parse parser decoded     Just decoded = decode content  historyRequestParser :: LByteString -> Message@@ -132,6 +194,48 @@           "tail"   -> HistoryTail           "search" -> HistorySearch           str      -> error $ "Unknown history access type: " ++ str++statusMessageParser :: LByteString -> Message+statusMessageParser = requestParser $ \obj -> do+  execution_state <- obj .: "execution_state"+  return $ PublishStatus noHeader execution_state++streamMessageParser :: LByteString -> Message+streamMessageParser = requestParser $ \obj -> do+  streamType <- obj .: "name"+  streamContent <- obj .: "text"+  return $ PublishStream noHeader streamType streamContent++inputMessageParser :: LByteString -> Message+inputMessageParser = requestParser $ \obj -> do+  code <- obj .: "code"+  executionCount <- obj .: "execution_count"+  return $ Input noHeader code executionCount++getDisplayDatas Nothing = []+getDisplayDatas (Just dataDict) = makeDisplayDatas dataDict++outputMessageParser :: LByteString -> Message+outputMessageParser = requestParser $ \obj -> do+  -- Handle both "data" and "text" keys+  maybeDataDict1 :: Maybe Object <- obj .:? "data"+  let displayDatas1 = getDisplayDatas maybeDataDict1++  maybeDataDict2 :: Maybe Object <- obj .:? "text"+  let displayDatas2 = getDisplayDatas maybeDataDict2++  executionCount <- obj .: "execution_count"+  return $ Output noHeader (displayDatas1 ++ displayDatas2) executionCount++clearOutputMessageParser :: LByteString -> Message+clearOutputMessageParser = requestParser $ \obj -> do+  wait <- obj .: "wait"+  return $ ClearOutput noHeader wait++isCompleteRequestParser :: LByteString -> Message+isCompleteRequestParser = requestParser $ \obj -> do+  code <- obj .: "code"+  return $ IsCompleteRequest noHeader code  completeRequestParser :: LByteString -> Message completeRequestParser = requestParser $ \obj -> do
src/IHaskell/IPython/Message/UUID.hs view
@@ -3,10 +3,10 @@ -- Generate, parse, and pretty print UUIDs for use with IPython. module IHaskell.IPython.Message.UUID (UUID, random, randoms, uuidToString) where +import           Control.Applicative ((<$>), (<*>)) import           Control.Monad (mzero, replicateM)-import           Control.Applicative ((<$>))-import           Data.Text (pack) import           Data.Aeson+import           Data.Text (pack) import           Data.UUID.V4 (nextRandom)  -- | A UUID (universally unique identifier).
src/IHaskell/IPython/Message/Writer.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-name-shadowing -fno-warn-unused-matches #-}  -- | Description : @ToJSON@ for Messages --@@ -6,14 +7,10 @@ module IHaskell.IPython.Message.Writer (ToJSON(..)) where  import           Data.Aeson+import           Data.Aeson.Types (Pair) import           Data.Map (Map)-import           Data.Text (Text, pack) import           Data.Monoid (mempty)--import qualified Data.ByteString.Lazy as L-import qualified Data.ByteString as B-import           Data.Text.Encoding-+import           Data.Text (Text, pack) import           IHaskell.IPython.Types  instance ToJSON LanguageInfo where@@ -34,6 +31,23 @@       , "language_info" .= languageInfo rep       ] +  toJSON ExecuteRequest+    { getCode = code+    , getSilent = silent+    , getStoreHistory = storeHistory+    , getAllowStdin = allowStdin+    , getUserVariables = userVariables+    , getUserExpressions = userExpressions+    } =+    object+      [ "code" .= code+      , "silent" .= silent+      , "store_history" .= storeHistory+      , "allow_stdin" .= allowStdin+      , "user_variables" .= userVariables+      , "user_expressions" .= userExpressions+      ]+   toJSON ExecuteReply { status = status, executionCounter = counter, pagerOutput = pager } =     object       [ "status" .= show status@@ -116,6 +130,18 @@       tuplify (HistoryReplyElement sess linum res) = (sess, linum, case res of                                                                      Left inp         -> toJSON inp                                                                      Right (inp, out) -> toJSON out)++  toJSON req@IsCompleteReply{} =+    object pairs+    where+      pairs =+        case reviewResult req of+          CodeComplete       -> status "complete"+          CodeIncomplete ind -> status "incomplete" ++ indent ind+          CodeInvalid        -> status "invalid"+          CodeUnknown        -> status "unknown"+      status x = ["status" .= pack x]+      indent x = ["indent" .= pack x]    toJSON body = error $ "Do not know how to convert to JSON for message " ++ show body 
src/IHaskell/IPython/Types.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings, DeriveDataTypeable, DeriveGeneric #-}+{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-name-shadowing -fno-warn-unused-matches #-}  -- | This module contains all types used to create an IPython language kernel. module IHaskell.IPython.Types (@@ -17,6 +18,7 @@     Username(..),     Metadata(..),     MessageType(..),+    CodeReview(..),     Width(..),     Height(..),     StreamType(..),@@ -34,19 +36,18 @@     extractPlain,     ) where -import           Data.Aeson import           Control.Applicative ((<$>), (<*>))+import           Data.Aeson import           Data.ByteString (ByteString)+import           Data.List (find)+import           Data.Map (Map)+import           Data.Serialize+import           Data.Text (Text) 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) import           Data.Typeable-import           Data.List (find)-import           Data.Map (Map)+import           GHC.Generics (Generic)+import           IHaskell.IPython.Message.UUID  ------------------ IPython Kernel Profile Types ---------------------- --@@ -169,13 +170,18 @@ -- | The type of a message, corresponding to IPython message types. data MessageType = KernelInfoReplyMessage                  | KernelInfoRequestMessage+                 | ExecuteInputMessage                  | ExecuteReplyMessage+                 | ExecuteErrorMessage                  | ExecuteRequestMessage+                 | ExecuteResultMessage                  | StatusMessage                  | StreamMessage                  | DisplayDataMessage                  | OutputMessage                  | InputMessage+                 | IsCompleteRequestMessage+                 | IsCompleteReplyMessage                  | CompleteRequestMessage                  | CompleteReplyMessage                  | InspectRequestMessage@@ -195,13 +201,18 @@ showMessageType :: MessageType -> String showMessageType KernelInfoReplyMessage = "kernel_info_reply" showMessageType KernelInfoRequestMessage = "kernel_info_request"+showMessageType ExecuteInputMessage = "execute_input" showMessageType ExecuteReplyMessage = "execute_reply"+showMessageType ExecuteErrorMessage = "error" showMessageType ExecuteRequestMessage = "execute_request"+showMessageType ExecuteResultMessage = "execute_result" showMessageType StatusMessage = "status" showMessageType StreamMessage = "stream" showMessageType DisplayDataMessage = "display_data" showMessageType OutputMessage = "pyout" showMessageType InputMessage = "pyin"+showMessageType IsCompleteRequestMessage = "is_complete_request"+showMessageType IsCompleteReplyMessage = "is_complete_reply" showMessageType CompleteRequestMessage = "complete_request" showMessageType CompleteReplyMessage = "complete_reply" showMessageType InspectRequestMessage = "inspect_request"@@ -222,13 +233,18 @@     case s of       "kernel_info_reply"   -> return KernelInfoReplyMessage       "kernel_info_request" -> return KernelInfoRequestMessage+      "execute_input"       -> return ExecuteInputMessage       "execute_reply"       -> return ExecuteReplyMessage+      "error"               -> return ExecuteErrorMessage       "execute_request"     -> return ExecuteRequestMessage+      "execute_result"      -> return ExecuteResultMessage       "status"              -> return StatusMessage       "stream"              -> return StreamMessage       "display_data"        -> return DisplayDataMessage       "pyout"               -> return OutputMessage       "pyin"                -> return InputMessage+      "is_complete_request" -> return IsCompleteRequestMessage+      "is_complete_reply"   -> return IsCompleteReplyMessage       "complete_request"    -> return CompleteRequestMessage       "complete_reply"      -> return CompleteReplyMessage       "inspect_request"     -> return InspectRequestMessage@@ -243,6 +259,7 @@       "comm_close"          -> return CommCloseMessage       "history_request"     -> return HistoryRequestMessage       "history_reply"       -> return HistoryReplyMessage+      "status_message"      -> return StatusMessage        _                     -> fail ("Unknown message type: " ++ show s)   parseJSON _ = fail "Must be a string."@@ -256,6 +273,12 @@          }   deriving (Show, Eq) +data CodeReview = CodeComplete+                | CodeIncomplete String -- ^ String to be used to indent next line of input+                | CodeInvalid+                | CodeUnknown+  deriving Show+ -- | A message used to communicate with the IPython frontend. data Message =              -- | A request from a frontend for information about the kernel.@@ -270,6 +293,13 @@                  }              |              -- | A request from a frontend to execute some code.+               ExecuteInput+                 { header :: MessageHeader+                 , getCode :: Text         -- ^ The code string.+                 , executionCounter :: Int -- ^ The execution count, i.e. which output this is.+                 }+             |+             -- | A request from a frontend to execute some code.                ExecuteRequest                  { header :: MessageHeader                  , getCode :: Text              -- ^ The code string.@@ -288,6 +318,23 @@                  , executionCounter :: Int               -- ^ The execution count, i.e. which output this is.                  }              |+             -- | A reply to an execute request.+               ExecuteResult+                 { header :: MessageHeader+                 , dataResult :: [DisplayData]           -- ^ Key/value pairs (keys are MIME types)+                 , metadataResult :: Map String String   -- ^ Any metadata that describes the data+                 , executionCounter :: Int               -- ^ The execution count, i.e. which output this is.+                 }+             |+             -- | An error reply to an execute request+               ExecuteError+                 { header :: MessageHeader+                 , pagerOutput :: [DisplayData]          -- ^ The mimebundles to display in the pager.+                 , traceback :: [Text]+                 , ename :: Text+                 , evalue :: Text+                 }+             |                PublishStatus                  { header :: MessageHeader                  , executionState :: ExecutionState      -- ^ The execution state of the kernel.@@ -316,7 +363,19 @@                  , inCode :: String                      -- ^ Submitted input code.                  , executionCount :: Int                 -- ^ Which input this is.                  }+             | Input { header :: MessageHeader, getCode :: Text, executionCount :: Int }+             | Output { header :: MessageHeader, getText :: [DisplayData], executionCount :: Int }              |+               IsCompleteRequest+                 { header :: MessageHeader+                 , inputToReview :: String               -- ^ The code entered in the repl.+                 }+             |+               IsCompleteReply+                 { header :: MessageHeader+                 , reviewResult :: CodeReview            -- ^ The result of reviewing the code.+                 }+             |                CompleteRequest                  { header :: MessageHeader                  , getCode :: Text  {- ^@@ -415,6 +474,11 @@                         | Err                         | Abort +instance FromJSON ExecuteReplyStatus where+  parseJSON (String "ok") = return Ok+  parseJSON (String "error") = return Err+  parseJSON (String "abort") = return Abort+ instance Show ExecuteReplyStatus where   show Ok = "ok"   show Err = "error"@@ -426,15 +490,27 @@                     | Starting   deriving Show +instance FromJSON ExecutionState where+  parseJSON (String "busy") = return Busy+  parseJSON (String "idle") = return Idle+  parseJSON (String "starting") = return Starting+ -- | Input and output streams. data StreamType = Stdin                 | Stdout+                | Stderr   deriving Show +instance FromJSON StreamType where+  parseJSON (String "stdin") = return Stdin+  parseJSON (String "stdout") = return Stdout+  parseJSON (String "stderr") = return Stderr+ -- | Get the reply message type for a request message type. replyType :: MessageType -> Maybe MessageType replyType KernelInfoRequestMessage = Just KernelInfoReplyMessage replyType ExecuteRequestMessage = Just ExecuteReplyMessage+replyType IsCompleteRequestMessage = Just IsCompleteReplyMessage replyType CompleteRequestMessage = Just CompleteReplyMessage replyType InspectRequestMessage = Just InspectReplyMessage replyType ShutdownRequestMessage = Just ShutdownReplyMessage@@ -491,3 +567,12 @@   show MimeSvg = "image/svg+xml"   show MimeLatex = "text/latex"   show MimeJavascript = "application/javascript"++instance Read MimeType where+  readsPrec _ "text/plain" = [(PlainText, "")]+  readsPrec _ "text/html" = [(MimeHtml, "")]+  readsPrec _ "image/png" = [(MimePng 50 50, "")]+  readsPrec _ "image/jpg" = [(MimeJpg 50 50, "")]+  readsPrec _ "image/svg+xml" = [(MimeSvg, "")]+  readsPrec _ "text/latex" = [(MimeLatex, "")]+  readsPrec _ "application/javascript" = [(MimeJavascript, "")]
src/IHaskell/IPython/ZeroMQ.hs view
@@ -18,9 +18,9 @@ import           Control.Exception import           Control.Monad import           Data.Aeson-import qualified Data.ByteString.Lazy as LBS import           Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as Char+import qualified Data.ByteString.Lazy as LBS import           Data.Char import           Data.Digest.Pure.SHA as SHA import           Data.Monoid ((<>))@@ -28,9 +28,9 @@ import           System.ZMQ4 as ZMQ4 hiding (stdin) import           Text.Read (readMaybe) -import           IHaskell.IPython.Types import           IHaskell.IPython.Message.Parser-import           IHaskell.IPython.Message.Writer+import           IHaskell.IPython.Message.Writer ()+import           IHaskell.IPython.Types  -- | The channel interface to the ZeroMQ sockets. All communication is done via Messages, which are -- encoded and decoded into a lower level form before being transmitted to IPython. These channels