8000 Included a shorter and more concise explanation · Impaler343/matplotlib@2990c46 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2990c46

Browse files
committed
Included a shorter and more concise explanation
pin pytest Deprecate plot_date Correctly set temporary pdf/pgf backends Calling `FigureCanvasPdf(figure)` will call `figure.set_canvas(self)`, meaning the `cbook._setattr_cm` context manager that wraps this change will see the _new_ canvas, and the old canvas isn't restored. Instead, just pass the `backend` parameter, as `savefig` already knows how to correctly save and restore the canvas if it needs to change backends. Fixes matplotlib#27865 Bump the actions group with 2 updates Bumps the actions group with 2 updates: [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) and [scientific-python/upload-nightly-action](https://github.com/scientific-python/upload-nightly-action). Updates `pypa/gh-action-pypi-publish` from 1.8.11 to 1.8.12 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](pypa/gh-action-pypi-publish@2f6f737...e53eb8b) Updates `scientific-python/upload-nightly-action` from 0.3.0 to 0.5.0 - [Release notes](https://github.com/scientific-python/upload-nightly-action/releases) - [Commits](scientific-python/upload-nightly-action@6e9304f...b67d7fc) --- updated-dependencies: - dependency-name: pypa/gh-action-pypi-publish dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: scientific-python/upload-nightly-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com> Bump pydata-sphinx-theme to 0.15 Fix search button placement in navbar Fix doc sidebar Fix version switcher url for circleCI Don't use custom CSS for announcement banner Disable parallel build Don't show doc source link Add dtype/copy args to internal testing class Use pybind11 string formatter for exception messages This can eventually be replaced by `std::format` when we require C++20. doc: add description of **kwargs usage to collections (matplotlib#27872) * doc: add description of **kwargs usage to collections * Update lib/matplotlib/collections.py Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> --------- Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> TST: adding tests of current clear behavior on ticks closes matplotlib#23839 DOC: update comments and docstrings Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Update lib/matplotlib/tests/test_axes.py BLD,Cygwin: Included Python.h first in src/_c_internal_utils.cpp Python.h needs to be included before any system includes. This is easiest if it is the first include. Interestingly, pybind11/pybind11.h does not include Python, possibly depending on downstream projects including Python.h beforehand. CI: Include Python.h first in _tkagg.cpp Needs to be included before system headers to set visibility macros for pybind11 BLD: Include Python.h first in _backend_agg.cpp BLD: Include Python.h before pybind11/pybind11.h pybind11 assumes Python.h is included first. CI: Specify python version for default pytest. CI,Cygwin: Run pytest with python -m pytest Cygwin pytest recently updated, and only installs pytest-3.9 CI,Cygwin: Revert use of alternatives to set pytest script. Cygwin pytest only installs pytest-3.9. I should possibly suggest using alternatives for that and pip. CI,Cygwin: Avoid running pytest in root directory. CI,Cygwin: Revert running pytest in different directory. CI,Cygwin: Call pytest-3.9 explicitly. BLD: Include Python.h first in src/_path.h BLD,BUG: Remove Python.h includes immediately preceeding pybind11/pybind11.h includes pybind11 seems decent about including Python.h before any system headers, once you chase three layers of includes in to see that. FIX: handle nans in RGBA input with ScalarMappables DOC: Update some animation related topics - use `set_data_3d` - cross-reference `Line2d` `set_data`, `set_xdata`, `set_ydata` - Rewrite parts of the FuncAnimation description Inspired through matplotlib#27830. Revert "Merge branch 'matplotlib:main' into doc-change" This reverts commit feeabe6, reversing changes made to bcbc2ef. Reapply "Merge branch 'matplotlib:main' into doc-change" This reverts commit ed91cee. Convert path extension to pybind11 Add a pybind11 type caster for agg::rect_d Add a pybind11 type caster for agg::trans_affine Add a pybind11 type caster for mpl::PathIterator Add a pybind11 type caster for e_snap_mode Add a pybind11 type caster for SketchParams Optimize convert_polygon_vector a bit FIX: don't copy twice on RGB input Fix devdocs version switcher Allow passing a transformation to secondary_[xy]axis Add transform argument to secondary axes Update _secax_docstring Move new params to end of functions Add input check to secondary axes Add tests Add examples Move transform type checks and improve docs Add type stubs Update _secax_docstring Move new params to end of functions Add input check to secondary axes Move transform type checks and improve docs Fix rebase error Fix stub for SecondaryAxis.__init__ Clarify example Add default param to secax constructor Fix stub for secax constructor Simplify imports Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com> Remove redundancy in docs Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com> Fix typo DOC: fix stray release note entry BLD: Add a fallback URL for FreeType FreeType is available from both Savannah and SourceForge, and sometimes AppVeyor seems to have trouble downloading from Savannah, so perhaps this fallback will help. We used to try both these URLs in the pre-Meson build system. DOC: State approximate documentation build time Since the doc build takes very long, an order-of-magnitude estimate is helpful to manage expectations. I'm not wedded to the actual numbers, if somebody has better suggestions. A quick test on an old i7 6700 (from 2015) yielded - `O=-j1`: 23min - `O=-j4`: 15min Doc build on CI is around 18min. Add BackendRegistry singleton class Use backend_registry for name of singleton instance Use class variables for immutable collections Review comments Update lib/matplotlib/backend_bases.py Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Linting/mypy fixes Remove INTERACTIVE_NON_WEB backend filter Small changes from review Use _api.caching_module_getattr for deprecated module-level attributes Add docstrings Add api changes and what new docs Fix docs Inline the deprecation function calls Import BackendFilter and backend_registry into matplotlib.backends.__init__.py Mypy fixes Remove unused _safe_pyplot_import Remove unneeded type annotations Make sure custom alpha param does not change 'none' colors in a list of colors (matplotlib#27845) * fix issue 27839, make sure alpha param does not affect none colors Apply review feedbacks Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> * Update lib/matplotlib/colors.py Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com> --------- Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Co-authored-by: Elliott Sales de Andrade <quantum.analyst@gmail.com> DOC: fix :mpltype:`color` role `inline.interpreted()` already returns a list of nodes. We mustn't wrap it in another list. Use :mpltype:`color` for color types
1 parent de4b7ca commit 2990c46

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1114
-875
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ commands:
147147
export RELEASE_TAG='-t release'
148148
fi
149149
mkdir -p logs
150-
make html O="-T $RELEASE_TAG -j4 -w /tmp/sphinxerrorswarnings.log"
150+
make html O="-T $RELEASE_TAG -j1 -w /tmp/sphinxerrorswarnings.log"
151151
rm -r build/html/_sources
152152
working_directory: doc
153153
- save_cache:

