Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-spyder-kernels for 
openSUSE:Factory checked in at 2022-11-07 13:52:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-spyder-kernels (Old)
 and      /work/SRC/openSUSE:Factory/.python-spyder-kernels.new.1597 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-spyder-kernels"

Mon Nov  7 13:52:08 2022 rev:37 rq:1034141 version:2.4.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-spyder-kernels/python-spyder-kernels.changes  
    2022-09-04 22:12:04.392334803 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-spyder-kernels.new.1597/python-spyder-kernels.changes
    2022-11-07 13:52:14.691988207 +0100
@@ -1,0 +2,7 @@
+Sun Nov  6 15:08:20 UTC 2022 - Ben Greiner <c...@bnavigator.de>
+
+- Update to verison 2.4.0
+  * Add support for Python 3.11
+  * Flush standard streams after execution.
+
+-------------------------------------------------------------------

Old:
----
  python-spyder-kernels-2.3.3.tar.gz

New:
----
  python-spyder-kernels-2.4.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-spyder-kernels.spec ++++++
--- /var/tmp/diff_new_pack.POUVzs/_old  2022-11-07 13:52:15.195991041 +0100
+++ /var/tmp/diff_new_pack.POUVzs/_new  2022-11-07 13:52:15.199991063 +0100
@@ -16,12 +16,10 @@
 #
 
 
-%{?!python_module:%define python_module() python3-%{**}}
-%define skip_python2 1
 # flaky for obs, only test locally
 %bcond_with dasktest
 Name:           python-spyder-kernels
-Version:        2.3.3
+Version:        2.4.0
 Release:        0
 Summary:        Jupyter kernels for Spyder's console
 License:        MIT
@@ -29,15 +27,17 @@
 URL:            https://github.com/spyder-ide/spyder-kernels
 # PyPI tarballs do not include the tests: 
https://github.com/spyder-ide/spyder-kernels/issues/66
 Source:         %{url}/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
+BuildRequires:  %{python_module base >= 3.7}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 # SECTION test requirements
 BuildRequires:  %{python_module Cython}
+BuildRequires:  %{python_module Django}
 BuildRequires:  %{python_module Pillow}
 BuildRequires:  %{python_module cloudpickle}
 BuildRequires:  %{python_module flaky}
-BuildRequires:  %{python_module ipykernel >= 6.9.2 with %python-ipykernel < 7}
+BuildRequires:  %{python_module ipykernel >= 6.16.1 with %python-ipykernel < 7}
 BuildRequires:  %{python_module ipython >= 7.31.1}
 BuildRequires:  %{python_module jupyter_client >= 7.3.4 with 
%python-jupyter_client < 8}
 BuildRequires:  %{python_module matplotlib}
@@ -56,7 +56,7 @@
 Requires:       python-ipython >= 7.31.1
 Requires:       python-pyzmq >= 22.1
 Requires:       python-wurlitzer >= 1.0.3
-Requires:       (python-ipykernel >= 6.9.2 with python-ipykernel < 7)
+Requires:       (python-ipykernel >= 6.16.1 with python-ipykernel < 7)
 Requires:       (python-jupyter_client >= 7.3.4 with python-jupyter_client < 8)
 BuildArch:      noarch
 

++++++ python-spyder-kernels-2.3.3.tar.gz -> python-spyder-kernels-2.4.0.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.3.3/CHANGELOG.md 
new/spyder-kernels-2.4.0/CHANGELOG.md
--- old/spyder-kernels-2.3.3/CHANGELOG.md       2022-08-28 03:53:56.000000000 
+0200
+++ new/spyder-kernels-2.4.0/CHANGELOG.md       2022-11-03 01:06:16.000000000 
+0100
@@ -1,5 +1,29 @@
 # History of changes
 
