# HG changeset patch # User Brendan Rius # Date 1461920335 -3600 # Node ID 696cc0775abb0374498c553c950def430f61c5bf # Parent 92e342d23ebc9e4ab790e4a430921c442a3487df Change package name diff -r 92e342d23ebc -r 696cc0775abb c_kernel/__init__.py diff -r 92e342d23ebc -r 696cc0775abb c_kernel/__main__.py --- a/c_kernel/__main__.py Fri Apr 29 09:52:03 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -from ipykernel.kernelapp import IPKernelApp -from .kernel import CKernel -IPKernelApp.launch_instance(kernel_class=CKernel) diff -r 92e342d23ebc -r 696cc0775abb c_kernel/kernel.py --- a/c_kernel/kernel.py Fri Apr 29 09:52:03 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -from ipykernel.kernelbase import Kernel -import subprocess -import tempfile -import os - - -class CKernel(Kernel): - implementation = 'c_kernel' - implementation_version = '1.0' - language = 'c' - language_version = 'C11' - language_info = {'name': 'c', - 'mimetype': 'text/plain', - 'file_extension': 'c'} - banner = "C kernel.\n" \ - "Uses gcc, compiles in C11, and creates source code files and executables in temporary folder.\n" - - def __init__(self, *args, **kwargs): - super(CKernel, self).__init__(*args, **kwargs) - self.files = [] - - def cleanup_files(self): - """Remove all the temporary files created by the kernel""" - for file in self.files: - os.remove(file) - - def new_temp_file(self, **kwargs): - """Create a new temp file to be deleted when the kernel shuts down""" - # We don't want the file to be deleted when closed, but only when the kernel stops - kwargs['delete'] = False - kwargs['mode'] = 'w' - file = tempfile.NamedTemporaryFile(**kwargs) - self.files.append(file.name) - return file - - @staticmethod - def execute_command(cmd): - """Execute a command and returns the return code, stdout and stderr""" - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - return p.returncode, stdout.decode('utf-8'), stderr.decode('utf-8') - - @staticmethod - def compile_with_gcc(source_filename, binary_filename): - args = ['gcc', source_filename, '-std=c11', '-o', binary_filename] - return CKernel.execute_command(args) - - def do_execute(self, code, silent, store_history=True, - user_expressions=None, allow_stdin=False): - - retcode, stdout, stderr = None, '', '' - with self.new_temp_file(suffix='.c') as source_file: - source_file.write(code) - source_file.flush() - with self.new_temp_file(suffix='.out') as binary_file: - retcode, stdout, stderr = self.compile_with_gcc(source_file.name, binary_file.name) - if retcode != 0: - stderr += "[C kernel] GCC exited with code {}, the executable will not be executed".format(retcode) - self.log.info("GCC return code: {}".format(retcode)) - self.log.info("GCC stdout: {}".format(stdout)) - self.log.info("GCC stderr: {}".format(stderr)) - - if retcode == 0: # If the compilation succeeded - retcode, out, err = CKernel.execute_command([binary_file.name]) - if retcode != 0: - stderr += "[C kernel] Executable exited with code {}".format(retcode) - self.log.info("Executable retcode: {}".format(retcode)) - self.log.info("Executable stdout: {}".format(out)) - self.log.info("Executable stderr: {}".format(err)) - stdout += out - stderr += err - else: - self.log.info('Compilation failed, the program will not be executed') - - if not silent: - stream_content = {'name': 'stderr', 'text': stderr} - self.send_response(self.iopub_socket, 'stream', stream_content) - stream_content = {'name': 'stdout', 'text': stdout} - self.send_response(self.iopub_socket, 'stream', stream_content) - return {'status': 'ok', 'execution_count': self.execution_count, 'payload': [], 'user_expressions': {}} - - def do_shutdown(self, restart): - """Cleanup the created source code files and executables when shutting down the kernel""" - self.cleanup_files() diff -r 92e342d23ebc -r 696cc0775abb jupyter_c_kernel/__init__.py diff -r 92e342d23ebc -r 696cc0775abb jupyter_c_kernel/__main__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jupyter_c_kernel/__main__.py Fri Apr 29 09:58:55 2016 +0100 @@ -0,0 +1,3 @@ +from ipykernel.kernelapp import IPKernelApp +from .kernel import CKernel +IPKernelApp.launch_instance(kernel_class=CKernel) diff -r 92e342d23ebc -r 696cc0775abb jupyter_c_kernel/kernel.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jupyter_c_kernel/kernel.py Fri Apr 29 09:58:55 2016 +0100 @@ -0,0 +1,84 @@ +from ipykernel.kernelbase import Kernel +import subprocess +import tempfile +import os + + +class CKernel(Kernel): + implementation = 'jupyter_c_kernel' + implementation_version = '1.0' + language = 'c' + language_version = 'C11' + language_info = {'name': 'c', + 'mimetype': 'text/plain', + 'file_extension': 'c'} + banner = "C kernel.\n" \ + "Uses gcc, compiles in C11, and creates source code files and executables in temporary folder.\n" + + def __init__(self, *args, **kwargs): + super(CKernel, self).__init__(*args, **kwargs) + self.files = [] + + def cleanup_files(self): + """Remove all the temporary files created by the kernel""" + for file in self.files: + os.remove(file) + + def new_temp_file(self, **kwargs): + """Create a new temp file to be deleted when the kernel shuts down""" + # We don't want the file to be deleted when closed, but only when the kernel stops + kwargs['delete'] = False + kwargs['mode'] = 'w' + file = tempfile.NamedTemporaryFile(**kwargs) + self.files.append(file.name) + return file + + @staticmethod + def execute_command(cmd): + """Execute a command and returns the return code, stdout and stderr""" + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + return p.returncode, stdout.decode('utf-8'), stderr.decode('utf-8') + + @staticmethod + def compile_with_gcc(source_filename, binary_filename): + args = ['gcc', source_filename, '-std=c11', '-o', binary_filename] + return CKernel.execute_command(args) + + def do_execute(self, code, silent, store_history=True, + user_expressions=None, allow_stdin=False): + + retcode, stdout, stderr = None, '', '' + with self.new_temp_file(suffix='.c') as source_file: + source_file.write(code) + source_file.flush() + with self.new_temp_file(suffix='.out') as binary_file: + retcode, stdout, stderr = self.compile_with_gcc(source_file.name, binary_file.name) + if retcode != 0: + stderr += "[C kernel] GCC exited with code {}, the executable will not be executed".format(retcode) + self.log.info("GCC return code: {}".format(retcode)) + self.log.info("GCC stdout: {}".format(stdout)) + self.log.info("GCC stderr: {}".format(stderr)) + + if retcode == 0: # If the compilation succeeded + retcode, out, err = CKernel.execute_command([binary_file.name]) + if retcode != 0: + stderr += "[C kernel] Executable exited with code {}".format(retcode) + self.log.info("Executable retcode: {}".format(retcode)) + self.log.info("Executable stdout: {}".format(out)) + self.log.info("Executable stderr: {}".format(err)) + stdout += out + stderr += err + else: + self.log.info('Compilation failed, the program will not be executed') + + if not silent: + stream_content = {'name': 'stderr', 'text': stderr} + self.send_response(self.iopub_socket, 'stream', stream_content) + stream_content = {'name': 'stdout', 'text': stdout} + self.send_response(self.iopub_socket, 'stream', stream_content) + return {'status': 'ok', 'execution_count': self.execution_count, 'payload': [], 'user_expressions': {}} + + def do_shutdown(self, restart): + """Cleanup the created source code files and executables when shutting down the kernel""" + self.cleanup_files() diff -r 92e342d23ebc -r 696cc0775abb setup.py --- a/setup.py Fri Apr 29 09:52:03 2016 +0100 +++ b/setup.py Fri Apr 29 09:58:55 2016 +0100 @@ -5,5 +5,5 @@ description='Minimalistic C kernel for Jupyter', author='Brendan Rius', author_email='ping@brendan-rius.com', - packages=['c_kernel'], - ) + packages=['jupyter_c_kernel'], + )