Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-mplcursors for 
openSUSE:Factory checked in at 2021-04-12 17:10:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-mplcursors (Old)
 and      /work/SRC/openSUSE:Factory/.python-mplcursors.new.2401 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-mplcursors"

Mon Apr 12 17:10:41 2021 rev:5 rq:884582 version:0.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-mplcursors/python-mplcursors.changes      
2020-07-24 09:59:32.421619803 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-mplcursors.new.2401/python-mplcursors.changes
    2021-04-12 17:10:51.078597305 +0200
@@ -1,0 +2,20 @@
+Fri Apr  9 22:02:53 UTC 2021 - Ben Greiner <[email protected]>
+
+- Update to v0.4
+  * Invisible artists are now unpickable (patch suggested by
+    @eBardieCT).
+  * The bindings kwarg can require modifier keys for mouse button
+    events.
+  * Transient hovering (suggested by @LaurenceMolloy).
+  * Switch to supporting only "new-style" (LineCollection) stem
+    plots.
+  * Cursors are drawn with zorder=np.inf.
+- Drop patches merged upstream
+  * mplcursors-unicodeminus.patch
+  * mplcursors-newstem.patch
+  * mplcursors-parse_annotation.patch
+  * mplcursors-fix-LineCollection.patch
+  * mplcursors-unicodeminus2.patch
+- Skip python36: No python36-matplotlib in TW.
+
+-------------------------------------------------------------------

Old:
----
  mplcursors-0.3.tar.gz
  mplcursors-fix-LineCollection.patch
  mplcursors-newstem.patch
  mplcursors-parse_annotation.patch
  mplcursors-unicodeminus.patch
  mplcursors-unicodeminus2.patch

New:
----
  mplcursors-0.4.tar.gz

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

Other differences:
------------------
++++++ python-mplcursors.spec ++++++
--- /var/tmp/diff_new_pack.0dPDSL/_old  2021-04-12 17:10:51.598597880 +0200
+++ /var/tmp/diff_new_pack.0dPDSL/_new  2021-04-12 17:10:51.602597885 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-mplcursors
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,29 +16,24 @@
 #
 
 
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%{?!python_module:%define python_module() python3-%{**}}
 %define         skip_python2 1
+%define         skip_python36 1
 Name:           python-mplcursors
-Version:        0.3
+Version:        0.4
 Release:        0
 Summary:        Interactive data selection cursors for Matplotlib
 License:        MIT
 URL:            https://github.com/anntzer/mplcursors
 Source:         
https://files.pythonhosted.org/packages/source/m/mplcursors/mplcursors-%{version}.tar.gz
-# PATCH-FIX-UPSTREAM gh#anntzer/mplcursors#26
-Patch0:         mplcursors-unicodeminus.patch
-Patch1:         mplcursors-newstem.patch
-Patch2:         mplcursors-parse_annotation.patch
-Patch3:         mplcursors-fix-LineCollection.patch
-Patch4:         mplcursors-unicodeminus2.patch
 BuildRequires:  %{python_module setuptools_scm}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-Requires:       python-matplotlib >= 2.1
+Requires:       python-matplotlib >= 3.1
 BuildArch:      noarch
 # SECTION test requirements
-BuildRequires:  %{python_module matplotlib >= 2.1}
+BuildRequires:  %{python_module matplotlib >= 3.1}
 BuildRequires:  %{python_module pytest}
 # /SECTION
 %python_subpackages

++++++ mplcursors-0.3.tar.gz -> mplcursors-0.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/.doc-requirements.txt 
new/mplcursors-0.4/.doc-requirements.txt
--- old/mplcursors-0.3/.doc-requirements.txt    2019-09-15 20:40:47.000000000 
+0200
+++ new/mplcursors-0.4/.doc-requirements.txt    2020-05-06 22:34:21.000000000 
+0200
@@ -1,3 +1,3 @@
-pandas==0.24.1
-sphinx==1.5.6
-sphinx-gallery==0.1.13
+pandas==1.0.0
+sphinx==2.4.4
+sphinx-gallery==0.6.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/.github/workflows/build.yml 
new/mplcursors-0.4/.github/workflows/build.yml
--- old/mplcursors-0.3/.github/workflows/build.yml      1970-01-01 
01:00:00.000000000 +0100
+++ new/mplcursors-0.4/.github/workflows/build.yml      2020-11-25 
00:01:39.000000000 +0100
@@ -0,0 +1,38 @@
+name: build
+
+on: [push, pull_request]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        python-version: [3.6, 3.7, 3.8, 3.9]
+        oldest: [0]
+        include:
+        - python-version: 3.6
+          oldest: 1
+    steps:
+    - uses: actions/checkout@v2
+    - uses: actions/setup-python@v2
+      with:
+        python-version: ${{ matrix.python-version }}
+    - name: Install
+      run: |
+        if [[ '${{ matrix.oldest }}' = 1 ]]; then
+          PYTEST_VERSION='==3.7.1'
+          PYTEST_COV_VERSION='==2.9.0'
+          NUMPY_VERSION='==1.11.*'
+          MATPLOTLIB_VERSION='==3.1.0'
+        fi &&
+        pip install --upgrade pip wheel pytest"$PYTEST_VERSION" 
pytest-cov"$PYTEST_COV_VERSION" codecov &&
+        # Force install of numpy before matplotlib.
+        pip install --upgrade --upgrade-strategy=only-if-needed 
--only-binary=:all: numpy"$NUMPY_VERSION" &&
+        pip install --upgrade --upgrade-strategy=only-if-needed 
matplotlib"$MATPLOTLIB_VERSION" &&
+        pip install . &&
+        pip list
+    - name: Test
+      run: |
+        python -mpytest --cov --cov-branch --cov-report=xml
+    - name: Codecov
+      uses: codecov/codecov-action@v1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/.travis.yml 
new/mplcursors-0.4/.travis.yml
--- old/mplcursors-0.3/.travis.yml      2019-09-15 20:41:02.000000000 +0200
+++ new/mplcursors-0.4/.travis.yml      1970-01-01 01:00:00.000000000 +0100
@@ -1,37 +0,0 @@
-git:
-  depth: 1
-dist: xenial
-sudo: true
-language: python
-cache:
-  pip: true
-matrix:
-  include:
-  - python: "3.6"
-    env: |
-      PYTEST_VERSION='==3.7.1'
-      NUMPY_VERSION='==1.11'
-      MATPLOTLIB_VERSION='==3.1.0'
-  - python: "3.7"
-    env: |
-      PYTEST_VERSION=
-      NUMPY_VERSION=
-      MATPLOTLIB_VERSION=
-  - python: "nightly"
-    env: |
-      PYTEST_VERSION=
-      NUMPY_VERSION=
-      MATPLOTLIB_VERSION=
-      PIP_INSTALL_PRE=1
-      PIP_FIND_LINKS=https://nightly.matplotlib.org
-  allow_failures:
-  - python: "nightly"
-install: |
-  pip install --upgrade pip pytest"$PYTEST_VERSION" pytest-cov codecov
-  # Force install of numpy before matplotlib.
-  pip install --upgrade --upgrade-strategy=only-if-needed numpy"$NUMPY_VERSION"
-  pip install --upgrade --upgrade-strategy=only-if-needed 
matplotlib"$MATPLOTLIB_VERSION"
-  pip install .
-  pip list
-script: pytest --cov
-after_success: codecov
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/CHANGELOG.rst 
new/mplcursors-0.4/CHANGELOG.rst
--- old/mplcursors-0.3/CHANGELOG.rst    2019-09-15 20:57:07.000000000 +0200
+++ new/mplcursors-0.4/CHANGELOG.rst    2020-12-09 21:28:47.000000000 +0100
@@ -1,3 +1,12 @@
+0.4
+===
+
+- Invisible artists are now unpickable (patch suggested by @eBardieCT).
+- The ``bindings`` kwarg can require modifier keys for mouse button events.
+- Transient hovering (suggested by @LaurenceMolloy).
+- Switch to supporting only "new-style" (`LineCollection`) `stem` plots.
+- Cursors are drawn with ``zorder=np.inf``.
+
 0.3
 ===
 
