← Back to team overview

beeseek-devs team mailing list archive

[Branch ~beeseek-devs/beeseek/trunk] Rev 189: Merged scalable-interfaces branch.

 

------------------------------------------------------------
revno: 189
committer: Andrea Corbellini <andrea.corbellini@xxxxxxxxxxx>
branch nick: trunk
timestamp: Thu 2009-01-08 18:08:39 +0100
message:
  Merged scalable-interfaces branch.
modified:
  beeseek/interfaces.py
  beeseek/session.py
  beeseek/utils/__init__.py
    ------------------------------------------------------------
    revno: 187.2.4
    committer: Andrea Corbellini <andrea.corbellini@xxxxxxxxxxx>
    branch nick: interfaces
    timestamp: Wed 2008-12-31 14:50:42 +0100
    message:
      Merge with trunk.
    modified:
      beeseek/utils/__init__.py
    ------------------------------------------------------------
    revno: 187.2.3
    committer: Andrea Corbellini <andrea.corbellini@xxxxxxxxxxx>
    branch nick: interfaces
    timestamp: Wed 2008-12-31 14:42:08 +0100
    message:
      Improved _SignatureChecker behavior.
    modified:
      beeseek/interfaces.py
      beeseek/session.py
    ------------------------------------------------------------
    revno: 187.2.2
    committer: Andrea Corbellini <andrea.corbellini@xxxxxxxxxxx>
    branch nick: interfaces
    timestamp: Wed 2008-12-31 14:41:07 +0100
    message:
      Moved get_argcount from beeseek.interfaces to beeseek.utils.
    modified:
      beeseek/utils/__init__.py
    ------------------------------------------------------------
    revno: 187.2.1
    committer: Andrea Corbellini <andrea.corbellini@xxxxxxxxxxx>
    branch nick: interfaces
    timestamp: Mon 2008-12-29 16:24:45 +0100
    message:
      Improved interfaces code by calling the original __metaclass__ first.
    modified:
      beeseek/interfaces.py

=== modified file 'beeseek/interfaces.py'
--- a/beeseek/interfaces.py	2008-12-24 17:44:16 +0000
+++ b/beeseek/interfaces.py	2008-12-31 13:42:08 +0000
@@ -23,6 +23,7 @@
 
 import sys
 from types import MethodType, NoneType
+from beeseek.utils import get_argcount
 
 __all__ = ['Interface', 'implements', 'ImplementationError']
 
@@ -39,27 +40,6 @@
                 return True
         return False
 
-# XXX To be moved to beeseek.utils
-def _get_argcount(function):
-    """Return the number of arguments required by a function.
-
-    To be more precise, return a three-items tuple with the minimum number of
-    arguments, the maximum number (None if undefined) and a bool that is True
-    if the function accepts keyword arguments.
-
-    >>> def testfunction(arg1, arg2, arg3='default', *args, **kwargs):
-    ...     pass
-    ...
-    >>> _get_argcount(testfunction)
-    (2, None, True)
-    """
-    maxargs = function.func_code.co_argcount
-    minargs = maxargs - len(function.func_defaults or ())
-    if function.func_code.co_flags & 0x04:
-        maxargs = None
-    haskwargs = function.func_code.co_flags & 0x08
-    return minargs, maxargs, bool(haskwargs)
-
 
 class Interface(object):
     """An object which represents a class interface.
@@ -69,7 +49,7 @@
     """
 
     def __new__(cls):
-        raise TypeError('Cannot instance an Interface')
+        raise TypeError('Cannot directly instance Interface')
 
 
 class ImplementationError(StandardError):
@@ -93,33 +73,29 @@
         self.metaclass = metaclass
         self.interfaces = interfaces
 
-    def __call__(self, classname, bases, origattrs):
-        # Get the original __metaclass__ and restore it
-        metaclass = origattrs.pop('__metaclass__')
+    def __call__(self, name, bases, attrs):
+        # Get the original __metaclass__
+        metaclass = attrs['__metaclass__']
         if metaclass is self:
             metaclass = self.metaclass
-        if metaclass is not type and metaclass is not self:
-            origattrs['__metaclass__'] = metaclass
-        else:
-            metaclass = type
-
-        # Sanity check
+
+        # Call the original __metaclass__()
+        # We need to do this step now because the old __metaclass__ may add or
+        # modify some attributes that we need
+        # NOTE: __mataclass__() may not always return a class
+        cls = metaclass(name, bases, attrs)
+
+        # Check if the ``implements`` attribute is changed
         interfaces = self.interfaces
