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-01-22 08:18:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-spyder-kernels (Old)
 and      /work/SRC/openSUSE:Factory/.python-spyder-kernels.new.1938 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-spyder-kernels"

Sat Jan 22 08:18:38 2022 rev:32 rq:948029 version:2.2.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-spyder-kernels/python-spyder-kernels.changes  
    2022-01-11 21:23:58.377157319 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-spyder-kernels.new.1938/python-spyder-kernels.changes
    2022-01-22 08:19:31.554361259 +0100
@@ -1,0 +2,30 @@
+Fri Jan 21 19:34:25 UTC 2022 - Ben Greiner <[email protected]>
+
+- Update to version 2.2.1
+  * Improve error message when setting a Matplotlib backend whose
+    module is not present, by @ccordoba12 (347)
+  * Filter another benign message coming from comm handlers, by
+    @ccordoba12 (365)
+  * Catch error when validating if an object is defined in the
+    namespace, by @ccordoba12
+  * Fix error when running multiprocessing code that contains
+    classes, by @impact27
+  * Catch KeyError when closing comm, by @ccordoba12
+  * Increase minimal required version of pyzmq for Python 3, by
+    @ccordoba12
+  * Increase minimal required version of ipykernel to 6.6.1, by
+    @ccordoba12
+  * Require jupyter-client 7.1.0 to fix issues on Windows, by
+    @ccordoba12
+  * Increase minimal required version of jupyter-client to 7.0+ for
+    Python 3, by @ccordoba12
+  * Implement a less hacky solution to fix namespace issues, by
+    @impact27
+  * More namespace fixes, by @impact27
+  * Don't print DeprecationWarning's that come from comm handlers,
+    by @ccordoba12 (343)
+  * Update Quansight logo in Readme, by @ccordoba12
+  * Fix some namespace issues, by @impact27 (345)
+  * Fix misplaced section in changelog, by @ccordoba12 
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ python-spyder-kernels.spec ++++++
--- /var/tmp/diff_new_pack.ooOPwj/_old  2022-01-22 08:19:32.086357675 +0100
+++ /var/tmp/diff_new_pack.ooOPwj/_new  2022-01-22 08:19:32.090357647 +0100
@@ -16,11 +16,12 @@
 #
 
 
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%{?!python_module:%define python_module() python3-%{**}}
 %define skip_python2 1
-%define skip_python36 1
+# flaky for obs, only test locally
+%bcond_with dasktest
 Name:           python-spyder-kernels
-Version:        2.2.0
+Version:        2.2.1
 Release:        0
 Summary:        Jupyter kernels for Spyder's console
 License:        MIT
@@ -35,25 +36,27 @@
 BuildRequires:  %{python_module Cython}
 BuildRequires:  %{python_module Pillow}
 BuildRequires:  %{python_module cloudpickle}
-BuildRequires:  %{python_module dask-distributed}
 BuildRequires:  %{python_module flaky}
-BuildRequires:  %{python_module ipykernel >= 5.3.0}
+BuildRequires:  %{python_module ipykernel >= 6.6.1}
 BuildRequires:  %{python_module ipython >= 7.6.0}
-BuildRequires:  %{python_module jupyter_client >= 5.3.4}
+BuildRequires:  %{python_module jupyter_client >= 7.1.0}
 BuildRequires:  %{python_module matplotlib}
 BuildRequires:  %{python_module numpy}
 BuildRequires:  %{python_module pandas}
 BuildRequires:  %{python_module pytest}
-BuildRequires:  %{python_module pyzmq >= 17}
+BuildRequires:  %{python_module pyzmq >= 22.1}
 BuildRequires:  %{python_module scipy}
 BuildRequires:  %{python_module wurlitzer >= 1.0.3}
 BuildRequires:  %{python_module xarray}
+%if %{with dasktest}
+BuildRequires:  %{python_module dask-distributed}
+%endif
 # /SECTION
 Requires:       python-cloudpickle
-Requires:       python-ipykernel >= 5.3.0
+Requires:       python-ipykernel >= 6.6.1
 Requires:       python-ipython >= 7.6.0
-Requires:       python-jupyter_client >= 5.3.4
-Requires:       python-pyzmq >= 17
+Requires:       python-jupyter_client >= 7.1.0
+Requires:       python-pyzmq >= 22.1
 Requires:       python-wurlitzer >= 1.0.3
 BuildArch:      noarch
 
@@ -71,6 +74,7 @@
 
 %prep
 %autosetup -p1 -n spyder-kernels-%{version}
+sed -i -e '/ipython/ s/,<8;/;/' setup.py
 
 %build
 %python_build
@@ -80,16 +84,10 @@
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
-# flaky for obs
-donttest="test_dask_multiprocessing"
-# these fail server-side but not when testing with osc build
-donttest+=" or (test_console_kernel and test_cwd_in_sys_path)"
-donttest+=" or (test_console_kernel and test_multiprocessing)"
-donttest+=" or (test_console_kernel and test_runfile)"
-donttest+=" or (test_console_kernel and test_np_threshold)"
-donttest+=" or (test_console_kernel and test_matplotlib_inline)"
-
-%pytest -k "not (${donttest})" -ra
+%if ! %{with dasktest}
+donttest=("-k" "not test_dask_multiprocessing")
+%endif
+%pytest "${donttest[@]}"
 
 %files %{python_files}
 %doc CHANGELOG.md README.md

