diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2016-04-30 11:45:18 -0400 |
---|---|---|
committer | Jason R. Coombs <jaraco@jaraco.com> | 2016-04-30 11:45:18 -0400 |
commit | baf1cfad6a76e98adc078f36a70a5ceecd6138fb (patch) | |
tree | 61ccef2f4f66a3fb56863db1d03098deb24c4439 | |
parent | 32a163ca17e1c3d78945ad2214e6c1fb5a8e0bf1 (diff) | |
parent | 7f77d77d18234382582c8a3a3e2a526841e900ba (diff) | |
download | cherrypy-baf1cfad6a76e98adc078f36a70a5ceecd6138fb.tar.gz |
Merge https://bitbucket.org/cherrypy/cherrypy/pull-requests/125/
-rw-r--r-- | .travis.yml | 20 | ||||
-rw-r--r-- | CHANGES.txt | 15 | ||||
-rw-r--r-- | CONTRIBUTING.txt | 2 | ||||
-rw-r--r-- | cherrypy/__init__.py | 13 | ||||
-rw-r--r-- | cherrypy/_cpdispatch.py | 4 | ||||
-rw-r--r-- | cherrypy/_cpreqbody.py | 2 | ||||
-rw-r--r-- | cherrypy/_cptools.py | 4 | ||||
-rw-r--r-- | cherrypy/lib/caching.py | 2 | ||||
-rw-r--r-- | cherrypy/lib/httputil.py | 2 | ||||
-rw-r--r-- | cherrypy/lib/sessions.py | 2 | ||||
-rw-r--r-- | cherrypy/process/wspbus.py | 6 | ||||
-rw-r--r-- | cherrypy/test/test_config_server.py | 2 | ||||
-rw-r--r-- | cherrypy/test/test_conn.py | 2 | ||||
-rw-r--r-- | cherrypy/test/test_core.py | 4 | ||||
-rw-r--r-- | cherrypy/test/test_http.py | 4 | ||||
-rw-r--r-- | cherrypy/test/test_mime.py | 2 | ||||
-rw-r--r-- | cherrypy/test/test_objectmapping.py | 4 | ||||
-rw-r--r-- | cherrypy/test/test_proxy.py | 2 | ||||
-rw-r--r-- | cherrypy/test/test_request_obj.py | 10 | ||||
-rw-r--r-- | cherrypy/test/test_xmlrpc.py | 2 | ||||
-rw-r--r-- | cherrypy/wsgiserver/ssl_builtin.py | 27 | ||||
-rw-r--r-- | cherrypy/wsgiserver/wsgiserver2.py | 32 | ||||
-rw-r--r-- | cherrypy/wsgiserver/wsgiserver3.py | 32 | ||||
-rw-r--r-- | docs/install.rst | 6 | ||||
-rw-r--r-- | docs/tutorials.rst | 3 | ||||
-rw-r--r-- | release.py | 62 | ||||
-rw-r--r-- | setup.cfg | 26 | ||||
-rw-r--r-- | setup.py | 2 |
28 files changed, 168 insertions, 126 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..18b91098 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +language: python +python: +- 2.6 +- 2.7 +- 3.2 +- 3.3 +- 3.4 +- 3.5 +script: +- nosetests -s . +deploy: + provider: pypi + on: + tags: true + all_branches: true + python: 3.5 + user: jaraco + password: + secure: CQqUvtssQ4wmRluPcxh6m5lIXi83Qu9dAFAvZLS/+AQNIG78XECXv5xFTEdGSLX9yncKDpDKI3xRJeCKyO4OJUN0t6W1MRycY72+R63i9e9wPjfvtRqYH1TBT+no7jj/DHqXIrWSlpjRNAt4XXeSv7OzKWT4PmTNkNQSKyS1DWCmZGlbCKlV774Z9PbrfltflxL0V6DiX6ZfoY1THBO4rIopjMk/MPLgS5zvwLgXVbT9sK/DcPOgOq47iSLCs0oScbwiFzYW4DbcVZrBMv4ALtQTjk6ZEaBQ7KtKgsyxgi/ToVhjRxYg4rwvhjsyjixUdECLUqL3WgWfzW/lo82lhb79ERwhnjf1DvPNexlXhv9hHwHsFROpaOmM0nyDJsJg0rCNPVfO4SpBHEnd/ujlHO6yorHj0S54jZWqqDwD5gN19v3hEMT48Pc8uvazE9K1kMQbNXEzqn+SJjVB+DG7qK5Jm9Kk7ZC4R88hJAJNsR+SlFCXMGzkS9WUefUGLHQFfezZk43sMPIXMnh9d2XqCQo4QpUawdg3pwaTukFfyaHlK39CIHhZNas5D/UFL5spQPAAkH1IMcPILiSUwYYnXIJFWJIiulfEQalJroAQjrzvst/NVB8BbeYuCfmVLVOZw8Y6GOYONGgiXjT3nfmw/dN+uw+GY3EgAV5jl+fa434= + distributions: release diff --git a/CHANGES.txt b/CHANGES.txt index 2652b6d6..af9c7322 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,18 @@ +5.3.0 +----- + +* #1202: Add support for specifying a certificate authority when + serving SSL using the built-in SSL support. +* Use ssl.create_default_context when available. +* #1392: Catch platform-specific socket errors on OS X. +* #1386: Fix parsing of URIs containing ``://`` in the path part. + +5.2.0 +----- + +* #1410: Moved hosting to Github ( + `cherrypy/cherrypy <https://github.com/cherrypy/cherrypy>`_. + 5.1.0 ----- diff --git a/CONTRIBUTING.txt b/CONTRIBUTING.txt index 6c653f75..c321e13a 100644 --- a/CONTRIBUTING.txt +++ b/CONTRIBUTING.txt @@ -3,4 +3,4 @@ CherryPy is a community-maintained, open-source project hosted at Bitbucket. To contribute, first read `How to write the perfect pull request <http://blog.jaraco.com/2014/04/how-to-write-perfect-pull-request.html>`_ and file your contribution with the `CherryPy Project page -<https://bitbucket.org/cherrypy/cherrypy>`_. +<https://github.com/cherrypy/cherrypy>`_. diff --git a/cherrypy/__init__.py b/cherrypy/__init__.py index 6e2f9bdb..30a8cadf 100644 --- a/cherrypy/__init__.py +++ b/cherrypy/__init__.py @@ -56,7 +56,10 @@ with customized or extended components. The core API's are: These API's are described in the `CherryPy specification <https://bitbucket.org/cherrypy/cherrypy/wiki/CherryPySpec>`_. """ -__version__ = "5.1.0" +try: + import pkg_resources +except ImportError: + pass from cherrypy._cpcompat import urljoin as _urljoin, urlencode as _urlencode from cherrypy._cpcompat import basestring, unicodestr @@ -88,6 +91,12 @@ except ImportError: engine = process.bus +try: + __version__ = pkg_resources.require('cherrypy')[0].version +except Exception: + __version__ = 'unknown' + + # Timeout monitor. We add two channels to the engine # to which cherrypy.Application will publish. engine.listeners['before_request'] = set() @@ -318,7 +327,7 @@ class _GlobalLogManager(_cplogging.LogManager): """Log the given message to the app.log or global log as appropriate. """ # Do NOT use try/except here. See - # https://bitbucket.org/cherrypy/cherrypy/issue/945 + # https://github.com/cherrypy/cherrypy/issues/945 if hasattr(request, 'app') and hasattr(request.app, 'log'): log = request.app.log else: diff --git a/cherrypy/_cpdispatch.py b/cherrypy/_cpdispatch.py index 710bb3fd..2cb03c7e 100644 --- a/cherrypy/_cpdispatch.py +++ b/cherrypy/_cpdispatch.py @@ -422,7 +422,7 @@ class Dispatcher(object): object_trail.insert( i + 1, ["default", defhandler, conf, segleft]) request.config = set_conf() - # See https://bitbucket.org/cherrypy/cherrypy/issue/613 + # See https://github.com/cherrypy/cherrypy/issues/613 request.is_index = path.endswith("/") return defhandler, fullpath[fullpath_len - segleft:-1] @@ -675,7 +675,7 @@ def VirtualHost(next_dispatcher=Dispatcher(), use_x_forwarded_host=True, result = next_dispatcher(path_info) # Touch up staticdir config. See - # https://bitbucket.org/cherrypy/cherrypy/issue/614. + # https://github.com/cherrypy/cherrypy/issues/614. section = request.config.get('tools.staticdir.section') if section: section = section[len(prefix):] diff --git a/cherrypy/_cpreqbody.py b/cherrypy/_cpreqbody.py index d2dbbc92..13a8adb7 100644 --- a/cherrypy/_cpreqbody.py +++ b/cherrypy/_cpreqbody.py @@ -940,7 +940,7 @@ class RequestBody(Entity): # Don't parse the request body at all if the client didn't provide # a Content-Type header. See - # https://bitbucket.org/cherrypy/cherrypy/issue/790 + # https://github.com/cherrypy/cherrypy/issues/790 default_content_type = '' """This defines a default ``Content-Type`` to use if no Content-Type header is given. The empty string is used for RequestBody, which results in the diff --git a/cherrypy/_cptools.py b/cherrypy/_cptools.py index 06a56e87..af76ae06 100644 --- a/cherrypy/_cptools.py +++ b/cherrypy/_cptools.py @@ -271,7 +271,7 @@ class SessionTool(Tool): body. This is off by default for safety reasons; for example, a large upload would block the session, denying an AJAX progress meter - (`issue <https://bitbucket.org/cherrypy/cherrypy/issue/630>`_). + (`issue <https://github.com/cherrypy/cherrypy/issues/630>`_). When 'explicit' (or any other value), you need to call cherrypy.session.acquire_lock() yourself before using @@ -376,7 +376,7 @@ class XMLRPCController(object): body = subhandler(*(vpath + rpcparams), **params) else: - # https://bitbucket.org/cherrypy/cherrypy/issue/533 + # https://github.com/cherrypy/cherrypy/issues/533 # if a method is not found, an xmlrpclib.Fault should be returned # raising an exception here will do that; see # cherrypy.lib.xmlrpcutil.on_error diff --git a/cherrypy/lib/caching.py b/cherrypy/lib/caching.py index fab6b569..375d5f0e 100644 --- a/cherrypy/lib/caching.py +++ b/cherrypy/lib/caching.py @@ -353,7 +353,7 @@ def get(invalid_methods=("POST", "PUT", "DELETE"), debug=False, **kwargs): return False # Copy the response headers. See - # https://bitbucket.org/cherrypy/cherrypy/issue/721. + # https://github.com/cherrypy/cherrypy/issues/721. response.headers = rh = httputil.HeaderMap() for k in h: dict.__setitem__(rh, k, dict.__getitem__(h, k)) diff --git a/cherrypy/lib/httputil.py b/cherrypy/lib/httputil.py index 69a18d45..f249e6dd 100644 --- a/cherrypy/lib/httputil.py +++ b/cherrypy/lib/httputil.py @@ -13,7 +13,7 @@ from cherrypy._cpcompat import basestring, bytestr, iteritems, nativestr from cherrypy._cpcompat import reversed, sorted, unicodestr, unquote_qs response_codes = BaseHTTPRequestHandler.responses.copy() -# From https://bitbucket.org/cherrypy/cherrypy/issue/361 +# From https://github.com/cherrypy/cherrypy/issues/361 response_codes[500] = ('Internal Server Error', 'The server encountered an unexpected condition ' 'which prevented it from fulfilling the request.') diff --git a/cherrypy/lib/sessions.py b/cherrypy/lib/sessions.py index 37556363..e9605cb8 100644 --- a/cherrypy/lib/sessions.py +++ b/cherrypy/lib/sessions.py @@ -182,7 +182,7 @@ class Session(object): cherrypy.log('Expired or malicious session %r; ' 'making a new one' % id, 'TOOLS.SESSIONS') # Expired or malicious session. Make a new one. - # See https://bitbucket.org/cherrypy/cherrypy/issue/709. + # See https://github.com/cherrypy/cherrypy/issues/709. self.id = None self.missing = True self._regenerate() diff --git a/cherrypy/process/wspbus.py b/cherrypy/process/wspbus.py index c9de3511..9c9a2739 100644 --- a/cherrypy/process/wspbus.py +++ b/cherrypy/process/wspbus.py @@ -85,7 +85,7 @@ class ChannelFailures(Exception): def __init__(self, *args, **kwargs): # Don't use 'super' here; Exceptions are old-style in Py2.4 - # See https://bitbucket.org/cherrypy/cherrypy/issue/959 + # See https://github.com/cherrypy/cherrypy/issues/959 Exception.__init__(self, *args, **kwargs) self._exceptions = list() @@ -317,10 +317,10 @@ class Bus(object): raise # Waiting for ALL child threads to finish is necessary on OS X. - # See https://bitbucket.org/cherrypy/cherrypy/issue/581. + # See https://github.com/cherrypy/cherrypy/issues/581. # It's also good to let them all shut down before allowing # the main thread to call atexit handlers. - # See https://bitbucket.org/cherrypy/cherrypy/issue/751. + # See https://github.com/cherrypy/cherrypy/issues/751. self.log("Waiting for child threads to terminate...") for t in threading.enumerate(): # Validate the we're not trying to join the MainThread diff --git a/cherrypy/test/test_config_server.py b/cherrypy/test/test_config_server.py index 40504d8f..f4f574de 100644 --- a/cherrypy/test/test_config_server.py +++ b/cherrypy/test/test_config_server.py @@ -93,7 +93,7 @@ class ServerConfigTests(helper.CPWebCase): self.getPage("/", headers=[('From', "x" * 500)]) self.assertStatus(413) - # Test for https://bitbucket.org/cherrypy/cherrypy/issue/421 + # Test for https://github.com/cherrypy/cherrypy/issues/421 # (Incorrect border condition in readline of SizeCheckWrapper). # This hangs in rev 891 and earlier. lines256 = "x" * 248 diff --git a/cherrypy/test/test_conn.py b/cherrypy/test/test_conn.py index 6577e03a..3e0cbc16 100644 --- a/cherrypy/test/test_conn.py +++ b/cherrypy/test/test_conn.py @@ -205,7 +205,7 @@ class ConnectionCloseTests(helper.CPWebCase): self.assertRaises(NotConnected, self.getPage, "/") # Try HEAD. See - # https://bitbucket.org/cherrypy/cherrypy/issue/864. + # https://github.com/cherrypy/cherrypy/issues/864. self.getPage("/stream", method='HEAD') self.assertStatus('200 OK') self.assertBody('') diff --git a/cherrypy/test/test_core.py b/cherrypy/test/test_core.py index 4ebc170a..16a0219d 100644 --- a/cherrypy/test/test_core.py +++ b/cherrypy/test/test_core.py @@ -403,7 +403,7 @@ class CoreRequestHandlingTest(helper.CPWebCase): self.assertStatus(('302 Found', '303 See Other')) # check injection protection - # See https://bitbucket.org/cherrypy/cherrypy/issue/1003 + # See https://github.com/cherrypy/cherrypy/issues/1003 self.getPage( "/redirect/custom?" "code=303&url=/foobar/%0d%0aSet-Cookie:%20somecookie=someval") @@ -551,7 +551,7 @@ class CoreRequestHandlingTest(helper.CPWebCase): def skip_if_bad_cookies(self): """ cookies module fails to reject invalid cookies - https://bitbucket.org/cherrypy/cherrypy/issues/1405 + https://github.com/cherrypy/cherrypy/issues/1405 """ cookies = sys.modules.get('http.cookies') _is_legal_key = getattr(cookies, '_is_legal_key', lambda x: False) diff --git a/cherrypy/test/test_http.py b/cherrypy/test/test_http.py index 0df589fa..46ae226c 100644 --- a/cherrypy/test/test_http.py +++ b/cherrypy/test/test_http.py @@ -150,7 +150,7 @@ class HTTPTests(helper.CPWebCase): def test_post_filename_with_commas(self): '''Testing that we can handle filenames with commas. This was reported as a bug in: - https://bitbucket.org/cherrypy/cherrypy/issue/1146/''' + https://github.com/cherrypy/cherrypy/issues/1146/''' # We'll upload a bunch of files with differing names. for fname in ['boop.csv', 'foo, bar.csv', 'bar, xxxx.csv', 'file"name.csv']: files = [('myfile', fname, 'yunyeenyunyue')] @@ -200,7 +200,7 @@ class HTTPTests(helper.CPWebCase): c = self.make_connection() c.putrequest('GET', '/') c.putheader('Content-Type', 'text/plain') - # See https://bitbucket.org/cherrypy/cherrypy/issue/941 + # See https://github.com/cherrypy/cherrypy/issues/941 c._output(ntob('Re, 1.2.3.4#015#012')) c.endheaders() diff --git a/cherrypy/test/test_mime.py b/cherrypy/test/test_mime.py index f5f2b9fb..ca2f9c63 100644 --- a/cherrypy/test/test_mime.py +++ b/cherrypy/test/test_mime.py @@ -74,7 +74,7 @@ This is the <strong>HTML</strong> version '--X', # Test a param with more than one value. # See - # https://bitbucket.org/cherrypy/cherrypy/issue/1028 + # https://github.com/cherrypy/cherrypy/issues/1028 'Content-Disposition: form-data; name="baz"', '', '111', diff --git a/cherrypy/test/test_objectmapping.py b/cherrypy/test/test_objectmapping.py index e80a7a71..a24e84e1 100644 --- a/cherrypy/test/test_objectmapping.py +++ b/cherrypy/test/test_objectmapping.py @@ -281,7 +281,7 @@ class ObjectMappingTest(helper.CPWebCase): # Make sure /foobar maps to Root.foobar and not to the app # mounted at /foo. See - # https://bitbucket.org/cherrypy/cherrypy/issue/573 + # https://github.com/cherrypy/cherrypy/issues/573 self.getPage("/foobar") self.assertBody("bar") @@ -332,7 +332,7 @@ class ObjectMappingTest(helper.CPWebCase): self.assertBody("default for dir1, param is:('dir2', '5', '3', 'sir')") # test that extra positional args raises an 404 Not Found - # See https://bitbucket.org/cherrypy/cherrypy/issue/733. + # See https://github.com/cherrypy/cherrypy/issues/733. self.getPage("/dir1/dir2/script_name/extra/stuff") self.assertStatus(404) diff --git a/cherrypy/test/test_proxy.py b/cherrypy/test/test_proxy.py index 821a4e52..bdc5eada 100644 --- a/cherrypy/test/test_proxy.py +++ b/cherrypy/test/test_proxy.py @@ -131,7 +131,7 @@ class ProxyTest(helper.CPWebCase): self.assertBody(expected) # Test trailing slash (see - # https://bitbucket.org/cherrypy/cherrypy/issue/562). + # https://github.com/cherrypy/cherrypy/issues/562). self.getPage("/xhost/", headers=[('X-Host', 'www.example.test')]) self.assertHeader('Location', "%s://www.example.test/xhost" % self.scheme) diff --git a/cherrypy/test/test_request_obj.py b/cherrypy/test/test_request_obj.py index a74ddddf..58736b54 100644 --- a/cherrypy/test/test_request_obj.py +++ b/cherrypy/test/test_request_obj.py @@ -184,7 +184,7 @@ class RequestObjectTests(helper.CPWebCase): return cherrypy.request.headers[headername] def doubledheaders(self): - # From https://bitbucket.org/cherrypy/cherrypy/issue/165: + # From https://github.com/cherrypy/cherrypy/issues/165: # "header field names should not be case sensitive sayes the # rfc. if i set a headerfield in complete lowercase i end up # with two header fields, one in lowercase, the other in @@ -643,7 +643,7 @@ class RequestObjectTests(helper.CPWebCase): "en;q=0.7") # Test malformed header parsing. See - # https://bitbucket.org/cherrypy/cherrypy/issue/763. + # https://github.com/cherrypy/cherrypy/issues/763. self.getPage("/headerelements/get_elements?headername=Content-Type", # Note the illegal trailing ";" headers=[('Content-Type', 'text/html; charset=utf-8;')]) @@ -652,7 +652,7 @@ class RequestObjectTests(helper.CPWebCase): def test_repeated_headers(self): # Test that two request headers are collapsed into one. - # See https://bitbucket.org/cherrypy/cherrypy/issue/542. + # See https://github.com/cherrypy/cherrypy/issues/542. self.getPage("/headers/Accept-Charset", headers=[("Accept-Charset", "iso-8859-5"), ("Accept-Charset", "unicode-1-1;q=0.8")]) @@ -738,7 +738,7 @@ class RequestObjectTests(helper.CPWebCase): self.assertBody(b) # Request a PUT method with a file body but no Content-Type. - # See https://bitbucket.org/cherrypy/cherrypy/issue/790. + # See https://github.com/cherrypy/cherrypy/issues/790. b = ntob("one thing on top of another") self.persistent = True try: @@ -757,7 +757,7 @@ class RequestObjectTests(helper.CPWebCase): self.persistent = False # Request a PUT method with no body whatsoever (not an empty one). - # See https://bitbucket.org/cherrypy/cherrypy/issue/650. + # See https://github.com/cherrypy/cherrypy/issues/650. # Provide a C-T or webtest will provide one (and a C-L) for us. h = [("Content-Type", "text/plain")] self.getPage("/method/reachable", headers=h, method="PUT") diff --git a/cherrypy/test/test_xmlrpc.py b/cherrypy/test/test_xmlrpc.py index 8f091ff1..4beed0a3 100644 --- a/cherrypy/test/test_xmlrpc.py +++ b/cherrypy/test/test_xmlrpc.py @@ -163,7 +163,7 @@ class XmlRpcTest(helper.CPWebCase): else: self.fail("Expected xmlrpclib.Fault") - # https://bitbucket.org/cherrypy/cherrypy/issue/533 + # https://github.com/cherrypy/cherrypy/issues/533 # if a method is not found, an xmlrpclib.Fault should be raised try: proxy.non_method() diff --git a/cherrypy/wsgiserver/ssl_builtin.py b/cherrypy/wsgiserver/ssl_builtin.py index 2c74ad84..3faf7039 100644 --- a/cherrypy/wsgiserver/ssl_builtin.py +++ b/cherrypy/wsgiserver/ssl_builtin.py @@ -33,6 +33,14 @@ class BuiltinSSLAdapter(wsgiserver.SSLAdapter): private_key = None """The filename of the server's private key file.""" + + certificate_chain = None + """The filename of the certificate chain file.""" + + """The ssl.SSLContext that will be used to wrap sockets where available + (on Python > 2.7.9 / 3.3) + """ + context = None def __init__(self, certificate, private_key, certificate_chain=None): if ssl is None: @@ -40,6 +48,12 @@ class BuiltinSSLAdapter(wsgiserver.SSLAdapter): self.certificate = certificate self.private_key = private_key self.certificate_chain = certificate_chain + if hasattr(ssl, 'create_default_context'): + self.context = ssl.create_default_context( + purpose=ssl.Purpose.CLIENT_AUTH, + cafile=certificate_chain + ) + self.context.load_cert_chain(certificate, private_key) def bind(self, sock): """Wrap and return the given socket.""" @@ -48,10 +62,15 @@ class BuiltinSSLAdapter(wsgiserver.SSLAdapter): def wrap(self, sock): """Wrap and return the given socket, plus WSGI environ entries.""" try: - s = ssl.wrap_socket(sock, do_handshake_on_connect=True, - server_side=True, certfile=self.certificate, - keyfile=self.private_key, - ssl_version=ssl.PROTOCOL_SSLv23) + if self.context is not None: + s = self.context.wrap_socket(sock,do_handshake_on_connect=True, + server_side=True) + else: + s = ssl.wrap_socket(sock, do_handshake_on_connect=True, + server_side=True, certfile=self.certificate, + keyfile=self.private_key, + ssl_version=ssl.PROTOCOL_SSLv23, + ca_certs=self.certificate_chain) except ssl.SSLError: e = sys.exc_info()[1] if e.errno == ssl.SSL_ERROR_EOF: diff --git a/cherrypy/wsgiserver/wsgiserver2.py b/cherrypy/wsgiserver/wsgiserver2.py index 7bcf216f..a386d73d 100644 --- a/cherrypy/wsgiserver/wsgiserver2.py +++ b/cherrypy/wsgiserver/wsgiserver2.py @@ -103,6 +103,10 @@ except ImportError: # Python 2.6 import io +try: + import pkg_resources +except ImportError: + pass if 'win' in sys.platform and hasattr(socket, "AF_INET6"): if not hasattr(socket, 'IPPROTO_IPV6'): @@ -114,6 +118,12 @@ if 'win' in sys.platform and hasattr(socket, "AF_INET6"): DEFAULT_BUFFER_SIZE = io.DEFAULT_BUFFER_SIZE +try: + cp_version = pkg_resources.require('cherrypy')[0].version +except Exception: + cp_version = 'unknown' + + class FauxSocket(object): """Faux socket with the minimal interface required by pypy""" @@ -192,6 +202,8 @@ socket_errors_to_ignore = plat_specific_errors( ) socket_errors_to_ignore.append("timed out") socket_errors_to_ignore.append("The read operation timed out") +if sys.platform == 'darwin': + socket_errors_to_ignore.append(plat_specific_errors("EPROTOTYPE")) socket_errors_nonblocking = plat_specific_errors( 'EAGAIN', 'EWOULDBLOCK', 'WSAEWOULDBLOCK') @@ -298,7 +310,7 @@ class SizeCheckWrapper(object): self.bytes_read += len(data) self._check_length() res.append(data) - # See https://bitbucket.org/cherrypy/cherrypy/issue/421 + # See https://github.com/cherrypy/cherrypy/issues/421 if len(data) < 256 or data[-1:] == LF: return EMPTY.join(res) @@ -798,7 +810,7 @@ class HTTPRequest(object): if self.inheaders.get("Expect", "") == "100-continue": # Don't use simple_response here, because it emits headers # we don't want. See - # https://bitbucket.org/cherrypy/cherrypy/issue/951 + # https://github.com/cherrypy/cherrypy/issues/951 msg = self.server.protocol + " 100 Continue\r\n\r\n" try: self.conn.wfile.sendall(msg) @@ -1361,7 +1373,7 @@ class HTTPConnection(object): # Don't error if we're between requests; only error # if 1) no request has been started at all, or 2) we're # in the middle of a request. - # See https://bitbucket.org/cherrypy/cherrypy/issue/853 + # See https://github.com/cherrypy/cherrypy/issues/853 if (not request_seen) or (req and req.started_request): # Don't bother writing the 408 if the response # has already started being written. @@ -1654,7 +1666,7 @@ class ThreadPool(object): except (AssertionError, # Ignore repeated Ctrl-C. # See - # https://bitbucket.org/cherrypy/cherrypy/issue/691. + # https://github.com/cherrypy/cherrypy/issues/691. KeyboardInterrupt): pass @@ -1754,7 +1766,7 @@ class HTTPServer(object): timeout = 10 """The timeout in seconds for accepted connections (default 10).""" - version = "CherryPy/5.1.0" + version = "CherryPy/" + cp_version """A version string for the HTTPServer.""" software = None @@ -1979,7 +1991,7 @@ class HTTPServer(object): # If listening on the IPV6 any address ('::' = IN6ADDR_ANY), # activate dual-stack. See - # https://bitbucket.org/cherrypy/cherrypy/issue/871. + # https://github.com/cherrypy/cherrypy/issues/871. if (hasattr(socket, 'AF_INET6') and family == socket.AF_INET6 and self.bind_addr[0] in ('::', '::0', '::0.0.0.0')): try: @@ -2073,15 +2085,15 @@ class HTTPServer(object): # the call, and I *think* I'm reading it right that Python # will then go ahead and poll for and handle the signal # elsewhere. See - # https://bitbucket.org/cherrypy/cherrypy/issue/707. + # https://github.com/cherrypy/cherrypy/issues/707. return if x.args[0] in socket_errors_nonblocking: # Just try again. See - # https://bitbucket.org/cherrypy/cherrypy/issue/479. + # https://github.com/cherrypy/cherrypy/issues/479. return if x.args[0] in socket_errors_to_ignore: # Our socket was closed. - # See https://bitbucket.org/cherrypy/cherrypy/issue/686. + # See https://github.com/cherrypy/cherrypy/issues/686. return raise @@ -2114,7 +2126,7 @@ class HTTPServer(object): if x.args[0] not in socket_errors_to_ignore: # Changed to use error code and not message # See - # https://bitbucket.org/cherrypy/cherrypy/issue/860. + # https://github.com/cherrypy/cherrypy/issues/860. raise else: # Note that we're explicitly NOT using AI_PASSIVE, diff --git a/cherrypy/wsgiserver/wsgiserver3.py b/cherrypy/wsgiserver/wsgiserver3.py index b7ee36e3..7b89489e 100644 --- a/cherrypy/wsgiserver/wsgiserver3.py +++ b/cherrypy/wsgiserver/wsgiserver3.py @@ -101,6 +101,10 @@ except ImportError: # Python 2.6 import io +try: + import pkg_resources +except ImportError: + pass if 'win' in sys.platform and hasattr(socket, "AF_INET6"): if not hasattr(socket, 'IPPROTO_IPV6'): @@ -112,6 +116,12 @@ if 'win' in sys.platform and hasattr(socket, "AF_INET6"): DEFAULT_BUFFER_SIZE = io.DEFAULT_BUFFER_SIZE +try: + cp_version = pkg_resources.require('cherrypy')[0].version +except Exception: + cp_version = 'unknown' + + if sys.version_info >= (3, 0): bytestr = bytes unicodestr = str @@ -178,6 +188,8 @@ socket_errors_to_ignore = plat_specific_errors( ) socket_errors_to_ignore.append("timed out") socket_errors_to_ignore.append("The read operation timed out") +if sys.platform == 'darwin': + socket_errors_to_ignore.append(plat_specific_errors("EPROTOTYPE")) socket_errors_nonblocking = plat_specific_errors( 'EAGAIN', 'EWOULDBLOCK', 'WSAEWOULDBLOCK') @@ -284,7 +296,7 @@ class SizeCheckWrapper(object): self.bytes_read += len(data) self._check_length() res.append(data) - # See https://bitbucket.org/cherrypy/cherrypy/issue/421 + # See https://github.com/cherrypy/cherrypy/issues/421 if len(data) < 256 or data[-1:] == LF: return EMPTY.join(res) @@ -787,7 +799,7 @@ class HTTPRequest(object): if self.inheaders.get(b"Expect", b"") == b"100-continue": # Don't use simple_response here, because it emits headers # we don't want. See - # https://bitbucket.org/cherrypy/cherrypy/issue/951 + # https://github.com/cherrypy/cherrypy/issues/951 msg = self.server.protocol.encode( 'ascii') + b" 100 Continue\r\n\r\n" try: @@ -1090,7 +1102,7 @@ class HTTPConnection(object): # Don't error if we're between requests; only error # if 1) no request has been started at all, or 2) we're # in the middle of a request. - # See https://bitbucket.org/cherrypy/cherrypy/issue/853 + # See https://github.com/cherrypy/cherrypy/issues/853 if (not request_seen) or (req and req.started_request): # Don't bother writing the 408 if the response # has already started being written. @@ -1379,7 +1391,7 @@ class ThreadPool(object): except (AssertionError, # Ignore repeated Ctrl-C. # See - # https://bitbucket.org/cherrypy/cherrypy/issue/691. + # https://github.com/cherrypy/cherrypy/issues/691. KeyboardInterrupt): pass @@ -1479,7 +1491,7 @@ class HTTPServer(object): timeout = 10 """The timeout in seconds for accepted connections (default 10).""" - version = "CherryPy/5.1.0" + version = "CherryPy/" + cp_version """A version string for the HTTPServer.""" software = None @@ -1704,7 +1716,7 @@ class HTTPServer(object): # If listening on the IPV6 any address ('::' = IN6ADDR_ANY), # activate dual-stack. See - # https://bitbucket.org/cherrypy/cherrypy/issue/871. + # https://github.com/cherrypy/cherrypy/issues/871. if (hasattr(socket, 'AF_INET6') and family == socket.AF_INET6 and self.bind_addr[0] in ('::', '::0', '::0.0.0.0')): try: @@ -1798,15 +1810,15 @@ class HTTPServer(object): # the call, and I *think* I'm reading it right that Python # will then go ahead and poll for and handle the signal # elsewhere. See - # https://bitbucket.org/cherrypy/cherrypy/issue/707. + # https://github.com/cherrypy/cherrypy/issues/707. return if x.args[0] in socket_errors_nonblocking: # Just try again. See - # https://bitbucket.org/cherrypy/cherrypy/issue/479. + # https://github.com/cherrypy/cherrypy/issues/479. return if x.args[0] in socket_errors_to_ignore: # Our socket was closed. - # See https://bitbucket.org/cherrypy/cherrypy/issue/686. + # See https://github.com/cherrypy/cherrypy/issues/686. return raise @@ -1839,7 +1851,7 @@ class HTTPServer(object): if x.args[0] not in socket_errors_to_ignore: # Changed to use error code and not message # See - # https://bitbucket.org/cherrypy/cherrypy/issue/860. + # https://github.com/cherrypy/cherrypy/issues/860. raise else: # Note that we're explicitly NOT using AI_PASSIVE, diff --git a/docs/install.rst b/docs/install.rst index 68dd9692..dec9c007 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -6,7 +6,7 @@ CherryPy is a pure Python library. This has various consequences: - It can run anywhere Python runs - It does not require a C compiler - - It can run on various implementations of the Python language: `CPython <http://python.org/>`_, + - It can run on various implementations of the Python language: `CPython <http://python.org/>`_, `IronPython <http://ironpython.net/>`_, `Jython <http://www.jython.org/>`_ and `PyPy <http://pypy.org/>`_ .. contents:: @@ -45,11 +45,11 @@ CherryPy can be easily installed via common Python package managers such as setu $ pip install cherrypy -You may also get the latest CherryPy version by grabbing the source code from BitBucket: +You may also get the latest CherryPy version by grabbing the source code from Github: .. code-block:: bash - $ hg clone https://bitbucket.org/cherrypy/cherrypy + $ git clone https://github.com/cherrypy/cherrypy $ cd cherrypy $ python setup.py install diff --git a/docs/tutorials.rst b/docs/tutorials.rst index e50fa1dd..fc695dfb 100644 --- a/docs/tutorials.rst +++ b/docs/tutorials.rst @@ -915,10 +915,11 @@ First, let's see how our HTML code has changed: <link href="/static/css/style.css" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script> <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script> + <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script> </head> <body> <div id="generator"></div> - <script type="text/javascript" src="static/js/gen.js"></script> + <script type="text/babel" src="static/js/gen.js"></script> </body> </html> diff --git a/release.py b/release.py deleted file mode 100644 index 14af0069..00000000 --- a/release.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -Use jaraco.packaging with this script to cut a release. After installing -jaraco.packaging, invoke: - -python -m jaraco.packaging.release -""" - -from __future__ import print_function - -import sys -import os -import shutil -import importlib -import textwrap - -files_with_versions = ( - 'setup.py', - 'cherrypy/__init__.py', - 'cherrypy/wsgiserver/wsgiserver2.py', - 'cherrypy/wsgiserver/wsgiserver3.py', -) - - -def check_wheel(): - """ - Ensure 'wheel' is installed (required for bdist_wheel). - """ - try: - importlib.import_module('wheel') - except ImportError: - print("CherryPy requires 'wheel' be installed to produce wheels.", - file=sys.stderr) - raise SystemExit(5) - - -def before_upload(): - check_wheel() - remove_files() - -test_info = textwrap.dedent(""" - Run tests with `nosetests -s ./` on Windows, Linux, and Mac on at least - Python 2.4, 2.5, 2.7, and 3.2. - """).lstrip() - -dist_commands = 'sdist', 'bdist_wheel' - - -def remove_files(): - if os.path.isfile('MANIFEST'): - os.remove('MANIFEST') - if os.path.isdir('dist'): - shutil.rmtree('dist') - - -def announce(): - print('Distributions have been uploaded.') - print('Please ask in IRC for others to help you test this release.') - print("Please confirm that the distro installs properly " - "with `easy_install CherryPy=={version}`.".format(**globals())) - print("Please change the Wiki: Home page (news), CherryPyDownload") - print("Please announce the release on newsgroups, mailing lists, " - "and IRC /topic.") @@ -1,8 +1,24 @@ +[bumpversion] +current_version = 5.2.0 +commit = True +tag = True + +[aliases] +clean_egg_info = egg_info -RDb '' +release = clean_egg_info sdist bdist_wheel + [sdist] -formats=gztar,zip +formats = gztar,zip [nosetests] -where=cherrypy -logging-filter=cherrypy -verbosity=2 -nocapture=True +where = cherrypy +logging-filter = cherrypy +verbosity = 2 +nocapture = True + +[egg_info] +tag_build = .post +tag_date = 1 + +[bumpversion:file:setup.py] + @@ -36,7 +36,7 @@ class cherrypy_build_py(build_py): # arguments for the setup command ############################################################################### name = "CherryPy" -version = "5.1.0" +version = "5.2.0" desc = "Object-Oriented HTTP framework" long_desc = "CherryPy is a pythonic, object-oriented HTTP framework" classifiers = [ |