/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test__static_tuple.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2020-08-23 01:15:41 UTC
  • mfrom: (7520.1.4 merge-3.1)
  • Revision ID: breezy.the.bot@gmail.com-20200823011541-nv0oh7nzaganx2qy
Merge lp:brz/3.1.

Merged from https://code.launchpad.net/~jelmer/brz/merge-3.1/+merge/389690

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2009, 2010, 2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
"""Tests for the StaticTuple type."""
18
18
 
19
 
import cPickle
20
 
import gc
 
19
try:
 
20
    import cPickle as pickle
 
21
except ImportError:
 
22
    import pickle
 
23
import operator
21
24
import sys
22
25
 
23
 
from bzrlib import (
 
26
from breezy import (
24
27
    _static_tuple_py,
25
28
    debug,
26
 
    errors,
27
29
    osutils,
28
30
    static_tuple,
29
31
    tests,
30
32
    )
31
 
 
32
 
 
33
 
def load_tests(standard_tests, module, loader):
 
33
from breezy.tests import (
 
34
    features,
 
35
    )
 
36
 
 
37
 
 
38
def load_tests(loader, standard_tests, pattern):
34
39
    """Parameterize tests for all versions of groupcompress."""
35
40
    global compiled_static_tuple_feature
36
41
    suite, compiled_static_tuple_feature = tests.permute_tests_for_extension(
37
 
        standard_tests, loader, 'bzrlib._static_tuple_py',
38
 
        'bzrlib._static_tuple_c')
 
42
        standard_tests, loader, 'breezy._static_tuple_py',
 
43
        'breezy._static_tuple_c')
39
44
    return suite
40
45
 
41
46
 
42
 
class _Meliae(tests.Feature):
43
 
 
44
 
    def _probe(self):
45
 
        try:
46
 
            from meliae import scanner
47
 
        except ImportError:
48
 
            return False
49
 
        return True
50
 
 
51
 
    def feature_name(self):
52
 
        return "Meliae - python memory debugger"
53
 
 
54
 
Meliae = _Meliae()
55
 
 
56
 
 
57
47
class TestStaticTuple(tests.TestCase):
58
48
 
59
49
    def assertRefcount(self, count, obj):
68
58
        # self.assertEqual(count, sys.getrefcount(obj)-1)
69
59
        # Then it works fine. Something about passing it to assertRefcount is
70
60
        # actually double-incrementing (and decrementing) the refcount
71
 
        self.assertEqual(count, sys.getrefcount(obj)-3)
 
61
        self.assertEqual(count, sys.getrefcount(obj) - 3)
72
62
 
73
63
    def test_create(self):
74
64
        k = self.module.StaticTuple('foo')
75
65
        k = self.module.StaticTuple('foo', 'bar')
76
66
 
77
67
    def test_create_bad_args(self):
78
 
        args_256 = ['a']*256
 
68
        args_256 = ['a'] * 256
79
69
        # too many args
80
70
        self.assertRaises(TypeError, self.module.StaticTuple, *args_256)
81
 
        args_300 = ['a']*300
 
71
        args_300 = ['a'] * 300
82
72
        self.assertRaises(TypeError, self.module.StaticTuple, *args_300)
83
73
        # not a string
84
74
        self.assertRaises(TypeError, self.module.StaticTuple, object())
118
108
    def test_concat_with_non_tuple(self):
119
109
        st1 = self.module.StaticTuple('foo')
120
110
        self.assertRaises(TypeError, lambda: st1 + 10)
121
 
        
 
111
 
122
112
    def test_as_tuple(self):
123
113
        k = self.module.StaticTuple('foo')
124
114
        t = k.as_tuple()
161
151
        self.assertEqual(2, len(k))
162
152
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'b')
163
153
        self.assertEqual(7, len(k))
164
 
        args = ['foo']*255
 
154
        args = ['foo'] * 255
165
155
        k = self.module.StaticTuple(*args)
166
156
        self.assertEqual(255, len(k))
167
157
 
180
170
        self.assertEqual('z', k[6])
181
171
        self.assertEqual('z', k[-1])
182
172
        self.assertRaises(IndexError, k.__getitem__, 7)
183
 
        self.assertRaises(IndexError, k.__getitem__, 256+7)
 
173
        self.assertRaises(IndexError, k.__getitem__, 256 + 7)
184
174
        self.assertRaises(IndexError, k.__getitem__, 12024)
