[python-shapely] 01/06: Imported Upstream version 1.5.13

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Sun Oct 11 10:00:24 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository python-shapely.

commit 5faff2115a2de564aab062462f6d084960365631
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sun Oct 11 11:03:32 2015 +0200

    Imported Upstream version 1.5.13
---
 CHANGES.txt                          |   8 ++
 setup.py                             |   2 +-
 shapely/__init__.py                  |   2 +-
 shapely/{libgeos.py => _buildcfg.py} |  73 +++++++++-------
 shapely/geometry/base.py             |   4 +-
 shapely/geometry/polygon.py          |   2 +-
 shapely/geos.py                      | 161 +++++++++++++++++++++++++++++++++--
 tests/__init__.py                    |   4 +-
 tests/test_dlls.py                   |   6 +-
 tests/test_hash.py                   |  24 +++++-
 10 files changed, 234 insertions(+), 52 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 3257c36..e353755 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,14 @@
 Changes
 =======
 
+1.5.13 (2015-10-09)
+-------------------
+- Restore setup and runtime discovery and loading of GEOS shared library to
+  state at version 1.5.9 (#326).
+- On OS X we try to reuse any GEOS shared library that may have been loaded
+  via import of Fiona or Rasterio in order to avoid a bug involving the
+  GEOS AbstractSTRtree (#324, #327).
+
 1.5.12 (2015-08-27)
 -------------------
 - Remove configuration of root logger from libgeos.py (#312).
diff --git a/setup.py b/setup.py
index 34d7969..abe841a 100755
--- a/setup.py
+++ b/setup.py
@@ -35,7 +35,7 @@ from distutils.version import StrictVersion as Version
 
 # Get geos_version from GEOS dynamic library, which depends on
 # GEOS_LIBRARY_PATH and/or GEOS_CONFIG environment variables
-from shapely.libgeos import geos_version_string, geos_version, \
+from shapely._buildcfg import geos_version_string, geos_version, \
         geos_config, get_geos_config
 
 logging.basicConfig()
diff --git a/shapely/__init__.py b/shapely/__init__.py
index da34e60..1d51ed9 100644
--- a/shapely/__init__.py
+++ b/shapely/__init__.py
@@ -1 +1 @@
-__version__ = "1.5.12"
+__version__ = "1.5.13"
diff --git a/shapely/libgeos.py b/shapely/_buildcfg.py
similarity index 81%
rename from shapely/libgeos.py
rename to shapely/_buildcfg.py
index e35a854..d692b9d 100644
--- a/shapely/libgeos.py
+++ b/shapely/_buildcfg.py
@@ -19,9 +19,14 @@ import subprocess
 import sys
 
 
+# Add message handler to this module's logger
 log = logging.getLogger(__name__)
+ch = logging.StreamHandler()
+log.addHandler(ch)
+
 if 'all' in sys.warnoptions:
-    log.level = logging.DEBUG
+    # show GEOS messages in console with: python -W all
+    log.setLevel(logging.DEBUG)
 
 
 # The main point of this module is to load a dynamic library to this variable
@@ -124,23 +129,37 @@ if not lgeos and geos_config:
 
 # Platform-specific attempts, and build `free` object
 
-def load_dll(libname, fallbacks=[]):
-    '''Load GEOS dynamic library'''
+def load_dll(libname, fallbacks=None):
     lib = find_library(libname)
+    dll = None
     if lib is not None:
         try:
-            return CDLL(lib)
-        except OSError:
-            pass
-    for name in fallbacks:
-        try:
-            return CDLL(name)
+            log.debug("Trying `CDLL(%s)`", lib)
+            dll = CDLL(lib)
         except OSError:
-            # move on to the next fallback
+            log.warn("Failed `CDLL(%s)`", lib)
             pass
-    raise OSError(
-        "Could not find library %s or load any of its variants %s" % (
-            libname, fallbacks))
+
+    if not dll and fallbacks is not None:
+        for name in fallbacks:
+            try:
+                log.debug("Trying `CDLL(%s)`", name)
+                dll = CDLL(name)
+            except OSError:
+                # move on to the next fallback
+                log.warn("Failed `CDLL(%s)`", name)
+                pass
+
+    if dll:
+        log.debug("Library path: %r", lib or name)
+        log.debug("DLL: %r", dll)
+        return dll
+    else:
+        # No shared library was loaded. Raise OSError.
+        raise OSError(
+            "Could not find library {0} or load any of its variants {1}".format(
+                libname, fallbacks or []))
+
 
 if sys.platform.startswith('linux'):
     if not lgeos:
@@ -152,24 +171,18 @@ if sys.platform.startswith('linux'):
 
 elif sys.platform == 'darwin':
     if not lgeos:
-        # First test to see if this is a delocated wheel with a GEOS dylib.
-        geos_whl_dylib = os.path.abspath(os.path.join(
-            os.path.dirname(__file__), '.dylibs/libgeos_c.1.dylib'))
-        if os.path.exists(geos_whl_dylib):
-            lgeos = CDLL(geos_whl_dylib)
+        if hasattr(sys, 'frozen'):
+            # .app file from py2app
+            alt_paths = [os.path.join(os.environ['RESOURCEPATH'],
+                         '..', 'Frameworks', 'libgeos_c.dylib')]
         else:
-            if hasattr(sys, 'frozen'):
-                # .app file from py2app
-                alt_paths = [os.path.join(os.environ['RESOURCEPATH'],
-                             '..', 'Frameworks', 'libgeos_c.dylib')]
-            else:
-                alt_paths = [
-                    # The Framework build from Kyng Chaos
-                    "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS",
-                    # macports
-                    '/opt/local/lib/libgeos_c.dylib',
-                ]
-            lgeos = load_dll('geos_c', fallbacks=alt_paths)
+            alt_paths = [
+                # The Framework build from Kyng Chaos
+                "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS",
+                # macports
+                '/opt/local/lib/libgeos_c.dylib',
+            ]
+        lgeos = load_dll('geos_c', fallbacks=alt_paths)
 
     free = load_dll('c', fallbacks=['/usr/lib/libc.dylib']).free
     free.argtypes = [c_void_p]
diff --git a/shapely/geometry/base.py b/shapely/geometry/base.py
index 6498e06..42d821f 100644
--- a/shapely/geometry/base.py
+++ b/shapely/geometry/base.py
@@ -270,7 +270,7 @@ class BaseGeometry(object):
     def __ne__(self, other):
         return not self.__eq__(other)
 
-    __hash__ = object.__hash__
+    __hash__ = None
 
     # Array and ctypes interfaces
     # ---------------------------
@@ -773,7 +773,7 @@ class BaseMultipartGeometry(BaseGeometry):
     def __ne__(self, other):
         return not self.__eq__(other)
 
-    __hash__ = object.__hash__
+    __hash__ = None
 
     def svg(self, scale_factor=1., color=None):
         """Returns a group of SVG elements for the multipart geometry.
diff --git a/shapely/geometry/polygon.py b/shapely/geometry/polygon.py
index 7c7c0cb..945a108 100644
--- a/shapely/geometry/polygon.py
+++ b/shapely/geometry/polygon.py
@@ -264,7 +264,7 @@ class Polygon(BaseGeometry):
     def __ne__(self, other):
         return not self.__eq__(other)
 
-    __hash__ = object.__hash__
+    __hash__ = None
 
     @property
     def ctypes(self):
diff --git a/shapely/geos.py b/shapely/geos.py
index c767d72..976173b 100644
--- a/shapely/geos.py
+++ b/shapely/geos.py
@@ -2,33 +2,178 @@
 Proxies for libgeos, GEOS-specific exceptions, and utilities
 """
 
+import os
 import re
 import sys
 import atexit
 import logging
 import threading
-from ctypes import CDLL, cdll, pointer, string_at, cast, POINTER
+from ctypes import CDLL, cdll, pointer, string_at, cast, POINTER, DEFAULT_MODE
 from ctypes import c_void_p, c_size_t, c_char_p, c_int, c_float
 from ctypes.util import find_library
 
 from .ctypes_declarations import prototype, EXCEPTION_HANDLER_FUNCTYPE
-from .libgeos import lgeos as _lgeos, geos_version
 from . import ftools
 
 
 # Add message handler to this module's logger
 LOG = logging.getLogger(__name__)
+ch = logging.StreamHandler()
+LOG.addHandler(ch)
 
 if 'all' in sys.warnoptions:
     # show GEOS messages in console with: python -W all
-    logging.basicConfig()
-else:
-    # no handler messages shown
-    class NullHandler(logging.Handler):
-        def emit(self, record):
+    LOG.setLevel(logging.DEBUG)
+
+
+# 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, mode=DEFAULT_MODE):
+    lib = find_library(libname)
+    dll = None
+    if lib is not None:
+        try:
+            LOG.debug("Trying `CDLL(%s)`", lib)
+            dll = CDLL(lib, mode=mode)
+        except OSError:
+            LOG.warn("Failed `CDLL(%s)`", lib)
             pass
 
-    LOG.addHandler(NullHandler())
+    if not dll and fallbacks is not None:
+        for name in fallbacks:
+            try:
+                LOG.debug("Trying `CDLL(%s)`", name)
+                dll = CDLL(name, mode=mode)
+            except OSError:
+                # move on to the next fallback
+                LOG.warn("Failed `CDLL(%s)`", name)
+                pass
+
+    if dll:
+        LOG.debug("Library path: %r", lib or name)
+        LOG.debug("DLL: %r", dll)
+        return dll
+    else:
+        # No shared library was loaded. Raise OSError.
+        raise OSError(
+            "Could not find lib {0} or load any of its variants {1}.".format(
+                libname, fallbacks or []))
+
+_lgeos = None
+
+if sys.platform.startswith('linux'):
+    _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':
+    # First: have we already loaded GEOS through a Fiona or Rasterio?
+    # If so, let's obtain a handle to it instead of loading this module's
+    # copy to side step the mysterious issue described at
+    # https://github.com/Toblerity/Shapely/issues/324.
+    geos_mod = sys.modules.get('fiona') or sys.modules.get('rasterio')
+    if geos_mod:
+        dll_path = os.path.join(
+            os.path.dirname(geos_mod.__file__), '.dylibs',
+            'libgeos_c.1.dylib')
+        try:
+            _lgeos = CDLL(dll_path, mode=(DEFAULT_MODE | 16))
+        except OSError:
+            LOG.debug("GEOS DLL in fiona or rasterio .dylibs not found.")
+            alt_paths = [
+                # The Framework build from Kyng Chaos
+                "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS",
+                # macports
+                '/opt/local/lib/libgeos_c.dylib',
+            ]
+            _lgeos = load_dll('geos_c', fallbacks=alt_paths,
+                              mode=(DEFAULT_MODE | 16))
+        if _lgeos:
+            LOG.debug("Found %r already loaded, using it.", _lgeos)
+
+    # If neither fiona nor rasterio have been imported, or if the block
+    # above failed to assign _lgeos, we will locate and load the GEOS
+    # DLL.
+    if not _lgeos:
+        # Test to see if we have a delocated wheel with a GEOS dylib.
+        geos_whl_dylib = os.path.abspath(os.path.join(os.path.dirname(
+            __file__), '.dylibs/libgeos_c.1.dylib'))
+        if os.path.exists(geos_whl_dylib):
+            _lgeos = CDLL(geos_whl_dylib)
+            LOG.debug("Found GEOS DLL: %r, using it.", _lgeos)
+
+        else:
+            if hasattr(sys, 'frozen'):
+                try:
+                    # .app file from py2app
+                    alt_paths = [os.path.join(os.environ['RESOURCEPATH'],
+                                '..', 'Frameworks', 'libgeos_c.dylib')]
+                except KeyError:
+                    # binary from pyinstaller
+                    alt_paths = [
+                        os.path.join(sys.executable, 'libgeos_c.dylib')]
+            else:
+                alt_paths = [
+                    # The Framework build from Kyng Chaos
+                    "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS",
+                    # macports
+                    '/opt/local/lib/libgeos_c.dylib',
+                ]
+            _lgeos = load_dll('geos_c', fallbacks=alt_paths)
+
+    free = load_dll('c').free
+    free.argtypes = [c_void_p]
+    free.restype = None
+
+elif sys.platform == 'win32':
+    try:
+        egg_dlls = os.path.abspath(os.path.join(os.path.dirname(__file__),
+                                   "DLLs"))
+        wininst_dlls = os.path.abspath(os.__file__ + "../../../DLLs")
+        original_path = os.environ['PATH']
+        os.environ['PATH'] = "%s;%s;%s" % \
+            (egg_dlls, wininst_dlls, original_path)
+        _lgeos = CDLL("geos.dll")
+    except (ImportError, WindowsError, OSError):
+        raise
+
+    def free(m):
+        try:
+            cdll.msvcrt.free(m)
+        except WindowsError:
+            # XXX: See http://trac.gispython.org/projects/PCL/ticket/149
+            pass
+
+elif sys.platform == 'sunos5':
+    _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
+    _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
+
+
+def _geos_version():
+    # extern const char GEOS_DLL *GEOSversion();
+    GEOSversion = _lgeos.GEOSversion
+    GEOSversion.restype = c_char_p
+    GEOSversion.argtypes = []
+    #define GEOS_CAPI_VERSION "@VERSION at -CAPI-@CAPI_VERSION@"
+    geos_version_string = GEOSversion()
+    if sys.version_info[0] >= 3:
+        geos_version_string = geos_version_string.decode('ascii')
+    res = re.findall(r'(\d+)\.(\d+)\.(\d+)', geos_version_string)
+    assert len(res) == 2, res
+    geos_version = tuple(int(x) for x in res[0])
+    capi_version = tuple(int(x) for x in res[1])
+    return geos_version_string, geos_version, capi_version
+
+geos_version_string, geos_version, geos_capi_version = _geos_version()
 
 
 # If we have the new interface, then record a baseline so that we know what
diff --git a/tests/__init__.py b/tests/__init__.py
index cf0c6b2..396da18 100755
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,6 +1,6 @@
 import sys
-from shapely.libgeos import geos_version_string
-from shapely.geos import lgeos, WKTWriter
+
+from shapely.geos import geos_version_string, lgeos, WKTWriter
 from shapely import speedups
 
 
diff --git a/tests/test_dlls.py b/tests/test_dlls.py
index 55db556..306e94f 100644
--- a/tests/test_dlls.py
+++ b/tests/test_dlls.py
@@ -1,8 +1,8 @@
-from . import unittest
-
-from shapely.libgeos import load_dll
 import sys
 
+from . import unittest
+from shapely.geos import load_dll
+
 
 class LoadingTestCase(unittest.TestCase):
 
diff --git a/tests/test_hash.py b/tests/test_hash.py
index 97f5919..712974c 100644
--- a/tests/test_hash.py
+++ b/tests/test_hash.py
@@ -3,19 +3,35 @@ from shapely.geometry import Point, MultiPoint, Polygon, GeometryCollection
 
 def test_point():
     g = Point(0, 0)
-    assert hash(g)
+    try:
+        assert hash(g)
+        return False
+    except TypeError:
+        return True
 
 
 def test_multipoint():
     g = MultiPoint([(0, 0)])
-    assert hash(g)
+    try:
+        assert hash(g)
+        return False
+    except TypeError:
+        return True
 
 
 def test_polygon():
     g = Point(0, 0).buffer(1.0)
-    assert hash(g)
+    try:
+        assert hash(g)
+        return False
+    except TypeError:
+        return True
 
 
 def test_collection():
     g = GeometryCollection([Point(0, 0)])
-    assert hash(g)
+    try:
+        assert hash(g)
+        return False
+    except TypeError:
+        return True

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/python-shapely.git



More information about the Pkg-grass-devel mailing list