[Python-modules-commits] [python-tornado] 01/14: Import python-tornado_4.5.1.orig.tar.gz

Ondřej Nový onovy at moszumanska.debian.org
Fri May 12 14:52:09 UTC 2017


This is an automated email from the git hooks/post-receive script.

onovy pushed a commit to branch master
in repository python-tornado.

commit 1f987a3c9a55782f3e1e10c318c91cae71630000
Author: Ondřej Nový <onovy at debian.org>
Date:   Fri May 12 16:13:38 2017 +0200

    Import python-tornado_4.5.1.orig.tar.gz
---
 .travis.yml                                       |  31 +-
 MANIFEST.in                                       |   1 +
 appveyor.yml                                      |  16 +-
 demos/chat/static/chat.js                         |   9 +-
 demos/chat/templates/index.html                   |   4 +-
 demos/file_upload/file_receiver.py                |  63 +++
 demos/file_upload/file_uploader.py                | 114 ++++
 demos/tcpecho/README.md                           |  30 ++
 demos/tcpecho/client.py                           |  23 +
 demos/tcpecho/server.py                           |  34 ++
 demos/websocket/static/chat.js                    |   4 +-
 demos/websocket/templates/index.html              |   2 +-
 docs/conf.py                                      |  17 +-
 docs/gen.rst                                      |   2 +
 docs/guide/coroutines.rst                         |  28 +-
 docs/guide/structure.rst                          |   6 +-
 docs/httpclient.rst                               |   8 +
 docs/index.rst                                    |  36 +-
 docs/locks.rst                                    |  10 +-
 docs/releases.rst                                 |   2 +
 docs/releases/v2.3.0.rst                          |   2 +-
 docs/releases/v3.2.0.rst                          |   8 +-
 docs/releases/v4.1.0.rst                          |   2 +-
 docs/releases/v4.5.0.rst                          | 231 ++++++++
 docs/releases/v4.5.1.rst                          |  15 +
 docs/routing.rst                                  |   5 +
 docs/web.rst                                      |  16 +-
 docs/webframework.rst                             |   1 +
 docs/websocket.rst                                |   1 +
 maint/circlerefs/circlerefs.py                    | 100 ++++
 maint/requirements.txt                            |  62 ++-
 maint/scripts/custom_fixers/fix_future_imports.py |   3 +-
 maint/test/cython/tox.ini                         |   3 +-
 maint/vm/README                                   |   4 +-
 maint/vm/ubuntu10.04/Vagrantfile                  |   9 -
 maint/vm/ubuntu10.04/setup.sh                     |  43 --
 maint/vm/ubuntu10.04/tox.ini                      |  14 -
 setup.py                                          |   4 +-
 tornado/__init__.py                               |   6 +-
 tornado/_locale_data.py                           |   2 +-
 tornado/auth.py                                   |  25 +-
 tornado/autoreload.py                             |   9 +-
 tornado/concurrent.py                             |  19 +-
 tornado/curl_httpclient.py                        |  14 +-
 tornado/escape.py                                 |   6 +-
 tornado/gen.py                                    |  69 ++-
 tornado/http1connection.py                        |   7 +-
 tornado/httpclient.py                             |  47 +-
 tornado/httpserver.py                             | 113 ++--
 tornado/httputil.py                               |  41 +-
 tornado/ioloop.py                                 |  67 +--
 tornado/iostream.py                               | 236 ++++----
 tornado/locale.py                                 |   8 +-
 tornado/locks.py                                  |   2 +-
 tornado/log.py                                    |  83 ++-
 tornado/netutil.py                                |   6 +-
 tornado/options.py                                |   2 +-
 tornado/platform/asyncio.py                       |   5 +-
 tornado/platform/auto.py                          |   2 +-
 tornado/platform/caresresolver.py                 |   2 +-
 tornado/platform/common.py                        |  25 +-
 tornado/platform/epoll.py                         |   2 +-
 tornado/platform/interface.py                     |   3 +-
 tornado/platform/kqueue.py                        |   2 +-
 tornado/platform/posix.py                         |   8 +-
 tornado/platform/select.py                        |   2 +-
 tornado/platform/twisted.py                       |   3 +-
 tornado/platform/windows.py                       |   2 +-
 tornado/process.py                                |   8 +-
 tornado/queues.py                                 |  12 +-
 tornado/routing.py                                | 625 ++++++++++++++++++++++
 tornado/simple_httpclient.py                      |   7 +-
 tornado/stack_context.py                          |   4 +-
 tornado/tcpclient.py                              |  55 +-
 tornado/tcpserver.py                              |  28 +-
 tornado/template.py                               |   6 +-
 tornado/test/__main__.py                          |   2 +-
 tornado/test/asyncio_test.py                      |  12 +-
 tornado/test/auth_test.py                         |   7 +-
 tornado/test/concurrent_test.py                   |  24 +-
 tornado/test/curl_httpclient_test.py              |   2 +-
 tornado/test/escape_test.py                       |   2 +-
 tornado/test/gen_test.py                          |  97 +++-
 tornado/test/gettext_translations/extract_me.py   |   2 +-
 tornado/test/http1connection_test.py              |   2 +-
 tornado/test/httpclient_test.py                   |   2 +-
 tornado/test/httpserver_test.py                   |  34 +-
 tornado/test/httputil_test.py                     |  41 +-
 tornado/test/import_test.py                       |   4 +-
 tornado/test/ioloop_test.py                       |  22 +-
 tornado/test/iostream_test.py                     |  47 +-
 tornado/test/locale_test.py                       |   2 +-
 tornado/test/locks_test.py                        |   2 +-
 tornado/test/log_test.py                          |   2 +-
 tornado/test/netutil_test.py                      |   2 +-
 tornado/test/options_test.py                      |   4 +-
 tornado/test/process_test.py                      |  27 +-
 tornado/test/queues_test.py                       |   2 +-
 tornado/test/resolve_test_helper.py               |   2 +-
 tornado/test/routing_test.py                      | 224 ++++++++
 tornado/test/runtests.py                          |   7 +-
 tornado/test/simple_httpclient_test.py            |   2 +-
 tornado/test/stack_context_test.py                |   3 +-
 tornado/test/tcpclient_test.py                    |  43 +-
 tornado/test/tcpserver_test.py                    |  33 +-
 tornado/test/template_test.py                     |  11 +-
 tornado/test/testing_test.py                      |   2 +-
 tornado/test/twisted_test.py                      |   2 +-
 tornado/test/util.py                              |  20 +-
 tornado/test/util_test.py                         |   9 +-
 tornado/test/web_test.py                          |  57 +-
 tornado/test/websocket_test.py                    | 224 +++++++-
 tornado/test/windows_test.py                      |   2 +
 tornado/test/wsgi_test.py                         |   6 +-
 tornado/testing.py                                |  13 +-
 tornado/util.py                                   |  44 +-
 tornado/web.py                                    | 484 ++++++++---------
 tornado/websocket.py                              | 314 ++++++++---
 tornado/wsgi.py                                   |   2 +-
 tox.ini                                           |  19 +-
 120 files changed, 3448 insertions(+), 942 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 16f6183..4b2ac2b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,6 +7,7 @@ python:
     - 3.3
     - 3.4
     - 3.5