@@ -39,8 +48,8 @@
 - Selections on images now have an index as well.
 - Selections created on `scatter` plots, `errorbar` plots, and `polar` plots
   can now be moved.
-- `PathCollection`\s not created by `plt.scatter` are now picked as paths, not
-  as collections of points.
+- `PathCollection`\s not created by `scatter` are now picked as paths, not as
+  collections of points.
 - `Patch`\es now pick on their borders, not their interior.
 - Improved picking of `Container`\s.
 - In hover mode, annotations can still be removed by right-clicking.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/PKG-INFO new/mplcursors-0.4/PKG-INFO
--- old/mplcursors-0.3/PKG-INFO 2019-09-16 01:55:05.000000000 +0200
+++ new/mplcursors-0.4/PKG-INFO 2020-12-09 22:11:21.692934500 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: mplcursors
-Version: 0.3
+Version: 0.4
 Summary: Interactive data selection cursors for Matplotlib.
 Home-page: https://github.com/anntzer/mplcursors
 Author: Antony Lee
@@ -8,27 +8,35 @@
 Description: Interactive data selection cursors for Matplotlib
         =================================================
         
-        |PyPI| |conda-forge| |Fedora Rawhide|
-        
-        |Read the Docs| |Travis| |CodeCov|
+        | |GitHub| |PyPI| |conda-forge| |Debian| |Fedora| |openSUSE|
+        | |Read the Docs| |Build| |CodeCov|
         
+        .. |GitHub|
+           image:: 
https://img.shields.io/badge/github-anntzer%2Fmplcursors-brightgreen
+           :target: https://github.com/anntzer/mplcursors
         .. |PyPI|
-           image:: https://img.shields.io/pypi/v/mplcursors.svg
+           image:: 
https://img.shields.io/pypi/v/mplcursors.svg?color=brightgreen
            :target: https://pypi.python.org/pypi/mplcursors
         .. |conda-forge|
-           image:: https://img.shields.io/conda/v/conda-forge/mplcursors.svg
+           image:: 
https://img.shields.io/conda/v/conda-forge/mplcursors.svg?label=conda-forge&color=brightgreen
            :target: https://anaconda.org/conda-forge/mplcursors
-        .. |Fedora Rawhide|
-           image:: 
https://repology.org/badge/version-for-repo/fedora_rawhide/python:mplcursors.svg
-           :target: https://apps.fedoraproject.org/packages/python-mplcursors
+        .. |Debian|
+           image:: 
https://repology.org/badge/version-for-repo/debian_testing/mplcursors.svg?header=Debian
+           :target: https://packages.debian.org/sid/main/python3-mplcursors
+        .. |Fedora|
+           image:: 
https://repology.org/badge/version-for-repo/fedora_rawhide/python:mplcursors.svg?header=Fedora
+           :target: https://src.fedoraproject.org/rpms/python-mplcursors
+        .. |openSUSE|
+           image:: 
https://repology.org/badge/version-for-repo/opensuse_tumbleweed/python:mplcursors.svg?header=openSUSE
+           :target: https://software.opensuse.org/package/python3-mplcursors
         .. |Read the Docs|
-           image:: 
https://readthedocs.org/projects/mplcursors/badge/?version=latest
+           image:: https://img.shields.io/readthedocs/mplcursors
            :target: http://mplcursors.readthedocs.io/en/latest/?badge=latest
-        .. |Travis|
-           image:: https://travis-ci.org/anntzer/mplcursors.svg?branch=master
-           :target: https://travis-ci.org/anntzer/mplcursors
+        .. |Build|
+           image:: 
https://img.shields.io/github/workflow/status/anntzer/mplcursors/build
+           :target: https://github.com/anntzer/mplcursors/actions
         .. |CodeCov|
-           image:: https://codecov.io/gh/anntzer/mplcursors/master.svg
+           image:: https://img.shields.io/codecov/c/github/anntzer/mplcursors
            :target: https://codecov.io/gh/anntzer/mplcursors
         
         mplcursors provides interactive data selection cursors for 
Matplotlib_.  It is
@@ -56,6 +64,7 @@
         
 Platform: UNKNOWN
 Classifier: Development Status :: 4 - Beta
+Classifier: Framework :: Matplotlib
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Programming Language :: Python :: 3
 Requires-Python: >=3.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/README.rst 
new/mplcursors-0.4/README.rst
--- old/mplcursors-0.3/README.rst       2019-09-15 20:41:02.000000000 +0200
+++ new/mplcursors-0.4/README.rst       2020-11-25 00:15:25.000000000 +0100
@@ -1,27 +1,35 @@
 Interactive data selection cursors for Matplotlib
 =================================================
 
-|PyPI| |conda-forge| |Fedora Rawhide|
-
-|Read the Docs| |Travis| |CodeCov|
+| |GitHub| |PyPI| |conda-forge| |Debian| |Fedora| |openSUSE|
+| |Read the Docs| |Build| |CodeCov|
 
+.. |GitHub|
+   image:: https://img.shields.io/badge/github-anntzer%2Fmplcursors-brightgreen
+   :target: https://github.com/anntzer/mplcursors
 .. |PyPI|
-   image:: https://img.shields.io/pypi/v/mplcursors.svg
+   image:: https://img.shields.io/pypi/v/mplcursors.svg?color=brightgreen
    :target: https://pypi.python.org/pypi/mplcursors
 .. |conda-forge|
-   image:: https://img.shields.io/conda/v/conda-forge/mplcursors.svg
+   image:: 
https://img.shields.io/conda/v/conda-forge/mplcursors.svg?label=conda-forge&color=brightgreen
    :target: https://anaconda.org/conda-forge/mplcursors
-.. |Fedora Rawhide|
-   image:: 
https://repology.org/badge/version-for-repo/fedora_rawhide/python:mplcursors.svg
-   :target: https://apps.fedoraproject.org/packages/python-mplcursors
+.. |Debian|
+   image:: 
https://repology.org/badge/version-for-repo/debian_testing/mplcursors.svg?header=Debian
+   :target: https://packages.debian.org/sid/main/python3-mplcursors
+.. |Fedora|
+   image:: 
https://repology.org/badge/version-for-repo/fedora_rawhide/python:mplcursors.svg?header=Fedora
+   :target: https://src.fedoraproject.org/rpms/python-mplcursors
+.. |openSUSE|
+   image:: 
https://repology.org/badge/version-for-repo/opensuse_tumbleweed/python:mplcursors.svg?header=openSUSE
+   :target: https://software.opensuse.org/package/python3-mplcursors
 .. |Read the Docs|
-   image:: https://readthedocs.org/projects/mplcursors/badge/?version=latest
+   image:: https://img.shields.io/readthedocs/mplcursors
    :target: http://mplcursors.readthedocs.io/en/latest/?badge=latest
-.. |Travis|
-   image:: https://travis-ci.org/anntzer/mplcursors.svg?branch=master
-   :target: https://travis-ci.org/anntzer/mplcursors
+.. |Build|
+   image:: 
https://img.shields.io/github/workflow/status/anntzer/mplcursors/build
+   :target: https://github.com/anntzer/mplcursors/actions
 .. |CodeCov|
