3

When a Python object is created dynamically, either in a live interpreter session, by un-marshalling a pickled object or some other way, the inspect module can no longer be used to retrieve its source code (as inspect relies on the idea that the source has been compiled from some file on disk).

If I have a simple class like this:

>>> class Foo(object):
...     def __init__(self):
...             self.a = 100
...     def bar(self):
...             print 'hello'
... 
>>> f = Foo()
>>> 

is there some straight forward way to get hold of the source code of the Foo class, or the f object?

I'm aware that there are a few ways around at least part of this problem. For example, one can use inspect.getmembers to find all members of f, iterate through the members to find callables and non-callables, use inspect.getargspec to determine method signatures, etc. From all that, at least some of the source code can be regenerated, but not the code inside each method. A bytecode version of each method can be generated by the dis module, but that would still need to be decompiled into source code.

Is there a better way to do this that I've missed? Can something be done with the results of sys._getframe()?

snim2
  • 4,004
  • 27
  • 44
  • Do you want to get the source, or are you trying to prevent someone getting the source? Put another way, what are you trying to build? – Ned Batchelder Jul 16 '12 at 01:15
  • If it is open source then you should (by definition) have access to all of the source you need. If not, you are attempting to access for free, code code that some developer is trying to make a living from. – Phil Cooper Jul 16 '12 at 01:23
  • Ned - I want to get the source. Phil - it's not a matter of open or closed source. In the scenarios I'm thinking of the source is not available because the objects are created dynamically. Here's a similar scenario to the ones I've described above, say you import some code from a file `Baz` and you create an instance of class `Arg`. Then you dynamically add a method `bar` to your instance of `Arg`. So now you have an object with all of `Arg`s members plus `bar`. How do you generate source for that /new/ object, with the `bar` method? – snim2 Jul 16 '12 at 01:29
  • Why are you dynamically adding methods? Why not instead update the source directly? or remember that you added the method, and the next time you want to use those methods, add them again? – Ned Batchelder Jul 16 '12 at 01:34
  • @snim2 In that case there is no "source" for your instance. Nature of the beast with a dynamically typed language. – Phil Cooper Jul 16 '12 at 01:38
  • Ned - yes, both reasonable ways around the problem, I was just hoping for something more straight forward. Phil - ditto. – snim2 Jul 16 '12 at 01:39
  • If this is for interpreter use, your best bet is probably modifying the interpreter, although that's no small feat. As far as unpickled objects, as @PhilCooper said, there is no source to obtain. – Michael Mior Oct 22 '12 at 02:32

1 Answers1

2

You can't get the source code, but you can get the bytecode, and that can be disassembled with the stdlib dis module. The bytecode can usually be read pretty easily by someone with a little experience.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662