Hello community,

here is the log from the commit of package python-tornado for openSUSE:Factory 
checked in at 2012-12-03 11:30:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-tornado (Old)
 and      /work/SRC/openSUSE:Factory/.python-tornado.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-tornado", Maintainer is "[email protected]"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-tornado/python-tornado.changes    
2012-09-11 09:18:55.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-tornado.new/python-tornado.changes       
2012-12-03 11:31:01.000000000 +0100
@@ -1,0 +2,11 @@
+Sun Nov 25 11:41:29 UTC 2012 - [email protected]
+
+- Update to 2.4.1:
+  - Fixed a memory leak in tornado.stack_context that was especially
+    likely with long-running @gen.engine functions.
+  - tornado.auth.TwitterMixin now works on Python 3.
+  - Fixed a bug in which IOStream.read_until_close with a streaming
+    callback would sometimes pass the last chunk of data to the
+    final callback instead of the streaming callback.
+
+-------------------------------------------------------------------
python3-tornado.changes: same change

Old:
----
  tornado-2.4.tar.bz2

New:
----
  tornado-2.4.1.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-tornado.spec ++++++
--- /var/tmp/diff_new_pack.ofgBvy/_old  2012-12-03 11:31:02.000000000 +0100
+++ /var/tmp/diff_new_pack.ofgBvy/_new  2012-12-03 11:31:02.000000000 +0100
@@ -17,7 +17,7 @@
 
 %define modname tornado
 Name:           python-%{modname}
-Version:        2.4
+Version:        2.4.1
 Release:        0
 Url:            http://www.tornadoweb.org
 Summary:        Open source version of scalable, non-blocking web server that 
power FriendFeed

++++++ python3-tornado.spec ++++++
--- /var/tmp/diff_new_pack.ofgBvy/_old  2012-12-03 11:31:02.000000000 +0100
+++ /var/tmp/diff_new_pack.ofgBvy/_new  2012-12-03 11:31:02.000000000 +0100
@@ -17,7 +17,7 @@
 
 %define modname tornado
 Name:           python3-%{modname}
-Version:        2.4
+Version:        2.4.1
 Release:        0
 Url:            http://www.tornadoweb.org
 Summary:        Open source version of scalable, non-blocking web server that 
power FriendFeed

++++++ tornado-2.4.tar.bz2 -> tornado-2.4.1.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/PKG-INFO new/tornado-2.4.1/PKG-INFO
--- old/tornado-2.4/PKG-INFO    2012-09-04 07:10:21.000000000 +0200
+++ new/tornado-2.4.1/PKG-INFO  2012-11-25 03:28:47.000000000 +0100
@@ -1,11 +1,11 @@
 Metadata-Version: 1.1
 Name: tornado
-Version: 2.4
+Version: 2.4.1
 Summary: Tornado is an open source version of the scalable, non-blocking web 
server and and tools that power FriendFeed
 Home-page: http://www.tornadoweb.org/
 Author: Facebook
 Author-email: [email protected]
 License: http://www.apache.org/licenses/LICENSE-2.0
-Download-URL: http://github.com/downloads/facebook/tornado/tornado-2.4.tar.gz
+Download-URL: http://github.com/downloads/facebook/tornado/tornado-2.4.1.tar.gz
 Description: UNKNOWN
 Platform: UNKNOWN
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/setup.py new/tornado-2.4.1/setup.py
--- old/tornado-2.4/setup.py    2012-09-04 07:06:58.000000000 +0200
+++ new/tornado-2.4.1/setup.py  2012-11-25 03:21:53.000000000 +0100
@@ -33,7 +33,7 @@
     extensions.append(distutils.core.Extension(
         "tornado.epoll", ["tornado/epoll.c"]))
 
-version = "2.4"
+version = "2.4.1"
 
 if major >= 3:
     import setuptools  # setuptools is required for use_2to3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/tornado/__init__.py 
new/tornado-2.4.1/tornado/__init__.py
--- old/tornado-2.4/tornado/__init__.py 2012-09-04 07:07:17.000000000 +0200
+++ new/tornado-2.4.1/tornado/__init__.py       2012-11-25 03:22:02.000000000 
+0100
@@ -25,5 +25,5 @@
 # is zero for an official release, positive for a development branch,
 # or negative for a release candidate (after the base version number
 # has been incremented)
