New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tab completion in interactive shell not working since Python version 3.8 #1604
Comments
I've noticed that if I start typing a letter or two, autocomplete will start to work:
So a workaround would be to just start typing a single letter before before hitting TAB, but I just want to see ALL attributes available at once. |
Could it possibly be an issue o Python 38 that got fixed in 3.9? Either way, I'm not sure what we could do to fix this. I'm open to any ideas. |
I thought that if an object had too many attributes, that new versions of Python would not show all those attributes when you hit tab. Below I show that an object with ~17k attributes, in new version of Python, will still work as expected when you hit tab.
So why then, does tab completion not work? |
Can anyone else replicate this? I showed you how to run this in docker, so hopefully it should be easy enough to duplicate. (The issue can be demonstrated outside of docker btw) |
In Ubuntu 20.04 I can't replicate it with Python3.9 installed using APT from default repositories, but Python3.10 installed from deadsnakes PPA has this problem. |
Summary
Environments
Steps to reproduce
Expected Behavior
Actual BehaviorAs I mentioned before in "Summary" section. NotesKite Engine and IntelliCode for VSCode are enabled and ready. It's not Kite or VSCode's fault. |
I'm using Docker Desktop for Windows with WSL2 backend. I followed the steps as what @CelestialGuru did before. When I type in a few characters it CAN auto-complete for me, but if I left it empty and invoke Console Logs (too long, click to expand)
|
This issue is stale because it has been open for 30 days with no activity. |
I see the same problem on Python 3.9 in PyCharm. I wonder if this is just due to the high level of dynamism in Faker? I.e. attributes are added in via But makes the library a pain to use as not discoverable via IDE. |
I just filed a duplicate (missed this one) in #1684 Here's my completions as of faker 13.15.0, example: from faker import Faker
def test_faker(faker: Faker):
assert isinstance(faker.name(), str) This example above is based on Pytest Fixture's examples, annotating with |
This issue is stale because it has been open for 30 days with no activity. |
Everybody wants completions for faker edit: I don't believe anybody specifically doesn't want it 😃 |
I'm just commenting to say that I'd greatly appreciate this feature as well. I'd imagine it would be trivial to add a mypy stub or similar to declare all of the many provider's attributes as members of the base Faker class. I'm trying to write the stub file myself, I'll try to remember to report back if it works. |
Well, it didn't take long for me to find the issue that's causing our autocomplete not to work. Unfortunately it's not as easy to solve as I'd hoped. def __dir__(self):
attributes = set(super(Faker, self).__dir__())
for factory in self.factories:
attributes |= {attr for attr in dir(factory) if not attr.startswith("_")}
return sorted(attributes) Because of I know that MyPy can provide type hints/autocompletion even for generated classes (I can't remember where I've seen it before - I think the AWS API library boto3 is an example). There has to be a way to get dynamic type hints even with the generated factories. Edit: I had forgotten that boto3's type hints are actually quite cumbersome to use. Due to its heavy use of generated classes (I digress, but why did they choose to make them dynamic???) the mypy type hints have to be imported manually (from the ugly-named |
@KaylaHood You are correct in factories and metaclasses masking completions due to being reliant on runtime. If you accomplish anything it'd be nice to see where it goes. But it may be too runtime-heavy to get completion and typings for. |
@tony well I seem to have made something helpful but objectively not very Pythonic. I wrote a little script that makes heavy use of the standard lib You have to run the stub generator every time you install/upgrade Faker; I can see it getting tedious very quickly. NOTE: the automated stub generation solution I just described should NEVER be used for a production or client-facing application. You don't know me! I could change my stub generation script to be a data miner! (I wouldn't, but y'know what I mean) If you would like to incorporate it into your product, then consider forking my repo to your own github/artifactory/server/etc and then use your cloned version of my script in your product's build pipeline. Hopefully you find it useful! |
We could integrate @KaylaHood 's script in our CI build and run it before every release, but that would still not cover community providers that users have installed on their own. On one hand, that'd be better than nothing. On the other, it may set the wrong expectation on users. |
@fcurella if y'all do incorporate my script, please feel free to refactor it and optimize it. I did very little optimization, I approached this with more of an "MVP" mindset :-) I agree with your last point, incorporating my stubs could confuse users who utilize their own providers or who select a specific locale. |
@KaylaHood I try your repo and it works great on my device! Thank you! Environments
Screenshots |
This is a night and day difference. Environment
Instructionsmkdir -p ~/projects/python; cd ~/projects/python
git clone https://github.com/joke2k/faker
git clone https://github.com/KaylaHood/faker-stubs
cd ~/projects/python/faker
virtualenv .venv
. .venv/bin/activate
pip install -e .
python ../faker-stubs/generate_stub.py You should now see this with
If the Before (via here)from faker import Faker
def test_faker(faker: Faker):
assert isinstance(faker.name(), str) With faker-stubs @
|
Thanks for pointing this out, I made a quick fix for this: I had forgotten to include the mangled methods from the Faker class ( Edit: use this version of my faker-stubs script instead: https://github.com/KaylaHood/faker-stubs/tree/d555b36a4deeeaccdecdfb5a90cda134dbb38605 |
@KaylaHood Follow up to #1604 (comment) + #1604 (comment) Environment
New docstring completions + locale kwargThis looks good.
Got it and this looks good (screenshot 1)
Roger that, and this looks good (screenshot 1) Provider functions v. member names
Good catch here as well Before, with faker-stubs @ With faker-stubs @ With faker-stubs @ With faker-stubs @ Side note, re:
|
**config: Any, |
I've never used any **config
kwargs, so I'm not sure what this is used for. If it's something deterministic, there's new PEPs and backported support available:
- PEP 692 "Using TypedDict for more precise **kwargs typing" may be able to help. Backport supported by mypy 0.981
- PEP 655 "Marking individual TypedDict items as required or potentially-missing", supported in
typing_extensions
since 4.1.0 (thoughTypedDict
must be imported viatyping_extensions
This issue is stale because it has been open for 30 days with no activity. |
This issue is stale because it has been open for 30 days with no activity. |
I'm still interested. |
Me too! It is a big caveat for me, that there is no any type hints for possible data. Mimesis offers that, so if there is comparison, lack of annotations is much bigger deal |
This issue is stale because it has been open for 30 days with no activity. |
I think this is still relevant |
@fcurella Fine to keep open |
@fcurella Would you be open to have a PR implementing the generation of a stub file like @KaylaHood did? This would generate a single If so, I can open a PR with a script inspired by @KaylaHood's work |
Of course! I’d love that!
…On Tue, Oct 17, 2023 at 2:16 PM Viicos ***@***.***> wrote:
@fcurella <https://github.com/fcurella> Would you be open to have a PR
implementing the generation of a stub file like @KaylaHood
<https://github.com/KaylaHood> did? This would generate a single proxy.pyi
file that would be shipped in next versions. We could make sure the file is
generated again each time a provider implements a new method.
If so, I can open a PR with a script inspirede by @KaylaHood
<https://github.com/KaylaHood>'s work
—
Reply to this email directly, view it on GitHub
<#1604 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAV4B37DSY7IZZ5DCEIST3X73KRPAVCNFSM5NP7YUK2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCNZWG4YDCNZTGAZA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Minor deconfliction / air traffic control:
@Viicos This would be a good idea. There hasn't been movement on this in some time. @KaylaHood Is this something you want a chance at PR'ing? If so, it wouldn't hurt to. Just want to make sure you don't lose credit for the effort at https://github.com/KaylaHood/faker-stubs. |
@tony thanks for giving me a heads up! I made a quick PR: #1939 FYI I had to put the generate_stubs.py script somewhere other than the faker/ directory because it will try to import faker.typing instead of the standard lib's typing module. Do you know if it's possible to force absolute import resolution in such a case? If so, I can move the generate_stubs.py script back into the faker directory. |
I've been working to help cleanup generate_stubs.py for #1939, and I gotta admit it's far more complex than I had originally thought. I was able to generate a proxy.pyi that works for all the providers, but I realized it was missing the The script will also stop working properly the moment anyone uses |
Sorry for not being active on this subject, I'm missing some time currently. I'm not sure I understand why forward refs are an issue in a stub file? Type checkers treat them as having I believe something built with Libcst or similar would be more robust. I'll see if I can come up with something soon |
The current iteration of I'm still investigating another solution but |
Ah ok I see, yes |
I was able to get the generate_stub.py working to generate all the methods for Faker. It even appears to handle future annotations. The only issue I'm seeing is one of convenience; I have no idea how get the stub generation to utilize type aliases. # from proxy.pyi
def simple_profile(
self, sex: Optional[Literal["M", "F"]] = ...
) -> Dict[str, Union[str, datetime.date, Literal["M", "F"]]]: ... vs # from profile/__init__.py
def simple_profile(self, sex: Optional[SexLiteral] = None) -> Dict[str, Union[str, date, SexLiteral]]: If there is a trick to substituting those, I'm unaware of it. |
The only way would be to parse the AST/CST I believe |
I suspect you're right. What has me confused is @KaylaHood had a few of the aliases in her version of the pyi. I could never get her version nor any of my iterations to do that. I'd love to know how she did that. Line 667 in e910dcc
With that said, what would you like to do from here? Since folks (myself included) are chomping at the bit to see a pyi file added to the library, shall I submit another PR for the updated changes? |
I think getting feedback from @MarcelWilson and @KaylaHood would be great. Sadly I don't have much time to review your work that is supposed to fix the missing imports in the initial PR, but having this script to generate stubs using |
I am @MarcelWilson. It's my work account. This is my personal account. Sorry for the confusion. |
Wonderful update. Couldn't have done better myself. 😂 |
This issue is stale because it has been open for 30 days with no activity. |
This issue was closed because it has been inactive for 14 days since being marked as stale. |
Tab autocomplete in python interactive shell unavailable when using Python versions 3.9, 3.10 or 3.11.
Python documents this feature: https://docs.python.org/3.11/tutorial/interactive.html#tab-completion-and-history-editing. (Docs here are the same in all versions of Python)
Setup
OS versions
What used to work
Type [TAB] once or twice and you see this:
What's broken
In Python 3.9, 3.10, and 3.11:
Type [TAB] once or twice and nothing happens.
The text was updated successfully, but these errors were encountered: