File: test_class_jy.py

package info (click to toggle)
jython 2.5.3-16%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 43,772 kB
  • ctags: 106,434
  • sloc: python: 351,322; java: 216,349; xml: 1,584; sh: 330; perl: 114; ansic: 102; makefile: 45
file content (403 lines) | stat: -rw-r--r-- 13,547 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
"""Misc. class tests. These are more general class tests than CPython's
test_class which focuses on operators.

Made for Jython
"""
import __builtin__
import types
import unittest
from java.lang import Object
from test import test_support

class ClassGeneralTestCase(unittest.TestCase):

    TE_MSG = "can't set attributes of built-in/extension type 'str'"

    def test_dunder_module(self):
        self.assertEqual(str.__module__, '__builtin__')
        class Foo:
            pass
        Fu = types.ClassType('Fu', (), {})
        for cls in Foo, Fu:
            self.assert_('__module__' in cls.__dict__)
            self.assertEqual(cls.__module__, __name__)
            self.assertEqual(str(cls), '%s.%s' % (__name__, cls.__name__))
            self.assert_(repr(cls).startswith('<class %s.%s at' %
                                              (__name__, cls.__name__)))
            obj = cls()
            self.assert_(str(obj).startswith('<%s.%s instance at' %
                                             (__name__, cls.__name__)))

        class Bar(object):
            pass
        class Baz(Object):
            pass
        Bang = type('Bang', (), {})
        for cls in Bar, Baz, Bang:
            self.assert_('__module__' in cls.__dict__)
            self.assertEqual(cls.__module__, __name__)
            self.assertEqual(str(cls), "<class '%s.%s'>" % (__name__, cls.__name__))
            self.assertEqual(repr(cls), "<class '%s.%s'>" % (__name__, cls.__name__))
        self.assert_(str(Bar()).startswith('<%s.Bar object at' % __name__))
        self.assert_(str(Baz()).startswith("org.python.proxies.%s$Baz" % __name__))

    def test_builtin_attributes(self):
        for attr, val in dict(__name__='foo', __module__='bar', __dict__={},
                              __flags__=1, __base__=object,
                              __bases__=(unicode, object),
                              __mro__=(unicode, object)).iteritems():
            try:
                setattr(str, attr, val)
            except TypeError, te:
                self.assertEqual(str(te), self.TE_MSG)
            else:
                self.assert_(False,
                             'setattr str.%s expected a TypeError' % attr)
            try:
                delattr(str, attr)
            except TypeError, te:
                self.assertEqual(str(te), self.TE_MSG)
            else:
                self.assert_(False,
                             'delattr str.%s expected a TypeError' % attr)


    def test_attributes(self):
        class Foo(object):
            pass

        Foo.__name__ = 'Bar'
        self.assertEqual(Foo.__name__, 'Bar')
        try:
            del Foo.__name__
        except TypeError, te:
            self.assertEqual(str(te), "can't delete Bar.__name__")
        else:
            self.assert_(False, 'Expected a TypeError')

        Foo.__module__ = 'baz'
        self.assertEqual(Foo.__module__, 'baz')
        try:
            del Foo.__module__
        except TypeError, te:
            self.assertEqual(str(te), "can't delete Bar.__module__")
        else:
            self.assert_(False, 'Expected a TypeError')

        try:
            Foo.__dict__ = {}
        except AttributeError, ae:
            self.assertEqual(str(ae),
                             "attribute '__dict__' of 'type' objects is not "
                             "writable")
        else:
            self.assert_(False, 'Expected an AttributeError')
        try:
            del Foo.__dict__
        except AttributeError, ae:
            self.assertEqual(str(ae),
                             "attribute '__dict__' of 'type' objects is not "
                             "writable")
        else:
            self.assert_(False, 'Expected an AttributeError')

        for attr, val in dict(__flags__=1, __base__=object,
                              __bases__=(unicode, object),
                              __mro__=(unicode, object)).iteritems():
            try:
                setattr(str, attr, val)
            except TypeError, te:
                self.assertEqual(str(te), self.TE_MSG)
            else:
                self.assert_(False,
                             'setattr Foo.%s expected a TypeError' % attr)
            try:
                delattr(str, attr)
            except TypeError, te:
                self.assertEqual(str(te), self.TE_MSG)
            else:
                self.assert_(False,
                             'delattr Foo.%s expected a TypeError' % attr)

    def test_newstyle_new_classobj(self):
        # Ensure new.classobj can create new style classes
        class Foo(object):
            pass
        def hello(self):
            return 'hello'
        Bar = types.ClassType('Bar', (Foo,), dict(hello=hello))
        self.assert_(type(Bar), type)
        self.assert_(issubclass(Bar, Foo))
        self.assert_(hasattr(Bar, 'hello'))
        self.assertEquals(Bar().hello(), 'hello')

    def test_attribute_error_message(self):
        # Ensure that AttributeError matches the CPython message
        class Bar:
            pass
        try:
            Bar.bar
            self._assert(False) # The previous line should have raised
                                # AttributeError
        except AttributeError, e:
            self.assertEqual("class Bar has no attribute 'bar'", str(e))

        class Foo(object):
            pass
        try:
            Foo.bar
            self._assert(False) # The previous line should have raised
                                # AttributeError
        except AttributeError, e:
            self.assertEqual("type object 'Foo' has no attribute 'bar'",
                             str(e))

    def test_inner_class_dict(self):
        class z:
            class t:
                def moo(self):
                    pass
        # Printing this caused an NPE in Jython 2.1
        keys = list(z.t.__dict__)
        keys.sort()
        self.assertEqual(str(keys), "['__doc__', '__module__', 'moo']")

    def test_metaclass_and_slotted_base(self):
        class Meta(type):
            pass
        class SlottedBase(object):
            __slots__ = 'foo'
        # A regression up until 2.5a3: Defining Bar would cause a
        # TypeError "mro() returned base with unsuitable layout ('Bar')"
        class Bar(SlottedBase):
            __metaclass__ = Meta

    def test_slotted_diamond_problem_bug(self):
        class A(object):
            __slots__ = 'foo'
        class B(A):
            pass
        class C(A):
            pass
        # used to raise TypeError: multiple bases have instance lay-out
        # conflict
        class D(B, C):
            pass

    def test_getitem_exceptions(self):
        class A:
            def __getitem__(self, key):
                raise IndexError, "Fraid not"
        self.assertRaises(IndexError, A().__getitem__, 'b')

    def test_winning_metatype(self):
        class Meta(type):
            def __new__(cls, name, bases, attrs):
                attrs['spam'] = name
                attrs['counter'] = 0
                return type.__new__(cls, name, bases, attrs)
            def __init__(cls, name, bases, attrs):
                cls.counter += 1

        class Base(object):
            __metaclass__ = Meta
        Foo = type('Foo', (Base,), {})
        # Previously we called the wrong __new__
        self.assertEqual(Foo.spam, 'Foo')
        # and called __init__ twice
        self.assertEqual(Foo.counter, 1)

class ClassNamelessModuleTestCase(unittest.TestCase):

    def setUp(self):
        global __name__
        self.name = __name__
        del __name__

    def tearDown(self):
        global __name__
        __name__ = self.name

    def test_nameless_module(self):
        class Foo:
            pass
        self.assertEqual(Foo.__module__, '__builtin__')
        self.assertEqual(str(Foo), '__builtin__.Foo')
        self.assert_(repr(Foo).startswith('<class __builtin__.Foo at'))
        foo = Foo()
        self.assert_(str(foo).startswith('<__builtin__.Foo instance at'))

        class Bar(object):
            pass
        self.assertEqual(Bar.__module__, '__builtin__')
        self.assertEqual(str(Bar), "<class 'Bar'>")
        self.assertEqual(repr(Bar), "<class 'Bar'>")
        bar = Bar()
        self.assert_(str(bar).startswith('<Bar '))
        self.assert_(repr(bar).startswith('<Bar object at'))


class BrokenNameTestCase(unittest.TestCase):

    def setUp(self):
        global __name__
        self.name = __name__
        self.builtin_name = __builtin__.__name__
        del __name__
        del __builtin__.__name__

    def tearDown(self):
        global __name__
        __builtin__.__name__ = self.builtin_name
        __name__ = self.name

    def test_broken_name(self):
        try:
            class Foobar:
                pass
        except NameError:
            pass
        else:
            self.assert_(False, "Expected a NameError")


class ClassLocalsTestCase(unittest.TestCase):

    def test_class_locals(self):
        class Foo(object):
            pass

        class Bar(object):
            foo = Foo()
        self.assert_(not hasattr(Bar, 'Foo'))

        class Bar2(object):
            foo = Foo()
            locals()
        # Observer effect: Bar2 differs because we looked at
        # locals. This might be considered 'buggy' behavior; but it
        # matches CPython and Pypy. see below for an example
        self.assert_(hasattr(Bar2, 'Foo'))

    def test_class_locals_realworld(self):
        # A more real world test of the above situation, for reference
        class FieldGathererMeta(type):
            def __new__(meta, name, bases, class_dict):
                cls = type.__new__(meta, name, bases, class_dict)
                cls.fields = [field.upper() for field in class_dict.iterkeys() \
                                  if not field.startswith('_')]
                cls.fields.sort()
                return cls

        class SomeClass(object):
            pass

        class MyFields(object):
            __metaclass__ = FieldGathererMeta
            jython = 'foo'
            java = ('bar', SomeClass())
        # Technically SomeClass and FieldGathererMeta are actually
        # locals in the MyFields' class definition scope, but we expect
        # them to be omitted from its class_dict
        self.assertEqual(MyFields.fields, ['JAVA', 'JYTHON'])

        class MyFields2(object):
            __metaclass__ = FieldGathererMeta
            jython = 'foo'
            java = ('bar', SomeClass())
            locals()
        # Oops, locals() updates f_locals. Hilarity ensues
        self.assertEqual(MyFields2.fields, ['FIELDGATHERERMETA', 'JAVA',
                                            'JYTHON', 'SOMECLASS'])

    def test___doc__(self):
        class Test(object):
            """doc"""
            test = 'Test %s' % __doc__
        self.assertEqual(Test.test, 'Test doc')


class IsDescendentTestCase(unittest.TestCase):

    def test_newstyle_descendent_of_oldstyle(self):
        class NewStyle(object):
            pass
        class OldStyle:
            pass
        class Retro(NewStyle, OldStyle):
            pass
        self.assert_(issubclass(Retro, NewStyle))
        self.assert_(issubclass(Retro, OldStyle))
        retro = Retro()
        self.assert_(isinstance(retro, NewStyle))
        self.assert_(isinstance(retro, OldStyle))


class JavaClassNamingTestCase(unittest.TestCase):

    """Tests for PyJavaClass naming."""

    def test_java_class_name(self):
        # The __name__ and __module__ attributes of Java classes should
        # be set according to the same convention that Python uses.
        from java.lang import String
        self.assertEqual(String.__name__, "String")
        self.assertEqual(String.__module__, "java.lang")


module_name = __name__

class ClassDefinesDunderModule(unittest.TestCase):

    """Verifies http://bugs.jython.org/issue1022 is fixed"""

    def test_dundermodule_in_classdef(self):
        class Foo:
            self.assertEqual(__module__, module_name)
        class Bar(object):
            self.assertEqual(__module__, module_name)

    def test_dundermodule_in_class_dict_copy(self):
        class_dict = {'a': 'this is a', 'b': 'this is b'}
        Foo = type.__new__(type, 'Foo', (object,), class_dict)
        Foo.keys = class_dict.keys
        assert sorted(Foo().keys()) == sorted(['a', 'b']), sorted(Foo().keys())


class ClassMetaclassRepr(unittest.TestCase):

    def test_repr_with_metaclass(self):
        # http://bugs.jython.org/issue1131
        class FooMetaclass(type):
            def __new__(cls, name, bases, attrs):
                return super(FooMetaclass, cls).__new__(cls, name, bases, attrs)

        class Foo(object):
            __metaclass__ = FooMetaclass
        self.assertEqual("<class '%s.Foo'>" % __name__, repr(Foo))

    def test_metaclass_str(self):
        class Foo(type):
            def __repr__(cls):
                return 'foo'
        class Bar(object):
            __metaclass__ = Foo
        self.assertEqual(repr(Bar), 'foo')
        # type.__str__ previously broke this
        self.assertEqual(str(Bar), 'foo')


def test_main():
    test_support.run_unittest(
        ClassGeneralTestCase,
        ClassNamelessModuleTestCase,
        BrokenNameTestCase,
        ClassLocalsTestCase,
        IsDescendentTestCase,
        JavaClassNamingTestCase,
        ClassDefinesDunderModule,
        ClassMetaclassRepr)


if __name__ == "__main__":
    test_main()