annotate c_kernel/kernel.py @ 2:b46b2e5b6c08

Improve error management by separating stdout and stderr
author Brendan Rius <brendan@omixy.com>
date Fri, 25 Mar 2016 14:08:26 +0000
parents 50ea00cf5896
children 8ddfdd2a8574
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
1 from ipykernel.kernelbase import Kernel
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
2 import subprocess
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
3 import tempfile
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
4 import os
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
5
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
6
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
7 class CKernel(Kernel):
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
8 implementation = 'c_kernel'
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
9 implementation_version = '1.0'
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
10 language = 'c'
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
11 language_version = 'C11'
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
12 language_info = {'name': 'c',
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
13 'mimetype': 'text/plain',
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
14 'file_extension': 'c'}
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
15 banner = "C kernel.\n" \
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
16 "Uses gcc, compiles in C11, and creates source code files and executables in temporary folder.\n"
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
17
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
18 def __init__(self, *args, **kwargs):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
19 super(CKernel, self).__init__(*args, **kwargs)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
20 self.files = []
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
21
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
22 def cleanup_files(self):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
23 """Remove all the temporary files created by the kernel"""
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
24 for file in self.files:
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
25 os.remove(file)
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
26
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
27 def new_temp_file(self, **kwargs):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
28 """Create a new temp file to be deleted when the kernel shuts down"""
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
29 # We don't want the file to be deleted when closed, but only when the kernel stops
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
30 kwargs['delete'] = False
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
31 file = tempfile.NamedTemporaryFile(**kwargs)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
32 self.files.append(file.name)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
33 return file
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
34
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
35 @staticmethod
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
36 def execute_command(cmd):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
37 """Execute a command and returns the return code, stdout and stderr"""
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
38 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
39 stdout, stderr = p.communicate()
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
40 return p.returncode, stdout, stderr
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
41
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
42 @staticmethod
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
43 def compile_with_gcc(source_filename, binary_filename):
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
44 args = ['gcc', source_filename, '-std=c11', '-o', binary_filename]
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
45 return CKernel.execute_command(args)
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
46
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
47 def do_execute(self, code, silent, store_history=True,
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
48 user_expressions=None, allow_stdin=False):
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
49
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
50 retcode, stdout, stderr = None, '', ''
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
51 with self.new_temp_file(suffix='.c') as source_file:
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
52 source_file.write(code)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
53 source_file.flush()
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
54 with self.new_temp_file(suffix='.out') as binary_file:
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
55 retcode, stdout, stderr = self.compile_with_gcc(source_file.name, binary_file.name)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
56 self.log.error(retcode)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
57 self.log.error(stdout)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
58 self.log.error(stderr)
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
59
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
60 retcode, out, err = CKernel.execute_command([binary_file.name])
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
61 stdout += out
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
62 stderr += err
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
63 self.log.error(retcode)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
64 self.log.error(out)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
65 self.log.error(err)
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
66
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
67 if not silent:
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
68 stream_content = {'name': 'stderr', 'text': stderr}
0
50ea00cf5896 Initial commit
Brendan Rius <brendan@omixy.com>
parents:
diff changeset
69 self.send_response(self.iopub_socket, 'stream', stream_content)
2
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
70 stream_content = {'name': 'stdout', 'text': stdout}
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
71 self.send_response(self.iopub_socket, 'stream', stream_content)
b46b2e5b6c08 Improve error management by separating stdout and stderr
Brendan Rius <brendan@omixy.com>
parents: 0
diff changeset
72 return {'status': 'ok', 'execution_count': self.execution_count, 'payload': [], 'user_expressions': {}}