++++++ python-spyder-kernels-2.2.0.tar.gz -> python-spyder-kernels-2.2.1.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/.github/workflows/linux-pip-tests.yml 
new/spyder-kernels-2.2.1/.github/workflows/linux-pip-tests.yml
--- old/spyder-kernels-2.2.0/.github/workflows/linux-pip-tests.yml      
2021-11-23 00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/.github/workflows/linux-pip-tests.yml      
2022-01-13 16:55:24.000000000 +0100
@@ -46,7 +46,7 @@
           conda list
       - name: Run tests
         shell: bash -l {0}
-        run: xvfb-run --auto-servernum pytest spyder_kernels 
--cov=spyder_kernels -x -vv
+        run: xvfb-run --auto-servernum pytest spyder_kernels 
--cov=spyder_kernels -x -vv || xvfb-run --auto-servernum pytest spyder_kernels 
--cov=spyder_kernels -x -vv || xvfb-run --auto-servernum pytest spyder_kernels 
--cov=spyder_kernels -x -vv
       - name: Upload coverage to Codecov
         if: matrix.PYTHON_VERSION == '3.8'
         shell: bash -l {0}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/.github/workflows/linux-tests.yml 
new/spyder-kernels-2.2.1/.github/workflows/linux-tests.yml
--- old/spyder-kernels-2.2.0/.github/workflows/linux-tests.yml  2021-11-23 
00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/.github/workflows/linux-tests.yml  2022-01-13 
16:55:24.000000000 +0100
@@ -22,6 +22,7 @@
       fail-fast: false 
       matrix:
         PYTHON_VERSION: ['2.7', '3.7', '3.8', '3.9']
+    timeout-minutes: 10
     steps:
       - name: Checkout branch
         uses: actions/checkout@v1
@@ -35,17 +36,16 @@
            activate-environment: test
            auto-update-conda: true
            auto-activate-base: false
+           channels: conda-forge
+           miniforge-variant: Mambaforge
            python-version: ${{ matrix.PYTHON_VERSION }} 
       - name: Install package dependencies
         shell: bash -l {0}
         run: |
-          conda install --file requirements/posix.txt -y -q
-          if [ "$PYTHON_VERSION" = "2.7" ]; then conda install --file 
requirements/python-27.txt -y -q; fi
+          if [ "$PYTHON_VERSION" != "2.7" ]; then mamba install --file 
requirements/posix.txt -y -q; else mamba install --file 
requirements/python-27.txt -y -q; fi
       - name: Install test dependencies
         shell: bash -l {0}
-        run: |
-          conda install nomkl -y -q
-          conda install --file requirements/tests.txt -y -q
+        run: mamba install --file requirements/tests.txt -y -q
       - name: Install Package
         shell: bash -l {0}
         run: pip install -e .
@@ -56,7 +56,7 @@
           conda list
       - name: Run tests
         shell: bash -l {0}
-        run: xvfb-run --auto-servernum pytest spyder_kernels 
--cov=spyder_kernels -x -vv
+        run: xvfb-run --auto-servernum pytest spyder_kernels 
--cov=spyder_kernels -x -vv || xvfb-run --auto-servernum pytest spyder_kernels 
--cov=spyder_kernels -x -vv || xvfb-run --auto-servernum pytest spyder_kernels 
--cov=spyder_kernels -x -vv
       - name: Upload coverage to Codecov
         if: matrix.PYTHON_VERSION == '3.8'
         shell: bash -l {0}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/.github/workflows/macos-tests.yml 
new/spyder-kernels-2.2.1/.github/workflows/macos-tests.yml
--- old/spyder-kernels-2.2.0/.github/workflows/macos-tests.yml  2021-11-23 
00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/.github/workflows/macos-tests.yml  2022-01-13 
16:55:24.000000000 +0100
@@ -22,6 +22,7 @@
       fail-fast: false 
       matrix:
         PYTHON_VERSION: ['2.7', '3.7', '3.8', '3.9']
+    timeout-minutes: 10
     steps:
       - name: Checkout branch
         uses: actions/checkout@v1
@@ -31,17 +32,16 @@
            activate-environment: test
            auto-update-conda: true
            auto-activate-base: false
+           channels: conda-forge
+           miniforge-variant: Mambaforge
            python-version: ${{ matrix.PYTHON_VERSION }} 
       - name: Install package dependencies
         shell: bash -l {0}
         run: |
-          conda install --file requirements/posix.txt -y -q
-          if [ "$PYTHON_VERSION" = "2.7" ]; then conda install --file 
requirements/python-27.txt -y -q; fi
+          if [ "$PYTHON_VERSION" != "2.7" ]; then mamba install --file 
requirements/posix.txt -y -q; else mamba install --file 
requirements/python-27.txt -y -q; fi
       - name: Install test dependencies
         shell: bash -l {0}
-        run: |
-          conda install nomkl -y -q
-          conda install --file requirements/tests.txt -y -q
+        run: mamba install --file requirements/tests.txt -y -q
       - name: Install Package
         shell: bash -l {0}
         run: pip install -e .
@@ -52,4 +52,4 @@
           conda list
       - name: Run tests
         shell: bash -l {0}
