This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository python-shapely.
commit 1557f80198839c56190b5ada745ad1ee605955b2 Author: Pietro Battiston <m...@pietrobattiston.it> Date: Sun Sep 19 10:10:19 2010 +0200 Imported Upstream version 1.2.4 --- CHANGES.txt | 7 +++++ PKG-INFO | 2 +- Shapely.egg-info/PKG-INFO | 2 +- Shapely.egg-info/SOURCES.txt | 2 ++ docs/_build/html/_sources/manual.txt | 6 ++-- docs/manual.txt | 6 ++-- setup.py | 2 +- shapely/geometry/base.py | 8 +++-- shapely/geos.py | 60 ++++++++++++++++-------------------- shapely/impl.py | 28 ++++++++++++++++- shapely/prepared.py | 8 +++-- shapely/tests/__init__.py | 4 ++- shapely/tests/test_delegated.py | 22 +++++++++++++ shapely/tests/test_dlls.py | 14 +++++++++ 14 files changed, 125 insertions(+), 46 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 95b6144..b006bbc 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,12 @@ All tickets are children of http://trac.gispython.org/lab/ticket. +1.2.4 (2010-09-09) +------------------ +- Raise AttributeError when there's no backend support for a method. +- Raise OSError if libgeos_c.so (or variants) can't be found and loaded. +- Add geos_c DLL loading support for linux platforms where find_library + doesn't work. + 1.2.3 (2010-08-17) ------------------ - Add mapping function. diff --git a/PKG-INFO b/PKG-INFO index d1567fe..e881ef0 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: Shapely -Version: 1.2.3 +Version: 1.2.4 Summary: Geometric objects, predicates, and operations Home-page: http://trac.gispython.org/lab/wiki/Shapely Author: Sean Gillies diff --git a/Shapely.egg-info/PKG-INFO b/Shapely.egg-info/PKG-INFO index d1567fe..e881ef0 100644 --- a/Shapely.egg-info/PKG-INFO +++ b/Shapely.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: Shapely -Version: 1.2.3 +Version: 1.2.4 Summary: Geometric objects, predicates, and operations Home-page: http://trac.gispython.org/lab/wiki/Shapely Author: Sean Gillies diff --git a/Shapely.egg-info/SOURCES.txt b/Shapely.egg-info/SOURCES.txt index 8674cb8..d0a387c 100644 --- a/Shapely.egg-info/SOURCES.txt +++ b/Shapely.egg-info/SOURCES.txt @@ -60,6 +60,8 @@ shapely/tests/linear-referencing.txt shapely/tests/linemerge.txt shapely/tests/polygonize.txt shapely/tests/test_collection.py +shapely/tests/test_delegated.py +shapely/tests/test_dlls.py shapely/tests/test_doctests.py shapely/tests/test_emptiness.py shapely/tests/test_equality.py diff --git a/docs/_build/html/_sources/manual.txt b/docs/_build/html/_sources/manual.txt index dd6ee8d..9025c9c 100644 --- a/docs/_build/html/_sources/manual.txt +++ b/docs/_build/html/_sources/manual.txt @@ -3,8 +3,8 @@ The Shapely 1.2 User Manual (Preview) ===================================== :Author: Sean Gillies, <sean.gill...@gmail.com> -:Revision: 1.2.2 -:Date: 10 August 2010 +:Revision: 1.2.3 +:Date: 19 August 2010 :Copyright: This work is licensed under a `Creative Commons Attribution 3.0 United States License`__. @@ -1717,6 +1717,8 @@ The GeoJSON-like mapping of a geometric object can be obtained using Return a new, independent geometry with coordinates `copied` from the context. + `New in version 1.2.3`. + For example, using the same `GeoThing` class: .. sourcecode:: pycon diff --git a/docs/manual.txt b/docs/manual.txt index dd6ee8d..9025c9c 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -3,8 +3,8 @@ The Shapely 1.2 User Manual (Preview) ===================================== :Author: Sean Gillies, <sean.gill...@gmail.com> -:Revision: 1.2.2 -:Date: 10 August 2010 +:Revision: 1.2.3 +:Date: 19 August 2010 :Copyright: This work is licensed under a `Creative Commons Attribution 3.0 United States License`__. @@ -1717,6 +1717,8 @@ The GeoJSON-like mapping of a geometric object can be obtained using Return a new, independent geometry with coordinates `copied` from the context. + `New in version 1.2.3`. + For example, using the same `GeoThing` class: .. sourcecode:: pycon diff --git a/setup.py b/setup.py index 00ad9b1..494211e 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ readme_text = file('README.txt', 'rb').read() setup_args = dict( metadata_version = '1.2', name = 'Shapely', - version = '1.2.3', + version = '1.2.4', requires_python = '>=2.5,<3', requires_external = 'libgeos_c (>=3.1)', description = 'Geometric objects, predicates, and operations', diff --git a/shapely/geometry/base.py b/shapely/geometry/base.py index ee1db9f..e6e6fee 100644 --- a/shapely/geometry/base.py +++ b/shapely/geometry/base.py @@ -7,7 +7,7 @@ import warnings from shapely.coords import CoordinateSequence from shapely.geos import lgeos -from shapely.impl import DefaultImplementation +from shapely.impl import DefaultImplementation, delegated from shapely import wkb, wkt GEOMETRY_TYPES = [ @@ -250,6 +250,7 @@ class BaseGeometry(object): """Returns the geometric center of the object""" return geom_factory(self.impl['centroid'](self)) + @delegated def representative_point(self): """Returns a point guaranteed to be within the object, cheaply.""" return geom_factory(self.impl['representative_point'](self)) @@ -299,6 +300,7 @@ class BaseGeometry(object): res = resolution return geom_factory(self.impl['buffer'](self, distance, res)) + @delegated def simplify(self, tolerance, preserve_topology=True): """Returns a simplified geometry produced by the Douglas-Puecker algorithm @@ -419,6 +421,7 @@ class BaseGeometry(object): # Linear referencing # ------------------ + @delegated def project(self, other, normalized=False): """Returns the distance along this geometry to a point nearest the specified point @@ -431,7 +434,8 @@ class BaseGeometry(object): else: op = self.impl['project'] return op(self, other) - + + @delegated def interpolate(self, distance, normalized=False): """Return a point at the specified distance along a linear geometry diff --git a/shapely/geos.py b/shapely/geos.py index 4dfe04f..bad1491 100644 --- a/shapely/geos.py +++ b/shapely/geos.py @@ -25,30 +25,38 @@ LOG.addHandler(NullHandler()) # Find and load the GEOS and C libraries # If this ever gets any longer, we'll break it into separate modules +def load_dll(libname, fallbacks=None): + lib = find_library(libname) + if lib is not None: + return CDLL(lib) + else: + if fallbacks is not None: + for name in fallbacks: + try: + return CDLL(name) + except OSError: + # move on to the next fallback + pass + # the end + raise OSError( + "Could not find library %s or load any of its variants %s" % ( + libname, fallbacks or [])) + if sys.platform == 'linux2': - _lgeos = CDLL(find_library('geos_c')) - free = CDLL(find_library('c')).free + _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so']) + free = load_dll('c').free free.argtypes = [c_void_p] free.restype = None elif sys.platform == 'darwin': - lib = find_library('geos_c') - if lib is None: - ## try a few more locations - lib_paths = [ + alt_paths = [ # The Framework build from Kyng Chaos: "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS", # macports '/opt/local/lib/libgeos_c.dylib', - ] - for path in lib_paths: - if os.path.exists(path): - lib = path - break - if lib is None: - raise ImportError("Could not find geos_c library") - _lgeos = CDLL(lib) - free = CDLL(find_library('c')).free + ] + _lgeos = load_dll('geos_c', fallbacks=alt_paths) + free = load_dll('c').free free.argtypes = [c_void_p] free.restype = None @@ -58,7 +66,7 @@ elif sys.platform == 'win32': original_path = os.environ['PATH'] os.environ['PATH'] = "%s;%s" % (local_dlls, original_path) _lgeos = CDLL("geos.dll") - except (ImportError, WindowsError): + except (ImportError, WindowsError, OSError): raise def free(m): try: @@ -68,28 +76,14 @@ elif sys.platform == 'win32': pass elif sys.platform == 'sunos5': - # Try the major versioned name first, falling back on the unversioned - # name. - try: - _lgeos = CDLL('libgeos_c.so.1') - except (OSError, ImportError): - _lgeos = CDLL('libgeos_c.so') - except: - raise + _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so']) free = CDLL('libc.so.1').free free.argtypes = [c_void_p] free.restype = None else: # other *nix systems - # Try the major versioned name first, falling back on the unversioned - # name. - try: - _lgeos = CDLL('libgeos_c.so.1') - except (OSError, ImportError): - _lgeos = CDLL('libgeos_c.so') - except: - raise - free = CDLL('libc.so.6').free + _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so']) + free = load_dll('c', fallbacks=['libc.so.6']).free free.argtypes = [c_void_p] free.restype = None diff --git a/shapely/impl.py b/shapely/impl.py index 5497672..62836c3 100644 --- a/shapely/impl.py +++ b/shapely/impl.py @@ -11,6 +11,8 @@ This is layer number 2 from the list below. Shapely 1.2 includes a GEOS backend and it is the default. """ +from functools import wraps + from shapely.coords import BoundsOp from shapely.geos import lgeos from shapely.linref import ProjectOp, InterpolateOp @@ -18,9 +20,33 @@ from shapely.predicates import BinaryPredicate, UnaryPredicate from shapely.topology import BinaryRealProperty, BinaryTopologicalOp from shapely.topology import UnaryRealProperty, UnaryTopologicalOp +def delegated(func): + """A delegated method raises AttributeError in the absence of backend + support.""" + @wraps(func) + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except KeyError: + raise AttributeError, "Method '%s' is not supported by %s" % ( + func.__name__, repr(args[0].impl)) + return wrapper # Map geometry methods to their GEOS delegates +class BaseImpl(object): + def __init__(self, values): + self.map = dict(values) + def update(self, values): + self.map.update(values) + def __getitem__(self, key): + return self.map[key] + +class GEOSImpl(BaseImpl): + def __repr__(self): + return '<GEOSImpl object: GEOS C API version %s>' % ( + lgeos.geos_capi_version,) + IMPL14 = { 'area': (UnaryRealProperty, 'area'), 'distance': (BinaryRealProperty, 'distance'), @@ -81,7 +107,7 @@ IMPL16LR = { def impl_items(defs): return [(k, v[0](v[1])) for k, v in defs.items()] -imp = dict(impl_items(IMPL14)) +imp = GEOSImpl(dict(impl_items(IMPL14))) if lgeos.geos_capi_version >= (1, 5, 0): imp.update(impl_items(IMPL15)) if lgeos.geos_capi_version >= (1, 6, 0): diff --git a/shapely/prepared.py b/shapely/prepared.py index 0f41406..c2dc3c7 100644 --- a/shapely/prepared.py +++ b/shapely/prepared.py @@ -3,7 +3,7 @@ Support for GEOS prepared geometry operations. """ from shapely.geos import lgeos -from shapely.impl import DefaultImplementation +from shapely.impl import DefaultImplementation, delegated class PreparedGeometry(object): @@ -34,16 +34,20 @@ class PreparedGeometry(object): @property def _geom(self): return self.__geom__ - + + @delegated def intersects(self, other): return bool(self.impl['prepared_intersects'](self, other)) + @delegated def contains(self, other): return bool(self.impl['prepared_contains'](self, other)) + @delegated def contains_properly(self, other): return bool(self.impl['prepared_contains_properly'](self, other)) + @delegated def covers(self, other): return bool(self.impl['prepared_covers'](self, other)) diff --git a/shapely/tests/__init__.py b/shapely/tests/__init__.py index 30f2347..ac6ce01 100644 --- a/shapely/tests/__init__.py +++ b/shapely/tests/__init__.py @@ -2,7 +2,7 @@ from unittest import TestSuite import test_doctests, test_prepared, test_equality, test_geomseq, test_xy import test_collection, test_emptiness, test_singularity, test_validation -import test_mapping +import test_mapping, test_delegated, test_dlls def test_suite(): suite = TestSuite() @@ -16,5 +16,7 @@ def test_suite(): suite.addTest(test_singularity.test_suite()) suite.addTest(test_validation.test_suite()) suite.addTest(test_mapping.test_suite()) + suite.addTest(test_delegated.test_suite()) + suite.addTest(test_dlls.test_suite()) return suite diff --git a/shapely/tests/test_delegated.py b/shapely/tests/test_delegated.py new file mode 100644 index 0000000..49cbf2d --- /dev/null +++ b/shapely/tests/test_delegated.py @@ -0,0 +1,22 @@ +import unittest +from shapely.geometry import Point +from shapely.impl import BaseImpl +from shapely.geometry.base import delegated + +class Geometry(object): + impl = BaseImpl({}) + @property + @delegated + def foo(self): + return self.impl['foo']() + +class WrapperTestCase(unittest.TestCase): + """When the backend has no support for a method, we get an AttributeError""" + def test_delegated(self): + self.assertRaises(AttributeError, getattr, Geometry(), 'foo') + def test_defaultimpl(self): + del Point.impl.map['project'] + self.assertRaises(AttributeError, Point(0, 0).project, 1.0) + +def test_suite(): + return unittest.TestLoader().loadTestsFromTestCase(WrapperTestCase) diff --git a/shapely/tests/test_dlls.py b/shapely/tests/test_dlls.py new file mode 100644 index 0000000..8715561 --- /dev/null +++ b/shapely/tests/test_dlls.py @@ -0,0 +1,14 @@ +import os +import sys +import unittest + +from shapely.geos import load_dll + +class LoadingTestCase(unittest.TestCase): + def test_load(self): + self.assertRaises(OSError, load_dll, 'geosh_c') + def test_fallbacks(self): + a = load_dll('geosh_c', fallbacks=['/opt/local/lib/libgeos_c.dylib']) + +def test_suite(): + return unittest.TestLoader().loadTestsFromTestCase(LoadingTestCase) -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/python-shapely.git _______________________________________________ Pkg-grass-devel mailing list Pkg-grass-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel