4

This is a bit of a random question that is more out of curiosity than any specific need.

Is it possible to write some python code that will print some stuff out, including the source code itself, without having the python code stored in a file? For example, doing something like this at the Bash prompt:

$ echo '
> print "The Code:"
> PrintScript() # What would this function look like?
> for i in range(5):
>     print i,
> print "!"
> ' | python

and get an output like this:

The Code:
print "The Code:"
PrintScript() # What would this function look like?
for i in range(5):
    print i,
print "!"
0 1 2 3 4 5 !

I suspect that this probably can't be done, but given python's introspection capabilities, I was curious to know whether it extended to this level.

Tamás
  • 47,239
  • 12
  • 105
  • 124
DrAl
  • 70,428
  • 10
  • 106
  • 108

4 Answers4

3

That's the closest I'm getting:

echo 'import  __main__,inspect;print inspect.getsource(__main__)' | python

which fails... In any case, the original code is eaten up (read from stdin) by the interpreter at startup. At most you may be able to get to the compiled code, again through the __main__ module.

Update:

The dis module is supposed to give you a disassembly of all functions in a module, but even that one isn't seeing any code:

$ echo -e 'import  __main__,dis;print dis.dis(__main__)' | python
None

And even when I throw in a function:

$ echo -e "import  __main__,dis;print dis.dis(__main__)\ndef x():\n pass" | python
None
Wim
  • 11,091
  • 41
  • 58
2

Yes, it is indeed possible to write a program which outputs it's own source. You don't need even introspection for this tasks, you just need to be able to print computed strings (works with every language).

The technique is called Quine and here is a rather short example in Python:

quine = 'quine = %r\r\nprint quine %% quine'
print quine % quine

But quines aren't limited to such simple programs. They can do much more, for example printing their own source backwards and so on... :)

tux21b
  • 90,183
  • 16
  • 117
  • 101
  • I don't think that is an answer to the question, which seems to be about how we can get the source code of some _arbitrary_ program without simply reading it from a file (hence the emphasis on getting it from the command line). A Quine is a very specific type of program. – user118967 May 15 '22 at 02:15
1

print open(__file__).read(),

This will work on UNIX systems I think, but I'm not sure about Windows. The trailing comma makes sure that the source code is printed exactly, without an extra trailing newline.

Just realized (based on the comments below) that this does not work if your source code comes from sys.stdin, which is exactly what you were asking for. In that case, you might take advantage of some of the ideas outlined on this page about quines (programs printing their own source codes) in Python, but none of the solutions would be a single function that just works. A language-independent discussion is here.

So, in short, no, I don't think this is possible with a single function if your source code comes from the standard input. There might be a possibility to access the interpreted form of your program as a Python code object and translate that back into source form, but the translated form will almost surely not match the original file contents exactly. (For instance, the comments and the shebang line would definitely be stripped away).

Tamás
  • 47,239
  • 12
  • 105
  • 124
  • 1
    This only works if your code is in a file, not if the code is passed in through stdin or `python -c `. – Wim Jun 30 '10 at 09:17
  • I tried this (on Cygwin under Windows and Linux) and both just produced an exception: `IOError: [Errno 2] No such file or directory: ''` – DrAl Jun 30 '10 at 09:20
  • 1
    You *can* read from `sys.stdin`, but the interpreter already read and compiled all your code on startup, so you won't be able to get it this way. – Wim Jun 30 '10 at 09:25
  • Thanks, you're right, I wasn't careful enough, Answer modified. – Tamás Jun 30 '10 at 09:32
1

closest you can get is using readline to interrogate the command history if available from what i can see e.g. but i suspect this may not contain stuff piped into the session and would only work for interactive sessions anyway

jk.
  • 13,817
  • 5
  • 37
  • 50