-        run: pytest spyder_kernels --cov=spyder_kernels -x -vv
+        run: pytest spyder_kernels --cov=spyder_kernels -x -vv || pytest 
spyder_kernels --cov=spyder_kernels -x -vv || pytest spyder_kernels 
--cov=spyder_kernels -x -vv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/.github/workflows/windows-tests.yml 
new/spyder-kernels-2.2.1/.github/workflows/windows-tests.yml
--- old/spyder-kernels-2.2.0/.github/workflows/windows-tests.yml        
2021-11-23 00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/.github/workflows/windows-tests.yml        
2022-01-13 16:55:24.000000000 +0100
@@ -22,6 +22,7 @@
       fail-fast: false 
       matrix:
         PYTHON_VERSION: ['3.7', '3.8', '3.9']
+    timeout-minutes: 25
     steps:
       - name: Checkout branch
         uses: actions/checkout@v1
@@ -31,14 +32,16 @@
            activate-environment: test
            auto-update-conda: true
            auto-activate-base: false
+           channels: conda-forge
+           miniforge-variant: Mambaforge
            python-version: ${{ matrix.PYTHON_VERSION }}
       - name: Install package dependencies
         shell: bash -l {0}
-        run: conda install --file requirements/windows.txt -y -q
+        run: mamba install --file requirements/windows.txt -y -q
       - name: Install test dependencies
         shell: bash -l {0}
         run: |
-          conda install --file requirements/tests.txt -y -q
+          mamba install --file requirements/tests.txt -y -q
       - name: Install Package
         shell: bash -l {0}
         run: pip install -e .
@@ -53,4 +56,4 @@
         run: echo "::set-env name=PYTHONIOENCODING::cp1252"
       - name: Run tests
         shell: bash -l {0}
-        run: pytest spyder_kernels --cov=spyder_kernels -x -vv
+        run: pytest spyder_kernels --cov=spyder_kernels -x -vv || pytest 
spyder_kernels --cov=spyder_kernels -x -vv || pytest spyder_kernels 
--cov=spyder_kernels -x -vv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.2.0/CHANGELOG.md 
new/spyder-kernels-2.2.1/CHANGELOG.md
--- old/spyder-kernels-2.2.0/CHANGELOG.md       2021-11-23 00:19:57.000000000 
+0100
+++ new/spyder-kernels-2.2.1/CHANGELOG.md       2022-01-13 16:55:24.000000000 
+0100
@@ -1,13 +1,49 @@
 # History of changes
 
