python script path stays same after compilation - python

I realized that after compile a python script, It fixes the path information of this script.
For example:
I have a python script as /tmp/src/foo.py which has a single print command
print foo
Now I am compiling this code and move it to compiled directory.
python -m compileall -f /tmp/src/foo.py
mv /tmp/src/foo.pyc /tmp/compiled/
Then I am running the script and It gives error as I excepts
python /tmp/compiled/foo.pyc
Traceback (most recent call last):
File "/tmp/src/foo.py", line 1, in <module> # focus heree
print foo
NameError: name 'foo' is not defined
As you realize, file name of script appeared in error as its name before compilation. (Exactly same as path which I give to compile command)
Actually I have no problem with this situation, I am asking because I am just wondering. What is the reason and is there any way to see real path in errors?
In my opinion, we could not change binary file but maybe we can give a command line parameter to python when run compiled code or maybe we can add a code segment to source code ?
Thanks

Your question derives from the notion that a compiled version of a Python module can and should be moved under certain conditions. I've actually never heard of such a thing before, so until shown a specification which approves of such a thing, I'd say that this is an abuse and you are lucky to be able to run the .pyc file at all without the .py at its side.
If you think of the .pyc files as mere caches of the compiled versions of the original, then you can easily explain all phenomena you observed: The path of the original .py file is stored in the .pyc along with everything else coming from that source. If moved, that contents of course stays the same and will be used in error messages.
There is no way to see the "real" path in the error message because the place of the .pyc file isn't known anymore after loading it; only its contents is taken into account, and not its location, because combining those two things is a step of compilation. The interpreter won't compile again anything to an already compiled module. It takes it as it is.
Patching the .pyc file to show a different path also does not seem to make sense because that message is for helping you debug the problem. You probably won't debug anything in the .pyc file but only in the .py file. So it seems appropriate to rather have the path of that file in the error message.

Related

How to excute Fortran program in python

I have a Fortran program and want to execute it in python for multiple files. I have 2000 input files but in my Fortran code I am able to run only one file at a time. How should I call the Fortran program in python?
My Script:
from numpy import f2py
with open("phase1.f") as sourcefile:
sourcecode = sourcefile.read()
f2py.compile(sourcecode, modulename='add')
Error:
Could not locate executable C:\Users\Vishnu\Anaconda2\python.exe
Executable C:\Users\Anaconda2\python.exe does not exist
For some starting places, take a look at https://cvw.cac.cornell.edu/python/combine. And consider F2Py, which is now included with numpy, I believe.
Regarding file paths, you may run into python interpreting C:\ as escaped, which I think is happening in your output above:
C:UsersVishnuAnaconda2python.exe
Try using:
'C:\\Users\\Vishnu\\Anaconda2\\python.exe'
or
r'C:\Users\Vishnu\Anaconda2\python.exe'
for example. See if that fixes the missing file problem.
[UPDATE]
I suspect the problem is somewhere in your user environment variables. Check the paths set there.
C:UsersVishnuAnaconda2python.exe
is trying to run your python, which is probably installed in:
C:\Users\Vishnu\Anaconda2\python.exe
Try simply typing 'environment' in your Start menu in windows. Check the paths there. That's a good place to start looking. (This may depend on which Windows you are using.)

Why does the existence of .pyc file change the result of my code?

I have a test case for an algorithm, which gives a different result after the first execution.
The test imports the algorithm and the test data from two files.
The first execution returns the correct results and creates a .pyc file for the test data file.
The second and all following executions return incorrect results.
When I delete the test data's .pyc file the next execution returns the correct results again (and creates a new .pyc file again).
When I move the test data into the same file as the test case itself (i.e. avoiding the creation of a .pyc file) the test always passes.
I cannot apply this fix to my full program.
Is this a known issue, is there a fix?
.pyc files contain byte code, which is what the Python interpreter compiles the source to. This code is then executed by Python's virtual machine.
Python's documentation explains the definition like this:
Python is an interpreted language, as opposed to a compiled one,
though the distinction can be blurry because of the presence of the
bytecode compiler. This means that source files can be run directly
without explicitly creating an executable which is then run
The .pyc files are created (and possibly overwritten) only when that python file is imported by some other script. If the import is called, Python checks to see if the .pyc file's internal timestamp matches the corresponding .py file. If it does, it loads the .pyc; if it does not or if the .pyc does not yet exist, Python compiles the .py file into a .pyc and loads it.
One thing I found that changes is the value of file (.pyc vs .py), which tripped me up writing a utility invoking stack traces.

IDLE Python not detecting changes

