diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml
index 941e875..a5943dc 100644
--- a/.github/workflows/github-ci.yml
+++ b/.github/workflows/github-ci.yml
@@ -1,5 +1,3 @@
-# This is a basic workflow to help you get started with Actions
-
name: Github CI Unit Testing
on:
diff --git a/.github/workflows/publish-on-pypi.yml b/.github/workflows/publish-on-pypi.yml
new file mode 100644
index 0000000..85495d4
--- /dev/null
+++ b/.github/workflows/publish-on-pypi.yml
@@ -0,0 +1,40 @@
+name: Publish to TestPyPI and if new version PyPI
+
+on:
+ push:
+ branches: [ master ]
+jobs:
+ build-n-publish:
+ name: Build and publish to TestPyPI and PyPI
+ runs-on: ubuntu-18.04
+ steps:
+ - uses: actions/checkout@master
+ - name: Set up Python 3
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3
+ - name: Install pypa/build
+ run: >-
+ python -m
+ pip install
+ build
+ --user
+ - name: Build a binary wheel and a source tarball
+ run: >-
+ python -m
+ build
+ --sdist
+ --wheel
+ --outdir dist/
+ .
+ - name: Publish to Test PyPI
+ uses: pypa/gh-action-pypi-publish@master
+ with:
+ skip_existing: true
+ password: ${{ secrets.TESTPYPI_API_TOKEN }}
+ repository_url: https://test.pypi.org/legacy/
+ - name: Publish to PyPI
+ if: startsWith(github.ref, 'refs/tags')
+ uses: pypa/gh-action-pypi-publish@master
+ with:
+ password: ${{ secrets.PYPI_API_TOKEN }}
\ No newline at end of file
diff --git a/dist/svgpathtools-1.0.1.tar.gz b/dist/svgpathtools-1.0.1.tar.gz
deleted file mode 100644
index 27ae20c..0000000
Binary files a/dist/svgpathtools-1.0.1.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.2.1.tar.gz b/dist/svgpathtools-1.2.1.tar.gz
deleted file mode 100644
index 888bdcb..0000000
Binary files a/dist/svgpathtools-1.2.1.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.2.2.tar.gz b/dist/svgpathtools-1.2.2.tar.gz
deleted file mode 100644
index ea38003..0000000
Binary files a/dist/svgpathtools-1.2.2.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.2.3.tar.gz b/dist/svgpathtools-1.2.3.tar.gz
deleted file mode 100644
index 9a8a50b..0000000
Binary files a/dist/svgpathtools-1.2.3.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.2.4.tar.gz b/dist/svgpathtools-1.2.4.tar.gz
deleted file mode 100644
index eea5bce..0000000
Binary files a/dist/svgpathtools-1.2.4.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.2.5-py2.py3-none-any.whl b/dist/svgpathtools-1.2.5-py2.py3-none-any.whl
deleted file mode 100644
index 3db636e..0000000
Binary files a/dist/svgpathtools-1.2.5-py2.py3-none-any.whl and /dev/null differ
diff --git a/dist/svgpathtools-1.2.5.tar.gz b/dist/svgpathtools-1.2.5.tar.gz
deleted file mode 100644
index 77fd8da..0000000
Binary files a/dist/svgpathtools-1.2.5.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.2.6-py2.py3-none-any.whl b/dist/svgpathtools-1.2.6-py2.py3-none-any.whl
deleted file mode 100644
index 1c129e0..0000000
Binary files a/dist/svgpathtools-1.2.6-py2.py3-none-any.whl and /dev/null differ
diff --git a/dist/svgpathtools-1.2.6.tar.gz b/dist/svgpathtools-1.2.6.tar.gz
deleted file mode 100644
index 8ad404b..0000000
Binary files a/dist/svgpathtools-1.2.6.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.3-py2.py3-none-any.whl b/dist/svgpathtools-1.3-py2.py3-none-any.whl
deleted file mode 100644
index 31e27c4..0000000
Binary files a/dist/svgpathtools-1.3-py2.py3-none-any.whl and /dev/null differ
diff --git a/dist/svgpathtools-1.3.1-py2.py3-none-any.whl b/dist/svgpathtools-1.3.1-py2.py3-none-any.whl
deleted file mode 100644
index 90533bb..0000000
Binary files a/dist/svgpathtools-1.3.1-py2.py3-none-any.whl and /dev/null differ
diff --git a/dist/svgpathtools-1.3.1.tar.gz b/dist/svgpathtools-1.3.1.tar.gz
deleted file mode 100644
index cb6931e..0000000
Binary files a/dist/svgpathtools-1.3.1.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.3.2-py2.py3-none-any.whl b/dist/svgpathtools-1.3.2-py2.py3-none-any.whl
deleted file mode 100644
index 8d07955..0000000
Binary files a/dist/svgpathtools-1.3.2-py2.py3-none-any.whl and /dev/null differ
diff --git a/dist/svgpathtools-1.3.2.tar.gz b/dist/svgpathtools-1.3.2.tar.gz
deleted file mode 100644
index 941613f..0000000
Binary files a/dist/svgpathtools-1.3.2.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.3.tar.gz b/dist/svgpathtools-1.3.tar.gz
deleted file mode 100644
index fea6566..0000000
Binary files a/dist/svgpathtools-1.3.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.4-py2.py3-none-any.whl b/dist/svgpathtools-1.4-py2.py3-none-any.whl
deleted file mode 100644
index 64a4894..0000000
Binary files a/dist/svgpathtools-1.4-py2.py3-none-any.whl and /dev/null differ
diff --git a/dist/svgpathtools-1.4.1-py2.py3-none-any.whl b/dist/svgpathtools-1.4.1-py2.py3-none-any.whl
deleted file mode 100644
index 7030e12..0000000
Binary files a/dist/svgpathtools-1.4.1-py2.py3-none-any.whl and /dev/null differ
diff --git a/dist/svgpathtools-1.4.1-py3.7.egg b/dist/svgpathtools-1.4.1-py3.7.egg
deleted file mode 100644
index 7759b14..0000000
Binary files a/dist/svgpathtools-1.4.1-py3.7.egg and /dev/null differ
diff --git a/dist/svgpathtools-1.4.1.tar.gz b/dist/svgpathtools-1.4.1.tar.gz
deleted file mode 100644
index cc9bd28..0000000
Binary files a/dist/svgpathtools-1.4.1.tar.gz and /dev/null differ
diff --git a/dist/svgpathtools-1.4.tar.gz b/dist/svgpathtools-1.4.tar.gz
deleted file mode 100644
index 0f9b93c..0000000
Binary files a/dist/svgpathtools-1.4.tar.gz and /dev/null differ
diff --git a/examples/wasm-via-pyodide-example.html b/examples/wasm-via-pyodide-example.html
new file mode 100644
index 0000000..608dc09
--- /dev/null
+++ b/examples/wasm-via-pyodide-example.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+ svgpathtools in JS!
+
+
+
+
+
+
+Output:
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 0228665..69e046c 100644
--- a/setup.py
+++ b/setup.py
@@ -3,18 +3,17 @@ import codecs
import os
-VERSION = '1.4.1'
+VERSION = '1.4.2'
AUTHOR_NAME = 'Andy Port'
AUTHOR_EMAIL = 'AndyAPort@gmail.com'
+GITHUB = 'https://github.com/mathandy/svgpathtools'
+
+_here = os.path.abspath(os.path.dirname(__file__))
-def read(*parts):
- """
- Build an absolute path from *parts* and and return the contents of the
- resulting file. Assume UTF-8 encoding.
- """
- HERE = os.path.abspath(os.path.dirname(__file__))
- with codecs.open(os.path.join(HERE, *parts), "rb", "utf-8") as f:
+def read(relative_path):
+ """Reads file at relative path, returning contents as string."""
+ with codecs.open(os.path.join(_here, relative_path), "rb", "utf-8") as f:
return f.read()
@@ -27,20 +26,24 @@ setup(name='svgpathtools',
long_description_content_type='text/markdown',
author=AUTHOR_NAME,
author_email=AUTHOR_EMAIL,
- url='https://github.com/mathandy/svgpathtools',
- # download_url = 'http://github.com/mathandy/svgpathtools/tarball/'+VERSION,
+ url=GITHUB,
+ download_url='{}/releases/download/{}/svgpathtools-{}-py2.py3-none-any.whl'
+ ''.format(GITHUB, VERSION, VERSION),
license='MIT',
- install_requires=['numpy', 'svgwrite'],
+ install_requires=['numpy', 'svgwrite', 'defusedxml'],
platforms="OS Independent",
- requires=['numpy', 'svgwrite'],
+ requires=['numpy', 'svgwrite', 'defusedxml'],
keywords=['svg', 'svg path', 'svg.path', 'bezier', 'parse svg path', 'display svg'],
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
"Topic :: Multimedia :: Graphics :: Editors :: Vector-Based",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Image Recognition",
diff --git a/svgpathtools/path.py b/svgpathtools/path.py
index 67e1d02..17a1101 100644
--- a/svgpathtools/path.py
+++ b/svgpathtools/path.py
@@ -637,7 +637,7 @@ class Line(object):
def points(self, ts):
"""Faster than running Path.point many times."""
- return self.poly(ts)
+ return self.poly()(ts)
def length(self, t0=0, t1=1, error=None, min_depth=None):
"""returns the length of the line segment between t0 and t1."""
@@ -914,7 +914,7 @@ class QuadraticBezier(object):
def points(self, ts):
"""Faster than running Path.point many times."""
- return self.poly(ts)
+ return self.poly()(ts)
def length(self, t0=0, t1=1, error=None, min_depth=None):
if t0 == 1 and t1 == 0:
@@ -1182,7 +1182,7 @@ class CubicBezier(object):
def points(self, ts):
"""Faster than running Path.point many times."""
- return self.poly(ts)
+ return self.poly()(ts)
def length(self, t0=0, t1=1, error=LENGTH_ERROR, min_depth=LENGTH_MIN_DEPTH):
"""Calculate the length of the path up to a certain position"""
diff --git a/test/test_path.py b/test/test_path.py
index 981259f..3e73745 100644
--- a/test/test_path.py
+++ b/test/test_path.py
@@ -1,6 +1,10 @@
# External dependencies
from __future__ import division, absolute_import, print_function
+<<<<<<< HEAD
from unittest import TestCase
+=======
+import os
+>>>>>>> master
import sys
from math import sqrt, pi
from operator import itemgetter
@@ -536,7 +540,7 @@ class ArcTest(TestCase):
except ValueError:
self.fail("Arc() raised ValueError unexpectedly!")
- def test_points(self):
+ def test_point(self):
arc1 = Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j)
self.assertAlmostEqual(arc1.center, 100 + 0j, delta=TOL)
self.assertAlmostEqual(arc1.theta, 180.0, delta=TOL)
@@ -739,46 +743,59 @@ class ArcTest(TestCase):
# noinspection PyTypeChecker
class TestPath(TestCase):
- def test_hash(self):
- line1 = Line(600.5 + 350.5j, 650.5 + 325.5j)
- arc1 = Arc(650 + 325j, 25 + 25j, -30, 0, 1, 700 + 300j)
- arc2 = Arc(650 + 325j, 30 + 25j, -30, 0, 0, 700 + 300j)
- cub1 = CubicBezier(650 + 325j, 25 + 25j, -30, 700 + 300j)
- cub2 = CubicBezier(700 + 300j, 800 + 400j, 750 + 200j, 600 + 100j)
- quad3 = QuadraticBezier(600 + 100j, 600, 600 + 300j)
- linez = Line(600 + 300j, 600 + 350j)
-
- bezpath = Path(line1, cub1, cub2, quad3)
- bezpathz = Path(line1, cub1, cub2, quad3, linez)
- path = Path(line1, arc1, cub2, quad3)
- pathz = Path(line1, arc1, cub2, quad3, linez)
- lpath = Path(linez)
- qpath = Path(quad3)
- cpath = Path(cub1)
- apath = Path(arc1, arc2)
-
- test_curves = [bezpath, bezpathz, path, pathz, lpath, qpath, cpath,
- apath, line1, arc1, arc2, cub1, cub2, quad3, linez]
-
- # this is necessary due to changes to the builtin `hash` function
- if sys.version_info.major == 2:
- expected_hashes = [
- -5762846476463470127, -138736730317965290, -2005041722222729058,
- 8448700906794235291, -5178990533869800243, -4003140762934044601,
- 8575549467429100514, 5166859065265868968, 1373103287265872323,
- -1022491904150314631, 4188352014604112779, -5090374009174854814,
- -7093907105533857815, 2036243740727202243, -8108488067585685407]
- else:
- expected_hashes = [
- -6073024107272494569, -2519772625496438197, 8726412907710383506,
- 2132930052750006195, 3112548573593977871, 991446120749438306,
- -5589397644574569777, -4438808571483114580, -3125333407400456536,
- -4418099728831808951, 702646573139378041, -6331016786776229094,
- 5053050772929443013, 6102272282813527681, -5385294438006156225,
- ]
-
- for c, h in zip(test_curves, expected_hashes):
- self.assertTrue(hash(c) == h, msg="hash {} was expected for curve = {}".format(h, c))
+ # def test_hash(self):
+ # line1 = Line(600.5 + 350.5j, 650.5 + 325.5j)
+ # arc1 = Arc(650 + 325j, 25 + 25j, -30, 0, 1, 700 + 300j)
+ # arc2 = Arc(650 + 325j, 30 + 25j, -30, 0, 0, 700 + 300j)
+ # cub1 = CubicBezier(650 + 325j, 25 + 25j, -30, 700 + 300j)
+ # cub2 = CubicBezier(700 + 300j, 800 + 400j, 750 + 200j, 600 + 100j)
+ # quad3 = QuadraticBezier(600 + 100j, 600, 600 + 300j)
+ # linez = Line(600 + 300j, 600 + 350j)
+ #
+ # bezpath = Path(line1, cub1, cub2, quad3)
+ # bezpathz = Path(line1, cub1, cub2, quad3, linez)
+ # path = Path(line1, arc1, cub2, quad3)
+ # pathz = Path(line1, arc1, cub2, quad3, linez)
+ # lpath = Path(linez)
+ # qpath = Path(quad3)
+ # cpath = Path(cub1)
+ # apath = Path(arc1, arc2)
+ #
+ # test_curves = [bezpath, bezpathz, path, pathz, lpath, qpath, cpath,
+ # apath, line1, arc1, arc2, cub1, cub2, quad3, linez]
+ #
+ # # this is necessary due to changes to the builtin `hash` function
+ # python_version = sys.version_info.major + 0.1*sys.version_info.minor
+ # user_hash_seed = os.environ.get("PYTHONHASHSEED", "")
+ # os.environ["PYTHONHASHSEED"] = "314"
+ # if 3.8 <= python_version:
+ # expected_hashes = [
+ # -6073024107272494569, -2519772625496438197, 8726412907710383506,
+ # 2132930052750006195, 3112548573593977871, 991446120749438306,
+ # -5589397644574569777, -4438808571483114580, -3125333407400456536,
+ # -4418099728831808951, 702646573139378041, -6331016786776229094,
+ # 5053050772929443013, 6102272282813527681, -5385294438006156225
+ # ]
+ # elif 3.2 <= python_version < 3.8:
+ # expected_hashes = [
+ # -5662973462929734898, 5166874115671195563, 5223434942701471389,
+ # -7224979960884350294, -5178990533869800243, -4003140762934044601,
+ # 8575549467429100514, -6692132994808317852, 1594848578230132678,
+ # -6374833902132909499, 4188352014604112779, -5090374009174854814,
+ # -7093907105533857815, 2036243740727202243, -8108488067585685407
+ # ]
+ # else:
+ # expected_hashes = [
+ # -5762846476463470127, -138736730317965290, -2005041722222729058,
+ # 8448700906794235291, -5178990533869800243, -4003140762934044601,
+ # 8575549467429100514, 5166859065265868968, 1373103287265872323,
+ # -1022491904150314631, 4188352014604112779, -5090374009174854814,
+ # -7093907105533857815, 2036243740727202243, -8108488067585685407
+ # ]
+ #
+ # for c, h in zip(test_curves, expected_hashes):
+ # self.assertTrue(hash(c) == h, msg="hash {} was expected for curve = {}".format(h, c))
+ # os.environ["PYTHONHASHSEED"] = user_hash_seed # restore user's hash seed
def test_circle(self):
arc1 = Arc(0j, 100 + 100j, 0, 0, 0, 200 + 0j)