185
175
        # Python's [] resolver handles the negative arguments, so we can't
186
176
        # really test StaticTuple_item() with negative values.
189
179
 
190
180
    def test_refcount(self):
191
181
        f = 'fo' + 'oo'
192
 
        num_refs = sys.getrefcount(f) - 1 #sys.getrefcount() adds one
 
182
        num_refs = sys.getrefcount(f) - 1  # sys.getrefcount() adds one
193
183
        k = self.module.StaticTuple(f)
194
184
        self.assertRefcount(num_refs + 1, f)
195
185
        b = k[0]
221
211
 
222
212
    def test_holds_int(self):
223
213
        k1 = self.module.StaticTuple(1)
 
214
 
224
215
        class subint(int):
225
216
            pass
226
217
        # But not a subclass, because subint could introduce refcycles
227
218
        self.assertRaises(TypeError, self.module.StaticTuple, subint(2))
228
219
 
229
 
    def test_holds_long(self):
230
 
        k1 = self.module.StaticTuple(2L**65)
231
 
        class sublong(long):
232
 
            pass
233
 
        # But not a subclass
234
 
        self.assertRaises(TypeError, self.module.StaticTuple, sublong(1))
235
 
 
236
220
    def test_holds_float(self):
237
221
        k1 = self.module.StaticTuple(1.2)
 
222
 
238
223
        class subfloat(float):
239
224
            pass
240
225
        self.assertRaises(TypeError, self.module.StaticTuple, subfloat(1.5))
241
226
 
242
 
    def test_holds_str(self):
243
 
        k1 = self.module.StaticTuple('astring')
244
 
        class substr(str):
 
227
    def test_holds_bytes(self):
 
228
        k1 = self.module.StaticTuple(b'astring')
 
229
 
 
230
        class substr(bytes):
245
231
            pass
246
 
        self.assertRaises(TypeError, self.module.StaticTuple, substr('a'))
 
232
        self.assertRaises(TypeError, self.module.StaticTuple, substr(b'a'))
247
233
 
248
234
    def test_holds_unicode(self):
249
235
        k1 = self.module.StaticTuple(u'\xb5')
250
 
        class subunicode(unicode):
 
236
 
 
237
        class subunicode(str):
251
238
            pass
252
239
        self.assertRaises(TypeError, self.module.StaticTuple,
253
240
                          subunicode(u'\xb5'))
292
279
        k6 = self.module.StaticTuple(k3, k4)
293
280
        self.assertCompareEqual(k5, k6)
294
281
 
295
 
    def assertCompareDifferent(self, k_small, k_big):
 
282
    def check_strict_compare(self, k1, k2, mismatched_types):
 
283
        """True if on Python 3 and stricter comparison semantics are used."""
 
284
        if mismatched_types:
 
285
            for op in ("ge", "gt", "le", "lt"):
 
286
                self.assertRaises(TypeError, getattr(operator, op), k1, k2)
 
287
            return True
 
288
        return False
 
289
 
 
290
    def assertCompareDifferent(self, k_small, k_big, mismatched_types=False):
296
291
        self.assertFalse(k_small == k_big)
297
 
        self.assertFalse(k_small >= k_big)
298
 
        self.assertFalse(k_small > k_big)
299
292
        self.assertTrue(k_small != k_big)
300
 
        self.assertTrue(k_small <= k_big)
301
 
        self.assertTrue(k_small < k_big)
 
293
        if not self.check_strict_compare(k_small, k_big, mismatched_types):
 
294
            self.assertFalse(k_small >= k_big)
 
295
            self.assertFalse(k_small > k_big)
 
296
            self.assertTrue(k_small <= k_big)
 
297
            self.assertTrue(k_small < k_big)
302
298
 
303
 
    def assertCompareNoRelation(self, k1, k2):
 
299
    def assertCompareNoRelation(self, k1, k2, mismatched_types=False):
304
300
        """Run the comparison operators, make sure they do something.
305
301
 
306
302
        However, we don't actually care what comes first or second. This is
309
305
        """
310
306
        self.assertFalse(k1 == k2)
311
307
        self.assertTrue(k1 != k2)
312
 
        # Do the comparison, but we don't care about the result
313
 
        k1 >= k2
314
 
        k1 > k2
315
 
        k1 <= k2
316
 
        k1 < k2
 
308
        if not self.check_strict_compare(k1, k2, mismatched_types):
 
