From e9b00cc78853373623031c657193cbe557488c0a Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 24 Sep 2024 03:52:45 +0200 Subject: [PATCH] [3.13] gh-121607: Edited source file import recipe to make it more clear (GH-121519) (#124080) gh-121607: Edited source file import recipe to make it more clear (GH-121519) (cherry picked from commit 38809171b8768517824fb62d48abe2cb0aff8429) Co-authored-by: Chris Barker Co-authored-by: Brett Cannon Co-authored-by: Peter Bierma --- Doc/library/importlib.rst | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index e408a8489f8eac..d63821c5267ef9 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1584,20 +1584,34 @@ Note that if ``name`` is a submodule (contains a dot), Importing a source file directly '''''''''''''''''''''''''''''''' -To import a Python source file directly, use the following recipe:: +This recipe should be used with caution: it is an approximation of an import +statement where the file path is specified directly, rather than +:data:`sys.path` being searched. Alternatives should first be considered first, +such as modifying :data:`sys.path` when a proper module is required, or using +:func:`runpy.run_path` when the global namespace resulting from running a Python +file is appropriate. - import importlib.util - import sys +To import a Python source file directly from a path, use the following recipe:: + + import importlib.util + import sys - # For illustrative purposes. - import tokenize - file_path = tokenize.__file__ - module_name = tokenize.__name__ - spec = importlib.util.spec_from_file_location(module_name, file_path) - module = importlib.util.module_from_spec(spec) - sys.modules[module_name] = module - spec.loader.exec_module(module) + def import_from_path(module_name, file_path): + spec = importlib.util.spec_from_file_location(module_name, file_path) + module = importlib.util.module_from_spec(spec) + sys.modules[module_name] = module + spec.loader.exec_module(module) + return module + + + # For illustrative purposes only (use of `json` is arbitrary). + import json + file_path = json.__file__ + module_name = json.__name__ + + # Similar outcome as `import json`. + json = import_from_path(module_name, file_path) Implementing lazy imports @@ -1623,7 +1637,6 @@ The example below shows how to implement lazy imports:: False - Setting up an importer ''''''''''''''''''''''