[Zope3-checkins] CVS: Zope3/src/zope/proxy - __init__.py:1.3

Barry Warsaw barry@zope.com
Wed, 16 Apr 2003 15:32:44 -0400


Update of /cvs-repository/Zope3/src/zope/proxy
In directory cvs.zope.org:/tmp/cvs-serv16433

Modified Files:
	__init__.py 
Log Message:
proxy_compatible_isinstance(): An isinstance() implementation that
mimics Python 2.3's version.  This compares the object's __class__ if
it differs from its type, so this works with proxies (the proxied
object is typechecked instead of the proxy).


=== Zope3/src/zope/proxy/__init__.py 1.2 => 1.3 ===
--- Zope3/src/zope/proxy/__init__.py:1.2	Wed Dec 25 09:15:16 2002
+++ Zope3/src/zope/proxy/__init__.py	Wed Apr 16 15:32:43 2003
@@ -1,2 +1,46 @@
+##############################################################################
 #
-# This file is necessary to make this directory a package.
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""More convenience functions for dealing with proxies.
+
+$Id$
+"""
+
+def proxy_compatible_isinstance(obj, cls):
+    """Like built-in isinstance() in Python 2.3.
+
+    This honors __class__ if the standard isinstance() fails.  This is how it
+    works in Python 2.3 so that even proxied objects will succeed the test.
+    """
+    if isinstance(obj, cls):
+        return True
+    oclass = obj.__class__
+    if type(obj) == oclass:
+        # Nothing more we can do
+        return False
+    # Note that cls may be a tuple, but issubclass can't deal with that so we
+    # need to expand recursively.
+    classes = {}
+    flatten = [cls]
+    while flatten:
+        thisclass = flatten.pop(0)
+        if thisclass in classes:
+            continue
+        if isinstance(thisclass, tuple):
+            flatten.extend(list(thisclass))
+        else:
+            classes[thisclass] = True
+    for bclass in classes.keys():
+        if issubclass(oclass, bclass):
+            return True
+    return False