You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
7.9 KiB

Merged revisions 61038,61042-61045,61047,61050,61053,61055-61056,61061-61062,61066,61068,61070,61083,61085,61092-61103 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r61098 | jeffrey.yasskin | 2008-02-28 05:45:36 +0100 (Thu, 28 Feb 2008) | 7 lines Move abc._Abstract into object by adding a new flag Py_TPFLAGS_IS_ABSTRACT, which forbids constructing types that have it set. The effect is to speed ./python.exe -m timeit -s 'import abc' -s 'class Foo(object): __metaclass__ = abc.ABCMeta' 'Foo()' up from 2.5us to 0.201us. This fixes issue 1762. ........ r61099 | jeffrey.yasskin | 2008-02-28 06:53:18 +0100 (Thu, 28 Feb 2008) | 3 lines Speed test_socketserver up from 28.739s to 0.226s, simplify the logic, and make sure all tests run even if some fail. ........ r61100 | jeffrey.yasskin | 2008-02-28 07:09:19 +0100 (Thu, 28 Feb 2008) | 21 lines Thread.start() used sleep(0.000001) to make sure it didn't return before the new thread had started. At least on my MacBook Pro, that wound up sleeping for a full 10ms (probably 1 jiffy). By using an Event instead, we can be absolutely certain that the thread has started, and return more quickly (217us). Before: $ ./python.exe -m timeit -s 'from threading import Thread' 't = Thread(); t.start(); t.join()' 100 loops, best of 3: 10.3 msec per loop $ ./python.exe -m timeit -s 'from threading import Thread; t = Thread()' 't.isAlive()' 1000000 loops, best of 3: 0.47 usec per loop After: $ ./python.exe -m timeit -s 'from threading import Thread' 't = Thread(); t.start(); t.join()' 1000 loops, best of 3: 217 usec per loop $ ./python.exe -m timeit -s 'from threading import Thread; t = Thread()' 't.isAlive()' 1000000 loops, best of 3: 0.86 usec per loop To be fair, the 10ms isn't CPU time, and other threads including the spawned one get to run during it. There are also some slightly more complicated ways to get back the .4us in isAlive() if we want. ........ r61101 | raymond.hettinger | 2008-02-28 10:23:48 +0100 (Thu, 28 Feb 2008) | 1 line Add repeat keyword argument to itertools.product(). ........ r61102 | christian.heimes | 2008-02-28 12:18:49 +0100 (Thu, 28 Feb 2008) | 1 line The empty tuple is usually a singleton with a much higher refcnt than 1 ........
18 years ago
Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60766,60769-60786 via svnmerge from 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. ........
18 years ago
  1. # Copyright 2007 Google, Inc. All Rights Reserved.
  2. # Licensed to PSF under a Contributor Agreement.
  3. """Abstract Base Classes (ABCs) according to PEP 3119."""
  4. from _weakrefset import WeakSet
  5. def abstractmethod(funcobj):
  6. """A decorator indicating abstract methods.
  7. Requires that the metaclass is ABCMeta or derived from it. A
  8. class that has a metaclass derived from ABCMeta cannot be
  9. instantiated unless all of its abstract methods are overridden.
  10. The abstract methods can be called using any of the normal
  11. 'super' call mechanisms.
  12. Usage:
  13. class C(metaclass=ABCMeta):
  14. @abstractmethod
  15. def my_abstract_method(self, ...):
  16. ...
  17. """
  18. funcobj.__isabstractmethod__ = True
  19. return funcobj
  20. class abstractclassmethod(classmethod):
  21. """
  22. A decorator indicating abstract classmethods.
  23. Similar to abstractmethod.
  24. Usage:
  25. class C(metaclass=ABCMeta):
  26. @abstractclassmethod
  27. def my_abstract_classmethod(cls, ...):
  28. ...
  29. 'abstractclassmethod' is deprecated. Use 'classmethod' with
  30. 'abstractmethod' instead.
  31. """
  32. __isabstractmethod__ = True
  33. def __init__(self, callable):
  34. callable.__isabstractmethod__ = True
  35. super().__init__(callable)
  36. class abstractstaticmethod(staticmethod):
  37. """
  38. A decorator indicating abstract staticmethods.
  39. Similar to abstractmethod.
  40. Usage:
  41. class C(metaclass=ABCMeta):
  42. @abstractstaticmethod
  43. def my_abstract_staticmethod(...):
  44. ...
  45. 'abstractstaticmethod' is deprecated. Use 'staticmethod' with
  46. 'abstractmethod' instead.
  47. """
  48. __isabstractmethod__ = True
  49. def __init__(self, callable):
  50. callable.__isabstractmethod__ = True
  51. super().__init__(callable)
  52. class abstractproperty(property):
  53. """
  54. A decorator indicating abstract properties.
  55. Requires that the metaclass is ABCMeta or derived from it. A
  56. class that has a metaclass derived from ABCMeta cannot be
  57. instantiated unless all of its abstract properties are overridden.
  58. The abstract properties can be called using any of the normal
  59. 'super' call mechanisms.
  60. Usage:
  61. class C(metaclass=ABCMeta):
  62. @abstractproperty
  63. def my_abstract_property(self):
  64. ...
  65. This defines a read-only property; you can also define a read-write
  66. abstract property using the 'long' form of property declaration:
  67. class C(metaclass=ABCMeta):
  68. def getx(self): ...
  69. def setx(self, value): ...
  70. x = abstractproperty(getx, setx)
  71. 'abstractproperty' is deprecated. Use 'property' with 'abstractmethod'
  72. instead.
  73. """
  74. __isabstractmethod__ = True
  75. class ABCMeta(type):
  76. """Metaclass for defining Abstract Base Classes (ABCs).
  77. Use this metaclass to create an ABC. An ABC can be subclassed
  78. directly, and then acts as a mix-in class. You can also register
  79. unrelated concrete classes (even built-in classes) and unrelated
  80. ABCs as 'virtual subclasses' -- these and their descendants will
  81. be considered subclasses of the registering ABC by the built-in
  82. issubclass() function, but the registering ABC won't show up in
  83. their MRO (Method Resolution Order) nor will method
  84. implementations defined by the registering ABC be callable (not
  85. even via super()).
  86. """
  87. # A global counter that is incremented each time a class is
  88. # registered as a virtual subclass of anything. It forces the
  89. # negative cache to be cleared before its next use.
  90. _abc_invalidation_counter = 0
  91. def __new__(mcls, name, bases, namespace):
  92. cls = super().__new__(mcls, name, bases, namespace)
  93. # Compute set of abstract method names
  94. abstracts = {name
  95. for name, value in namespace.items()
  96. if getattr(value, "__isabstractmethod__", False)}
  97. for base in bases:
  98. for name in getattr(base, "__abstractmethods__", set()):
  99. value = getattr(cls, name, None)
  100. if getattr(value, "__isabstractmethod__", False):
  101. abstracts.add(name)
  102. cls.__abstractmethods__ = frozenset(abstracts)
  103. # Set up inheritance registry
  104. cls._abc_registry = WeakSet()
  105. cls._abc_cache = WeakSet()
  106. cls._abc_negative_cache = WeakSet()
  107. cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
  108. return cls
  109. def register(cls, subclass):
  110. """Register a virtual subclass of an ABC.
  111. Returns the subclass, to allow usage as a class decorator.
  112. """
  113. if not isinstance(subclass, type):
  114. raise TypeError("Can only register classes")
  115. if issubclass(subclass, cls):
  116. return subclass # Already a subclass
  117. # Subtle: test for cycles *after* testing for "already a subclass";
  118. # this means we allow X.register(X) and interpret it as a no-op.
  119. if issubclass(cls, subclass):
  120. # This would create a cycle, which is bad for the algorithm below
  121. raise RuntimeError("Refusing to create an inheritance cycle")
  122. cls._abc_registry.add(subclass)
  123. ABCMeta._abc_invalidation_counter += 1 # Invalidate negative cache
  124. return subclass
  125. def _dump_registry(cls, file=None):
  126. """Debug helper to print the ABC registry."""
  127. print("Class: %s.%s" % (cls.__module__, cls.__name__), file=file)
  128. print("Inv.counter: %s" % ABCMeta._abc_invalidation_counter, file=file)
  129. for name in sorted(cls.__dict__.keys()):
  130. if name.startswith("_abc_"):
  131. value = getattr(cls, name)
  132. print("%s: %r" % (name, value), file=file)
  133. def __instancecheck__(cls, instance):
  134. """Override for isinstance(instance, cls)."""
  135. # Inline the cache checking
  136. subclass = instance.__class__
  137. if subclass in cls._abc_cache:
  138. return True
  139. subtype = type(instance)
  140. if subtype is subclass:
  141. if (cls._abc_negative_cache_version ==
  142. ABCMeta._abc_invalidation_counter and
  143. subclass in cls._abc_negative_cache):
  144. return False
  145. # Fall back to the subclass check.
  146. return cls.__subclasscheck__(subclass)
  147. return any(cls.__subclasscheck__(c) for c in {subclass, subtype})
  148. def __subclasscheck__(cls, subclass):
  149. """Override for issubclass(subclass, cls)."""
  150. # Check cache
  151. if subclass in cls._abc_cache:
  152. return True
  153. # Check negative cache; may have to invalidate
  154. if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
  155. # Invalidate the negative cache
  156. cls._abc_negative_cache = WeakSet()
  157. cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
  158. elif subclass in cls._abc_negative_cache:
  159. return False
  160. # Check the subclass hook
  161. ok = cls.__subclasshook__(subclass)
  162. if ok is not NotImplemented:
  163. assert isinstance(ok, bool)
  164. if ok:
  165. cls._abc_cache.add(subclass)
  166. else:
  167. cls._abc_negative_cache.add(subclass)
  168. return ok
  169. # Check if it's a direct subclass
  170. if cls in getattr(subclass, '__mro__', ()):
  171. cls._abc_cache.add(subclass)
  172. return True
  173. # Check if it's a subclass of a registered class (recursive)
  174. for rcls in cls._abc_registry:
  175. if issubclass(subclass, rcls):
  176. cls._abc_cache.add(subclass)
  177. return True
  178. # Check if it's a subclass of a subclass (recursive)
  179. for scls in cls.__subclasses__():
  180. if issubclass(subclass, scls):
  181. cls._abc_cache.add(subclass)
  182. return True
  183. # No dice; update negative cache
  184. cls._abc_negative_cache.add(subclass)
  185. return False