@@ -67,19 +67,31 @@ def bootstrap_env():
6767# In some build/test setups the compiled extension can be imported under the
6868# top-level name `_mapnik` (e.g. due to sys.path/build output layout) and then
6969# again as `mapnik._mapnik`. Loading the same pybind11 extension twice in one
70- # interpreter can raise errors like:
71- # pybind11::native_enum<...>("CompositeOp") is already registered!
72- # If a compatible `_mapnik` is already loaded , alias it to the canonical
73- # `mapnik._mapnik` name before importing symbols .
70+ # interpreter can raise "already registered" errors for pybind11 types/enums.
71+ #
72+ # To avoid a second load, if `_mapnik` is already present , alias it to the
73+ # canonical `mapnik._mapnik` name before importing.
7474_canonical_ext_name = f"{ __name__ } ._mapnik"
75- if _canonical_ext_name in sys .modules :
76- pass
77- elif "_mapnik" in sys .modules :
78- _candidate = sys .modules ["_mapnik" ]
79- # Heuristic guard: only alias if it looks like our Mapnik extension.
80- if hasattr (_candidate , "Map" ) and hasattr (_candidate , "version_string" ):
81- sys .modules [_canonical_ext_name ] = _candidate
82-
75+ if _canonical_ext_name not in sys .modules and "_mapnik" in sys .modules :
76+ # If a top-level `_mapnik` was imported first, alias it to the canonical
77+ # `mapnik._mapnik` name so Python reuses the same extension module object
78+ # rather than attempting a second load.
79+ sys .modules [_canonical_ext_name ] = sys .modules ["_mapnik" ]
80+
81+ _prev_err = getattr (sys , "_python_mapnik_ext_import_error" , None )
82+ if _prev_err is not None :
83+ # Avoid repeated attempts to load the extension in the same interpreter
84+ # after a failure (which can lead to confusing secondary errors like
85+ # "already registered" from pybind11).
86+ raise ImportError (str (_prev_err )) from None
87+
88+ try :
89+ from . import _mapnik as _ext
90+ except ImportError as e :
91+ setattr (sys , "_python_mapnik_ext_import_error" , e )
92+ raise
93+ # Ensure subsequent `import _mapnik` reuses the already-loaded extension.
94+ sys .modules .setdefault ("_mapnik" , _ext )
8395from ._mapnik import *
8496
8597def Shapefile (** keywords ):
0 commit comments