Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/build_and_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:

strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macos-13]
os: [ubuntu-24.04, windows-2025, macos-15]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- run: |
git fetch --prune --unshallow
Expand All @@ -33,15 +33,15 @@ jobs:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- run: |
git fetch --prune --unshallow

- name: Build sdist
run: pipx run build --sdist

- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: artifact-sdist
path: dist/*.tar.gz
Expand All @@ -54,7 +54,7 @@ jobs:
# alternatively, to publish when a GitHub Release is created, use the following rule:
if: github.event_name == 'release' && github.event.action == 'published'
steps:
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v7
with:
pattern: artifact-*
path: dist
Expand All @@ -63,7 +63,7 @@ jobs:
- name: Check dist
run: ls dist

- uses: pypa/gh-action-pypi-publish@v1.5.0
- uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_TOKEN }}
Expand Down
40 changes: 10 additions & 30 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@ jobs:
strategy:
matrix:
pyver: ["3.9", "3.11", "3.13"]
os: [ubuntu-22.04, windows-latest]
os: [ubuntu-24.04, windows-latest]
include:
- pyver: "3.10"
os: ubuntu-24.04-arm
- pyver: "3.12"
os: ubuntu-24.04-arm
# - pyver: "3.14"
# os: ubuntu-24.04
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Setting up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.pyver }}
- name: Install dependencies
Expand All @@ -26,30 +33,3 @@ jobs:
pip install -e .
- name: Test with pytest
run: pytest

test_aarch64:
name: "Build aarch64 ${{ matrix.pyver }}"
strategy:
matrix:
pyver: [cp310-cp310, cp312-cp312]
fail-fast: false
runs-on: ubuntu-latest
env:
py: /opt/python/${{ matrix.pyver }}/bin/python
img: quay.io/pypa/manylinux_2_28_aarch64
steps:
- name: Checkout
uses: actions/checkout@v4
- run: |
docker run --rm --privileged hypriot/qemu-register
- uses: docker://quay.io/pypa/manylinux_2_28_aarch64
with:
args: |
bash -c "${{ env.py }} -m pip install virtualenv && ${{ env.py }} -m venv .env && \
source .env/bin/activate && \
pip install --upgrade setuptools && \
python -m pip install --disable-pip-version-check --upgrade pip && \
pip install -U -r requirements.txt -r requirements-dev.txt && \
pip install -e . && \
pytest && \
deactivate"
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ["setuptools", "Cython>=0.29.33", "setuptools_scm"]
requires = ["setuptools", "Cython>=0.29.33", "setuptools_scm", "numpy>=2.0.0"]
build-backend = "setuptools.build_meta"

[project]
Expand All @@ -9,7 +9,7 @@ description = "A little word cloud generator"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.9"
license = "MIT"
dependencies = ["numpy>=1.6.1", "pillow", "matplotlib"]
dependencies = ["numpy>=1.19", "pillow", "matplotlib"]
dynamic = ["version"]

[project.urls]
Expand Down
21 changes: 0 additions & 21 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,3 @@ def tmp_text_file(tmpdir_factory):
fn = tmpdir_factory.mktemp("data").join("empty.txt")
fn.write(b'')
return fn


@pytest.fixture
def no_cover_compat(request):
"""A pytest fixture to disable coverage.

.. note::

After the next version of ``pytest-cov`` is released, it will be possible to directly
use the ``no_cover`` fixture or marker.
"""

# Check with hasplugin to avoid getplugin exception in older pytest.
if request.config.pluginmanager.hasplugin('_cov'):
plugin = request.config.pluginmanager.getplugin('_cov')
if plugin.cov_controller:
plugin.cov_controller.cov.stop()
plugin.cov_controller.unset_env()
yield plugin.cov_controller
plugin.cov_controller.set_env()
plugin.cov_controller.cov.start()
3 changes: 2 additions & 1 deletion test/test_wordcloud_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,13 @@ def test_cli_regexp_invalid(tmp_text_file, capsys):
assert "Invalid regular expression" in err


@pytest.mark.no_cover
@pytest.mark.parametrize("command,expected_output, expected_exit_code", [
("wordcloud_cli --help", "usage: wordcloud_cli", 0),
("%s -m wordcloud --help" % sys.executable, "usage: __main__", 0),
("%s %s/../wordcloud/wordcloud_cli.py --help" % (sys.executable, os.path.dirname(__file__)), "To execute the CLI", 1),
])
def test_cli_as_executable(command, expected_output, expected_exit_code, tmpdir, capfd, no_cover_compat):
def test_cli_as_executable(command, expected_output, expected_exit_code, tmpdir, capfd):

ret_code = 0
try:
Expand Down
22 changes: 18 additions & 4 deletions wordcloud/wordcloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,25 +730,39 @@ def to_file(self, filename):
img.save(filename, optimize=True)
return self

def to_array(self):
def to_array(self, copy=None):
"""Convert to numpy array.

Parameters
----------
copy : bool
If `True`, then the object is copied. If `None` then the object is copied
only if needed. For `False` it raises a ValueError if a copy cannot be
avoided. Default: `None`.

Returns
-------
image : nd-array size (width, height, 3)
Word cloud image as numpy matrix.
"""
return np.array(self.to_image())
return np.asarray(self.to_image(), copy=copy)

def __array__(self):
def __array__(self, copy=None):
"""Convert to numpy array.

Parameters
----------
copy : bool
If `True`, then the object is copied. If `None` then the object is copied
only if needed. For `False` it raises a ValueError if a copy cannot be
avoided. Default: `None`.

Returns
-------
image : nd-array size (width, height, 3)
Word cloud image as numpy matrix.
"""
return self.to_array()
return self.to_array(copy=copy)

def to_svg(self, embed_font=False, optimize_embedded_font=True, embed_image=False):
"""Export to SVG.
Expand Down