-        if origattrs['implements'] is not interfaces:
+        if cls.implements is not interfaces:
             raise ValueError('``implements`` changed in class definition')
 
-        attrs = origattrs.copy()
-        isbaseclass = origattrs.get('isbaseclass', False)
-        if not isbaseclass:
-            # Get the whole attributes, including the ones declared in the
-            # inherited classes
-            for cls in bases:
-                for name in dir(cls):
-                    if name not in attrs:
-                        attrs[name] = getattr(cls, name)
-
-
+        # Attributes commons to all the interfaces must be skipped
         commons = dir(Interface)
+        # Base classes can skip the declaration of some attributes
+        isbaseclass = attrs.get('isbaseclass', False)
+        attrs = dict((name, getattr(cls, name)) for name in dir(cls))
+
         for interface in interfaces:
             for name in dir(interface):
                 if name in commons:
@@ -130,15 +106,18 @@
                     # Base classes can skip the declaration of some attributes
                     if isbaseclass:
                         continue
-                    else:
-                        raise ImplementationError('%s is required by %r, but '
-                            'is not declared' % (name, interface))
+                    raise ImplementationError('%s is required by %r, but '
+                        'is not declared' % (name, interface))
 
                 value = getattr(interface, name)
-                if type(value) is MethodType:
+                if isinstance(value, MethodType):
                     # The attribute is a function; check the number of
                     # arguments
-                    if _get_argcount(value) != _get_argcount(attrs[name]):
+                    needargs = get_argcount(value)
+                    usedargs = get_argcount(attrs[name])
+                    if (needargs[1] and (needargs != usedargs)
+                       or (needargs[0] > usedargs[0]
+                       or needargs[2] != needargs[2])):
                         raise ImplementationError('Wrong number of arguments '
                                                   'for %s' % name)
                 else:
@@ -159,12 +138,10 @@
                     # Check if the variable type is correct
                     if not any(isinstance(attrs[name], cls or NoneType)
                                for cls in value):
-                        print attrs[name].__class__
                         raise ImplementationError('%s should be of type %r' %
                             (name, value))
-
-        # Return a new class
-        return metaclass.__new__(metaclass, classname, bases, origattrs)
+        # Return the class
+        return cls
 
 
 def implements(*interfaces, **kwargs):

=== modified file 'beeseek/session.py'
--- a/beeseek/session.py	2008-11-16 15:36:45 +0000
+++ b/beeseek/session.py	2008-12-31 13:42:08 +0000
@@ -27,8 +27,7 @@
 from beeseek.commands import *
 from beeseek.interfaces import *
 from beeseek.version import Version
-from beeseek.utils import filelocking
-from beeseek.interfaces import _get_argcount
+from beeseek.utils import filelocking, get_argcount
 from beeseek.network import ConnectionHandler
 
 
@@ -124,7 +123,7 @@
         return commands
 
     def _check_args(self, command, arguments):
-        minargs, maxargs, kwargs = _get_argcount(command.__call__)
+        minargs, maxargs, kwargs = get_argcount(command.__call__)
         # The '-1' is not to count 'self'
         if len(arguments) < minargs - 1:
             print >> sys.stderr, ('%s: ERROR: Not enough arguments for %s' %

=== modified file 'beeseek/utils/__init__.py'
--- a/beeseek/utils/__init__.py	2008-12-31 13:17:26 +0000
+++ b/beeseek/utils/__init__.py	2008-12-31 13:50:42 +0000
@@ -18,8 +18,30 @@
 """Common utilities for the BeeSeek code."""
 
 
+def get_argcount(function):
+    """Return the number of arguments required by a function.
+
+    To be more precise, return a three-items tuple with the minimum number of
+    arguments, the maximum number (None if undefined) and a bool that is True
+    if the function accepts keyword arguments.
+
+    >>> def testfunction(arg1, arg2, arg3='default', *args, **kwargs):
+    ...     pass
+    ...
+    >>> _get_argcount(testfunction)
+    (2, None, True)
+    """
+    maxargs = function.func_code.co_argcount
+    minargs = maxargs - len(function.func_defaults or ())
+    if function.func_code.co_flags & 0x04:
+        maxargs = None
+    haskwargs = function.func_code.co_flags & 0x08
+    return minargs, maxargs, bool(haskwargs)
+
+
 class NULL(object):
     """This is a special class useful when ``None`` can't be used."""
+
     pass
 
 



--
BeeSeek mainline
https://code.launchpad.net/~beeseek-devs/beeseek/trunk

You are receiving this branch notification because you are subscribed to it.