Python Package addict force error if not existing - python

The package addict allows you to use dicts through attribute setting:
Example from the website:
from addict import Dict
body = Dict()
body.query.filtered.query.match.description = 'addictive'
body.query.filtered.filter.term.created_by = 'Mats'
Now when when I use for example a = body.B and I haven't included B yet it does not throw an error, but just returns nothing. How can I make it throw an error when the attribute was net yet set?

addict.Dict implements the __missing__ method to generate a value for any missing key(/attribute); the current implementation generates a new Dict instance. If you don't want this behaviour, you'll have to override it:
class MyDict(Dict):
def __missing__(self, name):
raise KeyError(name)
Note that this will throw a KeyError for attribute access, which may be confusing; you could also override __getattr__ if you want to throw an AttributeError instead. In use:
>>> body = MyDict()
>>> body.B
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "path/to/addict.py", line 62, in __getattr__
return self.__getitem__(item)
File "<stdin>", line 3, in __missing__
KeyError: 'B'
>>> body.B = "hello"
>>> body.B
'hello'
Note also that this will break the other examples you showed as well, as e.g. foo.bar.baz = qux calls __getattr__ on foo before calling __setattr__ on foo.bar (if successful):
>>> body.query.filtered.query.match.description = 'addictive'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "path/to/addict.py", line 62, in __getattr__
return self.__getitem__(item)
File "<stdin>", line 3, in __missing__
KeyError: 'query'

Related

mypyc: Implementing a proxy object

Is there a way to implement a proxy object with mypyc?
For example, consider the following code which works fine with Python but not mypyc:
import typing
class Thing:
def __getattr__(self, name: str) -> typing.Any:
return 5
t = Thing()
print(t.lol)
Python output:
5
mypyc compiled output:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "blah.py", line 9, in <module>
print(t.lol)
AttributeError: 'Thing' object has no attribute 'lol'

Callable function not really callable?

I am using ParaView-5.4.1 under Ubuntu 16.04LTS.
I have an object r of class PVDReader (in pvpython, but this is likely irrelevant).
For the method TimestepValues of that class
>>> callable(r.TimestepValues)
True
>>> type(r.TimestepValues)
<class 'paraview.servermanager.VectorProperty'>
>>> r.TimestepValues
[0.0, 0.002]
>>> r.TimestepValues()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/res/apps/ParaView-5.4.1-Qt5-OpenGL2-MPI-Linux-64bit/lib/python2.7/site-packages/paraview/servermanager.py", line 681, in __call__
raise RuntimeError ("Cannot invoke this property")
RuntimeError: Cannot invoke this property
>>> import inspect
>>> inspect.getargspec(r.TimestepValues)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/santiago/apps/ParaView-5.4.1-Qt5-OpenGL2-MPI-Linux-64bit/lib/python2.7/inspect.py", line 816, in getargspec
raise TypeError('{!r} is not a Python function'.format(func))
TypeError: [0.0, 0.002] is not a Python function
So, on one hand, it is callable.
On the other hand, it behaves as if it were not.
How can this be understood?
Is this a bug?
tl;dr PS: Other more generic methods behave similarly (but not the same). E.g., compare with __class__:
>>> callable(r.__class__)
True
>>> type(fluid_pr_reader.__class__)
<type 'type'> <-- Rather obvious, just for completitude of the comparison with above
>>> r.__class__
<class 'paraview.servermanager.PVDReader'>
>>> r.__class__()
<paraview.servermanager.PVDReader object at 0x7f57ed56fd10> <-- No error here
>>> inspect.getargspec(r.__class__)
Traceback (most recent call last): <-- Same error here
File "<stdin>", line 1, in <module>
File "/home/res/apps/ParaView-5.4.1-Qt5-OpenGL2-MPI-Linux-64bit/lib/python2.7/inspect.py", line 816, in getargspec
raise TypeError('{!r} is not a Python function'.format(func))
TypeError: <class 'paraview.servermanager.PVDReader'> is not a Python function
EDIT: The result is the same if I do not access it as a straight property prior to accessing it as a callable
>>> callable(r.TimestepValues)
True
>>> r.TimestepValues()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/res/apps/ParaView-5.4.1-Qt5-OpenGL2-MPI-Linux-64bit/lib/python2.7/site-packages/paraview/servermanager.py", line 681, in __call__
raise RuntimeError ("Cannot invoke this property")
RuntimeError: Cannot invoke this property

