diff --git a/external-deps/spyder-kernels/.gitrepo b/external-deps/spyder-kernels/.gitrepo index a9d8a35c668..6d721eed754 100644 --- a/external-deps/spyder-kernels/.gitrepo +++ b/external-deps/spyder-kernels/.gitrepo @@ -4,9 +4,9 @@ ; git-subrepo command. See https://github.com/ingydotnet/git-subrepo#readme ; [subrepo] - remote = https://github.com/spyder-ide/spyder-kernels.git - branch = master - commit = d0b6a86831cf2ed8349b8b19d749530019492fb6 - parent = 3a5a0fbaabd3273d111e288f5ecf51c72bbc5e93 + remote = /Users/rclary/Documents/Repos/Spyder-IDE/spyder-kernels + branch = ppm-syspath + commit = 9bf65f9165102454b184236e4ae336768af9e402 + parent = 4176945fccffefa8d5588e6edf6893a0cfebdcf6 method = merge - cmdver = 0.4.3 + cmdver = 0.4.6 diff --git a/external-deps/spyder-kernels/spyder_kernels/console/kernel.py b/external-deps/spyder-kernels/spyder_kernels/console/kernel.py index 56902ee10f2..637d84fc493 100644 --- a/external-deps/spyder-kernels/spyder_kernels/console/kernel.py +++ b/external-deps/spyder-kernels/spyder_kernels/console/kernel.py @@ -595,7 +595,6 @@ def set_matplotlib_conf(self, conf): if bbox_inches_n in conf: self.set_mpl_inline_bbox_inches(conf[bbox_inches_n]) - def set_mpl_inline_bbox_inches(self, bbox_inches): """ Set inline print figure bbox inches. @@ -721,13 +720,13 @@ def set_special_kernel(self, special): return if special == "pylab": - import matplotlib + import matplotlib # noqa exec("from pylab import *", self.shell.user_ns) self.shell.special = special return - + if special == "sympy": - import sympy + import sympy # noqa sympy_init = "\n".join([ "from sympy import *", "x, y, z, t = symbols('x y z t')", @@ -740,7 +739,7 @@ def set_special_kernel(self, special): return if special == "cython": - import cython + import cython # noqa # Import pyximport to enable Cython files support for # import statement @@ -765,26 +764,33 @@ def set_special_kernel(self, special): raise NotImplementedError(f"{special}") @comm_handler - def update_syspath(self, path_dict, new_path_dict): + def update_syspath(self, old_path, new_path, prioritize): """ Update the PYTHONPATH of the kernel. - `path_dict` and `new_path_dict` have the paths as keys and the state - as values. The state is `True` for active and `False` for inactive. - - `path_dict` corresponds to the previous state of the PYTHONPATH. - `new_path_dict` corresponds to the new state of the PYTHONPATH. + `old_path` corresponds to the previous state of the PYTHONPATH. + `new_path` corresponds to the new state of the PYTHONPATH. + `prioritize` determines whether to prioritize PYTHONPATH in sys.path. """ # Remove old paths - for path in path_dict: + for path in old_path: while path in sys.path: sys.path.remove(path) # Add new paths - pypath = [path for path, active in new_path_dict.items() if active] - if pypath: - sys.path.extend(pypath) - os.environ.update({'PYTHONPATH': os.pathsep.join(pypath)}) + if new_path: + os.environ.update({'PYTHONPATH': os.pathsep.join(new_path)}) + + if prioritize: + new_path.reverse() + [sys.path.insert(0, path) for path in new_path] + + # Ensure current directory is always first + if '' in sys.path: + sys.path.remove('') + sys.path.insert(0, '') + else: + sys.path.extend(new_path) else: os.environ.pop('PYTHONPATH', None) @@ -907,9 +913,9 @@ def _set_mpl_backend(self, backend, pylab=False): return generic_error = ( - "\n" + "="*73 + "\n" + "\n" + "=" * 73 + "\n" "NOTE: The following error appeared when setting " - "your Matplotlib backend!!\n" + "="*73 + "\n\n" + "your Matplotlib backend!!\n" + "=" * 73 + "\n\n" "{0}" ) @@ -931,7 +937,7 @@ def _set_mpl_backend(self, backend, pylab=False): # trying to set a backend. See issue 5541 if "GUI eventloops" in str(err): previous_backend = matplotlib.get_backend() - if not backend in previous_backend.lower(): + if backend not in previous_backend.lower(): # Only inform about an error if the user selected backend # and the one set by Matplotlib are different. Else this # message is very confusing. diff --git a/external-deps/spyder-kernels/spyder_kernels/console/tests/test_console_kernel.py b/external-deps/spyder-kernels/spyder_kernels/console/tests/test_console_kernel.py index a9564febed3..74e4d6c6c12 100644 --- a/external-deps/spyder-kernels/spyder_kernels/console/tests/test_console_kernel.py +++ b/external-deps/spyder-kernels/spyder_kernels/console/tests/test_console_kernel.py @@ -75,13 +75,15 @@ def setup_kernel(cmd): ) # wait for connection file to exist, timeout after 5s tic = time.time() - while not os.path.exists(connection_file) \ - and kernel.poll() is None \ - and time.time() < tic + SETUP_TIMEOUT: + while ( + not os.path.exists(connection_file) + and kernel.poll() is None + and time.time() < tic + SETUP_TIMEOUT + ): time.sleep(0.1) if kernel.poll() is not None: - o,e = kernel.communicate() + o, e = kernel.communicate() raise IOError("Kernel failed to start:\n%s" % e) if not os.path.exists(connection_file): @@ -227,7 +229,7 @@ def kernel(request): 'True_' ], 'minmax': False, - 'filter_on':True + 'filter_on': True } # Teardown @@ -277,7 +279,7 @@ def test_get_namespace_view(kernel): """ Test the namespace view of the kernel. """ - execute = asyncio.run(kernel.do_execute('a = 1', True)) + asyncio.run(kernel.do_execute('a = 1', True)) nsview = repr(kernel.get_namespace_view()) assert "'a':" in nsview @@ -293,7 +295,7 @@ def test_get_namespace_view_filter_on(kernel, filter_on): """ Test the namespace view of the kernel with filters on and off. """ - execute = asyncio.run(kernel.do_execute('a = 1', True)) + asyncio.run(kernel.do_execute('a = 1', True)) asyncio.run(kernel.do_execute('TestFilterOff = 1', True)) settings = kernel.namespace_view_settings @@ -469,6 +471,7 @@ def test_get_doc(kernel): assert ("Define the builtin 'help'" in kernel.get_doc(objtxt)['docstring'] or "Define the built-in 'help'" in kernel.get_doc(objtxt)['docstring']) + def test_get_source(kernel): """Test to get object source.""" objtxt = 'help' @@ -505,7 +508,7 @@ def test_cwd_in_sys_path(): with setup_kernel(cmd) as client: reply = client.execute_interactive( "import sys; sys_path = sys.path", - user_expressions={'output':'sys_path'}, timeout=TIMEOUT) + user_expressions={'output': 'sys_path'}, timeout=TIMEOUT) # Transform value obtained through user_expressions user_expressions = reply['content']['user_expressions'] @@ -516,6 +519,21 @@ def test_cwd_in_sys_path(): assert '' in value +def test_prioritize(kernel): + """Test that user path priority is honored in sys.path.""" + syspath = kernel.get_syspath() + append_path = ['/test/append/path'] + prepend_path = ['/test/prepend/path'] + + kernel.update_syspath([], append_path, prioritize=False) + new_syspath = kernel.get_syspath() + assert new_syspath == syspath + append_path + + kernel.update_syspath(append_path, prepend_path, prioritize=True) + new_syspath = kernel.get_syspath() + assert new_syspath == prepend_path + syspath + + @flaky(max_runs=3) def test_multiprocessing(tmpdir): """ @@ -699,8 +717,10 @@ def test_runfile(tmpdir): assert content['found'] # Run code file `u` with current namespace - msg = client.execute_interactive("%runfile {} --current-namespace" - .format(repr(str(u))), timeout=TIMEOUT) + msg = client.execute_interactive( + "%runfile {} --current-namespace".format(repr(str(u))), + timeout=TIMEOUT + ) content = msg['content'] # Verify that the variable `result3` is defined @@ -950,11 +970,12 @@ def test_comprehensions_with_locals_in_pdb(kernel): # Check that the variable is not reported as being part of globals. kernel.shell.pdb_session.default("in_globals = 'zz' in globals()") - assert kernel.get_value('in_globals') == False + assert kernel.get_value('in_globals') is False pdb_obj.curframe = None pdb_obj.curframe_locals = None + def test_comprehensions_with_locals_in_pdb_2(kernel): """ Test that evaluating comprehensions with locals works in Pdb. @@ -985,7 +1006,7 @@ def test_namespaces_in_pdb(kernel): Test namespaces in pdb """ # Define get_ipython for timeit - get_ipython = lambda: kernel.shell + get_ipython = lambda: kernel.shell # noqa kernel.shell.user_ns["test"] = 0 pdb_obj = SpyderPdb() pdb_obj.curframe = inspect.currentframe() @@ -999,6 +1020,7 @@ def test_namespaces_in_pdb(kernel): # Create wrapper to check for errors old_error = pdb_obj.error pdb_obj._error_occured = False + def error_wrapper(*args, **kwargs): print(args, kwargs) pdb_obj._error_occured = True @@ -1050,7 +1072,6 @@ def test_functions_with_locals_in_pdb(kernel): 'zz = fun_a()') assert kernel.get_value('zz') == 1 - pdb_obj.curframe = None pdb_obj.curframe_locals = None @@ -1061,7 +1082,7 @@ def test_functions_with_locals_in_pdb_2(kernel): This is another regression test for spyder-ide/spyder-kernels#345 """ - baba = 1 + baba = 1 # noqa pdb_obj = SpyderPdb() pdb_obj.curframe = inspect.currentframe() pdb_obj.curframe_locals = pdb_obj.curframe.f_locals @@ -1098,7 +1119,7 @@ def test_locals_globals_in_pdb(kernel): """ Test thal locals and globals work properly in Pdb. """ - a = 1 + a = 1 # noqa pdb_obj = SpyderPdb() pdb_obj.curframe = inspect.currentframe() pdb_obj.curframe_locals = pdb_obj.curframe.f_locals @@ -1108,11 +1129,11 @@ def test_locals_globals_in_pdb(kernel): kernel.shell.pdb_session.default( 'test = "a" in globals()') - assert kernel.get_value('test') == False + assert kernel.get_value('test') is False kernel.shell.pdb_session.default( 'test = "a" in locals()') - assert kernel.get_value('test') == True + assert kernel.get_value('test') is True kernel.shell.pdb_session.default( 'def f(): return a') @@ -1126,11 +1147,11 @@ def test_locals_globals_in_pdb(kernel): kernel.shell.pdb_session.default( 'test = "a" in globals()') - assert kernel.get_value('test') == False + assert kernel.get_value('test') is False kernel.shell.pdb_session.default( 'test = "a" in locals()') - assert kernel.get_value('test') == True + assert kernel.get_value('test') is True pdb_obj.curframe = None pdb_obj.curframe_locals = None @@ -1205,7 +1226,7 @@ def test_global_message(tmpdir): def check_found(msg): if "text" in msg["content"]: - if ("WARNING: This file contains a global statement" in + if ("WARNING: This file contains a global statement" in msg["content"]["text"]): global found found = True @@ -1237,7 +1258,7 @@ def test_debug_namespace(tmpdir): d.write('def func():\n bb = "hello"\n breakpoint()\nfunc()') # Run code file `d` - msg_id = client.execute("%runfile {}".format(repr(str(d)))) + client.execute("%runfile {}".format(repr(str(d)))) # make sure that 'bb' returns 'hello' client.get_stdin_msg(timeout=TIMEOUT) @@ -1251,7 +1272,7 @@ def test_debug_namespace(tmpdir): if 'hello' in msg["content"].get("text"): break - # make sure that get_value('bb') returns 'hello' + # make sure that get_value('bb') returns 'hello' client.get_stdin_msg(timeout=TIMEOUT) client.input("get_ipython().kernel.get_value('bb')") @@ -1370,7 +1391,7 @@ def test_non_strings_in_locals(kernel): This is a regression test for issue spyder-ide/spyder#19145 """ - execute = asyncio.run(kernel.do_execute('locals().update({1:2})', True)) + asyncio.run(kernel.do_execute('locals().update({1:2})', True)) nsview = repr(kernel.get_namespace_view()) assert "1:" in nsview @@ -1382,8 +1403,7 @@ def test_django_settings(kernel): This is a regression test for issue spyder-ide/spyder#19516 """ - execute = asyncio.run(kernel.do_execute( - 'from django.conf import settings', True)) + asyncio.run(kernel.do_execute('from django.conf import settings', True)) nsview = repr(kernel.get_namespace_view()) assert "'settings':" in nsview diff --git a/external-deps/spyder-kernels/spyder_kernels/customize/spydercustomize.py b/external-deps/spyder-kernels/spyder_kernels/customize/spydercustomize.py index 99c2089890f..9edf888898d 100644 --- a/external-deps/spyder-kernels/spyder_kernels/customize/spydercustomize.py +++ b/external-deps/spyder-kernels/spyder_kernels/customize/spydercustomize.py @@ -11,7 +11,6 @@ # Spyder consoles sitecustomize # -import logging import os import pdb import sys @@ -252,17 +251,3 @@ def _patched_get_terminal_size(fd=None): # Pdb adjustments # ============================================================================= pdb.Pdb = SpyderPdb - -# ============================================================================= -# PYTHONPATH and sys.path Adjustments -# ============================================================================= -# PYTHONPATH is not passed to kernel directly, see spyder-ide/spyder#13519 -# This allows the kernel to start without crashing if modules in PYTHONPATH -# shadow standard library modules. -def set_spyder_pythonpath(): - pypath = os.environ.get('SPY_PYTHONPATH') - if pypath: - sys.path.extend(pypath.split(os.pathsep)) - os.environ.update({'PYTHONPATH': pypath}) - -set_spyder_pythonpath()