-   image:: https://codecov.io/gh/anntzer/mplcursors/master.svg
+   image:: https://img.shields.io/codecov/c/github/anntzer/mplcursors
    :target: https://codecov.io/gh/anntzer/mplcursors
 
 mplcursors provides interactive data selection cursors for Matplotlib_.  It is
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/doc/Makefile 
new/mplcursors-0.4/doc/Makefile
--- old/mplcursors-0.3/doc/Makefile     2018-09-06 21:08:08.000000000 +0200
+++ new/mplcursors-0.4/doc/Makefile     2020-05-06 22:34:21.000000000 +0200
@@ -4,7 +4,6 @@
 # You can set these variables from the command line.
 SPHINXOPTS    =
 SPHINXBUILD   = python -msphinx
-SPHINXPROJ    = mplcursors
 SOURCEDIR     = source
 BUILDDIR      = build
 
@@ -17,4 +16,4 @@
 # Catch-all target: route all unknown targets to Sphinx using the new
 # "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
 %: Makefile
-       @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
+       @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/doc/make.bat 
new/mplcursors-0.4/doc/make.bat
--- old/mplcursors-0.3/doc/make.bat     2018-03-27 11:46:49.000000000 +0200
+++ new/mplcursors-0.4/doc/make.bat     2020-05-06 22:34:21.000000000 +0200
@@ -9,7 +9,6 @@
 )
 set SOURCEDIR=source
 set BUILDDIR=build
-set SPHINXPROJ=mplcursors
 
 if "%1" == "" goto help
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mplcursors-0.3/doc/source/_static/hide_some_gallery_elements.css 
new/mplcursors-0.4/doc/source/_static/hide_some_gallery_elements.css
--- old/mplcursors-0.3/doc/source/_static/hide_some_gallery_elements.css        
1970-01-01 01:00:00.000000000 +0100
+++ new/mplcursors-0.4/doc/source/_static/hide_some_gallery_elements.css        
2020-07-21 23:14:18.000000000 +0200
@@ -0,0 +1,3 @@
+div.sphx-glr-download-link-note, div.sphx-glr-download-jupyter {
+  display: none;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/doc/source/conf.py 
new/mplcursors-0.4/doc/source/conf.py
--- old/mplcursors-0.3/doc/source/conf.py       2019-09-15 20:40:47.000000000 
+0200
+++ new/mplcursors-0.4/doc/source/conf.py       2020-07-21 23:20:07.000000000 
+0200
@@ -14,7 +14,7 @@
     'sphinx.ext.viewcode',
     'sphinx_gallery.gen_gallery',
 ]
-needs_extensions = {'sphinx_gallery.gen_gallery': '0.1.13'}
+needs_extensions = {'sphinx_gallery.gen_gallery': '0.6.0'}
 
 source_suffix = '.rst'
 exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
@@ -24,7 +24,7 @@
 copyright = '2016???present, Antony Lee'
 author = 'Antony Lee'
 
-# RTD modifies conf.py, making versioneer mark the version as -dirty.
+# RTD modifies conf.py, making setuptools_scm mark the version as -dirty.
 version = release = re.sub(r'\.dirty$', '', mplcursors.__version__)
 
 language = 'en'
@@ -38,7 +38,6 @@
 # -- Options for HTML output ----------------------------------------------
 
 html_theme = 'alabaster'
-html_sidebars = {'**': ['about.html', 'navigation.html', 'localtoc.html']}
 html_theme_options = {
     'description': 'Interactive data selection cursors for Matplotlib.',
     'github_user': 'anntzer',
@@ -47,6 +46,9 @@
     'github_button': False,
     'code_font_size': '80%',
 }
+html_css_files = ['hide_some_gallery_elements.css']
+html_static_path = ['_static']
+html_sidebars = {'**': ['about.html', 'navigation.html', 'localtoc.html']}
 # html_last_updated_fmt = ''  # bitprophet/alabaster#93
 
 htmlhelp_basename = 'mplcursors_doc'
@@ -102,7 +104,7 @@
 os.environ.pop("DISPLAY", None)  # Don't warn about non-GUI when running s-g.
 
 sphinx_gallery_conf = {
-    'backreferences_dir': False,
+    'backreferences_dir': None,
     'examples_dirs': '../../examples',
     'filename_pattern': r'.*\.py',
     'gallery_dirs': 'examples',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/doc/source/index.rst 
new/mplcursors-0.4/doc/source/index.rst
--- old/mplcursors-0.3/doc/source/index.rst     2019-09-15 20:41:02.000000000 
+0200
+++ new/mplcursors-0.4/doc/source/index.rst     2020-11-11 11:32:12.000000000 
+0100
@@ -1,17 +1,26 @@
 mplcursors ??? Interactive data selection cursors for Matplotlib
 ==============================================================
 
-|PyPI| |Travis| |CodeCov|
+|GitHub| |PyPI| |conda-forge| |Debian| |Fedora| |openSUSE|
 
+.. |GitHub|
+   image:: https://img.shields.io/badge/github-anntzer%2Fmplcursors-brightgreen
+   :target: https://github.com/anntzer/mplcursors
 .. |PyPI|
    image:: https://img.shields.io/pypi/v/mplcursors.svg
    :target: https://pypi.python.org/pypi/mplcursors
-.. |Travis|
-   image:: https://travis-ci.org/anntzer/mplcursors.svg?branch=master
-   :target: https://travis-ci.org/anntzer/mplcursors
-.. |CodeCov|
-   image:: https://codecov.io/gh/anntzer/mplcursors/master.svg
-   :target: https://codecov.io/gh/anntzer/mplcursors
+.. |conda-forge|
+   image:: 
https://img.shields.io/conda/v/conda-forge/mplcursors.svg?label=conda-forge
+   :target: https://anaconda.org/conda-forge/mplcursors
+.. |Debian|
+   image:: 
https://repology.org/badge/version-for-repo/debian_testing/mplcursors.svg?header=Debian
+   :target: https://packages.debian.org/sid/main/python3-mplcursors
+.. |Fedora|
+   image:: 
https://repology.org/badge/version-for-repo/fedora_rawhide/python:mplcursors.svg?header=Fedora
+   :target: https://src.fedoraproject.org/rpms/python-mplcursors
+.. |openSUSE|
+   image:: 
https://repology.org/badge/version-for-repo/opensuse_tumbleweed/python:mplcursors.svg?header=openSUSE
+   :target: https://software.opensuse.org/package/python3-mplcursors
 
 :mod:`mplcursors` provides interactive data selection cursors for Matplotlib_.
 It is inspired from mpldatacursor_, with a much simplified API.
@@ -260,6 +269,17 @@
 :class:`~matplotlib.animation.ArtistAnimation`\s which themselves fiddle with
 artist visibility).
 
+Users
+-----
+
+Some users of mplcursors (please let me know if you find this package useful!):
+
+- `reliability <https://reliability.readthedocs.io/>`_: A Python library for
+  reliability engineering.
+- `RepoDash <https://laurencemolloy.github.io/RepoDash/>`_:
+  Performance metrics for Github repositories.
+- `topplot <https://gitlab.com/eBardie/topplot>`_: Munge top logs in to graphs.
+
 Indices and tables
 ==================
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/examples/bar.py 
new/mplcursors-0.4/examples/bar.py
--- old/mplcursors-0.3/examples/bar.py  2019-09-15 20:41:02.000000000 +0200
+++ new/mplcursors-0.4/examples/bar.py  2020-05-06 22:34:21.000000000 +0200
@@ -14,11 +14,15 @@
 labels = string.ascii_uppercase[:9]
 ax.set(xticks=range(9), xticklabels=labels, title="Hover over a bar")
 
