From 51b8989d5c45b7ff6bf471ec15cb3ae9031b45ed Mon Sep 17 00:00:00 2001
From: Kyle Sunden <git@ksunden.space>
Date: Tue, 8 Nov 2022 01:06:37 -0600
Subject: [PATCH 1/3] Simplify appveyor to only use conda

Closes #24394

Adjust environment.yml

skip fontconfig private method test on windows

skip fontconfig private method test on windows

revert adding fontconfig explicitly to environment

Add wxpython back

Skip some wx tests

Upgrade to gtk4 in environment.yml

ignore private modules in getattr test

_backend_gtk would fail because it expects one of gtk4 or gtk3 to be imported first

Clean up appveyor.yml comments

skip memleak test for wxagg

conda activate does not, in fact, work

revert to simply activate
---
 .appveyor.yml                                 | 21 +++++-------------
 environment.yml                               |  2 +-
 .../tests/test_backends_interactive.py        |  7 ++++++
 lib/matplotlib/tests/test_font_manager.py     |  3 ++-
 lib/matplotlib/tests/test_getattr.py          | 22 ++++++++++++-------
 5 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/.appveyor.yml b/.appveyor.yml
index df7536f16c7e..0ed198d8f359 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -18,17 +18,14 @@ environment:
     PYTHONIOENCODING: UTF-8
     PYTEST_ARGS: -raR --numprocesses=auto --timeout=300 --durations=25
                  --cov-report= --cov=lib --log-level=DEBUG
-    PINNEDVERS: "pyzmq!=21.0.0,!=22.0.0"
 
   matrix:
     - PYTHON_VERSION: "3.8"
       CONDA_INSTALL_LOCN: "C:\\Miniconda3-x64"
       TEST_ALL: "no"
-      EXTRAREQS: "-r requirements/testing/extra.txt"
     - PYTHON_VERSION: "3.9"
       CONDA_INSTALL_LOCN: "C:\\Miniconda3-x64"
       TEST_ALL: "no"
-      EXTRAREQS: "-r requirements/testing/extra.txt"
 
 # We always use a 64-bit machine, but can build x86 distributions
 # with the PYTHON_ARCH variable
@@ -52,19 +49,13 @@ install:
   - conda config --prepend channels conda-forge
 
   # For building, use a new environment
-  - conda create -q -n test-environment python=%PYTHON_VERSION% tk "pip<22.0"
-  - activate test-environment
-  # pull pywin32 from conda because on py38 there is something wrong with finding
-  # the dlls when installed from pip
+  # Add python version to environment
+  # `^ ` escapes spaces for indentation
+  - echo ^ ^ - python=%PYTHON_VERSION% >> environment.yml
+  - conda env create -f environment.yml
+  - activate mpl-dev
   - conda install -c conda-forge pywin32
-  # install pyqt from conda-forge
-  - conda install -c conda-forge pyqt
   - echo %PYTHON_VERSION% %TARGET_ARCH%
-  # Install dependencies from PyPI.
-  - python -m pip install --upgrade -r requirements/testing/all.txt %EXTRAREQS% %PINNEDVERS%
-  # Install optional dependencies from PyPI.
-  # Sphinx is needed to run sphinxext tests
-  - python -m pip install --upgrade sphinx
   # Show the installed packages + versions
   - conda list
 
@@ -104,7 +95,7 @@ artifacts:
     type: zip
 
 on_finish:
-  - pip install codecov
+  - conda install codecov
   - codecov -e PYTHON_VERSION PLATFORM
 
 on_failure:
diff --git a/environment.yml b/environment.yml
index c9b7aa610720..e504b4b5e10b 100644
--- a/environment.yml
+++ b/environment.yml
@@ -44,7 +44,7 @@ dependencies:
   - coverage
   - flake8>=3.8
   - flake8-docstrings>=1.4.0
