[PyObjC-svn] r2215 - in trunk/pyobjc/pyobjc-core: . Lib/objc Lib/objc/test

[email protected] Sun, 10 May 2009 04:30:42 -0500
Newsgroups gmane.comp.python.pyobjc.cvs
Message-ID <[email protected]>
Author: ronaldoussoren
Date: Sun May 10 04:30:42 2009
New Revision: 2215

Log:
Improve handling of non-methods in objc.Category. This fixes #39

Modified:
   trunk/pyobjc/pyobjc-core/Lib/objc/_category.py
   trunk/pyobjc/pyobjc-core/Lib/objc/test/test_methodedits.py
   trunk/pyobjc/pyobjc-core/NEWS.txt

Modified: trunk/pyobjc/pyobjc-core/Lib/objc/_category.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/Lib/objc/_category.py	(original)
+++ trunk/pyobjc/pyobjc-core/Lib/objc/_category.py	Sun May 10 04:30:42 2009
@@ -1,6 +1,8 @@
 __all__ = ['classAddMethod', 'Category']
 
-from _objc import selector, classAddMethods, objc_class
+from _objc import selector, classAddMethods, objc_class, ivar
+
+from types import FunctionType, MethodType
 
 def classAddMethod(cls, name, method):
     """
@@ -26,22 +28,30 @@
     Meta class for categories.
     """
     __slots__ = ()
-    _IGNORENAMES = ('__module__', '__name__')
+    _IGNORENAMES = ('__module__', '__name__', '__doc__')
     def _newSubclass(cls, name, bases, methods):
         return type.__new__(cls, name, bases, methods)
     _newSubclass = classmethod(_newSubclass)
 
     def __new__(cls, name, bases, methods):
         if len(bases) != 1:
-            raise TypeError, "Cannot have multiple inheritance with Categories"
+            raise TypeError("Cannot have multiple inheritance with Categories")
 
         c = bases[0].real_class
 
         if c.__name__ != name:
-            raise TypeError, "Category name must be same as class name"
+            raise TypeError("Category name must be same as class name")
+
+
+        m = [ x[1] for x in methods.iteritems() if x[0] not in cls._IGNORENAMES  and isinstance(x[1], (FunctionType, MethodType, selector, classmethod))]
+        vars = [ x for x in methods.iteritems() if x[0] not in cls._IGNORENAMES  and not isinstance(x[1], (FunctionType, MethodType, selector, classmethod))]
+        for k, v in vars:
+            if isinstance(v, ivar):
+                raise TypeError("Cannot add instance variables in a Category")
 
-        m = [ x[1] for x in methods.iteritems() if x[0] not in cls._IGNORENAMES ]
         classAddMethods(c, m)
+        for k, v in vars:
+            setattr(c, k, v)
         return c
 
 def Category(cls):

Modified: trunk/pyobjc/pyobjc-core/Lib/objc/test/test_methodedits.py
==============================================================================
--- trunk/pyobjc/pyobjc-core/Lib/objc/test/test_methodedits.py	(original)
+++ trunk/pyobjc/pyobjc-core/Lib/objc/test/test_methodedits.py	Sun May 10 04:30:42 2009
@@ -312,6 +312,48 @@
         BaseClassRedef.foo = foo
 
         self.assertEquals(obj.foo(), 3)
+
+    def testCategeryWithDocString (self):
+        class NSObjectCat (NSObject):
+            pass
+
+        class NSObjectCat (objc.Category(NSObjectCat)):
+            """
+            This is a docstring
+            """
+
+            def withDocStringMethod(self):
+                return 42
+
+        o = NSObjectCat.alloc().init()
+        self.failUnlessEqual(o.withDocStringMethod(), 42)
+
+    def testCategoryWithClassMethod(self):
+        class NSObjectCat2 (NSObject):
+            pass
+
+        class NSObjectCat2 (objc.Category(NSObjectCat2)):
+            @classmethod
+            def aClassMethod(cls):
+                return 1
+
+        self.failUnlessEqual(NSObjectCat2.aClassMethod(), 1)
+
+    def testCategoryWithVariables(self):
+        class NSObjectCat3 (NSObject):
+            pass
+
+        class NSObjectCat3 (objc.Category(NSObjectCat3)):
+            classValue = "aap"
+
+            def getClassValue(self):
+                return self.classValue
+
+
+        self.failUnless(hasattr(NSObjectCat3, "classValue"))
+        o = NSObjectCat3.alloc().init()
+        self.failUnlessEqual(o.getClassValue(), "aap")
+
                 
 
 

Modified: trunk/pyobjc/pyobjc-core/NEWS.txt
==============================================================================
--- trunk/pyobjc/pyobjc-core/NEWS.txt	(original)
+++ trunk/pyobjc/pyobjc-core/NEWS.txt	Sun May 10 04:30:42 2009
@@ -7,6 +7,24 @@
 Version 2.2 (...)
 -----------------
 
+- Improve handling of non-methods in objc.Category:
+
+  * The docstring of a category is now ignored
+
+  * You'll get an explict error exception when trying to add ``ivar``s to
+    a class
+
+  * It's now possible to add class attributes in a category::
+
+       class NSObject (objc.Category(NSObject)):
+           aClassDefault = [ 1, 2, 3 ]
+
+	   @classmethod
+	   def getDefault(cls):
+	       return cls.aClassDefault
+
+
+
 - Fixed support for ``FSRef`` and ``FSSpec`` structures. 
 
   * Transparently convert ``Carbon.File.FSRef`` and ``Carbon.File.FSSpec``

------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image 
processing features enabled. http://p.sf.net/sfu/kodak-com