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 — Readline completion of module names in import statements · Issue #69605 · python/cpython

Readline completion of module names in import statements #69605

New issue
Copy link
New issue
Copy link
Closed
Closed
Readline completion of module names in import statements#69605
Copy link
Labels
stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-replRelated to the interactive shellRelated to the interactive shelltype-featureA feature request or enhancementA feature request or enhancement

Description

@vadmium
vadmium
opened on Oct 16, 2015
Issue body actions
BPO 25419
Nosy @vadmium, @serhiy-storchaka, @MojoVampire
Dependencies
  • bpo-16182: readline: Wrong tab completion scope indices in Unicode terminals
  • Files
  • complete-import.patch
  • complete-import.v2.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2015-10-16.11:16:48.120>
    labels = ['type-feature', 'library']
    title = 'Readline completion of module names in import statements'
    updated_at = <Date 2016-05-25.08:03:01.876>
    user = 'https://github.com/vadmium'

    bugs.python.org fields:

    activity = <Date 2016-05-25.08:03:01.876>
    actor = 'martin.panter'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2015-10-16.11:16:48.120>
    creator = 'martin.panter'
    dependencies = ['16182']
    files = ['40794', '42986']
    hgrepos = []
    issue_num = 25419
    keywords = ['patch']
    message_count = 6.0
    messages = ['253072', '253095', '253104', '253115', '253132', '266320']
    nosy_count = 3.0
    nosy_names = ['martin.panter', 'serhiy.storchaka', 'josh.r']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue25419'
    versions = ['Python 3.6']

    Linked PRs

    • gh-69605: Add module autocomplete to PyREPL #129329
    • gh-69605: Add PyREPL import autocomplete feature to 'What's New' #133358
    • gh-69605: Disable PyREPL module autocomplete fallback on regular completion #134181
    • [3.14] gh-69605: Disable PyREPL module autocomplete fallback on regular completion (gh-134181) #134680
    • gh-69605: Hardcode some stdlib submodules in PyREPL module completion (os.path, collections.abc...) #138268
    • [3.14] gh-69605: Hardcode some stdlib submodules in PyREPL module completion (os.path, collections.abc...) (GH-138268) #138943
    • gh-69605: Check for already imported modules in PyREPL module completion #139461
    • gh-69605: In test_pyrepl.test_already_imported*, invalidate FS import caches #143436
    • [3.14] gh-69605: Check for already imported modules in PyREPL module completion #143438
    • gh-69605: Add math.integer to PyREPL module completer hardcoded list #144811
    • gh-69605: PyREPL: insert "import" after "from foo <tab>" #148445
    • gh-69605: fix PyREPL completions inserted for import statements with spaces #148629
    • [3.15] gh-69605: fix PyREPL completions inserted for import statements with spaces (GH-148629) #159989
    Reacted by Chih-Hsuan Yen

    Activity

    Next
    1. vadmium commented on Oct 16, 2015

      @vadmium
      vadmium
      on Oct 16, 2015
      MemberAuthor
      More actions

      As mentioned in bpo-25209, here is a patch to complete module and attribute names in import statements. This is a rewrite of some personal code I have had kicking around for a few years, but I have added extra features (parsing “import x as alias”, supporting “from .relative import x”).

      All the existing completions should continue to work as long as the statement immediately preceding the cursor does not look like an “import” statement. When an import statement is detected, these other completions are disabled.

      When alternative completions are displayed, my code appends a dot (.) indicator to package names, but this is not inserted in the input line. Maybe people think this is a good idea or maybe not.

      This illustrates what it looks like in action. Text in square brackets was automatically completed:

      Python 3.6.0a0 (qbase qtip readline/complete-import.patch tip:65d2b721034a, Oct 16 2015, 10:02:3) 
      [GCC 5.1.0] on linux
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import io, h<Tab><Tab>
      hashlib  heapq    hmac     html.    http.    
      >>> import io, htm[l].<Tab><Tab>
      html.entities  html.parser    
      >>> import io, html.e[ntities]
      >>> from html import e<Tab><Tab>
      entities  escape    
      >>> from html import es[cape]

      The code works around bpo-16182 (byte vs code point indexing) in a very simplistic way. It probably won’t give useful completions (if any) for non-ASCII input involving imports.

      The patch currently does not complete built-in module names (sys.builtin_module_names). This should not be hard to add, but I need to decide whether the support should be added specially in rlcompleter, or generally in pkgutil.iter_modules() instead.

      I also have code to complete the following, which I could try to make patches for if there is interest:

      • keyword argument names to function calls, e.g. open("file", enc[oding=]
      • attributes on constructor return types, e.g. ValueError("msg").__t[raceback__]
    2. vadmium
      added
      stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
      type-featureA feature request or enhancementA feature request or enhancement
      on Oct 16, 2015
    3. serhiy-storchaka commented on Oct 16, 2015

      @serhiy-storchaka
      serhiy-storchaka
      on Oct 16, 2015
      Member
      More actions

      I'm reviewing the patch, but it will take a time.

      Wouldn't be simpler to use regular expressions instead of tokenizer?

      For now Completer doesn't depends on the readline module, nor other global state. It can be used for completing in other environment, for example to complete words in IDE. Patched Completer retrieves additional information from the readline module. This can break existing code. It would be nice to decouple Completer from readline. In contrary to user .pythonrc.py file, we are free to invent new interfaces. May be add methods to the Completer class that provides needed additional information (nothing by default), and add Completer's subclass ReadlineCompleter that implements these methods using readline?

      Found presumable bugs:

      "import sy" doesn't suggest completion "sys".

      "import os.p" doesn't suggest completion "os.path".

    4. MojoVampire commented on Oct 16, 2015

      @MojoVampire
      MojoVampiremannequin
      on Oct 16, 2015
      Mannequin
      More actions

      Is there a reason ipython's import completer couldn't be borrowed in its entirety? At work, I use a lightly adapted version of the code from ipython to do completion when I'm using the plain interactive interpreter (for whatever reason), and it works just fine.

    5. vadmium commented on Oct 17, 2015

      @vadmium
      vadmium
      on Oct 17, 2015
      MemberAuthor
      More actions

      Josh: Thanks for pointing out I Python. I haven’t used it much myself, but it does seem to do a similar thing to my proposal. Looks like the relevant code may be around module_completion() at <https://github.com/ipython/ipython/blob/ab929fe/IPython/core/completerlib.py#L209\>.

      The “sys” module is one of the builtin modules that I mentioned above. I plan to discuss changing pkgutil.iter_modules() to include it, in a separate bug report.

      The “os.path” case is more awkward. The “os” module is not actually a package. I believe “import os.path” only works because executing the “os” module modifies sys.modules. My code currently avoids importing non-packages, because I thought it would be annoying to accidentally run a script via tab completion (anything not protected by ‘if __name__ == "__main__" ’). On the other hand, I Python happily completes “os.path” (and many more non-submodule names). It also can be tricked into running scripts, e.g. if you do “import idlelib.__main__.” and press Tab. But maybe this is not a real problem, and I should stop being paranoid.

      I tend to avoid regular expressions if practical. But Serhiy you may be right that some simple string matching rules would reduce the need for tokenizing. It looks like I Python only has a few simple rules for the entire input line being “import x” and “from x import y”. The disadvantage is less accurate understanding of more complicated syntax, like “from x import y; from z import (a, bb as b, . . .”. It is a tradeoff between simpler code that only supports basic functionality versus complex code that supports more complete functionality.

      I hear your points about decoupling from Readline and backwards compatibility. I will consider the overall architecture more in a future update. It would be good to allow this stuff to be used in e.g. Idle (though I wouldn’t know where to wire it in myself).

    6. serhiy-storchaka commented on Oct 17, 2015

      @serhiy-storchaka
      serhiy-storchaka
      on Oct 17, 2015
      Member
      More actions

      Added few cursory comments on Rietveld.

      "sys" and "os.path" cases are not critical and we can ignore them if it complicates the code. But preserving Completer independence from readline looks more important to me. We can just add methods get_line_buffer(), get_begidx(), get_endidx() and get_completion_type() to Completer, but may be better to add more high level methods.

    7. vadmium commented on May 25, 2016

      @vadmium
      vadmium
      on May 25, 2016
      MemberAuthor
      More actions

      I moved all the calls targetting the readline module into a ReadlineCompleter subclass. However the logic for parsing “import” statements still exists in the base Completer class in private methods. An overview of the two classes:

      class Completer:
          def complete(self, text, state):
              self._get_matches(text)
          def _get_matches(text):
              # Only completes global and object.attr names, like before
          def _code_matches(self, code, ...):
              # Completes import statements, otherwise returns (None, ...)
      
      class ReadlineCompleter(Completer):  # New public class
          def complete(self, text, state):
              # Moved Yury’s Tab insertion logic here
              return super().complete(...)
          def _get_matches(text):
              code = readline.get_line_buffer()[:readline.get_endidx()]
              self._code_matches(code)
              super()._get_matches(text)  # Fallback to existing behaviour

      Perhaps the _code_matches() and related methods could be turned into more general public APIs, e.g. complete_code(code) -> list of modules, attributes, globals, etc. But that would affect global_matches() and attr_matches(), which I have not touched so far.

      Other changes:

      • Limit underscore-prefixed completions, consistent with bpo-25011; see new _filter_identifiers() method
      • Changed the demo in the documentation; attributes like __doc__ are omitted by default
      • Removed workaround for non-ASCII input in favour of fixing bpo-16182
    8. ezio-melotti
      transferred this issue fromon Apr 10, 2022
    9. serhiy-storchaka commented on Mar 28, 2024

      @serhiy-storchaka
      serhiy-storchaka
      on Mar 28, 2024
      Member
      More actions

      I changed my mind. I thought it would be easier to implement this with simple regular expressions and string operations, but handling the corner cases makes it difficult. I now think that using the tokenize module is the only correct solution.

      My apologies, @vadmium. Are you still interesting in continuing this work?

    10. vadmium commented on May 12, 2024

      @vadmium
      vadmium
      on May 12, 2024
      MemberAuthor
      More actions

      I don’t want to spend much time on this, but I’m happy for other people to build on my code.

    11. picnixz
      added
      topic-replRelated to the interactive shellRelated to the interactive shell
      on Jan 13, 2025
    12. tomasr8 commented on Jan 14, 2025

      @tomasr8
      tomasr8
      on Jan 14, 2025
      Member
      More actions

      I should have some time in the next couple of days so I'd like to look into implementing this :)

    13. pablogsal
      added a commit that references this issue on Apr 25, 2025

      gh-69605: Add module autocomplete to PyREPL (#129329)

      c3a7118
    14. hugovk
      added a commit that references this issue on May 4, 2025

      gh-69605: Add PyREPL import autocomplete feature to 'What's New' (#13…

      a247dd3
    15. 25 remaining items

    16. ambv
      added 3 commits that reference this issue on Jan 5, 2026

      pythongh-69605: Check for already imported modules in PyREPL module c…

      7db209b

      pythongh-69605: In test_pyrepl.test_already_imported*, invalidate FS …

      aed9050

      [3.14] gh-69605: Check for already imported modules in PyREPL module …

      98a2556
    17. loic-simon commented on Jan 5, 2026

      @loic-simon
      loic-simon
      on Jan 5, 2026
      Contributor
      More actions

      Nice, I think this issue can be closed again!

      Reacted by Tomas R.
    18. tomasr8
      closed this as completedon Jan 6, 2026
    19. thunder-coding
      added 2 commits that reference this issue on Feb 15, 2026

      pythongh-69605: Check for already imported modules in PyREPL module c…

      55f5b8b

      pythongh-69605: In test_pyrepl.test_already_imported*, invalidate FS …

      00cbeb7
    20. pablogsal
      added a commit that references this issue on Apr 5, 2026

      gh-69605: Add math.integer to PyREPL module completer hardcoded list (#…

      c64baff
    21. loic-simon commented on Apr 10, 2026

      @loic-simon
      loic-simon
      on Apr 10, 2026
      Contributor
      More actions
      • Wouldn't it be cool if from typing completed the import keyword? ImportParser.parse() returns None in such a case, and I don't know if there is precedent for completing after a space, might be a litte bit too magical?
      • Yup! I'm already working on that along with general improvements to the parser :)

      Hey @tomasr8, is this still on your radar? I'd love to see this land someday, can have a try at it if needed!

    22. tomasr8 commented on Apr 11, 2026

      @tomasr8
      tomasr8
      on Apr 11, 2026
      Member
      More actions
      • Wouldn't it be cool if from typing completed the import keyword? ImportParser.parse() returns None in such a case, and I don't know if there is precedent for completing after a space, might be a litte bit too magical?
      • Yup! I'm already working on that along with general improvements to the parser :)

      Hey @tomasr8, is this still on your radar? I'd love to see this land someday, can have a try at it if needed!

      Hey @loic-simon I was indeed working on that at some point (I even have a branch for it, but can't find it ATM), but feel free to pick it up! The import parser might also need some refactoring while you're at it :) I'll try to review it in a timely manner 😆

      Reacted by Loïc Simon
    23. ljfp
      added a commit that references this issue on Apr 25, 2026

      pythongh-69605: Add math.integer to PyREPL module completer hardcoded…

      568ac22
    24. gostak-dd
      added a commit that references this issue on Jun 2, 2026

      pythongh-69605: Disable PyREPL module autocomplete fallback on regula…

      eacca66
    25. ambv
      added 3 commits that reference this issue on Oct 20, 2026

      gh-69605: fix PyREPL completions inserted for import statements with …

      488ce0f

      [3.15] gh-69605: fix PyREPL completions inserted for import statement…

      96005d3

      gh-69605: PyREPL: insert "import" after "from foo <tab>" (#148445)

      fdee11f
    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

      stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-replRelated to the interactive shellRelated to the interactive shelltype-featureA feature request or enhancementA feature request or enhancement

      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.