1

I realized that after compiling 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 ?

halfer
  • 19,824
  • 17
  • 99
  • 186
ibrahim
  • 3,254
  • 7
  • 42
  • 56
  • What do you mean by "is there any way to see real path in errors?"? You're seeing real path already right? What do you want to see in trace there? – Bharadwaj Srigiriraju Dec 10 '13 at 13:12
  • 2
    Why do you want to manually "compile" a script and why do you to put it in a different directory? – smeso Dec 10 '13 at 13:18
  • @Forbidden Overseer I see the source path. I want to see path of compiled code. – ibrahim Dec 10 '13 at 13:19
  • 1
    .pyc are not supposed to be separated from the original source, they are nothing but a "cache". This is the reason why you get that path. Why do you want to do such a thing? – smeso Dec 10 '13 at 13:22
  • @Faust didn't you read the question! I have no problem. I just wondering. – ibrahim Dec 10 '13 at 13:26
  • Well, you can open an hexadecimal editor and change every "/tmp/src/foo.py" in what you want, if you manage to maintain the same length you will not have many problems. Otherwise you should probably read some doc to understand how to change things without destroy the file. I don't think that there is any command line option or code that you could use, just because nobody needs to do this. – smeso Dec 10 '13 at 13:30
  • @ibrahim: Go through this once: http://stackoverflow.com/q/3918689/1076075 The error points towards lines in source file, but you want it to show the pyc file instead, which means you want it to show you errors in the bytecode instead of showing them in source code. Which one do you think makes sense? – Bharadwaj Srigiriraju Dec 10 '13 at 13:32

1 Answers1

1

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.

Alfe
  • 56,346
  • 20
  • 107
  • 159
  • I am able to run .pyc without .py even on another machines, even it is a long script. – ibrahim Dec 10 '13 at 14:33
  • So? That's just because the bytecode is the same everywhere. – Alfe Dec 10 '13 at 14:34
  • I wanted to specify that because you said "you are lucky to be able to run the .pyc file at all without the .py at its side." – ibrahim Dec 10 '13 at 15:20
  • "*until shown a specification which approves of such a thing*" - [The 2.7 Python tutorial](http://docs.python.org/2.7/tutorial/modules.html#compiled-python-files) approves of this use. "It is possible to have a file called spam.pyc (or spam.pyo when -O is used) without a file spam.py for the same module. This can be used to distribute a library of Python code in a form that is moderately hard to reverse engineer." – Robᵩ Dec 10 '13 at 16:17
  • Fine, but it doesn't say that your main module also can be handled like this (and that's the case here). But on the other hand, that distinction might well seem artificial. – Alfe Dec 11 '13 at 08:28