+## Version 2.2.1 (2022-01-13)
+
+### Issues Closed
+
+* [Issue 365](https://github.com/spyder-ide/spyder-kernels/issues/365) - 
`IOStream.flush timed out` message shown after every evaluation ([PR 
367](https://github.com/spyder-ide/spyder-kernels/pull/367) by 
[@ccordoba12](https://github.com/ccordoba12))
+* [Issue 347](https://github.com/spyder-ide/spyder-kernels/issues/347) - 
Issues handling Matplotlib backend settings ([PR 
368](https://github.com/spyder-ide/spyder-kernels/pull/368) by 
[@ccordoba12](https://github.com/ccordoba12))
+* [Issue 345](https://github.com/spyder-ide/spyder-kernels/issues/345) - 
Namespace issues ([PR 
346](https://github.com/spyder-ide/spyder-kernels/pull/346) by 
[@impact27](https://github.com/impact27))
+* [Issue 343](https://github.com/spyder-ide/spyder-kernels/issues/343) - 
Shapely 1.8 and get_namespace_view spyder call raising deprecation warning ([PR 
350](https://github.com/spyder-ide/spyder-kernels/pull/350) by 
[@ccordoba12](https://github.com/ccordoba12))
+
+In this release 4 issues were closed.
+
+### Pull Requests Merged
+
+* [PR 368](https://github.com/spyder-ide/spyder-kernels/pull/368) - PR: 
Improve error message when setting a Matplotlib backend whose module is not 
present, by [@ccordoba12](https://github.com/ccordoba12) 
([347](https://github.com/spyder-ide/spyder-kernels/issues/347))
+* [PR 367](https://github.com/spyder-ide/spyder-kernels/pull/367) - PR: Filter 
another benign message coming from comm handlers, by 
[@ccordoba12](https://github.com/ccordoba12) 
([365](https://github.com/spyder-ide/spyder-kernels/issues/365))
+* [PR 364](https://github.com/spyder-ide/spyder-kernels/pull/364) - PR: Catch 
error when validating if an object is defined in the namespace, by 
[@ccordoba12](https://github.com/ccordoba12)
+* [PR 363](https://github.com/spyder-ide/spyder-kernels/pull/363) - PR: Fix 
error when running multiprocessing code that contains classes, by 
[@impact27](https://github.com/impact27)
+* [PR 362](https://github.com/spyder-ide/spyder-kernels/pull/362) - PR: Catch 
KeyError when closing comm, by [@ccordoba12](https://github.com/ccordoba12)
+* [PR 361](https://github.com/spyder-ide/spyder-kernels/pull/361) - PR: 
Increase minimal required version of pyzmq for Python 3, by 
[@ccordoba12](https://github.com/ccordoba12)
+* [PR 360](https://github.com/spyder-ide/spyder-kernels/pull/360) - PR: 
Increase minimal required version of ipykernel to 6.6.1, by 
[@ccordoba12](https://github.com/ccordoba12)
+* [PR 357](https://github.com/spyder-ide/spyder-kernels/pull/357) - PR: 
Require jupyter-client 7.1.0 to fix issues on Windows, by 
[@ccordoba12](https://github.com/ccordoba12)
+* [PR 356](https://github.com/spyder-ide/spyder-kernels/pull/356) - PR: 
Increase minimal required version of jupyter-client to 7.0+ for Python 3, by 
[@ccordoba12](https://github.com/ccordoba12)
+* [PR 354](https://github.com/spyder-ide/spyder-kernels/pull/354) - PR: 
Constraint IPython version to avoid issues when its next major version is 
released, by [@ccordoba12](https://github.com/ccordoba12)
+* [PR 353](https://github.com/spyder-ide/spyder-kernels/pull/353) - PR: 
Implement a less hacky solution to fix namespace issues, by 
[@impact27](https://github.com/impact27)
+* [PR 351](https://github.com/spyder-ide/spyder-kernels/pull/351) - PR: More 
namespace fixes, by [@impact27](https://github.com/impact27)
+* [PR 350](https://github.com/spyder-ide/spyder-kernels/pull/350) - PR: Don't 
print DeprecationWarning's that come from comm handlers, by 
[@ccordoba12](https://github.com/ccordoba12) 
([343](https://github.com/spyder-ide/spyder-kernels/issues/343))
+* [PR 349](https://github.com/spyder-ide/spyder-kernels/pull/349) - PR: Update 
Quansight logo in Readme, by [@ccordoba12](https://github.com/ccordoba12)
+* [PR 346](https://github.com/spyder-ide/spyder-kernels/pull/346) - PR: Fix 
some namespace issues, by [@impact27](https://github.com/impact27) 
([345](https://github.com/spyder-ide/spyder-kernels/issues/345))
+* [PR 338](https://github.com/spyder-ide/spyder-kernels/pull/338) - PR: Fix 
misplaced section in changelog, by [@ccordoba12](https://github.com/ccordoba12)
+
+In this release 16 pull requests were closed.
+
+
+----
+
+
+## Version 2.2.0 (2021-11-22)
+
 ### New features
 
 * Add the ability to capture segfaults and flush standard streams from
   Spyder.
 * Add support for jupyter_client 7.
 
-## Version 2.2.0 (2021-11-22)
-
 ### Issues Closed
 
 * [Issue 326](https://github.com/spyder-ide/spyder-kernels/issues/326) - 
Setting variables in recursive debugging namespaces is broken ([PR 
327](https://github.com/spyder-ide/spyder-kernels/pull/327) by 
[@impact27](https://github.com/impact27))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.2.0/README.md 
new/spyder-kernels-2.2.1/README.md
--- old/spyder-kernels-2.2.0/README.md  2021-11-23 00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/README.md  2022-01-13 16:55:24.000000000 +0100
@@ -64,7 +64,7 @@
 
 Spyder and its subprojects are funded thanks to the generous support of
 
-[![Quansight](https://static.wixstatic.com/media/095d2c_2508c560e87d436ea00357abc404cf1d~mv2.png/v1/crop/x_0,y_9,w_915,h_329/fill/w_380,h_128,al_c,usm_0.66_1.00_0.01/095d2c_2508c560e87d436ea00357abc404cf1d~mv2.png)](https://www.quansight.com/)[![Numfocus](https://i2.wp.com/numfocus.org/wp-content/uploads/2017/07/NumFocus_LRG.png?fit=320%2C148&ssl=1)](https://numfocus.org/)
+[![Quansight](https://user-images.githubusercontent.com/16781833/142477716-53152d43-99a0-470c-a70b-c04bbfa97dd4.png)](https://www.quansight.com/)[![Numfocus](https://i2.wp.com/numfocus.org/wp-content/uploads/2017/07/NumFocus_LRG.png?fit=320%2C148&ssl=1)](https://numfocus.org/)
 
 and the donations we have received from our users around the world through 
[Open Collective](https://opencollective.com/spyder/):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.2.0/requirements/posix.txt 
new/spyder-kernels-2.2.1/requirements/posix.txt
--- old/spyder-kernels-2.2.0/requirements/posix.txt     2021-11-23 
00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/requirements/posix.txt     2022-01-13 
16:55:24.000000000 +0100
@@ -1,3 +1,6 @@
 cloudpickle
-ipykernel
+ipykernel>=6.6.1
+ipython>=7.6.0,<8
+jupyter_client>=7.1.0
+pyzmq>=22.1.0
 wurlitzer>=1.0.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.2.0/requirements/python-27.txt 
new/spyder-kernels-2.2.1/requirements/python-27.txt
--- old/spyder-kernels-2.2.0/requirements/python-27.txt 2021-11-23 
00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/requirements/python-27.txt 2022-01-13 
16:55:24.000000000 +0100
@@ -1,2 +1,9 @@
-click =7
+decorator<5
 backports.functools_lru_cache
+cloudpickle
+ipykernel<5
+jupyter_client>=5.3.4,<6
+pyzmq>=17,<20
+wurlitzer>=1.0.3
+# To avoid an error with conda
+click =7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.2.0/requirements/windows.txt 
new/spyder-kernels-2.2.1/requirements/windows.txt
--- old/spyder-kernels-2.2.0/requirements/windows.txt   2021-11-23 
00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/requirements/windows.txt   2022-01-13 
16:55:24.000000000 +0100
@@ -1,4 +1,7 @@
 cloudpickle
-ipykernel
+ipykernel>=6.6.1
+ipython>=7.6.0,<8
+jupyter_client>=7.1.0
+pyzmq>=22.1.0
 # Pin pip version since we are getting 9.x and it causes IPython 6.1.0 to be 
installed
 pip>=19.3.1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.2.0/setup.py 
new/spyder-kernels-2.2.1/setup.py
--- old/spyder-kernels-2.2.0/setup.py   2021-11-23 00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/setup.py   2022-01-13 16:55:24.000000000 +0100
@@ -40,11 +40,13 @@
     'backports.functools-lru-cache; python_version<"3"',
     'cloudpickle',
     'ipykernel<5; python_version<"3"',
-    'ipykernel>=5.3.0; python_version>="3"',
+    'ipykernel>=6.6.1; python_version>="3"',
     'ipython<6; python_version<"3"',
-    'ipython>=7.6.0; python_version>="3"',
-    'jupyter-client>=5.3.4',
-    'pyzmq>=17',
+    'ipython>=7.6.0,<8; python_version>="3"',
+    'jupyter-client>=5.3.4,<6; python_version<"3"',
+    'jupyter-client>=7.1.0; python_version>="3"',
+    'pyzmq>=17,<20; python_version<"3"',
+    'pyzmq>=22.1.0; python_version>="3"',
     'wurlitzer>=1.0.3;platform_system!="Windows"',
 ]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/spyder-kernels-2.2.0/spyder_kernels/_version.py 
new/spyder-kernels-2.2.1/spyder_kernels/_version.py
--- old/spyder-kernels-2.2.0/spyder_kernels/_version.py 2021-11-23 
00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/spyder_kernels/_version.py 2022-01-13 
16:55:24.000000000 +0100
@@ -8,5 +8,5 @@
 
 """Version File."""
 
-VERSION_INFO = (2, 2, 0)
+VERSION_INFO = (2, 2, 1)
 __version__ = '.'.join(map(str, VERSION_INFO))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/spyder_kernels/comms/commbase.py 
new/spyder-kernels-2.2.1/spyder_kernels/comms/commbase.py
--- old/spyder-kernels-2.2.0/spyder_kernels/comms/commbase.py   2021-11-23 
00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/spyder_kernels/comms/commbase.py   2022-01-13 
16:55:24.000000000 +0100
@@ -170,8 +170,11 @@
         id_list = self.get_comm_id_list(comm_id)
 
         for comm_id in id_list:
-            self._comms[comm_id]['comm'].close()
-            del self._comms[comm_id]
+            try:
+                self._comms[comm_id]['comm'].close()
+                del self._comms[comm_id]
+            except KeyError:
+                pass
 
     def is_open(self, comm_id=None):
         """Check to see if the comm is open."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/spyder_kernels/comms/frontendcomm.py 
new/spyder-kernels-2.2.1/spyder_kernels/comms/frontendcomm.py
--- old/spyder-kernels-2.2.0/spyder_kernels/comms/frontendcomm.py       
2021-11-23 00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/spyder_kernels/comms/frontendcomm.py       
2022-01-13 16:55:24.000000000 +0100
@@ -271,7 +271,7 @@
             sys.stderr.write = saved_stderr_write
 
 
-class WriteWrapper():
+class WriteWrapper(object):
     """Wrapper to warn user when text is printed."""
 
     def __init__(self, write, name):
@@ -279,11 +279,29 @@
         self._name = name
         self._warning_shown = False
 
+    def is_benign_message(self, message):
+        """Determine if a message is benign in order to filter it."""
+        benign_messages = [
+            # Fixes spyder-ide/spyder#14928
+            # Fixes spyder-ide/spyder-kernels#343
+            'DeprecationWarning',
+            # Fixes spyder-ide/spyder-kernels#365
+            'IOStream.flush timed out'
+        ]
+
+        return any([msg in message for msg in benign_messages])
+
     def __call__(self, string):
         """Print warning once."""
-        if not self._warning_shown:
-            self._warning_shown = True
-            self._write(
-                "\nOutput from spyder call "
-                + repr(self._name) + ":\n")
-        return self._write(string)
+        if not self.is_benign_message(string):
+            if not self._warning_shown:
+                self._warning_shown = True
+
+                # Don't print handler name for `show_mpl_backend_errors`
+                # because we have a specific message for it.
+                if repr(self._name) != "'show_mpl_backend_errors'":
+                    self._write(
+                        "\nOutput from spyder call " + repr(self._name) + ":\n"
+                    )
+
+            return self._write(string)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/spyder_kernels/console/kernel.py 
new/spyder-kernels-2.2.1/spyder_kernels/console/kernel.py
--- old/spyder-kernels-2.2.0/spyder_kernels/console/kernel.py   2021-11-23 
00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/spyder_kernels/console/kernel.py   2022-01-13 
16:55:24.000000000 +0100
@@ -740,6 +740,15 @@
             # This covers other RuntimeError's
             else:
                 error = generic_error.format(traceback.format_exc())
+        except ImportError as err:
+            additional_info = (
+                "This is most likely caused by missing packages in the Python "
+                "environment\n"
+                "or installation whose interpreter is located at:\n\n"
+                "    {0}"
+            ).format(sys.executable)
+
+            error = generic_error.format(err) + '\n\n' + additional_info
         except Exception:
             error = generic_error.format(traceback.format_exc())
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/spyder_kernels/console/tests/test_console_kernel.py 
new/spyder-kernels-2.2.1/spyder_kernels/console/tests/test_console_kernel.py
--- 
old/spyder-kernels-2.2.0/spyder_kernels/console/tests/test_console_kernel.py    
    2021-11-23 00:19:57.000000000 +0100
+++ 
new/spyder-kernels-2.2.1/spyder_kernels/console/tests/test_console_kernel.py    
    2022-01-13 16:55:24.000000000 +0100
@@ -19,6 +19,7 @@
 from subprocess import Popen, PIPE
 import sys
 import inspect
+from collections import namedtuple
 
 # Test imports
 import ipykernel
@@ -424,6 +425,8 @@
         msg_id = client.execute("import sys; sys_path = sys.path",
                                 user_expressions={'output':'sys_path'})
         reply = client.get_shell_msg(timeout=TIMEOUT)
+        while 'user_expressions' not in reply['content']:
+            reply = client.get_shell_msg(timeout=TIMEOUT)
 
         # Transform value obtained through user_expressions
         user_expressions = reply['content']['user_expressions']
@@ -470,6 +473,8 @@
         # Verify that the `result` variable is defined
         client.inspect('result')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "found" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']
         assert content['found']
 
@@ -477,6 +482,54 @@
 @flaky(max_runs=3)
 @pytest.mark.skipif(not PY3,
                     reason="Only meant for Python 3")
+def test_multiprocessing_2(tmpdir):
+    """
+    Test that multiprocessing works on Python 3.
+    """
+    # Command to start the kernel
+    cmd = "from spyder_kernels.console import start; start.main()"
+
+    with setup_kernel(cmd) as client:
+        # Remove all variables
+        client.execute("%reset -f")
+        client.get_shell_msg(timeout=TIMEOUT)
+
+        # Write multiprocessing code to a file
+        code = """
+from multiprocessing import Pool
+
+class myClass():
+    def __init__(self, i):
+        self.i = i + 10
+
+def myFunc(i):
+    return myClass(i)
+
+if __name__ == '__main__':
+    with Pool(5) as p:
+        result = p.map(myFunc, [1, 2, 3])
+    result = [r.i for r in result]
+"""
+        p = tmpdir.join("mp-test.py")
+        p.write(code)
+
+        # Run code
+        client.execute("runfile(r'{}')".format(to_text_string(p)))
+        client.get_shell_msg(timeout=TIMEOUT)
+
+        # Verify that the `result` variable is defined
+        client.inspect('result')
+        msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "found" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
+        content = msg['content']
+        assert content['found']
+        assert "[11, 12, 13]" in content['data']['text/plain']
+
+
+@flaky(max_runs=3)
[email protected](not PY3,
+                    reason="Only meant for Python 3")
 def test_dask_multiprocessing(tmpdir):
     """
     Test that dask multiprocessing works on Python 3.
@@ -512,6 +565,8 @@
         # Verify that the `x` variable is defined
         client.inspect('x')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "found" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']
         assert content['found']
 
@@ -552,6 +607,8 @@
         # Verify that `result` is defined in the current namespace
         client.inspect('result')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "found" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']
         assert content['found']
 
@@ -563,6 +620,8 @@
         # Verify that the variable `result2` is defined
         client.inspect('result2')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "found" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']
         assert content['found']
 
@@ -575,12 +634,16 @@
         # Verify that the variable `result3` is defined
         client.inspect('result3')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "found" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']
         assert content['found']
 
         # Verify that the variable `__file__` is undefined
         client.inspect('__file__')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "found" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']
         assert not content['found']
 
@@ -622,24 +685,32 @@
         # Check correct decimal format
         client.inspect('a')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "data" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']['data']['text/plain']
         assert "123412341234.12" in content
 
         # Check threshold value
         client.inspect('t')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "data" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']['data']['text/plain']
         assert "inf" in content
 
         # Check suppress value
         client.inspect('s')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "data" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']['data']['text/plain']
         assert "True" in content
 
         # Check formatter
         client.inspect('f')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "data" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']['data']['text/plain']
         assert "{'float_kind': <built-in method format of str object" in 
content
 
@@ -697,6 +768,8 @@
         # Verify that the `tess` variable is defined
         client.inspect('tess')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "found" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']
         assert content['found']
 
@@ -713,6 +786,8 @@
         # Verify that the `a` variable is defined
         client.inspect('a')
         msg = client.get_shell_msg(timeout=TIMEOUT)
+        while "found" not in msg['content']:
+            msg = client.get_shell_msg(timeout=TIMEOUT)
         content = msg['content']
         assert content['found']
 
@@ -728,6 +803,8 @@
         code = "import matplotlib; backend = matplotlib.get_backend()"
         client.execute(code, user_expressions={'output': 'backend'})
         reply = client.get_shell_msg(timeout=TIMEOUT)
+        while 'user_expressions' not in reply['content']:
+            reply = client.get_shell_msg(timeout=TIMEOUT)
 
         # Transform value obtained through user_expressions
         user_expressions = reply['content']['user_expressions']
@@ -901,6 +978,119 @@
 
     pdb_obj.curframe = None
     pdb_obj.curframe_locals = None
+
+
+def test_functions_with_locals_in_pdb(kernel):
+    """
+    Test that functions with locals work in Pdb.
+
+    This is a regression test for spyder-ide/spyder-kernels#345
+    """
+    pdb_obj = SpyderPdb()
+    Frame = namedtuple("Frame", ["f_globals"])
+    pdb_obj.curframe = Frame(f_globals=kernel.shell.user_ns)
+    pdb_obj.curframe_locals = kernel.shell.user_ns
+    kernel.shell.pdb_session = pdb_obj
+
+    # Create a local function.
+    kernel.shell.pdb_session.default(
+        'def fun_a(): return [i for i in range(1)]')
+    kernel.shell.pdb_session.default(
+        'zz = fun_a()')
+    assert kernel.get_value('zz') == [0]
+
+    kernel.shell.pdb_session.default(
+        'a = 1')
+    kernel.shell.pdb_session.default(
+        'def fun_a(): return a')
+    kernel.shell.pdb_session.default(
+        'zz = fun_a()')
+    assert kernel.get_value('zz') == 1
+
+
+    pdb_obj.curframe = None
+    pdb_obj.curframe_locals = None
+
+
+def test_functions_with_locals_in_pdb_2(kernel):
+    """
+    Test that functions with locals work in Pdb.
+
+    This is another regression test for spyder-ide/spyder-kernels#345
+    """
+    baba = 1
+    pdb_obj = SpyderPdb()
+    pdb_obj.curframe = inspect.currentframe()
+    pdb_obj.curframe_locals = pdb_obj.curframe.f_locals
+    kernel.shell.pdb_session = pdb_obj
+
+    # Create a local function.
+    kernel.shell.pdb_session.default(
+        'def fun_a(): return [i for i in range(1)]')
+    kernel.shell.pdb_session.default(
+        'zz = fun_a()')
+    assert kernel.get_value('zz') == [0]
+
+    kernel.shell.pdb_session.default(
+        'a = 1')
+    kernel.shell.pdb_session.default(
+        'def fun_a(): return a')
+    kernel.shell.pdb_session.default(
+        'zz = fun_a()')
+    assert kernel.get_value('zz') == 1
+
+    # Check baba is in locals and not globals
+    kernel.shell.pdb_session.default(
+        'll = locals().keys()')
+    assert "baba" in kernel.get_value('ll')
+    kernel.shell.pdb_session.default(
+        'gg = globals().keys()')
+    assert "baba" not in kernel.get_value('gg')
+
+    pdb_obj.curframe = None
+    pdb_obj.curframe_locals = None
+
+
+def test_locals_globals_in_pdb(kernel):
+    """
+    Test thal locals and globals work properly in Pdb.
+    """
+    a = 1
+    pdb_obj = SpyderPdb()
+    pdb_obj.curframe = inspect.currentframe()
+    pdb_obj.curframe_locals = pdb_obj.curframe.f_locals
+    kernel.shell.pdb_session = pdb_obj
+
+    assert kernel.get_value('a') == 1
+
+    kernel.shell.pdb_session.default(
+        'test = "a" in globals()')
+    assert kernel.get_value('test') == False
+
+    kernel.shell.pdb_session.default(
+        'test = "a" in locals()')
+    assert kernel.get_value('test') == True
+
+    kernel.shell.pdb_session.default(
+        'def f(): return a')
+    kernel.shell.pdb_session.default(
+        'test = f()')
+    assert kernel.get_value('test') == 1
+
+    kernel.shell.pdb_session.default(
+        'a = 2')
+    assert kernel.get_value('a') == 2
+
+    kernel.shell.pdb_session.default(
+        'test = "a" in globals()')
+    assert kernel.get_value('test') == False
+
+    kernel.shell.pdb_session.default(
+        'test = "a" in locals()')
+    assert kernel.get_value('test') == True
+
+    pdb_obj.curframe = None
+    pdb_obj.curframe_locals = None
 
 
 if __name__ == "__main__":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/spyder_kernels/customize/spydercustomize.py 
new/spyder-kernels-2.2.1/spyder_kernels/customize/spydercustomize.py
--- old/spyder-kernels-2.2.0/spyder_kernels/customize/spydercustomize.py        
2021-11-23 00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/spyder_kernels/customize/spydercustomize.py        
2022-01-13 16:55:24.000000000 +0100
@@ -549,6 +549,14 @@
         if args is not None:
             for arg in shlex.split(args):
                 sys.argv.append(arg)
+
+        if "multiprocessing" in sys.modules:
+            # See https://github.com/spyder-ide/spyder/issues/16696
+            try:
+                sys.modules['__mp_main__'] = sys.modules['__main__']
+            except Exception:
+                pass
+
         if wdir is not None:
             if PY2:
                 try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/spyder_kernels/customize/spyderpdb.py 
new/spyder-kernels-2.2.1/spyder_kernels/customize/spyderpdb.py
--- old/spyder-kernels-2.2.0/spyder_kernels/customize/spyderpdb.py      
2021-11-23 00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/spyder_kernels/customize/spyderpdb.py      
2022-01-13 16:55:24.000000000 +0100
@@ -34,18 +34,6 @@
 logger = logging.getLogger(__name__)
 
 
-def uses_comprehension(code):
-    """Check if given code uses comprehensions."""
-    comprehension_statements = (
-        ast.ListComp,
-        ast.SetComp,
-        ast.GeneratorExp,
-        ast.DictComp
-    )
-    nodes = ast.walk(ast.parse(code))
-    return any(isinstance(node, comprehension_statements) for node in nodes)
-
-
 class DebugWrapper(object):
     """
     Notifies the frontend when debugging starts/stops
@@ -177,11 +165,6 @@
                         self.print_exclamation_warning()
         try:
             line = TransformerManager().transform_cell(line)
-            try:
-                code = compile(line + '\n', '<stdin>', 'single')
-            except SyntaxError:
-                # support multiline statments
-                code = compile(line + '\n', '<stdin>', 'exec')
             save_stdout = sys.stdout
             save_stdin = sys.stdin
             save_displayhook = sys.displayhook
@@ -192,36 +175,69 @@
                 if execute_events:
                      get_ipython().events.trigger('pre_execute')
 
-                 # Mitigates a CPython bug (https://bugs.python.org/issue41918)
-                 # that prevents running comprehensions with the frame locals
-                 # in Pdb.
-                 # See https://bugs.python.org/issue21161 and
-                 # spyder-ide/spyder#13909.
-                if uses_comprehension(line):
-                    # There are three potential problems with this approach:
-                    # 1. If the code access a globals variable that is
-                    #    masked by a locals variable, it will get the locals
-                    #    one.
-                    # 2. Any edit to that variable will be lost.
-                    # 3. The globals will appear to contain all the locals
-                    #    variables.
-                    # 4. Any new locals variable will be saved to globals
-                    #    instead
-                    fake_globals = globals.copy()
-                    fake_globals.update(locals)
-                    locals_keys = locals.keys()
-                    # Don't pass locals, solves spyder-ide/spyder#16790
-                    exec(code, fake_globals)
-                    # Avoid mixing locals and globals
-                    for key in locals_keys:
-                        locals[key] = fake_globals.pop(key, None)
-                    globals.update(fake_globals)
-                else:
-                    exec(code, globals, locals)
+                if locals is not globals:
+                    # Mitigates a behaviour of CPython that makes it difficult
+                    # to work with exec and the local namespace
+                    # See:
+                    #  - https://bugs.python.org/issue41918
+                    #  - https://bugs.python.org/issue46153
+                    #  - https://bugs.python.org/issue21161
+                    #  - spyder-ide/spyder#13909
+                    #  - spyder-ide/spyder-kernels#345
+                    #
+                    # The idea here is that the best way to emulate being in a
+                    # function is to actually execute the code in a function.
+                    # A function called `_spyderpdb_code` is created and
+                    # called. It will first load the locals, execute the code,
+                    # and then update the locals.
+                    #
+                    # One limitation of this approach is that locals() is only
+                    # a copy of the curframe locals. This means that closures
+                    # for example are early binding instead of late binding.
+
+                    # Check if line is an expression to print
+                    print_ret = False
+                    try:
+                        code = ast.parse(line + '\n', '<stdin>', 'single')
+                        if len(code.body) == 1:
+                            print_ret = isinstance(code.body[0], ast.Expr)
+                    except SyntaxError:
+                        pass
+
+                    # Create a function and load the locals
+                    globals["_spyderpdb_locals"] = locals
+                    indent = "    "
+                    code = ["def _spyderpdb_code():"]
+                    code += [indent + "{k} = _spyderpdb_locals['{k}']".format(
+                        k=k) for k in locals]
+
+                    # Run the code
+                    if print_ret:
+                        code += [indent + 'print(' + line.strip() + ")"]
+                    else:
+                        code += [indent + l for l in line.splitlines()]
 
+                    # Update the locals
+                    code += [indent + "_spyderpdb_locals.update(locals())"]
+
+                    # Run the function
+                    code += ["_spyderpdb_code()"]
+                    code = compile('\n'.join(code) + '\n', '<stdin>', 'exec')
+                    try:
+                        exec(code, globals)
+                    finally:
+                        globals.pop("_spyderpdb_locals", None)
+                        globals.pop("_spyderpdb_code", None)
+                else:
+                    try:
+                        code = compile(line + '\n', '<stdin>', 'single')
+                    except SyntaxError:
+                        # Support multiline statments
+                        code = compile(line + '\n', '<stdin>', 'exec')
+                    exec(code, globals)
+            finally:
                 if execute_events:
                      get_ipython().events.trigger('post_execute')
-            finally:
                 sys.stdout = save_stdout
                 sys.stdin = save_stdin
                 sys.displayhook = save_displayhook
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/spyder-kernels-2.2.0/spyder_kernels/utils/dochelpers.py 
new/spyder-kernels-2.2.1/spyder_kernels/utils/dochelpers.py
--- old/spyder-kernels-2.2.0/spyder_kernels/utils/dochelpers.py 2021-11-23 
00:19:57.000000000 +0100
+++ new/spyder-kernels-2.2.1/spyder_kernels/utils/dochelpers.py 2022-01-13 
16:55:24.000000000 +0100
@@ -315,7 +315,7 @@
     for attr in attr_list:
         try:
             attr_not_found = not hasattr(eval(base, namespace), attr)
-        except (SyntaxError, AttributeError):
+        except (AttributeError, SyntaxError, TypeError):
             return False
         if attr_not_found:
             if force_import:

Reply via email to