-cursor = mplcursors.cursor(hover=True)
+# With HoverMode.Transient, the annotation is removed as soon as the mouse
+# leaves the artist.  Alternatively, one can use HoverMode.Persistent (or True)
+# which keeps the annotation until another artist gets selected.
+cursor = mplcursors.cursor(hover=mplcursors.HoverMode.Transient)
 @cursor.connect("add")
 def on_add(sel):
     x, y, width, height = sel.artist[sel.target.index].get_bbox().bounds
-    sel.annotation.set(text=f"{x+width/2}: {height}", position=(0, 20))
+    sel.annotation.set(text=f"{x+width/2}: {height}",
+                       position=(0, 20), anncoords="offset points")
     sel.annotation.xy = (x + width / 2, y + height)
 
 plt.show()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/examples/hover.py 
new/mplcursors-0.4/examples/hover.py
--- old/mplcursors-0.3/examples/hover.py        2018-03-27 11:46:49.000000000 
+0200
+++ new/mplcursors-0.4/examples/hover.py        2020-05-06 22:34:22.000000000 
+0200
@@ -2,7 +2,7 @@
 Annotate on hover
 =================
 
-When ``hover`` is set to ``True``, annotations are displayed when the mouse
+When *hover* is set to ``True``, annotations are displayed when the mouse
 hovers over the artist, without the need for clicking.
 """
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/examples/labeled_points.py 
new/mplcursors-0.4/examples/labeled_points.py
--- old/mplcursors-0.3/examples/labeled_points.py       2018-03-27 
11:46:49.000000000 +0200
+++ new/mplcursors-0.4/examples/labeled_points.py       2020-05-06 
22:34:22.000000000 +0200
@@ -2,7 +2,7 @@
 Displaying a custom label for each individual point
 ===================================================
 
-mpldatacursor's ``point_labels`` functionality can be emulated with an event
+mpldatacursor's *point_labels* functionality can be emulated with an event
 handler that sets the annotation text with a label selected from the target
 index.
 """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/lib/mplcursors/__init__.py 
new/mplcursors-0.4/lib/mplcursors/__init__.py
--- old/mplcursors-0.3/lib/mplcursors/__init__.py       2018-03-27 
11:46:49.000000000 +0200
+++ new/mplcursors-0.4/lib/mplcursors/__init__.py       2020-05-06 
22:34:22.000000000 +0200
@@ -1,18 +1,12 @@
 try:
-    import setuptools_scm
-    __version__ = setuptools_scm.get_version(  # xref setup.py
-        root="../..", relative_to=__file__,
-        version_scheme="post-release", local_scheme="node-and-date")
-except (ImportError, LookupError):
-    try:
-        from ._version import version as __version__
-    except ImportError:
-        pass
+    from ._version import version as __version__
+except ImportError:
+    __version__ = "(unknown version)"
 
 
-from ._mplcursors import Cursor, cursor
+from ._mplcursors import Cursor, HoverMode, cursor
 from ._pick_info import Selection, compute_pick, get_ann_text, make_highlight
 
 
