New Upstream Release - python-vttlib
Ready changes
Summary
Merged new upstream version: 0.12.0+dfsg (was: 0.11.0+dfsg).
Diff
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..d45604f
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,6 @@
+# Set the default behavior, in case people don't have core.autocrlf set.
+* text=auto
+
+# Explicitly declare text files you want to always be normalized and converted
+# to native line endings on checkout.
+*.py text
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..0ebe939
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,64 @@
+name: Continuous Integration
+
+on:
+ push:
+ branches: [master]
+ tags: ["v*"]
+ pull_request:
+ branches: [master]
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+ - name: Install packages
+ run: pip install tox
+ - name: Lint
+ run: tox -e lint
+
+ test:
+ runs-on: ${{ matrix.platform }}
+ strategy:
+ matrix:
+ python-version: ['3.7', '3.11']
+ platform: [ubuntu-latest, windows-latest]
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v4
+ with:
+ python-version: ${{ matrix.python-version }}
+ - name: Install packages
+ run: pip install tox
+ - name: Run Tox
+ run: tox -e py-cov
+
+ deploy:
+ # only run if the commit is tagged...
+ if: startsWith(github.ref, 'refs/tags/v')
+ # ... and the previous jobs completed successfully
+ needs:
+ - lint
+ - test
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+ - name: Install packages
+ run: pip install build twine
+ - name: Build and publish
+ env:
+ TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
+ TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
+ run: |
+ python -m build
+ twine check dist/*
+ twine upload dist/*
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9cd791f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,120 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+pip-wheel-metadata
+_version.py
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# Visual Studio Code
+.vscode
diff --git a/README.md b/README.md
index 0631e65..fe5930f 100644
--- a/README.md
+++ b/README.md
@@ -12,10 +12,12 @@ The primary use case is version control of hinting data of fonts.
## Installation and Usage
-This package is not yet on PyPI, because... uh...
+Installation requires a Python 3.7+ interpreter.
+
+Install in a virtual environment with:
```bash
-$ pip install git+https://github.com/daltonmaag/vttLib.git
+$ pip install vttLib
$ python -m vttLib --help
```
diff --git a/debian/changelog b/debian/changelog
index c1e8de4..f7741e7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+python-vttlib (0.12.0+dfsg-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Tue, 11 Apr 2023 01:58:56 -0000
+
python-vttlib (0.11.0+dfsg-3) unstable; urgency=medium
* Update metadata
diff --git a/debian/patches/0001-Remove-test-requiring-non-DFSG-data.patch b/debian/patches/0001-Remove-test-requiring-non-DFSG-data.patch
index 5d7dc0d..d657076 100644
--- a/debian/patches/0001-Remove-test-requiring-non-DFSG-data.patch
+++ b/debian/patches/0001-Remove-test-requiring-non-DFSG-data.patch
@@ -7,11 +7,11 @@ Forwarded: not-needed
tests/vttLib_test.py | 26 --------------------------
1 file changed, 26 deletions(-)
-diff --git a/tests/vttLib_test.py b/tests/vttLib_test.py
-index 22359a8..449f733 100644
---- a/tests/vttLib_test.py
-+++ b/tests/vttLib_test.py
-@@ -184,29 +184,3 @@ class TestTransformAssembly(object):
+Index: python-vttlib.git/tests/vttLib_test.py
+===================================================================
+--- python-vttlib.git.orig/tests/vttLib_test.py
++++ python-vttlib.git/tests/vttLib_test.py
+@@ -208,29 +208,3 @@ class TestTransformAssembly(object):
assert expected == generated
diff --git a/mypy.ini b/mypy.ini
index 6600dd3..0270ba3 100644
--- a/mypy.ini
+++ b/mypy.ini
@@ -1,5 +1,5 @@
[mypy]
-python_version = 3.6
+python_version = 3.7
# Untyped definitions and calls
disallow_incomplete_defs = True
diff --git a/pyproject.toml b/pyproject.toml
index 399a2e4..296c75e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,17 +1,30 @@
[build-system]
build-backend = "setuptools.build_meta"
-requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4"]
+requires = ["setuptools>=61", "setuptools_scm[toml]>=6.2"]
+
+[project]
+name = "vttLib"
+authors = [{ name = "Dalton Maag Ltd", email = "info@daltonmaag.com" }]
+description = "Compile Visual TrueType assembly with FontTools."
+readme = "README.md"
+requires-python = ">=3.7"
+license = {text = "MIT"}
+dependencies = [
+ "fonttools[ufo]>=4.0.0",
+ "pyparsing>=2.1.5",
+ "ufoLib2>=0.7.1",
+]
+dynamic = ["version"]
+
+[project.urls]
+Source = "https://github.com/daltonmaag/vttLib"
[tool.setuptools_scm]
write_to = "src/vttLib/_version.py"
[tool.black]
-target-version = ["py36"]
+target-version = ["py37"]
[tool.isort]
-multi_line_output = 3
-include_trailing_comma = true
-force_grid_wrap = 0
-use_parentheses = true
-line_length = 88
+profile = "black"
known_first_party = "vttLib"
diff --git a/requirements-dev.in b/requirements-dev.in
index 41e0b68..b36c862 100644
--- a/requirements-dev.in
+++ b/requirements-dev.in
@@ -1,7 +1,7 @@
black
coverage
flake8
-isort[pyproject]
+isort
mypy
pytest
ufo2ft
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 5b1afdc..a8c05a7 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,45 +1,87 @@
#
-# This file is autogenerated by pip-compile
+# This file is autogenerated by pip-compile with python 3.8
# To update, run:
#
-# pip-compile requirements-dev.in
+# pip-compile '.\requirements-dev.in'
#
+--extra-index-url https://pypi.daltonmaag.com/simple/
+--no-binary damafontlab
-appdirs==1.4.4 # via black, fs
-atomicwrites==1.4.0 # via pytest
-attrs==19.3.0 # via black, pytest
-black==19.10b0 # via -r requirements-dev.in
-booleanoperations==0.9.0 # via ufo2ft
-click==7.1.2 # via black
-colorama==0.4.3 # via pytest
-compreffor==0.5.0 # via ufo2ft
-coverage==5.1 # via -r requirements-dev.in
-cu2qu==1.6.7 # via ufo2ft
-flake8==3.8.2 # via -r requirements-dev.in
-fonttools[ufo]==4.10.2 # via booleanoperations, compreffor, cu2qu, ufo2ft
-fs==2.4.11 # via fonttools
-isort[pyproject]==4.3.21 # via -r requirements-dev.in
-mccabe==0.6.1 # via flake8
-more-itertools==8.3.0 # via pytest
-mypy-extensions==0.4.3 # via mypy
-mypy==0.770 # via -r requirements-dev.in
-packaging==20.4 # via pytest
-pathspec==0.8.0 # via black
-pluggy==0.13.1 # via pytest
-py==1.8.1 # via pytest
-pyclipper==1.1.0.post3 # via booleanoperations
-pycodestyle==2.6.0 # via flake8
-pyflakes==2.2.0 # via flake8
-pyparsing==2.4.7 # via packaging
-pytest==5.4.2 # via -r requirements-dev.in
-pytz==2020.1 # via fs
-regex==2020.5.14 # via black
-six==1.15.0 # via fs, packaging
-toml==0.10.1 # via black, isort
-typed-ast==1.4.1 # via black, mypy
-typing-extensions==3.7.4.2 # via mypy
-ufo2ft==2.14.0 # via -r requirements-dev.in
-wcwidth==0.1.9 # via pytest
+appdirs==1.4.4
+ # via fs
+attrs==22.1.0
+ # via pytest
+black==22.10.0
+ # via -r .\requirements-dev.in
+booleanoperations==0.9.0
+ # via ufo2ft
+cffsubr==0.2.9.post1
+ # via ufo2ft
+click==8.1.3
+ # via black
+colorama==0.4.6
+ # via
+ # click
+ # pytest
+coverage==6.5.0
+ # via -r .\requirements-dev.in
+cu2qu==1.6.7.post1
+ # via ufo2ft
+exceptiongroup==1.0.0rc9
+ # via pytest
+flake8==5.0.4
+ # via -r .\requirements-dev.in
+fonttools[ufo]==4.38.0
+ # via
+ # booleanoperations
+ # cffsubr
+ # cu2qu
+ # ufo2ft
+fs==2.4.16
+ # via fonttools
+iniconfig==1.1.1
+ # via pytest
+isort==5.10.1
+ # via -r .\requirements-dev.in
+mccabe==0.7.0
+ # via flake8
+mypy==0.982
+ # via -r .\requirements-dev.in
+mypy-extensions==0.4.3
+ # via
+ # black
+ # mypy
+packaging==21.3
+ # via pytest
+pathspec==0.10.1
+ # via black
+platformdirs==2.5.2
+ # via black
+pluggy==1.0.0
+ # via pytest
+pyclipper==1.3.0.post3
+ # via booleanoperations
+pycodestyle==2.9.1
+ # via flake8
+pyflakes==2.5.0
+ # via flake8
+pyparsing==3.0.9
+ # via packaging
+pytest==7.2.0
+ # via -r .\requirements-dev.in
+six==1.16.0
+ # via fs
+tomli==2.0.1
+ # via
+ # black
+ # mypy
+ # pytest
+typing-extensions==4.4.0
+ # via
+ # black
+ # mypy
+ufo2ft==2.28.0
+ # via -r .\requirements-dev.in
# The following packages are considered to be unsafe in a requirements file:
# setuptools
diff --git a/requirements.txt b/requirements.txt
index dbf2248..2737487 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,18 +1,28 @@
#
-# This file is autogenerated by pip-compile
+# This file is autogenerated by pip-compile with python 3.8
# To update, run:
#
-# pip-compile --output-file=requirements.txt setup.py
+# pip-compile --output-file=requirements.txt pyproject.toml
#
+--extra-index-url https://pypi.daltonmaag.com/simple/
+--no-binary damafontlab
-appdirs==1.4.4 # via fs
-attrs==19.3.0 # via ufolib2
-fonttools[ufo]==4.10.2 # via ufolib2, vttLib (.\setup.py)
-fs==2.4.11 # via fonttools
-pyparsing==2.4.7 # via vttLib (.\setup.py)
-pytz==2020.1 # via fs
-six==1.15.0 # via fs
-ufolib2==0.7.1 # via vttLib (.\setup.py)
+appdirs==1.4.4
+ # via fs
+attrs==22.1.0
+ # via ufolib2
+fonttools[ufo]==4.38.0
+ # via
+ # ufolib2
+ # vttLib (pyproject.toml)
+fs==2.4.16
+ # via fonttools
+pyparsing==3.0.9
+ # via vttLib (pyproject.toml)
+six==1.16.0
+ # via fs
+ufolib2==0.13.1
+ # via vttLib (pyproject.toml)
# The following packages are considered to be unsafe in a requirements file:
# setuptools
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 93b405e..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,26 +0,0 @@
-[metadata]
-name = vttLib
-author = Dalton Maag Ltd
-author_email = info@daltonmaag.com
-home-page = https://github.com/daltonmaag/vttLib
-description = Compile Visual TrueType assembly with FontTools.
-license = MIT
-
-[options]
-python_requires = >=3.6
-packages = find:
-package_dir =
- =src
-install_requires =
- fonttools[ufo]>=4.0.0
- pyparsing>=2.1.5
- ufoLib2>=0.7.1
-setup_requires =
- setuptools_scm[toml]>=3.4
- wheel
-
-[options.packages.find]
-where=src
-
-[sdist]
-formats = zip
diff --git a/setup.py b/setup.py
deleted file mode 100644
index b908cbe..0000000
--- a/setup.py
+++ /dev/null
@@ -1,3 +0,0 @@
-import setuptools
-
-setuptools.setup()
diff --git a/src/vttLib/__init__.py b/src/vttLib/__init__.py
index 5d24cfa..21be54f 100644
--- a/src/vttLib/__init__.py
+++ b/src/vttLib/__init__.py
@@ -6,8 +6,8 @@ import re
from collections import OrderedDict, defaultdict, deque, namedtuple
import ufoLib2
-from fontTools.misc.arrayTools import Vector
from fontTools.misc.fixedTools import otRound
+from fontTools.misc.vector import Vector
from fontTools.ttLib import TTFont, TTLibError, newTable
from fontTools.ttLib.tables._g_l_y_f import (
ROUND_XY_TO_GRID,
@@ -288,6 +288,7 @@ def transform(tokens, components=None):
for point_index, rel_ppem, step_no in reversed(t.deltas):
deltas.setdefault(point_index, []).append((rel_ppem, step_no))
+ pairs = []
for point_index, delta_specs in deltas.items():
for rel_ppem, step_no in sorted(delta_specs, reverse=True):
if mnemonic.startswith(("DELTAP", "DELTAC")):
@@ -302,10 +303,17 @@ def transform(tokens, components=None):
delta_base = 41
# subtract the default 'delta base'
rel_ppem -= delta_base
- stack.appendleft(point_index)
# -8: 0, ... -1: 7, 1: 8, ... 8: 15
selector = (step_no + 7) if step_no > 0 else (step_no + 8)
- stack.appendleft((rel_ppem << 4) | selector)
+ pairs.append(((rel_ppem << 4) | selector, point_index))
+
+ # Reorder by exception spec, workaround for an issue where only the
+ # first delta is active when the spec/index pairs are ordered in a
+ # different way. This results in an order identical to what VTT does.
+ for spec, point_index in sorted(pairs, reverse=True):
+ stack.appendleft(point_index)
+ stack.appendleft(spec)
+
if mnemonic.startswith("DLT"):
mnemonic = mnemonic.replace("DLT", "DELTA")
elif mnemonic.startswith("#") and mnemonic.endswith(":"):
diff --git a/src/vttLib/parser.py b/src/vttLib/parser.py
index 871b161..c266391 100644
--- a/src/vttLib/parser.py
+++ b/src/vttLib/parser.py
@@ -82,7 +82,10 @@ delta_spec = (
+ Optional(Literal("/8")).suppress()
)
-delta = nestedExpr("(", ")", delta_spec, ignoreExpr=None)
+# NOTE: The type-ignore is weird, the docs at
+# https://pyparsing-docs.readthedocs.io/en/latest/pyparsing.html?highlight=nestedExpr#pyparsing.nested_expr
+# say that passing None is okay, but the typing says something else.
+delta = nestedExpr("(", ")", delta_spec, ignoreExpr=None) # type: ignore
deltas = Group(OneOrMore(delta)).setResultsName("deltas")
diff --git a/tests/vttLib_test.py b/tests/vttLib_test.py
index 22359a8..64109b3 100644
--- a/tests/vttLib_test.py
+++ b/tests/vttLib_test.py
@@ -175,6 +175,30 @@ class TestTransformAssembly(object):
).strip()
)
+ def test_delta_args_sorting(self):
+
+ vtt_assembly = dedent(
+ """
+ DLTC1[(4 @4 8) (4 @8 8) (4 @11 8) (4 @15 8) (5 @4 8) (5 @8 8) (5 @11 8) (5 @15 8) (12 @1 8) (12 @4 8) (12 @5 8) (12 @8 8) (12 @9 8) (12 @13 8) (12 @15 8) (12 @0 8) (13 @1 8) (13 @4 8) (13 @5 8) (13 @8 8) (13 @9 8) (13 @13 8) (13 @15 8) (13 @0 8) (14 @11 8) (14 @13 8) (14 @15 8) (15 @11 8) (15 @13 8) (15 @15 8)]
+ DLTC2[(4 @3 8) (4 @6 8) (4 @7 8) (4 @10 8) (4 @14 8) (5 @3 8) (5 @6 8) (5 @7 8) (5 @10 8) (5 @14 8) (12 @1 8) (12 @3 8) (12 @4 8) (12 @5 8) (12 @9 8) (12 @13 8) (13 @1 8) (13 @3 8) (13 @4 8) (13 @5 8) (13 @9 8) (13 @13 8) (14 @1 8) (14 @3 8) (14 @5 8) (14 @7 8) (14 @9 8) (14 @11 8) (14 @13 8) (15 @1 8) (15 @3 8) (15 @5 8) (15 @7 8) (15 @9 8) (15 @11 8) (15 @13 8)]
+ DLTC3[(4 @1 8) (4 @2 8) (4 @5 8) (5 @1 8) (5 @2 8) (5 @5 8) (12 @1 8) (12 @4 8) (13 @1 8) (13 @4 8) (14 @0 8) (14 @2 8) (14 @4 8) (15 @0 8) (15 @2 8) (15 @4 8)]
+ """
+ )
+
+ ft_assembly = transform_assembly(vtt_assembly)
+
+ assert (
+ ft_assembly
+ == dedent(
+ """
+ PUSH[] 15 14 15 15 31 4 31 5 31 12 31 13 47 4 47 5 47 14 47 15 79 12 79 13 79 14 79 15 95 4 95 5 16 31 12 31 13 31 14 31 15 63 4 63 5 63 12 63 13 63 14 63 15 79 12 79 13 95 12 95 13 95 14 95 15 111 4 111 5 127 4 127 5 127 14 127 15 159 12 159 13 159 14 159 15 175 4 175 5 191 14 191 15 223 12 223 13 223 14 223 15 239 4 239 5 36 15 12 15 13 31 12 31 13 79 4 79 5 79 12 79 13 95 12 95 13 143 4 143 5 143 12 143 13 159 12 159 13 191 4 191 5 191 14 191 15 223 12 223 13 223 14 223 15 255 4 255 5 255 12 255 13 255 14 255 15 30
+ DELTAC1[]
+ DELTAC2[]
+ DELTAC3[]
+ """
+ ).strip()
+ )
+
def test_end_to_end(self, input_and_expected):
vtt_assembly, expected = input_and_expected
diff --git a/tox.ini b/tox.ini
index cec2b83..c2269f4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,7 @@
[tox]
-envlist = lint, py3{6,8}-cov, htmlcov
+envlist = lint, py3{7,8,9,10,11}-cov, htmlcov
+skip_missing_interpreters = true
+isolated_build = true
[testenv]
deps =
@@ -26,8 +28,8 @@ deps =
-r requirements-dev.txt
commands =
black --check --diff .
- isort --check-only --diff --recursive src tests
- mypy src tests .
+ isort --check-only --diff src tests
+ mypy src tests
flake8
[flake8]