How do I force VS Code to import the latest Python source file? - python-3.x

I am working with Python in VS Code. I have two modules, mod_A and mod_b, where mod_A imports a method do_this_thing from mod_B. Everything was going fine until I tried to refactor do_this_thing into _do_this_thing. (The function is an internal function).
I used the Rename Symbol option in VS Code to perform the refactor. I doublechecked that all instances in my fairly simple code base were covered.
The strange behavior that I'm getting is that when I run mod_A and it gets to the renamed function call, I get an AttributeError telling me that there is no function _do_this_thing. The head scratcher, though, is that if I manually change _do_this_thing back into do_this_thing in mod_A, my code executes as expected— even though it is still defined as _do_this_thing in mod_B! Furthermore, I can't step into do_this_thing when I run it in mod_A.
I have tried deleting all __pycache__ files, as that was the first thing that I thought of. I've also tried clearing VS Code's cache, deleting my project, and starting over with the refactor from a fresh pull from GitHub. No dice.
Hopeful that someone here can help me solve this esoteric problem!
Edit: Adding some debugging context for the votes to close my question:
Windows 10, VS Code
Miniconda Python distribution
PYTHONPATH variable has project directory on it
Modules imported correctly; the bug happened when I changed the name of a function in the module being imported
Python appears to be importing a cached verison of the earlier code from somewhere, but I've reset everything and still have the issue

Related

Why does VSCode show 'problems' which do not exist?

I'm using VSCode with the python extension. The 'problems' tab as well as the indicators on the 'explorer' tab and the red underline in the code view itself all show there to be an error, even though the error isn't real.
After importing matplotlib.pyplot as plt, the code uses plt.cm.RdBu. VSCode is presenting the error that matplotlib.cm has no member RdBu.
There are two issues here:
Unless I'm just mistaken, plt.cm.RdBu ought to be equivalent to matplotlib.pyplot.cm.RdBu, not matplotlib.cm.RdBu. It seems to be interpreting that incorrectly.
But regardless of that, both cm and pyplot.cm actually do have an attribute called RdBu, both of which I was able to pull up information for using help(). The code runs perfectly and python throws no errors.
Why is VSCode telling me this is an error when it isn't? Is this just a bug or could it be a misconfiguration?
Unfortunately, there doesn't seem to be a way to fix this issue. The reason that VS Code, or more specifically, the linter used by the Python extension isn't picking up matplotlib.pyplot.cm.RdBu, or any other colormaps defined in cm is because they're defined dynamically. If you try looking inside cm.py, you'll only find this:
cmap_d = _gen_cmap_d()
locals().update(cmap_d)
Essentially, instead of being statically defined like RdBu = ..., these colormaps are defined dynamically by being injected into the module's global namespace at runtime. Even though this works fine when you run it, unfortunately it means that there's no way for the linter to know that names such as RdBu exist in the namespace until runtime. And as most linters such as pylint and flake8 are static code analysis tools that never actually execute the code, it's impossible for them to detect the existence of these colormaps.

Freeling Python API working on sample, get Import error on other code