-version = "2.4"
-version_info = (2, 4, 0, 0)
+version = "2.4.1"
+version_info = (2, 4, 1, 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/tornado/auth.py 
new/tornado-2.4.1/tornado/auth.py
--- old/tornado-2.4/tornado/auth.py     2012-08-30 17:30:01.000000000 +0200
+++ new/tornado-2.4.1/tornado/auth.py   2012-11-25 03:04:41.000000000 +0100
@@ -95,7 +95,7 @@
         args["openid.mode"] = u"check_authentication"
         url = self._OPENID_ENDPOINT
         if http_client is None:
-            http_client = httpclient.AsyncHTTPClient()
+            http_client = self.get_auth_http_client()
         http_client.fetch(url, self.async_callback(
             self._on_authentication_verified, callback),
             method="POST", body=urllib.urlencode(args))
@@ -208,6 +208,14 @@
             user["claimed_id"] = claimed_id
         callback(user)
 
+    def get_auth_http_client(self):
+        """Returns the AsyncHTTPClient instance to be used for auth requests.
+
+        May be overridden by subclasses to use an http client other than
+        the default.
+        """
+        return httpclient.AsyncHTTPClient()
+
 
 class OAuthMixin(object):
     """Abstract implementation of OAuth.
@@ -232,7 +240,7 @@
         if callback_uri and getattr(self, "_OAUTH_NO_CALLBACKS", False):
             raise Exception("This service does not support oauth_callback")
         if http_client is None:
-            http_client = httpclient.AsyncHTTPClient()
+            http_client = self.get_auth_http_client()
         if getattr(self, "_OAUTH_VERSION", "1.0a") == "1.0a":
             http_client.fetch(
                 self._oauth_request_token_url(callback_uri=callback_uri,
@@ -277,7 +285,7 @@
         if oauth_verifier:
             token["verifier"] = oauth_verifier
         if http_client is None:
-            http_client = httpclient.AsyncHTTPClient()
+            http_client = self.get_auth_http_client()
         http_client.fetch(self._oauth_access_token_url(token),
                           self.async_callback(self._on_access_token, callback))
 
@@ -394,6 +402,14 @@
         base_args["oauth_signature"] = signature
         return base_args
 
+    def get_auth_http_client(self):
+        """Returns the AsyncHTTPClient instance to be used for auth requests.
+
+        May be overridden by subclasses to use an http client other than
+        the default.
+        """
+        return httpclient.AsyncHTTPClient()
+
 
 class OAuth2Mixin(object):
     """Abstract implementation of OAuth v 2."""
@@ -471,6 +487,7 @@
     _OAUTH_AUTHORIZE_URL = "http://api.twitter.com/oauth/authorize";
     _OAUTH_AUTHENTICATE_URL = "http://api.twitter.com/oauth/authenticate";
     _OAUTH_NO_CALLBACKS = False
+    _TWITTER_BASE_URL = "http://api.twitter.com/1";
 
     def authenticate_redirect(self, callback_uri=None):
         """Just like authorize_redirect(), but auto-redirects if authorized.
@@ -478,7 +495,7 @@
         This is generally the right interface to use if you are using
         Twitter for single-sign on.
         """
-        http = httpclient.AsyncHTTPClient()
+        http = self.get_auth_http_client()
         http.fetch(self._oauth_request_token_url(callback_uri=callback_uri), 
self.async_callback(
             self._on_request_token, self._OAUTH_AUTHENTICATE_URL, None))
 
@@ -525,7 +542,7 @@
             # usual pattern: http://search.twitter.com/search.json
             url = path
         else:
-            url = "http://api.twitter.com/1"; + path + ".json"
+            url = self._TWITTER_BASE_URL + path + ".json"
         # Add the OAuth resource request signature if we have credentials
         if access_token:
             all_args = {}
@@ -538,7 +555,7 @@
         if args:
             url += "?" + urllib.urlencode(args)
         callback = self.async_callback(self._on_twitter_request, callback)
-        http = httpclient.AsyncHTTPClient()
+        http = self.get_auth_http_client()
         if post_args is not None:
             http.fetch(url, method="POST", body=urllib.urlencode(post_args),
                        callback=callback)
@@ -563,7 +580,7 @@
     def _oauth_get_user(self, access_token, callback):
         callback = self.async_callback(self._parse_user_response, callback)
         self.twitter_request(
-            "/users/show/" + access_token["screen_name"],
+            "/users/show/" + escape.native_str(access_token[b("screen_name")]),
             access_token=access_token, callback=callback)
 
     def _parse_user_response(self, callback, user):
@@ -660,7 +677,7 @@
         if args:
             url += "?" + urllib.urlencode(args)
         callback = self.async_callback(self._on_friendfeed_request, callback)
-        http = httpclient.AsyncHTTPClient()
+        http = self.get_auth_http_client()
         if post_args is not None:
             http.fetch(url, method="POST", body=urllib.urlencode(post_args),
                        callback=callback)
@@ -751,7 +768,7 @@
                 break
         token = self.get_argument("openid." + oauth_ns + ".request_token", "")
         if token:
-            http = httpclient.AsyncHTTPClient()
+            http = self.get_auth_http_client()
             token = dict(key=token, secret="")
             http.fetch(self._oauth_access_token_url(token),
                        self.async_callback(self._on_access_token, callback))
@@ -907,7 +924,7 @@
         args["sig"] = self._signature(args)
         url = "http://api.facebook.com/restserver.php?"; + \
             urllib.urlencode(args)
-        http = httpclient.AsyncHTTPClient()
+        http = self.get_auth_http_client()
         http.fetch(url, callback=self.async_callback(
             self._parse_response, callback))
 
@@ -953,6 +970,14 @@
             body = body.encode("utf-8")
         return hashlib.md5(body).hexdigest()
 
+    def get_auth_http_client(self):
+        """Returns the AsyncHTTPClient instance to be used for auth requests.
+
+        May be overridden by subclasses to use an http client other than
+        the default.
+        """
+        return httpclient.AsyncHTTPClient()
+
 
 class FacebookGraphMixin(OAuth2Mixin):
     """Facebook authentication using the new Graph API and OAuth2."""
@@ -987,7 +1012,7 @@
                 self.finish()
 
         """
-        http = httpclient.AsyncHTTPClient()
+        http = self.get_auth_http_client()
         args = {
           "redirect_uri": redirect_uri,
           "code": code,
@@ -1081,7 +1106,7 @@
         if all_args:
             url += "?" + urllib.urlencode(all_args)
         callback = self.async_callback(self._on_facebook_request, callback)
-        http = httpclient.AsyncHTTPClient()
+        http = self.get_auth_http_client()
         if post_args is not None:
             http.fetch(url, method="POST", body=urllib.urlencode(post_args),
                        callback=callback)
@@ -1096,6 +1121,14 @@
             return
         callback(escape.json_decode(response.body))
 
+    def get_auth_http_client(self):
+        """Returns the AsyncHTTPClient instance to be used for auth requests.
+
+        May be overridden by subclasses to use an http client other than
+        the default.
+        """
+        return httpclient.AsyncHTTPClient()
+
 
 def _oauth_signature(consumer_token, method, url, parameters={}, token=None):
     """Calculates the HMAC-SHA1 OAuth signature for the given request.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/tornado/gen.py 
new/tornado-2.4.1/tornado/gen.py
--- old/tornado-2.4/tornado/gen.py      2012-09-04 06:59:29.000000000 +0200
+++ new/tornado-2.4.1/tornado/gen.py    2012-11-25 03:04:41.000000000 +0100
@@ -354,6 +354,7 @@
                             "finished without waiting for callbacks %r" %
                             self.pending_callbacks)
                     self.deactivate_stack_context()
+                    self.deactivate_stack_context = None
                     return
                 except Exception:
                     self.finished = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/tornado/iostream.py 
new/tornado-2.4.1/tornado/iostream.py
--- old/tornado-2.4/tornado/iostream.py 2012-08-30 17:30:01.000000000 +0200
+++ new/tornado-2.4.1/tornado/iostream.py       2012-11-25 03:04:41.000000000 
+0100
@@ -176,8 +176,14 @@
         a ``streaming_callback`` is not used.
         """
         self._set_read_callback(callback)
+        self._streaming_callback = stack_context.wrap(streaming_callback)
         if self.closed():
-            self._run_callback(callback, self._consume(self._read_buffer_size))
+            if self._streaming_callback is not None:
+                self._run_callback(self._streaming_callback,
+                                   self._consume(self._read_buffer_size))
+            self._run_callback(self._read_callback,
+                               self._consume(self._read_buffer_size))
+            self._streaming_callback = None
             self._read_callback = None
             return
         self._read_until_close = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/tornado/stack_context.py 
new/tornado-2.4.1/tornado/stack_context.py
--- old/tornado-2.4/tornado/stack_context.py    2012-08-30 17:30:01.000000000 
+0200
+++ new/tornado-2.4.1/tornado/stack_context.py  2012-11-25 03:04:41.000000000 
+0100
@@ -161,6 +161,7 @@
                 return self.exception_handler(type, value, traceback)
         finally:
             _state.contexts = self.old_contexts
+            self.old_contexts = None
 
 
 class NullContext(object):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/tornado/test/auth_test.py 
new/tornado-2.4.1/tornado/test/auth_test.py
--- old/tornado-2.4/tornado/test/auth_test.py   2012-08-30 17:30:01.000000000 
+0200
+++ new/tornado-2.4.1/tornado/test/auth_test.py 2012-11-25 03:04:41.000000000 
+0100
@@ -5,7 +5,7 @@
 
 
 from __future__ import absolute_import, division, with_statement
-from tornado.auth import OpenIdMixin, OAuthMixin, OAuth2Mixin
+from tornado.auth import OpenIdMixin, OAuthMixin, OAuth2Mixin, TwitterMixin
 from tornado.escape import json_decode
 from tornado.testing import AsyncHTTPTestCase, LogTrapTestCase
 from tornado.util import b
@@ -101,6 +101,37 @@
         self.authorize_redirect()
 
 
+class TwitterClientLoginHandler(RequestHandler, TwitterMixin):
+    def initialize(self, test):
+        self._OAUTH_REQUEST_TOKEN_URL = 
test.get_url('/oauth1/server/request_token')
+        self._OAUTH_ACCESS_TOKEN_URL = 
test.get_url('/twitter/server/access_token')
+        self._OAUTH_AUTHORIZE_URL = test.get_url('/oauth1/server/authorize')
+        self._TWITTER_BASE_URL = test.get_url('/twitter/api')
+
+    @asynchronous
+    def get(self):
+        if self.get_argument("oauth_token", None):
+            self.get_authenticated_user(self.on_user)
+            return
+        self.authorize_redirect()
+
+    def on_user(self, user):
+        if user is None:
+            raise Exception("user is None")
+        self.finish(user)
+
+    def get_auth_http_client(self):
+        return self.settings['http_client']
+
+
+class TwitterServerAccessTokenHandler(RequestHandler):
+    def get(self):
+        self.write('oauth_token=hjkl&oauth_token_secret=vbnm&screen_name=foo')
+
+class TwitterServerShowUserHandler(RequestHandler):
+    def get(self, screen_name):
+        self.write(dict(screen_name=screen_name, 
name=screen_name.capitalize()))
+
 class AuthTest(AsyncHTTPTestCase, LogTrapTestCase):
     def get_app(self):
         return Application(
@@ -119,12 +150,19 @@
                  dict(version='1.0a')),
                 ('/oauth2/client/login', OAuth2ClientLoginHandler, 
dict(test=self)),
 
+                ('/twitter/client/login', TwitterClientLoginHandler, 
dict(test=self)),
+
                 # simulated servers
                 ('/openid/server/authenticate', 
OpenIdServerAuthenticateHandler),
                 ('/oauth1/server/request_token', 
OAuth1ServerRequestTokenHandler),
                 ('/oauth1/server/access_token', 
OAuth1ServerAccessTokenHandler),
+
+                ('/twitter/server/access_token', 
TwitterServerAccessTokenHandler),
+                (r'/twitter/api/users/show/(.*)\.json', 
TwitterServerShowUserHandler),
                 ],
-            http_client=self.http_client)
+            http_client=self.http_client,
+            twitter_consumer_key='test_twitter_consumer_key',
+            twitter_consumer_secret='test_twitter_consumer_secret')
 
     def test_openid_redirect(self):
         response = self.fetch('/openid/client/login', follow_redirects=False)