+## Version 2.4.0 (2022-11-02)
+
+### New features
+
+* Add support for Python 3.11
+* Flush standard streams after execution.
+
+### Pull Requests Merged
+
+* [PR 428](https://github.com/spyder-ide/spyder-kernels/pull/428) - PR: Patch 
for CVE-2007-4559 Tar directory traversal, by 
[@ccordoba12](https://github.com/ccordoba12)
+* [PR 426](https://github.com/spyder-ide/spyder-kernels/pull/426) - PR: Update 
ipykernel constraint to >=6.16.1, by [@dalthviz](https://github.com/dalthviz)
+* [PR 423](https://github.com/spyder-ide/spyder-kernels/pull/423) - PR: Fix 
lineno range, by [@impact27](https://github.com/impact27) 
([19862](https://github.com/spyder-ide/spyder/issues/19862))
+* [PR 422](https://github.com/spyder-ide/spyder-kernels/pull/422) - PR: Make 
comm lock reentrant, by [@impact27](https://github.com/impact27)
+* [PR 420](https://github.com/spyder-ide/spyder-kernels/pull/420) - PR: Only 
access sys.stdout and sys.stderr once, by 
[@impact27](https://github.com/impact27)
+* [PR 416](https://github.com/spyder-ide/spyder-kernels/pull/416) - PR: Fix 
some errors when computing the namespace view, by 
[@ccordoba12](https://github.com/ccordoba12)
+* [PR 415](https://github.com/spyder-ide/spyder-kernels/pull/415) - PR: Fix tk 
eventloop handling when debugging on Windows, by 
[@dalthviz](https://github.com/dalthviz)
+* [PR 413](https://github.com/spyder-ide/spyder-kernels/pull/413) - PR: Flush 
standard streams after execution, by [@impact27](https://github.com/impact27)
+
+In this release 8 pull requests were closed.
+
+
+----
+
+
 ## Version 2.3.3 (2022-08-28)
 
 ### Issues Closed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.3.3/requirements/posix.txt 
new/spyder-kernels-2.4.0/requirements/posix.txt
--- old/spyder-kernels-2.3.3/requirements/posix.txt     2022-08-28 
03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/requirements/posix.txt     2022-11-03 
01:06:16.000000000 +0100
@@ -1,5 +1,5 @@
 cloudpickle
-ipykernel>=6.9.2,<7
+ipykernel>=6.16.1,<7
 ipython>=7.31.1,<8
 jupyter_client>=7.3.4,<8
 pyzmq>=22.1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.3.3/requirements/tests.txt 
new/spyder-kernels-2.4.0/requirements/tests.txt
--- old/spyder-kernels-2.3.3/requirements/tests.txt     2022-08-28 
03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/requirements/tests.txt     2022-11-03 
01:06:16.000000000 +0100
@@ -11,3 +11,4 @@
 scipy
 xarray
 pillow
+django
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.3.3/requirements/windows.txt 
new/spyder-kernels-2.4.0/requirements/windows.txt
--- old/spyder-kernels-2.3.3/requirements/windows.txt   2022-08-28 
03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/requirements/windows.txt   2022-11-03 
01:06:16.000000000 +0100
@@ -1,5 +1,5 @@
 cloudpickle
-ipykernel>=6.9.2,<7
+ipykernel>=6.16.1,<7
 ipython>=7.31.1,<8
 jupyter_client>=7.3.4,<8
 pyzmq>=22.1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.3.3/setup.py 
new/spyder-kernels-2.4.0/setup.py
--- old/spyder-kernels-2.3.3/setup.py   2022-08-28 03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/setup.py   2022-11-03 01:06:16.000000000 +0100
@@ -40,7 +40,7 @@
     'backports.functools-lru-cache; python_version<"3"',
     'cloudpickle',
     'ipykernel<5; python_version<"3"',
-    'ipykernel>=6.9.2,<7; python_version>="3"',
+    'ipykernel>=6.16.1,<7; python_version>="3"',
     'ipython<6; python_version<"3"',
     'ipython>=7.31.1,<8; python_version>="3"',
     'jupyter-client>=5.3.4,<6; python_version<"3"',
@@ -64,6 +64,7 @@
     'scipy',
     'xarray',
     'pillow',
+    'django',
 ]
 
 setup(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.3.3/spyder_kernels/_version.py 
new/spyder-kernels-2.4.0/spyder_kernels/_version.py
--- old/spyder-kernels-2.3.3/spyder_kernels/_version.py 2022-08-28 
03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/spyder_kernels/_version.py 2022-11-03 
01:06:16.000000000 +0100
@@ -8,5 +8,5 @@
 
 """Version File."""
 
-VERSION_INFO = (2, 3, 3)
+VERSION_INFO = (2, 4, 0)
 __version__ = '.'.join(map(str, VERSION_INFO))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.3.3/spyder_kernels/comms/frontendcomm.py 
new/spyder-kernels-2.4.0/spyder_kernels/comms/frontendcomm.py
--- old/spyder-kernels-2.3.3/spyder_kernels/comms/frontendcomm.py       
2022-08-28 03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/spyder_kernels/comms/frontendcomm.py       
2022-11-03 01:06:16.000000000 +0100
@@ -64,7 +64,7 @@
         self.register_call_handler('_send_comm_config',
                                    self._send_comm_config)
 
-        self.comm_lock = threading.Lock()
+        self.comm_lock = threading.RLock()
 
         # self.kernel.parent is IPKernelApp unless we are in tests
         if self.kernel.parent:
@@ -259,19 +259,22 @@
 
     def _remote_callback(self, call_name, call_args, call_kwargs):
         """Call the callback function for the remote call."""
-        saved_stdout_write = sys.stdout.write
-        saved_stderr_write = sys.stderr.write
-        thread_id = threading.get_ident()
-        sys.stdout.write = WriteWrapper(
-            saved_stdout_write, call_name, thread_id)
-        sys.stderr.write = WriteWrapper(
-            saved_stderr_write, call_name, thread_id)
-        try:
-            return super(FrontendComm, self)._remote_callback(
-                call_name, call_args, call_kwargs)
-        finally:
-            sys.stdout.write = saved_stdout_write
-            sys.stderr.write = saved_stderr_write
+        with self.comm_lock:
+            current_stdout = sys.stdout
+            current_stderr = sys.stderr
+            saved_stdout_write = current_stdout.write
+            saved_stderr_write = current_stderr.write
+            thread_id = threading.get_ident()
+            current_stdout.write = WriteWrapper(
+                saved_stdout_write, call_name, thread_id)
+            current_stderr.write = WriteWrapper(
+                saved_stderr_write, call_name, thread_id)
+            try:
+                return super(FrontendComm, self)._remote_callback(
+                    call_name, call_args, call_kwargs)
+            finally:
+                current_stdout.write = saved_stdout_write
+                current_stderr.write = saved_stderr_write
 
 
 class WriteWrapper(object):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.3.3/spyder_kernels/console/kernel.py 
new/spyder-kernels-2.4.0/spyder_kernels/console/kernel.py
--- old/spyder-kernels-2.3.3/spyder_kernels/console/kernel.py   2022-08-28 
03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/spyder_kernels/console/kernel.py   2022-11-03 
01:06:16.000000000 +0100
@@ -20,6 +20,7 @@
 # Third-party imports
 import ipykernel
 from ipykernel.ipkernel import IPythonKernel
+from ipykernel import eventloops
 from traitlets.config.loader import LazyConfigValue
 
 # Local imports
@@ -88,7 +89,6 @@
             'pdb_input_reply': self.pdb_input_reply,
             '_interrupt_eventloop': self._interrupt_eventloop,
             'enable_faulthandler': self.enable_faulthandler,
-            "flush_std": self.flush_std,
             }
         for call_id in handlers:
             self.frontend_comm.register_call_handler(
@@ -120,11 +120,6 @@
             callback=callback,
             timeout=timeout)
 
-    def flush_std(self):
-        """Flush C standard streams."""
-        sys.__stderr__.flush()
-        sys.__stdout__.flush()
-
     def enable_faulthandler(self, fn):
         """
         Open a file to save the faulthandling and identifiers for
@@ -210,9 +205,9 @@
             properties = {}
             for name, value in list(data.items()):
                 properties[name] = {
-                    'is_list':  isinstance(value, (tuple, list)),
-                    'is_dict':  isinstance(value, dict),
-                    'is_set': isinstance(value, set),
+                    'is_list':  self._is_list(value),
+                    'is_dict':  self._is_dict(value),
+                    'is_set': self._is_set(value),
                     'len': self._get_len(value),
                     'is_array': self._is_array(value),
                     'is_image': self._is_image(value),
@@ -404,48 +399,43 @@
         """
         # Mapping from frameworks to backend names.
         mapping = {
-            'qt': 'QtAgg',  # For Matplotlib 3.5+
-            'qt5': 'Qt5Agg',
+            'qt': 'QtAgg',
             'tk': 'TkAgg',
             'macosx': 'MacOSX'
         }
 
-        try:
-            # --- Get interactive framework
-            framework = None
+        # --- Get interactive framework
+        framework = None
 
-            # This is necessary because _get_running_interactive_framework
-            # can't detect Tk in a Jupyter kernel.
-            if hasattr(self, 'app_wrapper'):
-                if hasattr(self.app_wrapper, 'app'):
-                    import tkinter
-                    if isinstance(self.app_wrapper.app, tkinter.Tk):
-                        framework = 'tk'
-
-            if framework is None:
-                try:
-                    # This is necessary for Matplotlib 3.3.0+
-                    from matplotlib import cbook
-                    framework = cbook._get_running_interactive_framework()
-                except AttributeError:
-                    # For older versions
-                    from matplotlib import backends
-                    framework = backends._get_running_interactive_framework()
-
-            # --- Return backend according to framework
-            if framework is None:
-                # Since no interactive backend has been set yet, this is
-                # equivalent to having the inline one.
-                return 0
-            elif framework in mapping:
-                return MPL_BACKENDS_TO_SPYDER[mapping[framework]]
+        # Detect if there is a graphical framework running by checking the
+        # eventloop function attached to the kernel.eventloop attribute (see
+        # `ipykernel.eventloops.enable_gui` for context).
+        from IPython.core.getipython import get_ipython
+        loop_func = get_ipython().kernel.eventloop
+
+        if loop_func is not None:
+            if loop_func == eventloops.loop_tk:
+                framework = 'tk'
+            elif loop_func == eventloops.loop_qt5:
+                framework = 'qt'
+            elif loop_func == eventloops.loop_cocoa:
+                framework = 'macosx'
             else:
-                # This covers the case of other backends (e.g. Wx or Gtk)
-                # which users can set interactively with the %matplotlib
-                # magic but not through our Preferences.
-                return -1
-        except Exception:
-            return None
+                # Spyder doesn't handle other backends
+                framework = 'other'
+
+        # --- Return backend according to framework
+        if framework is None:
+            # Since no interactive backend has been set yet, this is
+            # equivalent to having the inline one.
+            return 0
+        elif framework in mapping:
+            return MPL_BACKENDS_TO_SPYDER[mapping[framework]]
+        else:
+            # This covers the case of other backends (e.g. Wx or Gtk)
+            # which users can set interactively with the %matplotlib
+            # magic but not through our Preferences.
+            return -1
 
     def set_matplotlib_backend(self, backend, pylab=False):
         """Set matplotlib backend given a Spyder backend option."""
@@ -668,6 +658,30 @@
         except:
             return False
 
+    def _is_list(self, var):
+        """Return True if variable is a list or tuple."""
+        # The try/except is necessary to fix spyder-ide/spyder#19516.
+        try:
+            return isinstance(var, (tuple, list))
+        except Exception:
+            return False
+
+    def _is_dict(self, var):
+        """Return True if variable is a dictionary."""
+        # The try/except is necessary to fix spyder-ide/spyder#19516.
+        try:
+            return isinstance(var, dict)
+        except Exception:
+            return False
+
+    def _is_set(self, var):
+        """Return True if variable is a set."""
+        # The try/except is necessary to fix spyder-ide/spyder#19516.
+        try:
+            return isinstance(var, set)
+        except Exception:
+            return False
+
     def _get_array_shape(self, var):
         """Return array's shape"""
         try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.3.3/spyder_kernels/console/shell.py 
new/spyder-kernels-2.4.0/spyder_kernels/console/shell.py
--- old/spyder-kernels-2.3.3/spyder_kernels/console/shell.py    2022-08-28 
03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/spyder_kernels/console/shell.py    2022-11-03 
01:06:16.000000000 +0100
@@ -26,6 +26,9 @@
         self._pdb_obj = None
         super(SpyderShell, self).__init__(*args, **kwargs)
 
+        # register post_execute
+        self.events.register('post_execute', self.do_post_execute)
+
     # ---- Methods overriden by us.
     def ask_exit(self):
         """Engage the exit actions."""
@@ -104,3 +107,9 @@
     def user_ns(self, namespace):
         """Set user_ns."""
         self.__user_ns = namespace
+
+    def do_post_execute(self):
+        """Flush __std*__ after execution."""
+        # Flush C standard streams.
+        sys.__stderr__.flush()
+        sys.__stdout__.flush()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.3.3/spyder_kernels/console/tests/test_console_kernel.py 
new/spyder-kernels-2.4.0/spyder_kernels/console/tests/test_console_kernel.py
--- 
old/spyder-kernels-2.3.3/spyder_kernels/console/tests/test_console_kernel.py    
    2022-08-28 03:53:56.000000000 +0200
+++ 
new/spyder-kernels-2.4.0/spyder_kernels/console/tests/test_console_kernel.py    
    2022-11-03 01:06:16.000000000 +0100
@@ -1181,5 +1181,37 @@
                     break
 
 
+def test_non_strings_in_locals(kernel):
+    """
+    Test that we can hande non-string entries in `locals` when bulding the
+    namespace view.
+
+    This is a regression test for issue spyder-ide/spyder#19145
+    """
+    if IPYKERNEL_6:
+        execute = asyncio.run(kernel.do_execute(
+            'locals().update({1:2})', True))
+    else:
+        execute = kernel.do_execute('locals().update({1:2})', True)
+
+    nsview = repr(kernel.get_namespace_view())
+    assert "1:" in nsview
+
+
+@pytest.mark.skipif(
+    sys.version_info[0] < 3, reason="Doesn't work with Python 2")
+def test_django_settings(kernel):
+    """
+    Test that we don't generate errors when importing `django.conf.settings`.
+
+    This is a regression test for issue spyder-ide/spyder#19516
+    """
+    execute = asyncio.run(kernel.do_execute(
+        'from django.conf import settings', True))
+
+    nsview = repr(kernel.get_namespace_view())
+    assert "'settings':" in nsview
+
+
 if __name__ == "__main__":
     pytest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.3.3/spyder_kernels/customize/spyderpdb.py 
new/spyder-kernels-2.4.0/spyder_kernels/customize/spyderpdb.py
--- old/spyder-kernels-2.3.3/spyder_kernels/customize/spyderpdb.py      
2022-08-28 03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/spyder_kernels/customize/spyderpdb.py      
2022-11-03 01:06:16.000000000 +0100
@@ -10,6 +10,7 @@
 import ast
 import bdb
 import logging
+import os
 import sys
 import traceback
 import threading
@@ -684,6 +685,8 @@
         # Flush output before making the request.
         sys.stderr.flush()
         sys.stdout.flush()
+        sys.__stderr__.flush()
+        sys.__stdout__.flush()
 
         # Send the input request.
         self._cmd_input_line = None
@@ -701,7 +704,13 @@
         if is_main_thread and kernel.eventloop:
             while self._cmd_input_line is None:
                 eventloop = kernel.eventloop
-                if eventloop:
+                # Check if the current backend is Tk on Windows
+                # to let GUI update.
+                # See spyder-ide/spyder#17523
+                if (eventloop and hasattr(kernel, "app_wrapper") and
+                        os.name == "nt"):
+                    kernel.app_wrapper.app.update()
+                elif eventloop:
                     eventloop(kernel)
                 else:
                     break
@@ -731,11 +740,10 @@
         return line
 
     def postcmd(self, stop, line):
-        """
-        Notify spyder about (possibly) changed frame
-
-        Note: The PDB commands ???up???, ???down??? and ???jump??? change the 
current frame.
-        """
+        """Hook method executed just after a command dispatch is finished."""
+        # Flush in case the command produced output on underlying outputs
+        sys.__stderr__.flush()
+        sys.__stdout__.flush()
         self.publish_pdb_state()
         return super(SpyderPdb, self).postcmd(stop, line)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.3.3/spyder_kernels/customize/utils.py 
new/spyder-kernels-2.4.0/spyder_kernels/customize/utils.py
--- old/spyder-kernels-2.3.3/spyder_kernels/customize/utils.py  2022-08-28 
03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/spyder_kernels/customize/utils.py  2022-11-03 
01:06:16.000000000 +0100
@@ -8,6 +8,7 @@
 import ast
 import os
 import re
+import sys
 import sysconfig
 
 
@@ -113,6 +114,14 @@
         # Fix line number and column offset
         assign_node.lineno = expr_node.lineno
         assign_node.col_offset = expr_node.col_offset
+        if sys.version_info[:2] >= (3, 8):
+            # Exists from 3.8, necessary from 3.11
+            assign_node.end_lineno = expr_node.end_lineno
+            if assign_node.lineno == assign_node.end_lineno:
+                # Add 'globals()[{}] = ' and remove 'None'
+                assign_node.end_col_offset += expr_node.end_col_offset - 4
+            else:
+                assign_node.end_col_offset = expr_node.end_col_offset
         code_ast.body[-1] = assign_node
     return code_ast, capture_last_expression
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.3.3/spyder_kernels/utils/iofuncs.py 
new/spyder-kernels-2.4.0/spyder_kernels/utils/iofuncs.py
--- old/spyder-kernels-2.3.3/spyder_kernels/utils/iofuncs.py    2022-08-28 
03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/spyder_kernels/utils/iofuncs.py    2022-11-03 
01:06:16.000000000 +0100
@@ -23,7 +23,6 @@
 import tempfile
 import shutil
 import types
-import warnings
 import json
 import inspect
 import dis
@@ -370,6 +369,27 @@
     return error_message
 
 
+def is_within_directory(directory, target):
+    """Check if a file is within a directory."""
+    abs_directory = os.path.abspath(directory)
+    abs_target = os.path.abspath(target)
+    prefix = os.path.commonprefix([abs_directory, abs_target])
+    return prefix == abs_directory
+
+
+def safe_extract(tar, path=".", members=None, numeric_owner=False):
+    """Safely extract a tar file."""
+    for member in tar.getmembers():
+        member_path = os.path.join(path, member.name)
+        if not is_within_directory(path, member_path):
+            raise Exception(
+                "Attempted path traversal in tar file {}".format(
+                    repr(tar.name)
+                )
+            )
+    tar.extractall(path, members, numeric_owner=numeric_owner)
+
+
 def load_dictionary(filename):
     """Load dictionary from .spydata file"""
     filename = osp.abspath(filename)
@@ -380,7 +400,11 @@
     error_message = None
     try:
         with tarfile.open(filename, "r") as tar:
-            tar.extractall()
+            if PY2:
+                tar.extractall()
+            else:
+                safe_extract(tar)
+
         pickle_filename = glob.glob('*.pickle')[0]
         # 'New' format (Spyder >=2.2 for Python 2 and Python 3)
         with open(pickle_filename, 'rb') as fdesc:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.3.3/spyder_kernels/utils/nsview.py 
new/spyder-kernels-2.4.0/spyder_kernels/utils/nsview.py
--- old/spyder-kernels-2.3.3/spyder_kernels/utils/nsview.py     2022-08-28 
03:53:56.000000000 +0200
+++ new/spyder-kernels-2.4.0/spyder_kernels/utils/nsview.py     2022-11-03 
01:06:16.000000000 +0100
@@ -36,16 +36,27 @@
 
 
 def get_numpy_dtype(obj):
-    """Return NumPy data type associated to obj
-    Return None if NumPy is not available
-    or if obj is not a NumPy array or scalar"""
+    """
+    Return Numpy data type associated to `obj`.
+
+    Return None if Numpy is not available, if we get errors or if `obj` is not
+    a Numpy array or scalar.
+    """
+    # Check if NumPy is available
     if np.ndarray is not FakeObject:
-        # NumPy is available
-        if isinstance(obj, np.generic) or isinstance(obj, np.ndarray):
-        # Numpy scalars all inherit from np.generic.
-        # Numpy arrays all inherit from np.ndarray.
-        # If we check that we are certain we have one of these
-        # types then we are less likely to generate an exception below.
+        # All Numpy scalars inherit from np.generic and all Numpy arrays
+        # inherit from np.ndarray. If we check that we are certain we have one
+        # of these types then we are less likely to generate an exception
+        # below.
+        # Note: The try/except is necessary to fix spyder-ide/spyder#19516.
+        try:
+            scalar_or_array = (
+                isinstance(obj, np.generic) or isinstance(obj, np.ndarray)
+            )
+        except Exception:
+            return
+
+        if scalar_or_array:
             try:
                 return obj.dtype.type
             except (AttributeError, RuntimeError):
@@ -499,21 +510,25 @@
 # =============================================================================
 def get_type_string(item):
     """Return type string of an object."""
-    # Numpy objects (don't change the order!)
-    if isinstance(item, np.ma.MaskedArray):
-        return "MaskedArray"
-    if isinstance(item, np.matrix):
-        return "Matrix"
-    if isinstance(item, np.ndarray):
-        return "NDArray"
-
-    # Pandas objects
-    if isinstance(item, pd.DataFrame):
-        return "DataFrame"
-    if isinstance(item, pd.Index):
-        return type(item).__name__
-    if isinstance(item, pd.Series):
-        return "Series"
+    # The try/except is necessary to fix spyder-ide/spyder#19516.
+    try:
+        # Numpy objects (don't change the order!)
+        if isinstance(item, np.ma.MaskedArray):
+            return "MaskedArray"
+        if isinstance(item, np.matrix):
+            return "Matrix"
+        if isinstance(item, np.ndarray):
+            return "NDArray"
+
+        # Pandas objects
+        if isinstance(item, pd.DataFrame):
+            return "DataFrame"
+        if isinstance(item, pd.Index):
+            return type(item).__name__
+        if isinstance(item, pd.Series):
+            return "Series"
+    except Exception:
+        pass
 
     found = re.findall(r"<(?:type|class) '(\S*)'>",
                        to_text_string(type(item)))
@@ -534,13 +549,17 @@
 
 def get_human_readable_type(item):
     """Return human-readable type string of an item"""
-    if isinstance(item, (np.ndarray, np.ma.MaskedArray)):
-        return u'Array of ' + item.dtype.name
-    elif isinstance(item, PIL.Image.Image):
-        return "Image"
-    else:
-        text = get_type_string(item)
-        return text[text.find('.')+1:]
+    # The try/except is necessary to fix spyder-ide/spyder#19516.
+    try:
+        if isinstance(item, (np.ndarray, np.ma.MaskedArray)):
+            return u'Array of ' + item.dtype.name
+        elif isinstance(item, PIL.Image.Image):
+            return "Image"
+        else:
+            text = get_type_string(item)
+            return text[text.find('.')+1:]
+    except Exception:
+        return 'Unknown'
 
 
 #==============================================================================
@@ -593,11 +612,13 @@
                   excluded_names=None, exclude_callables_and_modules=None):
     """Keep objects in namespace view according to different criteria."""
     output_dict = {}
+    _is_string = is_type_text_string
+
     for key, value in list(input_dict.items()):
         excluded = (
-            (exclude_private and key.startswith('_')) or
-            (exclude_capitalized and key[0].isupper()) or
-            (exclude_uppercase and key.isupper() and
+            (exclude_private and _is_string(key) and key.startswith('_')) or
+            (exclude_capitalized and _is_string(key) and key[0].isupper()) or
+            (exclude_uppercase and _is_string(key) and key.isupper() and
              len(key) > 1 and not key[1:].isdigit()) or
             (key in excluded_names) or
             (exclude_callables_and_modules and is_callable_or_module(value)) or

Reply via email to