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
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.11"
python: "3.12"
sphinx:
configuration: docs/conf.py
python:
Expand Down
1 change: 0 additions & 1 deletion bin/update-tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,6 @@ def fetch_table_vs16_data() -> UnicodeTableRenderCtx:
For that reason, and that these values are not expected to change,
only this single shared table is exported.


One example, where v3.2 became v1.1 ("-" 12.0, "+" 15.1)::

-2620 FE0F ; Basic_Emoji ; skull and crossbones # 3.2 [1] (☠️)
Expand Down
1 change: 1 addition & 0 deletions bin/verify-table-integrity.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def bisearch_pair(ucs, table):


def main(log: logging.Logger):
# local
from wcwidth import ZERO_WIDTH, WIDE_EASTASIAN, list_versions

reversed_uni_versions = list(reversed(list_versions()))
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = 'en'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
Expand Down
8 changes: 4 additions & 4 deletions docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Briefly, return values of function ``wcwidth()`` are:
Function ``wcswidth()`` simply returns the sum of all values for each character
along a string, or ``-1`` when it occurs anywhere along a string.

Full API Documentation at https://wcwidth.readthedocs.org
Full API Documentation at https://wcwidth.readthedocs.io

==========
Developing
Expand All @@ -105,9 +105,9 @@ Install wcwidth in editable mode::

pip install -e .

Execute unit tests using tox_::
Execute unit tests using tox_ for all supported Python versions::

tox -e py36,py37,py38,py39,py310,py311,py312
tox -e py36,py37,py38,py39,py310,py311,py312,py313,py314

