From jython-checkins at python.org Mon Oct 10 03:28:41 2011 From: jython-checkins at python.org (frank.wierzbicki) Date: Mon, 10 Oct 2011 03:28:41 +0200 Subject: [Jython-checkins] =?utf8?q?jython=3A_Import__from_cpython_2=2E6?= =?utf8?q?=3A?= Message-ID: http://hg.python.org/jython/rev/e87c8777e6a0 changeset: 6248:e87c8777e6a0 user: Frank Wierzbicki date: Sun Oct 09 18:17:14 2011 -0700 summary: Import from cpython 2.6: Lib/SimpleHTTPServer.py at 71579:b9a95ce2692c files: Lib/SimpleHTTPServer.py | 26 ++++++++++++++------------ 1 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Lib/SimpleHTTPServer.py b/Lib/SimpleHTTPServer.py --- a/Lib/SimpleHTTPServer.py +++ b/Lib/SimpleHTTPServer.py @@ -14,8 +14,8 @@ import posixpath import BaseHTTPServer import urllib -import urlparse import cgi +import sys import shutil import mimetypes try: @@ -80,18 +80,17 @@ else: return self.list_directory(path) ctype = self.guess_type(path) - if ctype.startswith('text/'): - mode = 'r' - else: - mode = 'rb' try: - f = open(path, mode) + # Always read in binary mode. Opening files in text mode may cause + # newline translations, making the actual size of the content + # transmitted *less* than the content-length! + f = open(path, 'rb') except IOError: self.send_error(404, "File not found") return None self.send_response(200) self.send_header("Content-type", ctype) - fs = os.fstat(f.fileno()) if hasattr(os, 'fstat') else os.stat(path) + fs = os.fstat(f.fileno()) self.send_header("Content-Length", str(fs[6])) self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) self.end_headers() @@ -113,8 +112,9 @@ list.sort(key=lambda a: a.lower()) f = StringIO() displaypath = cgi.escape(urllib.unquote(self.path)) - f.write("Directory listing for %s\n" % displaypath) - f.write("

Directory listing for %s

\n" % displaypath) + f.write('') + f.write("\nDirectory listing for %s\n" % displaypath) + f.write("\n

Directory listing for %s