.github/workflows/cibuildwheel.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,4 @@ jobs:
213213
run: ls dist
214214

215215
- name: Publish package distributions to PyPI
216-
uses: pypa/gh-action-pypi-publish@2f6f737ca5f74c637829c0f5c3acd0e29ea5e8bf # v1.8.11
216+
uses: pypa/gh-action-pypi-publish@e53eb8b103ffcb59469888563dc324e3c8ba6f06 # v1.8.12

.github/workflows/cygwin.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ jobs:
243243
shell: bash.exe -eo pipefail -o igncr "{0}"
244244
id: cygwin-run-pytest
245245
run: |
246-
xvfb-run pytest -rfEsXR -n auto \
246+
xvfb-run pytest-3.${{ matrix.python-minor-version }} -rfEsXR -n auto \
247247
--maxfail=50 --timeout=300 --durations=25 \
248248
--cov-report=xml --cov=lib --log-level=DEBUG --color=yes
249249

.github/workflows/nightlies.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
ls -l dist/
6060
6161
- name: Upload wheels to Anaconda Cloud as nightlies
62-
uses: scientific-python/upload-nightly-action@6e9304f7a3a5501c6f98351537493ec898728299 # 0.3.0
62+
uses: scientific-python/upload-nightly-action@b67d7fcc0396e1128a474d1ab2b48aa94680f9fc # 0.5.0
6363
with:
6464
artifacts_path: dist
6565
anaconda_nightly_upload_token: ${{ secrets.ANACONDA_ORG_UPLOAD_TOKEN }}

doc/_static/mpl.css

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,6 @@
1414
margin: 0;
1515
}
1616

