From 616bc00e73f22b965b35880328e2728a4b2ea50a Mon Sep 17 00:00:00 2001 From: Vaibhav Sagar Date: Wed, 20 Feb 2019 22:12:32 -0500 Subject: [PATCH] Attempt to set error status --- .travis.yml | 12 ++++----- .../src/IHaskell/IPython/Message/Parser.hs | 2 +- ipython-kernel/src/IHaskell/IPython/Types.hs | 8 +++++- main/Main.hs | 6 ++--- src/IHaskell/Eval/Evaluate.hs | 26 +++++++++++++------ src/IHaskell/Publish.hs | 3 ++- src/tests/IHaskell/Test/Eval.hs | 2 +- 7 files changed, 38 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0d7a20c1..519f34b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -78,7 +78,7 @@ matrix: # Run the notebook to regenerate the outputs, then compare the new notebook to the old one. stack install --fast stack exec -- ihaskell install --stack - stack exec -- jupyter nbconvert --to=notebook --execute --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb + stack exec -- jupyter nbconvert --to=notebook --execute --allow-errors --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb # Images are rendered differently on different systems, so filter them out in the comparison diff <(egrep -v 'image/png|version|pygments' ~/ihaskell-out.ipynb) <(egrep -v 'image/png|version|pygments' notebooks/IHaskell.ipynb) @@ -158,7 +158,7 @@ matrix: # Run the notebook to regenerate the outputs, then compare the new notebook to the old one. stack install --fast stack exec -- ihaskell install --stack - stack exec -- jupyter nbconvert --to=notebook --execute --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb + stack exec -- jupyter nbconvert --to=notebook --execute --allow-errors --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb # Images are rendered differently on different systems, so filter them out in the comparison diff <(egrep -v 'image/png|version|pygments' ~/ihaskell-out.ipynb) <(egrep -v 'image/png|version|pygments' notebooks/IHaskell.ipynb) @@ -238,7 +238,7 @@ matrix: # Run the notebook to regenerate the outputs, then compare the new notebook to the old one. stack install --fast stack exec -- ihaskell install --stack - stack exec -- jupyter nbconvert --to=notebook --execute --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb + stack exec -- jupyter nbconvert --to=notebook --execute --allow-errors --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb # Images are rendered differently on different systems, so filter them out in the comparison diff <(egrep -v 'image/png|version|pygments' ~/ihaskell-out.ipynb) <(egrep -v 'image/png|version|pygments' notebooks/IHaskell.ipynb) @@ -318,7 +318,7 @@ matrix: # Run the notebook to regenerate the outputs, then compare the new notebook to the old one. stack install --fast stack exec -- ihaskell install --stack - stack exec -- jupyter nbconvert --to=notebook --execute --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb + stack exec -- jupyter nbconvert --to=notebook --execute --allow-errors --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb # Images are rendered differently on different systems, so filter them out in the comparison diff <(egrep -v 'image/png|version|pygments' ~/ihaskell-out.ipynb) <(egrep -v 'image/png|version|pygments' notebooks/IHaskell.ipynb) @@ -352,7 +352,7 @@ matrix: ihaskell-plot ihaskell-static-canvas ])' - - result/bin/ihaskell-nbconvert --to=notebook --execute --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb + - result/bin/ihaskell-nbconvert --to=notebook --execute --allow-errors --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb - diff <(egrep -v 'image/png|version|pygments' ~/ihaskell-out.ipynb) <(egrep -v 'image/png|version|pygments' notebooks/IHaskell.ipynb) - language: nix dist: xenial @@ -383,5 +383,5 @@ matrix: ihaskell-plot ihaskell-static-canvas ])' - - result/bin/ihaskell-nbconvert --to=notebook --execute --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb + - result/bin/ihaskell-nbconvert --to=notebook --execute --allow-errors --stdout notebooks/IHaskell.ipynb > ~/ihaskell-out.ipynb - diff <(egrep -v 'image/png|version|pygments' ~/ihaskell-out.ipynb) <(egrep -v 'image/png|version|pygments' notebooks/IHaskell.ipynb) diff --git a/ipython-kernel/src/IHaskell/IPython/Message/Parser.hs b/ipython-kernel/src/IHaskell/IPython/Message/Parser.hs index 0d40f88b..072b0d7f 100644 --- a/ipython-kernel/src/IHaskell/IPython/Message/Parser.hs +++ b/ipython-kernel/src/IHaskell/IPython/Message/Parser.hs @@ -148,7 +148,7 @@ executeErrorParser = requestParser $ \obj -> do traceback <- obj .: "traceback" ename <- obj .: "ename" evalue <- obj .: "evalue" - return $ ExecuteError noHeader [] traceback ename evalue + return $ ExecuteError noHeader traceback ename evalue makeDisplayDatas :: Object -> [DisplayData] makeDisplayDatas dataDict = [DisplayData (read $ unpack mimeType) content | (mimeType, String content) <- HM.toList diff --git a/ipython-kernel/src/IHaskell/IPython/Types.hs b/ipython-kernel/src/IHaskell/IPython/Types.hs index 8d80df08..d3cad68a 100644 --- a/ipython-kernel/src/IHaskell/IPython/Types.hs +++ b/ipython-kernel/src/IHaskell/IPython/Types.hs @@ -378,7 +378,6 @@ data Message = -- | 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 @@ -561,6 +560,13 @@ instance ToJSON Message where , "data" .= object (map displayDataToJson o) ] ] + toJSON ExecuteError { header = header, traceback = traceback, ename = ename, evalue = evalue } = + object + [ "header" .= show header + , "traceback" .= map toJSON traceback + , "ename" .= ename + , "evalue" .= evalue + ] toJSON PublishStatus { executionState = executionState } = object ["execution_state" .= executionState] toJSON PublishStream { streamType = streamType, streamContent = content } = diff --git a/main/Main.hs b/main/Main.hs index d353c646..9efc89b0 100644 --- a/main/Main.hs +++ b/main/Main.hs @@ -151,7 +151,7 @@ runKernel kOpts profileSrc = do kernelState { supportLibrariesAvailable = hasSupportLibraries } -- Initialize the context by evaluating everything we got from the command line flags. - let noPublish _ = return () + let noPublish _ _ = return () noWidget s _ = return s evaluator line = void $ do -- Create a new state each time. @@ -429,12 +429,12 @@ handleComm send kernelState req replyHeader = do CommDataMessage -> do disp <- run $ comm widget dat communicate pgrOut <- liftIO $ readMVar pOut - liftIO $ publish $ FinalResult disp (if toUsePager then pgrOut else []) [] + liftIO $ publish (FinalResult disp (if toUsePager then pgrOut else []) []) True return kernelState CommCloseMessage -> do disp <- run $ close widget dat pgrOut <- liftIO $ readMVar pOut - liftIO $ publish $ FinalResult disp (if toUsePager then pgrOut else []) [] + liftIO $ publish (FinalResult disp (if toUsePager then pgrOut else []) []) True return kernelState { openComms = Map.delete uuid widgets } _ -> -- Only sensible thing to do. diff --git a/src/IHaskell/Eval/Evaluate.hs b/src/IHaskell/Eval/Evaluate.hs index 7b2a6897..3cdc7548 100644 --- a/src/IHaskell/Eval/Evaluate.hs +++ b/src/IHaskell/Eval/Evaluate.hs @@ -126,7 +126,7 @@ testInterpret v = interpret GHC.Paths.libdir False (const v) -- | Evaluation function for testing. testEvaluate :: String -> IO () testEvaluate str = void $ testInterpret $ - evaluate defaultKernelState str (const $ return ()) (\state _ -> return state) + evaluate defaultKernelState str (\_ _ -> return ()) (\state _ -> return state) -- | Run an interpreting action. This is effectively runGhc with initialization and importing. First -- argument indicates whether `stdin` is handled specially, which cannot be done in a testing @@ -249,8 +249,9 @@ initializeItVariable = void $ execStmt "let it = ()" execOptions -- | Publisher for IHaskell outputs. The first argument indicates whether this output is final --- (true) or intermediate (false). -type Publisher = (EvaluationResult -> IO ()) +-- (true) or intermediate (false). The second argument indicates whether the evaluation +-- completed successfully (true) or an error occurred (false). +type Publisher = (EvaluationResult -> Bool -> IO ()) -- | Output of a command evaluation. data EvalOut = @@ -277,6 +278,11 @@ cleanString istr = if allBrackets -- should never happen: removeBracket other = error $ "Expected bracket as first char, but got string: " ++ other +-- | Converts Success/Failure to a boolean to set the output cell type. +successStatus :: ErrorOccurred -> Bool +successStatus Success = True +successStatus Failure = False + -- | Evaluate some IPython input code. evaluate :: KernelState -- ^ The kernel state. -> String -- ^ Haskell code or other interpreter commands. @@ -298,14 +304,16 @@ evaluate kernelState code output widgetHandler = do when (getLintStatus kernelState /= LintOff) $ liftIO $ do lintSuggestions <- lint cmds unless (noResults lintSuggestions) $ - output $ FinalResult lintSuggestions [] [] + output (FinalResult lintSuggestions [] []) True runUntilFailure kernelState (map unloc cmds ++ [storeItCommand execCount]) -- Print all parse errors. _ -> do forM_ errs $ \err -> do out <- evalCommand output err kernelState - liftIO $ output $ FinalResult (evalResult out) [] [] + liftIO $ output + (FinalResult (evalResult out) [] []) + (successStatus $ evalStatus out) return kernelState return updated { getExecutionCounter = execCount + 1 } @@ -338,7 +346,9 @@ evaluate kernelState code output widgetHandler = do -- Output things only if they are non-empty. unless (noResults result && null (evalPager evalOut)) $ - liftIO $ output $ FinalResult result (evalPager evalOut) [] + liftIO $ output + (FinalResult result (evalPager evalOut) []) + (successStatus $ evalStatus evalOut) let tempMsgs = evalMsgs evalOut tempState = evalState evalOut { evalMsgs = [] } @@ -693,7 +703,7 @@ evalCommand publish (Directive ShellCmd cmd) state = wrapExecution state $ case mExitCode of Nothing -> do -- Write to frontend and repeat. - readMVar outputAccum >>= output + readMVar outputAccum >>= flip output True loop Just exitCode -> do next <- readChars pipe "" maxSize @@ -1222,7 +1232,7 @@ evalStatementOrIO publish state cmd = do CapturedIO _ -> write state "Evaluating Action" - (printed, result) <- capturedEval output cmd + (printed, result) <- capturedEval (flip output True) cmd case result of ExecComplete (Right names) _ -> do dflags <- getSessionDynFlags diff --git a/src/IHaskell/Publish.hs b/src/IHaskell/Publish.hs index 53271ae1..ce21fae5 100644 --- a/src/IHaskell/Publish.hs +++ b/src/IHaskell/Publish.hs @@ -26,8 +26,9 @@ publishResult :: (Message -> IO ()) -- ^ A function to send messages -> MVar [DisplayData] -- ^ A MVar to use for storing pager output -> Bool -- ^ Whether to use the pager -> EvaluationResult -- ^ The evaluation result + -> Bool -- ^ Whether evaluation completed successfully -> IO () -publishResult send replyHeader displayed updateNeeded poutput upager result = do +publishResult send replyHeader displayed updateNeeded poutput upager result success = do let final = case result of IntermediateResult{} -> False diff --git a/src/tests/IHaskell/Test/Eval.hs b/src/tests/IHaskell/Test/Eval.hs index c301c83d..197fb772 100644 --- a/src/tests/IHaskell/Test/Eval.hs +++ b/src/tests/IHaskell/Test/Eval.hs @@ -24,7 +24,7 @@ eval :: String -> IO ([Display], String) eval string = do outputAccum <- newIORef [] pagerAccum <- newIORef [] - let publish evalResult = + let publish evalResult _ = case evalResult of IntermediateResult{} -> return () FinalResult outs page _ -> do