+    - 3.6
     - nightly
     - pypy3
 
@@ -18,21 +19,27 @@ install:
     - if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then travis_retry pip install pycurl; fi
     # Twisted runs on 2.x and 3.3+, but is flaky on pypy.
     - if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then travis_retry pip install Twisted; fi
-    - if [[ $TRAVIS_PYTHON_VERSION == '2.7' || $TRAVIS_PYTHON_VERSION == '3.5' ]]; then travis_retry pip install sphinx sphinx_rtd_theme; fi
+    - if [[ $TRAVIS_PYTHON_VERSION == '2.7' || $TRAVIS_PYTHON_VERSION == '3.5' || $TRAVIS_PYTHON_VERSION == '3.6' ]]; then travis_retry pip install sphinx sphinx_rtd_theme; fi
     # On travis the extension should always be built
     - if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then export TORNADO_EXTENSION=1; fi
     - travis_retry python setup.py install
-    - travis_retry pip install codecov
+    - travis_retry pip install codecov virtualenv
     # Create a separate no-dependencies virtualenv to make sure all imports
-    # of optional-dependencies are guarded.
-    - virtualenv ./nodeps
-    - ./nodeps/bin/python setup.py install
+    # of optional-dependencies are guarded. (skipped on pypy3 because
+    # virtualenv no longer supports py32)
+    - if [[ $TRAVIS_PYTHON_VERSION != 'pypy3' ]]; then virtualenv ./nodeps; fi
+    - if [[ $TRAVIS_PYTHON_VERSION != 'pypy3' ]]; then ./nodeps/bin/python -VV; fi
+    - if [[ $TRAVIS_PYTHON_VERSION != 'pypy3' ]]; then ./nodeps/bin/python setup.py install; fi
     - curl-config --version; pip freeze
 
 script:
-    # Get out of the source directory before running tests to avoid PYTHONPATH
-    # confusion.  This is necessary to ensure that the speedups module can
-    # be found in the installation directory.
+    # Run the tests once from the source directory to detect issues
+    # involving relative __file__ paths; see
+    # https://github.com/tornadoweb/tornado/issues/1780
+    - unset TORNADO_EXTENSION && python -m tornado.test
+    # For all other test variants, get out of the source directory before
+    # running tests to ensure that we get the installed speedups module
+    # instead of the source directory which doesn't have it.
     - cd maint
     # Copy the coveragerc down so coverage.py can find it.
     - cp ../.coveragerc .
@@ -56,17 +63,17 @@ script:
     - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then python $TARGET --httpclient=tornado.curl_httpclient.CurlAsyncHTTPClient; fi
     - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then python $TARGET --ioloop_time_monotonic; fi
     - if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then python $TARGET --ioloop=tornado.platform.twisted.TwistedIOLoop; fi
-    - if [[ $TRAVIS_PYTHON_VERSION == 3.4 || $TRAVIS_PYTHON_VERSION == 3.5 ]]; then python $TARGET --ioloop=tornado.platform.asyncio.AsyncIOLoop; fi
+    - if [[ $TRAVIS_PYTHON_VERSION == 3.4 || $TRAVIS_PYTHON_VERSION == 3.5 || $TRAVIS_PYTHON_VERSION == 3.6 ]]; then python $TARGET --ioloop=tornado.platform.asyncio.AsyncIOLoop; fi
     - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then python $TARGET --ioloop=tornado.platform.asyncio.AsyncIOLoop; fi
     - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then python $TARGET --resolver=tornado.platform.twisted.TwistedResolver; fi
     #- if [[ $TRAVIS_PYTHON_VERSION != pypy* ]]; then python $TARGET --resolver=tornado.platform.caresresolver.CaresResolver; fi
     - if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then python $TARGET --ioloop_time_monotonic; fi