17-
/* Make announcement an error colour for unreleased documentation, and sticky. */
18-
#unreleased-message.bd-header-announcement {
19-
border-bottom: solid var(--pst-color-danger-highlight);
20-
color: var(--pst-color-danger-text);
21-
font-weight: var(--pst-admonition-font-weight-heading);
22-
position: sticky;
23-
top: 0;
24-
z-index: 1050;
25-
}
26-
27-
#unreleased-message.bd-header-announcement:after {
28-
background-color: var(--pst-color-danger);
29-
opacity: 1;
30-
}
31-
32-
#unreleased-message.bd-header-announcement a {
33-
color: var(--pst-color-danger-text);
34-
}
35-
36-
#unreleased-message.bd-header-announcement + .bd-navbar {
37-
top: 3rem; /* Minimum height of announcement header. */
38-
}
39-
4017
/* multi column TOC */
4118
.contents ul {
4219
list-style-type: none;

doc/api/backend_registry_api.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
********************************
2+
``matplotlib.backends.registry``
3+
********************************
4+
5+
.. automodule:: matplotlib.backends.registry
6+
:members:
7+
:undoc-members:
8+
:show-inheritance:

doc/api/index_backend_api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
backend_pdf_api.rst
1818
backend_pgf_api.rst
1919
backend_ps_api.rst
20+
backend_registry_api.rst
2021
backend_qt_api.rst
2122
backend_svg_api.rst
2223
backend_tk_api.rst
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
``rcsetup.interactive_bk``, ``rcsetup.non_interactive_bk`` and ``rcsetup.all_backends``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
... are deprecated and replaced by ``matplotlib.backends.backend_registry.list_builtin``
5+
with the following arguments
6+
7+
- ``matplotlib.backends.BackendFilter.INTERACTIVE``
8+
- ``matplotlib.backends.BackendFilter.NON_INTERACTIVE``
9+
- ``None``
10+
11+
respectively.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
``plot_date``
2+
~~~~~~~~~~~~~
3+
4+
Use of `~.Axes.plot_date` has been discouraged since Matplotlib 3.5 and the
5+
function is now formally deprecated.
6+
7+
- ``datetime``-like data should directly be plotted using `~.Axes.plot`.
8+
- If you need to plot plain numeric data as :ref:`date-format` or need to set
9+
a timezone, call ``ax.xaxis.axis_date`` / ``ax.yaxis.axis_date`` before
10+
`~.Axes.plot`. See `.Axis.axis_date`.

doc/api/prev_api_changes/api_changes_3.7.0/behaviour.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,13 @@ dtype and *levels* is not specified, *levels* now defaults to ``[0.5]`` for
120120
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
121121

122122
This can occur if the user explicitly passes a ``levels`` array with no values
123+
between ``z.min()`` and ``z.max()``; or if ``z`` has the same value everywhere.
123124

124125
``AxesImage.set_extent`` now raises ``TypeError`` for unknown keyword arguments
125126
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
126127

127128
It previously raised a `ValueError`.
128129

129-
etween ``z.min()`` and ``z.max()``; or if ``z`` has the same value everywhere.
130-
131130
Change of ``legend(loc="best")`` behavior
132131
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
133132

doc/conf.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@
3636

3737
# are we running circle CI?
3838
CIRCLECI = 'CIRCLECI' in os.environ
39+
# are we deploying this build to matplotlib.org/devdocs?
40+
# This is a copy of the logic in .circleci/deploy-docs.sh
41+
DEVDOCS = (
42+
CIRCLECI and
43+
(os.environ.get("CIRCLE_PROJECT_USERNAME") == "matplotlib") and
44+
(os.environ.get("CIRCLE_BRANCH") == "main") and
45+
(not os.environ.get("CIRCLE_PULL_REQUEST", "").startswith(
46+
"https://github.com/matplotlib/matplotlib/pull")))
3947

4048

4149
def _parse_skip_subdirs_file():
@@ -200,6 +208,7 @@ def _check_dependencies():
200208
missing_references_write_json = False
201209
missing_references_warn_unused_ignores = False
202210

211+
203212
intersphinx_mapping = {
204213
'Pillow': ('https://pillow.readthedocs.io/en/stable/', None),
205214
'cycler': ('https://matplotlib.org/cycler/', None),
@@ -484,15 +493,21 @@ def js_tag_with_cache_busting(js):
484493
# the server, but will be used as part of the key for caching by browsers
485494
# so when we do a new meso release the switcher will update "promptly" on
486495
# the stable and devdocs.
487-
"json_url": f"https://matplotlib.org/devdocs/_static/switcher.json?{SHA}",
496+
"json_url": (
497+
"https://output.circle-artifacts.com/output/job/"
498+
f"{os.environ['CIRCLE_WORKFLOW_JOB_ID']}/artifacts/"
499+
f"{os.environ['CIRCLE_NODE_INDEX']}"
500+
"/doc/build/html/_static/switcher.json" if CIRCLECI and not DEVDOCS else
501+
f"https://matplotlib.org/devdocs/_static/switcher.json?{SHA}"
502+
),
488503
"version_match": (
489504
# The start version to show. This must be in switcher.json.
490505
# We either go to 'stable' or to 'devdocs'
491506
'stable' if matplotlib.__version_info__.releaselevel == 'final'
492507
else 'devdocs')
493508
},
494509
"navbar_end": ["theme-switcher", "version-switcher", "mpl_icon_links"],
495-
"secondary_sidebar_items": "page-toc.html",
510+
"navbar_persistent": ["search-button"],
496511
"footer_start": ["copyright", "sphinx-version", "doc_version"],
497512
# We override the announcement template from pydata-sphinx-theme, where
498513
# this special value indicates the use of the unreleased banner. If we need
@@ -543,6 +558,9 @@ def js_tag_with_cache_busting(js):
543558
# '**': ['localtoc.html', 'pagesource.html']
544559
}
545560