pickle doesn't work in compile/exec

I want to use pickle in compile/exec, but it doesn't work for me. It only works when I use the global namespace. But I don't want to use global namespace, is there any way for that ? Thanks
>>> a = compile("def f():\n\t'hello'\nimport pickle\npickle.dumps(f)", "<stdin>", "exec")
>>> exec(a) # works
>>> exec(a, {}) # fails
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in <module>
_pickle.PicklingError: Can't pickle <function f at 0x1050881e0>: it's not the same object as __main__.f
>>> exec(a, {'__name__': '__main__'}) # fails too
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in <module>
_pickle.PicklingError: Can't pickle <function f at 0x1050882f0>: it's not the same object as __main__.f
No, there is no way to do this (nothing reasonable anyway). Functions pickle by qualified name, they don't actually pickle any part of their implementation. They unpickle by simply importing the module they were defined in and loading the name in question. If there is no namespace to find the function on (you replaced the globals of __main__ with your own custom dict that has no ties to __main__'s globals), you can't pickle it, because __main__.f (the qualified name of f) doesn't exist in the globals of __main__.

How do I attach temporary information to my appengine ndb model instance?

I am trying to set an attribute to my model,
class Foo(ndb.Model):
name = ndb.StringProperty()
Retrieve Foo object from memcache
If not in memcache, query from database. Here I would like to attach additional information to the Foo instance foo.special_name = "don't persist this"
Pass this object from memcache to my custom JsonEncoder
Dump this object to a dictionary, foo = {name:"hello", special_name:"don't persist this"}
AFAIK, I can't set attributes of ndb.Model classes that are not fields.
I am afraid to use ndb.Expando because I am worried that this object will get persisted and special_name will be saved to my database.
What's the cleanest way to add temporary disposable value to foo?
EDIT:
>>> class Foo(ndb.Model):
name = ndb.StringProperty()
>>> f = Foo()
>>> f.put()
Key('Foo', 26740114379063)
>>> f.bar = 123
>>> f
Foo(name=None)
>>> f.bar
Traceback (most recent call last):
File "/base/data/home/apps/shell/1.335852500710379686/shell.py", line 267, in get
exec compiled in statement_module.__dict__
File "<string>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'bar'
>>> setattr(f, 'bar', 123)
>>> f
Foo(name=None)
>>> f.bar
Traceback (most recent call last):
File "/base/data/home/apps/shell/1.335852500710379686/shell.py", line 267, in get
exec compiled in statement_module.__dict__
File "<string>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'bar'
>>> setattr(f, 'bar', 123)
>>> getattr(f, 'bar')
Traceback (most recent call last):
File "/base/data/home/apps/shell/1.335852500710379686/shell.py", line 267, in get
exec compiled in statement_module.__dict__
File "<string>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'bar'
"I can't set attributes of ndb.Model classes that are not fields."
Why would you think this? Model instances are just objects, and like any other object in Python [*], you can set arbitrary attributes on them as much as you like.
[*]: (as long as the class doesn't define __slots__, which ndb.Model doesn't)

Is there a shortcut for self.assertNotEqual() in nose?

_eq seems to be the equal to self.assertEqual()
But is there also a self.assertNotEqual() in nose?
Thanks
Nose doesn't have an equivalent to self.assertNotEqual(), but you can use all of the unittest.TestCase assert methods via nose.tools. They are renamed to all-lowercase and with underscores. For example:
>>> from nose.tools import assert_not_equal
>>> assert_not_equal(1, 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 518, in assertNotEqual
raise self.failureException(msg)
AssertionError: 1 == 1
More info here.

Categories