source: packages/vanilla/trunk/Lib/vanilla/nsSubclasses.py @ 1

Revision 1, 2.8 KB checked in by tal, 6 years ago (diff)
initial import
Line 
1import objc
2import weakref
3
4
5class _VanillaMethods:
6
7    def __new__(cls, wrapper):
8        self = cls.alloc().init()
9        self.setVanillaWrapper_(wrapper)
10        return self
11
12    def setVanillaWrapper_(self, wrapper):
13        self._wrapperRef = weakref.ref(wrapper)
14        return self
15
16    def vanillaWrapper(self):
17        try:
18            return self._wrapperRef()
19        except AttributeError:
20            return None
21
22
23_subclasses = {}
24def getNSSubclass(classOrName=None):
25    """Return a subclass of a given Objective-C class.
26    This subclass allows us to store a weakref to a Vanilla wrapper
27    object. This way we can always get back at it. Mainly meant to
28    translate "sender" arguments of action methods to a Vanilla object.
29
30    The returned subclass can be instantiated from Python like this:
31
32        >>> class Wrapper(object): pass
33        ...
34        >>> wrpr = Wrapper()
35        >>> view = getNSSubclass("NSBox")(wrpr)
36        >>> view.vanillaWrapper() is wrpr
37        True
38
39        >>> from Foundation import NSObject
40        >>> class MyCustomNSClass(NSObject): pass
41        ...
42        >>> view = getNSSubclass(MyCustomNSClass)(wrpr)
43        >>> view.vanillaWrapper() is wrpr
44        True
45
46    """
47    subCls = None
48    if isinstance(classOrName, basestring):
49        cls = objc.lookUpClass(classOrName)
50        className = classOrName
51    else:
52        cls = classOrName
53        className = cls.__name__
54    subCls = _subclasses.get(className)
55    if subCls is None:
56        vName = "V" + className
57        subCls = cls.__class__(vName, (cls,), _VanillaMethods.__dict__.copy())
58        _subclasses[className] = subCls
59    return subCls
60
61
62def _doctest():
63    """
64        >>> from AppKit import NSTextView
65        >>> sc = getNSSubclass('NSTextView')
66        >>> sc.__name__
67        'VNSTextView'
68        >>> issubclass(sc, NSTextView)
69        True
70        >>> hasattr(sc, 'setVanillaWrapper_')
71        True
72        >>> hasattr(sc, 'vanillaWrapper')
73        True
74        >>> # duplicate test to test caching
75        >>> sc = getNSSubclass('NSTextView')
76        >>> sc.__name__
77        'VNSTextView'
78        >>> issubclass(sc, NSTextView)
79        True
80        >>> class Wrapper(object): pass
81        ...
82        >>> wrpr = Wrapper()
83        >>> isinstance(sc(wrpr), NSTextView)
84        True
85        >>> # test custom class
86        >>> from Foundation import NSObject
87        >>> class TestClass(NSObject): pass
88        ...
89        >>> sc = getNSSubclass(TestClass)
90        >>> sc.__name__
91        'VTestClass'
92        >>> isinstance(sc(wrpr), NSObject)
93        True
94        >>> isinstance(sc(wrpr), TestClass)
95        True
96        >>> hasattr(sc, 'setVanillaWrapper_')
97        True
98        >>> hasattr(sc, 'vanillaWrapper')
99        True
100    """
101
102if __name__ == "__main__":
103    import doctest
104    doctest.testmod()
Note: See TracBrowser for help on using the repository browser.