-    - ../nodeps/bin/python -m tornado.test.runtests
+    - if [[ $TRAVIS_PYTHON_VERSION != 'pypy3' ]]; then ../nodeps/bin/python -m tornado.test.runtests; fi
     # make coverage reports for Codecov to find
     - if [[ $TRAVIS_PYTHON_VERSION != nightly ]]; then coverage xml; fi
     - export TORNADO_EXTENSION=0
-    - if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then cd ../docs && mkdir sphinx-out && sphinx-build -E -n -W -b html . sphinx-out; fi
-    - if [[ $TRAVIS_PYTHON_VERSION == '2.7' || $TRAVIS_PYTHON_VERSION == '3.5' ]]; then cd ../docs && mkdir sphinx-doctest-out && sphinx-build -E -n -b doctest . sphinx-out; fi
+    - if [[ $TRAVIS_PYTHON_VERSION == '3.5' || $TRAVIS_PYTHON_VERSION == 3.6 ]]; then cd ../docs && mkdir sphinx-out && sphinx-build -E -n -W -b html . sphinx-out; fi
+    - if [[ $TRAVIS_PYTHON_VERSION == '2.7' || $TRAVIS_PYTHON_VERSION == '3.5' || $TRAVIS_PYTHON_VERSION == 3.6 ]]; then cd ../docs && mkdir sphinx-doctest-out && sphinx-build -E -n -b doctest . sphinx-out; fi
 
 after_success:
     # call codecov from project root
diff --git a/MANIFEST.in b/MANIFEST.in
index 30cdcd0..2ef76ae 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -16,5 +16,6 @@ include tornado/test/static_foo.txt
 include tornado/test/templates/utf8.html
 include tornado/test/test.crt
 include tornado/test/test.key
+include LICENSE
 include README.rst
 include runtests.sh
diff --git a/appveyor.yml b/appveyor.yml
index be30b3c..412369c 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -3,7 +3,7 @@ environment:
   global:
     TORNADO_EXTENSION: "1"
 
-  # We only build with 3.5 because it works out of the box, while other
+  # We only build with 3.5+ because it works out of the box, while other
   # versions require lots of machinery.
   matrix:
     - PYTHON: "C:\\Python35"
@@ -14,6 +14,14 @@ environment:
       PYTHON_VERSION: "3.5.x"
       PYTHON_ARCH: "64"
 
+    - PYTHON: "C:\\Python36"
+      PYTHON_VERSION: "3.6.x"
+      PYTHON_ARCH: "32"
+
+    - PYTHON: "C:\\Python36-x64"
+      PYTHON_VERSION: "3.6.x"
+      PYTHON_ARCH: "64"
+
 install:
   # Make sure the right python version is first on the PATH.
   - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
@@ -32,11 +40,11 @@ build: false  # Not a C# project, build stuff at the test step instead.
 
 test_script:
   # Build the compiled extension and run the project tests.
-  # This is a bit of a hack that won't scale when py36 is out,
+  # This is a bit of a hack that doesn't scale with new python versions,
   # but for now it lets us avoid duplication with .travis.yml and tox.ini.
-  # Running "py35-full" would be nice but it's failing on installing
+  # Running "py3x-full" would be nice but it's failing on installing
   # dependencies with no useful logs.
-  - "tox -e py35"
+  - "tox -e py35,py36 --skip-missing-interpreters"
 
 after_test:
   # If tests are successful, create binary packages for the project.
