Code completion for custom modules not working with PyDev - python

Let's say I make a module called mylib.py. In eclipse I type
import mylib
Then I type mylib. and hit CTRL+SPACE. This should suggest functions/variables in mylib, but it doesn't do anything. If I do something like import os and type os., suggestions immediately pop up, so I know code completion works in general, just not for my modules. Any reason why?

In order to get completion for custom modules, PyDev has to index it (if possible) and introspect the classes, functions, variables and imports defined there. To do so, you should add your module to the eclipse's PYTHONPATH and then reindex your venv (the one defined in PyDev).
Most of the times this is done automatically by the IDE but it doesn't work quite well (at least it is not perfect).
I really suggest you not to rely at 100% on the IDE completion.

Related

reduce namespace pollution in python scripts

I am working on some old python code and I was wondering if there is an easy way to find out which modules are imported but never used. I have a few hundred python scripts, each importing tens of modules (most scripts where copy-pasted by some template).
Pylint can do this. It reports "Unused import <module>" (warning named unused-import, code W0611).
This warning is enabled by default along with many others, but if you want to check for this warning specifically, you can do:
pylint --disable=all --enable=unused-import *.py
Using Pycharm does inform you if any modules or variables are used or not. That would be good for you in my opinion as an IDE.

how to make vscode detect / auto reload modules after editing them?

I've seen a few questions asking this, but none of the solutions worked for me.
I am developing a few functions/classes in different modules and have a main.py script that calls everything.
The problem is, when I make a change to a function in another module i.e. module1.py, VSCode does not detect the changes when I call the function in main.py after updating, it's still the older version.
I can get around this by doing something like:
from importlib import reload
reload module1
but this gets old real quick especially when I'm importing specific functions or classes from a module.
Simply re-running the imports at the top of my main.py doesn't actually do anything, I can only do that if I kill the shell and reopen it from the begining, which is not ideal if I am incrementally developing something.
I've read on a few questions that I could include this:
"files.useExperimentalFileWatcher" : true
into my settings.json, but it does not seem to be a known configuration setting in my version, 1.45.1.
This is something Spyder handles by default, and makes it very easy to code incrementally when calling functions and classes from multiple modules in the pkg you are developing.
How can I achieve this in VSCode? To be clear, I don't want to use IPython autoreload magic command.
Much appreciated
FYI here are the other questions I saw, but did not get a working solution out of, amongst others with similar questions/answers :
link1
link2
There is no support for this in VS Code as Python's reload mechanism is not reliable enough to use outside of the REPL, and even then you should be careful. It isn't a perfect solution and can lead to stale code lying about which can easily trip you up (and I know this because I wrote importlib.reload() 😁).

Pycharm autocomplete not working for some packages

I never really used pycharm before, but have used other JetBrains products and I expect the autocomplete to work.
When used on modules likes tkinter, after writing tk. I'll get the autocomplete, with methods like tk.Tk(). However, when used on another module (also included in python by default), ctypes, I don't get that kind of autocomplete.
If I start writing windll, I'll get an autocomplete for it, but won't get one after that, so if I write windll.user32, which is a perfectly valid code that runs just fine, I have no way of knowing whether user32 exists or not, ctrl+space shows nothing.
The variable is then successfully created, but using myVar. shows nothing. I'm using anaconda (but also tried on default python) and have the interpreter setup just fine.
Am I missing something?
PyCharm uses static analysis to provide completions, inspections, code insight features and so on.
Static analysis means reading project files and extracting knowledge from expected definitions of classes, function, attributes.
Due to dynamic nature of Python, some of these members could be declared dynamically via assignments, functions with side-effects, etc.
This is a possible reason why there could be no completion in some cases.

Python spyder debug freezes with circular importing

I have a problem with the debugger when some modules in my code call each other.
Practical example:
A file dog.py contains the following code:
import cat
print("Dog")
The file cat.py is the following:
import dog
print("Cat")
When I run dog.py (or cat.py) I don't have any problem and the program runs smoothly.
However, when I try to debug it, the whole spyder freezes and I have to kill the program.
Do you know how can I fix this? I would like to use this circular importing, as the modules use functions that are in the other modules.
Thank you!
When I run dog.py (or cat.py) I don't have any problem and the program runs smoothly.
AFAICT that's mostly because a script is imported under the special name ("__main__"), while a module is imported under it's own name (here "dog" or "cat"). NB : the only difference between a script and a module is actually loaded - passed an argument to the python runtime (python dog.py) or imported from a script or any module with an import statement.
(Actually circular imports issues are a bit more complicated than what I describe above, but I'll leave this to someone more knowledgeable.)
To make a long story short: except for this particular use case (which is actually more of a side effect), Python does not support circular imports. If you have functions (classes, whatever) shared by other scripts or modules, put these functions in a different module. Or if you find out that two modules really depends on each other, you may just want to regroup them into a single module (or regroup the parts that depend on each other in a same module and everything else in one or more other modules).
Also: unless it's a trivial one-shot util or something that only depends on the stdlib, your script's content is often better reduced to a main function parsing command-line arguments / reading config files / whatever, importing the required modules and starting the effective process.

Finding out importable modules in Python

iPython has this excellent feature of being able to auto-complete modules and this works extremely well in there.
For the longest time, I've had a shell function that allows me to change directories to where a given module is located. It does this by trying to import the name of the module from the first argument and looking into its __file__.
What I would like to do is to find out the importable modules that are available so I can write an auto-complete function for this little helper.
I know that for a give module, I can do something like dir(module_name) and that would give me what I need for that module but I am not sure what to do to find out what I can import, just like iPython when you do something like:
import [TAB]
Or
import St[TAB]
Which would autocomplete all the importable modules that start with St.
I know how to write the auto-completion functionality, I am interesting in just finding the way of knowing what can I import.
EDIT:
Digging through the IPython code I managed to find the exact piece that does the work of getting all of the current modules for the given environment:
from IPython.core.completerlib import module_completion
for module in module_completion('import '):
print module
The reason I'm printing the results is because I am actually using this for ZSH completion so I will need to deal with the output.
As a starting point, you could iterate through the paths in sys.path looking for python modules, as that is exactly what import does. Other than that, Python won’t have an index or something for all modules, as the imports are resolved on run-time, when it’s requested. You could easily provide an index for the built-in modules though and maybe have a cache or something for previously imported modules.

Categories