Updating Unicode Version
------------------------
Expand Down Expand Up @@ -264,7 +264,7 @@ History
Environment variable ``UNICODE_VERSION``, such as ``13.0``, or ``6.3.0``.
See the `jquast/ucs-detect`_ CLI utility for automatic detection.
* **Enhancement**:
API Documentation is published to readthedocs.org.
API Documentation is published to readthedocs.io.
* **Updated** tables for *all* Unicode Specifications with files
published in a programmatically consumable format, versions 4.1.0
through 13.0
Expand Down
43 changes: 23 additions & 20 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,57 +1,60 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --allow-unsafe --no-emit-index-url --output-file=docs/requirements.txt --strip-extras requirements-docs.in
# pip-compile --allow-unsafe --cert=None --client-cert=None --index-url=None --no-emit-index-url --output-file=docs/requirements.txt --pip-args=None --strip-extras requirements-docs.in
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(these extra arguments are because I use a "devpi-server" instance on localhost, they're just comments and harmless anyway)

#
alabaster==0.7.13

alabaster==1.0.0
# via sphinx
babel==2.12.1
babel==2.17.0
# via sphinx
certifi==2024.7.4
certifi==2025.8.3
# via requests
charset-normalizer==3.3.0
charset-normalizer==3.4.3
# via requests
docutils==0.17.1
docutils==0.21.2
# via
# sphinx
# sphinx-rtd-theme
idna==3.7
idna==3.10
# via requests
imagesize==1.4.1
# via sphinx
jinja2==3.1.6
# via sphinx
markupsafe==2.1.3
markupsafe==3.0.2
# via jinja2
packaging==23.2
packaging==25.0
# via sphinx
pygments==2.16.1
pygments==2.19.2
# via sphinx
requests==2.32.4
requests==2.32.5
# via sphinx
snowballstemmer==2.2.0
roman-numerals-py==3.1.0
# via sphinx
sphinx==4.5.0
snowballstemmer==3.0.1
# via sphinx
sphinx==8.2.3
# via
# -r requirements-docs.in
# sphinx-rtd-theme
# sphinxcontrib-jquery
sphinx-rtd-theme==1.3.0
sphinx-rtd-theme==3.0.2
# via -r requirements-docs.in
sphinxcontrib-applehelp==1.0.4
sphinxcontrib-applehelp==2.0.0
# via sphinx
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-devhelp==2.0.0
# via sphinx
sphinxcontrib-htmlhelp==2.0.1
sphinxcontrib-htmlhelp==2.1.0
# via sphinx
sphinxcontrib-jquery==4.1
# via sphinx-rtd-theme
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-qthelp==2.0.0
# via sphinx
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib-serializinghtml==2.0.0
# via sphinx
urllib3==2.5.0
# via requests
2 changes: 1 addition & 1 deletion requirements-docs.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Sphinx~=4.5
Sphinx
sphinx_rtd_theme
11 changes: 6 additions & 5 deletions requirements-tests39.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
#
# pip-compile --allow-unsafe --no-emit-index-url --output-file=requirements-tests39.txt --strip-extras requirements-tests39.in
#
coverage==7.9.1

coverage==7.10.6
# via pytest-cov
exceptiongroup==1.3.0
# via pytest
Expand All @@ -18,20 +19,20 @@ pluggy==1.6.0
# pytest-cov
py-cpuinfo==9.0.0
# via pytest-benchmark
pygments==2.19.1
pygments==2.19.2
# via pytest
pytest==8.4.0
pytest==8.4.2
# via
# -r requirements-tests39.in
# pytest-benchmark
# pytest-cov
pytest-benchmark==5.1.0
# via -r requirements-tests39.in
pytest-cov==6.2.1
pytest-cov==7.0.0
# via -r requirements-tests39.in
tomli==2.2.1
# via
# coverage
# pytest
typing-extensions==4.14.0
typing-extensions==4.15.0
# via exceptiongroup
23 changes: 12 additions & 11 deletions requirements-update.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --allow-unsafe --no-emit-index-url --output-file=requirements-update.txt --strip-extras requirements-update.in
# pip-compile --allow-unsafe --cert=None --client-cert=None --index-url=None --no-emit-index-url --output-file=requirements-update.txt --pip-args=None --strip-extras requirements-update.in
#
certifi==2023.7.22

certifi==2025.8.3
# via requests
charset-normalizer==3.3.0
charset-normalizer==3.4.3
# via requests
idna==3.4
idna==3.10
# via requests
jinja2==3.1.3
jinja2==3.1.6
# via -r requirements-update.in
markupsafe==2.1.3
markupsafe==3.0.2
# via jinja2
python-dateutil==2.8.2
python-dateutil==2.9.0.post0
# via -r requirements-update.in
requests==2.31.0
requests==2.32.5
# via -r requirements-update.in
six==1.16.0
six==1.17.0
# via python-dateutil
typing-extensions==4.8.0
typing-extensions==4.15.0
# via -r requirements-update.in
urllib3==2.0.7
urllib3==2.5.0
# via requests
9 changes: 5 additions & 4 deletions tests/test_emojis.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def test_longer_emoji_zwj_sequence():
"\u200d" # 'Cf', 'N' -- ZERO WIDTH JOINER
"\U0001F9D1" # 'So', 'W' -- ADULT
"\U0001F3FD" # 'Sk', 'W' -- EMOJI MODIFIER FITZPATRICK TYPE-4
) * 2
) * 2
# This test adapted from https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf
expect_length_each = (2, 0, 0, 1, 0, 0, 2, 0, 2, 0) * 2
expect_length_phrase = 4
Expand All @@ -140,8 +140,8 @@ def test_longer_emoji_zwj_sequence():
def read_sequences_from_file(filename):
fp = open(os.path.join(os.path.dirname(__file__), filename), 'r', encoding='utf-8')
lines = [line.strip()
for line in fp.readlines()
if not line.startswith('#') and line.strip()]
for line in fp.readlines()
if not line.startswith('#') and line.strip()]
fp.close()
sequences = [make_sequence_from_line(line) for line in lines]
return lines, sequences
Expand Down Expand Up @@ -218,6 +218,7 @@ def test_unicode_9_vs16():
assert length_each == expect_length_each
assert length_phrase == expect_length_phrase


def test_unicode_8_vs16():
"""Verify that VS-16 has no effect on unicode_version 8.0 and earler"""
phrase = ("\u2640" # FEMALE SIGN
Expand All @@ -232,4 +233,4 @@ def test_unicode_8_vs16():

# verify.
assert length_each == expect_length_each
assert length_phrase == expect_length_phrase
assert length_phrase == expect_length_phrase
5 changes: 4 additions & 1 deletion tests/test_table_integrity.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
"""
Executes verify-table-integrity.py as a unit test.
"""
# std imports
import os
import sys
import subprocess

# 3rd party
import pytest


@pytest.mark.skipif(sys.version_info[:2] != (3, 12), reason='Test only with a single version of python')
def test_verify_table_integrity():
subprocess.check_output([sys.executable, os.path.join(os.path.dirname(__file__),
os.path.pardir,
'bin',
'verify-table-integrity.py')])
'verify-table-integrity.py')])
53 changes: 17 additions & 36 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[tox]
envlist = update, compile, autopep8, docformatter, isort, pylint, flake8, pydocstyle, docs, verify_tables, py{36, 37, 38, 39, 310, 311, 312}, pypy{36, 37, 38, 39, 310}
envlist = update, compile, autopep8, docformatter, isort, pylint, flake8, pydocstyle, docs, verify_tables, py{36, 37, 38, 39, 310, 311, 312, 313, 314}, pypy{36, 37, 38, 39, 310}
skip_missing_interpreters = true
# needed for Python 3.6
# https://tox.wiki/en/4.11.3/faq.html#testing-end-of-life-python-versions
requires = virtualenv<20.22.0

