This one just hit me when I uploaded the app on GAE. No problems
whatsoever on the local development environment where I can pickle/
unpickle any Storage instance with Python 2.5.
The trace looks like:
Traceback (most recent call last):
File "/base/data/home/apps/s~b-stock-staging/1.354286568593706431/
gluon/restricted.py", line 194, in restricted
exec ccode in environment
File "/base/data/home/apps/s~b-stock-staging/1.354286568593706431/
applications/central/controllers/default.py:signup", line 153, in
<module>
File "/base/data/home/apps/s~b-stock-staging/1.354286568593706431/
gluon/globals.py", line 149, in <lambda>
self._caller = lambda f: f()
File "/base/data/home/apps/s~b-stock-staging/1.354286568593706431/
gluon/tools.py", line 2456, in f
return action(*a, **b)
File "/base/data/home/apps/s~b-stock-staging/1.354286568593706431/
applications/central/controllers/default.py:signup", line 36, in
signup
File "applications/central/modules/user_helpers.py", line 17, in
get_user_data
all_attributes =
attribute_helpers.BStockAttributes.get_attributes()
File "applications/central/modules/attribute_helpers.py", line 18,
in get_attributes
return current.cache.ram('cached_attributes', lambda:
BStockAttributes._get_attributes(), time_expire = 6000)
File "/base/data/home/apps/s~b-stock-staging/1.354286568593706431/
gluon/contrib/gae_memcache.py", line 39, in __call__
self.set(key, (time.time(), value))
File "/base/python_runtime/python_lib/versions/1/google/appengine/
api/memcache/__init__.py", line 767, in set
namespace=namespace)
File "/base/python_runtime/python_lib/versions/1/google/appengine/
api/memcache/__init__.py", line 872, in _set_with_policy
time, '', namespace)
File "/base/python_runtime/python_lib/versions/1/google/appengine/
api/memcache/__init__.py", line 951, in _set_multi_async_with_policy
stored_value, flags = _validate_encode_value(value,
self._do_pickle)
File "/base/python_runtime/python_lib/versions/1/google/appengine/
api/memcache/__init__.py", line 227, in _validate_encode_value
stored_value = do_pickle(value)
File "/base/python_runtime/python_lib/versions/1/google/appengine/
api/memcache/__init__.py", line 395, in _do_pickle
pickler.dump(value)
File "/base/python_runtime/python_dist/lib/python2.5/pickle.py",
line 218, in dump
self.save(obj)
File "/base/python_runtime/python_dist/lib/python2.5/pickle.py",
line 280, in save
f(self, obj) # Call unbound method with explicit self
File "/base/python_runtime/python_dist/lib/python2.5/pickle.py",
line 542, in save_tuple
save(element)
File "/base/python_runtime/python_dist/lib/python2.5/pickle.py",
line 300, in save
rv = reduce(self.proto)
TypeError: 'NoneType' object is not callable
The result of BStockAttributes._get_attributes() which I am trying to
cache are nested a couple of levels deep Storages:
<Storage {'hp': <Storage {'abbreviation': 'hp', 'name': 'My Site',
'url': 'http://test.com/staging/', 'logo_data': None, 'enabled': True,
'queue': None, 'do_not_market': False, 'attributes': <Storage
{'by_name': <Storage {'city': <Storage {'name': 'city', 'weight': 35,
'is_required': 'y', 'type': 'string', 'id': 8, 'location': 'usr'}
>, ... }>}>}>}>
The context where the exact error is raised looks like this:
File /base/python_runtime/python_dist/lib/python2.5/pickle.py in save
at line 300 code arguments variables
Function argument list:
(self=<pickle.Pickler instance at 0x1ebda96fc47dea10>, obj=<Storage
{'by_name': <Storage {'bank_name': <Sto...me': 'timezone', 'weight':
55L, 'id': 15002}>}>}>)
Code listing:
rv = reduce(obj)
else:
# Check for a __reduce_ex__ method, fall back to
__reduce__
reduce = getattr(obj, "__reduce_ex__", None)
if reduce:
rv = reduce(self.proto) #
<-----------fails right here
else:
reduce = getattr(obj, "__reduce__", None)
if reduce:
rv = reduce()
Variables:
reduce: <built-in method __reduce_ex__ of Storage object at
0x1ebda96fc467c600>
rv: undefined
self.proto: 2
self: <pickle.Pickler instance at 0x1ebda96fc47dea10>
I am aware that you can't pickle anything except Python native types,
lists, dicts, etc. but a Storage is basically a dict and I can't
replicate this on any other environment. GAE caches in memcache which
I also do in the dev. environment so not sure that is the issue
either. Anyone seen anything like this?
Appreciate your help...