[Zodb-checkins] CVS: ZODB3/Doc/guide - prog-zodb.tex:1.2.4.4

Jeremy Hylton jeremy@zope.com
Fri, 4 Oct 2002 14:44:28 -0400


Update of /cvs-repository/ZODB3/Doc/guide
In directory cvs.zope.org:/tmp/cvs-serv24551

Modified Files:
      Tag: ZODB3-3_1-branch
	prog-zodb.tex 
Log Message:
Remove discussion of isinstance and and issublcass.

They seem to work fine in 2.1 and up.


=== ZODB3/Doc/guide/prog-zodb.tex 1.2.4.3 => 1.2.4.4 ===
--- ZODB3/Doc/guide/prog-zodb.tex:1.2.4.3	Fri Oct  4 14:40:56 2002
+++ ZODB3/Doc/guide/prog-zodb.tex	Fri Oct  4 14:44:27 2002
@@ -314,11 +314,6 @@
 arithmetic operations: \method{__radd__}, \method{__rsub__}, and so
 forth.
 
-\item Python's built-in \function{isinstance()} and \function{issubclass()}
-functions don't work properly on ExtensionClasses.  Solution: use
-custom \function{isinstance()} and \function{issubclass()} functions
-that handle ExtensionClasses correctly.
-
 \item Recent versions of the ZODB allow writing a class with 
 \method{__setattr__} , \method{__getattr__}, or \method{__delattr__} methods.  (Older versions didn't support this at all.)
 If you write such a \method{__setattr__} or \method{__delattr__} method, 
@@ -423,100 +418,6 @@
 \function{type()} doesn't return the \code{InstanceType} object, so 
 no attempt is ever made to call \method{__cmp__}.  Perhaps Python 2.2
 will repair this.
-
-\subsubsection{Fixing \function{isinstance} and \function{issubclass}}
-
-Python's built-in functions 
-\function{isinstance()} and \function{issubclass} don't
-work on ExtensionClass instances, for much the same reason that 
-\method{__cmp__} is never called; in some bits of the Python core code,
-branches are taken only if an object is of the \class{InstanceType}
-type, and this can never be true for an ExtensionClass instance.
-Python 2.1 tried to fix this, and changed these functions slightly in
-an effort to make them work for ExtensionClasses; unfortunately, the
-changes didn't work.
-
-The solution is to use customized versions of these functions that
-handle ExtensionClasses specially and fall back to the built-in
-version otherwise.  Here are the versions we've written at the MEMS Exchange:
-
-\begin{verbatim}
-# The built-in 'isinstance()' and 'issubclass()' won't work on
-# ExtensionClasses, so you have to use the versions supplied here.
-# (But those versions work fine on regular instances and classes too,
-# so you should *always* use them.)
-
-def issubclass (class1, class2):
-    """A version of 'issubclass' that works with extension classes
-    as well as regular Python classes.
-    """
-
-    # Both class objects are regular Python classes, so use the
-    # built-in 'issubclass()'.
-    if type(class1) is ClassType and type(class2) is ClassType:
-        return __builtin__.issubclass(class1, class2)
-
-    # Both so-called class objects have a '__bases__' attribute: ie.,
-    # they aren't regular Python classes, but they sure look like them.
-    # Assume they are extension classes and reimplement what the builtin
-    # 'issubclass()' does behind the scenes.
-    elif hasattr(class1, '__bases__') and hasattr(class2, '__bases__'):
-        # XXX it appears that "ec.__class__ is type(ec)" for an
-        # extension class 'ec': could we/should we use this as an
-        # additional check for extension classes?
-
-        # Breadth-first traversal of class1's superclass tree.  Order
-        # doesn't matter because we're just looking for a "yes/no"
-        # answer from the tree; if we were trying to resolve a name,
-        # order would be important!
-        stack = [class1]
-        while stack:
-            if stack[0] is class2:
-                return 1
-            stack.extend(list(stack[0].__bases__))
-            del stack[0]
-        else:
-            return 0
-
-    # Not a regular class, not an extension class: blow up for consistency
-    # with builtin 'issubclass()"
-    else:
-        raise TypeError, "arguments must be class or ExtensionClass objects"
-
-# issubclass ()
-
-def isinstance (object, klass):
-    """A version of 'isinstance' that works with extension classes
-    as well as regular Python classes."""
-
-    if type(klass) is TypeType:
-        return __builtin__.isinstance(object, klass)
-    elif hasattr(object, '__class__'):
-        return issubclass(object.__class__, klass)
-    else:
-        return 0
-\end{verbatim}
-
-I'd recommend putting these functions in a module that always gets
-imported.  The convention on my work project is to put them in
-\file{mems/lib/base.py}, which contains various fundamental classes
-and functions for our system, and access them like this:
-
-\begin{verbatim}
-from mems.lib import base
-...
-if base.isinstance(object, Class): ...
-\end{verbatim}
-
-Don't insert the modified functions into Python's
-\module{__builtin__} module, or import just the
-\function{isinstance()} and \function{issubclass} functions.  
-If you consistently use \function{base.isinstance()}, then forgetting
-to import the \module{base} module will result in a
-\exception{NameError} exception.  In the
-case of a forgotten import, calling the functions directly would use
-Python's built-in versions, leading to subtle bugs that might not be
-noticed for some time.
 
 \subsubsection{\method{__getattr__}, \method{__delattr__}, and \method{__setattr__}}