Expand Down Expand Up @@ -67,18 +68,18 @@ source = wcwidth/
# version for the newest to oldest python versions for testing, must also use some
# targeted versions to 'compile' those requirements into their frozen form,
# otherwise incompatible packages would be pinned. At the time of this writing the
# files compiled for version 3.9 through 3.11 are compiled by python3.11.
# files compiled for version 3.9 and later are compiled by python3.13 [WIP].
[testenv:compile]
basepython = python3.11
basepython = python3.13
commands = python -m compileall {toxinidir}/wcwidth {toxinidir}/bin {toxinidir}/tests {toxinidir}/docs

[testenv:update_requirements_update]
basepython = python3.12
basepython = python3.13
deps = pip-tools
commands = {[base]pip_compile_command} requirements-update.in -o requirements-update.txt

[testenv:update_requirements_docs]
basepython = python3.11
basepython = python3.12
deps = pip-tools
commands = {[base]pip_compile_command} requirements-docs.in -o docs/requirements.txt

Expand Down Expand Up @@ -111,13 +112,14 @@ deps = -r requirements-tests36.txt
deps = -r requirements-tests36.txt

[testenv:update]
basepython = python3.12
basepython = python3.13
usedevelop = true
deps = -r requirements-update.txt
commands = python {toxinidir}/bin/update-tables.py {posargs:--no-check-last-modified}

[testenv:autopep8]
basepython = python3.11
deps = autopep8
commands =
{envbindir}/autopep8 \
--in-place \
Expand All @@ -126,54 +128,33 @@ commands =
--aggressive \
wcwidth/ bin/ tests/ setup.py

[testenv:docformatter]
basepython = python3.11
commands =
{envbindir}/docformatter \
--in-place \
--recursive \
--pre-summary-newline \
--wrap-summaries=100 \
--wrap-descriptions=100 \
{toxinidir}/wcwidth \
{toxinidir}/bin \
{toxinidir}/setup.py \
{toxinidir}/docs/conf.py

[testenv:isort]
basepython = python3.11
deps = isort
basepython = python3.13
commands = {envbindir}/isort --quiet --apply --recursive wcwidth tests bin

[testenv:pylint]
basepython = python3.11
basepython = python3.13
deps = pylint
commands = {envbindir}/pylint --rcfile={toxinidir}/.pylintrc \
--ignore=tests,docs,setup.py,conf.py,build,distutils,.pyenv,.git,.tox \
{posargs:{toxinidir}}/wcwidth

[testenv:flake8]
basepython = python3.11
basepython = python3.13
deps = flake8
commands = {envbindir}/flake8 --exclude=tests setup.py docs/ wcwidth/ bin/ tests/

[testenv:pydocstyle]
basepython = python3.11
commands = {envbindir}/pydocstyle --source --explain {toxinidir}/wcwidth
{envbindir}/rst-lint README.rst
{envbindir}/doc8 --ignore-path docs/_build --ignore-path docs/requirements.txt --ignore D000 docs

[testenv:docs]
basepython = python3.11
# matches .readthedocs.yaml and environment
basepython = python3.12
deps = -r {toxinidir}/docs/requirements.txt
commands = sphinx-build docs/ build/sphinx

[testenv:verify_tables]
basepython = python3.12
basepython = python3.13
commands = python {toxinidir}/bin/verify-table-integrity.py

[testenv:sphinx]
basepython = python3.11
deps = -r {toxinidir}/docs/requirements.txt
commands = {envbindir}/sphinx-build {posargs:-v -W -d {toxinidir}/docs/_build/doctrees -b html docs {toxinidir}/docs/_build/html}

[testenv:linkcheck]
basepython = python3.11
deps = -r {toxinidir}/docs/requirements.txt
Expand Down
Loading
Loading