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...

Reply via email to