561+
# Don't include link to doc source files
562+
html_show_sourcelink = False
563+
546564
# Copies only relevant code, not the '>>>' prompt
547565
copybutton_prompt_text = r'>>> |\.\.\. '
548566
copybutton_prompt_is_regexp = True

doc/devel/document.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ used. To build the documentation in html format, cd into :file:`doc/` and run:
6464
6565
make html
6666
67+
.. note::
68+
69+
Since the documentation is very large, the first build may take 10-20 minutes,
70+
depending on your machine. Subsequent builds will be faster.
71+
6772
Other useful invocations include
6873

6974
.. code-block:: sh

doc/sphinxext/custom_roles.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,8 @@ def mpltype_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
7272
if mpltype not in type_to_link_target:
7373
raise ValueError(f"Unknown mpltype: {mpltype!r}")
7474

75-
ref_nodes, messages = inliner.interpreted(
75+
node_list, messages = inliner.interpreted(
7676
mpltype, f'{mpltype} <{type_to_link_target[mpltype]}>', 'ref', lineno)
77-
node_list = [ref_nodes]
7877
return node_list, messages
7978

8079

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
BackendRegistry
2+
~~~~~~~~~~~~~~~
3+
4+
New :class:`~matplotlib.backends.registry.BackendRegistry` class is the single
5+
source of truth for available backends. The singleton instance is
6+
``matplotlib.backends.backend_registry``.

environment.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ dependencies:
3434
- ipywidgets
3535
- numpydoc>=1.0
3636
- packaging>=20
37-
- pydata-sphinx-theme~=0.13.1
37+
- pydata-sphinx-theme~=0.15.0
3838
- pyyaml
3939
- sphinx>=3.0.0,!=6.1.2
4040
- sphinx-copybutton
@@ -59,7 +59,7 @@ dependencies:
5959
- psutil
6060
- pre-commit
6161
- pydocstyle>=5.1.0
62-
- pytest!=4.6.0,!=5.4.0
62+
- pytest!=4.6.0,!=5.4.0,!=8.1.0
6363
- pytest-cov
6464
- pytest-rerunfailures
6565
- pytest-timeout

galleries/examples/animation/random_walk.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ def random_walk(num_steps, max_step=0.05):
2525

2626
def update_lines(num, walks, lines):
2727
for line, walk in zip(lines, walks):
28-
# NOTE: there is no .set_data() for 3 dim data...
29-
line.set_data(walk[:num, :2].T)
30-
line.set_3d_properties(walk[:num, 2])
28+
line.set_data_3d(walk[:num, :].T)
3129
return lines
3230

3331

galleries/examples/subplots_axes_and_figures/secondary_axis.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ def rad2deg(x):
4040
secax.set_xlabel('angle [rad]')
4141
plt.show()
4242

43+
# %%
44+
# By default, the secondary axis is drawn in the Axes coordinate space.
45+
# We can also provide a custom transform to place it in a different
46+
# coordinate space. Here we put the axis at Y = 0 in data coordinates.
47+
48+
fig, ax = plt.subplots(layout='constrained')
49+
x = np.arange(0, 10)
50+
np.random.seed(19680801)
51+
y = np.random.randn(len(x))
52+
ax.plot(x, y)
53+
ax.set_xlabel('X')
54+
ax.set_ylabel('Y')
55+
ax.set_title('Random data')
56+
57+
# Pass ax.transData as a transform to place the axis relative to our data
58+
secax = ax.secondary_xaxis(0, transform=ax.transData)
59+
secax.set_xlabel('Axis at Y = 0')
60+
plt.show()
61+
4362
# %%
4463
# Here is the case of converting from wavenumber to wavelength in a
4564
# log-log scale.

galleries/users_explain/animations/animations.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,28 +49,33 @@
4949
# *func* that modifies the data plotted on the figure. It uses the *frames*
5050
# parameter to determine the length of the animation. The *interval* parameter
5151
# is used to determine time in milliseconds between drawing of two frames.
52-
# Animating using `.FuncAnimation` would usually follow the following
53-
# structure:
54-
#
55-
# - Plot the initial figure, including all the required artists. Save all the
56-
# artists in variables so that they can be updated later on during the
57-
# animation.
58-
# - Create an animation function that updates the data in each artist to
59-
# generate the new frame at each function call.
60-
# - Create a `.FuncAnimation` object with the `.Figure` and the animation
61-
# function, along with the keyword arguments that determine the animation
62-
# properties.
63-
# - Use `.animation.Animation.save` or `.pyplot.show` to save or show the
64-
# animation.
65-
#
66-
# The update function uses the ``set_*`` function for different artists to
67-
# modify the data. The following table shows a few plotting methods, the artist
68-
# types they return and some methods that can be used to update them.
52+
# Animating using `.FuncAnimation` typically requires these steps:
53+
#
54+
# 1) Plot the initial figure as you would in a static plot. Save all the created
55+
# artists, which are returned by the plot functions, in variables so that you can
56+
# access and modify them later in the animation function.
57+
# 2) Create an animation function that updates the artists for a given frame.
58+
# Typically, this calls ``set_*`` methods of the artists.
59+
# 3) Create a `.FuncAnimation`, passing the `.Figure` and the animation function.
60+
# 4) Save or show the animation using one of the following methods:
61+
#
62+
# - `.pyplot.show` to show the animation in a window
63+
# - `.Animation.to_html5_video` to create a HTML ``<video>`` tag
64+
# - `.Animation.to_jshtml` to create HTML code with interactive JavaScript animation
65+
# controls
66+
# - `.Animation.save` to save the animation to a file
67+
#
68+
# The following table shows a few plotting methods, the artists they return and some
69+
# commonly used ``set_*`` methods that update the underlying data. While updating data
70+
# is the most common operation in animations, you can also update other aspects such as
71+
# color or text position.
6972
#
7073
# ======================================== ============================= ===========================
71-
# Plotting method Artist Set method
74+
# Plotting method Artist Data set methods
7275
# ======================================== ============================= ===========================
73-
# `.Axes.plot` `.lines.Line2D` `~.lines.Line2D.set_data`
76+
# `.Axes.plot` `.lines.Line2D` `~.Line2D.set_data`,
77+
# `~.Line2D.set_xdata`,
78+
# `~.Line2D.set_ydata`
7479
# `.Axes.scatter` `.collections.PathCollection` `~.collections.\
7580
# PathCollection.set_offsets`
7681
# `.Axes.imshow` `.image.AxesImage` ``AxesImage.set_data``
@@ -88,6 +93,7 @@
8893
# `~.Ellipse.set_center`,
8994
# `~.Ellipse.set_height`,
9095
# `~.Ellipse.set_width`
96+
# `.Axes.set_title`, `.Axes.text` `.text.Text` `~.Text.set_text`
9197
# ======================================== ============================= ===========================
9298
#
9399
# Covering the set methods for all types of artists is beyond the scope of this

0 commit comments

Comments
 (0)
0