-  - gtk3
+  - gtk4
   - ipykernel
   - nbconvert[execute]!=6.0.0,!=6.0.1
   - nbformat!=5.0.0,!=5.0.1
diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py
index e5e6b295e798..e6d0b8febdc5 100644
--- a/lib/matplotlib/tests/test_backends_interactive.py
+++ b/lib/matplotlib/tests/test_backends_interactive.py
@@ -166,6 +166,8 @@ def test_interactive_backend(env, toolbar):
     if env["MPLBACKEND"] == "macosx":
         if toolbar == "toolmanager":
             pytest.skip("toolmanager is not implemented for macosx.")
+    if env["MPLBACKEND"] == "wx":
+        pytest.skip("wx backend is deprecated; tests failed on appveyor")
     proc = _run_helper(_test_interactive_impl,
                        json.dumps({"toolbar": toolbar}),
                        timeout=_test_timeout,
@@ -568,6 +570,11 @@ def test_figure_leak_20490(env, time_mem):
     # We haven't yet directly identified the leaks so test with a memory growth
     # threshold.
     pause_time, acceptable_memory_leakage = time_mem
+    if env["MPLBACKEND"] == "wx":
+        pytest.skip("wx backend is deprecated; tests failed on appveyor")
+    if env["MPLBACKEND"] == "wxagg" and sys.platform == "win32":
+        pytest.skip("tests failed on appveyor")
+
     if env["MPLBACKEND"] == "macosx" or (
             env["MPLBACKEND"] == "tkagg" and sys.platform == 'darwin'
     ):
diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py
index b1b5b37f039a..8aaeb863ece3 100644
--- a/lib/matplotlib/tests/test_font_manager.py
+++ b/lib/matplotlib/tests/test_font_manager.py
@@ -73,7 +73,8 @@ def test_otf():
             assert res == is_opentype_cff_font(f.fname)
 
 
-@pytest.mark.skipif(not has_fclist, reason='no fontconfig installed')
+@pytest.mark.skipif(sys.platform == "win32" or not has_fclist,
+                    reason='no fontconfig installed')
 def test_get_fontconfig_fonts():
     assert len(_get_fontconfig_fonts()) > 1
 
diff --git a/lib/matplotlib/tests/test_getattr.py b/lib/matplotlib/tests/test_getattr.py
index 71556b5b4c71..76ae3d7143ed 100644
--- a/lib/matplotlib/tests/test_getattr.py
+++ b/lib/matplotlib/tests/test_getattr.py
@@ -4,14 +4,20 @@
 import matplotlib
 import pytest
 
-# Get the names of all matplotlib submodules, except for the unit tests.
-module_names = [m.name for m in walk_packages(path=matplotlib.__path__,
-                                              prefix=f'{matplotlib.__name__}.')
-                if not m.name.startswith(__package__)]
+# Get the names of all matplotlib submodules,
+# except for the unit tests and private modules.
+module_names = [
+    m.name
+    for m in walk_packages(
+        path=matplotlib.__path__, prefix=f"{matplotlib.__name__}."
+    )
+    if not m.name.startswith(__package__)
+    and not any(x.startswith("_") for x in m.name.split("."))
+]
 
 
-@pytest.mark.parametrize('module_name', module_names)
-@pytest.mark.filterwarnings('ignore::DeprecationWarning')
+@pytest.mark.parametrize("module_name", module_names)
+@pytest.mark.filterwarnings("ignore::DeprecationWarning")
 def test_getattr(module_name):
     """
     Test that __getattr__ methods raise AttributeError for unknown keys.
@@ -21,8 +27,8 @@ def test_getattr(module_name):
         module = import_module(module_name)
     except (ImportError, RuntimeError) as e:
         # Skip modules that cannot be imported due to missing dependencies
-        pytest.skip(f'Cannot import {module_name} due to {e}')
+        pytest.skip(f"Cannot import {module_name} due to {e}")
 
-    key = 'THIS_SYMBOL_SHOULD_NOT_EXIST'
+    key = "THIS_SYMBOL_SHOULD_NOT_EXIST"
     if hasattr(module, key):
         delattr(module, key)

From e2131bb26e9c60bbb823f74dbb5e6de03ba43ee0 Mon Sep 17 00:00:00 2001
From: Kyle Sunden <git@ksunden.space>
Date: Thu, 10 Nov 2022 00:53:59 -0600
Subject: [PATCH 2/3] Just skip memleak test on windows entirely

---
 lib/matplotlib/tests/test_backends_interactive.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py
index e6d0b8febdc5..d22bd6969f91 100644
--- a/lib/matplotlib/tests/test_backends_interactive.py
+++ b/lib/matplotlib/tests/test_backends_interactive.py
@@ -562,6 +562,8 @@ def _test_figure_leak():
 
 
 # TODO: "0.1" memory threshold could be reduced 10x by fixing tkagg
+@pytest.mark.skipif(sys.platform == "win32",
+                    reason="appveyor tests fail; gh-22988 suggests reworking")
 @pytest.mark.parametrize("env", _get_testable_interactive_backends())
 @pytest.mark.parametrize("time_mem", [(0.0, 2_000_000), (0.1, 30_000_000)])
 def test_figure_leak_20490(env, time_mem):
@@ -572,8 +574,6 @@ def test_figure_leak_20490(env, time_mem):
     pause_time, acceptable_memory_leakage = time_mem
     if env["MPLBACKEND"] == "wx":
         pytest.skip("wx backend is deprecated; tests failed on appveyor")
-    if env["MPLBACKEND"] == "wxagg" and sys.platform == "win32":
-        pytest.skip("tests failed on appveyor")
 
     if env["MPLBACKEND"] == "macosx" or (
             env["MPLBACKEND"] == "tkagg" and sys.platform == 'darwin'

From 518416a5ac281fb1cce0919206acf0bfa548202a Mon Sep 17 00:00:00 2001
From: Kyle Sunden <git@ksunden.space>
Date: Fri, 11 Nov 2022 19:44:19 -0600
Subject: [PATCH 3/3] Revert to single quotes

---
 lib/matplotlib/tests/test_getattr.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lib/matplotlib/tests/test_getattr.py b/lib/matplotlib/tests/test_getattr.py
index 76ae3d7143ed..8fcb981746b2 100644
--- a/lib/matplotlib/tests/test_getattr.py
+++ b/lib/matplotlib/tests/test_getattr.py
@@ -9,15 +9,15 @@
 module_names = [
     m.name
     for m in walk_packages(
-        path=matplotlib.__path__, prefix=f"{matplotlib.__name__}."
+        path=matplotlib.__path__, prefix=f'{matplotlib.__name__}.'
     )
     if not m.name.startswith(__package__)
-    and not any(x.startswith("_") for x in m.name.split("."))
+    and not any(x.startswith('_') for x in m.name.split('.'))
 ]
 
 
-@pytest.mark.parametrize("module_name", module_names)
-@pytest.mark.filterwarnings("ignore::DeprecationWarning")
+@pytest.mark.parametrize('module_name', module_names)
+@pytest.mark.filterwarnings('ignore::DeprecationWarning')
 def test_getattr(module_name):
     """
     Test that __getattr__ methods raise AttributeError for unknown keys.
@@ -27,8 +27,8 @@ def test_getattr(module_name):
         module = import_module(module_name)
     except (ImportError, RuntimeError) as e:
         # Skip modules that cannot be imported due to missing dependencies
-        pytest.skip(f"Cannot import {module_name} due to {e}")
+        pytest.skip(f'Cannot import {module_name} due to {e}')
 
-    key = "THIS_SYMBOL_SHOULD_NOT_EXIST"
+    key = 'THIS_SYMBOL_SHOULD_NOT_EXIST'
     if hasattr(module, key):
         delattr(module, key)