diff --git a/demos/chat/static/chat.js b/demos/chat/static/chat.js
index 0054c71..151a588 100644
--- a/demos/chat/static/chat.js
+++ b/demos/chat/static/chat.js
@@ -16,15 +16,16 @@ $(document).ready(function() {
     if (!window.console) window.console = {};
     if (!window.console.log) window.console.log = function() {};
 
-    $("#messageform").live("submit", function() {
+    $("#messageform").on("submit", function() {
         newMessage($(this));
         return false;
     });
-    $("#messageform").live("keypress", function(e) {
+    $("#messageform").on("keypress", function(e) {
         if (e.keyCode == 13) {
             newMessage($(this));
             return false;
         }
+        return true;
     });
     $("#message").select();
     updater.poll();
@@ -56,13 +57,13 @@ jQuery.postJSON = function(url, args, callback) {
             success: function(response) {
         if (callback) callback(eval("(" + response + ")"));
     }, error: function(response) {
-        console.log("ERROR:", response)
+        console.log("ERROR:", response);
     }});
 };
 
 jQuery.fn.formToDict = function() {
     var fields = this.serializeArray();
-    var json = {}
+    var json = {};
     for (var i = 0; i < fields.length; i++) {
         json[fields[i].name] = fields[i].value;
     }
diff --git a/demos/chat/templates/index.html b/demos/chat/templates/index.html
index 8916c35..58433b4 100644
--- a/demos/chat/templates/index.html
+++ b/demos/chat/templates/index.html
@@ -16,7 +16,7 @@
         <form action="/a/message/new" method="post" id="messageform">
           <table>
             <tr>
-              <td><input name="body" id="message" style="width:500px"></td>
+              <td><input type="text" name="body" id="message" style="width:500px"></td>
               <td style="padding-left:5px">
                 <input type="submit" value="{{ _("Post") }}">
                 <input type="hidden" name="next" value="{{ request.path }}">
@@ -27,7 +27,7 @@
         </form>
       </div>
     </div>
-    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js" type="text/javascript"></script>
     <script src="{{ static_url("chat.js") }}" type="text/javascript"></script>
   </body>
 </html>
diff --git a/demos/file_upload/file_receiver.py b/demos/file_upload/file_receiver.py
new file mode 100644
index 0000000..3b3e986
--- /dev/null
+++ b/demos/file_upload/file_receiver.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+
+"""Usage: python file_receiver.py
+
+Demonstrates a server that receives a multipart-form-encoded set of files in an
+HTTP POST, or streams in the raw data of a single file in an HTTP PUT.
+
+See file_uploader.py in this directory for code that uploads files in this format.
+"""
+
+import logging
+
+try:
+    from urllib.parse import unquote
+except ImportError:
+    # Python 2.
+    from urllib import unquote
+
+import tornado.ioloop
+import tornado.web
+from tornado import options
+
+
+class POSTHandler(tornado.web.RequestHandler):
+    def post(self):
+        for field_name, files in self.request.files.items():
+            for info in files:
+                filename, content_type = info['filename'], info['content_type']
+                body = info['body']
+                logging.info('POST "%s" "%s" %d bytes',
+                             filename, content_type, len(body))
+
+        self.write('OK')
+
+
+ at tornado.web.stream_request_body
+class PUTHandler(tornado.web.RequestHandler):
+    def initialize(self):
+        self.bytes_read = 0
+
+    def data_received(self, chunk):
+        self.bytes_read += len(chunk)
+
+    def put(self, filename):
+        filename = unquote(filename)
+        mtype = self.request.headers.get('Content-Type')
+        logging.info('PUT "%s" "%s" %d bytes', filename, mtype, self.bytes_read)
+        self.write('OK')
+
+
+def make_app():
+    return tornado.web.Application([
+        (r"/post", POSTHandler),
+        (r"/(.*)", PUTHandler),
+    ])
+
+
+if __name__ == "__main__":
+    # Tornado configures logging.
+    options.parse_command_line()
+    app = make_app()
+    app.listen(8888)
+    tornado.ioloop.IOLoop.current().start()
diff --git a/demos/file_upload/file_uploader.py b/demos/file_upload/file_uploader.py
new file mode 100644
index 0000000..025c215
--- /dev/null
+++ b/demos/file_upload/file_uploader.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+
+"""Usage: python file_uploader.py [--put] file1.txt file2.png ...
+
+Demonstrates uploading files to a server, without concurrency. It can either
+POST a multipart-form-encoded request containing one or more files, or PUT a
+single file without encoding.
+
+See also file_receiver.py in this directory, a server that receives uploads.
+"""
+
+import mimetypes
+import os
+import sys
+from functools import partial
+from uuid import uuid4
+
+try:
+    from urllib.parse import quote
+except ImportError:
+    # Python 2.
+    from urllib import quote
+
+from tornado import gen, httpclient, ioloop
+from tornado.options import define, options
+
+
+# Using HTTP POST, upload one or more files in a single multipart-form-encoded
+# request.
+ at gen.coroutine
+def multipart_producer(boundary, filenames, write):
+    boundary_bytes = boundary.encode()
+
+    for filename in filenames:
+        filename_bytes = filename.encode()
+        write(b'--%s\r\n' % (boundary_bytes,))
+        write(b'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' %
+              (filename_bytes, filename_bytes))
+
+        mtype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
+        write(b'Content-Type: %s\r\n' % (mtype.encode(),))
+        write(b'\r\n')
+        with open(filename, 'rb') as f:
+            while True:
+                # 16k at a time.
+                chunk = f.read(16 * 1024)
+                if not chunk:
+                    break
+                write(chunk)
+
+                # Let the IOLoop process its event queue.
+                yield gen.moment
+
+        write(b'\r\n')
+        yield gen.moment
+
+    write(b'--%s--\r\n' % (boundary_bytes,))
+
+
+# Using HTTP PUT, upload one raw file. This is preferred for large files since
+# the server can stream the data instead of buffering it entirely in memory.
+ at gen.coroutine
+def post(filenames):
+    client = httpclient.AsyncHTTPClient()
+    boundary = uuid4().hex
+    headers = {'Content-Type': 'multipart/form-data; boundary=%s' % boundary}
+    producer = partial(multipart_producer, boundary, filenames)
+    response = yield client.fetch('http://localhost:8888/post',
+                                  method='POST',
+                                  headers=headers,
+                                  body_producer=producer)
+
+    print(response)
+
+
+ at gen.coroutine
+def raw_producer(filename, write):
+    with open(filename, 'rb') as f:
+        while True:
+            # 16K at a time.
+            chunk = f.read(16 * 1024)
+            if not chunk:
+                # Complete.
+                break
+
+            write(chunk)
+
+
+ at gen.coroutine
+def put(filenames):
+    client = httpclient.AsyncHTTPClient()
+    for filename in filenames:
+        mtype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
+        headers = {'Content-Type': mtype}
+        producer = partial(raw_producer, filename)
+        url_path = quote(os.path.basename(filename))
+        response = yield client.fetch('http://localhost:8888/%s' % url_path,
+                                      method='PUT',
+                                      headers=headers,
+                                      body_producer=producer)
+    
+        print(response)
+
+
+define("put", type=bool, help="Use PUT instead of POST", group="file uploader")
+
+# Tornado configures logging from command line opts and returns remaining args.
+filenames = options.parse_command_line()
+if not filenames:
+    print("Provide a list of filenames to upload.", file=sys.stderr)
+    sys.exit(1)
+
+method = put if options.put else post
+ioloop.IOLoop.current().run_sync(lambda: method(filenames))
diff --git a/demos/tcpecho/README.md b/demos/tcpecho/README.md
new file mode 100644
index 0000000..60d0b70
--- /dev/null
+++ b/demos/tcpecho/README.md
@@ -0,0 +1,30 @@
+TCP echo demo
+=============
+
+This demo shows how to use Tornado's asynchronous TCP client and
+server by implementing `handle_stream` as a coroutine.
+
+To run the server:
+
+```
+$ python server.py
+```
+
+The client will send the message given with the `--message` option
+(which defaults to "ping"), wait for a response, then quit. To run:
+
+```
+$ python client.py --message="your message here"
+```
+
+Alternatively, you can interactively send messages to the echo server
+with a telnet client. For example:
+
+```
+$ telnet localhost 9888
+Trying ::1...
+Connected to localhost.
+Escape character is '^]'.
+ping
+ping
+```
diff --git a/demos/tcpecho/client.py b/demos/tcpecho/client.py
new file mode 100644
index 0000000..a369fa4
--- /dev/null
+++ b/demos/tcpecho/client.py
@@ -0,0 +1,23 @@
+from __future__ import print_function
+from tornado.ioloop import IOLoop
+from tornado import gen
+from tornado.tcpclient import TCPClient
+from tornado.options import options, define
+
+define("host", default="localhost", help="TCP server host")
+define("port", default=9888, help="TCP port to connect to")
+define("message", default="ping", help="Message to send")
+
+
+ at gen.coroutine
+def send_message():
+    stream = yield TCPClient().connect(options.host, options.port)
+    yield stream.write((options.message + "\n").encode())
+    print("Sent to server:", options.message)
+    reply = yield stream.read_until(b"\n")
+    print("Response from server:", reply.decode().strip())
+
+
+if __name__ == "__main__":
+    options.parse_command_line()
+    IOLoop.current().run_sync(send_message)
diff --git a/demos/tcpecho/server.py b/demos/tcpecho/server.py
new file mode 100644
index 0000000..bc0b054
--- /dev/null
+++ b/demos/tcpecho/server.py
@@ -0,0 +1,34 @@
+import logging
+from tornado.ioloop import IOLoop
+from tornado import gen
+from tornado.iostream import StreamClosedError
+from tornado.tcpserver import TCPServer
+from tornado.options import options, define
+
+define("port", default=9888, help="TCP port to listen on")
+logger = logging.getLogger(__name__)
+
+
+class EchoServer(TCPServer):
+    @gen.coroutine
+    def handle_stream(self, stream, address):
+        while True:
+            try:
+                data = yield stream.read_until(b"\n")
+                logger.info("Received bytes: %s", data)
+                if not data.endswith(b"\n"):
+                    data = data + b"\n"
+                yield stream.write(data)
+            except StreamClosedError:
+                logger.warning("Lost client at host %s", address[0])
+                break
+            except Exception as e:
+                print(e)
+
+
+if __name__ == "__main__":
+    options.parse_command_line()
+    server = EchoServer()
+    server.listen(options.port)
+    logger.info("Listening on TCP port %d", options.port)
+    IOLoop.current().start()
diff --git a/demos/websocket/static/chat.js b/demos/websocket/static/chat.js
index b4bb18a..4e7ec04 100644
--- a/demos/websocket/static/chat.js
+++ b/demos/websocket/static/chat.js
@@ -16,11 +16,11 @@ $(document).ready(function() {
     if (!window.console) window.console = {};
     if (!window.console.log) window.console.log = function() {};
 
-    $("#messageform").live("submit", function() {
+    $("#messageform").on("submit", function() {
         newMessage($(this));
         return false;
     });
-    $("#messageform").live("keypress", function(e) {
+    $("#messageform").on("keypress", function(e) {
         if (e.keyCode == 13) {
             newMessage($(this));
             return false;
diff --git a/demos/websocket/templates/index.html b/demos/websocket/templates/index.html
index cbf2b23..91a4536 100644
--- a/demos/websocket/templates/index.html
+++ b/demos/websocket/templates/index.html
@@ -27,7 +27,7 @@
         </form>
       </div>
     </div>
-    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
+    <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js" type="text/javascript"></script>
     <script src="{{ static_url("chat.js") }}" type="text/javascript"></script>
   </body>
 </html>
diff --git a/docs/conf.py b/docs/conf.py
index a12e7a4..5bc6635 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -16,7 +16,6 @@ extensions = [
     "sphinx.ext.autodoc",
     "sphinx.ext.coverage",
     "sphinx.ext.doctest",
-    "sphinx.ext.extlinks",
     "sphinx.ext.intersphinx",
     "sphinx.ext.viewcode",
     ]
@@ -71,6 +70,9 @@ coverage_ignore_functions = [
     # parse_qs_bytes should probably be documented but it's complicated by
     # having different implementations between py2 and py3.
     "parse_qs_bytes",
+
+    # tornado.gen
+    "Multi",
 ]
 
 html_favicon = 'favicon.ico'
@@ -79,19 +81,6 @@ latex_documents = [
     ('index', 'tornado.tex', 'Tornado Documentation', 'The Tornado Authors', 'manual', False),
     ]
 
-# HACK: sphinx has limited support for substitutions with the |version|
-# variable, but there doesn't appear to be any way to use this in a link
-# target.
-# http://stackoverflow.com/questions/1227037/substitutions-inside-links-in-rest-sphinx
-# The extlink extension can be used to do link substitutions, but it requires a
-# portion of the url to be literally contained in the document.  Therefore,
-# this link must be referenced as :current_tarball:`z`
-extlinks = {
-    'current_tarball': (
-        'https://pypi.python.org/packages/source/t/tornado/tornado-%s.tar.g%%s' % version,
-        'tornado-%s.tar.g' % version),
-    }
-
 intersphinx_mapping = {
     'python': ('https://docs.python.org/3.5/', None),
     }
diff --git a/docs/gen.rst b/docs/gen.rst
index 8e867ed..52c7f55 100644
--- a/docs/gen.rst
+++ b/docs/gen.rst
@@ -50,6 +50,8 @@
 
    .. autofunction:: maybe_future
 
+   .. autofunction:: is_coroutine_function
+
    Legacy interface
    ----------------
 
diff --git a/docs/guide/coroutines.rst b/docs/guide/coroutines.rst
index 2fefcb4..83e3048 100644
--- a/docs/guide/coroutines.rst
+++ b/docs/guide/coroutines.rst
@@ -40,9 +40,10 @@ Python 3.5: ``async`` and ``await``
 
 Python 3.5 introduces the ``async`` and ``await`` keywords (functions
 using these keywords are also called "native coroutines"). Starting in
-Tornado 4.3, you can use them in place of ``yield``-based coroutines.
-Simply use ``async def foo()`` in place of a function definition with
-the ``@gen.coroutine`` decorator, and ``await`` in place of yield. The
+Tornado 4.3, you can use them in place of most ``yield``-based
+coroutines (see the following paragraphs for limitations). Simply use
+``async def foo()`` in place of a function definition with the
+``@gen.coroutine`` decorator, and ``await`` in place of yield. The
 rest of this document still uses the ``yield`` style for compatibility
 with older versions of Python, but ``async`` and ``await`` will run
 faster when they are available::
@@ -55,9 +56,14 @@ faster when they are available::
 The ``await`` keyword is less versatile than the ``yield`` keyword.
 For example, in a ``yield``-based coroutine you can yield a list of
 ``Futures``, while in a native coroutine you must wrap the list in
-`tornado.gen.multi`. You can also use `tornado.gen.convert_yielded`
+`tornado.gen.multi`. This also eliminates the integration with
+`concurrent.futures`. You can use `tornado.gen.convert_yielded`
 to convert anything that would work with ``yield`` into a form that
-will work with ``await``.
+will work with ``await``::
+
+    async def f():
+        executor = concurrent.futures.ThreadPoolExecutor()
+        await tornado.gen.convert_yielded(executor.submit(g))
 
 While native coroutines are not visibly tied to a particular framework
 (i.e. they do not use a decorator like `tornado.gen.coroutine` or
@@ -143,7 +149,11 @@ the `.IOLoop` will log a stack trace::
     # we pass the function object to be called by the IOLoop.
     IOLoop.current().spawn_callback(divide, 1, 0)
 
-Finally, at the top level of a program, *if the `.IOLoop` is not yet
+Using `.IOLoop.spawn_callback` in this way is *recommended* for
+functions using ``@gen.coroutine``, but it is *required* for functions
+using ``async def`` (otherwise the coroutine runner will not start).
+
+Finally, at the top level of a program, *if the IOLoop is not yet
 running,* you can start the `.IOLoop`, run the coroutine, and then
 stop the `.IOLoop` with the `.IOLoop.run_sync` method. This is often
 used to start the ``main`` function of a batch-oriented program::
@@ -235,6 +245,12 @@ immediately, so you can start another operation before waiting:
 .. testoutput::
    :hide:
 
+This pattern is most usable with ``@gen.coroutine``. If
+``fetch_next_chunk()`` uses ``async def``, then it must be called as
+``fetch_future =
+tornado.gen.convert_yielded(self.fetch_next_chunk())`` to start the
+background processing.
+
 Looping
 ^^^^^^^
 
diff --git a/docs/guide/structure.rst b/docs/guide/structure.rst
index f0829df..b0735a1 100644
--- a/docs/guide/structure.rst
+++ b/docs/guide/structure.rst
@@ -153,6 +153,10 @@ By default uploaded files are fully buffered in memory; if you need to
 handle files that are too large to comfortably keep in memory see the
 `.stream_request_body` class decorator.
 
+In the demos directory,
+`file_receiver.py <https://github.com/tornadoweb/tornado/tree/master/demos/file_upload/>`_
+shows both methods of receiving file uploads.
+
 Due to the quirks of the HTML form encoding (e.g. the ambiguity around
 singular versus plural arguments), Tornado does not attempt to unify
 form arguments with other types of input.  In particular, we do not
@@ -278,7 +282,7 @@ to the prefix ``/photos/`` instead::
     app = tornado.web.Application([
         url(r"/photos/(.*)", MyPhotoHandler),
         url(r"/pictures/(.*)", tornado.web.RedirectHandler,
-            dict(url=r"/photos/\1")),
+            dict(url=r"/photos/{0}")),
         ])
 
 Unlike `.RequestHandler.redirect`, `.RedirectHandler` uses permanent
diff --git a/docs/httpclient.rst b/docs/httpclient.rst
index a641fa2..53a0a88 100644
--- a/docs/httpclient.rst
+++ b/docs/httpclient.rst
@@ -50,3 +50,11 @@ Implementations
 .. class:: CurlAsyncHTTPClient(io_loop, max_clients=10, defaults=None)
 
    ``libcurl``-based HTTP client.
+
+Example Code
+~~~~~~~~~~~~
+
+* `A simple webspider <https://github.com/tornadoweb/tornado/blob/master/demos/webspider/webspider.py>`_
+  shows how to fetch URLs concurrently.
+* `The file uploader demo <https://github.com/tornadoweb/tornado/tree/master/demos/file_upload/>`_
+  uses either HTTP POST or HTTP PUT to upload files to a server.
diff --git a/docs/index.rst b/docs/index.rst
index d7f435d..9905fe7 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -20,14 +20,12 @@ applications that require a long-lived connection to each user.
 Quick links
 -----------
 
-* |Download current version|: :current_tarball:`z` (:doc:`release notes <releases>`)
+* Current version: |version| (`download from PyPI <https://pypi.python.org/pypi/tornado>`_, :doc:`release notes <releases>`)
 * `Source (github) <https://github.com/tornadoweb/tornado>`_
 * Mailing lists: `discussion <http://groups.google.com/group/python-tornado>`_ and `announcements <http://groups.google.com/group/python-tornado-announce>`_
 * `Stack Overflow <http://stackoverflow.com/questions/tagged/tornado>`_
 * `Wiki <https://github.com/tornadoweb/tornado/wiki/Links>`_
 
-.. |Download current version| replace:: Download version |version|
-
 Hello, world
 ------------
 
@@ -57,29 +55,18 @@ that see this `simple chat room
 Installation
 ------------
 
-**Automatic installation**::
+::
 
     pip install tornado
 
 Tornado is listed in `PyPI <http://pypi.python.org/pypi/tornado>`_ and
-can be installed with ``pip`` or ``easy_install``.  Note that the
-source distribution includes demo applications that are not present
-when Tornado is installed in this way, so you may wish to download a
-copy of the source tarball as well.
-
-**Manual installation**: Download :current_tarball:`z`:
-
-.. parsed-literal::
-
-    tar xvzf tornado-|version|.tar.gz
-    cd tornado-|version|
-    python setup.py build
-    sudo python setup.py install
-
-The Tornado source code is `hosted on GitHub
-<https://github.com/tornadoweb/tornado>`_.
+can be installed with ``pip``. Note that the source distribution
+includes demo applications that are not present when Tornado is
+installed in this way, so you may wish to download a copy of the
+source tarball or clone the `git repository
+<https://github.com/tornadoweb/tornado>`_ as well.
 
-**Prerequisites**: Tornado 4.3 runs on Python 2.7, and 3.3+
+**Prerequisites**: Tornado runs on Python 2.7, and 3.3+
 For Python 2, version 2.7.9 or newer is *strongly*
 recommended for the improved SSL support. In addition to the requirements
 which will be installed automatically by ``pip`` or ``setup.py install``,
@@ -90,8 +77,7 @@ the following optional packages may be useful:
   `~tornado.netutil.ThreadedResolver`.  It is needed only on Python 2;
   Python 3 includes this package in the standard library.
 * `pycurl <http://pycurl.sourceforge.net>`_ is used by the optional
-  ``tornado.curl_httpclient``.  Libcurl version 7.19.3.1 or higher is required;
-  version 7.21.1 or higher is recommended.
+  ``tornado.curl_httpclient``.  Libcurl version 7.22 or higher is required.
 * `Twisted <http://www.twistedmatrix.com>`_ may be used with the classes in
   `tornado.platform.twisted`.
 * `pycares <https://pypi.python.org/pypi/pycares>`_ is an alternative
@@ -109,7 +95,9 @@ and BSD (with ``kqueue``) are recommended for production deployment
 networking performance is generally poor so it is recommended only for
 development use).  Tornado will also run on Windows, although this
 configuration is not officially supported and is recommended only for
-development use.
+development use. Without reworking Tornado IOLoop interface, it's not
+possible to add a native Tornado Windows IOLoop implementation or
+leverage Windows' IOCP support from frameworks like AsyncIO or Twisted.
 
 Documentation
 -------------
diff --git a/docs/locks.rst b/docs/locks.rst
index 7115b0d..94184db 100644
--- a/docs/locks.rst
+++ b/docs/locks.rst
@@ -6,10 +6,12 @@
 Coordinate coroutines with synchronization primitives analogous to those the
 standard library provides to threads.
 
-*(Note that these primitives are not actually thread-safe and cannot be used in
-place of those from the standard library--they are meant to coordinate Tornado
-coroutines in a single-threaded app, not to protect shared objects in a
-multithreaded app.)*
+.. warning::
+
+   Note that these primitives are not actually thread-safe and cannot be used in
+   place of those from the standard library--they are meant to coordinate Tornado
+   coroutines in a single-threaded app, not to protect shared objects in a
+   multithreaded app.
 
 .. automodule:: tornado.locks
 
diff --git a/docs/releases.rst b/docs/releases.rst
index 23f0966..8fb67c8 100644
--- a/docs/releases.rst
+++ b/docs/releases.rst
@@ -4,6 +4,8 @@ Release notes
 .. toctree::
    :maxdepth: 2
 
+   releases/v4.5.1
+   releases/v4.5.0
    releases/v4.4.3
    releases/v4.4.2
    releases/v4.4.1
diff --git a/docs/releases/v2.3.0.rst b/docs/releases/v2.3.0.rst
index 368ceec..d24f46c 100644
--- a/docs/releases/v2.3.0.rst
+++ b/docs/releases/v2.3.0.rst
@@ -80,7 +80,7 @@ HTTP Server
   backwards-incompatible change to an interface that was never technically
   private, but was not included in the documentation and does not appear
   to have been used outside Tornado itself.
-* Fixed a bug on python versions before 2.6.5 when `.URLSpec` regexes
+* Fixed a bug on python versions before 2.6.5 when `tornado.web.URLSpec` regexes
   are constructed from unicode strings and keyword arguments are extracted.
 * The ``reverse_url`` function in the template namespace now comes from
   the `.RequestHandler` rather than the `.Application`.  (Unless overridden,
diff --git a/docs/releases/v3.2.0.rst b/docs/releases/v3.2.0.rst
index 95db3e9..0905703 100644
--- a/docs/releases/v3.2.0.rst
+++ b/docs/releases/v3.2.0.rst
@@ -164,11 +164,11 @@ New modules
   argument could not be decoded.
 * `.RequestHandler.clear_all_cookies` now accepts ``domain`` and ``path``
   arguments, just like `~.RequestHandler.clear_cookie`.
-* It is now possible to specify handlers by name when using the `.URLSpec`
-  class.
+* It is now possible to specify handlers by name when using the
+  `tornado.web.URLSpec` class.
 * `.Application` now accepts 4-tuples to specify the ``name`` parameter
-  (which previously required constructing a `.URLSpec` object instead of
-  a tuple).
+  (which previously required constructing a `tornado.web.URLSpec` object
+  instead of a tuple).
 * Fixed an incorrect error message when handler methods return a value
   other than None or a Future.
 * Exceptions will no longer be logged twice when using both ``@asynchronous``
diff --git a/docs/releases/v4.1.0.rst b/docs/releases/v4.1.0.rst
index c38511b..29ad191 100644
--- a/docs/releases/v4.1.0.rst
+++ b/docs/releases/v4.1.0.rst
@@ -24,7 +24,7 @@ Backwards-compatibility notes
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 * `.HTTPServer` now calls ``start_request`` with the correct
-  arguments.  This change is backwards-incompatible, afffecting any
+  arguments.  This change is backwards-incompatible, affecting any
   application which implemented `.HTTPServerConnectionDelegate` by
   following the example of `.Application` instead of the documented
   method signatures.
diff --git a/docs/releases/v4.5.0.rst b/docs/releases/v4.5.0.rst
new file mode 100644
index 0000000..9cdf0ad
--- /dev/null
+++ b/docs/releases/v4.5.0.rst
@@ -0,0 +1,231 @@
+What's new in Tornado 4.5
+=========================
+
+Apr 16, 2017
+------------
+
+Backwards-compatibility warning
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- The `tornado.websocket` module now imposes a limit on the size of incoming
+  messages, which defaults to 10MiB.
+
+New module
+~~~~~~~~~~
+
+- `tornado.routing` provides a more flexible routing system than the one built in
+  to `.Application`.
+
+General changes
+~~~~~~~~~~~~~~~
+
+- Reduced the number of circular references, reducing memory usage and
+  improving performance.
+
+`tornado.auth`
+~~~~~~~~~~~~~~
+
+* The `tornado.auth` module has been updated for compatibility with `a
+  change to Facebook's access_token endpoint
+  <https://github.com/tornadoweb/tornado/pull/1977>`_. This includes both
+  the changes initially released in Tornado 4.4.3 and an additional change
+  to support the ```session_expires`` field in the new format.
+  The ``session_expires`` field is currently a string; it should be accessed
+  as ``int(user['session_expires'])`` because it will change from a string to
+  an int in Tornado 5.0.
+
+
+`tornado.autoreload`
+~~~~~~~~~~~~~~~~~~~~
+
+- Autoreload is now compatible with the `asyncio` event loop.
+- Autoreload no longer attempts to close the `.IOLoop` and all registered
... 6860 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-tornado.git



More information about the Python-modules-commits mailing list