<commit_before>from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
                                line_cell_magic, needs_local_scope)
from IPython.core.magic_arguments import (
    argument, magic_arguments, parse_argstring, argument_group
)


class RemoteKernel(object):

    def __init__(self, kernel_manager, kernel_name):
        # Locate the best match for the kernel_name in the list of possible
        # kernel names
        from jupyter_client.kernelspec import KernelSpecManager
        kernelspecs = list(KernelSpecManager().find_kernel_specs().keys())
        if kernel_name in kernelspecs:  # perfect match
            kernel_full_name = kernel_name
        elif sum(kernel_name in kernelspec for kernelspec in kernelspecs) == 1:  # exact substring of 1
            kernel_full_name = kernelspecs[[kernel_name in kernelspec for kernelspec in kernelspecs].index(True)]
        else:
            import re
            regex = re.compile(kernel_name.replace('_', '.*?'), re.I)
            matches = [re_search.search(kernelspec) for kernelspec in kernelspecs]
            has_match = [bool(match) for match in matches]
            if sum(has_match) == 1:
                kernel_full_name = kernelspecs[has_match.index(True)]
            else:
                raise ValueError("Can't find exactly one kernel matching {0} in list:\n{1}".format(kernel_name, kernelspces))

        self._kernel_name = kernel_name
        self._kernel_full_name = kernel_full_name
        self._kernel_id = kernel_manager.start_kernel(kernel_full_name)
        self._kernel = kernel_manager.get_kernel(self._kernel_id)
        self._client = self._kernel.client()
        self._client.execute('import pickle, os')

    def __del__(self):
        self._client.shutdown_kernel()

    def _execute_code(self, code, directory, output_variables):
        import pickle
        pickle_dumps = 'pickle.dumps({' + ','.join(['"{0}":{0}'.format(variable) for variable in output_variables]) + '})'
        # if directory:
        #     self._client.execute('os.chdir({0})'.format(directory))
        # sent_msg_id = self._client.execute(code, user_expressions={'output':pickle_dumps})
        # reply = self._client.get_shell_msg(sent_msg_id)
        # self.__dict__.update(pickle.loads(eval(reply['content']['user_expressions']['output']['data']['text/plain'])))
        print("{0} is supposed to run this code:".format(self._kernel_name))
        print("-"*80)
        print(code)
        print("-"*80)
        print("in directory {0},".format(directory))
        print("with kernel {0},".format(self._kernel_full_name))
        print("and output {0}.".format(output_variables))
        print(pickle_dumps)
        print()