I am using IDLE to write a few small sized Python programs. There are two class files - node.py (Node Class) and position.py (Position class). I have my main module code in main.py from which I instantiate Node and Position objects.
What I have noticed is that - when I make a change in node.py or position.py, check the modules and then run them using F5 the changes are not reflected back when I run main.py as long as all the files are open in IDLE. I noticed that I have to manually close all the three .py files and then close IDLE, start over again and run main.py to see the changes made in node.py and position.py.
What is the issue here? Are my environment variables not being set correctly? I have searched SO and online but have not found a satisfactory answer.
[Details: I am using IDLE version 2.7.3 in Ubuntu. All the three .py files and the corresponding .pyc byte code files are in the same directory. This directory is also seen in sys.path]
What was happening is that I needed to use "import node" but I was using "from node import *" from main.py. This was preventing the main.py from linking to the updated node module!
(Sorry for accepting my own answer, but may be someone would also face the same problem later and hence I am uploading the solution)
I used Ctrl+F6 as Matthew Plourde suggested. Using Python 3 and IDLE, I would have my test file and my core file open. I would then fix errors reported by my assertions in my test file in my core file but the test file would not see the changes. The only solution I had was closing and reopening which is a pain. Ctrl+F6 did work. I could not find the reload function in Python3.
I retract this statement. With python3, if you run IDLE a "-n" because of lack of admin rights or some other security reason you need to import imp and use imp.reload(function) for IDLE to pickup any changes to other python files you are editing and recalling. Otherwise python does not detect the changes and will not reload the files.
http://docs.python.org/3.0/library/imp.html#imp.reload

git cannot execute python-script as hook

I have created a little pre-commit hook in python. This hook works like a charm under Linux, but in Windows it keeps telling me:
error: cannot spawn .git/hooks/pre-commit: No such file or directory
I know there have been similar questions here about the same issue and the conclusion seams to be the shebang. My script has this on the very first line:
#!F:\PortableApps\PortablePython3.2\App\python.exe
It's also interesting to note that executing the script simply by writing .git/hooks/pre-commit works wonderful, but as soon as I try to commit, git spits out the above message.
Another interesting thing is, when I convert the encoding from ANSI to UTF-8 (using Notepad++), I get the following error when trying to execute the script:
.git/hooks/pre-commit: Cannot execute binary file
I'm using the following tools:
PortablePython 3.2.1.1
msysgit 1.7.6 (Portable)
I used the proxy-approach to make the python script work under windows (with msysgit). The complete script (with description on how I did it) might be found here: https://gist.github.com/1839424
Here is the important part about making it work under Windows
If you're working with Windows (and "msysgit"), it's a little more complicated. Since "msysgit" seems to have a problem handling the SHEBANG, you'll have to use a little trick to make the script executable (further information on this problem can be found here).
In order to make the script work, you'll want to remove the SHEBANG from the Python script ("pre-commit.py") and use a wrapper bash-script to call the interpreter. This script should look something like this:
#!/bin/sh
python .git/hooks/pre-commit.py
Store this script as a file called "pre-commit" (no file-ending). This assumes that you have Python in your PATH. If you don't, you can also specify the full path to your interpreter-executable.
This script will be called by "git commit" and call the python-script to check for the huge files. The path after the SHEBANG should not be changed, as "msysgit" will remap it automatically. You must specify a path relative to the repo-root for the Python script to be executed (because thats from where the script is called).
Afterwards you'll want to copy both the wrapper-file ("pre-commit") and the Python-script ("pre-commit.py") to your repos ".git/hooks"-directory, personalize the Python-script ("max_file_size" and "git_binary_path") and mark the "pre-commit"-file executable.

Python modules not updating after restarting the main module

I've recently come back to a project having had to stop for about 6 months, and after reinstalling my operating system and coming back to it I'm having all kinds of crazy things happen. I made sure to install the same version(2.6) of python that I was using before.
It started by giving me strange tkinter error that I hadn't had trouble with before, the program is relatively simple and the 2 or 3 bugs that were left when i quit, I had documented and weren't related to the interface.
Things got even weirder when the same error would pop up even after I had removed the offending section of code. In fact, the traceback pointed to a line that didn't even exist in the module it was referencing, eg: line 262 when the module was only 200 lines long.
After just starting a completely new file for the main module and copy/pasting it finally recognized that the offending code was gone and I stopped getting the error only to find that any updates to the code I made in another module didn't show up when I restarted the program through the shell. (I didn't forget to save.) After fiddling with this, of course, the old interface error came back, only in a different section of code that had been working previously.
In fact, if I revert back to the files I had six months ago, the program works fine. As soon as I change anything in the main module, however, the interface bug comes back.
Here's the original error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:\PyStuff\interface.py", line 202, in dispOne
__main__.top.destroy()
File "C:\Python26\lib\lib-tk\Tkinter.py", line 1938, in destroy
self.tk.call('destroy', self._w)
TclError: can't invoke "destroy" command: application has been destroyed
I'm guessing something else is going on here other than my own poor programming. Anyone have any ideas?
Edit: Thinking back, I believe I read something about it being a bad idea to run Tkinter programs through IDLE's shell, and it appears, at least, that the TclError has vanished if I instead start the main module by double clicking the .pyc file. Perhaps my problems were just a combination of that plus the timestamp/PYTHONPATH issues mentioned below by Chris Atlee and Vlad?
I've had something similar happen. The cause for my problems was that my source control software (hg) was setting the date of files to a date in the past. Because of this, python chose to use previously generated .pyc files which had newer timestamps.
The solution was to delete all the .pyc files before testing the code.
Check your PYTHON_PATH variable, you probably have an older version of the file.
Also start your python interpreter and type the following commands to check the path:
import sys
print sys.path
Take a careful look at the output and make sure you don't have any old directories sitting there.

Categories

Resources