309
            # Do the comparison, but we don't care about the result
 
310
            k1 >= k2
 
311
            k1 > k2
 
312
            k1 <= k2
 
313
            k1 < k2
317
314
 
318
315
    def test_compare_vs_none(self):
319
316
        k1 = self.module.StaticTuple('baz', 'bing')
320
 
        self.assertCompareDifferent(None, k1)
321
 
    
 
317
        self.assertCompareDifferent(None, k1, mismatched_types=True)
 
318
 
322
319
    def test_compare_cross_class(self):
323
320
        k1 = self.module.StaticTuple('baz', 'bing')
324
 
        self.assertCompareNoRelation(10, k1)
325
 
        self.assertCompareNoRelation('baz', k1)
 
321
        self.assertCompareNoRelation(10, k1, mismatched_types=True)
 
322
        self.assertCompareNoRelation('baz', k1, mismatched_types=True)
326
323
 
327
324
    def test_compare_all_different_same_width(self):
328
325
        k1 = self.module.StaticTuple('baz', 'bing')
349
346
        k4 = self.module.StaticTuple(k1, k2)
350
347
        self.assertCompareDifferent(k3, k4)
351
348
        k5 = self.module.StaticTuple('foo', None)
352
 
        self.assertCompareDifferent(k5, k1)
353
 
        self.assertCompareDifferent(k5, k2)
 
349
        self.assertCompareDifferent(k5, k1, mismatched_types=True)
 
350
        self.assertCompareDifferent(k5, k2, mismatched_types=True)
354
351
 
355
352
    def test_compare_diff_width(self):
356
353
        k1 = self.module.StaticTuple('foo')
364
361
        k1 = self.module.StaticTuple('foo', 'bar')
365
362
        k2 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
366
363
                                     k1)
367
 
        self.assertCompareNoRelation(k1, k2)
 
364
        self.assertCompareNoRelation(k1, k2, mismatched_types=True)
368
365
        k3 = self.module.StaticTuple('foo')
369
366
        self.assertCompareDifferent(k3, k1)
370
367
        k4 = self.module.StaticTuple(None)
371
 
        self.assertCompareDifferent(k4, k1)
 
368
        self.assertCompareDifferent(k4, k1, mismatched_types=True)
372
369
        k5 = self.module.StaticTuple(1)
373
 
        self.assertCompareNoRelation(k1, k5)
 
370
        self.assertCompareNoRelation(k1, k5, mismatched_types=True)
374
371
 
375
372
    def test_compare_to_tuples(self):
376
373
        k1 = self.module.StaticTuple('foo')
386
383
        self.assertCompareDifferent(('foo',), k2)
387
384
        self.assertCompareDifferent(('foo', 'aaa'), k2)
388
385
        self.assertCompareDifferent(('baz', 'bing'), k2)
389
 
        self.assertCompareDifferent(('foo', 10), k2)
 
386
        self.assertCompareDifferent(('foo', 10), k2, mismatched_types=True)
390
387
 
391
388
        k3 = self.module.StaticTuple(k1, k2)
392
389
        self.assertCompareEqual(k3, (('foo',), ('foo', 'bar')))
402
399
        # This requires comparing a StaticTuple to a 'string', and then
403
400
        # interpreting that value in the next higher StaticTuple. This used to
404
401
        # generate a PyErr_BadIternalCall. We now fall back to *something*.
405
 
        self.assertCompareNoRelation(k1, k2)
 
402
        self.assertCompareNoRelation(k1, k2, mismatched_types=True)
406
403
 
407
404
    def test_hash(self):
408
405
        k = self.module.StaticTuple('foo')
430
427
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
431
428
        self.assertEqual(('foo', 'bar'), k[:2])
432
429
        self.assertEqual(('baz',), k[2:-1])
433
 
        try:
434
 
            val = k[::2]
435
 
        except TypeError:
436
 
            # C implementation raises a TypeError, we don't need the
437
 
            # implementation yet, so allow this to pass
438
 
            pass
439
 
        else:
440
 
            # Python implementation uses a regular Tuple, so make sure it gives
441
 
            # the right result
442
 
            self.assertEqual(('foo', 'baz'), val)
 
430
        self.assertEqual(('foo', 'baz',), k[::2])
 
431
        self.assertRaises(TypeError, k.__getitem__, 'not_slice')
443
432
 
