Makes XEP-0009 compatible with Python 3 while maintaining compatibility with Python 2.6 and up.
This commit is contained in:
parent
27582f6fd2
commit
69022c6db7
1 changed files with 45 additions and 9 deletions
|
@ -6,7 +6,7 @@
|
||||||
See the file LICENSE for copying permission.
|
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
|
from threading import RLock
|
||||||
import abc
|
import abc
|
||||||
import inspect
|
import inspect
|
||||||
|
@ -18,6 +18,45 @@ import traceback
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
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 _intercept(method, name, public):
|
||||||
def _resolver(instance, *args, **kwargs):
|
def _resolver(instance, *args, **kwargs):
|
||||||
log.debug("Locally calling %s.%s with arguments %s.", instance.FQN(), method.__name__, args)
|
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__'):
|
if hasattr(function_argument, '__call__'):
|
||||||
return _intercept(function_argument, None, public)
|
return _intercept(function_argument, None, public)
|
||||||
else:
|
else:
|
||||||
if not isinstance(function_argument, basestring):
|
if not _isstr(function_argument):
|
||||||
if not isinstance(function_argument, bool):
|
if not isinstance(function_argument, bool):
|
||||||
raise Exception('Expected an RPC method name or visibility modifier!')
|
raise Exception('Expected an RPC method name or visibility modifier!')
|
||||||
else:
|
else:
|
||||||
|
@ -222,12 +261,11 @@ class TimeoutException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@_add_metaclass(abc.ABCMeta)
|
||||||
class Callback(object):
|
class Callback(object):
|
||||||
'''
|
'''
|
||||||
A base class for callback handlers.
|
A base class for callback handlers.
|
||||||
'''
|
'''
|
||||||
__metaclass__ = abc.ABCMeta
|
|
||||||
|
|
||||||
|
|
||||||
@abc.abstractproperty
|
@abc.abstractproperty
|
||||||
def set_value(self, value):
|
def set_value(self, value):
|
||||||
|
@ -291,7 +329,7 @@ class Future(Callback):
|
||||||
self._event.set()
|
self._event.set()
|
||||||
|
|
||||||
|
|
||||||
|
@_add_metaclass(abc.ABCMeta)
|
||||||
class Endpoint(object):
|
class Endpoint(object):
|
||||||
'''
|
'''
|
||||||
The Endpoint class is an abstract base class for all objects
|
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
|
which specifies which object an RPC call refers to. It is the
|
||||||
first part in a RPC method name '<fqn>.<method>'.
|
first part in a RPC method name '<fqn>.<method>'.
|
||||||
'''
|
'''
|
||||||
__metaclass__ = abc.ABCMeta
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, session, target_jid):
|
def __init__(self, session, target_jid):
|
||||||
'''
|
'''
|
||||||
|
@ -491,7 +527,7 @@ class RemoteSession(object):
|
||||||
|
|
||||||
def _find_key(self, dict, value):
|
def _find_key(self, dict, value):
|
||||||
"""return the key of dictionary dic given the 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:
|
if len(search) == 0:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
@ -547,7 +583,7 @@ class RemoteSession(object):
|
||||||
result = handler_cls(*args, **kwargs)
|
result = handler_cls(*args, **kwargs)
|
||||||
Endpoint.__init__(result, self, self._client.boundjid.full)
|
Endpoint.__init__(result, self, self._client.boundjid.full)
|
||||||
method_dict = result.get_methods()
|
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._client.plugin['xep_0009'].register_call(result.FQN(), method, method_name)
|
||||||
self._register_call(result.FQN(), method, method_name)
|
self._register_call(result.FQN(), method, method_name)
|
||||||
self._register_acl(result.FQN(), acl)
|
self._register_acl(result.FQN(), acl)
|
||||||
|
|
Loading…
Reference in a new issue