I'm trying out Freeling's API for python. The installation and test were ok, they provide a sample.py file that works perfectly (I've played around a little bit with it and it works).
So I was trying to use it on some other python code I have, in a different folder (I'm kind of guessing this is a path issue), but whenever I import freeling (like it shows on the sample.py):
import freeling
FREELINGDIR = "/usr/local";
DATA = FREELINGDIR+"/share/freeling/";
LANG="es";
freeling.util_init_locale("default");
I get this error:
ModuleNotFoundError: No module named 'freeling'.
The sample.py is located on the ~/Freeling-4.0/APIs/Python/ folder, while my other file is located in ~/project/, I dont know if that can be an issue.
Thank you!
A simple solution is to have a copy of freeling.py in the same directory as your code, since python will look there.
A better solution is to either paste it in one of the locations where it usually checks (like the lib folder in its install directory), or to tell it that the path where your file is should be scanned for a module.
You can check out this question to see how it can be done on Windows. You are basically just setting the PYTHONPATH environment variable, and there will only be minor differences in how to do so for other OSes. This page gives instructions that should work on Linux systems.
I like this answer since it adds the path at runtime in the script itself, doesn't make persistent changes, and is largely independent of the underlying OS (apart from the fact that you need to use the appropriate module path of course).
You need to set PYTHONPATH so python can find the modules if they are not in the same folder.

pyqt4 + pyyaml/ruamel.yaml dump + pyinstaller bundling breaks application

I'm confused with some specific behaviour and can't find some informations that help me understand the error.
The situation is as follows: I made a small pyqt4 app that at some point dumps an OrderedDict to a yaml string using pyyaml or ruamel.yaml (tried both) and writes this to a file, or reads from this file. This goes very well executing the code as normal. Now I want to distribute my app by bundling it into a single file windows exe using pyinstaller.
Now if I directly use yaml.dump() or ruamel.yaml.dump() in a method of my pyqt4 form class to generate the yaml-string and write to a file (the standard way using with open ...), I am able to bundle the app using pyinstaller and the exe runs fine.
However, if I write a small function in a sub-folder/module that uses the exact same call to pyyaml (yaml.dump(dict)) or ruamel.yaml (ruamel.yaml.dump(dict, Dumper=ruamel.yaml.RoundTripDumper)) to generate the yaml string and save to a file using with open ... and use this in my pyqt4 method (I just wanted to make things more readable), pyinstaller starts to load a bunch of modules and does a lot more stuff (according to console output), resulting in the exe file beeing almost 5 times larger plus unusable throwing a fatal error pyi_rth_pkgres returned -1 at start.
Unfortunately, I don't understand much from either console output or warnings log, viewable in this gist. Maybe I am searching for the wrong terms. I also tried renaming the module to prevent shadowing.
Now my question is, does anybody know whats going on and can explain this behaviour?
After doing a lot of trial and error, I finally got it working.
I created a new module and build the dumping functions inside it. pyinstaller and the bundled exe work flawless. However, if i do the exact same thing in the previous module, even refactoring the name, it does not work. I even copied the complete code to the old module and it doesn't work. I have no idea why and at this point I am too afraid to ask :|
I am just glad it works now.

VC++ EXE standalone has bugs that don't happen in IDE

My program has a very specific error that took me a while to track down - now I don't know how to fix it. My code is very long and in many files and I don't see much point in posting it here.
In the IDE, everything runs fine, in both Debug and Release (with the runtime library set to either /MTd or /MT, respectively, so I'm assuming all dependencies are included).
However, when I run the standalone, I get a crash. At first I thought it was a dependency problem but it doesn't seem so.
At some point in the code, I am accessing a vector via a method call: t->GetList(), where GetList is defined as std::vector<T*> & GetList() and the method simply returns a member variable (simply defined as std::vector<T*> field in the class).
It turns out, if I print out the size of the list while running from the IDE, I get 0 (which is the correct answer in this case).
However, when doing the same thing running from standalone, I get the size as 467467353.
I tried changing the method declaration to std::vector<T*> * GetList() and doing return &field; and updating the rest of the code but this didn't fix anything.
I then tried replacing the member variable field with a pointer, and in the constructor instantiating a new vector and deleting it in the destructor. Still no luck.
So I made a simple test case program that simply made a class with a vector field, and a method to return a reference to it. Then in main I would create an instance variable and getting the vector and printing the size. This worked both in VC++ and as a standalone - both returned zero.
This is driving me nuts and I can't figure out why I'm getting different behaviour. Why is the standalone running differently, and what should I be looking at to fix this?
Thanks
Okay so it was literally a bug in my code that was very well hidden. I was dynamically casting to a wrong type.
Somehow it slipped past when I was running on Windows and OSX in both Debug and Release, and as a standalone on OSX. Good thing I found it.

How to reload programatically a module contained within a package in python 3.2

So far I've seen the answer for Python2 however it doesn't work on Python3, I want to be able to always get the latest changes in a module that lives in a package every time the code runs without reopening a new interpreter every time. Since modules seems to be loaded just once for performance purposes as specified in documentation,I would like to be able to force a load in the modules programatically right before starting my program. Thanks in advance...
Although I'm not a fan of answering my own questions, I think in this case totally worth to mention it since seems to be quiet useful, in order to reload a module that you previously modified without having to restart the whole interpreter, just programatically forcing the modules (contained within a package) to get the latest changes this is the way to go:
import com.your.package.YourModule as MyModuleInPackage
import imp
imp.reload(MyModuleInPackage)
Notice that trying to use imp.reload(com.your.package.YourModule) causes an error, so the way to go is by having an Alias for the fully quialified name of the module and use it in the reload function to work properly...
Hope this helps.
Regards!

Resources