mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00

svn+ssh://pythondev@svn.python.org/python/trunk ........ r60752 | mark.dickinson | 2008-02-12 22:31:59 +0100 (Tue, 12 Feb 2008) | 5 lines Implementation of Fraction.limit_denominator. Remove Fraction.to_continued_fraction and Fraction.from_continued_fraction ........ r60754 | mark.dickinson | 2008-02-12 22:40:53 +0100 (Tue, 12 Feb 2008) | 3 lines Revert change in r60712: turn alternate constructors back into classmethods instead of staticmethods. ........ r60755 | mark.dickinson | 2008-02-12 22:46:54 +0100 (Tue, 12 Feb 2008) | 4 lines Replace R=fractions.Fraction with F=fractions.Fraction in test_fractions.py. This should have been part of the name change from Rational to Fraction. ........ r60758 | georg.brandl | 2008-02-13 08:20:22 +0100 (Wed, 13 Feb 2008) | 3 lines #2063: correct order of utime and stime in os.times() result on Windows. ........ r60762 | jeffrey.yasskin | 2008-02-13 18:58:04 +0100 (Wed, 13 Feb 2008) | 7 lines Working on issue #1762: Brought ./python.exe -m timeit -s 'from fractions import Fraction; f = Fraction(3, 2)' 'isinstance(3, Fraction); isinstance(f, Fraction)' from 12.3 usec/loop to 3.44 usec/loop and ./python.exe -m timeit -s 'from fractions import Fraction' 'Fraction(3, 2)' from 48.8 usec to 23.6 usec by avoiding genexps and sets in __instancecheck__ and inlining the common case from __subclasscheck__. ........ r60765 | brett.cannon | 2008-02-13 20:15:44 +0100 (Wed, 13 Feb 2008) | 5 lines Fix --enable-universalsdk and its comment line so that zsh's flag completion works. Thanks to Jeroen Ruigrok van der Werven for the fix. ........ r60771 | kurt.kaiser | 2008-02-14 01:08:55 +0100 (Thu, 14 Feb 2008) | 2 lines Bring NEWS.txt up to date from check-in msgs. ........ r60772 | raymond.hettinger | 2008-02-14 02:08:02 +0100 (Thu, 14 Feb 2008) | 3 lines Update notes on Decimal. ........ r60773 | raymond.hettinger | 2008-02-14 03:41:22 +0100 (Thu, 14 Feb 2008) | 1 line Fix decimal repr which should have used single quotes like other reprs. ........ r60785 | jeffrey.yasskin | 2008-02-14 07:12:24 +0100 (Thu, 14 Feb 2008) | 11 lines Performance optimizations on Fraction's constructor. ./python.exe -m timeit -s 'from fractions import Fraction' 'Fraction(3)` 31.7 usec/loop -> 9.2 usec/loop ./python.exe -m timeit -s 'from fractions import Fraction' 'Fraction(3, 2)'` 27.7 usec/loop -> 9.32 usec/loop ./python.exe -m timeit -s 'from fractions import Fraction; f = Fraction(3, 2)' 'Fraction(f)' 31.9 usec/loop -> 14.3 usec/loop ........ r60786 | jeffrey.yasskin | 2008-02-14 08:49:25 +0100 (Thu, 14 Feb 2008) | 5 lines Change simple instances (in Fraction) of self.numerator and self.denominator to self._numerator and self._denominator. This speeds abs() up from 12.2us to 10.8us and trunc() from 2.07us to 1.11us. This doesn't change _add and friends because they're more complicated. ........
173 lines
5.4 KiB
Python
173 lines
5.4 KiB
Python
# Copyright 2007 Google, Inc. All Rights Reserved.
|
|
# Licensed to PSF under a Contributor Agreement.
|
|
|
|
"""Unit tests for abc.py."""
|
|
|
|
import sys
|
|
import unittest
|
|
from test import test_support
|
|
|
|
import abc
|
|
|
|
|
|
class TestABC(unittest.TestCase):
|
|
|
|
def test_abstractmethod_basics(self):
|
|
@abc.abstractmethod
|
|
def foo(self): pass
|
|
self.assertEqual(foo.__isabstractmethod__, True)
|
|
def bar(self): pass
|
|
self.assertEqual(hasattr(bar, "__isabstractmethod__"), False)
|
|
|
|
def test_abstractproperty_basics(self):
|
|
@abc.abstractproperty
|
|
def foo(self): pass
|
|
self.assertEqual(foo.__isabstractmethod__, True)
|
|
def bar(self): pass
|
|
self.assertEqual(hasattr(bar, "__isabstractmethod__"), False)
|
|
|
|
class C(metaclass=abc.ABCMeta):
|
|
@abc.abstractproperty
|
|
def foo(self): return 3
|
|
class D(C):
|
|
@property
|
|
def foo(self): return super().foo
|
|
self.assertEqual(D().foo, 3)
|
|
|
|
def test_abstractmethod_integration(self):
|
|
for abstractthing in [abc.abstractmethod, abc.abstractproperty]:
|
|
class C(metaclass=abc.ABCMeta):
|
|
@abstractthing
|
|
def foo(self): pass # abstract
|
|
def bar(self): pass # concrete
|
|
self.assertEqual(C.__abstractmethods__, {"foo"})
|
|
self.assertRaises(TypeError, C) # because foo is abstract
|
|
class D(C):
|
|
def bar(self): pass # concrete override of concrete
|
|
self.assertEqual(D.__abstractmethods__, {"foo"})
|
|
self.assertRaises(TypeError, D) # because foo is still abstract
|
|
class E(D):
|
|
def foo(self): pass
|
|
self.assertEqual(E.__abstractmethods__, set())
|
|
E() # now foo is concrete, too
|
|
class F(E):
|
|
@abstractthing
|
|
def bar(self): pass # abstract override of concrete
|
|
self.assertEqual(F.__abstractmethods__, {"bar"})
|
|
self.assertRaises(TypeError, F) # because bar is abstract now
|
|
|
|
def test_subclass_oldstyle_class(self):
|
|
class A:
|
|
__metaclass__ = abc.ABCMeta
|
|
class OldstyleClass:
|
|
pass
|
|
self.assertFalse(issubclass(OldstyleClass, A))
|
|
self.assertFalse(issubclass(A, OldstyleClass))
|
|
|
|
def test_registration_basics(self):
|
|
class A(metaclass=abc.ABCMeta):
|
|
pass
|
|
class B(object):
|
|
pass
|
|
b = B()
|
|
self.assertEqual(issubclass(B, A), False)
|
|
self.assertEqual(isinstance(b, A), False)
|
|
A.register(B)
|
|
self.assertEqual(issubclass(B, A), True)
|
|
self.assertEqual(isinstance(b, A), True)
|
|
class C(B):
|
|
pass
|
|
c = C()
|
|
self.assertEqual(issubclass(C, A), True)
|
|
self.assertEqual(isinstance(c, A), True)
|
|
|
|
def test_isinstance_invalidation(self):
|
|
class A(metaclass=abc.ABCMeta):
|
|
pass
|
|
class B:
|
|
pass
|
|
b = B()
|
|
self.assertEqual(isinstance(b, A), False)
|
|
A.register(B)
|
|
self.assertEqual(isinstance(b, A), True)
|
|
|
|
def test_registration_builtins(self):
|
|
class A(metaclass=abc.ABCMeta):
|
|
pass
|
|
A.register(int)
|
|
self.assertEqual(isinstance(42, A), True)
|
|
self.assertEqual(issubclass(int, A), True)
|
|
class B(A):
|
|
pass
|
|
B.register(str)
|
|
class C(str): pass
|
|
self.assertEqual(isinstance("", A), True)
|
|
self.assertEqual(issubclass(str, A), True)
|
|
self.assertEqual(issubclass(C, A), True)
|
|
|
|
def test_registration_edge_cases(self):
|
|
class A(metaclass=abc.ABCMeta):
|
|
pass
|
|
A.register(A) # should pass silently
|
|
class A1(A):
|
|
pass
|
|
self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed
|
|
class B(object):
|
|
pass
|
|
A1.register(B) # ok
|
|
A1.register(B) # should pass silently
|
|
class C(A):
|
|
pass
|
|
A.register(C) # should pass silently
|
|
self.assertRaises(RuntimeError, C.register, A) # cycles not allowed
|
|
C.register(B) # ok
|
|
|
|
def test_registration_transitiveness(self):
|
|
class A(metaclass=abc.ABCMeta):
|
|
pass
|
|
self.failUnless(issubclass(A, A))
|
|
class B(metaclass=abc.ABCMeta):
|
|
pass
|
|
self.failIf(issubclass(A, B))
|
|
self.failIf(issubclass(B, A))
|
|
class C(metaclass=abc.ABCMeta):
|
|
pass
|
|
A.register(B)
|
|
class B1(B):
|
|
pass
|
|
self.failUnless(issubclass(B1, A))
|
|
class C1(C):
|
|
pass
|
|
B1.register(C1)
|
|
self.failIf(issubclass(C, B))
|
|
self.failIf(issubclass(C, B1))
|
|
self.failUnless(issubclass(C1, A))
|
|
self.failUnless(issubclass(C1, B))
|
|
self.failUnless(issubclass(C1, B1))
|
|
C1.register(int)
|
|
class MyInt(int):
|
|
pass
|
|
self.failUnless(issubclass(MyInt, A))
|
|
self.failUnless(isinstance(42, A))
|
|
|
|
def test_all_new_methods_are_called(self):
|
|
class A(metaclass=abc.ABCMeta):
|
|
pass
|
|
class B(object):
|
|
counter = 0
|
|
def __new__(cls):
|
|
B.counter += 1
|
|
return super().__new__(cls)
|
|
class C(A, B):
|
|
pass
|
|
self.assertEqual(B.counter, 0)
|
|
C()
|
|
self.assertEqual(B.counter, 1)
|
|
|
|
|
|
def test_main():
|
|
test_support.run_unittest(TestABC)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|