@@ -510,21 +510,28 @@ def normalize_table_name(name: str) -> str:
510510 return re .sub (r'\W+' , '_' , name ).strip ('_' ).lower ()
511511
512512
513- def try_import_xarray ():
514- """Import and return xarray, or None if xarray or xarray-sql is unavailable."""
513+ def try_import (module_name , load = True ):
514+ """Import and return a module, or None if it is unavailable.
515+
516+ With load=False the module is returned only if it has already been
517+ imported, a cheap check that never triggers an import; this lets a hot path
518+ ask whether an optional dependency is in play without paying to import it.
519+ With load=True (the default) the module is imported on demand.
520+ """
521+ if not load :
522+ return sys .modules .get (module_name )
515523 try :
516- import xarray
517- import xarray_sql # noqa
518- return xarray
524+ return importlib .import_module (module_name )
519525 except ImportError :
520526 return None
521527
522528
523- def try_import_geopandas ():
524- """Import and return geopandas , or None if it is not installed ."""
529+ def try_import_xarray ():
530+ """Import and return xarray , or None if xarray or xarray-sql is unavailable ."""
525531 try :
526- import geopandas
527- return geopandas
532+ import xarray
533+ import xarray_sql # noqa
534+ return xarray
528535 except ImportError :
529536 return None
530537
@@ -536,7 +543,7 @@ def is_geodataframe(df):
536543 a GeoDataFrame unless geopandas is loaded, so this stays cheap on the hot
537544 path and never speculatively imports geopandas.
538545 """
539- gpd = sys . modules . get ("geopandas" )
546+ gpd = try_import ("geopandas" , load = False )
540547 return gpd is not None and isinstance (df , gpd .GeoDataFrame )
541548
542549
@@ -546,7 +553,7 @@ def geometry_columns(df):
546553 Empty when geopandas is not imported (no geometry column can exist without
547554 it) or df has no geometry columns; never speculatively imports geopandas.
548555 """
549- gpd = sys . modules . get ("geopandas" )
556+ gpd = try_import ("geopandas" , load = False )
550557 if gpd is None :
551558 return []
552559 return [c for c in df .columns if isinstance (df [c ].dtype , gpd .array .GeometryDtype )]
@@ -563,7 +570,7 @@ def geometry_to_wkt(df):
563570 geom_cols = geometry_columns (df )
564571 if not geom_cols :
565572 return df
566- gpd = sys . modules [ "geopandas" ]
573+ gpd = try_import ( "geopandas" , load = False )
567574 df = pd .DataFrame (df ).copy ()
568575 for col in geom_cols :
569576 df [col ] = gpd .GeoSeries (df [col ]).to_wkt ()
0 commit comments