\n" % displaypath) f.write("
\n\n
\n") + f.write("\n
\n\n\n") length = f.tell() f.seek(0) self.send_response(200) - self.send_header("Content-type", "text/html") + encoding = sys.getfilesystemencoding() + self.send_header("Content-type", "text/html; charset=%s" % encoding) self.send_header("Content-Length", str(length)) self.end_headers() return f @@ -146,7 +147,8 @@ """ # abandon query parameters - path = urlparse.urlparse(path)[2] + path = path.split('?',1)[0] + path = path.split('#',1)[0] path = posixpath.normpath(urllib.unquote(path)) words = path.split('/') words = filter(None, words) -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Mon Oct 10 03:28:41 2011 From: jython-checkins at python.org (frank.wierzbicki) Date: Mon, 10 Oct 2011 03:28:41 +0200 Subject: [Jython-checkins] =?utf8?q?jython=3A_Apply_Jython_modifications?= =?utf8?q?=2E?= Message-ID: http://hg.python.org/jython/rev/9bf7b81d35a9 changeset: 6249:9bf7b81d35a9 user: Frank Wierzbicki date: Sun Oct 09 18:28:12 2011 -0700 summary: Apply Jython modifications. files: Lib/SimpleHTTPServer.py | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Lib/SimpleHTTPServer.py b/Lib/SimpleHTTPServer.py --- a/Lib/SimpleHTTPServer.py +++ b/Lib/SimpleHTTPServer.py @@ -11,6 +11,7 @@ __all__ = ["SimpleHTTPRequestHandler"] import os +import platform import posixpath import BaseHTTPServer import urllib @@ -90,7 +91,7 @@ return None self.send_response(200) self.send_header("Content-type", ctype) - fs = os.fstat(f.fileno()) + fs = os.fstat(f.fileno()) if hasattr(os, 'fstat') else os.stat(path) self.send_header("Content-Length", str(fs[6])) self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) self.end_headers() @@ -132,8 +133,9 @@ length = f.tell() f.seek(0) self.send_response(200) - encoding = sys.getfilesystemencoding() - self.send_header("Content-type", "text/html; charset=%s" % encoding) + if not platform.python_implementaton() == "Jython": + encoding = sys.getfilesystemencoding() + self.send_header("Content-type", "text/html; charset=%s" % encoding) self.send_header("Content-Length", str(length)) self.end_headers() return f -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Mon Oct 10 03:36:29 2011 From: jython-checkins at python.org (frank.wierzbicki) Date: Mon, 10 Oct 2011 03:36:29 +0200 Subject: [Jython-checkins] =?utf8?q?jython=3A_Import_from_cpython_2=2E6=3A?= Message-ID: http://hg.python.org/jython/rev/68c8d898fe80 changeset: 6250:68c8d898fe80 user: Frank Wierzbicki date: Sun Oct 09 18:33:14 2011 -0700 summary: Import from cpython 2.6: Lib/urllib.py at 71579:b9a95ce2692c files: Lib/urllib.py | 340 ++++++++++++++++++++++++------------- 1 files changed, 223 insertions(+), 117 deletions(-) diff --git a/Lib/urllib.py b/Lib/urllib.py --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -35,7 +35,7 @@ "localhost", "thishost", "ftperrors", "basejoin", "unwrap", "splittype", "splithost", "splituser", "splitpasswd", "splitport", "splitnport", "splitquery", "splitattr", "splitvalue", - "splitgophertype", "getproxies"] + "getproxies"] __version__ = '1.17' # XXX This version is not always updated :-( @@ -44,7 +44,7 @@ # Helper for non-unix systems if os.name == 'mac': from macurl2path import url2pathname, pathname2url -elif (os._name if sys.platform.startswith('java') else os.name) == 'nt': +elif os.name == 'nt': from nturl2path import url2pathname, pathname2url elif os.name == 'riscos': from rourl2path import url2pathname, pathname2url @@ -69,7 +69,11 @@ # Shortcut for basic usage _urlopener = None def urlopen(url, data=None, proxies=None): - """urlopen(url [, data]) -> open file-like object""" + """Create a file-like object for the specified URL to read from.""" + from warnings import warnpy3k + warnpy3k("urllib.urlopen() has been removed in Python 3.0 in " + "favor of urllib2.urlopen()", stacklevel=2) + global _urlopener if proxies is not None: opener = FancyURLopener(proxies=proxies) @@ -90,6 +94,16 @@ def urlcleanup(): if _urlopener: _urlopener.cleanup() + _safemaps.clear() + ftpcache.clear() + +# check for SSL +try: + import ssl +except: + _have_ssl = False +else: + _have_ssl = True # exception raised when downloaded size does not match content-length class ContentTooShortError(IOError): @@ -163,6 +177,9 @@ def open(self, fullurl, data=None): """Use URLopener().open(file) instead of open(file, 'r').""" fullurl = unwrap(toBytes(fullurl)) + # percent encode url. fixing lame server errors like space within url + # parts + fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]|") if self.tempcache and fullurl in self.tempcache: filename, headers = self.tempcache[fullurl] fp = open(filename, 'rb') @@ -215,46 +232,50 @@ try: fp = self.open_local_file(url1) hdrs = fp.info() - fp.close() + del fp return url2pathname(splithost(url1)[1]), hdrs except IOError, msg: pass fp = self.open(url, data) - headers = fp.info() - if filename: - tfp = open(filename, 'wb') - else: - import tempfile - garbage, path = splittype(url) - garbage, path = splithost(path or "") - path, garbage = splitquery(path or "") - path, garbage = splitattr(path or "") - suffix = os.path.splitext(path)[1] - (fd, filename) = tempfile.mkstemp(suffix) - self.__tempfiles.append(filename) - tfp = os.fdopen(fd, 'wb') - result = filename, headers - if self.tempcache is not None: - self.tempcache[url] = result - bs = 1024*8 - size = -1 - read = 0 - blocknum = 0 - if reporthook: - if "content-length" in headers: - size = int(headers["Content-Length"]) - reporthook(blocknum, bs, size) - while 1: - block = fp.read(bs) - if block == "": - break - read += len(block) - tfp.write(block) - blocknum += 1 - if reporthook: - reporthook(blocknum, bs, size) - fp.close() - tfp.close() + try: + headers = fp.info() + if filename: + tfp = open(filename, 'wb') + else: + import tempfile + garbage, path = splittype(url) + garbage, path = splithost(path or "") + path, garbage = splitquery(path or "") + path, garbage = splitattr(path or "") + suffix = os.path.splitext(path)[1] + (fd, filename) = tempfile.mkstemp(suffix) + self.__tempfiles.append(filename) + tfp = os.fdopen(fd, 'wb') + try: + result = filename, headers + if self.tempcache is not None: + self.tempcache[url] = result + bs = 1024*8 + size = -1 + read = 0 + blocknum = 0 + if reporthook: + if "content-length" in headers: + size = int(headers["Content-Length"]) + reporthook(blocknum, bs, size) + while 1: + block = fp.read(bs) + if block == "": + break + read += len(block) + tfp.write(block) + blocknum += 1 + if reporthook: + reporthook(blocknum, bs, size) + finally: + tfp.close() + finally: + fp.close() del fp del tfp @@ -326,13 +347,16 @@ if data is not None: h.send(data) errcode, errmsg, headers = h.getreply() + fp = h.getfile() if errcode == -1: + if fp: fp.close() # something went wrong with the HTTP status line raise IOError, ('http protocol error', 0, 'got a bad status line', None) - fp = h.getfile() - if errcode == 200: - return addinfourl(fp, headers, "http:" + url) + # According to RFC 2616, "2xx" code indicates that the client's + # request was successfully received, understood, and accepted. + if (200 <= errcode < 300): + return addinfourl(fp, headers, "http:" + url, errcode) else: if data is None: return self.http_error(url, fp, errcode, errmsg, headers) @@ -360,9 +384,10 @@ fp.close() raise IOError, ('http error', errcode, errmsg, headers) - if hasattr(socket, "ssl"): + if _have_ssl: def open_https(self, url, data=None): """Use HTTPS protocol.""" + import httplib user_passwd = None proxy_passwd = None @@ -417,13 +442,16 @@ if data is not None: h.send(data) errcode, errmsg, headers = h.getreply() + fp = h.getfile() if errcode == -1: + if fp: fp.close() # something went wrong with the HTTP status line raise IOError, ('http protocol error', 0, 'got a bad status line', None) - fp = h.getfile() - if errcode == 200: - return addinfourl(fp, headers, "https:" + url) + # According to RFC 2616, "2xx" code indicates that the client's + # request was successfully received, understood, and accepted. + if (200 <= errcode < 300): + return addinfourl(fp, headers, "https:" + url, errcode) else: if data is None: return self.http_error(url, fp, errcode, errmsg, headers) @@ -431,24 +459,6 @@ return self.http_error(url, fp, errcode, errmsg, headers, data) - def open_gopher(self, url): - """Use Gopher protocol.""" - if not isinstance(url, str): - raise IOError, ('gopher error', 'proxy support for gopher protocol currently not implemented') - import gopherlib - host, selector = splithost(url) - if not host: raise IOError, ('gopher error', 'no host given') - host = unquote(host) - type, selector = splitgophertype(selector) - selector, query = splitquery(selector) - selector = unquote(selector) - if query: - query = unquote(query) - fp = gopherlib.send_query(selector, query, host) - else: - fp = gopherlib.send_selector(selector, host) - return addinfourl(fp, noheaders(), "gopher:" + url) - def open_file(self, url): """Use local file or FTP depending on form of URL.""" if not isinstance(url, str): @@ -460,7 +470,7 @@ def open_local_file(self, url): """Use local file.""" - import mimetypes, mimetools, email.Utils + import mimetypes, mimetools, email.utils try: from cStringIO import StringIO except ImportError: @@ -472,7 +482,7 @@ except OSError, e: raise IOError(e.errno, e.strerror, e.filename) size = stats.st_size - modified = email.Utils.formatdate(stats.st_mtime, usegmt=True) + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) mtype = mimetypes.guess_type(url)[0] headers = mimetools.Message(StringIO( 'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' % @@ -584,7 +594,7 @@ else: encoding = '' msg = [] - msg.append('Date: %s'%time.strftime('%a, %d %b %Y %T GMT', + msg.append('Date: %s'%time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(time.time()))) msg.append('Content-type: %s' % type) if encoding == 'base64': @@ -613,7 +623,7 @@ def http_error_default(self, url, fp, errcode, errmsg, headers): """Default error handling -- don't raise an exception.""" - return addinfourl(fp, headers, "http:" + url) + return addinfourl(fp, headers, "http:" + url, errcode) def http_error_302(self, url, fp, errcode, errmsg, headers, data=None): """Error 302 -- relocated (temporarily).""" @@ -642,6 +652,18 @@ fp.close() # In case the server sent a relative URL, join with original: newurl = basejoin(self.type + ":" + url, newurl) + + # For security reasons we do not allow redirects to protocols + # other than HTTP, HTTPS or FTP. + newurl_lower = newurl.lower() + if not (newurl_lower.startswith('http://') or + newurl_lower.startswith('https://') or + newurl_lower.startswith('ftp://')): + raise IOError('redirect error', errcode, + errmsg + " - Redirection to url '%s' is not allowed" % + newurl, + headers) + return self.open(newurl) def http_error_301(self, url, fp, errcode, errmsg, headers, data=None): @@ -835,19 +857,21 @@ class ftpwrapper: """Class used by open_ftp() for cache of open FTP connections.""" - def __init__(self, user, passwd, host, port, dirs): + def __init__(self, user, passwd, host, port, dirs, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): self.user = user self.passwd = passwd self.host = host self.port = port self.dirs = dirs + self.timeout = timeout self.init() def init(self): import ftplib self.busy = 0 self.ftp = ftplib.FTP() - self.ftp.connect(self.host, self.port) + self.ftp.connect(self.host, self.port, self.timeout) self.ftp.login(self.user, self.passwd) for dir in self.dirs: self.ftp.cwd(dir) @@ -874,9 +898,19 @@ if not conn: # Set transfer mode to ASCII! self.ftp.voidcmd('TYPE A') - # Try a directory listing - if file: cmd = 'LIST ' + file - else: cmd = 'LIST' + # Try a directory listing. Verify that directory exists. + if file: + pwd = self.ftp.pwd() + try: + try: + self.ftp.cwd(file) + except ftplib.error_perm, reason: + raise IOError, ('ftp error', reason), sys.exc_info()[2] + finally: + self.ftp.cwd(pwd) + cmd = 'LIST ' + file + else: + cmd = 'LIST' conn = self.ftp.ntransfercmd(cmd) self.busy = 1 # Pass back both a suitably decorated object and a retrieval length @@ -955,14 +989,18 @@ class addinfourl(addbase): """class to add info() and geturl() methods to an open file.""" - def __init__(self, fp, headers, url): + def __init__(self, fp, headers, url, code=None): addbase.__init__(self, fp) self.headers = headers self.url = url + self.code = code def info(self): return self.headers + def getcode(self): + return self.code + def geturl(self): return self.url @@ -979,7 +1017,6 @@ # splitattr('/path;attr1=value1;attr2=value2;...') -> # '/path', ['attr1=value1', 'attr2=value2', ...] # splitvalue('attr=value') --> 'attr', 'value' -# splitgophertype('/Xselector') --> 'X', 'selector' # unquote('abc%20def') -> 'abc def' # quote('abc def') -> 'abc%20def') @@ -1139,14 +1176,8 @@ if match: return match.group(1, 2) return attr, None -def splitgophertype(selector): - """splitgophertype('/Xselector') --> 'X', 'selector'.""" - if selector[:1] == '/' and selector[1:2]: - return selector[1], selector[2:] - return None, selector - -_hextochr = dict(('%02x' % i, chr(i)) for i in range(256)) -_hextochr.update(('%02X' % i, chr(i)) for i in range(256)) +_hexdig = '0123456789ABCDEFabcdef' +_hextochr = dict((a+b, chr(int(a+b,16))) for a in _hexdig for b in _hexdig) def unquote(s): """unquote('abc%20def') -> 'abc def'.""" @@ -1292,42 +1323,107 @@ proxies[name[:-6]] = value return proxies +def proxy_bypass_environment(host): + """Test if proxies should not be used for a particular host. + + Checks the environment for a variable named no_proxy, which should + be a list of DNS suffixes separated by commas, or '*' for all hosts. + """ + no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '') + # '*' is special case for always bypass + if no_proxy == '*': + return 1 + # strip port off host + hostonly, port = splitport(host) + # check if the host ends with any of the DNS suffixes + for name in no_proxy.split(','): + if name and (hostonly.endswith(name) or host.endswith(name)): + return 1 + # otherwise, don't bypass + return 0 + + if sys.platform == 'darwin': - def getproxies_internetconfig(): + from _scproxy import _get_proxy_settings, _get_proxies + + def proxy_bypass_macosx_sysconf(host): + """ + Return True iff this host shouldn't be accessed using a proxy + + This function uses the MacOSX framework SystemConfiguration + to fetch the proxy information. + """ + import re + import socket + from fnmatch import fnmatch + + hostonly, port = splitport(host) + + def ip2num(ipAddr): + parts = ipAddr.split('.') + parts = map(int, parts) + if len(parts) != 4: + parts = (parts + [0, 0, 0, 0])[:4] + return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3] + + proxy_settings = _get_proxy_settings() + + # Check for simple host names: + if '.' not in host: + if proxy_settings['exclude_simple']: + return True + + hostIP = None + + for value in proxy_settings.get('exceptions', ()): + # Items in the list are strings like these: *.local, 169.254/16 + if not value: continue + + m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value) + if m is not None: + if hostIP is None: + try: + hostIP = socket.gethostbyname(hostonly) + hostIP = ip2num(hostIP) + except socket.error: + continue + + base = ip2num(m.group(1)) + mask = m.group(2) + if mask is None: + mask = 8 * (m.group(1).count('.') + 1) + + else: + mask = int(mask[1:]) + mask = 32 - mask + + if (hostIP >> mask) == (base >> mask): + return True + + elif fnmatch(host, value): + return True + + return False + + + def getproxies_macosx_sysconf(): """Return a dictionary of scheme -> proxy server URL mappings. - By convention the mac uses Internet Config to store - proxies. An HTTP proxy, for instance, is stored under - the HttpProxy key. + This function uses the MacOSX framework SystemConfiguration + to fetch the proxy information. + """ + return _get_proxies() - """ - try: - import ic - except ImportError: - return {} - try: - config = ic.IC() - except ic.error: - return {} - proxies = {} - # HTTP: - if 'UseHTTPProxy' in config and config['UseHTTPProxy']: - try: - value = config['HTTPProxyHost'] - except ic.error: - pass - else: - proxies['http'] = 'http://%s' % value - # FTP: XXXX To be done. - # Gopher: XXXX To be done. - return proxies - def proxy_bypass(x): - return 0 + def proxy_bypass(host): + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_macosx_sysconf(host) def getproxies(): - return getproxies_environment() or getproxies_internetconfig() + return getproxies_environment() or getproxies_macosx_sysconf() elif os.name == 'nt': def getproxies_registry(): @@ -1366,6 +1462,7 @@ proxies['http'] = proxyServer else: proxies['http'] = 'http://%s' % proxyServer + proxies['https'] = 'https://%s' % proxyServer proxies['ftp'] = 'ftp://%s' % proxyServer internetSettings.Close() except (WindowsError, ValueError, TypeError): @@ -1384,7 +1481,7 @@ """ return getproxies_environment() or getproxies_registry() - def proxy_bypass(host): + def proxy_bypass_registry(host): try: import _winreg import re @@ -1443,12 +1540,22 @@ return 1 return 0 + def proxy_bypass(host): + """Return a dictionary of scheme -> proxy server URL mappings. + + Returns settings gathered from the environment, if specified, + or the registry. + + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + else: # By default use environment variables getproxies = getproxies_environment - - def proxy_bypass(host): - return 0 + proxy_bypass = proxy_bypass_environment # Test and time quote() and unquote() def test1(): @@ -1480,7 +1587,6 @@ 'file:/etc/passwd', 'file://localhost/etc/passwd', 'ftp://ftp.gnu.org/pub/README', -## 'gopher://gopher.micro.umn.edu/1/', 'http://www.python.org/index.html', ] if hasattr(URLopener, "open_https"): @@ -1496,7 +1602,7 @@ print '======' fp = open(fn, 'rb') data = fp.read() - fp.close() + del fp if '\r' in data: table = string.maketrans("", "") data = data.translate(table, "\r") -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Mon Oct 10 03:36:29 2011 From: jython-checkins at python.org (frank.wierzbicki) Date: Mon, 10 Oct 2011 03:36:29 +0200 Subject: [Jython-checkins] =?utf8?q?jython=3A_Import_from_cpython_2=2E6=3A?= Message-ID: http://hg.python.org/jython/rev/f37130c7dfbd changeset: 6251:f37130c7dfbd user: Frank Wierzbicki date: Sun Oct 09 18:34:45 2011 -0700 summary: Import from cpython 2.6: Lib/test/test_urllib.py at 71579:b9a95ce2692c files: Lib/test/test_urllib.py | 211 +++++++++++++++++++++++++-- 1 files changed, 195 insertions(+), 16 deletions(-) diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -43,7 +43,7 @@ def test_interface(self): # Make sure object returned by urlopen() has the specified methods for attr in ("read", "readline", "readlines", "fileno", - "close", "info", "geturl", "__iter__"): + "close", "info", "geturl", "getcode", "__iter__"): self.assert_(hasattr(self.returned_obj, attr), "object returned by urlopen() lacks %s attribute" % attr) @@ -66,10 +66,8 @@ def test_fileno(self): file_num = self.returned_obj.fileno() - - # JYTHON - does not apply, since fileno's are not int's - #self.assert_(isinstance(file_num, int), - # "fileno() did not return an int") + self.assert_(isinstance(file_num, int), + "fileno() did not return an int") self.assertEqual(os.read(file_num, len(self.text)), self.text, "Reading on the file descriptor returned by fileno() " "did not return the expected text") @@ -85,6 +83,9 @@ def test_geturl(self): self.assertEqual(self.returned_obj.geturl(), self.pathname) + def test_getcode(self): + self.assertEqual(self.returned_obj.getcode(), None) + def test_iter(self): # Test iterator # Don't need to count number of iterations since test would fail the @@ -93,6 +94,28 @@ for line in self.returned_obj.__iter__(): self.assertEqual(line, self.text) +class ProxyTests(unittest.TestCase): + + def setUp(self): + # Records changes to env vars + self.env = test_support.EnvironmentVarGuard() + # Delete all proxy related env vars + for k in os.environ.keys(): + if 'proxy' in k.lower(): + self.env.unset(k) + + def tearDown(self): + # Restore all proxy related env vars + self.env.__exit__() + del self.env + + def test_getproxies_environment_keep_no_proxies(self): + self.env.set('NO_PROXY', 'localhost') + proxies = urllib.getproxies_environment() + # getproxies_environment use lowered case truncated (no '_proxy') keys + self.assertEquals('localhost', proxies['no']) + + class urlopen_HttpTests(unittest.TestCase): """Test urlopen() opening a fake http connection.""" @@ -121,12 +144,41 @@ fp = urllib.urlopen("http://python.org/") self.assertEqual(fp.readline(), 'Hello!') self.assertEqual(fp.readline(), '') + self.assertEqual(fp.geturl(), 'http://python.org/') + self.assertEqual(fp.getcode(), 200) + finally: + self.unfakehttp() + + def test_read_bogus(self): + # urlopen() should raise IOError for many error codes. + self.fakehttp('''HTTP/1.1 401 Authentication Required +Date: Wed, 02 Jan 2008 03:03:54 GMT +Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e +Connection: close +Content-Type: text/html; charset=iso-8859-1 +''') + try: + self.assertRaises(IOError, urllib.urlopen, "http://python.org/") + finally: + self.unfakehttp() + + def test_invalid_redirect(self): + # urlopen() should raise IOError for many error codes. + self.fakehttp("""HTTP/1.1 302 Found +Date: Wed, 02 Jan 2008 03:03:54 GMT +Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e +Location: file:README +Connection: close +Content-Type: text/html; charset=iso-8859-1 +""") + try: + self.assertRaises(IOError, urllib.urlopen, "http://python.org/") finally: self.unfakehttp() def test_empty_socket(self): - """urlopen() raises IOError if the underlying socket does not send any - data. (#1680230) """ + # urlopen() raises IOError if the underlying socket does not send any + # data. (#1680230) self.fakehttp('') try: self.assertRaises(IOError, urllib.urlopen, 'http://something') @@ -402,6 +454,32 @@ "using unquote(): not all characters escaped: " "%s" % result) + def test_unquoting_badpercent(self): + # Test unquoting on bad percent-escapes + given = '%xab' + expect = given + result = urllib.unquote(given) + self.assertEqual(expect, result, "using unquote(): %r != %r" + % (expect, result)) + given = '%x' + expect = given + result = urllib.unquote(given) + self.assertEqual(expect, result, "using unquote(): %r != %r" + % (expect, result)) + given = '%' + expect = given + result = urllib.unquote(given) + self.assertEqual(expect, result, "using unquote(): %r != %r" + % (expect, result)) + + def test_unquoting_mixed_case(self): + # Test unquoting on mixed-case hex digits in the percent-escapes + given = '%Ab%eA' + expect = '\xab\xea' + result = urllib.unquote(given) + self.assertEqual(expect, result, "using unquote(): %r != %r" + % (expect, result)) + def test_unquoting_parts(self): # Make sure unquoting works when have non-quoted characters # interspersed @@ -543,18 +621,119 @@ "url2pathname() failed; %s != %s" % (expect, result)) +class URLopener_Tests(unittest.TestCase): + """Testcase to test the open method of URLopener class.""" + def test_quoted_open(self): + class DummyURLopener(urllib.URLopener): + def open_spam(self, url): + return url + + self.assertEqual(DummyURLopener().open( + 'spam://example/ /'),'//example/%20/') + + # test the safe characters are not quoted by urlopen + self.assertEqual(DummyURLopener().open( + "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"), + "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/") + + +# Just commented them out. +# Can't really tell why keep failing in windows and sparc. +# Everywhere else they work ok, but on those machines, someteimes +# fail in one of the tests, sometimes in other. I have a linux, and +# the tests go ok. +# If anybody has one of the problematic enviroments, please help! +# . Facundo +# +# def server(evt): +# import socket, time +# serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +# serv.settimeout(3) +# serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +# serv.bind(("", 9093)) +# serv.listen(5) +# try: +# conn, addr = serv.accept() +# conn.send("1 Hola mundo\n") +# cantdata = 0 +# while cantdata < 13: +# data = conn.recv(13-cantdata) +# cantdata += len(data) +# time.sleep(.3) +# conn.send("2 No more lines\n") +# conn.close() +# except socket.timeout: +# pass +# finally: +# serv.close() +# evt.set() +# +# class FTPWrapperTests(unittest.TestCase): +# +# def setUp(self): +# import ftplib, time, threading +# ftplib.FTP.port = 9093 +# self.evt = threading.Event() +# threading.Thread(target=server, args=(self.evt,)).start() +# time.sleep(.1) +# +# def tearDown(self): +# self.evt.wait() +# +# def testBasic(self): +# # connects +# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) +# ftp.close() +# +# def testTimeoutNone(self): +# # global default timeout is ignored +# import socket +# self.assert_(socket.getdefaulttimeout() is None) +# socket.setdefaulttimeout(30) +# try: +# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) +# finally: +# socket.setdefaulttimeout(None) +# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) +# ftp.close() +# +# def testTimeoutDefault(self): +# # global default timeout is used +# import socket +# self.assert_(socket.getdefaulttimeout() is None) +# socket.setdefaulttimeout(30) +# try: +# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) +# finally: +# socket.setdefaulttimeout(None) +# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) +# ftp.close() +# +# def testTimeoutValue(self): +# ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [], +# timeout=30) +# self.assertEqual(ftp.ftp.sock.gettimeout(), 30) +# ftp.close() + def test_main(): - test_support.run_unittest( - urlopen_FileTests, - urlopen_HttpTests, - urlretrieve_FileTests, - QuotingTests, - UnquotingTests, - urlencode_Tests, - Pathname_Tests - ) + import warnings + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', ".*urllib\.urlopen.*Python 3.0", + DeprecationWarning) + test_support.run_unittest( + urlopen_FileTests, + urlopen_HttpTests, + urlretrieve_FileTests, + ProxyTests, + QuotingTests, + UnquotingTests, + urlencode_Tests, + Pathname_Tests, + URLopener_Tests, + #FTPWrapperTests, + ) -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Mon Oct 10 03:36:29 2011 From: jython-checkins at python.org (frank.wierzbicki) Date: Mon, 10 Oct 2011 03:36:29 +0200 Subject: [Jython-checkins] =?utf8?q?jython=3A_Reapply_Jython_adjustments?= =?utf8?q?=2E?= Message-ID: http://hg.python.org/jython/rev/f118d899e052 changeset: 6252:f118d899e052 user: Frank Wierzbicki date: Sun Oct 09 18:35:57 2011 -0700 summary: Reapply Jython adjustments. files: Lib/test/test_urllib.py | 5 +++-- Lib/urllib.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -66,8 +66,9 @@ def test_fileno(self): file_num = self.returned_obj.fileno() - self.assert_(isinstance(file_num, int), - "fileno() did not return an int") + if not test_support.is_jython: + self.assert_(isinstance(file_num, int), + "fileno() did not return an int") self.assertEqual(os.read(file_num, len(self.text)), self.text, "Reading on the file descriptor returned by fileno() " "did not return the expected text") diff --git a/Lib/urllib.py b/Lib/urllib.py --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -44,7 +44,7 @@ # Helper for non-unix systems if os.name == 'mac': from macurl2path import url2pathname, pathname2url -elif os.name == 'nt': +elif (os._name if sys.platform.startswith('java') else os.name) == 'nt': from nturl2path import url2pathname, pathname2url elif os.name == 'riscos': from rourl2path import url2pathname, pathname2url -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Tue Oct 11 03:41:57 2011 From: jython-checkins at python.org (frank.wierzbicki) Date: Tue, 11 Oct 2011 03:41:57 +0200 Subject: [Jython-checkins] =?utf8?q?jython=3A_The_=5F=5Fall=5F=5F_was_brea?= =?utf8?q?king_test=5F=5F=5Fall=5F=5F=2Epy_but_does_not_appear_to_break_an?= =?utf8?q?ything?= Message-ID: http://hg.python.org/jython/rev/704b07c1d5f5 changeset: 6253:704b07c1d5f5 user: Frank Wierzbicki date: Mon Oct 10 18:41:49 2011 -0700 summary: The __all__ was breaking test___all__.py but does not appear to break anything when removed. files: Lib/test/anygui.py | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/Lib/test/anygui.py b/Lib/test/anygui.py --- a/Lib/test/anygui.py +++ b/Lib/test/anygui.py @@ -2,7 +2,6 @@ import sys class anygui: - __all__ = ['Window'] # Etc... def __init__(self): self.__backend = None -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Tue Oct 25 02:17:39 2011 From: jython-checkins at python.org (philip.jenvey) Date: Tue, 25 Oct 2011 02:17:39 +0200 Subject: [Jython-checkins] =?utf8?q?jython_=282=2E5=29=3A_cleanup_import_f?= =?utf8?q?romlist_handling?= Message-ID: http://hg.python.org/jython/rev/4c672dbbcdb2 changeset: 6254:4c672dbbcdb2 branch: 2.5 parent: 6245:8831af94a9fc user: Philip Jenvey date: Mon Oct 24 17:12:51 2011 -0700 summary: cleanup import fromlist handling fixes #1811 thanks Mike Bayer files: Lib/test/issue1811/__init__.py | Bin Lib/test/issue1811/foo.py | 1 + Lib/test/test_import_jy.py | 6 ++ src/org/python/core/PyModule.java | 8 --- src/org/python/core/imp.java | 43 ++++++++++++++--- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/Lib/test/issue1811/__init__.py b/Lib/test/issue1811/__init__.py new file mode 100644 diff --git a/Lib/test/issue1811/foo.py b/Lib/test/issue1811/foo.py new file mode 100644 --- /dev/null +++ b/Lib/test/issue1811/foo.py @@ -0,0 +1,1 @@ +issue1811 = __import__('test.issue1811', globals(), locals(), ['foo']) diff --git a/Lib/test/test_import_jy.py b/Lib/test/test_import_jy.py --- a/Lib/test/test_import_jy.py +++ b/Lib/test/test_import_jy.py @@ -205,6 +205,12 @@ shutil.rmtree(test_support.TESTFN) test_support.unlink(sym) + def test_issue1811(self): + # Previously this blew out the stack + from test.issue1811 import foo + self.assertTrue(foo.issue1811.foo is foo) + + def test_main(): test_support.run_unittest(MislabeledImportTestCase, OverrideBuiltinsImportTestCase, diff --git a/src/org/python/core/PyModule.java b/src/org/python/core/PyModule.java --- a/src/org/python/core/PyModule.java +++ b/src/org/python/core/PyModule.java @@ -119,14 +119,6 @@ return null; } - @Override - public PyObject __findattr_ex__(String name) { - PyObject attr=super.__findattr_ex__(name); - if (attr!=null) - return attr; - return impAttr(name); - } - public void __setattr__(String name, PyObject value) { module___setattr__(name, value); } diff --git a/src/org/python/core/imp.java b/src/org/python/core/imp.java --- a/src/org/python/core/imp.java +++ b/src/org/python/core/imp.java @@ -844,19 +844,44 @@ } if (fromlist != null && fromlist != Py.None) { - StringBuilder modNameBuffer = new StringBuilder(name); - for (PyObject submodName : fromlist.asIterable()) { - if (mod.__findattr__(submodName.toString()) != null - || submodName.toString().equals("*")) { - continue; - } - String fullName = modNameBuffer.toString() + "." + submodName.toString(); - import_next(mod, modNameBuffer, submodName.toString(), fullName, null); - } + ensureFromList(mod, fromlist, name); } return mod; } + private static void ensureFromList(PyObject mod, PyObject fromlist, String name) { + ensureFromList(mod, fromlist, name, false); + } + + private static void ensureFromList(PyObject mod, PyObject fromlist, String name, + boolean recursive) { + if (mod.__findattr__("__path__") == null) { + return; + } + + StringBuilder modNameBuffer = new StringBuilder(name); + for (PyObject item : fromlist.asIterable()) { + if (!Py.isInstance(item, PyString.TYPE)) { + throw Py.TypeError("Item in ``from list'' not a string"); + } + if (item.toString().equals("*")) { + if (recursive) { + // Avoid endless recursion + continue; + } + PyObject all; + if ((all = mod.__findattr__("__all__")) != null) { + ensureFromList(mod, all, name, true); + } + } + + if (mod.__findattr__((PyString) item) == null) { + String fullName = modNameBuffer.toString() + "." + item.toString(); + import_next(mod, modNameBuffer, item.toString(), fullName, null); + } + } + } + /** * Import a module by name. * -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Tue Oct 25 02:17:39 2011 From: jython-checkins at python.org (philip.jenvey) Date: Tue, 25 Oct 2011 02:17:39 +0200 Subject: [Jython-checkins] =?utf8?q?jython_=28merge_2=2E5_-=3E_default=29?= =?utf8?q?=3A_merge_with_2=2E5?= Message-ID: http://hg.python.org/jython/rev/2a60a68ed086 changeset: 6255:2a60a68ed086 parent: 6253:704b07c1d5f5 parent: 6254:4c672dbbcdb2 user: Philip Jenvey date: Mon Oct 24 17:17:01 2011 -0700 summary: merge with 2.5 files: Lib/test/issue1811/__init__.py | Bin Lib/test/issue1811/foo.py | 1 + Lib/test/test_import_jy.py | 6 ++ src/org/python/core/PyModule.java | 8 --- src/org/python/core/imp.java | 43 ++++++++++++++--- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/Lib/test/issue1811/__init__.py b/Lib/test/issue1811/__init__.py new file mode 100644 diff --git a/Lib/test/issue1811/foo.py b/Lib/test/issue1811/foo.py new file mode 100644 --- /dev/null +++ b/Lib/test/issue1811/foo.py @@ -0,0 +1,1 @@ +issue1811 = __import__('test.issue1811', globals(), locals(), ['foo']) diff --git a/Lib/test/test_import_jy.py b/Lib/test/test_import_jy.py --- a/Lib/test/test_import_jy.py +++ b/Lib/test/test_import_jy.py @@ -205,6 +205,12 @@ shutil.rmtree(test_support.TESTFN) test_support.unlink(sym) + def test_issue1811(self): + # Previously this blew out the stack + from test.issue1811 import foo + self.assertTrue(foo.issue1811.foo is foo) + + def test_main(): test_support.run_unittest(MislabeledImportTestCase, OverrideBuiltinsImportTestCase, diff --git a/src/org/python/core/PyModule.java b/src/org/python/core/PyModule.java --- a/src/org/python/core/PyModule.java +++ b/src/org/python/core/PyModule.java @@ -119,14 +119,6 @@ return null; } - @Override - public PyObject __findattr_ex__(String name) { - PyObject attr=super.__findattr_ex__(name); - if (attr!=null) - return attr; - return impAttr(name); - } - public void __setattr__(String name, PyObject value) { module___setattr__(name, value); } diff --git a/src/org/python/core/imp.java b/src/org/python/core/imp.java --- a/src/org/python/core/imp.java +++ b/src/org/python/core/imp.java @@ -846,19 +846,44 @@ } if (fromlist != null && fromlist != Py.None) { - StringBuilder modNameBuffer = new StringBuilder(name); - for (PyObject submodName : fromlist.asIterable()) { - if (mod.__findattr__(submodName.toString()) != null - || submodName.toString().equals("*")) { - continue; - } - String fullName = modNameBuffer.toString() + "." + submodName.toString(); - import_next(mod, modNameBuffer, submodName.toString(), fullName, null); - } + ensureFromList(mod, fromlist, name); } return mod; } + private static void ensureFromList(PyObject mod, PyObject fromlist, String name) { + ensureFromList(mod, fromlist, name, false); + } + + private static void ensureFromList(PyObject mod, PyObject fromlist, String name, + boolean recursive) { + if (mod.__findattr__("__path__") == null) { + return; + } + + StringBuilder modNameBuffer = new StringBuilder(name); + for (PyObject item : fromlist.asIterable()) { + if (!Py.isInstance(item, PyString.TYPE)) { + throw Py.TypeError("Item in ``from list'' not a string"); + } + if (item.toString().equals("*")) { + if (recursive) { + // Avoid endless recursion + continue; + } + PyObject all; + if ((all = mod.__findattr__("__all__")) != null) { + ensureFromList(mod, all, name, true); + } + } + + if (mod.__findattr__((PyString) item) == null) { + String fullName = modNameBuffer.toString() + "." + item.toString(); + import_next(mod, modNameBuffer, item.toString(), fullName, null); + } + } + } + /** * Import a module by name. * -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sat Oct 29 01:40:55 2011 From: jython-checkins at python.org (philip.jenvey) Date: Sat, 29 Oct 2011 01:40:55 +0200 Subject: [Jython-checkins] =?utf8?q?jython_=282=2E5=29=3A_changelog_for_th?= =?utf8?q?e_last_commit?= Message-ID: http://hg.python.org/jython/rev/700d0f7c35db changeset: 6256:700d0f7c35db branch: 2.5 parent: 6254:4c672dbbcdb2 user: Philip Jenvey date: Fri Oct 28 16:39:50 2011 -0700 summary: changelog for the last commit files: NEWS | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ - [ 1727 ] Error in Jython 2.5.2 with os.stat and varargs - [ 1735 ] return type of os.read is unicode, not str - [ 1755 ] os.utime('/tmp/nonexistent-file', None) fails to raise OSError + - [ 1811 ] Recursive import bug w/ SQLAlchemy 0.7.3 Jython 2.5.2 same as 2.5.2rc4 -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sat Oct 29 01:40:55 2011 From: jython-checkins at python.org (philip.jenvey) Date: Sat, 29 Oct 2011 01:40:55 +0200 Subject: [Jython-checkins] =?utf8?q?jython_=28merge_2=2E5_-=3E_default=29?= =?utf8?q?=3A_merge_w/_2=2E5=3A_changelog_for_the_last_commit?= Message-ID: http://hg.python.org/jython/rev/3d719476e032 changeset: 6257:3d719476e032 parent: 6255:2a60a68ed086 parent: 6256:700d0f7c35db user: Philip Jenvey date: Fri Oct 28 16:40:34 2011 -0700 summary: merge w/ 2.5: changelog for the last commit files: NEWS | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ - [ 1727 ] Error in Jython 2.5.2 with os.stat and varargs - [ 1735 ] return type of os.read is unicode, not str - [ 1755 ] os.utime('/tmp/nonexistent-file', None) fails to raise OSError + - [ 1811 ] Recursive import bug w/ SQLAlchemy 0.7.3 Jython 2.5.2 same as 2.5.2rc4 -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sat Oct 29 20:06:57 2011 From: jython-checkins at python.org (alan.kennedy) Date: Sat, 29 Oct 2011 20:06:57 +0200 Subject: [Jython-checkins] =?utf8?q?jython_=282=2E5=29=3A_Fix_for_some_min?= =?utf8?q?or_socket_issues_relating_to_attributes=2E?= Message-ID: http://hg.python.org/jython/rev/be3145efdbb1 changeset: 6258:be3145efdbb1 branch: 2.5 user: Alan Kennedy date: Sat Oct 29 18:49:09 2011 +0100 summary: Fix for some minor socket issues relating to attributes. http://bugs.jython.org/issue1803 http://bugs.jython.org/issue1804 files: Lib/socket.py | 18 +++++++++++++----- Lib/test/test_socket.py | 17 ++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Lib/socket.py b/Lib/socket.py --- a/Lib/socket.py +++ b/Lib/socket.py @@ -581,17 +581,25 @@ return None return Protocol.getProtocolByName(protocol_name).getProto() -def _realsocket(family = AF_INET, type = SOCK_STREAM, protocol=0): +def _realsocket(family = AF_INET, sock_type = SOCK_STREAM, protocol=0): assert family in (AF_INET, AF_INET6), "Only AF_INET and AF_INET6 sockets are currently supported on jython" - assert type in (SOCK_DGRAM, SOCK_STREAM), "Only SOCK_STREAM and SOCK_DGRAM sockets are currently supported on jython" - if type == SOCK_STREAM: + assert sock_type in (SOCK_DGRAM, SOCK_STREAM), "Only SOCK_STREAM and SOCK_DGRAM sockets are currently supported on jython" + if sock_type == SOCK_STREAM: if protocol != 0: assert protocol == IPPROTO_TCP, "Only IPPROTO_TCP supported on SOCK_STREAM sockets" - return _tcpsocket() + else: + protocol = IPPROTO_TCP + result = _tcpsocket() else: if protocol != 0: assert protocol == IPPROTO_UDP, "Only IPPROTO_UDP supported on SOCK_DGRAM sockets" - return _udpsocket() + else: + protocol = IPPROTO_UDP + result = _udpsocket() + setattr(result, "family", family) + setattr(result, "type", sock_type) + setattr(result, "proto", protocol) + return result # # Attempt to provide IDNA (RFC 3490) support. diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -27,11 +27,6 @@ is_bsd = os_name == 'Mac OS X' or 'BSD' in os_name is_solaris = os_name == 'SunOS' -try: - True -except NameError: - True, False = 1, 0 - class SocketTCPTest(unittest.TestCase): HOST = HOST @@ -491,6 +486,18 @@ name = sock.getsockname() self.assertEqual(name, ("0.0.0.0", PORT+1)) + def testSockAttributes(self): + # Testing required attributes + for family in [socket.AF_INET, socket.AF_INET6]: + for sock_type in [socket.SOCK_STREAM, socket.SOCK_DGRAM]: + s = socket.socket(family, sock_type) + self.assertEqual(s.family, family) + self.assertEqual(s.type, sock_type) + if sock_type == socket.SOCK_STREAM: + self.assertEqual(s.proto, socket.IPPROTO_TCP) + else: + self.assertEqual(s.proto, socket.IPPROTO_UDP) + def testGetSockOpt(self): # Testing getsockopt() # We know a socket should start without reuse==0 -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sat Oct 29 20:06:57 2011 From: jython-checkins at python.org (alan.kennedy) Date: Sat, 29 Oct 2011 20:06:57 +0200 Subject: [Jython-checkins] =?utf8?q?jython_=28merge_2=2E5_-=3E_default=29?= =?utf8?q?=3A_merge_w/_2=2E5=3A_Fix_for_some_minor_socket_issues_relating_?= =?utf8?q?to_attributes?= Message-ID: http://hg.python.org/jython/rev/71b3f883f6c5 changeset: 6259:71b3f883f6c5 parent: 6257:3d719476e032 parent: 6258:be3145efdbb1 user: Alan Kennedy date: Sat Oct 29 18:59:05 2011 +0100 summary: merge w/ 2.5: Fix for some minor socket issues relating to attributes http://bugs.jython.org/issue1803 http://bugs.jython.org/issue1804 files: Lib/socket.py | 18 +++++++++++++----- Lib/test/test_socket.py | 17 ++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Lib/socket.py b/Lib/socket.py --- a/Lib/socket.py +++ b/Lib/socket.py @@ -581,17 +581,25 @@ return None return Protocol.getProtocolByName(protocol_name).getProto() -def _realsocket(family = AF_INET, type = SOCK_STREAM, protocol=0): +def _realsocket(family = AF_INET, sock_type = SOCK_STREAM, protocol=0): assert family in (AF_INET, AF_INET6), "Only AF_INET and AF_INET6 sockets are currently supported on jython" - assert type in (SOCK_DGRAM, SOCK_STREAM), "Only SOCK_STREAM and SOCK_DGRAM sockets are currently supported on jython" - if type == SOCK_STREAM: + assert sock_type in (SOCK_DGRAM, SOCK_STREAM), "Only SOCK_STREAM and SOCK_DGRAM sockets are currently supported on jython" + if sock_type == SOCK_STREAM: if protocol != 0: assert protocol == IPPROTO_TCP, "Only IPPROTO_TCP supported on SOCK_STREAM sockets" - return _tcpsocket() + else: + protocol = IPPROTO_TCP + result = _tcpsocket() else: if protocol != 0: assert protocol == IPPROTO_UDP, "Only IPPROTO_UDP supported on SOCK_DGRAM sockets" - return _udpsocket() + else: + protocol = IPPROTO_UDP + result = _udpsocket() + setattr(result, "family", family) + setattr(result, "type", sock_type) + setattr(result, "proto", protocol) + return result # # Attempt to provide IDNA (RFC 3490) support. diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -27,11 +27,6 @@ is_bsd = os_name == 'Mac OS X' or 'BSD' in os_name is_solaris = os_name == 'SunOS' -try: - True -except NameError: - True, False = 1, 0 - class SocketTCPTest(unittest.TestCase): HOST = HOST @@ -491,6 +486,18 @@ name = sock.getsockname() self.assertEqual(name, ("0.0.0.0", PORT+1)) + def testSockAttributes(self): + # Testing required attributes + for family in [socket.AF_INET, socket.AF_INET6]: + for sock_type in [socket.SOCK_STREAM, socket.SOCK_DGRAM]: + s = socket.socket(family, sock_type) + self.assertEqual(s.family, family) + self.assertEqual(s.type, sock_type) + if sock_type == socket.SOCK_STREAM: + self.assertEqual(s.proto, socket.IPPROTO_TCP) + else: + self.assertEqual(s.proto, socket.IPPROTO_UDP) + def testGetSockOpt(self): # Testing getsockopt() # We know a socket should start without reuse==0 -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sun Oct 30 14:13:30 2011 From: jython-checkins at python.org (alan.kennedy) Date: Sun, 30 Oct 2011 14:13:30 +0100 Subject: [Jython-checkins] =?utf8?q?jython_=282=2E5=29=3A_Fix_for_xml_attr?= =?utf8?q?ibute_namespaces_issue?= Message-ID: http://hg.python.org/jython/rev/936bd1b132eb changeset: 6260:936bd1b132eb branch: 2.5 user: Alan Kennedy date: Sun Oct 30 13:07:20 2011 +0000 summary: Fix for xml attribute namespaces issue http://bugs.jython.org/issue1768 files: Lib/test/test_sax.py | 46 ++++++++-------- Lib/xml/sax/drivers2/drv_javasax.py | 2 +- NEWS | 3 + 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py --- a/Lib/test/test_sax.py +++ b/Lib/test/test_sax.py @@ -390,22 +390,23 @@ gather = AttrGatherer() parser.setContentHandler(gather) - parser.parse(StringIO("" % ns_uri)) + a_name = "id" ; a_val = "val" + parser.parse(StringIO("" % (ns_uri, a_name, a_val) )) attrs = gather._attrs return attrs.getLength() == 1 and \ - attrs.getNames() == [(ns_uri, "attr")] and \ - attrs.getQNames() == ["ns:attr"] and \ + attrs.getNames() == [(ns_uri, a_name)] and \ + attrs.getQNames() == ["ns:%s" % a_name] and \ len(attrs) == 1 and \ - attrs.has_key((ns_uri, "attr")) and \ - attrs.keys() == [(ns_uri, "attr")] and \ - attrs.get((ns_uri, "attr")) == "val" and \ - attrs.get((ns_uri, "attr"), 25) == "val" and \ - attrs.items() == [((ns_uri, "attr"), "val")] and \ - attrs.values() == ["val"] and \ - attrs.getValue((ns_uri, "attr")) == "val" and \ - attrs[(ns_uri, "attr")] == "val" + attrs.has_key((ns_uri, a_name)) and \ + attrs.keys() == [(ns_uri, a_name)] and \ + attrs.get((ns_uri, a_name)) == a_val and \ + attrs.get((ns_uri, a_name), 25) == a_val and \ + attrs.items() == [((ns_uri, a_name), a_val)] and \ + attrs.values() == [a_val] and \ + attrs.getValue((ns_uri, a_name)) == a_val and \ + attrs[(ns_uri, a_name)] == a_val def test_expat_nsattrs_no_namespace(): parser = make_parser() @@ -413,22 +414,23 @@ gather = AttrGatherer() parser.setContentHandler(gather) - parser.parse(StringIO("")) + a_name = "id" ; a_val = "val" + parser.parse(StringIO("" % (a_name, a_val) )) attrs = gather._attrs return attrs.getLength() == 1 and \ - attrs.getNames() == [(None, "attr")] and \ - attrs.getQNames() == ["attr"] and \ + attrs.getNames() == [(None, a_name)] and \ + attrs.getQNames() == [a_name] and \ len(attrs) == 1 and \ - attrs.has_key((None, "attr")) and \ - attrs.keys() == [(None, "attr")] and \ - attrs.get((None, "attr")) == "val" and \ - attrs.get((None, "attr"), 25) == "val" and \ - attrs.items() == [((None, "attr"), "val")] and \ - attrs.values() == ["val"] and \ - attrs.getValue((None, "attr")) == "val" and \ - attrs[(None, "attr")] == "val" + attrs.has_key((None, a_name)) and \ + attrs.keys() == [(None, a_name)] and \ + attrs.get((None, a_name)) == a_val and \ + attrs.get((None, a_name), 25) == a_val and \ + attrs.items() == [((None, a_name), a_val)] and \ + attrs.values() == [a_val] and \ + attrs.getValue((None, a_name)) == a_val and \ + attrs[(None, a_name)] == a_val # ===== InputSource support diff --git a/Lib/xml/sax/drivers2/drv_javasax.py b/Lib/xml/sax/drivers2/drv_javasax.py --- a/Lib/xml/sax/drivers2/drv_javasax.py +++ b/Lib/xml/sax/drivers2/drv_javasax.py @@ -238,7 +238,7 @@ pass # TODO def _fixTuple(nsTuple, frm, to): - if len(nsTuple) == 2: + if isinstance(nsTuple, tuple) and len(nsTuple) == 2: nsUri, localName = nsTuple if nsUri == frm: nsUri = to diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -5,6 +5,9 @@ - [ 1727 ] Error in Jython 2.5.2 with os.stat and varargs - [ 1735 ] return type of os.read is unicode, not str - [ 1755 ] os.utime('/tmp/nonexistent-file', None) fails to raise OSError + - [ 1768 ] sax.parse doesn't handle attributes with name 'id' correctly + - [ 1803 ] _tcpsocket doesn't have 'family' attribute + - [ 1804 ] _tcpsocket doesn't have 'type' and 'proto' attributes - [ 1811 ] Recursive import bug w/ SQLAlchemy 0.7.3 Jython 2.5.2 -- Repository URL: http://hg.python.org/jython From jython-checkins at python.org Sun Oct 30 14:13:30 2011 From: jython-checkins at python.org (alan.kennedy) Date: Sun, 30 Oct 2011 14:13:30 +0100 Subject: [Jython-checkins] =?utf8?q?jython_=28merge_2=2E5_-=3E_default=29?= =?utf8?q?=3A_merge_from_2=2E5=3A_Fix_for_xml_attribute_namespace_issue?= Message-ID: http://hg.python.org/jython/rev/179cb4437158 changeset: 6261:179cb4437158 parent: 6259:71b3f883f6c5 parent: 6260:936bd1b132eb user: Alan Kennedy date: Sun Oct 30 13:11:40 2011 +0000 summary: merge from 2.5: Fix for xml attribute namespace issue http://bugs.jython.org/issue1768 files: Lib/test/test_sax.py | 46 ++++++++-------- Lib/xml/sax/drivers2/drv_javasax.py | 2 +- NEWS | 3 + 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py --- a/Lib/test/test_sax.py +++ b/Lib/test/test_sax.py @@ -390,22 +390,23 @@ gather = AttrGatherer() parser.setContentHandler(gather) - parser.parse(StringIO("" % ns_uri)) + a_name = "id" ; a_val = "val" + parser.parse(StringIO("" % (ns_uri, a_name, a_val) )) attrs = gather._attrs return attrs.getLength() == 1 and \ - attrs.getNames() == [(ns_uri, "attr")] and \ - attrs.getQNames() == ["ns:attr"] and \ + attrs.getNames() == [(ns_uri, a_name)] and \ + attrs.getQNames() == ["ns:%s" % a_name] and \ len(attrs) == 1 and \ - attrs.has_key((ns_uri, "attr")) and \ - attrs.keys() == [(ns_uri, "attr")] and \ - attrs.get((ns_uri, "attr")) == "val" and \ - attrs.get((ns_uri, "attr"), 25) == "val" and \ - attrs.items() == [((ns_uri, "attr"), "val")] and \ - attrs.values() == ["val"] and \ - attrs.getValue((ns_uri, "attr")) == "val" and \ - attrs[(ns_uri, "attr")] == "val" + attrs.has_key((ns_uri, a_name)) and \ + attrs.keys() == [(ns_uri, a_name)] and \ + attrs.get((ns_uri, a_name)) == a_val and \ + attrs.get((ns_uri, a_name), 25) == a_val and \ + attrs.items() == [((ns_uri, a_name), a_val)] and \ + attrs.values() == [a_val] and \ + attrs.getValue((ns_uri, a_name)) == a_val and \ + attrs[(ns_uri, a_name)] == a_val def test_expat_nsattrs_no_namespace(): parser = make_parser() @@ -413,22 +414,23 @@ gather = AttrGatherer() parser.setContentHandler(gather) - parser.parse(StringIO("")) + a_name = "id" ; a_val = "val" + parser.parse(StringIO("" % (a_name, a_val) )) attrs = gather._attrs return attrs.getLength() == 1 and \ - attrs.getNames() == [(None, "attr")] and \ - attrs.getQNames() == ["attr"] and \ + attrs.getNames() == [(None, a_name)] and \ + attrs.getQNames() == [a_name] and \ len(attrs) == 1 and \ - attrs.has_key((None, "attr")) and \ - attrs.keys() == [(None, "attr")] and \ - attrs.get((None, "attr")) == "val" and \ - attrs.get((None, "attr"), 25) == "val" and \ - attrs.items() == [((None, "attr"), "val")] and \ - attrs.values() == ["val"] and \ - attrs.getValue((None, "attr")) == "val" and \ - attrs[(None, "attr")] == "val" + attrs.has_key((None, a_name)) and \ + attrs.keys() == [(None, a_name)] and \ + attrs.get((None, a_name)) == a_val and \ + attrs.get((None, a_name), 25) == a_val and \ + attrs.items() == [((None, a_name), a_val)] and \ + attrs.values() == [a_val] and \ + attrs.getValue((None, a_name)) == a_val and \ + attrs[(None, a_name)] == a_val # ===== InputSource support diff --git a/Lib/xml/sax/drivers2/drv_javasax.py b/Lib/xml/sax/drivers2/drv_javasax.py --- a/Lib/xml/sax/drivers2/drv_javasax.py +++ b/Lib/xml/sax/drivers2/drv_javasax.py @@ -238,7 +238,7 @@ pass # TODO def _fixTuple(nsTuple, frm, to): - if len(nsTuple) == 2: + if isinstance(nsTuple, tuple) and len(nsTuple) == 2: nsUri, localName = nsTuple if nsUri == frm: nsUri = to diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -5,6 +5,9 @@ - [ 1727 ] Error in Jython 2.5.2 with os.stat and varargs - [ 1735 ] return type of os.read is unicode, not str - [ 1755 ] os.utime('/tmp/nonexistent-file', None) fails to raise OSError + - [ 1768 ] sax.parse doesn't handle attributes with name 'id' correctly + - [ 1803 ] _tcpsocket doesn't have 'family' attribute + - [ 1804 ] _tcpsocket doesn't have 'type' and 'proto' attributes - [ 1811 ] Recursive import bug w/ SQLAlchemy 0.7.3 Jython 2.5.2 -- Repository URL: http://hg.python.org/jython