From 8aefba84b5a21e27fd0572b2f61810e3158e8585 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Fri, 25 Jun 2021 17:08:44 +0100 Subject: [PATCH 1/3] turn pyclipper into a package, export dynamic '__version__' the _version.py file is autogenerated at build time from git tag using setuptools_scm; the pyclipper.__version__ variable exports that, as it's common in python packaging. This allows clients to import pyclipper and check its __version__ without needing to query the package metadata (which may be missing when pyclipper is embedded in native applications). --- .gitignore | 5 +++-- MANIFEST.in | 2 +- setup.py | 15 +++++++++------ {pyclipper => src}/clipper.cpp | 0 {pyclipper => src}/clipper.hpp | 0 {pyclipper => src}/extra_defines.hpp | 0 src/pyclipper/__init__.py | 6 ++++++ .../pyclipper.pyx => src/pyclipper/_pyclipper.pyx | 0 8 files changed, 19 insertions(+), 9 deletions(-) rename {pyclipper => src}/clipper.cpp (100%) rename {pyclipper => src}/clipper.hpp (100%) rename {pyclipper => src}/extra_defines.hpp (100%) create mode 100644 src/pyclipper/__init__.py rename pyclipper/pyclipper.pyx => src/pyclipper/_pyclipper.pyx (100%) diff --git a/.gitignore b/.gitignore index b7628f3..74fdf44 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,8 @@ build dist pyclipper.egg-info *.so -pyclipper/pyclipper.cpp +src/pyclipper/_pyclipper.cpp +src/pyclipper/_version.py *.pyc MANIFEST -.eggs/ \ No newline at end of file +.eggs/ diff --git a/MANIFEST.in b/MANIFEST.in index 4aa3d08..f3b346d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -3,7 +3,7 @@ # Here we only need to include those which are not tracked by git but we do # want to be included -include pyclipper/pyclipper.cpp +include src/pyclipper/_pyclipper.cpp # and exclude those that are tracked by git but don't want to be in the sdist exclude dev diff --git a/setup.py b/setup.py index bd0cd83..a0559d5 100755 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from __future__ import print_function import sys import os -from setuptools import setup +from setuptools import setup, find_packages from setuptools.extension import Extension from io import open @@ -23,7 +23,7 @@ from Cython.Distutils import build_ext print('Development mode: Compiling Cython modules from .pyx sources.') - sources = ["pyclipper/pyclipper.pyx", "pyclipper/clipper.cpp"] + sources = ["src/pyclipper/_pyclipper.pyx", "src/clipper.cpp"] from setuptools.command.sdist import sdist as _sdist @@ -40,7 +40,7 @@ def run(self): else: print('Distribution mode: Compiling Cython generated .cpp sources.') - sources = ["pyclipper/pyclipper.cpp", "pyclipper/clipper.cpp"] + sources = ["src/pyclipper/_pyclipper.cpp", "src/clipper.cpp"] cmdclass = {} @@ -48,13 +48,14 @@ def run(self): pytest_runner = ['pytest_runner'] if needs_pytest else [] -ext = Extension("pyclipper", +ext = Extension("pyclipper._pyclipper", sources=sources, language="c++", + include_dirs=["src"], # define extra macro definitions that are used by clipper # Available definitions that can be used with pyclipper: # use_lines, use_int32 - # See pyclipper/clipper.hpp + # See src/clipper.hpp # define_macros=[('use_lines', 1)] ) @@ -63,7 +64,7 @@ def run(self): setup( name='pyclipper', - use_scm_version=True, + use_scm_version={"write_to": "src/pyclipper/_version.py"}, description='Cython wrapper for the C++ translation of the Angus Johnson\'s Clipper library (ver. 6.4.2)', long_description=long_description, author='Angus Johnson, Maxime Chalton, Lukas Treyer, Gregor Ratajc', @@ -89,6 +90,8 @@ def run(self): "Topic :: Scientific/Engineering :: Mathematics", "Topic :: Software Development :: Libraries :: Python Modules" ], + package_dir={"": "src"}, + packages=find_packages(where="src"), ext_modules=[ext], setup_requires=[ 'cython>=0.28', diff --git a/pyclipper/clipper.cpp b/src/clipper.cpp similarity index 100% rename from pyclipper/clipper.cpp rename to src/clipper.cpp diff --git a/pyclipper/clipper.hpp b/src/clipper.hpp similarity index 100% rename from pyclipper/clipper.hpp rename to src/clipper.hpp diff --git a/pyclipper/extra_defines.hpp b/src/extra_defines.hpp similarity index 100% rename from pyclipper/extra_defines.hpp rename to src/extra_defines.hpp diff --git a/src/pyclipper/__init__.py b/src/pyclipper/__init__.py new file mode 100644 index 0000000..b1d5548 --- /dev/null +++ b/src/pyclipper/__init__.py @@ -0,0 +1,6 @@ +from ._pyclipper import * + +try: + from ._version import version as __version__ +except ImportError: + __version__ = "0.0.0+unknown" diff --git a/pyclipper/pyclipper.pyx b/src/pyclipper/_pyclipper.pyx similarity index 100% rename from pyclipper/pyclipper.pyx rename to src/pyclipper/_pyclipper.pyx From 1d003cdeaf677054ac01deae9fea5c91d73c64b8 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Fri, 25 Jun 2021 17:15:52 +0100 Subject: [PATCH 2/3] drop long deprecated SCALING_FACTOR warnings since we moved the extension module to an internal pyclipper._pyclipper submodule, setting SCALING_FACTOR on the parent pyclipper package won't work any more. We may as well remove the deprecation warnings altogether since they have been there for long time now. --- src/pyclipper/_pyclipper.pyx | 26 ------------------ tests/test_pyclipper.py | 52 +++--------------------------------- 2 files changed, 3 insertions(+), 75 deletions(-) diff --git a/src/pyclipper/_pyclipper.pyx b/src/pyclipper/_pyclipper.pyx index 693fd5d..8acf584 100644 --- a/src/pyclipper/_pyclipper.pyx +++ b/src/pyclipper/_pyclipper.pyx @@ -8,12 +8,6 @@ This wrapper was written by Maxime Chalton, Lukas Treyer and Gregor Ratajc. SILENT = True -""" -SCALING_FACTOR has been deprecated. See https://github.com/greginvm/pyclipper/wiki/Deprecating-SCALING_FACTOR -for an explanation. -""" -SCALING_FACTOR = 1 - def log_action(description): if not SILENT: @@ -670,8 +664,6 @@ cdef class Pyclipper: Returns: PyIntRect with left, right, bottom, top vertices that define the axis-aligned bounding rectangle. """ - _check_scaling_factor() - cdef IntRect rr with nogil: rr = self.thisptr.GetBounds() @@ -860,13 +852,9 @@ cdef class PyclipperOffset: More info: http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm """ def __get__(self): - _check_scaling_factor() - return self.thisptr.ArcTolerance def __set__(self, value): - _check_scaling_factor() - self.thisptr.ArcTolerance = value @@ -926,8 +914,6 @@ cdef Paths _to_clipper_paths(object polygons): cdef Path _to_clipper_path(object polygon): - _check_scaling_factor() - cdef Path path = Path() cdef IntPoint p for v in polygon: @@ -952,21 +938,9 @@ cdef object _from_clipper_paths(Paths paths): cdef object _from_clipper_path(Path path): - _check_scaling_factor() - poly = [] cdef IntPoint point for i in xrange(path.size()): point = path[i] poly.append([point.X, point.Y]) return poly - - -def _check_scaling_factor(): - """ - Check whether SCALING_FACTOR has been set by the code using this library and warn the user that it has been - deprecated and it's value is ignored. - """ - - if SCALING_FACTOR != 1: - _warnings.warn('SCALING_FACTOR is deprecated and it\'s value is ignored. See https://github.com/greginvm/pyclipper/wiki/Deprecating-SCALING_FACTOR for more information.', DeprecationWarning) diff --git a/tests/test_pyclipper.py b/tests/test_pyclipper.py index 15f4f79..5b9f70a 100644 --- a/tests/test_pyclipper.py +++ b/tests/test_pyclipper.py @@ -37,8 +37,6 @@ def test_has_namespace_methods(self): class TestNamespaceMethods(TestCase): - def setUp(self): - pyclipper.SCALING_FACTOR = 1 def test_orientation(self): self.assertFalse(pyclipper.Orientation(PATH_SUBJ_1)) @@ -166,7 +164,6 @@ def check_paths(self, paths, expected_nr): class TestPyclipperAddPaths(TestCase): def setUp(self): - pyclipper.SCALING_FACTOR = 1 self.pc = pyclipper.Pyclipper() def test_add_path(self): @@ -202,16 +199,13 @@ def test_pyclipper_properties(self): self.check_property_assignment(pc, prop_name, [True, False]) def test_pyclipperoffset_properties(self): - for factor in range(6): - pyclipper.SCALING_FACTOR = 10 ** factor - pc = pyclipper.PyclipperOffset() - for prop_name in ('MiterLimit', 'ArcTolerance'): - self.check_property_assignment(pc, prop_name, [2.912, 132.12, 12, -123]) + pc = pyclipper.PyclipperOffset() + for prop_name in ('MiterLimit', 'ArcTolerance'): + self.check_property_assignment(pc, prop_name, [2.912, 132.12, 12, -123]) class TestPyclipperExecute(TestCase): def setUp(self): - pyclipper.SCALING_FACTOR = 1 self.pc = pyclipper.Pyclipper() self.add_default_paths(self.pc) self.default_args = [pyclipper.CT_INTERSECTION, pyclipper.PFT_EVENODD, pyclipper.PFT_EVENODD] @@ -285,8 +279,6 @@ def check_pypolynode(self, node): class TestPyclipperOffset(TestCase): - def setUp(self): - pyclipper.SCALING_FACTOR = 1 @staticmethod def add_path(pc, path): @@ -316,44 +308,6 @@ def test_clear(self): self.assertEqual(len(solution), 0) -class TestScalingFactorWarning(TestCase): - def setUp(self): - pyclipper.SCALING_FACTOR = 2. - self.pc = pyclipper.Pyclipper() - - def test_orientation(self): - with self.assertWarns(DeprecationWarning): - pyclipper.Orientation(PATH_SUBJ_1) - - def test_area(self): - with self.assertWarns(DeprecationWarning): - pyclipper.Area(PATH_SUBJ_1) - - def test_point_in_polygon(self): - with self.assertWarns(DeprecationWarning): - self.assertEqual(pyclipper.PointInPolygon((180, 200), PATH_SUBJ_1), -1) - - def test_minkowski_sum(self): - with self.assertWarns(DeprecationWarning): - pyclipper.MinkowskiSum(PATTERN, PATH_SIGMA, False) - - def test_minkowski_sum2(self): - with self.assertWarns(DeprecationWarning): - pyclipper.MinkowskiSum2(PATTERN, [PATH_SIGMA], False) - - def test_minkowski_diff(self): - with self.assertWarns(DeprecationWarning): - pyclipper.MinkowskiDiff(PATH_SUBJ_1, PATH_SUBJ_2) - - def test_add_path(self): - with self.assertWarns(DeprecationWarning): - self.pc.AddPath(PATH_CLIP_1, poly_type=pyclipper.PT_CLIP) - - def test_add_paths(self): - with self.assertWarns(DeprecationWarning): - self.pc.AddPaths([PATH_SUBJ_1, PATH_SUBJ_2], poly_type=pyclipper.PT_SUBJECT) - - class TestScalingFunctions(TestCase): scale = 2 ** 31 path = [(0, 0), (1, 1)] From 19fcc36ee1e2d866eb2772a3efc2f8104b8c9235 Mon Sep 17 00:00:00 2001 From: Cosimo Lupo Date: Fri, 25 Jun 2021 17:30:35 +0100 Subject: [PATCH 3/3] test_pyclipper: check pyclipper.__version__ exists and is a string --- tests/test_pyclipper.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_pyclipper.py b/tests/test_pyclipper.py index 5b9f70a..ab278c0 100644 --- a/tests/test_pyclipper.py +++ b/tests/test_pyclipper.py @@ -375,6 +375,12 @@ def test_sympyzero(self): assert path == [[0, 0], [0, 2147483648]] +class TestPackageVersion(TestCase): + def test__version__(self): + assert hasattr(pyclipper, "__version__") + assert isinstance(pyclipper.__version__, str) + + def _do_solutions_match(paths_1, paths_2, factor=None): if len(paths_1) != len(paths_2): return False