@@ -300,16 +300,36 @@ def PixelArray(surface): # pylint: disable=unused-argument
300300except (ImportError , OSError ):
301301 scrap = MissingModule ("scrap" , urgent = 0 )
302302
303- try :
304- import pygame .surfarray
305- except (ImportError , OSError ):
306- surfarray = MissingModule ("surfarray" , urgent = 0 )
303+ # Two lazily imported modules to avoid loading numpy unnecessarily
307304
308- try :
309- import pygame .sndarray
310- except (ImportError , OSError ):
305+ from importlib .util import LazyLoader , find_spec , module_from_spec
306+
307+
308+ def lazy_import (name ):
309+ """See https://docs.python.org/3/library/importlib.html#implementing-lazy-imports
310+
311+ Only load modules upon their first attribute access.
312+ Lazily imported modules are directly referenced in packager_imports function.
313+ """
314+ spec = find_spec ("pygame." + name )
315+ loader = LazyLoader (spec .loader )
316+ spec .loader = loader
317+ module = module_from_spec (spec )
318+ sys .modules [spec .name ] = module
319+ loader .exec_module (module )
320+ return module
321+
322+
323+ if find_spec ("numpy" ) is not None :
324+ surfarray = lazy_import ("surfarray" )
325+ sndarray = lazy_import ("sndarray" )
326+ else :
327+ # Preserve MissingModule behavior when numpy is not installed
328+ surfarray = MissingModule ("surfarray" , urgent = 0 )
311329 sndarray = MissingModule ("sndarray" , urgent = 0 )
312330
331+ del LazyLoader , find_spec , lazy_import , module_from_spec
332+
313333try :
314334 import pygame ._debug
315335 from pygame ._debug import print_debug_info
@@ -366,6 +386,10 @@ def packager_imports():
366386 import pygame .macosx
367387 import pygame .colordict
368388
389+ # lazy imports
390+ import pygame .surfarray
391+ import pygame .sndarray
392+
369393
370394# make Rects pickleable
371395
0 commit comments