444
433
    def test_referents(self):
445
434
        # We implement tp_traverse so that things like 'meliae' can measure the
446
435
        # amount of referenced memory. Unfortunately gc.get_referents() first
447
436
        # checks the IS_GC flag before it traverses anything. We could write a
448
437
        # helper func, but that won't work for the generic implementation...
449
 
        self.requireFeature(Meliae)
 
438
        self.requireFeature(features.meliae)
450
439
        from meliae import scanner
451
440
        strs = ['foo', 'bar', 'baz', 'bing']
452
441
        k = self.module.StaticTuple(*strs)
454
443
            refs = strs + [self.module.StaticTuple]
455
444
        else:
456
445
            refs = strs
457
 
        self.assertEqual(sorted(refs), sorted(scanner.get_referents(k)))
 
446
        def key(k):
 
447
            if isinstance(k, type):
 
448
                return (0, k)
 
449
            if isinstance(k, str):
 
450
                return (1, k)
 
451
            raise TypeError(k)
 
452
        self.assertEqual(
 
453
            sorted(refs, key=key),
 
454
            sorted(scanner.get_referents(k), key=key))
458
455
 
459
456
    def test_nested_referents(self):
460
 
        self.requireFeature(Meliae)
 
457
        self.requireFeature(features.meliae)
461
458
        from meliae import scanner
462
459
        strs = ['foo', 'bar', 'baz', 'bing']
463
460
        k1 = self.module.StaticTuple(*strs[:2])
466
463
        refs = [k1, k2]
467
464
        if self.module is _static_tuple_py:
468
465
            refs.append(self.module.StaticTuple)
469
 
        self.assertEqual(sorted(refs),
470
 
                         sorted(scanner.get_referents(k3)))
 
466
        def key(k):
 
467
            if isinstance(k, type):
 
468
                return (0, k)
 
469
            if isinstance(k, self.module.StaticTuple):
 
470
                return (1, k)
 
471
            raise TypeError(k)
 
472
 
 
473
        self.assertEqual(sorted(refs, key=key),
 
474
                         sorted(scanner.get_referents(k3), key=key))
471
475
 
472
476
    def test_empty_is_singleton(self):
473
477
        key = self.module.StaticTuple()
490
494
 
491
495
    def test__c_intern_handles_refcount(self):
492
496
        if self.module is _static_tuple_py:
493
 
            return # Not applicable
 
497
            return  # Not applicable
494
498
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
495
499
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
496
500
        key = self.module.StaticTuple(unique_str1, unique_str2)
525
529
 
526
530
    def test__c_keys_are_not_immortal(self):
527
531
        if self.module is _static_tuple_py:
528
 
            return # Not applicable
 
532
            return  # Not applicable
529
533
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
530
534
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
531
535
        key = self.module.StaticTuple(unique_str1, unique_str2)
596
600
 
597
601
    def test_pickle(self):
598
602
        st = self.module.StaticTuple('foo', 'bar')
599
 
        pickled = cPickle.dumps(st)
600
 
        unpickled = cPickle.loads(pickled)
 
603
        pickled = pickle.dumps(st)
 
604
        unpickled = pickle.loads(pickled)
601
605
        self.assertEqual(unpickled, st)
602
606
 
603
607
    def test_pickle_empty(self):
604
608
        st = self.module.StaticTuple()
605
 
        pickled = cPickle.dumps(st)
606
 
        unpickled = cPickle.loads(pickled)
 
609
        pickled = pickle.dumps(st)
 
610
        unpickled = pickle.loads(pickled)
607
611
        self.assertIs(st, unpickled)
608
612
 
609
613
    def test_pickle_nested(self):
610
614
        st = self.module.StaticTuple('foo', self.module.StaticTuple('bar'))
611
 
        pickled = cPickle.dumps(st)
612
 
        unpickled = cPickle.loads(pickled)
 
615
        pickled = pickle.dumps(st)
 
616
        unpickled = pickle.loads(pickled)
613
617
        self.assertEqual(unpickled, st)
614
618
 
615
619
    def test_static_tuple_thunk(self):
616
620
        # Make sure the right implementation is available from
617
 
        # bzrlib.static_tuple.StaticTuple.
 
621
        # breezy.static_tuple.StaticTuple.
618
622
        if self.module is _static_tuple_py:
619
623
            if compiled_static_tuple_feature.available():
620
624
                # We will be using the C version