This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository python-shapely.
commit b5f3c9f91b8c102bae8e24ae1421187990b783f4 Author: Bas Couwenberg <[email protected]> Date: Sat Dec 31 11:53:06 2016 +0100 Imported Upstream version 1.6~b3 --- CHANGES.txt | 9 ++++++++ setup.cfg | 2 +- shapely/__init__.py | 2 +- shapely/geos.py | 38 ++++++++++++------------------ shapely/speedups/__init__.py | 21 +++++++++++------ shapely/speedups/_speedups.pyx | 16 +++++++++++-- tests/test_geos_err_handler.py | 52 ++++++++++++++++++++++++++++++++++-------- 7 files changed, 95 insertions(+), 45 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index a39734d..2e51be8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,15 @@ Changes ======= +1.6b3 (2016-12-31) +------------------ + +Bug fixes: + +- Level for log messages originating from the GEOS notice handler reduced from + WARNING to INFO (#447). +- Permit speedups to be imported again without Numpy (#444). + 1.6b2 (2016-12-12) ------------------ diff --git a/setup.cfg b/setup.cfg index 5ee6477..25c6497 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,2 @@ -[pytest] +[tool:pytest] testpaths = tests diff --git a/shapely/__init__.py b/shapely/__init__.py index fb79012..2060dbb 100644 --- a/shapely/__init__.py +++ b/shapely/__init__.py @@ -1 +1 @@ -__version__ = "1.6b2" +__version__ = "1.6b3" diff --git a/shapely/geos.py b/shapely/geos.py index 3cff7f1..b9d66f6 100644 --- a/shapely/geos.py +++ b/shapely/geos.py @@ -203,35 +203,25 @@ if geos_version >= (3, 1, 0): _lgeos.finishGEOS_r.argtypes = [c_void_p] -def handler(level): - """Error handler - - While this function can take any number of positional arguments when - called from Python and GEOS expects its error handler to accept any - number of arguments (like printf), I'm unable to get ctypes to make - a callback object from this function that will accept any number of - arguments. - - At the moment, functions in the GEOS C API only pass 0 or - 1 arguments to the error handler. We can deal with this, but when if - that changes, Shapely may break. +def make_logging_callback(func): + """Error or notice handler callback producr + + Wraps a logger method, func, as a GEOS callback. """ - def callback(fmt, *args): + def callback(fmt, *fmt_args): fmt = fmt.decode('ascii') conversions = re.findall(r'%.', fmt) - log_vals = [] - for spec, arg in zip(conversions, args): - if spec == '%s' and arg is not None: - log_vals.append(string_at(arg).decode('ascii')) - else: - LOG.error("An error occurred, but the format string " - "'%s' could not be converted.", fmt) - return - getattr(LOG, level)(fmt, *log_vals) + args = [ + string_at(arg).decode('ascii') + for spec, arg in zip(conversions, fmt_args) + if spec == '%s' and arg is not None] + + func(fmt, *args) + return callback -error_handler = handler('error') -notice_handler = handler('warning') +error_handler = make_logging_callback(LOG.error) +notice_handler = make_logging_callback(LOG.info) error_h = EXCEPTION_HANDLER_FUNCTYPE(error_handler) notice_h = EXCEPTION_HANDLER_FUNCTYPE(notice_handler) diff --git a/shapely/speedups/__init__.py b/shapely/speedups/__init__.py index cc30606..faa9205 100644 --- a/shapely/speedups/__init__.py +++ b/shapely/speedups/__init__.py @@ -4,6 +4,9 @@ from shapely.geometry import linestring, polygon from shapely import coords import shapely.affinity +from ..ftools import wraps + + try: from shapely.speedups import _speedups available = True @@ -14,7 +17,7 @@ except ImportError: # TODO: This does not appear to do anything useful import_error_msg = sys.exc_info()[1] -from ..ftools import wraps + def method_wrapper(f): def wrapper(*args, **kwargs): return f(*args, **kwargs) @@ -26,6 +29,7 @@ _orig = {} # keep track of whether speedups are enabled enabled = False + def enable(): """Enable Cython speedups @@ -46,23 +50,25 @@ def enable(): if not available: warnings.warn("shapely.speedups not available", RuntimeWarning) return - + if _orig: return - + _orig['CoordinateSequence.ctypes'] = coords.CoordinateSequence.ctypes coords.CoordinateSequence.ctypes = property(_speedups.coordseq_ctypes) - + _orig['CoordinateSequence.__iter__'] = coords.CoordinateSequence.__iter__ - coords.CoordinateSequence.__iter__ = method_wrapper(_speedups.coordseq_iter) + coords.CoordinateSequence.__iter__ = method_wrapper( + _speedups.coordseq_iter) _orig['geos_linestring_from_py'] = linestring.geos_linestring_from_py linestring.geos_linestring_from_py = _speedups.geos_linestring_from_py - _orig['geos_linearring_from_py'] = polygon.geos_linearring_from_py + _orig['geos_linearring_from_py'] = polygon.geos_linearring_from_py polygon.geos_linearring_from_py = _speedups.geos_linearring_from_py - + _orig['affine_transform'] = shapely.affinity.affine_transform + # copy docstring from original function def affine_transform(geom, matrix): return _speedups.affine_transform(geom, matrix) @@ -72,6 +78,7 @@ def enable(): global enabled enabled = True + def disable(): """Disable Cython speedups """ diff --git a/shapely/speedups/_speedups.pyx b/shapely/speedups/_speedups.pyx index 72da797..8754c1b 100644 --- a/shapely/speedups/_speedups.pyx +++ b/shapely/speedups/_speedups.pyx @@ -6,7 +6,7 @@ # Transcription to cython: Copyright (c) 2011, Oliver Tonnhofer import ctypes -import numpy +import logging from shapely.geos import lgeos from shapely.geometry import Point, LineString, LinearRing @@ -16,6 +16,18 @@ include "../_geos.pxi" from libc.stdint cimport uintptr_t + +log = logging.getLogger(__name__) + +try: + import numpy + has_numpy = True +except ImportError: + log.info("Numpy was not imported, continuing without requires()") + has_numpy = False + numpy = None + + cdef inline GEOSGeometry *cast_geom(uintptr_t geom_addr): return <GEOSGeometry *>geom_addr @@ -36,7 +48,7 @@ def required(ob): """Return an object that meets Shapely requirements for self-owned C-continguous data, copying if necessary, or just return the original object.""" - if hasattr(ob, '__array_interface__'): + if has_numpy and hasattr(ob, '__array_interface__'): return numpy.require(ob, numpy.float64, ["C", "OWNDATA"]) else: return ob diff --git a/tests/test_geos_err_handler.py b/tests/test_geos_err_handler.py index b4b11ce..cf7e7d8 100644 --- a/tests/test_geos_err_handler.py +++ b/tests/test_geos_err_handler.py @@ -7,27 +7,59 @@ from shapely.errors import ReadingError from shapely.wkt import loads -def test_error_handler(tmpdir): +def test_error_handler_exception(tmpdir): + """Error logged in addition to exception""" logger = logging.getLogger('shapely.geos') - logger.setLevel(logging.DEBUG) - logfile = str(tmpdir.join('test_error.log')) fh = logging.FileHandler(logfile) logger.addHandler(fh) - # This operation calls error_handler with a format string that - # has *no* conversion specifiers. - LineString([(0, 0), (2, 2)]).project(LineString([(1, 1), (1.5, 1.5)])) - # This calls error_handler with a format string of "%s" and one # value. with pytest.raises(ReadingError): loads('POINT (LOLWUT)') - g = loads('MULTIPOLYGON (((10 20, 10 120, 60 70, 30 70, 30 40, 60 40, 60 70, 90 20, 10 20)))') - assert g.is_valid == False + log = open(logfile).read() + assert "Expected number but encountered word: 'LOLWUT'" in log + + +def test_error_handler(tmpdir): + logger = logging.getLogger('shapely.geos') + logfile = str(tmpdir.join('test_error.log')) + fh = logging.FileHandler(logfile) + logger.addHandler(fh) + + # This operation calls error_handler with a format string that + # has *no* conversion specifiers. + LineString([(0, 0), (2, 2)]).project(LineString([(1, 1), (1.5, 1.5)])) log = open(logfile).read() assert "third argument of GEOSProject_r must be Point*" in log - assert "Expected number but encountered word: 'LOLWUT'" in log + + +def test_info_handler(tmpdir): + logger = logging.getLogger('shapely.geos') + logfile = str(tmpdir.join('test_error.log')) + fh = logging.FileHandler(logfile) + logger.addHandler(fh) + logger.setLevel(logging.INFO) + + g = loads('MULTIPOLYGON (((10 20, 10 120, 60 70, 30 70, 30 40, 60 40, 60 70, 90 20, 10 20)))') + assert not g.is_valid + + log = open(logfile).read() assert "Ring Self-intersection at or near point 60 70" in log + + +def test_info_handler_quiet(tmpdir): + logger = logging.getLogger('shapely.geos') + logfile = str(tmpdir.join('test_error.log')) + fh = logging.FileHandler(logfile) + logger.addHandler(fh) + logger.setLevel(logging.WARNING) + + g = loads('MULTIPOLYGON (((10 20, 10 120, 60 70, 30 70, 30 40, 60 40, 60 70, 90 20, 10 20)))') + assert not g.is_valid + + log = open(logfile).read() + assert "Ring Self-intersection at or near point 60 70" not in log -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/python-shapely.git _______________________________________________ Pkg-grass-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

