Why Does Python Autocomplete Show Useless Suggestions First?
I typed os. in VSCode, expecting os.path to appear at the top. Instead, I got this:
os.abort <- Never used thisos.CLD_CONTINUED <- What is this?os.CLD_DUMPED <- Never needed thisos.EX_CANTCREAT <- Seriously?...os.path <- Finally! (scrolled way down)Every. Single. Time.
The Problem
Python’s autocomplete in VSCode is embarrassingly dumb. It shows rarely-used options like os.abort before commonly-used ones like os.path or os.remove.
I’m not alone in this frustration. A Reddit post by u/matan-h captured it perfectly:
“When I opened vscode, and typed ‘os.’, it showed me autocomplete options that I almost never used, like os.abort or os.CLD_CONTINUED, Instead of showing me actually used options, like path or remove.”
The community response was telling:
“It feels quite absurd that basic intelligence like this is lacking from the majority of programs” - 40 points
Another user pointed out:
“Pylance does a pretty good job but it is so slow and uses so much memory. I mean, why does a language typing service need 4GB+ of RAM?”
Why This Happens
The culprit is Pylance, VSCode’s default Python language server. Here’s what’s going wrong:
1. No usage-based learning
Pylance doesn’t track which completions you actually select. It has zero memory of your preferences.
2. Static ranking
Instead of learning from usage patterns, Pylance sorts completions alphabetically or uses static heuristics based on signatures. That’s why abort appears before path.
3. Legacy LSP architecture
The Language Server Protocol (LSP) was designed for correctness, not UX intelligence. Most LSP implementations prioritize returning accurate completions over smart ranking.
┌─────────────────────────────────────────┐│ LSP Design Priorities │├─────────────────────────────────────────┤│ 1. Correctness ✓ (all options) ││ 2. Performance ✓ (fast response) ││ 3. Intelligence ✗ (dumb ranking) │└─────────────────────────────────────────┘How to Fix It
Option 1: Community Fix (Hash Table Lookup)
One developer created a hash table lookup of commonly-used Python prefixes to reorder suggestions:
# Common prefixes that should rank higherCOMMON_PREFIXES = { 'os': ['path', 'remove', 'rename', 'mkdir', 'listdir', 'getcwd'], 'sys': ['argv', 'path', 'exit', 'stdout', 'stderr'], 'json': ['loads', 'dumps', 'load', 'dump'], # ... more mappings}
def reorder_completions(prefix: str, completions: list) -> list: """Reorder completions based on common usage.""" if prefix not in COMMON_PREFIXES: return completions
preferred = COMMON_PREFIXES[prefix] ranked = [] remaining = []
for completion in completions: if completion in preferred: ranked.append(completion) else: remaining.append(completion)
# Sort ranked by preference order, then append remaining ranked.sort(key=lambda x: preferred.index(x) if x in preferred else len(preferred)) return ranked + sorted(remaining)This approach works but requires maintaining the hash table manually.
Option 2: Switch to Jedi Language Server
Jedi is lighter and often smarter:
{ "python.languageServer": "Jedi"}Restart VSCode after changing this setting.
Jedi uses different heuristics and often surfaces more relevant completions. It also uses significantly less memory than Pylance.
Option 3: Configure Pylance Settings
If you want to stick with Pylance, try these optimizations:
{ "python.analysis.completeFunctionParens": true, "python.analysis.autoImportCompletions": true, "python.analysis.typeCheckingMode": "basic", "python.analysis.memory": 4096}The memory setting limits Pylance’s RAM usage, which can help with performance on smaller machines.
Option 4: Use VSCode’s IntelliCode
VSCode has a feature called IntelliCode that learns from your code patterns:
{ "vsintellicode.modify.editor.suggestSelection": "automaticallyOverrodeDefaultValue", "editor.suggestSelection": "recentlyUsedByPrefix"}This enables recently-used-by-prefix ranking, which helps VSCode remember your preferred completions.
Why Pylance Uses So Much Memory
The 4GB+ memory usage mentioned in the Reddit thread is a real issue. Pylance builds a comprehensive type analysis of your entire project and dependencies. Here’s what’s happening:
┌────────────────────────────────────────────┐│ Pylance Memory Usage │├────────────────────────────────────────────┤│ Type analysis of project files ~500MB ││ Type stubs for standard library ~200MB ││ Type stubs for dependencies ~1-2GB ││ Cached analysis results ~500MB ││ Index structures ~1GB │└────────────────────────────────────────────┘For large projects with many dependencies, this adds up quickly.
The Bigger Picture
This problem highlights a gap in developer tool UX. Modern IDEs like JetBrains products have had usage-based ranking for years. VSCode’s approach of delegating intelligence to language servers has trade-offs:
- Pros: Consistent behavior across languages, easier plugin development
- Cons: Each language server implements its own ranking, quality varies
The LSP specification doesn’t include usage frequency in its completion protocol. This means each language server must implement its own ranking mechanism, and many (like Pylance) prioritize correctness over intelligence.
Related Knowledge
Language Server Protocol (LSP): Microsoft’s protocol for language-specific features like autocomplete, go-to-definition, and find-references. It separates the language intelligence from the editor, allowing any editor to support any language via LSP.
IntelliSense vs IntelliCode: IntelliSense is the basic autocomplete system. IntelliCode is Microsoft’s ML-powered enhancement that learns from your code patterns. Not all languages support IntelliCode.
Jedi vs Pylance: Jedi is an older, lighter Python language server. Pylance is Microsoft’s newer, more feature-rich server built on Pyright. Jedi focuses on speed; Pylance focuses on type accuracy.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments