planetfederal / qgis-suite-plugin

GNU General Public License v2.0
25 stars 17 forks source link

Drag/drop pickling error for GsTreeItem-inherited items #174

Closed dakcarto closed 9 years ago

dakcarto commented 9 years ago

When dragging GsTreeItem-inherited items, e.g. GeoServer layers/styles, the following error is thrown:

Traceback (most recent call last):
  File "/usr/local/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/usr/local/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/local/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/local/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 419, in save_reduce
    save(state)
  File "/usr/local/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/local/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/usr/local/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/usr/local/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "/Users/larrys/.qgis2/python/plugins/opengeo/geoserver/retry.py", line 11, in decorator
    raise e
AttributeError: 'function' object has no attribute '__mro__'

This appears to be related to the retry method decorator in a0eb5c3.

volaya commented 9 years ago

Not able to reproduce it. Drag and drop works fine here. The error seems a bit strange, because it is trying to look for a the mro attribute in a function, while that is something that should be an attribute of a class.

One solution we might try is to not decorate magic methods, which seems to be the cause of issues when pickling. What do you think of that?

If the decorator is causing problems, we can remove it temporarily, or i can try to use a different approach, like using a metaclass

On Wed, Mar 18, 2015 at 6:40 PM, Larry Shaffer notifications@github.com wrote:

Assigned #174 https://github.com/boundlessgeo/suite-qgis-plugin/issues/174 to @volaya https://github.com/volaya.

— Reply to this email directly or view it on GitHub https://github.com/boundlessgeo/suite-qgis-plugin/issues/174#event-258423638 .

Victor Olaya Software Engineer | Boundless http://boundlessgeo.com/ volaya@boundlessgeo.com @boundlessgeo http://twitter.com/boundlessgeo/

dakcarto commented 9 years ago

@volaya I was able to redo the 'retry' using functools to ensure the function is not renamed, and I added a filter for magic names; but, I still get the pickle error.

from functools import wraps
from geoserver.catalog import Catalog

def retryMethodDecorator(func):
    @wraps(func)
    def decorator(*args, **kwargs):
        try:
            result = func(*args, **kwargs)
        except Exception, e:
            if "Errno 10053" in unicode(e):
                result = func(*args, **kwargs)
            else:
                raise e
        return result
    return decorator

class RetryCatalog(Catalog):
    def __getattribute__(self, attr_name):
        obj = super(RetryCatalog, self).__getattribute__(attr_name)
        if hasattr(obj, '__call__') and hasattr(obj, '__name__'):
            if not obj.__name__.startswith('__'):
                return retryMethodDecorator(obj)
        return obj

I believe a meta class may be the way to go, because any decorator appears to cause the __mro__ issue.

volaya commented 9 years ago

I changed the approach and decorated the http connection instead. This seems to be working and not causing the pickle error

dakcarto commented 9 years ago

Indeed, it works.