Hello community, here is the log from the commit of package python-jupyter_ipython for openSUSE:Factory checked in at 2019-03-04 09:22:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-jupyter_ipython (Old) and /work/SRC/openSUSE:Factory/.python-jupyter_ipython.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-jupyter_ipython" Mon Mar 4 09:22:02 2019 rev:15 rq:680627 version:7.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-jupyter_ipython/python-jupyter_ipython-doc.changes 2018-12-24 11:48:13.769089710 +0100 +++ /work/SRC/openSUSE:Factory/.python-jupyter_ipython.new.28833/python-jupyter_ipython-doc.changes 2019-03-04 09:22:16.432580482 +0100 @@ -1,0 +2,26 @@ +Fri Mar 1 18:00:07 UTC 2019 - Arun Persaud <a...@gmx.de> + +- specfile: + * update copyright year + +- update to version 7.3.0: + * The biggest change to this release is the implementation of the + "%conda" and "%pip" magics, that will attempt to install packages + in the **current environment**. You may still need to restart your + interpreter or kernel for the change to be taken into account, but + it should simplify installation of packages into remote + environment. Installing using pip/conda from the command line is + still the prefer method. + * The "%pip" magic was already present, but was only printing a + warning; now it will actually forward commands to pip. + * Misc bug fixes and improvements: + + Compatibility with Python 3.8. + + Do not expand shell variable in execution magics, and added the + "no_var_expand" decorator for magic requiring a similar + functionality :ghpull:`11516` + + Add "%pip" and "%conda" magic :ghpull:`11524` + + Re-initialize posix aliases after a "%reset" :ghpull:`11528` + + Allow the IPython command line to run "*.ipynb" files + :ghpull:`11529` + +------------------------------------------------------------------- python-jupyter_ipython.changes: same change Old: ---- ipython-7.2.0.tar.gz New: ---- ipython-7.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-jupyter_ipython-doc.spec ++++++ --- /var/tmp/diff_new_pack.OQ4G8y/_old 2019-03-04 09:22:18.508580108 +0100 +++ /var/tmp/diff_new_pack.OQ4G8y/_new 2019-03-04 09:22:18.512580107 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-jupyter_ipython-doc # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,16 +18,15 @@ # This package has to be kept separate from the main package to avoid # dependency loops with most of the core jupyter packages. - %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define oldpython python Name: python-jupyter_ipython-doc -Version: 7.2.0 +Version: 7.3.0 Release: 0 Summary: Documentation for python3-jupyter_ipython License: BSD-3-Clause Group: Documentation/Other -Url: https://github.com/ipython/ipython +URL: https://github.com/ipython/ipython Source0: https://files.pythonhosted.org/packages/source/i/ipython/ipython-%{version}.tar.gz # Please make sure you update the documentation files at every release Source1: https://media.readthedocs.org/pdf/ipython/stable/ipython.pdf ++++++ python-jupyter_ipython.spec ++++++ --- /var/tmp/diff_new_pack.OQ4G8y/_old 2019-03-04 09:22:18.524580106 +0100 +++ /var/tmp/diff_new_pack.OQ4G8y/_new 2019-03-04 09:22:18.524580106 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-jupyter_ipython # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -20,12 +20,12 @@ %define skip_python2 1 %bcond_without iptest Name: python-jupyter_ipython -Version: 7.2.0 +Version: 7.3.0 Release: 0 Summary: Rich architecture for interactive computing with Python License: BSD-3-Clause Group: Development/Languages/Python -Url: https://github.com/ipython/ipython +URL: https://github.com/ipython/ipython Source: https://files.pythonhosted.org/packages/source/i/ipython/ipython-%{version}.tar.gz Source1: https://raw.githubusercontent.com/jupyter/qtconsole/4.0.0/qtconsole/resources/icon/JupyterConsole.svg BuildRequires: %{python_module backcall} @@ -56,15 +56,14 @@ Recommends: python-jupyter_nbformat Recommends: python-jupyter_notebook Recommends: python-jupyter_qtconsole -BuildArch: noarch -%if %{with ico} -BuildRequires: icoutils -%endif Provides: IPython3 = %{version} Obsoletes: IPython3 < %{version} Provides: python3-IPython = %{version} Obsoletes: python3-IPython < %{version} - +BuildArch: noarch +%if %{with ico} +BuildRequires: icoutils +%endif %python_subpackages %description ++++++ ipython-7.2.0.tar.gz -> ipython-7.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/completer.py new/ipython-7.3.0/IPython/core/completer.py --- old/ipython-7.2.0/IPython/core/completer.py 2018-11-29 03:45:49.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/completer.py 2019-02-18 22:35:17.000000000 +0100 @@ -1134,10 +1134,15 @@ self.dict_key_matches, ] - def all_completions(self, text): + def all_completions(self, text) -> List[str]: """ - Wrapper around the complete method for the benefit of emacs. + Wrapper around the completions method for the benefit of emacs. """ + prefix = text[:text.rfind(".") + 1] + with provisionalcompleter(): + return list(map(lambda c: prefix + c.text, + self.completions(text, len(text)))) + return self.complete(text)[1] def _clean_glob(self, text): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/crashhandler.py new/ipython-7.3.0/IPython/core/crashhandler.py --- old/ipython-7.2.0/IPython/core/crashhandler.py 2018-11-03 22:32:57.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/crashhandler.py 2019-01-06 21:28:33.000000000 +0100 @@ -179,13 +179,14 @@ print('Could not create crash report on disk.', file=sys.stderr) return - # Inform user on stderr of what happened - print('\n'+'*'*70+'\n', file=sys.stderr) - print(self.message_template.format(**self.info), file=sys.stderr) + with report: + # Inform user on stderr of what happened + print('\n'+'*'*70+'\n', file=sys.stderr) + print(self.message_template.format(**self.info), file=sys.stderr) + + # Construct report on disk + report.write(self.make_report(traceback)) - # Construct report on disk - report.write(self.make_report(traceback)) - report.close() input("Hit <Enter> to quit (your terminal may close):") def make_report(self,traceback): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/debugger.py new/ipython-7.3.0/IPython/core/debugger.py --- old/ipython-7.2.0/IPython/core/debugger.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/debugger.py 2019-01-06 21:28:33.000000000 +0100 @@ -206,9 +206,8 @@ except IOError: return [] else: - out = outfile.readlines() - outfile.close() - return out + with out: + return outfile.readlines() class Pdb(OldPdb): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/interactiveshell.py new/ipython-7.3.0/IPython/core/interactiveshell.py --- old/ipython-7.2.0/IPython/core/interactiveshell.py 2018-11-29 03:45:49.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/interactiveshell.py 2019-02-18 22:35:17.000000000 +0100 @@ -107,6 +107,14 @@ """ pass +if sys.version_info > (3,8): + from ast import Module +else : + # mock the new API, ignore second argument + # see https://github.com/ipython/ipython/issues/11590 + from ast import Module as OriginalModule + Module = lambda nodelist, type_ignores: OriginalModule(nodelist) + if sys.version_info > (3,6): _assign_nodes = (ast.AugAssign, ast.AnnAssign, ast.Assign) _single_targets_nodes = (ast.AugAssign, ast.AnnAssign) @@ -1433,6 +1441,13 @@ self.alias_manager.clear_aliases() self.alias_manager.init_aliases() + # Now define aliases that only make sense on the terminal, because they + # need direct access to the console in a way that we can't emulate in + # GUI or web frontend + if os.name == 'posix': + for cmd in ('clear', 'more', 'less', 'man'): + self.alias_manager.soft_define_alias(cmd, cmd) + # Flush the private list of module references kept for script # execution protection self.clear_main_mod_cache() @@ -2220,7 +2235,8 @@ self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics, m.ConfigMagics, m.DisplayMagics, m.ExecutionMagics, m.ExtensionMagics, m.HistoryMagics, m.LoggingMagics, - m.NamespaceMagics, m.OSMagics, m.PylabMagics, m.ScriptMagics, + m.NamespaceMagics, m.OSMagics, m.PackagingMagics, + m.PylabMagics, m.ScriptMagics, ) if sys.version_info >(3,5): self.register_magics(m.AsyncMagics) @@ -2273,10 +2289,14 @@ # Note: this is the distance in the stack to the user's frame. # This will need to be updated if the internal calling logic gets # refactored, or else we'll be expanding the wrong variables. - + # Determine stack_depth depending on where run_line_magic() has been called stack_depth = _stack_depth - magic_arg_s = self.var_expand(line, stack_depth) + if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False): + # magic has opted out of var_expand + magic_arg_s = line + else: + magic_arg_s = self.var_expand(line, stack_depth) # Put magic args in a list so we can call with f(*a) syntax args = [magic_arg_s] kwargs = {} @@ -2284,12 +2304,12 @@ if getattr(fn, "needs_local_scope", False): kwargs['local_ns'] = sys._getframe(stack_depth).f_locals with self.builtin_trap: - result = fn(*args,**kwargs) + result = fn(*args, **kwargs) return result def run_cell_magic(self, magic_name, line, cell): """Execute the given cell magic. - + Parameters ---------- magic_name : str @@ -2318,7 +2338,11 @@ # This will need to be updated if the internal calling logic gets # refactored, or else we'll be expanding the wrong variables. stack_depth = 2 - magic_arg_s = self.var_expand(line, stack_depth) + if getattr(fn, magic.MAGIC_NO_VAR_EXPAND_ATTR, False): + # magic has opted out of var_expand + magic_arg_s = line + else: + magic_arg_s = self.var_expand(line, stack_depth) with self.builtin_trap: result = fn(magic_arg_s, cell) return result @@ -3172,15 +3196,15 @@ if _async: # If interactivity is async the semantics of run_code are # completely different Skip usual machinery. - mod = ast.Module(nodelist) - async_wrapper_code = compiler(mod, 'cell_name', 'exec') + mod = Module(nodelist, []) + async_wrapper_code = compiler(mod, cell_name, 'exec') exec(async_wrapper_code, self.user_global_ns, self.user_ns) async_code = removed_co_newlocals(self.user_ns.pop('async-def-wrapper')).__code__ if (yield from self.run_code(async_code, result, async_=True)): return True else: for i, node in enumerate(to_run_exec): - mod = ast.Module([node]) + mod = Module([node], []) code = compiler(mod, cell_name, "exec") if (yield from self.run_code(code, result)): return True @@ -3460,9 +3484,8 @@ self.tempfiles.append(filename) if data: - tmp_file = open(filename,'w') - tmp_file.write(data) - tmp_file.close() + with open(filename, 'w') as tmp_file: + tmp_file.write(data) return filename @undoc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/magic.py new/ipython-7.3.0/IPython/core/magic.py --- old/ipython-7.2.0/IPython/core/magic.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/magic.py 2019-01-06 21:28:19.000000000 +0100 @@ -265,6 +265,25 @@ return magic_deco +MAGIC_NO_VAR_EXPAND_ATTR = '_ipython_magic_no_var_expand' + + +def no_var_expand(magic_func): + """Mark a magic function as not needing variable expansion + + By default, IPython interprets `{a}` or `$a` in the line passed to magics + as variables that should be interpolated from the interactive namespace + before passing the line to the magic function. + This is not always desirable, e.g. when the magic executes Python code + (%timeit, %time, etc.). + Decorate magics with `@no_var_expand` to opt-out of variable expansion. + + .. versionadded:: 7.3 + """ + setattr(magic_func, MAGIC_NO_VAR_EXPAND_ATTR, True) + return magic_func + + # Create the actual decorators for public use # These three are used to decorate methods in class definitions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/magics/__init__.py new/ipython-7.3.0/IPython/core/magics/__init__.py --- old/ipython-7.2.0/IPython/core/magics/__init__.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/magics/__init__.py 2019-01-06 21:28:19.000000000 +0100 @@ -24,6 +24,7 @@ from .logging import LoggingMagics from .namespace import NamespaceMagics from .osm import OSMagics +from .packaging import PackagingMagics from .pylab import PylabMagics from .script import ScriptMagics diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/magics/basic.py new/ipython-7.3.0/IPython/core/magics/basic.py --- old/ipython-7.2.0/IPython/core/magics/basic.py 2018-11-29 03:45:49.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/magics/basic.py 2019-01-06 21:28:19.000000000 +0100 @@ -179,7 +179,7 @@ @line_magic def lsmagic(self, parameter_s=''): """List currently available magic functions.""" - return MagicsDisplay(self.shell.magics_manager, ignore=[self.pip]) + return MagicsDisplay(self.shell.magics_manager, ignore=[]) def _magic_docs(self, brief=False, rest=False): """Return docstrings from magic functions.""" @@ -379,25 +379,6 @@ except: xmode_switch_err('user') - - - @line_magic - def pip(self, args=''): - """ - Intercept usage of ``pip`` in IPython and direct user to run command outside of IPython. - """ - print(textwrap.dedent(''' - The following command must be run outside of the IPython shell: - - $ pip {args} - - The Python package manager (pip) can only be used from outside of IPython. - Please reissue the `pip` command in a separate terminal or command prompt. - - See the Python documentation for more information on how to install packages: - - https://docs.python.org/3/installing/'''.format(args=args))) - @line_magic def quickref(self, arg): """ Show a quick reference sheet """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/magics/code.py new/ipython-7.3.0/IPython/core/magics/code.py --- old/ipython-7.2.0/IPython/core/magics/code.py 2018-11-03 22:32:57.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/magics/code.py 2019-01-06 21:28:33.000000000 +0100 @@ -722,7 +722,8 @@ if is_temp: try: - return open(filename).read() + with open(filename) as f: + return f.read() except IOError as msg: if msg.filename == filename: warn('File not found. Did you forget to save?') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/magics/execution.py new/ipython-7.3.0/IPython/core/magics/execution.py --- old/ipython-7.2.0/IPython/core/magics/execution.py 2018-11-29 03:45:49.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/magics/execution.py 2019-01-06 21:28:33.000000000 +0100 @@ -36,7 +36,8 @@ from IPython.core.error import UsageError from IPython.core.macro import Macro from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic, - line_cell_magic, on_off, needs_local_scope) + line_cell_magic, on_off, needs_local_scope, + no_var_expand) from IPython.testing.skipdoctest import skip_doctest from IPython.utils.contexts import preserve_keys from IPython.utils.capture import capture_output @@ -184,6 +185,7 @@ python-profiler package from non-free.""") @skip_doctest + @no_var_expand @line_cell_magic def prun(self, parameter_s='', cell=None): @@ -293,6 +295,11 @@ You can read the complete documentation for the profile module with:: In [1]: import profile; profile.help() + + .. versionchanged:: 7.3 + User variables are no longer expanded, + the magic line is always left unmodified. + """ opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q', list_all=True, posix=False) @@ -363,9 +370,8 @@ print('\n*** Profile stats marshalled to file',\ repr(dump_file)+'.',sys_exit) if text_file: - pfile = open(text_file,'w') - pfile.write(output) - pfile.close() + with open(text_file, 'w') as pfile: + pfile.write(output) print('\n*** Profile printout saved to text file',\ repr(text_file)+'.',sys_exit) @@ -422,6 +428,7 @@ You can omit this in cell magic mode. """ ) + @no_var_expand @line_cell_magic def debug(self, line='', cell=None): """Activate the interactive debugger. @@ -442,6 +449,11 @@ If you want IPython to automatically do this on every exception, see the %pdb magic for more details. + + .. versionchanged:: 7.3 + When running code, user variables are no longer expanded, + the magic line is always left unmodified. + """ args = magic_arguments.parse_argstring(self.debug, line) @@ -972,6 +984,7 @@ print("Wall time: %10.2f s." % (twall1 - twall0)) @skip_doctest + @no_var_expand @line_cell_magic @needs_local_scope def timeit(self, line='', cell=None, local_ns=None): @@ -1017,6 +1030,9 @@ -o: return a TimeitResult that can be stored in a variable to inspect the result in more details. + .. versionchanged:: 7.3 + User variables are no longer expanded, + the magic line is always left unmodified. Examples -------- @@ -1161,6 +1177,7 @@ return timeit_result @skip_doctest + @no_var_expand @needs_local_scope @line_cell_magic def time(self,line='', cell=None, local_ns=None): @@ -1175,12 +1192,16 @@ - In line mode you can time a single-line statement (though multiple ones can be chained with using semicolons). - - In cell mode, you can time the cell body (a directly + - In cell mode, you can time the cell body (a directly following statement raises an error). - This function provides very basic timing functionality. Use the timeit + This function provides very basic timing functionality. Use the timeit magic for more control over the measurement. + .. versionchanged:: 7.3 + User variables are no longer expanded, + the magic line is always left unmodified. + Examples -------- :: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/magics/osm.py new/ipython-7.3.0/IPython/core/magics/osm.py --- old/ipython-7.2.0/IPython/core/magics/osm.py 2018-11-20 19:37:09.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/magics/osm.py 2019-02-18 22:35:17.000000000 +0100 @@ -825,7 +825,7 @@ The file will be overwritten unless the -a (--append) flag is specified. """ args = magic_arguments.parse_argstring(self.writefile, line) - if re.match(r'[\'*\']|["*"]', args.filename): + if re.match(r'^(\'.*\')|(".*")$', args.filename): filename = os.path.expanduser(args.filename[1:-1]) else: filename = os.path.expanduser(args.filename) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/magics/packaging.py new/ipython-7.3.0/IPython/core/magics/packaging.py --- old/ipython-7.2.0/IPython/core/magics/packaging.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/magics/packaging.py 2019-01-06 21:28:33.000000000 +0100 @@ -0,0 +1,104 @@ +"""Implementation of packaging-related magic functions. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2018 The IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +import os +import re +import shlex +import sys +from subprocess import Popen, PIPE + +from IPython.core.magic import Magics, magics_class, line_magic + + +def _is_conda_environment(): + """Return True if the current Python executable is in a conda env""" + # TODO: does this need to change on windows? + conda_history = os.path.join(sys.prefix, 'conda-meta', 'history') + return os.path.exists(conda_history) + + +def _get_conda_executable(): + """Find the path to the conda executable""" + # Check if there is a conda executable in the same directory as the Python executable. + # This is the case within conda's root environment. + conda = os.path.join(os.path.dirname(sys.executable), 'conda') + if os.path.isfile(conda): + return conda + + # Otherwise, attempt to extract the executable from conda history. + # This applies in any conda environment. + R = re.compile(r"^#\s*cmd:\s*(?P<command>.*conda)\s[create|install]") + with open(os.path.join(sys.prefix, 'conda-meta', 'history')) as f: + for line in f: + match = R.match(line) + if match: + return match.groupdict()['command'] + + # Fallback: assume conda is available on the system path. + return "conda" + + +CONDA_COMMANDS_REQUIRING_PREFIX = { + 'install', 'list', 'remove', 'uninstall', 'update', 'upgrade', +} +CONDA_COMMANDS_REQUIRING_YES = { + 'install', 'remove', 'uninstall', 'update', 'upgrade', +} +CONDA_ENV_FLAGS = {'-p', '--prefix', '-n', '--name'} +CONDA_YES_FLAGS = {'-y', '--y'} + + +@magics_class +class PackagingMagics(Magics): + """Magics related to packaging & installation""" + + @line_magic + def pip(self, line): + """Run the pip package manager within the current kernel. + + Usage: + %pip install [pkgs] + """ + self.shell.system(' '.join([sys.executable, '-m', 'pip', line])) + print("Note: you may need to restart the kernel to use updated packages.") + + @line_magic + def conda(self, line): + """Run the conda package manager within the current kernel. + + Usage: + %conda install [pkgs] + """ + if not _is_conda_environment(): + raise ValueError("The python kernel does not appear to be a conda environment. " + "Please use ``%pip install`` instead.") + + conda = _get_conda_executable() + args = shlex.split(line) + command = args[0] + args = args[1:] + extra_args = [] + + # When the subprocess does not allow us to respond "yes" during the installation, + # we need to insert --yes in the argument list for some commands + stdin_disabled = getattr(self.shell, 'kernel', None) is not None + needs_yes = command in CONDA_COMMANDS_REQUIRING_YES + has_yes = set(args).intersection(CONDA_YES_FLAGS) + if stdin_disabled and needs_yes and not has_yes: + extra_args.append("--yes") + + # Add --prefix to point conda installation to the current environment + needs_prefix = command in CONDA_COMMANDS_REQUIRING_PREFIX + has_prefix = set(args).intersection(CONDA_ENV_FLAGS) + if needs_prefix and not has_prefix: + extra_args.extend(["--prefix", sys.prefix]) + + self.shell.system(' '.join([conda, command] + extra_args + args)) + print("\nNote: you may need to restart the kernel to use updated packages.") \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/oinspect.py new/ipython-7.3.0/IPython/core/oinspect.py --- old/ipython-7.2.0/IPython/core/oinspect.py 2018-11-29 03:57:26.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/oinspect.py 2019-01-06 21:28:19.000000000 +0100 @@ -1051,7 +1051,9 @@ # add up name, parameters, braces (2), and commas if len(obj_name) + sum(len(r) + 2 for r in result) > 75: # This doesn’t fit behind “Signature: ” in an inspect window. - rendered = '{}(\n{})'.format(obj_name, ''.join(' {},\n'.format(result))) + rendered = '{}(\n{})'.format(obj_name, ''.join( + ' {},\n'.format(r) for r in result) + ) else: rendered = '{}({})'.format(obj_name, ', '.join(result)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/release.py new/ipython-7.3.0/IPython/core/release.py --- old/ipython-7.2.0/IPython/core/release.py 2018-11-30 02:17:33.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/release.py 2019-02-18 22:58:52.000000000 +0100 @@ -20,7 +20,7 @@ # release. 'dev' as a _version_extra string means this is a development # version _version_major = 7 -_version_minor = 2 +_version_minor = 3 _version_patch = 0 _version_extra = '.dev' # _version_extra = 'b1' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/shellapp.py new/ipython-7.3.0/IPython/core/shellapp.py --- old/ipython-7.2.0/IPython/core/shellapp.py 2018-11-29 03:45:49.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/shellapp.py 2019-01-06 21:28:33.000000000 +0100 @@ -329,7 +329,7 @@ # behavior. with preserve_keys(self.shell.user_ns, '__file__'): self.shell.user_ns['__file__'] = fname - if full_filename.endswith('.ipy'): + if full_filename.endswith('.ipy') or full_filename.endswith('.ipynb'): self.shell.safe_execfile_ipy(full_filename, shell_futures=shell_futures) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/tests/test_completer.py new/ipython-7.3.0/IPython/core/tests/test_completer.py --- old/ipython-7.2.0/IPython/core/tests/test_completer.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/tests/test_completer.py 2019-01-06 21:28:19.000000000 +0100 @@ -16,7 +16,7 @@ from traitlets.config.loader import Config from IPython import get_ipython from IPython.core import completer -from IPython.external.decorators import knownfailureif +from IPython.external import decorators from IPython.utils.tempdir import TemporaryDirectory, TemporaryWorkingDirectory from IPython.utils.generics import complete_object from IPython.testing import decorators as dec @@ -183,7 +183,7 @@ nt.assert_equal(matches[0], 'Ⅴ') @nt.nottest # now we have a completion for \jmath -@dec.knownfailureif(sys.platform == 'win32', 'Fails if there is a C:\\j... path') +@decorators.dec.knownfailureif(sys.platform == 'win32', 'Fails if there is a C:\\j... path') def test_no_ascii_back_completion(): ip = get_ipython() with TemporaryWorkingDirectory(): # Avoid any filename completions @@ -234,7 +234,7 @@ nt.assert_false(completer.has_open_quotes(s)) -@knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows") +@decorators.dec.knownfailureif(sys.platform == 'win32', "abspath completions fail on Windows") def test_abspath_file_completions(): ip = get_ipython() with TemporaryDirectory() as tmpdir: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/tests/test_interactiveshell.py new/ipython-7.3.0/IPython/core/tests/test_interactiveshell.py --- old/ipython-7.2.0/IPython/core/tests/test_interactiveshell.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/tests/test_interactiveshell.py 2019-02-18 22:35:17.000000000 +0100 @@ -495,6 +495,16 @@ self.assertFalse(ip.last_execution_result.success) self.assertIsInstance(ip.last_execution_result.error_in_exec, NameError) + def test_reset_aliasing(self): + """ Check that standard posix aliases work after %reset. """ + if os.name != 'posix': + return + + ip.reset() + for cmd in ('clear', 'more', 'less', 'man'): + res = ip.run_cell('%' + cmd) + self.assertEqual(res.success, True) + class TestSafeExecfileNonAsciiPath(unittest.TestCase): @@ -599,10 +609,18 @@ class Negator(ast.NodeTransformer): """Negates all number literals in an AST.""" + + # for python 3.7 and earlier def visit_Num(self, node): node.n = -node.n return node + # for python 3.8+ + def visit_Constant(self, node): + if isinstance(node.value, int): + return self.visit_Num(node) + return node + class TestAstTransform(unittest.TestCase): def setUp(self): self.negator = Negator() @@ -664,12 +682,23 @@ class IntegerWrapper(ast.NodeTransformer): """Wraps all integers in a call to Integer()""" + + # for Python 3.7 and earlier + + # for Python 3.7 and earlier def visit_Num(self, node): if isinstance(node.n, int): return ast.Call(func=ast.Name(id='Integer', ctx=ast.Load()), args=[node], keywords=[]) return node + # For Python 3.8+ + def visit_Constant(self, node): + if isinstance(node.value, int): + return self.visit_Num(node) + return node + + class TestAstTransform2(unittest.TestCase): def setUp(self): self.intwrapper = IntegerWrapper() @@ -710,9 +739,18 @@ class ErrorTransformer(ast.NodeTransformer): """Throws an error when it sees a number.""" + + # for Python 3.7 and earlier def visit_Num(self, node): raise ValueError("test") + # for Python 3.8+ + def visit_Constant(self, node): + if isinstance(node.value, int): + return self.visit_Num(node) + return node + + class TestAstTransformError(unittest.TestCase): def test_unregistering(self): err_transformer = ErrorTransformer() @@ -731,10 +769,17 @@ Used to verify that NodeTransformers can signal that a piece of code should not be executed by throwing an InputRejected. """ - + + #for python 3.7 and earlier def visit_Str(self, node): raise InputRejected("test") + # 3.8 only + def visit_Constant(self, node): + if isinstance(node.value, str): + raise InputRejected("test") + return node + class TestAstTransformInputRejection(unittest.TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/tests/test_magic.py new/ipython-7.3.0/IPython/core/tests/test_magic.py --- old/ipython-7.2.0/IPython/core/tests/test_magic.py 2018-11-29 03:45:49.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/tests/test_magic.py 2019-02-18 22:35:17.000000000 +0100 @@ -769,6 +769,36 @@ nt.assert_in('line1\n', s) nt.assert_in('line2', s) +@dec.skip_win32 +def test_file_single_quote(): + """Basic %%writefile with embedded single quotes""" + ip = get_ipython() + with TemporaryDirectory() as td: + fname = os.path.join(td, '\'file1\'') + ip.run_cell_magic("writefile", fname, u'\n'.join([ + 'line1', + 'line2', + ])) + with open(fname) as f: + s = f.read() + nt.assert_in('line1\n', s) + nt.assert_in('line2', s) + +@dec.skip_win32 +def test_file_double_quote(): + """Basic %%writefile with embedded double quotes""" + ip = get_ipython() + with TemporaryDirectory() as td: + fname = os.path.join(td, '"file1"') + ip.run_cell_magic("writefile", fname, u'\n'.join([ + 'line1', + 'line2', + ])) + with open(fname) as f: + s = f.read() + nt.assert_in('line1\n', s) + nt.assert_in('line2', s) + def test_file_var_expand(): """%%writefile $filename""" ip = get_ipython() @@ -1087,7 +1117,8 @@ lm.logstart(os.path.join(td, "quiet_from_config.log")) finally: _ip.logger.logstop() - + + def test_logging_magic_not_quiet(): _ip.config.LoggingMagics.quiet = False lm = logging.LoggingMagics(shell=_ip) @@ -1098,9 +1129,15 @@ finally: _ip.logger.logstop() -## + +def test_time_no_var_expand(): + _ip.user_ns['a'] = 5 + _ip.user_ns['b'] = [] + _ip.magic('time b.append("{a}")') + assert _ip.user_ns['b'] == ['{a}'] + + # this is slow, put at the end for local testing. -## def test_timeit_arguments(): "Test valid timeit arguments, should not cause SyntaxError (GH #1269)" if sys.version_info < (3,7): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/tests/test_oinspect.py new/ipython-7.3.0/IPython/core/tests/test_oinspect.py --- old/ipython-7.2.0/IPython/core/tests/test_oinspect.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/tests/test_oinspect.py 2019-01-06 21:28:19.000000000 +0100 @@ -5,7 +5,7 @@ # Distributed under the terms of the Modified BSD License. -from inspect import Signature, Parameter +from inspect import signature, Signature, Parameter import os import re import sys @@ -432,3 +432,43 @@ init_def = info['init_definition'] nt.assert_is_not_none(init_def) + +def test_render_signature_short(): + def short_fun(a=1): pass + sig = oinspect._render_signature( + signature(short_fun), + short_fun.__name__, + ) + nt.assert_equal(sig, 'short_fun(a=1)') + + +def test_render_signature_long(): + from typing import Optional + + def long_function( + a_really_long_parameter: int, + and_another_long_one: bool = False, + let_us_make_sure_this_is_looong: Optional[str] = None, + ) -> bool: pass + + sig = oinspect._render_signature( + signature(long_function), + long_function.__name__, + ) + nt.assert_in(sig, [ + # Python >=3.7 + '''\ +long_function( + a_really_long_parameter: int, + and_another_long_one: bool = False, + let_us_make_sure_this_is_looong: Union[str, NoneType] = None, +) -> bool\ +''', # Python <=3.6 + '''\ +long_function( + a_really_long_parameter:int, + and_another_long_one:bool=False, + let_us_make_sure_this_is_looong:Union[str, NoneType]=None, +) -> bool\ +''', + ]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/tests/test_run.py new/ipython-7.3.0/IPython/core/tests/test_run.py --- old/ipython-7.2.0/IPython/core/tests/test_run.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/tests/test_run.py 2019-01-06 21:28:19.000000000 +0100 @@ -538,7 +538,7 @@ nt.assert_in("RuntimeError", out) nt.assert_equal(out.count("---->"), 3) -@dec.knownfailureif(sys.platform == 'win32', "writes to io.stdout aren't captured on Windows") +@dec.dec.knownfailureif(sys.platform == 'win32', "writes to io.stdout aren't captured on Windows") def test_script_tb(): """Test traceback offset in `ipython script.py`""" with TemporaryDirectory() as td: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/core/tests/test_ultratb.py new/ipython-7.3.0/IPython/core/tests/test_ultratb.py --- old/ipython-7.2.0/IPython/core/tests/test_ultratb.py 2018-11-29 03:45:49.000000000 +0100 +++ new/ipython-7.3.0/IPython/core/tests/test_ultratb.py 2019-02-18 22:35:17.000000000 +0100 @@ -379,10 +379,16 @@ handler(*sys.exc_info()) buff.write('') +from IPython.testing.decorators import skipif class TokenizeFailureTest(unittest.TestCase): """Tests related to https://github.com/ipython/ipython/issues/6864.""" + # that appear to test that we are handling an exception that can be thrown + # by the tokenizer due to a bug that seem to have been fixed in 3.8, though + # I'm unsure if other sequences can make it raise this error. Let's just + # skip in 3.8 for now + @skipif(sys.version_info > (3,8)) def testLogging(self): message = "An unexpected error occurred while tokenizing input" cell = 'raise ValueError("""a\nb""")' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/extensions/autoreload.py new/ipython-7.3.0/IPython/extensions/autoreload.py --- old/ipython-7.2.0/IPython/extensions/autoreload.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/extensions/autoreload.py 2019-02-18 22:35:17.000000000 +0100 @@ -274,7 +274,9 @@ old_obj = getattr(old, key) try: new_obj = getattr(new, key) - if old_obj == new_obj: + # explicitly checking that comparison returns True to handle + # cases where `==` doesn't return a boolean. + if (old_obj == new_obj) is True: continue except AttributeError: # obsolete attribute: remove it diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/extensions/storemagic.py new/ipython-7.3.0/IPython/extensions/storemagic.py --- old/ipython-7.2.0/IPython/extensions/storemagic.py 2018-11-03 22:32:57.000000000 +0100 +++ new/ipython-7.3.0/IPython/extensions/storemagic.py 2019-01-06 21:28:33.000000000 +0100 @@ -172,20 +172,19 @@ fil = open(fnam, 'a') else: fil = open(fnam, 'w') - obj = ip.ev(args[0]) - print("Writing '%s' (%s) to file '%s'." % (args[0], - obj.__class__.__name__, fnam)) + with fil: + obj = ip.ev(args[0]) + print("Writing '%s' (%s) to file '%s'." % (args[0], + obj.__class__.__name__, fnam)) + if not isinstance (obj, str): + from pprint import pprint + pprint(obj, fil) + else: + fil.write(obj) + if not obj.endswith('\n'): + fil.write('\n') - if not isinstance (obj, str): - from pprint import pprint - pprint(obj, fil) - else: - fil.write(obj) - if not obj.endswith('\n'): - fil.write('\n') - - fil.close() return # %store foo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/extensions/tests/test_autoreload.py new/ipython-7.3.0/IPython/extensions/tests/test_autoreload.py --- old/ipython-7.2.0/IPython/extensions/tests/test_autoreload.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/extensions/tests/test_autoreload.py 2019-01-06 21:28:33.000000000 +0100 @@ -109,19 +109,13 @@ time.sleep(1.05) # Write - f = open(filename, 'w') - try: + with open(filename, 'w') as f: f.write(content) - finally: - f.close() def new_module(self, code): mod_name, mod_fn = self.get_module() - f = open(mod_fn, 'w') - try: + with open(mod_fn, 'w') as f: f.write(code) - finally: - f.close() return mod_name, mod_fn #----------------------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/external/decorators/__init__.py new/ipython-7.3.0/IPython/external/decorators/__init__.py --- old/ipython-7.2.0/IPython/external/decorators/__init__.py 2018-10-27 01:55:12.000000000 +0200 +++ new/ipython-7.3.0/IPython/external/decorators/__init__.py 2019-01-06 21:28:19.000000000 +0100 @@ -1,5 +1,6 @@ try: - from numpy.testing.decorators import * + from numpy.testing import * + from numpy.testing import dec from numpy.testing.noseclasses import KnownFailure except ImportError: from ._decorators import * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/lib/display.py new/ipython-7.3.0/IPython/lib/display.py --- old/ipython-7.2.0/IPython/lib/display.py 2018-11-03 22:32:57.000000000 +0100 +++ new/ipython-7.3.0/IPython/lib/display.py 2019-01-06 21:28:19.000000000 +0100 @@ -33,9 +33,9 @@ * Bytestring containing raw PCM data or * URL pointing to a file on the web. - If the array option is used the waveform will be normalized. + If the array option is used, the waveform will be normalized. - If a filename or url is used the format support will be browser + If a filename or url is used, the format support will be browser dependent. url : unicode A URL to download the data from. @@ -63,7 +63,7 @@ import numpy as np framerate = 44100 t = np.linspace(0,5,framerate*5) - data = np.sin(2*np.pi*220*t) + np.sin(2*np.pi*224*t)) + data = np.sin(2*np.pi*220*t) + np.sin(2*np.pi*224*t) Audio(data,rate=framerate) # Can also do stereo or more channels diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/sphinxext/ipython_directive.py new/ipython-7.3.0/IPython/sphinxext/ipython_directive.py --- old/ipython-7.2.0/IPython/sphinxext/ipython_directive.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/sphinxext/ipython_directive.py 2019-01-06 21:28:33.000000000 +0100 @@ -82,7 +82,7 @@ Sphinx source directory. The default is `html_static_path`. ipython_rgxin: The compiled regular expression to denote the start of IPython input - lines. The default is ``re.compile('In \[(\d+)\]:\s?(.*)\s*')``. You + lines. The default is ``re.compile('In \\[(\\d+)\\]:\\s?(.*)\\s*')``. You shouldn't need to change this. ipython_warning_is_error: [default to True] Fail the build if something unexpected happen, for example if a block raise @@ -90,7 +90,7 @@ what is considered strict, may change between the sphinx directive version. ipython_rgxout: The compiled regular expression to denote the start of IPython output - lines. The default is ``re.compile('Out\[(\d+)\]:\s?(.*)\s*')``. You + lines. The default is ``re.compile('Out\\[(\\d+)\\]:\\s?(.*)\\s*')``. You shouldn't need to change this. ipython_promptin: The string to represent the IPython input prompt in the generated ReST. @@ -1047,9 +1047,9 @@ app.add_config_value('ipython_savefig_dir', 'savefig', 'env') app.add_config_value('ipython_warning_is_error', True, 'env') app.add_config_value('ipython_rgxin', - re.compile('In \[(\d+)\]:\s?(.*)\s*'), 'env') + re.compile(r'In \[(\d+)\]:\s?(.*)\s*'), 'env') app.add_config_value('ipython_rgxout', - re.compile('Out\[(\d+)\]:\s?(.*)\s*'), 'env') + re.compile(r'Out\[(\d+)\]:\s?(.*)\s*'), 'env') app.add_config_value('ipython_promptin', 'In [%d]:', 'env') app.add_config_value('ipython_promptout', 'Out[%d]:', 'env') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/terminal/debugger.py new/ipython-7.3.0/IPython/terminal/debugger.py --- old/ipython-7.2.0/IPython/terminal/debugger.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/terminal/debugger.py 2019-02-18 22:35:17.000000000 +0100 @@ -58,6 +58,7 @@ complete_style=self.shell.pt_complete_style, style=self.shell.style, inputhook=self.shell.inputhook, + color_depth=self.shell.color_depth, ) def cmdloop(self, intro=None): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/terminal/interactiveshell.py new/ipython-7.3.0/IPython/terminal/interactiveshell.py --- old/ipython-7.2.0/IPython/terminal/interactiveshell.py 2018-11-20 19:37:09.000000000 +0100 +++ new/ipython-7.3.0/IPython/terminal/interactiveshell.py 2019-02-18 22:35:17.000000000 +0100 @@ -288,7 +288,7 @@ include_default_pygments_style=False, mouse_support=self.mouse_support, enable_open_in_editor=self.extra_open_editor_shortcuts, - color_depth=(ColorDepth.TRUE_COLOR if self.true_color else None), + color_depth=self.color_depth, **self._extra_prompt_options()) def _make_style_from_name_or_cls(self, name_or_cls): @@ -365,6 +365,10 @@ 'readlinelike': CompleteStyle.READLINE_LIKE, }[self.display_completions] + @property + def color_depth(self): + return (ColorDepth.TRUE_COLOR if self.true_color else None) + def _extra_prompt_options(self): """ Return the current layout option for the current Terminal InteractiveShell @@ -447,7 +451,7 @@ # need direct access to the console in a way that we can't emulate in # GUI or web frontend if os.name == 'posix': - for cmd in ['clear', 'more', 'less', 'man']: + for cmd in ('clear', 'more', 'less', 'man'): self.alias_manager.soft_define_alias(cmd, cmd) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/terminal/ptutils.py new/ipython-7.3.0/IPython/terminal/ptutils.py --- old/ipython-7.2.0/IPython/terminal/ptutils.py 2018-11-29 03:45:49.000000000 +0100 +++ new/ipython-7.3.0/IPython/terminal/ptutils.py 2019-02-18 22:35:17.000000000 +0100 @@ -53,7 +53,7 @@ def _adjust_completion_text_based_on_context(text, body, offset): - if text.endswith('=') and len(body) > offset and body[offset] is '=': + if text.endswith('=') and len(body) > offset and body[offset] == '=': return text[:-1] else: return text diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/terminal/tests/test_debug_magic.py new/ipython-7.3.0/IPython/terminal/tests/test_debug_magic.py --- old/ipython-7.2.0/IPython/terminal/tests/test_debug_magic.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/terminal/tests/test_debug_magic.py 2019-01-06 21:28:33.000000000 +0100 @@ -26,7 +26,7 @@ """ import pexpect import re - in_prompt = re.compile(b'In ?\[\\d+\]:') + in_prompt = re.compile(br'In ?\[\d+\]:') ipdb_prompt = 'ipdb>' env = os.environ.copy() child = pexpect.spawn(sys.executable, ['-m', 'IPython', '--colors=nocolor', '--simple-prompt'], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/testing/decorators.py new/ipython-7.3.0/IPython/testing/decorators.py --- old/ipython-7.2.0/IPython/testing/decorators.py 2018-11-03 22:32:57.000000000 +0100 +++ new/ipython-7.3.0/IPython/testing/decorators.py 2019-01-06 21:28:19.000000000 +0100 @@ -333,7 +333,7 @@ skipif_not_sympy = skip_without('sympy') -skip_known_failure = knownfailureif(True,'This test is known to fail') +skip_known_failure = dec.knownfailureif(True,'This test is known to fail') # A null 'decorator', useful to make more readable code that needs to pick # between different decorators based on OS or other conditions diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/testing/iptest.py new/ipython-7.3.0/IPython/testing/iptest.py --- old/ipython-7.2.0/IPython/testing/iptest.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/testing/iptest.py 2019-01-06 21:28:19.000000000 +0100 @@ -37,7 +37,7 @@ from IPython.utils.py3compat import decode from IPython.utils.importstring import import_item from IPython.testing.plugin.ipdoctest import IPythonDoctest -from IPython.external.decorators import KnownFailure, knownfailureif +from IPython.external.decorators import KnownFailure, dec pjoin = path.join @@ -83,7 +83,7 @@ # ------------------------------------------------------------------------------ def monkeypatch_xunit(): try: - knownfailureif(True)(lambda: None)() + dec.knownfailureif(True)(lambda: None)() except Exception as e: KnownFailureTest = type(e) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/testing/plugin/ipdoctest.py new/ipython-7.3.0/IPython/testing/plugin/ipdoctest.py --- old/ipython-7.2.0/IPython/testing/plugin/ipdoctest.py 2018-11-03 22:32:57.000000000 +0100 +++ new/ipython-7.3.0/IPython/testing/plugin/ipdoctest.py 2019-01-06 21:28:33.000000000 +0100 @@ -688,11 +688,8 @@ else: if self.extension and anyp(filename.endswith, self.extension): name = os.path.basename(filename) - dh = open(filename) - try: + with open(filename) as dh: doc = dh.read() - finally: - dh.close() test = self.parser.get_doctest( doc, globs={'__file__': filename}, name=name, filename=filename, lineno=0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/testing/tools.py new/ipython-7.3.0/IPython/testing/tools.py --- old/ipython-7.2.0/IPython/testing/tools.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/testing/tools.py 2019-01-06 21:28:33.000000000 +0100 @@ -422,8 +422,7 @@ def make_tempfile(name): """ Create an empty, named, temporary file for the duration of the context. """ - f = open(name, 'w') - f.close() + open(name, 'w').close() try: yield finally: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/utils/_sysinfo.py new/ipython-7.3.0/IPython/utils/_sysinfo.py --- old/ipython-7.2.0/IPython/utils/_sysinfo.py 2018-11-30 02:17:58.000000000 +0100 +++ new/ipython-7.3.0/IPython/utils/_sysinfo.py 2019-02-18 22:59:11.000000000 +0100 @@ -1,2 +1,2 @@ # GENERATED BY setup.py -commit = u"523ed2fe5" +commit = u"2e1cca5bc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/utils/tests/test_module_paths.py new/ipython-7.3.0/IPython/utils/tests/test_module_paths.py --- old/ipython-7.2.0/IPython/utils/tests/test_module_paths.py 2018-11-20 19:37:09.000000000 +0100 +++ new/ipython-7.3.0/IPython/utils/tests/test_module_paths.py 2019-01-06 21:28:33.000000000 +0100 @@ -37,8 +37,7 @@ old_syspath = sys.path def make_empty_file(fname): - f = open(fname, 'w') - f.close() + open(fname, 'w').close() def setup(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/IPython/utils/tests/test_openpy.py new/ipython-7.3.0/IPython/utils/tests/test_openpy.py --- old/ipython-7.2.0/IPython/utils/tests/test_openpy.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/IPython/utils/tests/test_openpy.py 2019-01-06 21:28:33.000000000 +0100 @@ -8,8 +8,8 @@ nonascii_path = os.path.join(mydir, '../../core/tests/nonascii.py') def test_detect_encoding(): - f = open(nonascii_path, 'rb') - enc, lines = openpy.detect_encoding(f.readline) + with open(nonascii_path, 'rb') as f: + enc, lines = openpy.detect_encoding(f.readline) nt.assert_equal(enc, 'iso-8859-5') def test_read_file(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/PKG-INFO new/ipython-7.3.0/PKG-INFO --- old/ipython-7.2.0/PKG-INFO 2018-11-30 02:17:58.000000000 +0100 +++ new/ipython-7.3.0/PKG-INFO 2019-02-18 22:59:11.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: ipython -Version: 7.2.0 +Version: 7.3.0 Summary: IPython: Productive Interactive Computing Home-page: https://ipython.org Author: The IPython Development Team diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/README.rst new/ipython-7.3.0/README.rst --- old/ipython-7.2.0/README.rst 2018-11-19 20:37:00.000000000 +0100 +++ new/ipython-7.3.0/README.rst 2019-01-06 21:28:19.000000000 +0100 @@ -87,7 +87,7 @@ For more information see one of our blog posts: - https://blog.jupyter.org/2016/07/08/ipython-5-0-released/ + https://blog.jupyter.org/release-of-ipython-5-0-8ce60b8d2e8e As well as the following Pull-Request for discussion: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/docs/source/coredev/index.rst new/ipython-7.3.0/docs/source/coredev/index.rst --- old/ipython-7.2.0/docs/source/coredev/index.rst 2018-11-30 02:17:33.000000000 +0100 +++ new/ipython-7.3.0/docs/source/coredev/index.rst 2019-02-18 22:58:52.000000000 +0100 @@ -215,20 +215,26 @@ Commit the changes to release.py:: - git commit -am "release $VERSION" + git commit -am "release $VERSION" -S git push origin $BRANCH +(omit the ``-S`` if you are no signing the package) + Create and push the tag:: - git tag -am "release $VERSION" "$VERSION" + git tag -am "release $VERSION" "$VERSION" -S git push origin $VERSION +(omit the ``-S`` if you are no signing the package) + Update release.py back to ``x.y-dev`` or ``x.y-maint``, and re-add the ``development`` entry in ``docs/source/whatsnew/index.rst`` and push:: - git commit -am "back to development" + git commit -am "back to development" -S git push origin $BRANCH +(omit the ``-S`` if you are no signing the package) + Now checkout the tag we just made:: git checkout $VERSION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/docs/source/interactive/shell.rst new/ipython-7.3.0/docs/source/interactive/shell.rst --- old/ipython-7.2.0/docs/source/interactive/shell.rst 2018-10-27 01:55:12.000000000 +0200 +++ new/ipython-7.3.0/docs/source/interactive/shell.rst 2019-02-18 22:35:17.000000000 +0100 @@ -186,13 +186,13 @@ Now we can just remove these files by doing 'rm $junk.s'. -The .s, .n, .p properties +The .n, .s, .p properties ------------------------- -The ``.s`` property returns one string where lines are separated by -single space (for convenient passing to system commands). The ``.n`` -property return one string where the lines are separated by a newline -(i.e. the original output of the function). If the items in string -list are file names, ``.p`` can be used to get a list of "path" objects -for convenient file manipulation. +Properties of `SList <https://ipython.readthedocs.io/en/stable/api/generated/IPython.utils.text.html?highlight=SList#IPython.utils.text.SList>`_ wrapper +provide a convenient ways to use contained text in different formats: +* ``.n`` returns (original) string with lines separated by a newline +* ``.s`` returns string with lines separated by single space (for + convenient passing to system commands) +* ``.p`` returns list of "path" objects from detected file names diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/docs/source/overview.rst new/ipython-7.3.0/docs/source/overview.rst --- old/ipython-7.2.0/docs/source/overview.rst 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/docs/source/overview.rst 2019-01-06 21:28:19.000000000 +0100 @@ -208,7 +208,7 @@ qtconsole``, and ``jupyter notebook``. As an example, this means that when you start ``jupyter qtconsole``, you're -really starting two processes, a kernel and a Qt-based client can send +really starting two processes, a kernel and a Qt-based client which can send commands to and receive results from that kernel. If there is already a kernel running that you want to connect to, you can pass the ``--existing`` flag which will skip initiating a new kernel and connect to the most recent kernel, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/docs/source/sphinxext.rst new/ipython-7.3.0/docs/source/sphinxext.rst --- old/ipython-7.2.0/docs/source/sphinxext.rst 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/docs/source/sphinxext.rst 2019-02-18 22:35:17.000000000 +0100 @@ -127,10 +127,10 @@ 1. Run the *input* lines in your IPython directive block against the current Python kernel (remember that the session persists across IPython directive blocks); -2. Compare the *output* of this with the output text that you've put in the IPython directive block 9what comes +2. Compare the *output* of this with the output text that you've put in the IPython directive block (what comes after `Out[NN]`); -3. If there is a difference, the directive will raise an error and your documentation build will fial. +3. If there is a difference, the directive will raise an error and your documentation build will fail. You can do doctesting on multi-line output as well. Just be careful when using non-deterministic inputs like random numbers in the ipython diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/docs/source/whatsnew/github-stats-7.rst new/ipython-7.3.0/docs/source/whatsnew/github-stats-7.rst --- old/ipython-7.2.0/docs/source/whatsnew/github-stats-7.rst 2018-11-30 02:11:33.000000000 +0100 +++ new/ipython-7.3.0/docs/source/whatsnew/github-stats-7.rst 2019-02-18 22:50:03.000000000 +0100 @@ -1,8 +1,39 @@ Issues closed in the 7.x development cycle ========================================== +Issues closed in 7.3 +-------------------- + +GitHub stats for 2018/11/30 - 2019/02/18 (tag: 7.2.0) + +These lists are automatically generated, and may be incomplete or contain duplicates. + +We closed 4 issues and merged 20 pull requests. +The full list can be seen `on GitHub <https://github.com/ipython/ipython/issues?q=milestone%3A7.3>`__ + +The following 17 authors contributed 99 commits. + +* anatoly techtonik +* Benjamin Ragan-Kelley +* Gabriel Potter +* Ian Bell +* Jake VanderPlas +* Jan S. (Milania1) +* Jesse Widner +* Kyungdahm Yun +* Laurent Gautier +* Matthias Bussonnier +* memeplex +* Mickaël Schoentgen +* Partha P. Mukherjee +* Philipp A +* Sanyam Agarwal +* Steve Nicholson +* Tony Fast + Issues closed in 7.2 -------------------- + GitHub stats for 2018/10/28 - 2018/11/29 (tag: 7.1.1) These lists are automatically generated, and may be incomplete or contain duplicates. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/docs/source/whatsnew/version7.rst new/ipython-7.3.0/docs/source/whatsnew/version7.rst --- old/ipython-7.2.0/docs/source/whatsnew/version7.rst 2018-11-30 02:03:56.000000000 +0100 +++ new/ipython-7.3.0/docs/source/whatsnew/version7.rst 2019-02-18 22:38:24.000000000 +0100 @@ -2,8 +2,36 @@ 7.x Series ============ +.. _whatsnew730: + +IPython 7.3.0 +============= + .. _whatsnew720: +IPython 7.3.0 bring several bug fixes and small improvements that you will +described bellow. + +The biggest change to this release is the implementation of the ``%conda`` and +``%pip`` magics, that will attempt to install packages in the **current +environment**. You may still need to restart your interpreter or kernel for the +change to be taken into account, but it should simplify installation of packages +into remote environment. Installing using pip/conda from the command line is +still the prefer method. + +The ``%pip`` magic was already present, but was only printing a warning; now it +will actually forward commands to pip. + +Misc bug fixes and improvements: + + - Compatibility with Python 3.8. + - Do not expand shell variable in execution magics, and added the + ``no_var_expand`` decorator for magic requiring a similar functionality + :ghpull:`11516` + - Add ``%pip`` and ``%conda`` magic :ghpull:`11524` + - Re-initialize posix aliases after a ``%reset`` :ghpull:`11528` + - Allow the IPython command line to run ``*.ipynb`` files :ghpull:`11529` + IPython 7.2.0 ============= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/docs/sphinxext/apigen.py new/ipython-7.3.0/docs/sphinxext/apigen.py --- old/ipython-7.2.0/docs/sphinxext/apigen.py 2018-11-03 22:32:57.000000000 +0100 +++ new/ipython-7.3.0/docs/sphinxext/apigen.py 2019-01-06 21:28:33.000000000 +0100 @@ -105,7 +105,7 @@ if *package_name* is ``sphinx``, then ``sphinx.util`` will result in ``.util`` being passed for earching by these regexps. If is None, gives default. Default is: - ['\.tests$'] + ['\\.tests$'] module_skip_patterns : None or sequence Sequence of strings giving URIs of modules to be excluded Operates on the module name including preceding URI path, @@ -113,7 +113,7 @@ ``sphinx.util.console`` results in the string to search of ``.util.console`` If is None, gives default. Default is: - ['\.setup$', '\._'] + ['\\.setup$', '\\._'] names_from__all__ : set, optional Modules listed in here will be scanned by doing ``from mod import *``, rather than finding function and class definitions by scanning the @@ -355,7 +355,7 @@ >>> mods = dw.discover_modules() >>> 'sphinx.util' in mods True - >>> dw.package_skip_patterns.append('\.util$') + >>> dw.package_skip_patterns.append('\\.util$') >>> 'sphinx.util' in dw.discover_modules() False >>> @@ -392,9 +392,8 @@ # write out to file outfile = os.path.join(outdir, m + self.rst_extension) - fileobj = open(outfile, 'wt') - fileobj.write(api_str) - fileobj.close() + with open(outfile, 'wt') as fileobj: + fileobj.write(api_str) written_modules.append(m) self.written_modules = written_modules @@ -445,11 +444,10 @@ relpath = outdir.replace(relative_to + os.path.sep, '') else: relpath = outdir - idx = open(path,'wt') - w = idx.write - w('.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n') - w('.. autosummary::\n' - ' :toctree: %s\n\n' % relpath) - for mod in self.written_modules: - w(' %s\n' % mod) - idx.close() + with open(path,'wt') as idx: + w = idx.write + w('.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n') + w('.. autosummary::\n' + ' :toctree: %s\n\n' % relpath) + for mod in self.written_modules: + w(' %s\n' % mod) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' "old/ipython-7.2.0/examples/IPython Kernel/Rich Output.ipynb" "new/ipython-7.3.0/examples/IPython Kernel/Rich Output.ipynb" --- "old/ipython-7.2.0/examples/IPython Kernel/Rich Output.ipynb" 2018-11-04 18:33:17.000000000 +0100 +++ "new/ipython-7.3.0/examples/IPython Kernel/Rich Output.ipynb" 2019-01-06 21:28:33.000000000 +0100 @@ -3023,7 +3023,8 @@ "source": [ "from IPython.display import HTML\n", "from base64 import b64encode\n", - "video = open(\"../images/animation.m4v\", \"rb\").read()\n", + "with open(\"../images/animation.m4v\", \"rb\") as f:\n", + " video = f.read()\n", "video_encoded = b64encode(video).decode('ascii')\n", "video_tag = '<video controls alt=\"test\" src=\"data:video/x-m4v;base64,{0}\">'.format(video_encoded)\n", "HTML(data=video_tag)" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' "old/ipython-7.2.0/examples/IPython Kernel/ipython-get-history.py" "new/ipython-7.3.0/examples/IPython Kernel/ipython-get-history.py" --- "old/ipython-7.2.0/examples/IPython Kernel/ipython-get-history.py" 2018-10-27 01:55:12.000000000 +0200 +++ "new/ipython-7.3.0/examples/IPython Kernel/ipython-get-history.py" 2019-01-06 21:28:33.000000000 +0100 @@ -27,11 +27,13 @@ else: dest = sys.stdout raw = True -dest.write("# coding: utf-8\n") -# Profiles other than 'default' can be specified here with a profile= argument: -hist = HistoryAccessor() +with dest: + dest.write("# coding: utf-8\n") -for session, lineno, cell in hist.get_range(session=session_number, raw=raw): - cell = cell.encode('utf-8') # This line is only needed on Python 2. - dest.write(cell + '\n') + # Profiles other than 'default' can be specified here with a profile= argument: + hist = HistoryAccessor() + + for session, lineno, cell in hist.get_range(session=session_number, raw=raw): + cell = cell.encode('utf-8') # This line is only needed on Python 2. + dest.write(cell + '\n') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipython-7.2.0/setupbase.py new/ipython-7.3.0/setupbase.py --- old/ipython-7.2.0/setupbase.py 2018-11-04 18:33:17.000000000 +0100 +++ new/ipython-7.3.0/setupbase.py 2019-01-06 21:28:33.000000000 +0100 @@ -270,7 +270,7 @@ # Write .cmd wrappers for Windows so 'ipython' etc. work at the # command line cmd_file = os.path.join(self.build_dir, name + '.cmd') - cmd = '@"{python}" "%~dp0\{script}" %*\r\n'.format( + cmd = r'@"{python}" "%~dp0\{script}" %*\r\n'.format( python=sys.executable, script=name) log.info("Writing %s wrapper script" % cmd_file) with open(cmd_file, 'w') as f: @@ -358,7 +358,7 @@ def run(self): # loose as `.dev` is suppose to be invalid print("check version number") - loose_pep440re = re.compile('^(\d+)\.(\d+)\.(\d+((a|b|rc)\d+)?)(\.post\d+)?(\.dev\d*)?$') + loose_pep440re = re.compile(r'^(\d+)\.(\d+)\.(\d+((a|b|rc)\d+)?)(\.post\d+)?(\.dev\d*)?$') if not loose_pep440re.match(version): raise ValueError("Version number '%s' is not valid (should match [N!]N(.N)*[{a|b|rc}N][.postN][.devN])" % version) ++++++ ipython.pdf ++++++ (binary differes) ++++++ ipython.zip ++++++ Binary files /var/tmp/diff_new_pack.OQ4G8y/_old and /var/tmp/diff_new_pack.OQ4G8y/_new differ