at 22.05-pre 6.9 kB view raw
1diff --git a/shapely/geos.py b/shapely/geos.py 2index 4619732..1abdb5e 100644 3--- a/shapely/geos.py 4+++ b/shapely/geos.py 5@@ -55,148 +55,21 @@ def load_dll(libname, fallbacks=None, mode=DEFAULT_MODE): 6 "Could not find lib {} or load any of its variants {}.".format( 7 libname, fallbacks or [])) 8 9-_lgeos = None 10 def exists_conda_env(): 11 """Does this module exist in a conda environment?""" 12 return os.path.exists(os.path.join(sys.prefix, 'conda-meta')) 13 14- 15-if sys.platform.startswith('linux'): 16- # Test to see if we have a wheel repaired by auditwheel which contains its 17- # own libgeos_c. Note: auditwheel 3.1 changed the location of libs. 18- geos_whl_so = glob.glob( 19- os.path.abspath(os.path.join(os.path.dirname(__file__), ".libs/libgeos*.so*")) 20- ) or glob.glob( 21- os.path.abspath( 22- os.path.join( 23- os.path.dirname(__file__), "..", "Shapely.libs", "libgeos*.so*" 24- ) 25- ) 26- ) 27- 28- if len(geos_whl_so) > 0: 29- # We have observed problems with CDLL of libgeos_c not automatically 30- # loading the sibling c++ library since the change made by auditwheel 31- # 3.1, so we explicitly load them both. 32- geos_whl_so = sorted(geos_whl_so) 33- CDLL(geos_whl_so[0]) 34- _lgeos = CDLL(geos_whl_so[-1]) 35- LOG.debug("Found GEOS DLL: %r, using it.", _lgeos) 36- 37- elif hasattr(sys, 'frozen'): 38- geos_pyinstaller_so = glob.glob(os.path.join(sys.prefix, 'libgeos_c-*.so.*')) 39- if len(geos_pyinstaller_so) >= 1: 40- _lgeos = CDLL(geos_pyinstaller_so[0]) 41- LOG.debug("Found GEOS DLL: %r, using it.", _lgeos) 42- elif exists_conda_env(): 43- # conda package. 44- _lgeos = CDLL(os.path.join(sys.prefix, 'lib', 'libgeos_c.so')) 45- else: 46- alt_paths = [ 47- 'libgeos_c.so.1', 48- 'libgeos_c.so', 49- ] 50- _lgeos = load_dll('geos_c', fallbacks=alt_paths) 51- 52+_lgeos = CDLL('@libgeos_c@') 53+if sys.platform == 'darwin': 54 # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen 55 # manpage says, "If filename is NULL, then the returned handle is for the 56 # main program". This way we can let the linker do the work to figure out 57 # which libc Python is actually using. 58 free = CDLL(None).free 59- free.argtypes = [c_void_p] 60- free.restype = None 61- 62-elif sys.platform == 'darwin': 63- # Test to see if we have a delocated wheel with a GEOS dylib. 64- geos_whl_dylib = os.path.abspath(os.path.join(os.path.dirname( 65- __file__), '.dylibs/libgeos_c.1.dylib')) 66- 67- if os.path.exists(geos_whl_dylib): 68- handle = CDLL(None) 69- if hasattr(handle, "initGEOS_r"): 70- LOG.debug("GEOS already loaded") 71- _lgeos = handle 72- else: 73- _lgeos = CDLL(geos_whl_dylib) 74- LOG.debug("Found GEOS DLL: %r, using it.", _lgeos) 75- 76- elif exists_conda_env(): 77- # conda package. 78- _lgeos = CDLL(os.path.join(sys.prefix, 'lib', 'libgeos_c.dylib')) 79- else: 80- if hasattr(sys, 'frozen'): 81- try: 82- # .app file from py2app 83- alt_paths = [os.path.join( 84- os.environ['RESOURCEPATH'], '..', 'Frameworks', 85- 'libgeos_c.dylib')] 86- except KeyError: 87- alt_paths = [ 88- # binary from pyinstaller 89- os.path.join(sys.executable, 'libgeos_c.dylib'), 90- # .app from cx_Freeze 91- os.path.join(os.path.dirname(sys.executable), 'libgeos_c.1.dylib')] 92- if hasattr(sys, '_MEIPASS'): 93- alt_paths.append( 94- os.path.join(sys._MEIPASS, 'libgeos_c.1.dylib')) 95- else: 96- alt_paths = [ 97- # The Framework build from Kyng Chaos 98- "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS", 99- # macports 100- '/opt/local/lib/libgeos_c.dylib', 101- # homebrew Intel 102- '/usr/local/lib/libgeos_c.dylib', 103- # homebrew Apple Silicon 104- '/opt/homebrew/lib/libgeos_c.dylib', 105- ] 106- _lgeos = load_dll('geos_c', fallbacks=alt_paths) 107- 108- free = CDLL(None).free 109- free.argtypes = [c_void_p] 110- free.restype = None 111- 112-elif sys.platform == 'win32': 113- _conda_dll_path = os.path.join(sys.prefix, 'Library', 'bin', 'geos_c.dll') 114- if exists_conda_env() and os.path.exists(_conda_dll_path): 115- # conda package. 116- _lgeos = CDLL(_conda_dll_path) 117- else: 118- try: 119- egg_dlls = os.path.abspath( 120- os.path.join(os.path.dirname(__file__), 'DLLs')) 121- if hasattr(sys, '_MEIPASS'): 122- wininst_dlls = sys._MEIPASS 123- elif hasattr(sys, "frozen"): 124- wininst_dlls = os.path.normpath( 125- os.path.abspath(sys.executable + '../../DLLS')) 126- else: 127- wininst_dlls = os.path.abspath(os.__file__ + "../../../DLLs") 128- original_path = os.environ['PATH'] 129- os.environ['PATH'] = "%s;%s;%s" % \ 130- (egg_dlls, wininst_dlls, original_path) 131- _lgeos = load_dll("geos_c.dll") 132- except (ImportError, WindowsError, OSError): 133- raise 134- 135- def free(m): 136- try: 137- cdll.msvcrt.free(m) 138- except WindowsError: 139- # XXX: See http://trac.gispython.org/projects/PCL/ticket/149 140- pass 141- 142-elif sys.platform == 'sunos5': 143- _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so']) 144- free.restype = None 145- free.argtypes = [c_void_p] 146- free.restype = None 147- 148-else: # other *nix systems 149- _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so']) 150- free = CDLL(None).free 151- free.argtypes = [c_void_p] 152- free.restype = None 153+else: 154+ free = CDLL('@libc@').free 155+free.argtypes = [c_void_p] 156+free.restype = None 157 158 159 def _geos_version(): 160diff --git a/tests/test_dlls.py b/tests/test_dlls.py 161index c71da8e..fae9da6 100644 162--- a/tests/test_dlls.py 163+++ b/tests/test_dlls.py 164@@ -12,10 +12,4 @@ class LoadingTestCase(unittest.TestCase): 165 @unittest.skipIf(sys.platform == "win32", "FIXME: adapt test for win32") 166 def test_fallbacks(self): 167 load_dll('geos_c', fallbacks=[ 168- os.path.join(sys.prefix, "lib", "libgeos_c.dylib"), # anaconda (Mac OS X) 169- '/opt/local/lib/libgeos_c.dylib', # MacPorts 170- '/usr/local/lib/libgeos_c.dylib', # homebrew (Mac OS X) 171- '/opt/homebrew/lib/libgeos_c.dylib', # homebrew (macOS) 172- os.path.join(sys.prefix, "lib", "libgeos_c.so"), # anaconda (Linux) 173- 'libgeos_c.so.1', 174- 'libgeos_c.so']) 175+ '@libgeos_c@'])