@@ -198,3 +236,28 @@
         response = self.fetch('/oauth2/client/login', follow_redirects=False)
         self.assertEqual(response.code, 302)
         self.assertTrue('/oauth2/server/authorize?' in 
response.headers['Location'])
+
+    def test_twitter_redirect(self):
+        # Same as test_oauth10a_redirect
+        response = self.fetch('/twitter/client/login', follow_redirects=False)
+        self.assertEqual(response.code, 302)
+        self.assertTrue(response.headers['Location'].endswith(
+            '/oauth1/server/authorize?oauth_token=zxcv'))
+        # the cookie is base64('zxcv')|base64('1234')
+        self.assertTrue(
+            '_oauth_request_token="enhjdg==|MTIzNA=="' in 
response.headers['Set-Cookie'],
+            response.headers['Set-Cookie'])
+
+    def test_twitter_get_user(self):
+        response = self.fetch(
+            '/twitter/client/login?oauth_token=zxcv',
+            headers={'Cookie': '_oauth_request_token=enhjdg==|MTIzNA=='})
+        response.rethrow()
+        parsed = json_decode(response.body)
+        self.assertEqual(parsed,
+                         {u'access_token': {u'key': u'hjkl',
+                                            u'screen_name': u'foo',
+                                            u'secret': u'vbnm'},
+                          u'name': u'Foo',
+                          u'screen_name': u'foo',
+                          u'username': u'foo'})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/tornado/test/gen_test.py 
new/tornado-2.4.1/tornado/test/gen_test.py
--- old/tornado-2.4/tornado/test/gen_test.py    2012-08-30 17:30:01.000000000 
+0200
+++ new/tornado-2.4.1/tornado/test/gen_test.py  2012-11-25 03:04:41.000000000 
+0100
@@ -269,6 +269,28 @@
         initial_stack_depth = len(stack_context._state.contexts)
         self.run_gen(outer)
 
