GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Improve the docs regarding the migration from imp to importlib · Issue #104212 · python/cpython

Improve the docs regarding the migration from imp to importlib  #104212

New issue
Copy link
New issue
Copy link
Closed
Closed
Improve the docs regarding the migration from imp to importlib #104212
Copy link
Labels
3.11only security fixesonly security fixes3.12only security fixesonly security fixesdocsDocumentation in the Doc dirDocumentation in the Doc dir

Description

@alexprengere
alexprengere
opened on May 5, 2023
Issue body actions

Now that the imp removal has landed on main, users migrating to Python3.12 will likely need help to move to importlib.
The current imp docs have tips on how to do just that. Great!

One caveat: the imp.load_source has been removed from the docs a long time ago, now it is only visible is the Python2 version of the docs. So users of imp.load_source cannot rely on the docs to help them migrate, and have to Google this. The first results on stackoverflow are a bit wrong:

  • many point to SourceFileLoader(...).load_module(), but this is also deprecated and slated for removal in 3.12 (according to the warning)
  • some solutions point to importlib.util.spec_from_file_location, but this does not work with files that do not end with ".py"

The solution that I think is the best translation:

def imp_load_source(module_name, module_path):
    loader = SourceFileLoader(module_name, module_path)
    module = types.ModuleType(loader.name)
    loader.exec_module(module)
    return module

I think it would be beneficial to have that kind of information in the docs. Unfortunately, imp.load_source is not officially documented, but there are several GitHub issues and SO threads discussing how to migrate code to importlib. IMO, we should do one of:

  • add it back to the docs, with explanations on how to migrate it to importlib
  • just document the migration in the release notes, in the section "Porting to Python 3.12"

What do you think?

Linked PRs

  • gh-104212: Add importlib.util.load_source_path() function #105755
  • gh-104212: Explain how to port imp code to importlib #105905
  • gh-104212: Explain how to port imp.load_source() #105951
  • [3.12] gh-104212: Explain how to port imp code to importlib (GH-105905) #105952
  • gh-104212: Explain how to port imp.load_source() #105978
  • [3.12] gh-104212: Explain how to port imp.load_source() (GH-105978) #106083
Reacted by Michael R. Crusoe

Activity

