summaryrefslogtreecommitdiff
path: root/sleekxmpp/plugins/xep_0009/remote.py
diff options
context:
space:
mode:
authorMike Taylor <bear42@gmail.com>2015-04-11 18:32:42 -0400
committerMike Taylor <bear42@gmail.com>2015-04-11 18:32:42 -0400
commit83f71a661021dd37d4b60545dc80631711d1425f (patch)
tree6ca7b77933d534e7cf37e69e004df09eae645628 /sleekxmpp/plugins/xep_0009/remote.py
parent271343a32d60dccf7c8095b7e469eaa0609b81b1 (diff)
parent69022c6db79131b8f1c95f135a80d2b219a7d13c (diff)
downloadslixmpp-83f71a661021dd37d4b60545dc80631711d1425f.tar.gz
slixmpp-83f71a661021dd37d4b60545dc80631711d1425f.tar.bz2
slixmpp-83f71a661021dd37d4b60545dc80631711d1425f.tar.xz
slixmpp-83f71a661021dd37d4b60545dc80631711d1425f.zip
Merge pull request #348 from gribouille-dev/tor_fixes
Makes XEP-0009 compatible with Python 2 & 3.
Diffstat (limited to 'sleekxmpp/plugins/xep_0009/remote.py')
-rw-r--r--sleekxmpp/plugins/xep_0009/remote.py54
1 files changed, 45 insertions, 9 deletions
diff --git a/sleekxmpp/plugins/xep_0009/remote.py b/sleekxmpp/plugins/xep_0009/remote.py
index 8847ff24..f5ed8008 100644
--- a/sleekxmpp/plugins/xep_0009/remote.py
+++ b/sleekxmpp/plugins/xep_0009/remote.py
@@ -6,7 +6,7 @@
See the file LICENSE for copying permission.
"""
-from binding import py2xml, xml2py, xml2fault, fault2xml
+from sleekxmpp.plugins.xep_0009.binding import py2xml, xml2py, xml2fault, fault2xml
from threading import RLock
import abc
import inspect
@@ -18,6 +18,45 @@ import traceback
log = logging.getLogger(__name__)
+# Define a function _isstr() to check if an object is a string in a way
+# compatible with Python 2 and Python 3 (basestring does not exists in Python 3).
+try:
+ basestring # This evaluation will throw an exception if basestring does not exists (Python 3).
+ def _isstr(obj):
+ return isinstance(obj, basestring)
+except NameError:
+ def _isstr(obj):
+ return isinstance(obj, str)
+
+
+# Class decorator to declare a metaclass to a class in a way compatible with Python 2 and 3.
+# This decorator is copied from 'six' (https://bitbucket.org/gutworth/six):
+#
+# Copyright (c) 2010-2015 Benjamin Peterson
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+def _add_metaclass(metaclass):
+ def wrapper(cls):
+ orig_vars = cls.__dict__.copy()
+ slots = orig_vars.get('__slots__')
+ if slots is not None:
+ if isinstance(slots, str):
+ slots = [slots]
+ for slots_var in slots:
+ orig_vars.pop(slots_var)
+ orig_vars.pop('__dict__', None)
+ orig_vars.pop('__weakref__', None)
+ return metaclass(cls.__name__, cls.__bases__, orig_vars)
+ return wrapper
+
def _intercept(method, name, public):
def _resolver(instance, *args, **kwargs):
log.debug("Locally calling %s.%s with arguments %s.", instance.FQN(), method.__name__, args)
@@ -68,7 +107,7 @@ def remote(function_argument, public = True):
if hasattr(function_argument, '__call__'):
return _intercept(function_argument, None, public)
else:
- if not isinstance(function_argument, basestring):
+ if not _isstr(function_argument):
if not isinstance(function_argument, bool):
raise Exception('Expected an RPC method name or visibility modifier!')
else:
@@ -222,12 +261,11 @@ class TimeoutException(Exception):
pass
+@_add_metaclass(abc.ABCMeta)
class Callback(object):
'''
A base class for callback handlers.
'''
- __metaclass__ = abc.ABCMeta
-
@abc.abstractproperty
def set_value(self, value):
@@ -291,7 +329,7 @@ class Future(Callback):
self._event.set()
-
+@_add_metaclass(abc.ABCMeta)
class Endpoint(object):
'''
The Endpoint class is an abstract base class for all objects
@@ -303,8 +341,6 @@ class Endpoint(object):
which specifies which object an RPC call refers to. It is the
first part in a RPC method name '<fqn>.<method>'.
'''
- __metaclass__ = abc.ABCMeta
-
def __init__(self, session, target_jid):
'''
@@ -491,7 +527,7 @@ class RemoteSession(object):
def _find_key(self, dict, value):
"""return the key of dictionary dic given the value"""
- search = [k for k, v in dict.iteritems() if v == value]
+ search = [k for k, v in dict.items() if v == value]
if len(search) == 0:
return None
else:
@@ -547,7 +583,7 @@ class RemoteSession(object):
result = handler_cls(*args, **kwargs)
Endpoint.__init__(result, self, self._client.boundjid.full)
method_dict = result.get_methods()
- for method_name, method in method_dict.iteritems():
+ for method_name, method in method_dict.items():
#!!! self._client.plugin['xep_0009'].register_call(result.FQN(), method, method_name)
self._register_call(result.FQN(), method, method_name)
self._register_acl(result.FQN(), acl)