Obtained source code of python function is wrong - python

I would like to obtain the source code of a Python function. However, the functions I am dealing with have decorators that are instantiated with functions themselves. It seems like inspect or dill have problems with that. In particular, I tried the following MWE:
class Decorator(object):
def __init__(self, item):
self.item = item
self.func = None
def __call__(self, func):
self.func = func
return self
#Decorator(42)
def fun_1():
pass
#Decorator(lambda x: 42)
def fun_2():
pass
#Decorator(fun_2.item)
def fun_3():
pass
import inspect
print("Inspect results")
print(inspect.getsource(fun_1.func))
print(inspect.getsource(fun_2.func))
print(inspect.getsource(fun_3.func))
import dill
print("Dill results")
print(dill.source.getsource(fun_1.func))
print(dill.source.getsource(fun_2.func))
print(dill.source.getsource(fun_3.func))
For functions fun_1 and fun_3, this gives the expected results. For fun_2 (although it is essentially the same as fun_3), the source code as returned by inspect or dill is just wrong - it only gives me the decorator line. I would expect to get
#Decorator(lambda x: 42)
def fun_2():
pass
but all I get is
#Decorator(lambda x: 42)
I can imagine that both modules just search for the first function declaration. Is this assumption correct and is there a good workaround besides reimplementing inspect or dill?
Edit: I am using Python 2.7, but experienced the same behavior using Python 3.4.

