shapely / shapely/shapely

pyinstaller-frozen app including shapely on Mac fails to find libgeos dylib in conda environment

Open
#1,301 2 comments 0 reactions 1 assignee View on GitHub

@sgillies is already working on this.

Since May 3, 2022.

bug
Dominant language
Python
Stars
4.5k
Forks
631
Avg merge
1d 11h
Merged PRs (30d)
10

Description

On Mac, when using pyinstaller to freeze an app which uses shapely, the frozen app fails to run when the user is in an Anaconda/miniconda environment. The problem (at least in 1.7.1 and 1.8.0) is in shapely/geos.py:

    # 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):
        handle = CDLL(None)
        if hasattr(handle, "initGEOS_r"):
            LOG.debug("GEOS already loaded")
            _lgeos = handle
        else:
            _lgeos = CDLL(geos_whl_dylib)
            LOG.debug("Found GEOS DLL: %r, using it.", _lgeos)

    elif os.getenv('CONDA_PREFIX', ''):
        # conda package.
        _lgeos = CDLL(os.path.join(sys.prefix, 'lib', 'libgeos_c.dylib'))
    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')]
                if hasattr(sys, '_MEIPASS'):
                    alt_paths.append(
                        os.path.join(sys._MEIPASS, 'libgeos_c.1.dylib'))
        else:
            alt_paths = [
                # The Framework build from Kyng Chaos
                "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS",
                # macports
                '/opt/local/lib/libgeos_c.dylib',
                # homebrew
                '/usr/local/lib/libgeos_c.dylib',
            ]
        _lgeos = load_dll('geos_c', fallbacks=alt_paths)

The presence of a conda environment is checked before the probe for the frozen environment; I'm pretty sure it should be the other way around.

Expected behavior and actual behavior.

Expected behavior is that the app should run without incident. Actual behavior is the following error:

Traceback (most recent call last):
  File "PyInstaller/loader/pyimod04_ctypes.py", line 53, in __init__
  File "ctypes/__init__.py", line 364, in __init__
OSError: dlopen(/Users/sam/Desktop/mainV3.app/Contents/MacOS/lib/libgeos_c.dylib, 6): image not found

Steps to reproduce the problem.

  • create an app using pyinstaller which uses shapely and imports shapely.geos.
  • activate a conda environment (base environment is fine)
  • run the frozen app

Operating system

MacOS 11.6.3.

Shapely version and provenance

Version 1.7.1, installed from pypi. However, I've confirmed visually that the same incorrect checking order is present in the 1.8.0 source code.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.