# The class MUST call this class decorator at creation time
@magics_class
class MyMagics(Magics):

    def __init__(self, **kwargs):
        # Create dictionary of server objects, each of which contains its
        # connection, a tuple of input variables, and a dictionary of output
        # variables.  The input and output variables should be addressable by a
        # dot.
        super(MyMagics, self).__init__(**kwargs)
        from jupyter_client import MultiKernelManager
        self.kernel_manager = MultiKernelManager()
        self.kernels = {}

    def __del__(self):
        for key, value in self.kernels:
            del value

    @magic_arguments()
    @argument(
        '-k', '--kernels', required=True,
        help=''
    )
    @argument(
        '-o', '--output',
        help=''
    )
    @argument(
        '-i', '--input',
        help='Variables from local scope that will be substituted into the given code'
    )
    @argument(
        '-p', '--persistent',
        help=''
    )
    @argument(
        'code',
        nargs='*',
    )
    @needs_local_scope
    @line_cell_magic
    def remote_exec(self, line, cell=None, local_ns=None):
        """Run code remotely via SSH

        This command logs in via SSH to remote servers, opens an ipython shell,
        and runs the given code.  It then returns the requested output
        variables.

        Parameters
        ==========
        s: string or comma-separated list of strings
            Name of server or servers on which to run the code.  These must be
            recognized by SSH, possibly via ~/.ssh/config.<commit_msg>Remove persistent argument, as it is not supported<commit_after>from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
                                line_cell_magic, needs_local_scope)
from IPython.core.magic_arguments import (
    argument, magic_arguments, parse_argstring, argument_group
)


class RemoteKernel(object):

    def __init__(self, kernel_manager, kernel_name):
        # Locate the best match for the kernel_name in the list of possible
        # kernel names
        from jupyter_client.kernelspec import KernelSpecManager
        kernelspecs = list(KernelSpecManager().find_kernel_specs().keys())
        if kernel_name in kernelspecs:  # perfect match
            kernel_full_name = kernel_name
        elif sum(kernel_name in kernelspec for kernelspec in kernelspecs) == 1:  # exact substring of 1
            kernel_full_name = kernelspecs[[kernel_name in kernelspec for kernelspec in kernelspecs].index(True)]
        else:
            import re
            regex = re.compile(kernel_name.replace('_', '.*?'), re.I)
            matches = [re_search.search(kernelspec) for kernelspec in kernelspecs]
            has_match = [bool(match) for match in matches]
            if sum(has_match) == 1:
                kernel_full_name = kernelspecs[has_match.index(True)]
            else:
                raise ValueError("Can't find exactly one kernel matching {0} in list:\n{1}".format(kernel_name, kernelspces))

        self._kernel_name = kernel_name
        self._kernel_full_name = kernel_full_name
        self._kernel_id = kernel_manager.start_kernel(kernel_full_name)
        self._kernel = kernel_manager.get_kernel(self._kernel_id)
        self._client = self._kernel.client()
        self._client.execute('import pickle, os')

    def __del__(self):
        self._client.shutdown_kernel()

    def _execute_code(self, code, directory, output_variables):
        import pickle
        pickle_dumps = 'pickle.dumps({' + ','.join(['"{0}":{0}'.format(variable) for variable in output_variables]) + '})'
        # if directory:
        #     self._client.execute('os.chdir({0})'.format(directory))
        # sent_msg_id = self._client.execute(code, user_expressions={'output':pickle_dumps})
        # reply = self._client.get_shell_msg(sent_msg_id)
        # self.__dict__.update(pickle.loads(eval(reply['content']['user_expressions']['output']['data']['text/plain'])))
        print("{0} is supposed to run this code:".format(self._kernel_name))
        print("-"*80)
        print(code)
        print("-"*80)
        print("in directory {0},".format(directory))
        print("with kernel {0},".format(self._kernel_full_name))
        print("and output {0}.".format(output_variables))
        print(pickle_dumps)
        print()


# The class MUST call this class decorator at creation time
@magics_class
class MyMagics(Magics):

    def __init__(self, **kwargs):
        # Create dictionary of server objects, each of which contains its
        # connection, a tuple of input variables, and a dictionary of output
        # variables.  The input and output variables should be addressable by a
        # dot.
        super(MyMagics, self).__init__(**kwargs)
        from jupyter_client import MultiKernelManager
        self.kernel_manager = MultiKernelManager()
        self.kernels = {}

    def __del__(self):
        for key, value in self.kernels:
            del value

    @magic_arguments()
    @argument(
        '-k', '--kernels', required=True,
        help=''
    )
    @argument(
        '-o', '--output',
        help=''
    )
    @argument(
        '-i', '--input',
        help='Variables from local scope that will be substituted into the given code'
    )
    @argument(
        'code',
        nargs='*',
    )
    @needs_local_scope
    @line_cell_magic
    def remote_exec(self, line, cell=None, local_ns=None):
        """Run code remotely via SSH

        This command logs in via SSH to remote servers, opens an ipython shell,
        and runs the given code.  It then returns the requested output
        variables.

        Parameters
        ==========
        s: string or comma-separated list of strings
            Name of server or servers on which to run the code.  These must be
            recognized by SSH, possibly via ~/.ssh/config.
{'fraction_non_alphanumeric': 0.10631918819188192, 'fraction_numerical': 0.0036900369003690036, 'mean_word_length': 2.647182506307822, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5745415', 'n_tokens_mistral': 2569, 'n_tokens_neox': 2448, 'n_words': 662}