-__all__ = ["Cursor", "cursor", "Selection",
+__all__ = ["Cursor", "HoverMode", "cursor", "Selection",
            "compute_pick", "get_ann_text", "make_highlight"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/lib/mplcursors/_mplcursors.py 
new/mplcursors-0.4/lib/mplcursors/_mplcursors.py
--- old/mplcursors-0.3/lib/mplcursors/_mplcursors.py    2019-09-15 
20:41:02.000000000 +0200
+++ new/mplcursors-0.4/lib/mplcursors/_mplcursors.py    2020-12-09 
21:26:31.000000000 +0100
@@ -1,7 +1,7 @@
-from collections import Counter
 from collections.abc import Iterable
 from contextlib import suppress
 import copy
+from enum import IntEnum
 from functools import partial
 import sys
 import weakref
@@ -41,13 +41,13 @@
 )
 _default_annotation_positions = [
     dict(position=(-15, 15), anncoords="offset points",
-         ha="right", va="bottom"),
+         horizontalalignment="right", verticalalignment="bottom"),
     dict(position=(15, 15), anncoords="offset points",
-         ha="left", va="bottom"),
+         horizontalalignment="left", verticalalignment="bottom"),
     dict(position=(15, -15), anncoords="offset points",
-         ha="left", va="top"),
+         horizontalalignment="left", verticalalignment="top"),
     dict(position=(-15, -15), anncoords="offset points",
-         ha="right", va="top"),
+         horizontalalignment="right", verticalalignment="top"),
 ]
 _default_highlight_kwargs = dict(
     # Only the kwargs corresponding to properties of the artist will be passed.
@@ -66,6 +66,17 @@
     """A string subclass solely for marking purposes."""
 
 
+def _mouse_event_matches(event, spec):
+    """
+    Return whether a mouse event "matches" an event spec, which is either a
+    single mouse button, or a mapping matched against ``vars(event)``, e.g.
+    ``{"button": 1, "key": "control"}``.
+    """
+    if isinstance(spec, int):
+        spec = {"button": spec}
+    return all(getattr(event, k) == v for k, v in spec.items())
+
+
 def _get_rounded_intersection_area(bbox_1, bbox_2):
     """Compute the intersection area between two bboxes rounded to 8 digits."""
     # The rounding allows sorting areas without floating point issues.
@@ -99,6 +110,10 @@
     return event
 
 
+class HoverMode(IntEnum):
+    NoHover, Persistent, Transient = range(3)
+
+
 class Cursor:
     """
     A cursor for selecting Matplotlib artists.
@@ -136,22 +151,30 @@
         artists : List[Artist]
             A list of artists that can be selected by this cursor.
 
-        multiple : bool, optional
-            Whether multiple artists can be "on" at the same time (defaults to
-            False).
+        multiple : bool, default: False
+            Whether multiple artists can be "on" at the same time.
 
-        highlight : bool, optional
+        highlight : bool, default: False
             Whether to also highlight the selected artist.  If so,
             "highlighter" artists will be placed as the first item in the
             :attr:`extras` attribute of the `Selection`.
 
-        hover : bool, optional
+        hover : `HoverMode`, default: False
             Whether to select artists upon hovering instead of by clicking.
             (Hovering over an artist while a button is pressed will not trigger
             a selection; right clicking on an annotation will still remove it.)
+            Possible values are
+
+            - False, alias `HoverMode.NoHover`: hovering is inactive.
+            - True, alias `HoverMode.Persistent`: hovering is active;
+              annotations remain in place even after the mouse moves away from
+              the artist (until another artist is selected, if *multiple* is
+              False.
+            - 2, alias `HoverMode.Transient`: hovering is active; annotations
+              are removed as soon as the mouse moves away from the artist.
 
         bindings : dict, optional
-            A mapping of button and keybindings to actions.  Valid entries are:
+            A mapping of actions to button and keybindings.  Valid keys are:
 
             ================ ==================================================
             'select'         mouse button to select an artist
@@ -175,16 +198,21 @@
             ================ ==================================================
 
             Missing entries will be set to the defaults.  In order to not
-            assign any binding to an action, set it to ``None``.
+            assign any binding to an action, set it to ``None``.  Modifier keys
+            (or other event properties) can be set for mouse button bindings by
+            passing them as e.g. ``{"button": 1, "key": "control"}``.
 
-        annotation_kwargs : dict, optional
+        annotation_kwargs : dict, default: {}
             Keyword argments passed to the `annotate
             <matplotlib.axes.Axes.annotate>` call.
 
         annotation_positions : List[dict], optional
             List of positions tried by the annotation positioning algorithm.
+            The default is to try four positions, 15 points to the NW, NE, SE,
+            and SW from the selected point; annotations that stay within the
+            axes are preferred.
 
-        highlight_kwargs : dict, optional
+        highlight_kwargs : dict, default: {}
             Keyword arguments used to create a highlighted artist.
         """
 
@@ -204,6 +232,7 @@
         self._last_auto_position = None
         self._callbacks = {"add": [], "remove": []}
 
+        self._hover = hover
         connect_pairs = [("key_press_event", self._on_key_press)]
         if hover:
             connect_pairs += [
@@ -223,11 +252,15 @@
         if unknown_bindings:
             raise ValueError("Unknown binding(s): {}".format(
                 ", ".join(sorted(unknown_bindings))))
-        duplicate_bindings = [
-            k for k, v in Counter(bindings.values()).items() if v > 1]
-        if duplicate_bindings:
-            raise ValueError("Duplicate binding(s): {}".format(
-                ", ".join(sorted(map(str, duplicate_bindings)))))
+        bindings_items = list(bindings.items())
+        for i in range(len(bindings)):
+            action, key = bindings_items[i]
+            for j in range(i):
+                other_action, other_key = bindings_items[j]
+                if key == other_key:
+                    raise ValueError(
+                        f"Duplicate bindings: {key} is used for "
+                        f"{other_action} and for {action}")
         self.bindings = bindings
 
         self.annotation_kwargs = (
@@ -334,8 +367,10 @@
         ann = axes.annotate(
             _pick_info.get_ann_text(*pi), xy=pi.target,
             xytext=(np.nan, np.nan),
-            ha=_MarkedStr("center"), va=_MarkedStr("center"),
+            horizontalalignment=_MarkedStr("center"),
+            verticalalignment=_MarkedStr("center"),
             visible=self.visible,
+            zorder=np.inf,
             **self.annotation_kwargs)
         ann.draggable(use_blit=not self._multiple)
         extras = []
@@ -371,12 +406,14 @@
             ann.set(**self.annotation_positions[auto_position])
             self._last_auto_position = auto_position
         else:
-            if isinstance(ann.get_ha(), _MarkedStr):
-                ann.set_ha({-1: "right", 0: "center", 1: "left"}[
-                    np.sign(np.nan_to_num(ann.xyann[0]))])
-            if isinstance(ann.get_va(), _MarkedStr):
-                ann.set_va({-1: "top", 0: "center", 1: "bottom"}[
-                    np.sign(np.nan_to_num(ann.xyann[1]))])
+            if isinstance(ann.get_horizontalalignment(), _MarkedStr):
+                ann.set_horizontalalignment(
+                    {-1: "right", 0: "center", 1: "left"}[
+                        np.sign(np.nan_to_num(ann.xyann[0]))])
+            if isinstance(ann.get_verticalalignment(), _MarkedStr):
+                ann.set_verticalalignment(
+                    {-1: "top", 0: "center", 1: "bottom"}[
+                        np.sign(np.nan_to_num(ann.xyann[1]))])
 
         if (extras
                 or len(self.selections) > 1 and not self._multiple
@@ -390,8 +427,7 @@
             # Fast path, only needed if the annotation has not been immediately
             # removed.
             figure.draw_artist(ann)
-            # Explicit argument needed on MacOSX backend.
-            figure.canvas.blit(figure.bbox)
+            figure.canvas.blit()
         # Removal comes after addition so that the fast blitting path works.
         if not self._multiple:
             for sel in self.selections[:-1]:
@@ -442,6 +478,14 @@
 
             # Make label non-draggable:
             lambda sel: sel.draggable(False)
+
+        Note that when a single event causes both the removal of an "old"
+        selection and the addition of a "new" one (typically, clicking on an
+        artist when another one is selected, or hovering -- both assuming that
+        ``multiple=False``), the "add" callback is called *first*.  This allows
+        it, in particular, to "cancel" the addition (by immediately removing
+        the "new" selection) and thus avoid removing the "old" selection.
+        However, this call order may change in a future release.
         """
         if event not in self._callbacks:
             raise ValueError(f"{event!r} is not a valid cursor event")
@@ -481,20 +525,20 @@
 
     def _nonhover_handler(self, event):
         if event.name == "button_press_event":
-            if event.button == self.bindings["select"]:
-                self._on_select_button_press(event)
-            if event.button == self.bindings["deselect"]:
-                self._on_deselect_button_press(event)
+            if _mouse_event_matches(event, self.bindings["select"]):
+                self._on_select_event(event)
+            if _mouse_event_matches(event, self.bindings["deselect"]):
+                self._on_deselect_event(event)
 
     def _hover_handler(self, event):
         if event.name == "motion_notify_event" and event.button is None:
             # Filter away events where the mouse is pressed, in particular to
             # avoid conflicts between hover and draggable.
-            self._on_select_button_press(event)
+            self._on_select_event(event)
         elif (event.name == "button_press_event"
-              and event.button == self.bindings["deselect"]):
+              and _mouse_event_matches(event, self.bindings["deselect"])):
             # Still allow removing the annotation by right clicking.
-            self._on_deselect_button_press(event)
+            self._on_deselect_event(event)
 
     def _filter_mouse_event(self, event):
         # Accept the event iff we are enabled, and either
@@ -505,7 +549,7 @@
         return (self.enabled
                 and event.canvas.widgetlock.locked() == event.dblclick)
 
-    def _on_select_button_press(self, event):
+    def _on_select_event(self, event):
         if not self._filter_mouse_event(event):
             return
         # Work around lack of support for twinned axes.
@@ -515,18 +559,30 @@
         for artist in self.artists:
             if (artist.axes is None  # Removed or figure-level artist.
                     or event.canvas is not artist.figure.canvas
+                    or not artist.get_visible()
                     or not artist.axes.contains(event)[0]):  # Cropped by axes.
                 continue
             pi = _pick_info.compute_pick(artist, per_axes_event[artist.axes])
-            if pi and not any((pi.artist, tuple(pi.target))
-                              == (other.artist, tuple(other.target))
-                              for other in self._selections):
+            if pi:
                 pis.append(pi)
-        if not pis:
-            return
-        self.add_selection(min(pis, key=lambda pi: pi.dist))
+        # The any() check avoids picking an already selected artist at the same
+        # point, as likely the user is just dragging it.  We check this here
+        # rather than not adding the pick_info to pis at all, because in
+        # transient hover mode, selections should be cleared out only when no
+        # candidate picks (including such duplicates) exist at all.
+        pi = min((pi for pi in pis
+                  if not any((pi.artist, tuple(pi.target))
+                             == (other.artist, tuple(other.target))
+                             for other in self._selections)),
+                 key=lambda pi: pi.dist, default=None)
+        if pi:
+            self.add_selection(pi)
+        elif not pis and self._hover == HoverMode.Transient:
+            for sel in self.selections:
+                if event.canvas is sel.annotation.figure.canvas:
+                    self.remove_selection(sel)
 
-    def _on_deselect_button_press(self, event):
+    def _on_deselect_event(self, event):
         if not self._filter_mouse_event(event):
             return
         for sel in self.selections[::-1]:  # LIFO.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/lib/mplcursors/_pick_info.py 
new/mplcursors-0.4/lib/mplcursors/_pick_info.py
--- old/mplcursors-0.3/lib/mplcursors/_pick_info.py     2019-09-15 
20:57:07.000000000 +0200
+++ new/mplcursors-0.4/lib/mplcursors/_pick_info.py     2020-11-11 
11:32:12.000000000 +0100
@@ -93,6 +93,9 @@
     figure = property(lambda self: _artist_in_container(self.container).figure)
     axes = property(lambda self: _artist_in_container(self.container).axes)
 
+    def get_visible(self):
+        return True  # For lack of anything better.
+
 
 class AttrArray(np.ndarray):
     """An array subclass that can store additional attributes."""
@@ -287,20 +290,14 @@
         ds = np.hypot(*(xy - data_screen_xy).T)
         try:
             argmin = np.nanargmin(ds)
-            dmin = ds[argmin]
-        except (ValueError, IndexError):
-            # numpy 1.7.0's `nanargmin([nan])` returns nan, so
-            # `ds[argmin]` raises IndexError.  In later versions of numpy,
-            # `nanargmin([nan])` raises ValueError (the release notes for 1.8.0
-            # are incorrect on this topic).
+        except ValueError:  # Raised by nanargmin([nan]).
             pass
         else:
-            # More precise than transforming back.
             target = _with_attrs(
-                _untransform(
+                _untransform(  # More precise than transforming back.
                     data_xy[argmin], data_screen_xy[argmin], artist.axes),
                 index=argmin)
-            sels.append(Selection(artist, target, dmin, None, None))
+            sels.append(Selection(artist, target, ds[argmin], None, None))
     # If lines are visible, find the closest projection.
     if (artist.get_linestyle() not in ["None", "none", " ", "", None]
             and len(artist.get_xydata()) > 1):
@@ -332,13 +329,15 @@
 @compute_pick.register(PatchCollection)
 @compute_pick.register(PathCollection)
 def _(artist, event):
-    # Use the C implementation to prune the list of segments.
-    contains, info = artist.contains(event)
-    if not contains:
-        return
     offsets = artist.get_offsets()
     paths = artist.get_paths()
     if _is_scatter(artist):
+        # Use the C implementation to prune the list of segments -- but only
+        # for scatter plots as that implementation is inconsistent with Line2D
+        # for segment-like collections (matplotlib/matplotlib#17279).
+        contains, info = artist.contains(event)
+        if not contains:
+            return
         inds = info["ind"]
         offsets = artist.get_offsets()[inds]
         offsets_screen = artist.get_offset_transform().transform(offsets)
@@ -350,23 +349,21 @@
         return Selection(artist, target, ds[argmin], None, None)
     else:
         # Note that this won't select implicitly closed paths.
-        sels = [
+        sels = [*filter(None, [
             _compute_projection_pick(
                 artist,
                 Affine2D().translate(*offsets[ind % len(offsets)])
                 .transform_path(paths[ind % len(paths)]),
                 (event.x, event.y))
-            for ind in info["ind"]]
-        sel, index = min(
-            ((sel, info["ind"][idx]) for idx, sel in enumerate(sels) if sel),
-            key=lambda sel_idx: sel_idx[0].dist,
-            default=(None, None))
-        if sel:
-            sel = sel._replace(artist=artist)
-            sel.target.index = (index, sel.target.index)
-            if (isinstance(artist, PatchCollection)
-                    and sel.dist >= PATCH_PICKRADIUS):
-                sel = None
+            for ind in range(max(len(offsets), len(paths)))])]
+        if not sels:
+            return None
+        idx = min(range(len(sels)), key=lambda idx: sels[idx].dist)
+        sel = sels[idx]
+        if sel.dist >= artist.get_pickradius():
+            return None
+        sel = sel._replace(artist=artist)
+        sel.target.index = (idx, sel.target.index)
         return sel
 
 
@@ -464,14 +461,16 @@
     sel = compute_pick(container.markerline, event)
     if sel:
         return sel
-    idx_sel = min(filter(lambda idx_sel: idx_sel[1] is not None,
-                         ((idx, compute_pick(line, event))
-                          for idx, line in enumerate(container.stemlines))),
-                  key=lambda idx_sel: idx_sel[1].dist, default=None)
-    if idx_sel:
-        idx, _ = idx_sel
+    if not isinstance(container.stemlines, LineCollection):
+        warnings.warn("Only stem plots created with use_line_collection=True "
+                      "are supported.")
+        return
+    sel = compute_pick(container.stemlines, event)
+    if sel:
+        idx, _ = sel.target.index
         target = _with_attrs(
-            container.stemlines[idx].get_xydata()[-1], index=idx)
+            container.stemlines.get_segments()[idx][-1],
+            index=sel.target.index)
         return Selection(container, target, 0, None, None)
 
 
@@ -520,7 +519,7 @@
     classes follow.
     """
     warnings.warn(
-        f"Annotation support for {type(sel.artist).__name__} is missing")
+        f"Annotation support for {type(sel.artist).__name__} is missing.")
     return ""
 
 
@@ -632,10 +631,16 @@
                          for e in err]
                 # We'd normally want to check err.sum() == 0, but that can run
                 # into fp inaccuracies.
-                if len({s.lstrip("+-") for s in err_s}) == 1:
+                signs = "+-\N{MINUS SIGN}"
+                if len({s.lstrip(signs) for s in err_s}) == 1:
                     repl = rf"\1=$\2\\pm{err_s[1]}$\3"
                 else:
-                    err_s = [("+" if not s.startswith(("+", "-")) else "") + s
+                    # Replacing unicode minus by ascii minus don't change the
+                    # rendering as the string is mathtext, but allows keeping
+                    # the same tests across Matplotlib versions that use
+                    # unicode minus and those that don't.
+                    err_s = [("+" if not s.startswith(tuple(signs)) else "")
+                             + s.replace("\N{MINUS SIGN}", "-")
                              for s in err_s]
                     repl = r"\1=$\2_{%s}^{%s}$\3" % tuple(err_s)
                 ann_text = re.sub(f"({dir})=(.*)(\n?)", repl, ann_text)
@@ -747,7 +752,7 @@
     classes follow.
     """
     warnings.warn(
-        f"Highlight support for {type(sel.artist).__name__} is missing")
+        f"Highlight support for {type(sel.artist).__name__} is missing.")
 
 
 def _set_valid_props(artist, kwargs):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/lib/mplcursors/_version.py 
new/mplcursors-0.4/lib/mplcursors/_version.py
--- old/mplcursors-0.3/lib/mplcursors/_version.py       2019-09-16 
01:55:05.000000000 +0200
+++ new/mplcursors-0.4/lib/mplcursors/_version.py       2020-12-09 
22:11:21.000000000 +0100
@@ -1,4 +1,4 @@
 # coding: utf-8
 # file generated by setuptools_scm
 # don't change, don't track in version control
-version = '0.3'
+version = '0.4'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/lib/mplcursors.egg-info/PKG-INFO 
new/mplcursors-0.4/lib/mplcursors.egg-info/PKG-INFO
--- old/mplcursors-0.3/lib/mplcursors.egg-info/PKG-INFO 2019-09-16 
01:55:05.000000000 +0200
+++ new/mplcursors-0.4/lib/mplcursors.egg-info/PKG-INFO 2020-12-09 
22:11:21.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: mplcursors
-Version: 0.3
+Version: 0.4
 Summary: Interactive data selection cursors for Matplotlib.
 Home-page: https://github.com/anntzer/mplcursors
 Author: Antony Lee
@@ -8,27 +8,35 @@
 Description: Interactive data selection cursors for Matplotlib
         =================================================
         
-        |PyPI| |conda-forge| |Fedora Rawhide|
-        
-        |Read the Docs| |Travis| |CodeCov|
+        | |GitHub| |PyPI| |conda-forge| |Debian| |Fedora| |openSUSE|
+        | |Read the Docs| |Build| |CodeCov|
         
+        .. |GitHub|
+           image:: 
https://img.shields.io/badge/github-anntzer%2Fmplcursors-brightgreen
+           :target: https://github.com/anntzer/mplcursors
         .. |PyPI|
-           image:: https://img.shields.io/pypi/v/mplcursors.svg
+           image:: 
https://img.shields.io/pypi/v/mplcursors.svg?color=brightgreen
            :target: https://pypi.python.org/pypi/mplcursors
         .. |conda-forge|
-           image:: https://img.shields.io/conda/v/conda-forge/mplcursors.svg
+           image:: 
https://img.shields.io/conda/v/conda-forge/mplcursors.svg?label=conda-forge&color=brightgreen
            :target: https://anaconda.org/conda-forge/mplcursors
-        .. |Fedora Rawhide|
-           image:: 
https://repology.org/badge/version-for-repo/fedora_rawhide/python:mplcursors.svg
-           :target: https://apps.fedoraproject.org/packages/python-mplcursors
+        .. |Debian|
+           image:: 
https://repology.org/badge/version-for-repo/debian_testing/mplcursors.svg?header=Debian
+           :target: https://packages.debian.org/sid/main/python3-mplcursors
+        .. |Fedora|
+           image:: 
https://repology.org/badge/version-for-repo/fedora_rawhide/python:mplcursors.svg?header=Fedora
+           :target: https://src.fedoraproject.org/rpms/python-mplcursors
+        .. |openSUSE|
+           image:: 
https://repology.org/badge/version-for-repo/opensuse_tumbleweed/python:mplcursors.svg?header=openSUSE
+           :target: https://software.opensuse.org/package/python3-mplcursors
         .. |Read the Docs|
-           image:: 
https://readthedocs.org/projects/mplcursors/badge/?version=latest
+           image:: https://img.shields.io/readthedocs/mplcursors
            :target: http://mplcursors.readthedocs.io/en/latest/?badge=latest
-        .. |Travis|
-           image:: https://travis-ci.org/anntzer/mplcursors.svg?branch=master
-           :target: https://travis-ci.org/anntzer/mplcursors
+        .. |Build|
+           image:: 
https://img.shields.io/github/workflow/status/anntzer/mplcursors/build
+           :target: https://github.com/anntzer/mplcursors/actions
         .. |CodeCov|
-           image:: https://codecov.io/gh/anntzer/mplcursors/master.svg
+           image:: https://img.shields.io/codecov/c/github/anntzer/mplcursors
            :target: https://codecov.io/gh/anntzer/mplcursors
         
         mplcursors provides interactive data selection cursors for 
Matplotlib_.  It is
@@ -56,6 +64,7 @@
         
 Platform: UNKNOWN
 Classifier: Development Status :: 4 - Beta
+Classifier: Framework :: Matplotlib
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Programming Language :: Python :: 3
 Requires-Python: >=3.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/lib/mplcursors.egg-info/SOURCES.txt 
new/mplcursors-0.4/lib/mplcursors.egg-info/SOURCES.txt
--- old/mplcursors-0.3/lib/mplcursors.egg-info/SOURCES.txt      2019-09-16 
01:55:05.000000000 +0200
+++ new/mplcursors-0.4/lib/mplcursors.egg-info/SOURCES.txt      2020-12-09 
22:11:21.000000000 +0100
@@ -3,13 +3,13 @@
 .doc-requirements.txt
 .gitignore
 .readthedocs.yml
-.travis.yml
 CHANGELOG.rst
 LICENSE.txt
 README.rst
 setup.cfg
 setup.py
 setupext.py
+.github/workflows/build.yml
 doc/.gitignore
 doc/Makefile
 doc/make.bat
@@ -18,6 +18,7 @@
 doc/source/index.rst
 doc/source/modules.rst
 doc/source/mplcursors.rst
+doc/source/_static/hide_some_gallery_elements.css
 doc/source/images/basic.png
 examples/README.txt
 examples/artist_labels.py
@@ -48,5 +49,4 @@
 lib/mplcursors.egg-info/top_level.txt
 tests/__init__.py
 tests/conftest.py
-tests/test_mplcursors.py
-vendor/setuptools_scm-1.17.0.egg
\ No newline at end of file
+tests/test_mplcursors.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/setup.cfg new/mplcursors-0.4/setup.cfg
--- old/mplcursors-0.3/setup.cfg        2019-09-16 01:55:05.000000000 +0200
+++ new/mplcursors-0.4/setup.cfg        2020-12-09 22:11:21.692934500 +0100
@@ -1,10 +1,3 @@
-[easy_install]
-allow_hosts = ""
-find_links = vendor
-
-[metadata]
-license_file = LICENSE.txt
-
 [tool:pytest]
 filterwarnings = 
        error
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/setup.py new/mplcursors-0.4/setup.py
--- old/mplcursors-0.3/setup.py 2019-09-15 20:41:02.000000000 +0200
+++ new/mplcursors-0.4/setup.py 2020-11-11 11:32:12.000000000 +0100
@@ -61,6 +61,7 @@
     license="MIT",
     classifiers=[
         "Development Status :: 4 - Beta",
+        "Framework :: Matplotlib",
         "License :: OSI Approved :: MIT License",
         "Programming Language :: Python :: 3",
     ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/tests/__init__.py 
new/mplcursors-0.4/tests/__init__.py
--- old/mplcursors-0.3/tests/__init__.py        2016-07-26 01:45:52.000000000 
+0200
+++ new/mplcursors-0.4/tests/__init__.py        2020-11-21 22:39:50.000000000 
+0100
@@ -1,7 +0,0 @@
-import os
-import matplotlib
-
-
-# For testing on Travis.
-if not os.environ.get("DISPLAY"):
-    matplotlib.use("Agg")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mplcursors-0.3/tests/test_mplcursors.py 
new/mplcursors-0.4/tests/test_mplcursors.py
--- old/mplcursors-0.3/tests/test_mplcursors.py 2019-09-15 20:57:07.000000000 
+0200
+++ new/mplcursors-0.4/tests/test_mplcursors.py 2020-07-22 01:13:18.000000000 
+0200
@@ -13,7 +13,7 @@
 from matplotlib.axes import Axes
 from matplotlib.backend_bases import KeyEvent, MouseEvent
 import mplcursors
-from mplcursors import _pick_info, Selection
+from mplcursors import _pick_info, Selection, HoverMode
 import numpy as np
 import pytest
 
@@ -38,16 +38,12 @@
 
 @pytest.fixture(autouse=True)
 def cleanup():
-    for fig in map(plt.figure, plt.get_fignums()):
-        fig.clf()
-
-
[email protected](autouse=True)
-def cleanup_warnings():
-    try:
-        yield
-    finally:
-        mplcursors.__warningregistry__ = {}
+    with mpl.rc_context({"axes.unicode_minus": False}):
+        try:
+            yield
+        finally:
+            mplcursors.__warningregistry__ = {}
+            plt.close("all")
 
 
 def _internal_warnings(record):
@@ -124,8 +120,8 @@
     # On the line.
     _process_event("__mouse_click__", ax, (.1, .4), 1)
     assert len(cursor.selections) == len(ax.texts) == 1
-    assert (_parse_annotation(cursor.selections[0], "foo\nx=(.*)\ny=(.*)")
-            == approx((.1, .4)))
+    assert _parse_annotation(
+        cursor.selections[0], "foo\nx=(.*)\ny=(.*)") == approx((.1, .4))
     # Not removing it.
     _process_event("__mouse_click__", ax, (0, 1), 3)
     assert len(cursor.selections) == len(ax.texts) == 1
@@ -133,8 +129,8 @@
     artist.set_label(None)
     _process_event("__mouse_click__", ax, (.6, .9), 1)
     assert len(cursor.selections) == len(ax.texts) == 2
-    assert (_parse_annotation(cursor.selections[1], "x=(.*)\ny=(.*)")
-            == approx((.6, .9)))
+    assert _parse_annotation(
+        cursor.selections[1], "x=(.*)\ny=(.*)") == approx((.6, .9))
     # Remove both of them (first removing the second one, to test
     # `Selection.__eq__` -- otherwise it is bypassed as `list.remove`
     # checks identity first).
@@ -163,7 +159,8 @@
     ax.scatter([0, 1], [0, 1], c=[2, 3])
     cursor = mplcursors.cursor()
     _process_event("__mouse_click__", ax, (0, 0), 1)
-    assert cursor.selections[0].annotation.get_text() == "x=0\ny=0\n[2]"
+    assert _parse_annotation(
+        cursor.selections[0], "x=(.*)\ny=(.*)\n\[(.*)\]") == (0, 0, 2)
 
 
 def test_steps_index():
@@ -260,25 +257,25 @@
     # Annotation text includes image value.
     _process_event("__mouse_click__", ax, (.25, .25), 1)
     sel, = cursor.selections
-    assert (_parse_annotation(sel, r"x=(.*)\ny=(.*)\n\[0\]")
-            == approx((.25, .25)))
+    assert _parse_annotation(
+        sel, r"x=(.*)\ny=(.*)\n\[0\]") == approx((.25, .25))
     # Moving around.
     _process_event("key_press_event", ax, (.123, .456), "shift+right")
     sel, = cursor.selections
-    assert sel.annotation.get_text() == "x=1\ny=0\n[1]"
+    assert _parse_annotation(sel, r"x=(.*)\ny=(.*)\n\[1\]") == (1, 0)
     assert array[sel.target.index] == 1
     _process_event("key_press_event", ax, (.123, .456), "shift+right")
     sel, = cursor.selections
-    assert sel.annotation.get_text() == "x=0\ny=0\n[0]"
+    assert _parse_annotation(sel, r"x=(.*)\ny=(.*)\n\[0\]") == (0, 0)
     assert array[sel.target.index] == 0
     _process_event("key_press_event", ax, (.123, .456), "shift+up")
     sel, = cursor.selections
-    assert (sel.annotation.get_text()
-            == {"upper": "x=0\ny=2\n[4]", "lower": "x=0\ny=1\n[2]"}[origin])
+    assert (_parse_annotation(sel, r"x=(.*)\ny=(.*)\n\[(.*)\]")
+            == {"upper": (0, 2, 4), "lower": (0, 1, 2)}[origin])
     assert array[sel.target.index] == {"upper": 4, "lower": 2}[origin]
     _process_event("key_press_event", ax, (.123, .456), "shift+down")
     sel, = cursor.selections
-    assert sel.annotation.get_text() == "x=0\ny=0\n[0]"
+    assert _parse_annotation(sel, r"x=(.*)\ny=(.*)\n\[0\]") == (0, 0)
     assert array[sel.target.index] == 0
 
     cursor = mplcursors.cursor()
@@ -295,12 +292,12 @@
     cursor = mplcursors.cursor()
     _process_event("__mouse_click__", ax, (0, 0), 1)
     sel, = cursor.selections
-    assert (_parse_annotation(sel, r"x=(.*)\ny=(.*)\n\[0.1, 0.2, 0.3\]")
-            == approx((0, 0)))
+    assert _parse_annotation(
+        sel, r"x=(.*)\ny=(.*)\n\[0.1, 0.2, 0.3\]") == approx((0, 0))
     _process_event("key_press_event", ax, (.123, .456), "shift+right")
     sel, = cursor.selections
-    assert (_parse_annotation(sel, r"x=(.*)\ny=(.*)\n\[0.4, 0.5, 0.6\]")
-            == approx((1, 0)))
+    assert _parse_annotation(
+        sel, r"x=(.*)\ny=(.*)\n\[0.4, 0.5, 0.6\]") == approx((1, 0))
 
 
 def test_image_subclass(ax):
@@ -315,7 +312,8 @@
 def test_linecollection(ax):
     ax.eventplot([0, 1])
     cursor = mplcursors.cursor()
-    _process_event("__mouse_click__", ax, (0, .5), 1)
+    _process_event("__mouse_click__", ax, (0, 0), 1)
+    _process_event("__mouse_click__", ax, (.5, 1), 1)
     assert len(cursor.selections) == 0
     _process_event("__mouse_click__", ax, (0, 1), 1)
     assert cursor.selections[0].target.index == approx((0, .5))
@@ -339,7 +337,8 @@
     _process_event("__mouse_click__", ax, (.5, 0), 1)
     assert len(cursor.selections) == 0
     _process_event("__mouse_click__", ax, (1, 0), 1)
-    assert cursor.selections[0].annotation.get_text() == "x=1\ny=0\n(1, 1)"
+    assert _parse_annotation(
+        cursor.selections[0], r"x=(.*)\ny=(.*)\n\(1, 1\)") == (1, 0)
 
 
 @pytest.mark.parametrize("plotter,order",
@@ -363,14 +362,17 @@
     assert len(cursor.selections) == 0
     _process_event("__mouse_click__", ax, (.5, .5), 1)
     assert cursor.selections[0].target == approx((.5, .5))
-    assert (_parse_annotation(cursor.selections[0], "x=(.*)\ny=(.*)")
-            == approx((.5, .5)))
+    assert _parse_annotation(
+        cursor.selections[0], "x=(.*)\ny=(.*)") == approx((.5, .5))
     _process_event("__mouse_click__", ax, (0, 1), 1)
     assert cursor.selections[0].target == approx((0, 0))
-    assert cursor.selections[0].annotation.get_text() == "x=0\ny=$0\\pm1$"
+    assert _parse_annotation(
+        cursor.selections[0], r"x=(.*)\ny=\$(.*)\\pm(.*)\$") == (0, 0, 1)
     _process_event("__mouse_click__", ax, (1, 2), 1)
-    assert cursor.selections[0].target == approx((1, 1))
-    assert cursor.selections[0].annotation.get_text() == "x=1\ny=$1_{-1}^{+2}$"
+    sel, = cursor.selections
+    assert sel.target == approx((1, 1))
+    assert _parse_annotation(
+        sel, r"x=(.*)\ny=\$(.*)_\{(.*)\}\^\{(.*)\}\$") == (1, 1, -1, 2)
 
 
 def test_dataless_errorbar(ax):
@@ -384,7 +386,7 @@
 
 def test_stem(ax):
     with pytest.warns(None):  # stem use_line_collection API change.
-        ax.stem([1, 2, 3])
+        ax.stem([1, 2, 3], use_line_collection=True)
     cursor = mplcursors.cursor()
     assert len(cursor.artists) == 1
     _process_event("__mouse_click__", ax, (.5, .5), 1)
@@ -455,14 +457,18 @@
     assert cursor.selections[0].target.index == 0
 
 
-def test_hover(ax):
[email protected](
+    "hover", [True, HoverMode.Persistent, 2, HoverMode.Transient])
+def test_hover(ax, hover):
     l1, = ax.plot([0, 1])
     l2, = ax.plot([1, 2])
-    cursor = mplcursors.cursor(hover=True)
+    cursor = mplcursors.cursor(hover=hover)
     _process_event("motion_notify_event", ax, (.5, .5), 1)
     assert len(cursor.selections) == 0  # No trigger if mouse button pressed.
     _process_event("motion_notify_event", ax, (.5, .5))
     assert cursor.selections[0].artist == l1
+    _process_event("motion_notify_event", ax, (.5, 1))
+    assert bool(cursor.selections) == (hover == HoverMode.Persistent)
     _process_event("motion_notify_event", ax, (.5, 1.5))
     assert cursor.selections[0].artist == l2
 
Binary files old/mplcursors-0.3/vendor/setuptools_scm-1.17.0.egg and 
new/mplcursors-0.4/vendor/setuptools_scm-1.17.0.egg differ

Reply via email to