Next
  1. alexprengere
    added
    docsDocumentation in the Doc dirDocumentation in the Doc dir
    on May 5, 2023
  2. warsaw commented on May 5, 2023

    @warsaw
    warsaw
    on May 5, 2023
    Member
    More actions

    Maybe we need a porting guide in the importlib docs for porting older imp and other APIs to importlib? I don't like that imp module has been deleted but the docs are still there.

    Reacted by Hugo van Kemenade
  3. hugovk commented on May 5, 2023

    @hugovk
    hugovk
    on May 5, 2023
    Member
    More actions

    Good idea!

    In fact we were just discussing this earlier today and thought about putting a migration guide in both the imp and importlib docs and in the 3.12 porting guide.

    cc @vstinner

  4. hugovk
    added
    3.11only security fixesonly security fixes
    3.12only security fixesonly security fixes
    on May 5, 2023
  5. terryjreedy commented on May 5, 2023

    @terryjreedy
    terryjreedy
    on May 5, 2023
    Member
    More actions

    In current 3.12, 'imp' is no longer present in the module index, which suggests that it is gone.

  6. vstinner commented on May 5, 2023

    @vstinner
    vstinner
    on May 5, 2023
    Member
    More actions

    I don't know the importlib design, so maybe it doesn't make sense, but... Would it make sense to add a imp_load_source() function to importlib? Maybe under a different name.

  7. vstinner commented on May 5, 2023

    @vstinner
    vstinner
    on May 5, 2023
    Member
    More actions

    My own use case of load_module(): old code written first for Python 2 using imp then ported to SourceLoader. It's a short script which looks for "test_xxx.py" files and then run them. Stupid but simple pytest-like, good enough for my needs: https://github.com/vstinner/hachoir/blob/0a030e3c8045441a0c30a04475a94f3aadd818ed/runtests.py#L72

    I was already annoyed to have to port to them a first date to get rid of imp. So the code should be updated again?

  8. CAM-Gerlach commented on May 6, 2023

    @CAM-Gerlach
    CAM-Gerlach
    on May 6, 2023
    Member
    More actions

    Would it make sense to add a imp_load_source() function to importlib?

    Just to note, see, e.g., #58756 for some previous discussion of this.

  9. vstinner
    added a commit that references this issue on May 24, 2023

    Port runtests.py to Python 3.12

    c4610a5
  10. vstinner commented on May 24, 2023

    @vstinner
    vstinner
    on May 24, 2023
    Member
    More actions

    The recipe didn't work for me:

    • (1) The module has no __file__ variable
    • (2) The module was no registered in sys.modules

    imp.load_source() defines __file__ and adds the module to sys.modules.

    I used this recipe instead:

    def load_module(module_name, filename):
        loader = importlib.machinery.SourceFileLoader(module_name, filename)
        module = types.ModuleType(loader.name)
        module.__file__ = filename
        sys.modules[module.__name__] = module
        loader.exec_module(module)
        return module
    Reacted by Alex Prengère, romainsc and mroelandts
  11. vstinner commented on Jun 13, 2023

    @vstinner
    vstinner
    on Jun 13, 2023
    Member
    More actions

    Minor step forward: I documented how to replace removed imp.new_module(): 457a459

  12. vstinner
    added a commit that references this issue on Jun 13, 2023

    pythongh-104212: Add importlib.util.load_source() function

    c3a44b9
  13. brettcannon commented on Jun 16, 2023

    @brettcannon
    brettcannon
    on Jun 16, 2023
    Member
    More actions
    • some solutions point to importlib.util.spec_from_file_location, but this does not work with files that do not end with ".py"

    That's actually only true if you don't pass in the loader you need to use as the code has to guess as what you're after. You can use either importlib.util.spec_from_loader() or importlib.util.spec_from_file_location(), they just need different specifics to do the right thing.

    Reacted by Alex Prengère
  14. vstinner
    added a commit that references this issue on Jun 16, 2023

    pythongh-104212: Add importlib.util.load_source_path() function

    d426783
  15. 20 remaining items

  16. brettcannon commented on Jun 23, 2023

    @brettcannon
    brettcannon
    on Jun 23, 2023
    Member
    More actions

    I'm not sure neither how find_module() was used with load_module() to load modules. Is the use case to specify a search path which is not in sys.path?

    I think so.

    Why not putting the path in sys.path and simply use importlib.import_module()?

    Worried they would forget to clean up sys.path after importing the one file they wanted?

  17. miss-islington
    added a commit that references this issue on Jun 25, 2023

    pythongh-104212: Explain how to port imp.load_source() (pythonGH-105978)

    5db404b
  18. vstinner
    added a commit that references this issue on Jun 25, 2023

    [3.12] gh-104212: Explain how to port imp.load_source() (GH-105978) (#…

    e9366df
  19. vstinner commented on Jun 25, 2023

    @vstinner
    vstinner
    on Jun 25, 2023
    Member
    More actions

    add it back to the docs, with explanations on how to migrate it to importlib
    just document the migration in the release notes, in the section "Porting to Python 3.12"

    That's now done in What's New in Python 3.12, but under the "Removed" section, where removals are mentioned. I dislike documenting the same removal at two places.

    https://docs.python.org/dev/whatsnew/3.12.html#removed

    I just wrote a 3.12 backport for my second doc change: PR #106083. It'ss going to be merged soon.

    I added a recipe to replace imp.load_source(). I consider that this documentation issue is now solved and I close the issue.

    If someone wants a more complete explanation for a specific removed imp function, please open a new issue.

    Thanks @alexprengere for the bug report, thanks @brettcannon and @arhadthedev for the reviews.

  20. vstinner
    closed this as completedon Jun 25, 2023
  21. melissalinkert
    added a commit that references this issue on Mar 6, 2024

    Try to replace imp with importlib for Python 3.12 compatibility

    7f99b6a
  22. Ansuel
    added 7 commits that reference this issue on Apr 28, 2024

    ndiff: Fix support for Python 3.12

    e87be0b

    ndiff: Fix support for Python 3.12

    1c2e595

    ndiff: Fix support for Python 3.12

    3475e35

    ndiff: Fix support for Python 3.12

    16b8686

    Convert ndifftest to importlib for Python 3.12 support

    9d36db7

    ndiff: convert ndifftest to importlib for Python 3.12 support

    62e981f

    ndiff: convert ndifftest to importlib for Python 3.12 support

    1d8c0e1
  23. Hoeze commented on Jan 30, 2026

    @Hoeze
    Hoeze
    on Jan 30, 2026
    More actions

    The docs now state to replace imp.load_source() with this:

            import importlib.util
            import importlib.machinery
    
            def load_source(modname, filename):
                loader = importlib.machinery.SourceFileLoader(modname, filename)
                spec = importlib.util.spec_from_file_location(modname, filename, loader=loader)
                module = importlib.util.module_from_spec(spec)
                # The module is always executed and not cached in sys.modules.
                # Uncomment the following line to cache the module.
                # sys.modules[module.__name__] = module
                loader.exec_module(module)
                return module

    Is there a reason why this function was not directly put into importlib.util?

  24. brettcannon commented on Feb 2, 2026

    @brettcannon
    brettcannon
    on Feb 2, 2026
    Member
    More actions

    Is there a reason why this function was not directly put into importlib.util?

    1. There is a lot of variance people want for similar functionality as the code comment hints at.
    2. It avoids the import system while stuff in importlib.util is meant to help use it in some advanced ways.
    3. Not everything needs to be in the stdlib.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.11only security fixesonly security fixes3.12only security fixesonly security fixesdocsDocumentation in the Doc dirDocumentation in the Doc dir

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.