]> granicus.if.org Git - python/commitdiff
asyncio: Add asyncio.compat module
authorVictor Stinner <victor.stinner@gmail.com>
Sat, 25 Jul 2015 00:23:21 +0000 (02:23 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Sat, 25 Jul 2015 00:23:21 +0000 (02:23 +0200)
Move compatibility helpers for the different Python versions to a new
asyncio.compat module.

Lib/asyncio/compat.py [new file with mode: 0644]
Lib/asyncio/coroutines.py
Lib/asyncio/events.py
Lib/asyncio/futures.py
Lib/asyncio/locks.py
Lib/asyncio/streams.py
Lib/asyncio/tasks.py
Lib/asyncio/transports.py

diff --git a/Lib/asyncio/compat.py b/Lib/asyncio/compat.py
new file mode 100644 (file)
index 0000000..660b7e7
--- /dev/null
@@ -0,0 +1,17 @@
+"""Compatibility helpers for the different Python versions."""
+
+import sys
+
+PY34 = sys.version_info >= (3, 4)
+PY35 = sys.version_info >= (3, 5)
+
+
+def flatten_list_bytes(list_of_data):
+    """Concatenate a sequence of bytes-like objects."""
+    if not PY34:
+        # On Python 3.3 and older, bytes.join() doesn't handle
+        # memoryview.
+        list_of_data = (
+            bytes(data) if isinstance(data, memoryview) else data
+            for data in list_of_data)
+    return b''.join(list_of_data)
index 15475f23b410b3579067bbf06237b4d80e8ba6ca..e11b21b09754b40e0aa91da9aee3fd296599670f 100644 (file)
@@ -9,14 +9,12 @@ import sys
 import traceback
 import types
 
+from . import compat
 from . import events
 from . import futures
 from .log import logger
 
 
-_PY35 = sys.version_info >= (3, 5)
-
-
 # Opcode of "yield from" instruction
 _YIELD_FROM = opcode.opmap['YIELD_FROM']
 
@@ -140,7 +138,7 @@ class CoroWrapper:
     def gi_code(self):
         return self.gen.gi_code
 
-    if _PY35:
+    if compat.PY35:
 
         __await__ = __iter__ # make compatible with 'await' expression
 
index 496075bacf36465a35254ed8beca579c0d857c66..d5f0d4519513cc6d05bc5fe8fe86061d02ade26d 100644 (file)
@@ -17,12 +17,11 @@ import sys
 import threading
 import traceback
 
-
-_PY34 = sys.version_info >= (3, 4)
+from asyncio import compat
 
 
 def _get_function_source(func):
-    if _PY34:
+    if compat.PY34:
         func = inspect.unwrap(func)
     elif hasattr(func, '__wrapped__'):
         func = func.__wrapped__
@@ -31,7 +30,7 @@ def _get_function_source(func):
         return (code.co_filename, code.co_firstlineno)
     if isinstance(func, functools.partial):
         return _get_function_source(func.func)
-    if _PY34 and isinstance(func, functools.partialmethod):
+    if compat.PY34 and isinstance(func, functools.partialmethod):
         return _get_function_source(func.func)
     return None
 
index d06828a620441f22bce24c72ee822b33f41fdf99..dbe06c4a98b2031f118a5d8a9c2e7468ecfc90bf 100644 (file)
@@ -11,6 +11,7 @@ import reprlib
 import sys
 import traceback
 
+from . import compat
 from . import events
 
 # States for Future.
@@ -18,9 +19,6 @@ _PENDING = 'PENDING'
 _CANCELLED = 'CANCELLED'
 _FINISHED = 'FINISHED'
 
-_PY34 = sys.version_info >= (3, 4)
-_PY35 = sys.version_info >= (3, 5)
-
 Error = concurrent.futures._base.Error
 CancelledError = concurrent.futures.CancelledError
 TimeoutError = concurrent.futures.TimeoutError
@@ -199,7 +197,7 @@ class Future:
     # On Python 3.3 and older, objects with a destructor part of a reference
     # cycle are never destroyed. It's not more the case on Python 3.4 thanks
     # to the PEP 442.
-    if _PY34:
+    if compat.PY34:
         def __del__(self):
             if not self._log_traceback:
                 # set_exception() was not called, or result() or exception()
@@ -352,7 +350,7 @@ class Future:
         self._exception = exception
         self._state = _FINISHED
         self._schedule_callbacks()
-        if _PY34:
+        if compat.PY34:
             self._log_traceback = True
         else:
             self._tb_logger = _TracebackLogger(self, exception)
@@ -388,7 +386,7 @@ class Future:
         assert self.done(), "yield from wasn't used with future"
         return self.result()  # May raise too.
 
-    if _PY35:
+    if compat.PY35:
         __await__ = __iter__ # make compatible with 'await' expression
 
 
index b2e516b5430ef9ffe0a2b114f4268cd0fae7e0bc..cc6f2bf76f16aac7c7827aa5b568ecb96b3b06a7 100644 (file)
@@ -5,14 +5,12 @@ __all__ = ['Lock', 'Event', 'Condition', 'Semaphore', 'BoundedSemaphore']
 import collections
 import sys
 
+from . import compat
 from . import events
 from . import futures
 from .coroutines import coroutine
 
 
-_PY35 = sys.version_info >= (3, 5)
-
-
 class _ContextManager:
     """Context manager.
 
@@ -70,7 +68,7 @@ class _ContextManagerMixin:
         yield from self.acquire()
         return _ContextManager(self)
 
-    if _PY35:
+    if compat.PY35:
 
         def __await__(self):
             # To make "with await lock" work.
index 176c65e3969cb4bfc11c5e90e8aabadc41d58cf9..6cd60c42f6476c27c13d7bf7b5fcaf67cb121b92 100644 (file)
@@ -12,6 +12,7 @@ if hasattr(socket, 'AF_UNIX'):
     __all__.extend(['open_unix_connection', 'start_unix_server'])
 
 from . import coroutines
+from . import compat
 from . import events
 from . import futures
 from . import protocols
@@ -20,7 +21,6 @@ from .log import logger
 
 
 _DEFAULT_LIMIT = 2**16
-_PY35 = sys.version_info >= (3, 5)
 
 
 class IncompleteReadError(EOFError):
@@ -488,7 +488,7 @@ class StreamReader:
 
         return b''.join(blocks)
 
-    if _PY35:
+    if compat.PY35:
         @coroutine
         def __aiter__(self):
             return self
index d8193ba48e1e1e6332bef9b1174a284c31eb5ed8..1d5f865444224f503af7f4c4718a716c8c8b60db 100644 (file)
@@ -16,13 +16,12 @@ import traceback
 import warnings
 import weakref
 
+from . import compat
 from . import coroutines
 from . import events
 from . import futures
 from .coroutines import coroutine
 
-_PY34 = (sys.version_info >= (3, 4))
-
 
 class Task(futures.Future):
     """A coroutine wrapped in a Future."""
@@ -83,7 +82,7 @@ class Task(futures.Future):
     # On Python 3.3 or older, objects with a destructor that are part of a
     # reference cycle are never destroyed. That's not the case any more on
     # Python 3.4 thanks to the PEP 442.
-    if _PY34:
+    if compat.PY34:
         def __del__(self):
             if self._state == futures._PENDING and self._log_destroy_pending:
                 context = {
index 22df3c7aede77de1b868e1e0334cc57e349c6bcb..7a28d908e43935698c0bdc12177adfcc6fce3808 100644 (file)
@@ -2,7 +2,7 @@
 
 import sys
 
-_PY34 = sys.version_info >= (3, 4)
+from asyncio import compat
 
 __all__ = ['BaseTransport', 'ReadTransport', 'WriteTransport',
            'Transport', 'DatagramTransport', 'SubprocessTransport',
@@ -94,12 +94,8 @@ class WriteTransport(BaseTransport):
         The default implementation concatenates the arguments and
         calls write() on the result.
         """
-        if not _PY34:
-            # In Python 3.3, bytes.join() doesn't handle memoryview.
-            list_of_data = (
-                bytes(data) if isinstance(data, memoryview) else data
-                for data in list_of_data)
-        self.write(b''.join(list_of_data))
+        data = compat.flatten_list_bytes(list_of_data)
+        self.write(data)
 
     def write_eof(self):
         """Close the write end after flushing buffered data.