+    def test_stack_context_leak_exception(self):
+        # same as previous, but with a function that exits with an exception
+        from tornado import stack_context
+
+        @gen.engine
+        def inner(callback):
+            yield gen.Task(self.io_loop.add_callback)
+            1 / 0
+
+        @gen.engine
+        def outer():
+            for i in xrange(10):
+                try:
+                    yield gen.Task(inner)
+                except ZeroDivisionError:
+                    pass
+            stack_increase = len(stack_context._state.contexts) - 
initial_stack_depth
+            self.assertTrue(stack_increase <= 2)
+            self.stop()
+        initial_stack_depth = len(stack_context._state.contexts)
+        self.run_gen(outer)
+
 
 class GenSequenceHandler(RequestHandler):
     @asynchronous
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/tornado/test/iostream_test.py 
new/tornado-2.4.1/tornado/test/iostream_test.py
--- old/tornado-2.4/tornado/test/iostream_test.py       2012-09-04 
06:59:29.000000000 +0200
+++ new/tornado-2.4.1/tornado/test/iostream_test.py     2012-11-25 
03:04:41.000000000 +0100
@@ -296,6 +296,42 @@
             server.close()
             client.close()
 
+    def test_read_until_close_after_close(self):
+        # Similar to test_delayed_close_callback, but read_until_close takes
+        # a separate code path so test it separately.
+        server, client = self.make_iostream_pair()
+        client.set_close_callback(self.stop)
+        try:
+            server.write(b("1234"))
+            server.close()
+            self.wait()
+            client.read_until_close(self.stop)
+            data = self.wait()
+            self.assertEqual(data, b("1234"))
+        finally:
+            server.close()
+            client.close()
+
+    def test_streaming_read_until_close_after_close(self):
+        # Same as the preceding test but with a streaming_callback.
+        # All data should go through the streaming callback,
+        # and the final read callback just gets an empty string.
+        server, client = self.make_iostream_pair()
+        client.set_close_callback(self.stop)
+        try:
+            server.write(b("1234"))
+            server.close()
+            self.wait()
+            streaming_data = []
+            client.read_until_close(self.stop,
+                                    streaming_callback=streaming_data.append)
+            data = self.wait()
+            self.assertEqual(b(''), data)
+            self.assertEqual(b('').join(streaming_data), b("1234"))
+        finally:
+            server.close()
+            client.close()
+
     def test_large_read_until(self):
         # Performance test: read_until used to have a quadratic component
         # so a read_until of 4MB would take 8 seconds; now it takes 0.25
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/tornado-2.4/tornado.egg-info/PKG-INFO 
new/tornado-2.4.1/tornado.egg-info/PKG-INFO
--- old/tornado-2.4/tornado.egg-info/PKG-INFO   2012-09-04 07:10:19.000000000 
+0200
+++ new/tornado-2.4.1/tornado.egg-info/PKG-INFO 2012-11-25 03:28:45.000000000 
+0100
@@ -1,11 +1,11 @@
 Metadata-Version: 1.1
 Name: tornado
-Version: 2.4
+Version: 2.4.1
 Summary: Tornado is an open source version of the scalable, non-blocking web 
server and and tools that power FriendFeed
 Home-page: http://www.tornadoweb.org/
 Author: Facebook
 Author-email: [email protected]
 License: http://www.apache.org/licenses/LICENSE-2.0
-Download-URL: http://github.com/downloads/facebook/tornado/tornado-2.4.tar.gz
+Download-URL: http://github.com/downloads/facebook/tornado/tornado-2.4.1.tar.gz
 Description: UNKNOWN
 Platform: UNKNOWN

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to