I'm the dill author. I think you've found a bug in inspect, with regard to parsing code blocks containing a lambda as an argument in a decorator.
>>> f = lambda x: 42
>>> #Decorator(f)
... def fun_4():
... pass
...
>>>
>>> print dill.source.getsource(fun_4.func)
#Decorator(f)
def fun_4():
pass
>>>
Note that the above works, when you simply use a pointer to the lambda object. So that's your workaround.
I believe this corner case is a bug in inspect, which dill is using under the covers... so it's a bug in dill also.
I've opened a ticket on the dill GitHub page, and I'll investigate it further to see (1) if there's an easy workaround that can be implemented in dill, and (2) if indeed it's a bug in inspect (I'm guessing it is) -- and if so, it should be populated up to the python developers. Here's the link to the ticket: https://github.com/uqfoundation/dill/issues/221

Related

Hash of a function implementation

I'd like to cache intermediate results. I think that a decorator might help.
I not only want to cache based on function arguments, but also based on the implementation.
Background: I want to cache results between program runs because I am experimenting with the individual implementations, and I want to re-use results of the last run if possible.
It seems to be possible to get a function hash with pickle:
from hashlib import sha256
import pickle
def foo(bar):
print(bar)
h = sha256()
h.update(pickle.dumps(foo))
The next step would now be to use this in a decorator:
from hashlib import sha256
import pickle
def decorated(f):
def inner(*args, **kwargs):
h = sha256()
h.update(pickle.dumps((args, kwargs, f))
print(h.hexdigest())
return f(*args, **kwargs)
return inner
#decorated
def foo(bar):
print(bar)
foo("bar")
Now pickle complains:
_pickle.PicklingError: Can't pickle <function foo at 0x7f3d177fdee0>: it's not the same object as __main__.foo
I can understand that my original function got re-assigned during the decoration and that this causes trouble (foo=decorared(foo)).
Is pickling the correct choice here at all?
edit
This question here shows how to get the source code of a method:
How can I get the source code of a Python function? – maybe that's the better approach?
Is pickling the correct choice here at all?
If you want to serialize python function and might use external modules, then you might use dill for that purpose.

py.test's monkeypatch.setattr(...) not working in some cases

In conftest (in an autouse fixture):
monkeypatch.setattr('collector.util.download_data', lambda url:"Winning" )
In collector/util.py:
def download_data(url):
assert False
In the_caller.py:
from collector.util import download_data
def some_function():
download_data("blah")
When I call some_function(), I get the assert. However, if I change the_caller.py to:
import collector
def some_function():
collector.util.download_data("blah")
then I get "Winning".
Why is this behaving differently, and how can I make the monkeypatch
work for both scenarios?
In general, it seems that the issue relates to how imports work in python. I'm not sure that there is a good solution.
The best work-around that I have found so far is the following:
monkeypatch.setattr('collector.util.download_data.__code__', replacement_function.__code__)
This works with both import types.
One limitation is that this doesn't work with closures.
This functionality can be added to the framework via:
from _pytest.monkeypatch import monkeypatch
monkeypatch.setcode = lambda self, func_str, replacement_func: \
monkeypatch.setattr(self, func_str + ".__code__", replacement_func.__code__)
Reference: https://mail.python.org/pipermail/pytest-dev/2013-October/002386.html

Can I use aspects in python without changing a method / function's signature?

I've been using python-aspectlib to weave an aspect to certain methods - unfortunately this changes the methods signature to Argspec(args=[], varargs='args', keywords='kwargs', default=None), which creates problems when working with libraries that depend on inspect returning the proper signature(s).
Is there a way to use python-aspectlib without changing a method's signature? If not, are there other python aspect libraries that can do this?
I've looked at the decorator module, which explicitly mentions the problem of changing a method signature: http://micheles.googlecode.com/hg/decorator/documentation.html#statement-of-the-problem , but I was hoping to find a solution where I don't need to modify the methods I want to weave (since they are part of a third party library).
I'm using python 2.7.6
I've managed to 'fix' this for my specific use case with the following piece of code:
from decorator import decorator
from Module1 import Class1
from Module2 import Class2
def _my_decorator(func, *args, **kwargs):
#add decorator code here
return func(*args, **kwargs)
def my_decorator(f):
return decorator(_my_decorator, f)
methods_to_decorate = [
'Class1.method1',
'Class2.method2',
]
for method in methods_to_decorate:
exec_str = method + '= my_decorator('+method+'.im_func)'
exec(exec_str)
This probably doesn't handle all of the issues mentioned in the How you implement your Python decorator is wrong blog posts, but it full fills the criteria most important to me: correct method signatures.

Synthetic functions in python

In python I can create a class without class statement:
MyClass = type('X', (object,), dict(a=1))
Is there a way to create a function without 'def'?
Thats as far as i got...
d={} # func from string
exec'''\
def synthetics(s):
return s*s+1
''' in d
>>> d.keys()
['__builtins__', 'synthetics']
>>> d['synthetics']
<function synthetics at 0x00D09E70>
>>> foo = d['synthetics']
>>> foo(1)
2
Technically, yes, this is possible. The type of a function is, like all other types, a constructor for instances of that type:
FunctionType = type(lambda: 0)
help(FunctionType)
As you can see from the help, you need at minimum code and globals. The former is a compiled bytecode object; the latter is a dictionary.
To make the code object, you can use the code type's constructor:
CodeType = type((lambda: 0).func_code)
help(CodeType)
The help says this is "not for the faint of heart" and that's true. You need to pass bytecode and a bunch of other stuff to this constructor. So the easiest way to get a code object is from another function, or using the compile() function. But it is technically possible to generate code objects completely synthetically if you understand Python bytecode well enough. (I have done this, on a very limited basis, to construct signature-preserving wrapper functions for use in decorators.)
PS -- FunctionType and CodeType are also available via the types module.
There might be a more direct way than the following, but here's a full-blown function without def. First, use a trivial lambda expression to get a function object:
>>> func = lambda: None
Then, compile some source code to get a code object and use that to replace the lambda's code:
>>> func.__code__ = compile("print('Hello, world!')", "<no file>", "exec")
>>> func()
Hello, world!

How do I look inside a Python object?

I'm starting to code in various projects using Python (including Django web development and Panda3D game development).
To help me understand what's going on, I would like to basically 'look' inside the Python objects to see how they tick - like their methods and properties.
So say I have a Python object, what would I need to print out its contents? Is that even possible?
Python has a strong set of introspection features.
Take a look at the following built-in functions:
type()
dir()
id()
getattr()
hasattr()
globals()
locals()
callable()
type() and dir() are particularly useful for inspecting the type of an object and its set of attributes, respectively.
object.__dict__
I'm surprised no one's mentioned help yet!
In [1]: def foo():
...: "foo!"
...:
In [2]: help(foo)
Help on function foo in module __main__:
foo()
foo!
Help lets you read the docstring and get an idea of what attributes a class might have, which is pretty helpful.
First, read the source.
Second, use the dir() function.
If this is for exploration to see what's going on, I'd recommend looking at IPython. This adds various shortcuts to obtain an objects documentation, properties and even source code. For instance appending a "?" to a function will give the help for the object (effectively a shortcut for "help(obj)", wheras using two ?'s ("func??") will display the sourcecode if it is available.
There are also a lot of additional conveniences, like tab completion, pretty printing of results, result history etc. that make it very handy for this sort of exploratory programming.
For more programmatic use of introspection, the basic builtins like dir(), vars(), getattr etc will be useful, but it is well worth your time to check out the inspect module. To fetch the source of a function, use "inspect.getsource" eg, applying it to itself:
>>> print inspect.getsource(inspect.getsource)
def getsource(object):
"""Return the text of the source code for an object.
The argument may be a module, class, method, function, traceback, frame,
or code object. The source code is returned as a single string. An
IOError is raised if the source code cannot be retrieved."""
lines, lnum = getsourcelines(object)
return string.join(lines, '')
inspect.getargspec is also frequently useful if you're dealing with wrapping or manipulating functions, as it will give the names and default values of function parameters.
If you're interested in a GUI for this, take a look at objbrowser. It uses the inspect module from the Python standard library for the object introspection underneath.
You can list the attributes of a object with dir() in the shell:
>>> dir(object())
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
Of course, there is also the inspect module: http://docs.python.org/library/inspect.html#module-inspect
Try ppretty
from ppretty import ppretty
class A(object):
s = 5
def __init__(self):
self._p = 8
#property
def foo(self):
return range(10)
print ppretty(A(), indent=' ', depth=2, width=30, seq_length=6,
show_protected=True, show_private=False, show_static=True,
show_properties=True, show_address=True)
Output:
__main__.A at 0x1debd68L (
_p = 8,
foo = [0, 1, 2, ..., 7, 8, 9],
s = 5
)
While pprint has been mentioned already by others I'd like to add some context.
The pprint module provides a capability to “pretty-print” arbitrary
Python data structures in a form which can be used as input to the
interpreter. If the formatted structures include objects which are not
fundamental Python types, the representation may not be loadable. This
may be the case if objects such as files, sockets, classes, or
instances are included, as well as many other built-in objects which
are not representable as Python constants.
pprint might be in high-demand by developers with a PHP background who are looking for an alternative to var_dump().
Objects with a dict attribute can be dumped nicely using pprint() mixed with vars(), which returns the __dict__ attribute for a module, class, instance, etc.:
from pprint import pprint
pprint(vars(your_object))
So, no need for a loop.
To dump all variables contained in the global or local scope simply use:
pprint(globals())
pprint(locals())
locals() shows variables defined in a function.
It's also useful to access functions with their corresponding name as a string key, among other usages:
locals()['foo']() # foo()
globals()['foo']() # foo()
Similarly, using dir() to see the contents of a module, or the attributes of an object.
And there is still more.
"""Visit http://diveintopython.net/"""
__author__ = "Mark Pilgrim (mark#diveintopython.org)"
def info(object, spacing=10, collapse=1):
"""Print methods and doc strings.
Takes module, class, list, dictionary, or string."""
methodList = [e for e in dir(object) if callable(getattr(object, e))]
processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
print "\n".join(["%s %s" %
(method.ljust(spacing),
processFunc(str(getattr(object, method).__doc__)))
for method in methodList])
if __name__ == "__main__":
print help.__doc__
Others have already mentioned the dir() built-in which sounds like what you're looking for, but here's another good tip. Many libraries -- including most of the standard library -- are distributed in source form. Meaning you can pretty easily read the source code directly. The trick is in finding it; for example:
>>> import string
>>> string.__file__
'/usr/lib/python2.5/string.pyc'
The *.pyc file is compiled, so remove the trailing 'c' and open up the uncompiled *.py file in your favorite editor or file viewer:
/usr/lib/python2.5/string.py
I've found this incredibly useful for discovering things like which exceptions are raised from a given API. This kind of detail is rarely well-documented in the Python world.
There is a very cool tool called objexplore. Here is a simple example on how to use its explore function on a pandas DataFrame.
import pandas as pd
df=pd.read_csv('https://storage.googleapis.com/download.tensorflow.org/data/heart.csv')
from objexplore import explore
explore(df)
Will pop up the following in your shell:
Two great tools for inspecting code are:
IPython. A python terminal that allows you to inspect using tab completion.
Eclipse with the PyDev plugin. It has an excellent debugger that allows you to break at a given spot and inspect objects by browsing all variables as a tree. You can even use the embedded terminal to try code at that spot or type the object and press '.' to have it give code hints for you.
If you want to look at parameters and methods, as others have pointed out you may well use pprint or dir()
If you want to see the actual value of the contents, you can do
object.__dict__
pprint and dir together work great
There is a python code library build just for this purpose: inspect Introduced in Python 2.7
If you are interested to see the source code of the function corresponding to the object myobj, you can type in iPython or Jupyter Notebook:
myobj??
In Python 3.8, you can print out the contents of an object by using the __dict__. For example,
class Person():
pass
person = Person()
## set attributes
person.first = 'Oyinda'
person.last = 'David'
## to see the content of the object
print(person.__dict__)
{"first": "Oyinda", "last": "David"}
If you are looking for a slightly more delicate solution, you could try objprint. A positive side of it is that it can handle nested objects. For example:
from objprint import objprint
class Position:
def __init__(self, x, y):
self.x = x
self.y = y
class Player:
def __init__(self):
self.name = "Alice"
self.age = 18
self.items = ["axe", "armor"]
self.coins = {"gold": 1, "silver": 33, "bronze": 57}
self.position = Position(3, 5)
objprint(Player())
Will print out
<Player
.name = 'Alice',
.age = 18,
.items = ['axe', 'armor'],
.coins = {'gold': 1, 'silver': 33, 'bronze': 57},
.position = <Position
.x = 3,
.y = 5
>
>
import pprint
pprint.pprint(obj.__dict__)
or
pprint.pprint(vars(obj))
If you want to look inside a live object, then python's inspect module is a good answer. In general, it works for getting the source code of functions that are defined in a source file somewhere on disk. If you want to get the source of live functions and lambdas that were defined in the interpreter, you can use dill.source.getsource from dill. It also can get the code for from bound or unbound class methods and functions defined in curries... however, you might not be able to compile that code without the enclosing object's code.
>>> from dill.source import getsource
>>>
>>> def add(x,y):
... return x+y
...
>>> squared = lambda x:x**2
>>>
>>> print getsource(add)
def add(x,y):
return x+y
>>> print getsource(squared)
squared = lambda x:x**2
>>>
>>> class Foo(object):
... def bar(self, x):
... return x*x+x
...
>>> f = Foo()
>>>
>>> print getsource(f.bar)
def bar(self, x):
return x*x+x
>>>
vars(obj) returns the attributes of an object.
In addition if you want to look inside list and dictionaries, you can use pprint()
Many good tipps already, but the shortest and easiest (not necessarily the best) has yet to be mentioned:
object?
Try using:
print(object.stringify())
where object is the variable name of the object you are trying to inspect.
This prints out a nicely formatted and tabbed output showing all the hierarchy of keys and values in the object.
NOTE: This works in python3. Not sure if it works in earlier versions
UPDATE: This doesn't work on all types of objects. If you encounter one of those types (like a Request object), use one of the following instead:
dir(object())
or
import pprint
then:
pprint.pprint(object.__dict__)

Categories

Resources