You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(107) |
Dec
(67) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(76) |
Feb
(125) |
Mar
(72) |
Apr
(13) |
May
(18) |
Jun
(12) |
Jul
(129) |
Aug
(47) |
Sep
(1) |
Oct
(36) |
Nov
(128) |
Dec
(124) |
2002 |
Jan
(59) |
Feb
|
Mar
(14) |
Apr
(14) |
May
(72) |
Jun
(9) |
Jul
(3) |
Aug
(5) |
Sep
(18) |
Oct
(65) |
Nov
(28) |
Dec
(12) |
2003 |
Jan
(10) |
Feb
(2) |
Mar
(4) |
Apr
(33) |
May
(21) |
Jun
(9) |
Jul
(29) |
Aug
(34) |
Sep
(4) |
Oct
(8) |
Nov
(15) |
Dec
(4) |
2004 |
Jan
(26) |
Feb
(12) |
Mar
(11) |
Apr
(9) |
May
(7) |
Jun
|
Jul
(5) |
Aug
|
Sep
(3) |
Oct
(7) |
Nov
(1) |
Dec
(10) |
2005 |
Jan
(2) |
Feb
(72) |
Mar
(16) |
Apr
(39) |
May
(48) |
Jun
(97) |
Jul
(57) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(100) |
Dec
(24) |
2006 |
Jan
(15) |
Feb
(34) |
Mar
(33) |
Apr
(31) |
May
(79) |
Jun
(64) |
Jul
(41) |
Aug
(64) |
Sep
(31) |
Oct
(46) |
Nov
(55) |
Dec
(37) |
2007 |
Jan
(32) |
Feb
(61) |
Mar
(11) |
Apr
(58) |
May
(46) |
Jun
(30) |
Jul
(94) |
Aug
(93) |
Sep
(86) |
Oct
(69) |
Nov
(125) |
Dec
(177) |
2008 |
Jan
(169) |
Feb
(97) |
Mar
(74) |
Apr
(113) |
May
(120) |
Jun
(334) |
Jul
(215) |
Aug
(237) |
Sep
(72) |
Oct
(189) |
Nov
(126) |
Dec
(160) |
2009 |
Jan
(180) |
Feb
(45) |
Mar
(98) |
Apr
(140) |
May
(151) |
Jun
(71) |
Jul
(107) |
Aug
(119) |
Sep
(73) |
Oct
(121) |
Nov
(14) |
Dec
(6) |
2010 |
Jan
(13) |
Feb
(9) |
Mar
(10) |
Apr
(64) |
May
(3) |
Jun
(16) |
Jul
(7) |
Aug
(23) |
Sep
(17) |
Oct
(37) |
Nov
(5) |
Dec
(8) |
2011 |
Jan
(10) |
Feb
(11) |
Mar
(77) |
Apr
(11) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <pj...@us...> - 2010-04-18 00:59:08
|
Revision: 7034 http://jython.svn.sourceforge.net/jython/?rev=7034&view=rev Author: pjenvey Date: 2010-04-18 00:59:01 +0000 (Sun, 18 Apr 2010) Log Message: ----------- update to jffi-1.0.1/jaffl-0.5.1/jnr-posix-1.1.4-79b6c76/constantine-0.7 Modified Paths: -------------- trunk/jython/build.xml trunk/jython/extlibs/constantine.jar trunk/jython/extlibs/jaffl.jar trunk/jython/extlibs/jffi-Darwin.jar trunk/jython/extlibs/jffi-i386-FreeBSD.jar trunk/jython/extlibs/jffi-i386-Linux.jar trunk/jython/extlibs/jffi-i386-SunOS.jar trunk/jython/extlibs/jffi-i386-Windows.jar trunk/jython/extlibs/jffi-ppc-AIX.jar trunk/jython/extlibs/jffi-s390x-Linux.jar trunk/jython/extlibs/jffi-sparc-SunOS.jar trunk/jython/extlibs/jffi-sparcv9-SunOS.jar trunk/jython/extlibs/jffi-x86_64-FreeBSD.jar trunk/jython/extlibs/jffi-x86_64-Linux.jar trunk/jython/extlibs/jffi-x86_64-SunOS.jar trunk/jython/extlibs/jffi.jar trunk/jython/extlibs/jnr-posix.jar trunk/jython/src/org/python/modules/posix/PosixModule.java trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java Added Paths: ----------- trunk/jython/extlibs/jffi-ppc-Linux.jar trunk/jython/extlibs/jffi-ppc64-Linux.jar trunk/jython/extlibs/jffi-x86_64-Windows.jar Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2010-04-17 19:35:37 UTC (rev 7033) +++ trunk/jython/build.xml 2010-04-18 00:59:01 UTC (rev 7034) @@ -196,6 +196,8 @@ <pathelement path="${extlibs.dir}/jffi-i386-SunOS.jar"/> <pathelement path="${extlibs.dir}/jffi-i386-Windows.jar"/> <pathelement path="${extlibs.dir}/jffi-ppc-AIX.jar"/> + <pathelement path="${extlibs.dir}/jffi-ppc-Linux.jar"/> + <pathelement path="${extlibs.dir}/jffi-ppc64-Linux.jar"/> <pathelement path="${extlibs.dir}/jffi-s390x-Linux.jar"/> <pathelement path="${extlibs.dir}/jffi-sparc-SunOS.jar"/> <pathelement path="${extlibs.dir}/jffi-sparcv9-SunOS.jar"/> @@ -203,6 +205,7 @@ <pathelement path="${extlibs.dir}/jffi-x86_64-Linux.jar"/> <pathelement path="${extlibs.dir}/jffi-x86_64-OpenBSD.jar"/> <pathelement path="${extlibs.dir}/jffi-x86_64-SunOS.jar"/> + <pathelement path="${extlibs.dir}/jffi-x86_64-Windows.jar"/> <pathelement path="${extlibs.dir}/jffi.jar"/> <pathelement path="${extlibs.dir}/jnr-posix.jar"/> <pathelement path="${extlibs.dir}/jnr-netdb-0.4.jar"/> @@ -589,6 +592,8 @@ <zipfileset src="extlibs/jffi-i386-SunOS.jar"/> <zipfileset src="extlibs/jffi-i386-Windows.jar"/> <zipfileset src="extlibs/jffi-ppc-AIX.jar"/> + <zipfileset src="extlibs/jffi-ppc-Linux.jar"/> + <zipfileset src="extlibs/jffi-ppc64-Linux.jar"/> <zipfileset src="extlibs/jffi-s390x-Linux.jar"/> <zipfileset src="extlibs/jffi-sparc-SunOS.jar"/> <zipfileset src="extlibs/jffi-sparcv9-SunOS.jar"/> @@ -596,6 +601,7 @@ <zipfileset src="extlibs/jffi-x86_64-Linux.jar"/> <zipfileset src="extlibs/jffi-x86_64-OpenBSD.jar"/> <zipfileset src="extlibs/jffi-x86_64-SunOS.jar"/> + <zipfileset src="extlibs/jffi-x86_64-Windows.jar"/> <zipfileset src="extlibs/jffi.jar"/> <zipfileset src="extlibs/jnr-posix.jar"/> <zipfileset src="extlibs/jnr-netdb-0.4.jar"/> Modified: trunk/jython/extlibs/constantine.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jaffl.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-Darwin.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-i386-FreeBSD.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-i386-Linux.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-i386-SunOS.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-i386-Windows.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-ppc-AIX.jar =================================================================== (Binary files differ) Added: trunk/jython/extlibs/jffi-ppc-Linux.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-ppc-Linux.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-ppc64-Linux.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-ppc64-Linux.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/jython/extlibs/jffi-s390x-Linux.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-sparc-SunOS.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-sparcv9-SunOS.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-x86_64-FreeBSD.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-x86_64-Linux.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-x86_64-SunOS.jar =================================================================== (Binary files differ) Added: trunk/jython/extlibs/jffi-x86_64-Windows.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-x86_64-Windows.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/jython/extlibs/jffi.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jnr-posix.jar =================================================================== (Binary files differ) Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-17 19:35:37 UTC (rev 7033) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-18 00:59:01 UTC (rev 7034) @@ -18,7 +18,6 @@ import java.util.Map; import org.jruby.ext.posix.FileStat; -import org.jruby.ext.posix.JavaPOSIX; import org.jruby.ext.posix.POSIX; import org.jruby.ext.posix.POSIXFactory; import org.jruby.ext.posix.util.Platform; @@ -104,7 +103,7 @@ // Successful termination dict.__setitem__("EX_OK", Py.Zero); - boolean nativePosix = !(posix instanceof JavaPOSIX); + boolean nativePosix = posix.isNative(); dict.__setitem__("_native_posix", Py.newBoolean(nativePosix)); dict.__setitem__("_posix_impl", Py.java2py(posix)); dict.__setitem__("environ", getEnviron()); Modified: trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java 2010-04-17 19:35:37 UTC (rev 7033) +++ trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java 2010-04-18 00:59:01 UTC (rev 7034) @@ -1,8 +1,7 @@ /* Copyright (c) Jython Developers */ package org.python.modules.posix; -import com.kenai.constantine.Constant; -import com.kenai.constantine.ConstantSet; +import com.kenai.constantine.platform.Errno; import java.io.File; import java.io.InputStream; @@ -21,14 +20,8 @@ */ public class PythonPOSIXHandler implements POSIXHandler { - private ConstantSet errnos = ConstantSet.getConstantSet("Errno"); - - public void error(POSIX.ERRORS error, String extraData) { - Constant errno = errnos.getConstant(error.name()); - if (errno == null) { - throw Py.OSError(extraData); - } - throw Py.OSError(errno, extraData); + public void error(Errno error, String extraData) { + throw Py.OSError(error, extraData); } public void unimplementedError(String methodName) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-17 19:35:44
|
Revision: 7033 http://jython.svn.sourceforge.net/jython/?rev=7033&view=rev Author: pjenvey Date: 2010-04-17 19:35:37 +0000 (Sat, 17 Apr 2010) Log Message: ----------- minor changes Modified Paths: -------------- trunk/jython/src/org/python/core/PyBaseCode.java Modified: trunk/jython/src/org/python/core/PyBaseCode.java =================================================================== --- trunk/jython/src/org/python/core/PyBaseCode.java 2010-04-17 18:16:45 UTC (rev 7032) +++ trunk/jython/src/org/python/core/PyBaseCode.java 2010-04-17 19:35:37 UTC (rev 7033) @@ -1,4 +1,7 @@ -// Copyright (c) Corporation for National Research Initiatives +/* + * Copyright (c) Corporation for National Research Initiatives + * Copyright (c) Jython Developers + */ package org.python.core; import org.python.modules._systemrestart; @@ -191,17 +194,16 @@ return call(state, os, keywords, globals, defaults, closure); } - public PyObject call(ThreadState state, PyObject args[], String kws[], PyObject globals, PyObject[] defs, - PyObject closure) { + public PyObject call(ThreadState state, PyObject args[], String kws[], PyObject globals, + PyObject[] defs, PyObject closure) { PyFrame frame = new PyFrame(this, globals); int argcount = args.length - kws.length; - int defcount = defs != null ? defs.length : 0; - PyObject[] fastlocals = frame.f_fastlocals; if (co_argcount > 0 || (varargs || varkwargs)) { int i; int n = argcount; PyObject kwdict = null; + PyObject[] fastlocals = frame.f_fastlocals; if (varkwargs) { kwdict = new PyDictionary(); i = co_argcount; @@ -212,6 +214,7 @@ } if (argcount > co_argcount) { if (!varargs) { + int defcount = defs != null ? defs.length : 0; String msg = String.format("%.200s() takes %s %d %sargument%s (%d given)", co_name, defcount > 0 ? "at most" : "exactly", @@ -263,6 +266,7 @@ } } if (argcount < co_argcount) { + int defcount = defs != null ? defs.length : 0; int m = co_argcount - defcount; for (i = argcount; i < m; i++) { if (fastlocals[i] == null) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-17 18:16:51
|
Revision: 7032 http://jython.svn.sourceforge.net/jython/?rev=7032&view=rev Author: amak Date: 2010-04-17 18:16:45 +0000 (Sat, 17 Apr 2010) Log Message: ----------- Fix for bug 1375: XML SAX: attrs.get((None, 'attr')) gives NPE Modified Paths: -------------- trunk/jython/Lib/test/test_sax.py trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py Modified: trunk/jython/Lib/test/test_sax.py =================================================================== --- trunk/jython/Lib/test/test_sax.py 2010-04-17 16:51:11 UTC (rev 7031) +++ trunk/jython/Lib/test/test_sax.py 2010-04-17 18:16:45 UTC (rev 7032) @@ -407,6 +407,29 @@ attrs.getValue((ns_uri, "attr")) == "val" and \ attrs[(ns_uri, "attr")] == "val" +def test_expat_nsattrs_no_namespace(): + parser = make_parser() + parser.setFeature(handler.feature_namespaces, 1) + gather = AttrGatherer() + parser.setContentHandler(gather) + + parser.parse(StringIO("<doc attr='val'/>")) + + attrs = gather._attrs + + return attrs.getLength() == 1 and \ + attrs.getNames() == [(None, "attr")] and \ + attrs.getQNames() == ["attr"] 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" + # ===== InputSource support xml_test_out = open(findfile("test.xml.out")).read() Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-17 16:51:11 UTC (rev 7031) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-17 18:16:45 UTC (rev 7032) @@ -237,7 +237,22 @@ def endEntity(self, name): pass # TODO +def _fixTuple(nsTuple, frm, to): + if len(nsTuple) == 2: + nsUri, localName = nsTuple + if nsUri == frm: + nsUri = to + return (nsUri, localName) + return nsTuple + +def _makeJavaNsTuple(nsTuple): + return _fixTuple(nsTuple, None, '') + +def _makePythonNsTuple(nsTuple): + return _fixTuple(nsTuple, '', None) + class AttributesImpl: + def __init__(self, attrs = None): self._attrs = attrs @@ -245,16 +260,16 @@ return self._attrs.getLength() def getType(self, name): - return self._attrs.getType(name) + return self._attrs.getType(_makeJavaNsTuple(name)) def getValue(self, name): - value = self._attrs.getValue(name) + value = self._attrs.getValue(_makeJavaNsTuple(name)) if value == None: raise KeyError(name) return value def getNames(self): - return [self._attrs.getQName(index) for index in range(len(self))] + return [_makePythonNsTuple(self._attrs.getQName(index)) for index in range(len(self))] def getQNames(self): return [self._attrs.getQName(index) for index in range(len(self))] @@ -272,7 +287,7 @@ return qname def getQNameByName(self, name): - idx = self._attrs.getIndex(name) + idx = self._attrs.getIndex(_makeJavaNsTuple(name)) if idx == -1: raise KeyError, name return name @@ -316,10 +331,12 @@ AttributesImpl.__init__(self, attrs) def getType(self, name): + name = _makeJavaNsTuple(name) return self._attrs.getType(name[0], name[1]) def getValue(self, name): - value = self._attrs.getValue(name[0], name[1]) + jname = _makeJavaNsTuple(name) + value = self._attrs.getValue(jname[0], jname[1]) if value == None: raise KeyError(name) return value @@ -327,17 +344,17 @@ def getNames(self): names = [] for idx in range(len(self)): - names.append((self._attrs.getURI(idx), - self._attrs.getLocalName(idx))) + names.append(_makePythonNsTuple( (self._attrs.getURI(idx), self._attrs.getLocalName(idx)) )) return names def getNameByQName(self, qname): idx = self._attrs.getIndex(qname) if idx == -1: raise KeyError, qname - return (self._attrs.getURI(idx), self._attrs.getLocalName(idx)) + return _makePythonNsTuple( (self._attrs.getURI(idx), self._attrs.getLocalName(idx)) ) def getQNameByName(self, name): + name = _makeJavaNsTuple(name) idx = self._attrs.getIndex(name[0], name[1]) if idx == -1: raise KeyError, name This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-17 16:51:19
|
Revision: 7031 http://jython.svn.sourceforge.net/jython/?rev=7031&view=rev Author: pjenvey Date: 2010-04-17 16:51:11 +0000 (Sat, 17 Apr 2010) Log Message: ----------- minor cleanup Modified Paths: -------------- trunk/jython/src/org/python/core/PyBuiltinCallable.java trunk/jython/src/org/python/core/PyXRange.java Modified: trunk/jython/src/org/python/core/PyBuiltinCallable.java =================================================================== --- trunk/jython/src/org/python/core/PyBuiltinCallable.java 2010-04-16 18:50:03 UTC (rev 7030) +++ trunk/jython/src/org/python/core/PyBuiltinCallable.java 2010-04-17 16:51:11 UTC (rev 7031) @@ -1,3 +1,4 @@ +/* Copyright (c) Jython Developers */ package org.python.core; import org.python.expose.ExposedGet; @@ -53,6 +54,7 @@ this.info = info; } + @Override public String toString() { PyObject self = getSelf(); if (self == null) { @@ -76,6 +78,10 @@ public static class DefaultInfo implements Info { + private String name; + + private int maxargs, minargs; + public DefaultInfo(String name, int minargs, int maxargs) { this.name = name; this.minargs = minargs; @@ -86,10 +92,6 @@ this(name, -1, -1); } - private String name; - - private int maxargs, minargs; - public String getName() { return name; } @@ -103,39 +105,39 @@ } public static boolean check(int nargs, int minargs, int maxargs) { - if(nargs < minargs) + if (nargs < minargs) { return false; - if(maxargs != -1 && nargs > maxargs) + } + if (maxargs != -1 && nargs > maxargs) { return false; + } return true; } - public static PyException unexpectedCall(int nargs, - boolean keywords, - String name, - int minargs, - int maxargs) { - if(keywords) + public static PyException unexpectedCall(int nargs, boolean keywords, String name, + int minargs, int maxargs) { + if (keywords) { return Py.TypeError(name + "() takes no keyword arguments"); + } + String argsblurb; - if(minargs == maxargs) { - if(minargs == 0) + if (minargs == maxargs) { + if (minargs == 0) { argsblurb = "no arguments"; - else if(minargs == 1) + } else if (minargs == 1) { argsblurb = "exactly one argument"; - else + } else { argsblurb = minargs + " arguments"; - } else if(maxargs == -1) { - return Py.TypeError(name + "() requires at least " + minargs - + " (" + nargs + " given)"); + } + } else if (maxargs == -1) { + return Py.TypeError(String.format("%s() requires at least %d arguments (%d) given", + name, minargs, nargs)); + } else if (minargs <= 0) { + argsblurb = "at most " + maxargs + " arguments"; } else { - if(minargs <= 0) - argsblurb = "at most " + maxargs + " arguments"; - else - argsblurb = minargs + "-" + maxargs + " arguments"; + argsblurb = minargs + "-" + maxargs + " arguments"; } - return Py.TypeError(name + "() takes " + argsblurb + " (" + nargs - + " given)"); + return Py.TypeError(String.format("%s() takes %s (%d given)", name, argsblurb, nargs)); } public PyException unexpectedCall(int nargs, boolean keywords) { Modified: trunk/jython/src/org/python/core/PyXRange.java =================================================================== --- trunk/jython/src/org/python/core/PyXRange.java 2010-04-16 18:50:03 UTC (rev 7030) +++ trunk/jython/src/org/python/core/PyXRange.java 2010-04-17 16:51:11 UTC (rev 7031) @@ -14,11 +14,11 @@ public static final PyType TYPE = PyType.fromClass(PyXRange.class); - private int start; + private final int start; - private int step; + private final int step; - private int len; + private final int len; public PyXRange(int ihigh) { this(0, ihigh, 1); @@ -145,15 +145,13 @@ @Override public String toString() { - String rtn; int stop = start + len * step; if (start == 0 && step == 1) { - rtn = String.format("xrange(%d)", stop); + return String.format("xrange(%d)", stop); } else if (step == 1) { - rtn = String.format("xrange(%d, %d)", start, stop); + return String.format("xrange(%d, %d)", start, stop); } else { - rtn = String.format("xrange(%d, %d, %d)", start, stop, step); + return String.format("xrange(%d, %d, %d)", start, stop, step); } - return rtn; } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-16 18:50:09
|
Revision: 7030 http://jython.svn.sourceforge.net/jython/?rev=7030&view=rev Author: amak Date: 2010-04-16 18:50:03 +0000 (Fri, 16 Apr 2010) Log Message: ----------- A full set of handlers for the LexicalHandler methods. Some will need to be implemented, e.g. the startCDATA and endCDATA methods. Modified Paths: -------------- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-16 18:22:42 UTC (rev 7029) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-16 18:50:03 UTC (rev 7030) @@ -211,9 +211,32 @@ def processingInstruction(self, target, data): self._cont_handler.processingInstruction(target, data) + # Lexical handler methods def comment(self, char, start, len): - self._cont_handler.comment(unicode(String(char, start, len))) + try: + # Need to wrap this in a try..except in case the parser does not support lexical events + self._cont_handler.comment(unicode(String(char, start, len))) + except: + pass + def startCDATA(self): + pass # TODO + + def endCDATA(self): + pass # TODO + + def startDTD(self, name, publicId, systemId): + pass # TODO + + def endDTD(self): + pass # TODO + + def startEntity(self, name): + pass # TODO + + def endEntity(self, name): + pass # TODO + class AttributesImpl: def __init__(self, attrs = None): self._attrs = attrs This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-16 18:22:48
|
Revision: 7029 http://jython.svn.sourceforge.net/jython/?rev=7029&view=rev Author: amak Date: 2010-04-16 18:22:42 +0000 (Fri, 16 Apr 2010) Log Message: ----------- Accidentally left in a debug statement. Modified Paths: -------------- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-16 18:12:55 UTC (rev 7028) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-16 18:22:42 UTC (rev 7029) @@ -212,7 +212,6 @@ self._cont_handler.processingInstruction(target, data) def comment(self, char, start, len): - print "Content handler is %s" % self._cont_handler.__class__ self._cont_handler.comment(unicode(String(char, start, len))) class AttributesImpl: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-16 18:13:01
|
Revision: 7028 http://jython.svn.sourceforge.net/jython/?rev=7028&view=rev Author: amak Date: 2010-04-16 18:12:55 +0000 (Fri, 16 Apr 2010) Log Message: ----------- Fix for bug 1488: sax JyInputSourceWrapper does not support unicode strings Thanks to Arthur Noel for the report and fix. Modified Paths: -------------- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-16 17:37:44 UTC (rev 7027) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-16 18:12:55 UTC (rev 7028) @@ -63,7 +63,7 @@ class JyInputSourceWrapper(javasax.InputSource): def __init__(self, source): - if isinstance(source, str): + if isinstance(source, basestring): javasax.InputSource.__init__(self, source) elif hasattr(source, "read"):#file like object f = source @@ -212,6 +212,7 @@ self._cont_handler.processingInstruction(target, data) def comment(self, char, start, len): + print "Content handler is %s" % self._cont_handler.__class__ self._cont_handler.comment(unicode(String(char, start, len))) class AttributesImpl: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-16 17:37:51
|
Revision: 7027 http://jython.svn.sourceforge.net/jython/?rev=7027&view=rev Author: amak Date: 2010-04-16 17:37:44 +0000 (Fri, 16 Apr 2010) Log Message: ----------- Fix for bug 1510: minidom is not parsing comment information correctly http://bugs.jython.org/issue1510 Thanks to William Bernardet for the bug report and the patch. Modified Paths: -------------- trunk/jython/Lib/test/test_pulldom.py trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py Modified: trunk/jython/Lib/test/test_pulldom.py =================================================================== --- trunk/jython/Lib/test/test_pulldom.py 2010-04-14 02:39:55 UTC (rev 7026) +++ trunk/jython/Lib/test/test_pulldom.py 2010-04-16 17:37:44 UTC (rev 7027) @@ -22,6 +22,7 @@ <p>Some greek: ΑΒΓΔΕ</p> <greek attrs="ΖΗΘΙΚ"/> <?greek ΛΜΝΞΟ?> + <!--ΛΜΝΞΟ--> </document> """ @@ -35,7 +36,7 @@ text.append(node.data) try: result = u"".join(text) - self.failUnlessEqual(repr(result), r"u'\n Some greek: \u0391\u0392\u0393\u0394\u0395\n \n \n'") + self.failUnlessEqual(repr(result), r"u'\n Some greek: \u0391\u0392\u0393\u0394\u0395\n \n \n \n'") except Exception, x: self.fail("Unexpected exception joining text pieces: %s" % str(x)) @@ -66,6 +67,17 @@ except Exception, x: self.fail("Unexpected exception joining pi data pieces: %s" % str(x)) + def testComment(self): + commentText = [] + for event, node in pulldom.parse(self.testFile): + if event == pulldom.COMMENT: + commentText.append(node.data) + try: + result = u"".join(commentText) + self.failUnlessEqual(repr(result), r"u'ΛΜΝΞΟ'") + except Exception, x: + self.fail("Unexpected exception joining comment data pieces: %s" % str(x)) + def test_main(): tests = [ UnicodeTests, Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-14 02:39:55 UTC (rev 7026) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-16 17:37:44 UTC (rev 7027) @@ -25,6 +25,7 @@ from org.python.core import FilelikeInputStream from org.xml.sax.helpers import XMLReaderFactory from org.xml import sax as javasax + from org.xml.sax.ext import LexicalHandler except ImportError: raise _exceptions.SAXReaderNotAvailable("SAX is not on the classpath", None) @@ -119,7 +120,7 @@ return self.sysId # --- JavaSAXParser -class JavaSAXParser(xmlreader.XMLReader, javasax.ContentHandler): +class JavaSAXParser(xmlreader.XMLReader, javasax.ContentHandler, LexicalHandler): "SAX driver for the Java SAX parsers." def __init__(self, jdriver = None): @@ -133,6 +134,10 @@ self.setEntityResolver(self.getEntityResolver()) self.setErrorHandler(self.getErrorHandler()) self.setDTDHandler(self.getDTDHandler()) + try: + self._parser.setProperty("http://xml.org/sax/properties/lexical-handler", self) + except Exception, x: + pass # XMLReader methods @@ -206,6 +211,9 @@ def processingInstruction(self, target, data): self._cont_handler.processingInstruction(target, data) + def comment(self, char, start, len): + self._cont_handler.comment(unicode(String(char, start, len))) + class AttributesImpl: def __init__(self, attrs = None): self._attrs = attrs This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-14 02:40:01
|
Revision: 7026 http://jython.svn.sourceforge.net/jython/?rev=7026&view=rev Author: pjenvey Date: 2010-04-14 02:39:55 +0000 (Wed, 14 Apr 2010) Log Message: ----------- make the SynchronizedCallable callable fixes #1596 Modified Paths: -------------- trunk/jython/Lib/test/test_thread_jy.py trunk/jython/NEWS trunk/jython/src/org/python/modules/synchronize.java Modified: trunk/jython/Lib/test/test_thread_jy.py =================================================================== --- trunk/jython/Lib/test/test_thread_jy.py 2010-04-14 01:59:14 UTC (rev 7025) +++ trunk/jython/Lib/test/test_thread_jy.py 2010-04-14 02:39:55 UTC (rev 7026) @@ -8,12 +8,13 @@ class AllocateLockTest(unittest.TestCase): def test_lock_type(self): - "thread.LockType should exist" + """thread.LockType should exist""" t = thread.LockType self.assertEquals(t, type(thread.allocate_lock()), "thread.LockType has wrong value") class SynchronizeTest(unittest.TestCase): + def test_make_synchronized(self): doneSignal = CountDownLatch(10) class SynchedRunnable(Runnable): @@ -28,7 +29,10 @@ doneSignal.await() self.assertEquals(10, runner.i) + def test_synchronized_callable(self): + self.assertTrue(callable(synchronize.make_synchronized(lambda: None))) + def test_main(): test.test_support.run_unittest(AllocateLockTest, SynchronizeTest) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-14 01:59:14 UTC (rev 7025) +++ trunk/jython/NEWS 2010-04-14 02:39:55 UTC (rev 7026) @@ -32,6 +32,7 @@ - [ 1390 ] ihooks fails due to unimplemented methods in imp module - [ 1456 ] sys.trace/profile attributes cause: AttributeError: write-only attr: trace in PyAMF - [ 1385 ] generator.throw uncaught on new generator doesn't stop the generator + - [ 1596 ] SynchronizedCallable does not report that it is callable [suggested fix] - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/modules/synchronize.java =================================================================== --- trunk/jython/src/org/python/modules/synchronize.java 2010-04-14 01:59:14 UTC (rev 7025) +++ trunk/jython/src/org/python/modules/synchronize.java 2010-04-14 02:39:55 UTC (rev 7026) @@ -89,5 +89,10 @@ return callable.__call__(arg1, args, keywords); } } + + @Override + public boolean isCallable() { + return true; + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-14 01:59:21
|
Revision: 7025 http://jython.svn.sourceforge.net/jython/?rev=7025&view=rev Author: pjenvey Date: 2010-04-14 01:59:14 +0000 (Wed, 14 Apr 2010) Log Message: ----------- small posix cleanup, remove its now unneeded initEncoding workaround Modified Paths: -------------- trunk/jython/src/org/python/core/PySystemState.java trunk/jython/src/org/python/modules/posix/Hider.java trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2010-04-13 02:16:14 UTC (rev 7024) +++ trunk/jython/src/org/python/core/PySystemState.java 2010-04-14 01:59:14 UTC (rev 7025) @@ -169,13 +169,7 @@ stdin = __stdin__ = new PyFile(System.in, "<stdin>", "r" + mode, buffering, false); stdout = __stdout__ = new PyFile(System.out, "<stdout>", "w" + mode, buffering, false); stderr = __stderr__ = new PyFile(System.err, "<stderr>", "w" + mode, 0, false); - if (Py.getSystemState() != null) { - // XXX: initEncoding fails without an existing sys module as it can't import - // os (for os.isatty). In that case PySystemState.doInitialize calls it for - // us. The correct fix for this is rewriting the posix/nt module portions of - // os in Java - initEncoding(); - } + initEncoding(); __displayhook__ = new PySystemStateFunctions("displayhook", 10, 1, 1); __excepthook__ = new PySystemStateFunctions("excepthook", 30, 3, 3); Modified: trunk/jython/src/org/python/modules/posix/Hider.java =================================================================== --- trunk/jython/src/org/python/modules/posix/Hider.java 2010-04-13 02:16:14 UTC (rev 7024) +++ trunk/jython/src/org/python/modules/posix/Hider.java 2010-04-14 01:59:14 UTC (rev 7025) @@ -25,8 +25,9 @@ * @param native whether the underlying posix is native */ public static void hideFunctions(Class<?> cls, PyObject dict, OS os, boolean isNative) { + PosixImpl posixImpl = isNative ? PosixImpl.NATIVE : PosixImpl.JAVA; for (Method method: cls.getDeclaredMethods()) { - if (isHidden(method, os, isNative ? PosixImpl.NATIVE : PosixImpl.JAVA)) { + if (isHidden(method, os, posixImpl)) { dict.__setitem__(method.getName(), null); } } Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-13 02:16:14 UTC (rev 7024) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-14 01:59:14 UTC (rev 7025) @@ -118,6 +118,7 @@ // Hide from Python Hider.hideFunctions(PosixModule.class, dict, os, nativePosix); dict.__setitem__("classDictInit", null); + dict.__setitem__("__init__", null); dict.__setitem__("getPOSIX", null); dict.__setitem__("getOSName", null); dict.__setitem__("badFD", null); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-13 02:16:20
|
Revision: 7024 http://jython.svn.sourceforge.net/jython/?rev=7024&view=rev Author: pjenvey Date: 2010-04-13 02:16:14 +0000 (Tue, 13 Apr 2010) Log Message: ----------- fix throw on a just started generator not fully stopping it fixes #1385 Modified Paths: -------------- trunk/jython/Lib/test/test_generators_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyGenerator.java Modified: trunk/jython/Lib/test/test_generators_jy.py =================================================================== --- trunk/jython/Lib/test/test_generators_jy.py 2010-04-13 00:35:47 UTC (rev 7023) +++ trunk/jython/Lib/test/test_generators_jy.py 2010-04-13 02:16:14 UTC (rev 7024) @@ -1,7 +1,7 @@ from __future__ import generators import unittest -#tests for deeply nested try/except/finally's +# tests for deeply nested try/except/finally's class FinallyTests(unittest.TestCase): def gen1(self): @@ -160,5 +160,13 @@ def testExcept(self): self.assertEquals([1, 1, 1], list(self.genNestedExcept())) +class TestThrowTestCase(unittest.TestCase): + + def test_just_started_throw(self): + genexp = (i for i in range(2)) + self.assertRaises(IOError, genexp.throw, IOError) + self.assertEqual(genexp.gi_frame, None) + self.assertRaises(StopIteration, genexp.next) + if __name__ == "__main__": unittest.main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-13 00:35:47 UTC (rev 7023) +++ trunk/jython/NEWS 2010-04-13 02:16:14 UTC (rev 7024) @@ -31,6 +31,7 @@ - [ 1483 ] optparse std module dies on non-ASCII unicode data - [ 1390 ] ihooks fails due to unimplemented methods in imp module - [ 1456 ] sys.trace/profile attributes cause: AttributeError: write-only attr: trace in PyAMF + - [ 1385 ] generator.throw uncaught on new generator doesn't stop the generator - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/core/PyGenerator.java =================================================================== --- trunk/jython/src/org/python/core/PyGenerator.java 2010-04-13 00:35:47 UTC (rev 7023) +++ trunk/jython/src/org/python/core/PyGenerator.java 2010-04-13 02:16:14 UTC (rev 7024) @@ -93,6 +93,7 @@ private PyObject raiseException(PyException ex) { if (gi_frame == null || gi_frame.f_lasti == 0) { + gi_frame = null; throw ex; } gi_frame.setGeneratorInput(ex); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-13 00:35:53
|
Revision: 7023 http://jython.svn.sourceforge.net/jython/?rev=7023&view=rev Author: pjenvey Date: 2010-04-13 00:35:47 +0000 (Tue, 13 Apr 2010) Log Message: ----------- bump bytecode magic Modified Paths: -------------- trunk/jython/src/org/python/core/imp.java Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2010-04-12 22:03:17 UTC (rev 7022) +++ trunk/jython/src/org/python/core/imp.java 2010-04-13 00:35:47 UTC (rev 7023) @@ -21,7 +21,7 @@ private static final String UNKNOWN_SOURCEFILE = "<unknown>"; - private static final int APIVersion = 26; + private static final int APIVersion = 27; public static final int NO_MTIME = -1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-12 22:03:23
|
Revision: 7022 http://jython.svn.sourceforge.net/jython/?rev=7022&view=rev Author: amak Date: 2010-04-12 22:03:17 +0000 (Mon, 12 Apr 2010) Log Message: ----------- Fixing a bug with translation of line endings when that should not be happening. Fixes http://bugs.jython.org/issue1549 Thanks to Jacob Fenwick for the (jfenwick) for the patch. Modified Paths: -------------- trunk/jython/Lib/modjy/modjy_wsgi.py trunk/jython/src/org/python/core/PyFile.java trunk/jython/src/org/python/core/util/FileUtil.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java Added Paths: ----------- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestPostData.java trunk/jython/tests/modjy/test_apps_dir/post_data_tests.py Modified: trunk/jython/Lib/modjy/modjy_wsgi.py =================================================================== --- trunk/jython/Lib/modjy/modjy_wsgi.py 2010-04-12 16:47:34 UTC (rev 7021) +++ trunk/jython/Lib/modjy/modjy_wsgi.py 2010-04-12 22:03:17 UTC (rev 7022) @@ -125,7 +125,7 @@ def set_wsgi_streams(self, req, resp, dict): try: - dict["wsgi.input"] = create_py_file(req.getInputStream()) + dict["wsgi.input"] = create_py_file(req.getInputStream(), "rb") dict["wsgi.errors"] = create_py_file(System.err) except IOException, iox: raise ModjyIOException(iox) Modified: trunk/jython/src/org/python/core/PyFile.java =================================================================== --- trunk/jython/src/org/python/core/PyFile.java 2010-04-12 16:47:34 UTC (rev 7021) +++ trunk/jython/src/org/python/core/PyFile.java 2010-04-12 22:03:17 UTC (rev 7022) @@ -96,7 +96,7 @@ file___init__(raw, name, mode, bufsize); } - PyFile(InputStream istream, String name, String mode, int bufsize, boolean closefd) { + public PyFile(InputStream istream, String name, String mode, int bufsize, boolean closefd) { parseMode(mode); file___init__(new StreamIO(istream, closefd), name, mode, bufsize); } Modified: trunk/jython/src/org/python/core/util/FileUtil.java =================================================================== --- trunk/jython/src/org/python/core/util/FileUtil.java 2010-04-12 16:47:34 UTC (rev 7021) +++ trunk/jython/src/org/python/core/util/FileUtil.java 2010-04-12 22:03:17 UTC (rev 7022) @@ -14,6 +14,13 @@ public class FileUtil { /** + * Creates a PyFile that reads from the given <code>InputStream</code> with mode. + */ + public static PyFile wrap(InputStream is, String mode) { + return new PyFile(is, "<Java InputStream '" + is + "' as file>", mode, -1, true); + } + + /** * Creates a PyFile that reads from the given <code>InputStream</code> with bufsize. */ public static PyFile wrap(InputStream is, int bufsize) { Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2010-04-12 16:47:34 UTC (rev 7021) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2010-04-12 22:03:17 UTC (rev 7022) @@ -95,6 +95,12 @@ getFactory().addRequestWrapper(request); } + public void setMethod(String method) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setMethod(method); + getFactory().addRequestWrapper(request); + } + public void setBodyContent(String content) { MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); request.setBodyContent(content); @@ -244,6 +250,7 @@ suite.addTestSuite(ModjyTestInterpreterLifecycle.class); suite.addTestSuite(ModjyTestWebInf.class); suite.addTestSuite(ModjyTestWSGIStreams.class); + suite.addTestSuite(ModjyTestPostData.class); suite.addTestSuite(PyServletTest.class); suite.addTestSuite(PyFilterTest.class); junit.textui.TestRunner.run(suite); Added: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestPostData.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestPostData.java (rev 0) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestPostData.java 2010-04-12 22:03:17 UTC (rev 7022) @@ -0,0 +1,47 @@ +/*### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +###*/ + +package com.xhaus.modjy; + +public class ModjyTestPostData extends ModjyTestBase { + + protected void postDataTestSetUp() throws Exception { + baseSetUp(); + setAppFile("post_data_tests.py"); + } + + public void doHeaderTest(String appName, String postData) throws Exception { + postDataTestSetUp(); + setMethod("POST"); + setAppName(appName); + createServlet(); + if (postData != null) + setBodyContent(postData); + doPost(); + } + + public void testPostDataLineEndsNotTranslated() throws Exception { + String testData = "this\r\ndata\r\ncontains\r\ncarriage\r\nreturns\r\n"; + String expectedData = "'"+testData.replace("\r", "\\r").replace("\n", "\\n")+"'"; + doHeaderTest("test_return_post_data", testData); + assertEquals("Wrong post data returned >>" + getOutput() + "<< != >>"+expectedData+"<<", expectedData, getOutput()); + } + +} Added: trunk/jython/tests/modjy/test_apps_dir/post_data_tests.py =================================================================== --- trunk/jython/tests/modjy/test_apps_dir/post_data_tests.py (rev 0) +++ trunk/jython/tests/modjy/test_apps_dir/post_data_tests.py 2010-04-12 22:03:17 UTC (rev 7022) @@ -0,0 +1,31 @@ +# -*- coding: windows-1252 -*- + +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +""" + App callables used to test post data +""" + +def test_return_post_data(environ, start_response): + post_data = environ['wsgi.input'].read() + return_value = repr(post_data) + start_response("200 OK", [('content-length', '%s' % len(return_value))]) + return [return_value] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-12 16:47:41
|
Revision: 7021 http://jython.svn.sourceforge.net/jython/?rev=7021&view=rev Author: amak Date: 2010-04-12 16:47:34 +0000 (Mon, 12 Apr 2010) Log Message: ----------- Updating build.xml to remove $py.class files before attempting to run tests. Modified Paths: -------------- trunk/jython/tests/modjy/build.xml Modified: trunk/jython/tests/modjy/build.xml =================================================================== --- trunk/jython/tests/modjy/build.xml 2010-04-11 22:21:31 UTC (rev 7020) +++ trunk/jython/tests/modjy/build.xml 2010-04-12 16:47:34 UTC (rev 7021) @@ -18,7 +18,7 @@ <property name="jython_cachedir" location="${jython_home}/cachedir" /> <property name="mockrunner_home" location="${env.MOCKRUNNER_HOME}" /> - <target name="init"> + <target name="init" depends="clean_py_class_files"> <available property="jython_home.exists" file="${jython_home}" /> <fail unless="jython_home.exists" message="jython_home, ${jython_home}, doesn't exist" /> <available property="mockrunner_home.exists" file="${mockrunner_home}" /> @@ -27,7 +27,14 @@ <mkdir dir="${build}" /> </target> - <target name="clean" description="clean up"> + <target name="clean_py_class_files"> + <!-- Clean out $py.class files in case the class file format has changed --> + <delete> + <fileset dir="." includes="**/*$py.class"/> + </delete> + </target> + + <target name="clean" depends="clean_py_class_files" description="clean up"> <!-- Delete the ${build} and ${dist} directory trees --> <delete dir="${build}" /> </target> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-11 22:21:43
|
Revision: 7020 http://jython.svn.sourceforge.net/jython/?rev=7020&view=rev Author: pjenvey Date: 2010-04-11 22:21:31 +0000 (Sun, 11 Apr 2010) Log Message: ----------- remove bean accessors for sys.settrace/profile that we don't want fixes #1456 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/core/PySystemState.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-11 19:49:26 UTC (rev 7019) +++ trunk/jython/NEWS 2010-04-11 22:21:31 UTC (rev 7020) @@ -30,6 +30,7 @@ - [ 1520 ] os.listdir doesn't return unicode when requested - [ 1483 ] optparse std module dies on non-ASCII unicode data - [ 1390 ] ihooks fails due to unimplemented methods in imp module + - [ 1456 ] sys.trace/profile attributes cause: AttributeError: write-only attr: trace in PyAMF - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2010-04-11 19:49:26 UTC (rev 7019) +++ trunk/jython/src/org/python/core/PySystemState.java 2010-04-11 22:21:31 UTC (rev 7020) @@ -34,8 +34,7 @@ */ // xxx Many have lamented, this should really be a module! // but it will require some refactoring to see this wish come true. -public class PySystemState extends PyObject -{ +public class PySystemState extends PyObject implements ClassDictInit { public static final String PYTHON_CACHEDIR = "python.cachedir"; public static final String PYTHON_CACHEDIR_SKIP = "python.cachedir.skip"; public static final String PYTHON_CONSOLE_ENCODING = "python.console.encoding"; @@ -191,6 +190,12 @@ __dict__.__setitem__("excepthook", __excepthook__); } + public static void classDictInit(PyObject dict) { + // XXX: Remove bean accessors for settrace/profile that we don't want + dict.__setitem__("trace", null); + dict.__setitem__("profile", null); + } + void reload() throws PyIgnoreMethodTag { __dict__.invoke("update", getType().fastGetDict()); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-11 19:49:33
|
Revision: 7019 http://jython.svn.sourceforge.net/jython/?rev=7019&view=rev Author: pjenvey Date: 2010-04-11 19:49:26 +0000 (Sun, 11 Apr 2010) Log Message: ----------- make this easier to find Added Paths: ----------- trunk/jython/Lib/test/test_generators_jy.py Removed Paths: ------------- trunk/jython/Lib/test/test_jy_generators.py Copied: trunk/jython/Lib/test/test_generators_jy.py (from rev 7009, trunk/jython/Lib/test/test_jy_generators.py) =================================================================== --- trunk/jython/Lib/test/test_generators_jy.py (rev 0) +++ trunk/jython/Lib/test/test_generators_jy.py 2010-04-11 19:49:26 UTC (rev 7019) @@ -0,0 +1,164 @@ +from __future__ import generators +import unittest + +#tests for deeply nested try/except/finally's + +class FinallyTests(unittest.TestCase): + def gen1(self): + try: + pass + finally: + yield 1 + def genContinue(self): + for i in range(3): + try: + continue + finally: + yield i + def genPass(self): + for i in range(3): + try: + pass + finally: + yield i + def genLocal(self): + x = 1 + try: + pass + finally: + yield x + def genConditional(self): + for i in range(3): + x = 0 + try: + if i == 2: + continue + x = 1 + finally: + for j in range(x, x + 2): + yield j + def genTryExceptAroundFinally(self): + try: + for i in range(1): + try: + for i in range(3): + try: + try: + 1//0 + finally: + yield i + except: + pass + 1//0 + except: + yield 3 + except: + pass + def genNested(self): + for i in range(2): + try: + continue + finally: + for j in range(2): + try: + pass + finally: + yield (i, j) + def genNestedReversed(self): + for i in range(2): + try: + pass + finally: + for j in range(2): + try: + continue + finally: + yield (i, j) + def genNestedDeeply(self): + for i in range(4): + try: + continue + finally: + for j in range(i): + try: + pass + finally: + for k in range(j): + try: + try: + 1//0 + finally: + yield (i, j, k) + except: + pass + def genNestedTryExcept(self): + for j in range(3): + try: + try: + 1//0 + finally: + for k in range(3): + try: + 1//0 + finally: + yield (j, k) + except: + pass + def genNestedDeeplyTryExcept(self): + for i in range(3): + try: + try: + 1//0 + finally: + for j in range(3): + try: + 1//0 + finally: + for k in range(3): + try: + 1//0 + finally: + yield (i, j, k) + except: + pass + def testFinally(self): + self.assertEquals([1], list(self.gen1())) + self.assertEquals([0, 1, 2], list(self.genContinue())) + self.assertEquals([0, 1, 2], list(self.genPass())) + self.assertEquals([1], list(self.genLocal())) + self.assertEquals( + [1, 2, 1, 2, 0, 1], + list(self.genConditional())) + self.assertEquals([0, 1, 2, 3], list(self.genTryExceptAroundFinally())) + self.assertEquals( + [(0, 0), (0, 1), (1, 0), (1, 1)], + list(self.genNested())) + self.assertEquals( + [(0, 0), (0, 1), (1, 0), (1, 1)], + list(self.genNestedReversed())) + self.assertEquals( + [(2, 1, 0), (3, 1, 0), (3, 2, 0), (3, 2, 1)], + list(self.genNestedDeeply())) + self.assertEquals( + [(0, 0), (1, 0), (2, 0)], + list(self.genNestedTryExcept())) + self.assertEquals( + [(0, 0, 0), (1, 0, 0), (2, 0, 0)], + list(self.genNestedDeeplyTryExcept())) + +class TryExceptTests(unittest.TestCase): + def genNestedExcept(self): + for j in range(3): + try: + try: + 1//0 + except ZeroDivisionError, e: + yield 1 + raise e + except ZeroDivisionError: + pass + def testExcept(self): + self.assertEquals([1, 1, 1], list(self.genNestedExcept())) + +if __name__ == "__main__": + unittest.main() Deleted: trunk/jython/Lib/test/test_jy_generators.py =================================================================== --- trunk/jython/Lib/test/test_jy_generators.py 2010-04-11 19:20:41 UTC (rev 7018) +++ trunk/jython/Lib/test/test_jy_generators.py 2010-04-11 19:49:26 UTC (rev 7019) @@ -1,164 +0,0 @@ -from __future__ import generators -import unittest - -#tests for deeply nested try/except/finally's - -class FinallyTests(unittest.TestCase): - def gen1(self): - try: - pass - finally: - yield 1 - def genContinue(self): - for i in range(3): - try: - continue - finally: - yield i - def genPass(self): - for i in range(3): - try: - pass - finally: - yield i - def genLocal(self): - x = 1 - try: - pass - finally: - yield x - def genConditional(self): - for i in range(3): - x = 0 - try: - if i == 2: - continue - x = 1 - finally: - for j in range(x, x + 2): - yield j - def genTryExceptAroundFinally(self): - try: - for i in range(1): - try: - for i in range(3): - try: - try: - 1//0 - finally: - yield i - except: - pass - 1//0 - except: - yield 3 - except: - pass - def genNested(self): - for i in range(2): - try: - continue - finally: - for j in range(2): - try: - pass - finally: - yield (i, j) - def genNestedReversed(self): - for i in range(2): - try: - pass - finally: - for j in range(2): - try: - continue - finally: - yield (i, j) - def genNestedDeeply(self): - for i in range(4): - try: - continue - finally: - for j in range(i): - try: - pass - finally: - for k in range(j): - try: - try: - 1//0 - finally: - yield (i, j, k) - except: - pass - def genNestedTryExcept(self): - for j in range(3): - try: - try: - 1//0 - finally: - for k in range(3): - try: - 1//0 - finally: - yield (j, k) - except: - pass - def genNestedDeeplyTryExcept(self): - for i in range(3): - try: - try: - 1//0 - finally: - for j in range(3): - try: - 1//0 - finally: - for k in range(3): - try: - 1//0 - finally: - yield (i, j, k) - except: - pass - def testFinally(self): - self.assertEquals([1], list(self.gen1())) - self.assertEquals([0, 1, 2], list(self.genContinue())) - self.assertEquals([0, 1, 2], list(self.genPass())) - self.assertEquals([1], list(self.genLocal())) - self.assertEquals( - [1, 2, 1, 2, 0, 1], - list(self.genConditional())) - self.assertEquals([0, 1, 2, 3], list(self.genTryExceptAroundFinally())) - self.assertEquals( - [(0, 0), (0, 1), (1, 0), (1, 1)], - list(self.genNested())) - self.assertEquals( - [(0, 0), (0, 1), (1, 0), (1, 1)], - list(self.genNestedReversed())) - self.assertEquals( - [(2, 1, 0), (3, 1, 0), (3, 2, 0), (3, 2, 1)], - list(self.genNestedDeeply())) - self.assertEquals( - [(0, 0), (1, 0), (2, 0)], - list(self.genNestedTryExcept())) - self.assertEquals( - [(0, 0, 0), (1, 0, 0), (2, 0, 0)], - list(self.genNestedDeeplyTryExcept())) - -class TryExceptTests(unittest.TestCase): - def genNestedExcept(self): - for j in range(3): - try: - try: - 1//0 - except ZeroDivisionError, e: - yield 1 - raise e - except ZeroDivisionError: - pass - def testExcept(self): - self.assertEquals([1, 1, 1], list(self.genNestedExcept())) - -if __name__ == "__main__": - unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-11 19:20:47
|
Revision: 7018 http://jython.svn.sourceforge.net/jython/?rev=7018&view=rev Author: pjenvey Date: 2010-04-11 19:20:41 +0000 (Sun, 11 Apr 2010) Log Message: ----------- add missing imp.is_builtin/frozen and load_compiled fixes #1390 Modified Paths: -------------- trunk/jython/Lib/test/test_chdir.py trunk/jython/Lib/test/test_import_jy.py trunk/jython/NEWS trunk/jython/src/org/python/modules/imp.java Modified: trunk/jython/Lib/test/test_chdir.py =================================================================== --- trunk/jython/Lib/test/test_chdir.py 2010-04-11 17:37:29 UTC (rev 7017) +++ trunk/jython/Lib/test/test_chdir.py 2010-04-11 19:20:41 UTC (rev 7018) @@ -269,7 +269,14 @@ self.assertEqual(mod.__file__, self.basename1) self.assert_(os.path.exists(self.bytecode)) + def test_imp_load_compiled(self): + __import__(self.mod_name) + self.assertTrue(os.path.exists(self.bytecode)) + basename = os.path.basename(self.bytecode) + mod = imp.load_compiled(self.mod_name, basename) + self.assertEqual(mod.__file__, basename) + class ImportPackageTestCase(BaseChdirTestCase): SYSPATH = ('',) Modified: trunk/jython/Lib/test/test_import_jy.py =================================================================== --- trunk/jython/Lib/test/test_import_jy.py 2010-04-11 17:37:29 UTC (rev 7017) +++ trunk/jython/Lib/test/test_import_jy.py 2010-04-11 19:20:41 UTC (rev 7018) @@ -2,6 +2,7 @@ Made for Jython. """ +from __future__ import with_statement import imp import os import shutil @@ -143,6 +144,24 @@ (None, '__builtin__', ('', '', 6))) self.assertEqual(imp.find_module('imp'), (None, 'imp', ('', '', 6))) + def test_imp_is_builtin(self): + self.assertTrue(all(imp.is_builtin(mod) + for mod in ['sys', '__builtin__', 'imp'])) + self.assertFalse(imp.is_builtin('os')) + + def test_load_compiled(self): + compiled = os.__file__ + if compiled.endswith('.py'): + compiled = compiled[:-3] + COMPILED_SUFFIX + + os.__doc__ = 'foo' + self.assertEqual(os, imp.load_compiled("os", compiled)) + self.assertFalse(os.__doc__ == 'foo') + with open(compiled, 'rb') as fp: + os.__doc__ = 'foo' + self.assertEqual(os, imp.load_compiled("os", compiled, fp)) + self.assertFalse(os.__doc__ == 'foo') + def test_getattr_module(self): '''Replacing __getattr__ in a class shouldn't lead to calls to __getitem__ Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-11 17:37:29 UTC (rev 7017) +++ trunk/jython/NEWS 2010-04-11 19:20:41 UTC (rev 7018) @@ -29,6 +29,7 @@ - [ 1582 ] com.ziclix.python.sql.PyConnection leaks memory - [ 1520 ] os.listdir doesn't return unicode when requested - [ 1483 ] optparse std module dies on non-ASCII unicode data + - [ 1390 ] ihooks fails due to unimplemented methods in imp module - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/modules/imp.java =================================================================== --- trunk/jython/src/org/python/modules/imp.java 2010-04-11 17:37:29 UTC (rev 7017) +++ trunk/jython/src/org/python/modules/imp.java 2010-04-11 19:20:41 UTC (rev 7018) @@ -159,6 +159,25 @@ return mod; } + public static PyObject load_compiled(String name, String pathname) { + return load_compiled(name, pathname, new PyFile(pathname, "rb", -1)); + } + + public static PyObject load_compiled(String name, String pathname, PyObject file) { + InputStream stream = (InputStream) file.__tojava__(InputStream.class); + if (stream == Py.NoConversion) { + throw Py.TypeError("must be a file-like object"); + } + + // XXX: Ideally we wouldn't care about sourceName here (see + // http://bugs.jython.org/issue1605847 msg3805) + String sourceName = pathname; + if (sourceName.endsWith("$py.class")) { + sourceName = sourceName.substring(0, sourceName.length() - 9) + ".py"; + } + return org.python.core.imp.loadFromCompiled(name.intern(), stream, sourceName, pathname); + } + public static PyObject find_module(String name) { return find_module(name, Py.None); } @@ -192,13 +211,14 @@ PySystemState sys = Py.getSystemState(); int type = data.__getitem__(2).asInt(); while(mod == Py.None) { - Object o = file.__tojava__(InputStream.class); - if (o == Py.NoConversion) { - throw Py.TypeError("must be a file-like object"); - } String compiledName; switch (type) { case PY_SOURCE: + Object o = file.__tojava__(InputStream.class); + if (o == Py.NoConversion) { + throw Py.TypeError("must be a file-like object"); + } + // XXX: This should load the accompanying byte code file instead, if it exists String resolvedFilename = sys.getPath(filename.toString()); compiledName = org.python.core.imp.makeCompiledFilename(resolvedFilename); @@ -221,15 +241,7 @@ mtime); break; case PY_COMPILED: - compiledName = filename.toString(); - // XXX: Ideally we wouldn't care about sourceName here (see - // http://bugs.jython.org/issue1605847 msg3805) - String sourceName = compiledName; - if (compiledName.endsWith("$py.class")) { - sourceName = compiledName.substring(0, compiledName.length() - 9) + ".py"; - } - mod = org.python.core.imp.loadFromCompiled( - name.intern(), (InputStream)o, sourceName, filename.toString()); + mod = load_compiled(name, filename.toString(), file); break; case PKG_DIRECTORY: PyModule m = org.python.core.imp.addModule(name); @@ -262,6 +274,14 @@ return new PyModule(name, null); } + public static boolean is_builtin(String name) { + return PySystemState.getBuiltin(name) != null; + } + + public static boolean is_frozen(String name) { + return false; + } + /** * Acquires the interpreter's import lock for the current thread. * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-11 17:37:36
|
Revision: 7017 http://jython.svn.sourceforge.net/jython/?rev=7017&view=rev Author: pjenvey Date: 2010-04-11 17:37:29 +0000 (Sun, 11 Apr 2010) Log Message: ----------- fix unicode.translate not properly dealing in code points fixes #1483 Modified Paths: -------------- trunk/jython/Lib/test/test_unicode_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyUnicode.java trunk/jython/src/org/python/modules/_codecs.java Modified: trunk/jython/Lib/test/test_unicode_jy.py =================================================================== --- trunk/jython/Lib/test/test_unicode_jy.py 2010-04-11 03:18:37 UTC (rev 7016) +++ trunk/jython/Lib/test/test_unicode_jy.py 2010-04-11 17:37:29 UTC (rev 7017) @@ -138,7 +138,17 @@ self.assertEquals('\xe2\x82\xac', encoded_euro) self.assertEquals(EURO_SIGN, encoded_euro.decode('utf-8')) + def test_translate(self): + # http://bugs.jython.org/issue1483 + self.assertEqual( + u'\u0443\u043a\u0430\u0437\u0430\u0442\u044c'.translate({}), + u'\u0443\u043a\u0430\u0437\u0430\u0442\u044c') + self.assertEqual(u'\u0443oo'.translate({0x443: 102}), u'foo') + self.assertEqual( + unichr(sys.maxunicode).translate({sys.maxunicode: 102}), + u'f') + class UnicodeFormatTestCase(unittest.TestCase): def test_unicode_mapping(self): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-11 03:18:37 UTC (rev 7016) +++ trunk/jython/NEWS 2010-04-11 17:37:29 UTC (rev 7017) @@ -28,6 +28,7 @@ - [ 1479 ] xml parser file lock - [ 1582 ] com.ziclix.python.sql.PyConnection leaks memory - [ 1520 ] os.listdir doesn't return unicode when requested + - [ 1483 ] optparse std module dies on non-ASCII unicode data - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/core/PyUnicode.java =================================================================== --- trunk/jython/src/org/python/core/PyUnicode.java 2010-04-11 03:18:37 UTC (rev 7016) +++ trunk/jython/src/org/python/core/PyUnicode.java 2010-04-11 17:37:29 UTC (rev 7017) @@ -1147,8 +1147,7 @@ @ExposedMethod(doc = BuiltinDocs.unicode_translate_doc) final PyObject unicode_translate(PyObject table) { - String trans = _codecs.translate_charmap(string, "ignore", table, true).__getitem__(0).toString(); - return new PyUnicode(trans); + return _codecs.translateCharmap(this, "ignore", table); } // these tests need to be UTF-16 aware because they are character-by-character tests, Modified: trunk/jython/src/org/python/modules/_codecs.java =================================================================== --- trunk/jython/src/org/python/modules/_codecs.java 2010-04-11 03:18:37 UTC (rev 7016) +++ trunk/jython/src/org/python/modules/_codecs.java 2010-04-11 17:37:29 UTC (rev 7017) @@ -9,6 +9,7 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.util.Iterator; import org.python.core.Py; import org.python.core.PyDictionary; @@ -183,60 +184,38 @@ } // parallel to CPython's PyUnicode_TranslateCharmap - public static PyTuple translate_charmap(String str, - String errors, - PyObject mapping, boolean ignoreUnmapped) { + public static PyObject translateCharmap(PyUnicode str, String errors, PyObject mapping) { + StringBuilder buf = new StringBuilder(str.toString().length()); - int size = str.length(); - StringBuilder v = new StringBuilder(size); - for (int i = 0; i < size; i++) { - char ch = str.charAt(i); - if (ch > 0xFF) { - i = codecs.insertReplacementAndGetResume(v, - errors, - "charmap", - str, - i, - i + 1, - "ordinal not in range(255)") - 1; - continue; - } - PyObject w = Py.newInteger(ch); - PyObject x = mapping.__finditem__(w); - if (x == null) { - if (ignoreUnmapped) { - v.append(ch); - } else { - i = codecs.insertReplacementAndGetResume(v, errors, "charmap", str, i, i + 1, "no mapping found") - 1; - } - continue; - } - /* Apply mapping */ - if (x instanceof PyInteger) { - int value = ((PyInteger) x).getValue(); + for (Iterator<Integer> iter = str.newSubsequenceIterator(); iter.hasNext();) { + int codePoint = iter.next(); + PyObject result = mapping.__finditem__(Py.newInteger(codePoint)); + if (result == null) { + // No mapping found means: use 1:1 mapping + buf.appendCodePoint(codePoint); + } else if (result == Py.None) { + // XXX: We don't support the fancier error handling CPython does here of + // capturing regions of chars removed by the None mapping to optionally + // pass to an error handler. Though we don't seem to even use this + // functionality anywhere either + ; + } else if (result instanceof PyInteger) { + int value = result.asInt(); if (value < 0 || value > PySystemState.maxunicode) { - throw Py.TypeError("character mapping must return " + "integer greater than 0 and less than sys.maxunicode"); + throw Py.TypeError(String.format("character mapping must be in range(0x%x)", + PySystemState.maxunicode + 1)); } - v.append((char) value); - } else if (x == Py.None) { - i = codecs.insertReplacementAndGetResume(v, - errors, - "charmap", - str, - i, - i + 1, - "character maps to <undefined>") - 1; - } else if (x instanceof PyUnicode) { - v.append(x.toString()); + buf.appendCodePoint(value); + } else if (result instanceof PyUnicode) { + buf.append(result.toString()); } else { - /* wrong return value */ - throw Py.TypeError("character mapping must return " + "integer, None or unicode"); + // wrong return value + throw Py.TypeError("character mapping must return integer, None or unicode"); } } - return decode_tuple(v.toString(), size); + return new PyUnicode(buf.toString()); } - - + public static PyTuple charmap_encode(String str, String errors, PyObject mapping) { //Default to Latin-1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-11 03:18:43
|
Revision: 7016 http://jython.svn.sourceforge.net/jython/?rev=7016&view=rev Author: pjenvey Date: 2010-04-11 03:18:37 +0000 (Sun, 11 Apr 2010) Log Message: ----------- have os.listdir return unicode when requested fixes #1520 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-10 20:50:46 UTC (rev 7015) +++ trunk/jython/NEWS 2010-04-11 03:18:37 UTC (rev 7016) @@ -17,7 +17,7 @@ - [ 1396 ] Assigning os module funcs as class attributes incompatible with CPython - [ 1504 ] Inheriting twice from the same Java interface causes MRO problems - [ 1511 ] PySet doesn't support Java serialization - - [ 1426 ] JSR 223 Bindings changes not taking effect and leaking between threads; unnecessary synchronization + - [ 1426 ] JSR 223 Bindings changes not taking effect and leaking between threads; unnecessary synchronization - [ 1548 ] Parentheses in CLASSPATH cause errors in jython.bat - [ 1576 ] files opened in 'a+' mode not readable - [ 1563 ] unicode() for Java objects working differently in 2.2 and 2.5 @@ -27,6 +27,7 @@ - [ 1534 ] new style object __dict__[name] ignored - [ 1479 ] xml parser file lock - [ 1582 ] com.ziclix.python.sql.PyConnection leaks memory + - [ 1520 ] os.listdir doesn't return unicode when requested - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-10 20:50:46 UTC (rev 7015) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-11 03:18:37 UTC (rev 7016) @@ -474,12 +474,12 @@ "path: path of directory to list\n\n" + "The list is in arbitrary order. It does not include the special\n" + "entries '.' and '..' even if they are present in the directory."); - public static PyList listdir(String path) { - ensurePath(path); + public static PyList listdir(PyObject pathObj) { + ensurePath(pathObj); + String path = pathObj.asString(); PyList list = new PyList(); File file = new RelativeFile(path); String[] names = file.list(); - if (names == null) { // Can't read the path for some reason. stat will throw an error if it can't // read it either @@ -493,8 +493,10 @@ } throw Py.OSError("listdir(): an unknown error occured: " + path); } + + PyString string = (PyString) pathObj; for (String name : names) { - list.append(new PyString(name)); + list.append(string.createInstance(name)); } return list; } @@ -894,6 +896,13 @@ return new RelativeFile(path).getPath(); } + private static void ensurePath(PyObject path) { + if (!(path instanceof PyString)) { + throw Py.TypeError(String.format("coercing to Unicode: need string, %s type found", + path.getType().fastGetName())); + } + } + private static void ensurePath(String path) { if (path == null) { throw Py.TypeError("coercing to Unicode: need string or buffer, NoneType found"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-10 20:50:52
|
Revision: 7015 http://jython.svn.sourceforge.net/jython/?rev=7015&view=rev Author: pjenvey Date: 2010-04-10 20:50:46 +0000 (Sat, 10 Apr 2010) Log Message: ----------- o bring in Java 6's Collections.newSetFromMap as Generic.newSetFromMap which makes our ConcurrentHashSet redundant o hold PyConnection cursors/statements in a weak Set so they can be GC'd easier. synchronize these sets too fixes #1582 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/com/ziclix/python/sql/PyConnection.java trunk/jython/src/org/python/util/Generic.java Removed Paths: ------------- trunk/jython/src/org/python/core/util/ConcurrentHashSet.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-10 20:48:35 UTC (rev 7014) +++ trunk/jython/NEWS 2010-04-10 20:50:46 UTC (rev 7015) @@ -26,6 +26,7 @@ - [ 1502 ] string-escape codec incorrect - [ 1534 ] new style object __dict__[name] ignored - [ 1479 ] xml parser file lock + - [ 1582 ] com.ziclix.python.sql.PyConnection leaks memory - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/com/ziclix/python/sql/PyConnection.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2010-04-10 20:48:35 UTC (rev 7014) +++ trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2010-04-10 20:50:46 UTC (rev 7015) @@ -11,10 +11,11 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.Collections; -import java.util.HashSet; +import java.util.WeakHashMap; import java.util.Set; import org.python.core.ClassDictInit; +import org.python.core.ContextManager; import org.python.core.Py; import org.python.core.PyBuiltinMethodSet; import org.python.core.PyException; @@ -23,12 +24,11 @@ import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyUnicode; +import org.python.core.ThreadState; +import org.python.util.Generic; import com.ziclix.python.sql.util.PyArgParser; -import org.python.core.ContextManager; -import org.python.core.ThreadState; - /** * A connection to the database. * @@ -93,9 +93,11 @@ */ public PyConnection(Connection connection) throws SQLException { this.closed = false; - this.cursors = new HashSet<PyCursor>(); + cursors = Generic.newSetFromMap(new WeakHashMap<PyCursor, Boolean>()); + cursors = Collections.synchronizedSet(cursors); this.connection = connection; - this.statements = new HashSet<PyStatement>(); + statements = Generic.newSetFromMap(new WeakHashMap<PyStatement, Boolean>()); + statements = Collections.synchronizedSet(statements); this.supportsTransactions = this.connection.getMetaData().supportsTransactions(); this.supportsMultipleResultSets = this.connection.getMetaData().supportsMultipleResultSets(); Deleted: trunk/jython/src/org/python/core/util/ConcurrentHashSet.java =================================================================== --- trunk/jython/src/org/python/core/util/ConcurrentHashSet.java 2010-04-10 20:48:35 UTC (rev 7014) +++ trunk/jython/src/org/python/core/util/ConcurrentHashSet.java 2010-04-10 20:50:46 UTC (rev 7015) @@ -1,109 +0,0 @@ -/* Copyright (c) Jython Developers */ -package org.python.core.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.util.AbstractSet; -import java.util.Collection; -import java.util.Iterator; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * A Set backed by ConcurrentHashMap. - */ -public class ConcurrentHashSet<E> extends AbstractSet<E> implements Serializable { - - /** The backing Map. */ - private final ConcurrentMap<E, Boolean> map; - - /** Backing's KeySet. */ - private transient Set<E> keySet; - - public ConcurrentHashSet() { - map = new ConcurrentHashMap<E, Boolean>(); - keySet = map.keySet(); - } - - public ConcurrentHashSet(int initialCapacity) { - map = new ConcurrentHashMap<E, Boolean>(initialCapacity); - keySet = map.keySet(); - } - - public ConcurrentHashSet(int initialCapacity, float loadFactor, int concurrencyLevel) { - map = new ConcurrentHashMap<E, Boolean>(initialCapacity, loadFactor, concurrencyLevel); - keySet = map.keySet(); - } - - @Override - public int size() { - return map.size(); - } - - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return map.containsKey(o); - } - - @Override - public Iterator<E> iterator() { - return keySet.iterator(); - } - - @Override - public Object[] toArray() { - return keySet.toArray(); - } - - @Override - public <T> T[] toArray(T[] a) { - return keySet.toArray(a); - } - - @Override - public boolean add(E e) { - return map.put(e, Boolean.TRUE) == null; - } - - @Override - public boolean remove(Object o) { - return map.remove(o) != null; - } - - @Override - public boolean removeAll(Collection<?> c) { - return keySet.removeAll(c); - } - - @Override - public boolean retainAll(Collection<?> c) { - return keySet.retainAll(c); - } - - @Override - public void clear() { - map.clear(); - } - - @Override - public boolean equals(Object o) { - return keySet.equals(o); - } - - @Override - public int hashCode() { - return keySet.hashCode(); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - keySet = map.keySet(); - } -} Modified: trunk/jython/src/org/python/util/Generic.java =================================================================== --- trunk/jython/src/org/python/util/Generic.java 2010-04-10 20:48:35 UTC (rev 7014) +++ trunk/jython/src/org/python/util/Generic.java 2010-04-10 20:50:46 UTC (rev 7015) @@ -1,16 +1,20 @@ package org.python.util; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.AbstractSet; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import org.python.core.util.ConcurrentHashSet; - /** * Static methods to make instances of collections with their generic types inferred from what * they're being assigned to. The idea is stolen from <code>Sets</code>, <code>Lists</code> and @@ -64,8 +68,8 @@ /** * Makes a Set using the generic type inferred from whatever this is being assigned to. */ - public static <T> Set<T> set() { - return new HashSet<T>(); + public static <E> Set<E> set() { + return new HashSet<E>(); } /** @@ -84,8 +88,128 @@ * Makes a Set, ensuring safe concurrent operations, using generic types inferred from * whatever this is being assigned to. */ - public static <T> Set<T> concurrentSet() { - return new ConcurrentHashSet<T>(CHM_INITIAL_CAPACITY, CHM_LOAD_FACTOR, - CHM_CONCURRENCY_LEVEL); + public static <E> Set<E> concurrentSet() { + return newSetFromMap(new ConcurrentHashMap<E, Boolean>(CHM_INITIAL_CAPACITY, + CHM_LOAD_FACTOR, + CHM_CONCURRENCY_LEVEL)); } + + /** + * Return a Set backed by the specified Map with the same ordering, concurrency and + * performance characteristics. + * + * The specified Map must be empty at the time this method is invoked. + * + * Note that this method is based on Java 6's Collections.newSetFromMap, and will be + * removed in a future version of Jython (likely 2.6) that will rely on Java 6. + * + * @param map the backing Map + * @return a Set backed by the Map + * @throws IllegalArgumentException if Map is not empty + */ + public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) { + return new SetFromMap<E>(map); + } + + /** + * A Set backed by a generic Map. + */ + private static class SetFromMap<E> extends AbstractSet<E> + implements Serializable { + + /** The backing Map. */ + private final Map<E, Boolean> map; + + /** Backing's KeySet. */ + private transient Set<E> keySet; + + public SetFromMap(Map<E, Boolean> map) { + if (!map.isEmpty()) { + throw new IllegalArgumentException("Map is non-empty"); + } + this.map = map; + keySet = map.keySet(); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return map.containsKey(o); + } + + @Override + public boolean containsAll(Collection<?> c) { + return keySet.containsAll(c); + } + + @Override + public Iterator<E> iterator() { + return keySet.iterator(); + } + + @Override + public Object[] toArray() { + return keySet.toArray(); + } + + @Override + public <T> T[] toArray(T[] a) { + return keySet.toArray(a); + } + + @Override + public boolean add(E e) { + return map.put(e, Boolean.TRUE) == null; + } + + @Override + public boolean remove(Object o) { + return map.remove(o) != null; + } + + @Override + public boolean removeAll(Collection<?> c) { + return keySet.removeAll(c); + } + + @Override + public boolean retainAll(Collection<?> c) { + return keySet.retainAll(c); + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public boolean equals(Object o) { + return o == this || keySet.equals(o); + } + + @Override + public int hashCode() { + return keySet.hashCode(); + } + + @Override + public String toString() { + return keySet.toString(); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + keySet = map.keySet(); + } + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-10 20:48:41
|
Revision: 7014 http://jython.svn.sourceforge.net/jython/?rev=7014&view=rev Author: pjenvey Date: 2010-04-10 20:48:35 +0000 (Sat, 10 Apr 2010) Log Message: ----------- just skip this for now on Windows so the buildbot is happy Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2010-04-10 19:47:19 UTC (rev 7013) +++ trunk/jython/Lib/test/test_java_integration.py 2010-04-10 20:48:35 UTC (rev 7014) @@ -420,6 +420,9 @@ class SecurityManagerTest(unittest.TestCase): def test_nonexistent_import_with_security(self): + if os._name == 'nt': + # http://bugs.jython.org/issue1371 + return script = test_support.findfile("import_nonexistent.py") home = os.path.realpath(sys.prefix) if not os.path.commonprefix((home, os.path.realpath(script))) == home: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-10 19:47:25
|
Revision: 7013 http://jython.svn.sourceforge.net/jython/?rev=7013&view=rev Author: pjenvey Date: 2010-04-10 19:47:19 +0000 (Sat, 10 Apr 2010) Log Message: ----------- force __get__ on PyBuiltinMethodSet as its Java subclasses don't always allow visibility of __get__ via reflection Modified Paths: -------------- trunk/jython/src/org/python/core/PyBuiltinMethodSet.java Modified: trunk/jython/src/org/python/core/PyBuiltinMethodSet.java =================================================================== --- trunk/jython/src/org/python/core/PyBuiltinMethodSet.java 2010-04-10 02:13:10 UTC (rev 7012) +++ trunk/jython/src/org/python/core/PyBuiltinMethodSet.java 2010-04-10 19:47:19 UTC (rev 7013) @@ -49,6 +49,11 @@ } @Override + public boolean implementsDescrGet() { + return true; + } + + @Override public String toString() { return String.format("<built-in method %s>", info.getName()); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-10 02:13:18
|
Revision: 7012 http://jython.svn.sourceforge.net/jython/?rev=7012&view=rev Author: pjenvey Date: 2010-04-10 02:13:10 +0000 (Sat, 10 Apr 2010) Log Message: ----------- close file handles fixes #1479 Modified Paths: -------------- trunk/jython/Lib/test/test_xml_etree_jy.py trunk/jython/Lib/xml/etree/ElementTree.py trunk/jython/NEWS Modified: trunk/jython/Lib/test/test_xml_etree_jy.py =================================================================== --- trunk/jython/Lib/test/test_xml_etree_jy.py 2010-04-10 02:09:19 UTC (rev 7011) +++ trunk/jython/Lib/test/test_xml_etree_jy.py 2010-04-10 02:13:10 UTC (rev 7012) @@ -750,5 +750,22 @@ Entity name: entity """ +def test_close_files(): + # http://bugs.jython.org/issue1479 + """ + >>> import os + >>> from test import test_support + >>> from xml.etree import ElementTree as ET + + >>> ET.ElementTree(ET.XML('<test/>')).write(test_support.TESTFN) + >>> os.remove(test_support.TESTFN) + + >>> fp = open(test_support.TESTFN, 'w') + >>> fp.write('<test/>') + >>> fp.close() + >>> tree = ET.parse(test_support.TESTFN) + >>> os.remove(test_support.TESTFN) + """ + if __name__ == "__main__": doctest.testmod() Modified: trunk/jython/Lib/xml/etree/ElementTree.py =================================================================== --- trunk/jython/Lib/xml/etree/ElementTree.py 2010-04-10 02:09:19 UTC (rev 7011) +++ trunk/jython/Lib/xml/etree/ElementTree.py 2010-04-10 02:13:10 UTC (rev 7012) @@ -575,17 +575,22 @@ # @defreturn Element def parse(self, source, parser=None): - if not hasattr(source, "read"): + managed_file = not hasattr(source, "read") + if managed_file: source = open(source, "rb") - if not parser: - parser = XMLTreeBuilder() - while 1: - data = source.read(32768) - if not data: - break - parser.feed(data) - self._root = parser.close() - return self._root + try: + if not parser: + parser = XMLTreeBuilder() + while 1: + data = source.read(32768) + if not data: + break + parser.feed(data) + self._root = parser.close() + return self._root + finally: + if managed_file: + source.close() ## # Creates a tree iterator for the root element. The iterator loops @@ -654,13 +659,18 @@ def write(self, file, encoding="us-ascii"): assert self._root is not None - if not hasattr(file, "write"): + managed_file = not hasattr(file, "write") + if managed_file: file = open(file, "wb") - if not encoding: - encoding = "us-ascii" - elif encoding != "utf-8" and encoding != "us-ascii": - file.write("<?xml version='1.0' encoding='%s'?>\n" % encoding) - self._write(file, self._root, encoding, {}) + try: + if not encoding: + encoding = "us-ascii" + elif encoding != "utf-8" and encoding != "us-ascii": + file.write("<?xml version='1.0' encoding='%s'?>\n" % encoding) + self._write(file, self._root, encoding, {}) + finally: + if managed_file: + file.close() def _write(self, file, node, encoding, namespaces): # write XML to file @@ -874,7 +884,8 @@ class iterparse: def __init__(self, source, events=None): - if not hasattr(source, "read"): + self._managed_file = not hasattr(source, "read") + if self._managed_file: source = open(source, "rb") self._file = source self._events = [] @@ -938,6 +949,8 @@ else: self._root = self._parser.close() self._parser = None + if self._managed_file: + self._file.close() else: self._index = self._index + 1 return item Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-10 02:09:19 UTC (rev 7011) +++ trunk/jython/NEWS 2010-04-10 02:13:10 UTC (rev 7012) @@ -25,6 +25,7 @@ - [ 1517 ] TypeError: get_referrers - [ 1502 ] string-escape codec incorrect - [ 1534 ] new style object __dict__[name] ignored + - [ 1479 ] xml parser file lock - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-10 02:09:25
|
Revision: 7011 http://jython.svn.sourceforge.net/jython/?rev=7011&view=rev Author: pjenvey Date: 2010-04-10 02:09:19 +0000 (Sat, 10 Apr 2010) Log Message: ----------- from: http://svn.python.org/projects/python/branches/release25-maint/Lib/xml/etree/ElementTree.py@50941 Added Paths: ----------- trunk/jython/Lib/xml/etree/ElementTree.py Added: trunk/jython/Lib/xml/etree/ElementTree.py =================================================================== --- trunk/jython/Lib/xml/etree/ElementTree.py (rev 0) +++ trunk/jython/Lib/xml/etree/ElementTree.py 2010-04-10 02:09:19 UTC (rev 7011) @@ -0,0 +1,1260 @@ +# +# ElementTree +# $Id: ElementTree.py 2326 2005-03-17 07:45:21Z fredrik $ +# +# light-weight XML support for Python 1.5.2 and later. +# +# history: +# 2001-10-20 fl created (from various sources) +# 2001-11-01 fl return root from parse method +# 2002-02-16 fl sort attributes in lexical order +# 2002-04-06 fl TreeBuilder refactoring, added PythonDoc markup +# 2002-05-01 fl finished TreeBuilder refactoring +# 2002-07-14 fl added basic namespace support to ElementTree.write +# 2002-07-25 fl added QName attribute support +# 2002-10-20 fl fixed encoding in write +# 2002-11-24 fl changed default encoding to ascii; fixed attribute encoding +# 2002-11-27 fl accept file objects or file names for parse/write +# 2002-12-04 fl moved XMLTreeBuilder back to this module +# 2003-01-11 fl fixed entity encoding glitch for us-ascii +# 2003-02-13 fl added XML literal factory +# 2003-02-21 fl added ProcessingInstruction/PI factory +# 2003-05-11 fl added tostring/fromstring helpers +# 2003-05-26 fl added ElementPath support +# 2003-07-05 fl added makeelement factory method +# 2003-07-28 fl added more well-known namespace prefixes +# 2003-08-15 fl fixed typo in ElementTree.findtext (Thomas Dartsch) +# 2003-09-04 fl fall back on emulator if ElementPath is not installed +# 2003-10-31 fl markup updates +# 2003-11-15 fl fixed nested namespace bug +# 2004-03-28 fl added XMLID helper +# 2004-06-02 fl added default support to findtext +# 2004-06-08 fl fixed encoding of non-ascii element/attribute names +# 2004-08-23 fl take advantage of post-2.1 expat features +# 2005-02-01 fl added iterparse implementation +# 2005-03-02 fl fixed iterparse support for pre-2.2 versions +# +# Copyright (c) 1999-2005 by Fredrik Lundh. All rights reserved. +# +# fr...@py... +# http://www.pythonware.com +# +# -------------------------------------------------------------------- +# The ElementTree toolkit is +# +# Copyright (c) 1999-2005 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# -------------------------------------------------------------------- + +# Licensed to PSF under a Contributor Agreement. +# See http://www.python.org/2.4/license for licensing details. + +__all__ = [ + # public symbols + "Comment", + "dump", + "Element", "ElementTree", + "fromstring", + "iselement", "iterparse", + "parse", + "PI", "ProcessingInstruction", + "QName", + "SubElement", + "tostring", + "TreeBuilder", + "VERSION", "XML", + "XMLParser", "XMLTreeBuilder", + ] + +## +# The <b>Element</b> type is a flexible container object, designed to +# store hierarchical data structures in memory. The type can be +# described as a cross between a list and a dictionary. +# <p> +# Each element has a number of properties associated with it: +# <ul> +# <li>a <i>tag</i>. This is a string identifying what kind of data +# this element represents (the element type, in other words).</li> +# <li>a number of <i>attributes</i>, stored in a Python dictionary.</li> +# <li>a <i>text</i> string.</li> +# <li>an optional <i>tail</i> string.</li> +# <li>a number of <i>child elements</i>, stored in a Python sequence</li> +# </ul> +# +# To create an element instance, use the {@link #Element} or {@link +# #SubElement} factory functions. +# <p> +# The {@link #ElementTree} class can be used to wrap an element +# structure, and convert it from and to XML. +## + +import string, sys, re + +class _SimpleElementPath: + # emulate pre-1.2 find/findtext/findall behaviour + def find(self, element, tag): + for elem in element: + if elem.tag == tag: + return elem + return None + def findtext(self, element, tag, default=None): + for elem in element: + if elem.tag == tag: + return elem.text or "" + return default + def findall(self, element, tag): + if tag[:3] == ".//": + return element.getiterator(tag[3:]) + result = [] + for elem in element: + if elem.tag == tag: + result.append(elem) + return result + +try: + import ElementPath +except ImportError: + # FIXME: issue warning in this case? + ElementPath = _SimpleElementPath() + +# TODO: add support for custom namespace resolvers/default namespaces +# TODO: add improved support for incremental parsing + +VERSION = "1.2.6" + +## +# Internal element class. This class defines the Element interface, +# and provides a reference implementation of this interface. +# <p> +# You should not create instances of this class directly. Use the +# appropriate factory functions instead, such as {@link #Element} +# and {@link #SubElement}. +# +# @see Element +# @see SubElement +# @see Comment +# @see ProcessingInstruction + +class _ElementInterface: + # <tag attrib>text<child/>...</tag>tail + + ## + # (Attribute) Element tag. + + tag = None + + ## + # (Attribute) Element attribute dictionary. Where possible, use + # {@link #_ElementInterface.get}, + # {@link #_ElementInterface.set}, + # {@link #_ElementInterface.keys}, and + # {@link #_ElementInterface.items} to access + # element attributes. + + attrib = None + + ## + # (Attribute) Text before first subelement. This is either a + # string or the value None, if there was no text. + + text = None + + ## + # (Attribute) Text after this element's end tag, but before the + # next sibling element's start tag. This is either a string or + # the value None, if there was no text. + + tail = None # text after end tag, if any + + def __init__(self, tag, attrib): + self.tag = tag + self.attrib = attrib + self._children = [] + + def __repr__(self): + return "<Element %s at %x>" % (self.tag, id(self)) + + ## + # Creates a new element object of the same type as this element. + # + # @param tag Element tag. + # @param attrib Element attributes, given as a dictionary. + # @return A new element instance. + + def makeelement(self, tag, attrib): + return Element(tag, attrib) + + ## + # Returns the number of subelements. + # + # @return The number of subelements. + + def __len__(self): + return len(self._children) + + ## + # Returns the given subelement. + # + # @param index What subelement to return. + # @return The given subelement. + # @exception IndexError If the given element does not exist. + + def __getitem__(self, index): + return self._children[index] + + ## + # Replaces the given subelement. + # + # @param index What subelement to replace. + # @param element The new element value. + # @exception IndexError If the given element does not exist. + # @exception AssertionError If element is not a valid object. + + def __setitem__(self, index, element): + assert iselement(element) + self._children[index] = element + + ## + # Deletes the given subelement. + # + # @param index What subelement to delete. + # @exception IndexError If the given element does not exist. + + def __delitem__(self, index): + del self._children[index] + + ## + # Returns a list containing subelements in the given range. + # + # @param start The first subelement to return. + # @param stop The first subelement that shouldn't be returned. + # @return A sequence object containing subelements. + + def __getslice__(self, start, stop): + return self._children[start:stop] + + ## + # Replaces a number of subelements with elements from a sequence. + # + # @param start The first subelement to replace. + # @param stop The first subelement that shouldn't be replaced. + # @param elements A sequence object with zero or more elements. + # @exception AssertionError If a sequence member is not a valid object. + + def __setslice__(self, start, stop, elements): + for element in elements: + assert iselement(element) + self._children[start:stop] = list(elements) + + ## + # Deletes a number of subelements. + # + # @param start The first subelement to delete. + # @param stop The first subelement to leave in there. + + def __delslice__(self, start, stop): + del self._children[start:stop] + + ## + # Adds a subelement to the end of this element. + # + # @param element The element to add. + # @exception AssertionError If a sequence member is not a valid object. + + def append(self, element): + assert iselement(element) + self._children.append(element) + + ## + # Inserts a subelement at the given position in this element. + # + # @param index Where to insert the new subelement. + # @exception AssertionError If the element is not a valid object. + + def insert(self, index, element): + assert iselement(element) + self._children.insert(index, element) + + ## + # Removes a matching subelement. Unlike the <b>find</b> methods, + # this method compares elements based on identity, not on tag + # value or contents. + # + # @param element What element to remove. + # @exception ValueError If a matching element could not be found. + # @exception AssertionError If the element is not a valid object. + + def remove(self, element): + assert iselement(element) + self._children.remove(element) + + ## + # Returns all subelements. The elements are returned in document + # order. + # + # @return A list of subelements. + # @defreturn list of Element instances + + def getchildren(self): + return self._children + + ## + # Finds the first matching subelement, by tag name or path. + # + # @param path What element to look for. + # @return The first matching element, or None if no element was found. + # @defreturn Element or None + + def find(self, path): + return ElementPath.find(self, path) + + ## + # Finds text for the first matching subelement, by tag name or path. + # + # @param path What element to look for. + # @param default What to return if the element was not found. + # @return The text content of the first matching element, or the + # default value no element was found. Note that if the element + # has is found, but has no text content, this method returns an + # empty string. + # @defreturn string + + def findtext(self, path, default=None): + return ElementPath.findtext(self, path, default) + + ## + # Finds all matching subelements, by tag name or path. + # + # @param path What element to look for. + # @return A list or iterator containing all matching elements, + # in document order. + # @defreturn list of Element instances + + def findall(self, path): + return ElementPath.findall(self, path) + + ## + # Resets an element. This function removes all subelements, clears + # all attributes, and sets the text and tail attributes to None. + + def clear(self): + self.attrib.clear() + self._children = [] + self.text = self.tail = None + + ## + # Gets an element attribute. + # + # @param key What attribute to look for. + # @param default What to return if the attribute was not found. + # @return The attribute value, or the default value, if the + # attribute was not found. + # @defreturn string or None + + def get(self, key, default=None): + return self.attrib.get(key, default) + + ## + # Sets an element attribute. + # + # @param key What attribute to set. + # @param value The attribute value. + + def set(self, key, value): + self.attrib[key] = value + + ## + # Gets a list of attribute names. The names are returned in an + # arbitrary order (just like for an ordinary Python dictionary). + # + # @return A list of element attribute names. + # @defreturn list of strings + + def keys(self): + return self.attrib.keys() + + ## + # Gets element attributes, as a sequence. The attributes are + # returned in an arbitrary order. + # + # @return A list of (name, value) tuples for all attributes. + # @defreturn list of (string, string) tuples + + def items(self): + return self.attrib.items() + + ## + # Creates a tree iterator. The iterator loops over this element + # and all subelements, in document order, and returns all elements + # with a matching tag. + # <p> + # If the tree structure is modified during iteration, the result + # is undefined. + # + # @param tag What tags to look for (default is to return all elements). + # @return A list or iterator containing all the matching elements. + # @defreturn list or iterator + + def getiterator(self, tag=None): + nodes = [] + if tag == "*": + tag = None + if tag is None or self.tag == tag: + nodes.append(self) + for node in self._children: + nodes.extend(node.getiterator(tag)) + return nodes + +# compatibility +_Element = _ElementInterface + +## +# Element factory. This function returns an object implementing the +# standard Element interface. The exact class or type of that object +# is implementation dependent, but it will always be compatible with +# the {@link #_ElementInterface} class in this module. +# <p> +# The element name, attribute names, and attribute values can be +# either 8-bit ASCII strings or Unicode strings. +# +# @param tag The element name. +# @param attrib An optional dictionary, containing element attributes. +# @param **extra Additional attributes, given as keyword arguments. +# @return An element instance. +# @defreturn Element + +def Element(tag, attrib={}, **extra): + attrib = attrib.copy() + attrib.update(extra) + return _ElementInterface(tag, attrib) + +## +# Subelement factory. This function creates an element instance, and +# appends it to an existing element. +# <p> +# The element name, attribute names, and attribute values can be +# either 8-bit ASCII strings or Unicode strings. +# +# @param parent The parent element. +# @param tag The subelement name. +# @param attrib An optional dictionary, containing element attributes. +# @param **extra Additional attributes, given as keyword arguments. +# @return An element instance. +# @defreturn Element + +def SubElement(parent, tag, attrib={}, **extra): + attrib = attrib.copy() + attrib.update(extra) + element = parent.makeelement(tag, attrib) + parent.append(element) + return element + +## +# Comment element factory. This factory function creates a special +# element that will be serialized as an XML comment. +# <p> +# The comment string can be either an 8-bit ASCII string or a Unicode +# string. +# +# @param text A string containing the comment string. +# @return An element instance, representing a comment. +# @defreturn Element + +def Comment(text=None): + element = Element(Comment) + element.text = text + return element + +## +# PI element factory. This factory function creates a special element +# that will be serialized as an XML processing instruction. +# +# @param target A string containing the PI target. +# @param text A string containing the PI contents, if any. +# @return An element instance, representing a PI. +# @defreturn Element + +def ProcessingInstruction(target, text=None): + element = Element(ProcessingInstruction) + element.text = target + if text: + element.text = element.text + " " + text + return element + +PI = ProcessingInstruction + +## +# QName wrapper. This can be used to wrap a QName attribute value, in +# order to get proper namespace handling on output. +# +# @param text A string containing the QName value, in the form {uri}local, +# or, if the tag argument is given, the URI part of a QName. +# @param tag Optional tag. If given, the first argument is interpreted as +# an URI, and this argument is interpreted as a local name. +# @return An opaque object, representing the QName. + +class QName: + def __init__(self, text_or_uri, tag=None): + if tag: + text_or_uri = "{%s}%s" % (text_or_uri, tag) + self.text = text_or_uri + def __str__(self): + return self.text + def __hash__(self): + return hash(self.text) + def __cmp__(self, other): + if isinstance(other, QName): + return cmp(self.text, other.text) + return cmp(self.text, other) + +## +# ElementTree wrapper class. This class represents an entire element +# hierarchy, and adds some extra support for serialization to and from +# standard XML. +# +# @param element Optional root element. +# @keyparam file Optional file handle or name. If given, the +# tree is initialized with the contents of this XML file. + +class ElementTree: + + def __init__(self, element=None, file=None): + assert element is None or iselement(element) + self._root = element # first node + if file: + self.parse(file) + + ## + # Gets the root element for this tree. + # + # @return An element instance. + # @defreturn Element + + def getroot(self): + return self._root + + ## + # Replaces the root element for this tree. This discards the + # current contents of the tree, and replaces it with the given + # element. Use with care. + # + # @param element An element instance. + + def _setroot(self, element): + assert iselement(element) + self._root = element + + ## + # Loads an external XML document into this element tree. + # + # @param source A file name or file object. + # @param parser An optional parser instance. If not given, the + # standard {@link XMLTreeBuilder} parser is used. + # @return The document root element. + # @defreturn Element + + def parse(self, source, parser=None): + if not hasattr(source, "read"): + source = open(source, "rb") + if not parser: + parser = XMLTreeBuilder() + while 1: + data = source.read(32768) + if not data: + break + parser.feed(data) + self._root = parser.close() + return self._root + + ## + # Creates a tree iterator for the root element. The iterator loops + # over all elements in this tree, in document order. + # + # @param tag What tags to look for (default is to return all elements) + # @return An iterator. + # @defreturn iterator + + def getiterator(self, tag=None): + assert self._root is not None + return self._root.getiterator(tag) + + ## + # Finds the first toplevel element with given tag. + # Same as getroot().find(path). + # + # @param path What element to look for. + # @return The first matching element, or None if no element was found. + # @defreturn Element or None + + def find(self, path): + assert self._root is not None + if path[:1] == "/": + path = "." + path + return self._root.find(path) + + ## + # Finds the element text for the first toplevel element with given + # tag. Same as getroot().findtext(path). + # + # @param path What toplevel element to look for. + # @param default What to return if the element was not found. + # @return The text content of the first matching element, or the + # default value no element was found. Note that if the element + # has is found, but has no text content, this method returns an + # empty string. + # @defreturn string + + def findtext(self, path, default=None): + assert self._root is not None + if path[:1] == "/": + path = "." + path + return self._root.findtext(path, default) + + ## + # Finds all toplevel elements with the given tag. + # Same as getroot().findall(path). + # + # @param path What element to look for. + # @return A list or iterator containing all matching elements, + # in document order. + # @defreturn list of Element instances + + def findall(self, path): + assert self._root is not None + if path[:1] == "/": + path = "." + path + return self._root.findall(path) + + ## + # Writes the element tree to a file, as XML. + # + # @param file A file name, or a file object opened for writing. + # @param encoding Optional output encoding (default is US-ASCII). + + def write(self, file, encoding="us-ascii"): + assert self._root is not None + if not hasattr(file, "write"): + file = open(file, "wb") + if not encoding: + encoding = "us-ascii" + elif encoding != "utf-8" and encoding != "us-ascii": + file.write("<?xml version='1.0' encoding='%s'?>\n" % encoding) + self._write(file, self._root, encoding, {}) + + def _write(self, file, node, encoding, namespaces): + # write XML to file + tag = node.tag + if tag is Comment: + file.write("<!-- %s -->" % _escape_cdata(node.text, encoding)) + elif tag is ProcessingInstruction: + file.write("<?%s?>" % _escape_cdata(node.text, encoding)) + else: + items = node.items() + xmlns_items = [] # new namespaces in this scope + try: + if isinstance(tag, QName) or tag[:1] == "{": + tag, xmlns = fixtag(tag, namespaces) + if xmlns: xmlns_items.append(xmlns) + except TypeError: + _raise_serialization_error(tag) + file.write("<" + _encode(tag, encoding)) + if items or xmlns_items: + items.sort() # lexical order + for k, v in items: + try: + if isinstance(k, QName) or k[:1] == "{": + k, xmlns = fixtag(k, namespaces) + if xmlns: xmlns_items.append(xmlns) + except TypeError: + _raise_serialization_error(k) + try: + if isinstance(v, QName): + v, xmlns = fixtag(v, namespaces) + if xmlns: xmlns_items.append(xmlns) + except TypeError: + _raise_serialization_error(v) + file.write(" %s=\"%s\"" % (_encode(k, encoding), + _escape_attrib(v, encoding))) + for k, v in xmlns_items: + file.write(" %s=\"%s\"" % (_encode(k, encoding), + _escape_attrib(v, encoding))) + if node.text or len(node): + file.write(">") + if node.text: + file.write(_escape_cdata(node.text, encoding)) + for n in node: + self._write(file, n, encoding, namespaces) + file.write("</" + _encode(tag, encoding) + ">") + else: + file.write(" />") + for k, v in xmlns_items: + del namespaces[v] + if node.tail: + file.write(_escape_cdata(node.tail, encoding)) + +# -------------------------------------------------------------------- +# helpers + +## +# Checks if an object appears to be a valid element object. +# +# @param An element instance. +# @return A true value if this is an element object. +# @defreturn flag + +def iselement(element): + # FIXME: not sure about this; might be a better idea to look + # for tag/attrib/text attributes + return isinstance(element, _ElementInterface) or hasattr(element, "tag") + +## +# Writes an element tree or element structure to sys.stdout. This +# function should be used for debugging only. +# <p> +# The exact output format is implementation dependent. In this +# version, it's written as an ordinary XML file. +# +# @param elem An element tree or an individual element. + +def dump(elem): + # debugging + if not isinstance(elem, ElementTree): + elem = ElementTree(elem) + elem.write(sys.stdout) + tail = elem.getroot().tail + if not tail or tail[-1] != "\n": + sys.stdout.write("\n") + +def _encode(s, encoding): + try: + return s.encode(encoding) + except AttributeError: + return s # 1.5.2: assume the string uses the right encoding + +if sys.version[:3] == "1.5": + _escape = re.compile(r"[&<>\"\x80-\xff]+") # 1.5.2 +else: + _escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"')) + +_escape_map = { + "&": "&", + "<": "<", + ">": ">", + '"': """, +} + +_namespace_map = { + # "well-known" namespace prefixes + "http://www.w3.org/XML/1998/namespace": "xml", + "http://www.w3.org/1999/xhtml": "html", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf", + "http://schemas.xmlsoap.org/wsdl/": "wsdl", +} + +def _raise_serialization_error(text): + raise TypeError( + "cannot serialize %r (type %s)" % (text, type(text).__name__) + ) + +def _encode_entity(text, pattern=_escape): + # map reserved and non-ascii characters to numerical entities + def escape_entities(m, map=_escape_map): + out = [] + append = out.append + for char in m.group(): + text = map.get(char) + if text is None: + text = "&#%d;" % ord(char) + append(text) + return string.join(out, "") + try: + return _encode(pattern.sub(escape_entities, text), "ascii") + except TypeError: + _raise_serialization_error(text) + +# +# the following functions assume an ascii-compatible encoding +# (or "utf-16") + +def _escape_cdata(text, encoding=None, replace=string.replace): + # escape character data + try: + if encoding: + try: + text = _encode(text, encoding) + except UnicodeError: + return _encode_entity(text) + text = replace(text, "&", "&") + text = replace(text, "<", "<") + text = replace(text, ">", ">") + return text + except (TypeError, AttributeError): + _raise_serialization_error(text) + +def _escape_attrib(text, encoding=None, replace=string.replace): + # escape attribute value + try: + if encoding: + try: + text = _encode(text, encoding) + except UnicodeError: + return _encode_entity(text) + text = replace(text, "&", "&") + text = replace(text, "'", "'") # FIXME: overkill + text = replace(text, "\"", """) + text = replace(text, "<", "<") + text = replace(text, ">", ">") + return text + except (TypeError, AttributeError): + _raise_serialization_error(text) + +def fixtag(tag, namespaces): + # given a decorated tag (of the form {uri}tag), return prefixed + # tag and namespace declaration, if any + if isinstance(tag, QName): + tag = tag.text + namespace_uri, tag = string.split(tag[1:], "}", 1) + prefix = namespaces.get(namespace_uri) + if prefix is None: + prefix = _namespace_map.get(namespace_uri) + if prefix is None: + prefix = "ns%d" % len(namespaces) + namespaces[namespace_uri] = prefix + if prefix == "xml": + xmlns = None + else: + xmlns = ("xmlns:%s" % prefix, namespace_uri) + else: + xmlns = None + return "%s:%s" % (prefix, tag), xmlns + +## +# Parses an XML document into an element tree. +# +# @param source A filename or file object containing XML data. +# @param parser An optional parser instance. If not given, the +# standard {@link XMLTreeBuilder} parser is used. +# @return An ElementTree instance + +def parse(source, parser=None): + tree = ElementTree() + tree.parse(source, parser) + return tree + +## +# Parses an XML document into an element tree incrementally, and reports +# what's going on to the user. +# +# @param source A filename or file object containing XML data. +# @param events A list of events to report back. If omitted, only "end" +# events are reported. +# @return A (event, elem) iterator. + +class iterparse: + + def __init__(self, source, events=None): + if not hasattr(source, "read"): + source = open(source, "rb") + self._file = source + self._events = [] + self._index = 0 + self.root = self._root = None + self._parser = XMLTreeBuilder() + # wire up the parser for event reporting + parser = self._parser._parser + append = self._events.append + if events is None: + events = ["end"] + for event in events: + if event == "start": + try: + parser.ordered_attributes = 1 + parser.specified_attributes = 1 + def handler(tag, attrib_in, event=event, append=append, + start=self._parser._start_list): + append((event, start(tag, attrib_in))) + parser.StartElementHandler = handler + except AttributeError: + def handler(tag, attrib_in, event=event, append=append, + start=self._parser._start): + append((event, start(tag, attrib_in))) + parser.StartElementHandler = handler + elif event == "end": + def handler(tag, event=event, append=append, + end=self._parser._end): + append((event, end(tag))) + parser.EndElementHandler = handler + elif event == "start-ns": + def handler(prefix, uri, event=event, append=append): + try: + uri = _encode(uri, "ascii") + except UnicodeError: + pass + append((event, (prefix or "", uri))) + parser.StartNamespaceDeclHandler = handler + elif event == "end-ns": + def handler(prefix, event=event, append=append): + append((event, None)) + parser.EndNamespaceDeclHandler = handler + + def next(self): + while 1: + try: + item = self._events[self._index] + except IndexError: + if self._parser is None: + self.root = self._root + try: + raise StopIteration + except NameError: + raise IndexError + # load event buffer + del self._events[:] + self._index = 0 + data = self._file.read(16384) + if data: + self._parser.feed(data) + else: + self._root = self._parser.close() + self._parser = None + else: + self._index = self._index + 1 + return item + + try: + iter + def __iter__(self): + return self + except NameError: + def __getitem__(self, index): + return self.next() + +## +# Parses an XML document from a string constant. This function can +# be used to embed "XML literals" in Python code. +# +# @param source A string containing XML data. +# @return An Element instance. +# @defreturn Element + +def XML(text): + parser = XMLTreeBuilder() + parser.feed(text) + return parser.close() + +## +# Parses an XML document from a string constant, and also returns +# a dictionary which maps from element id:s to elements. +# +# @param source A string containing XML data. +# @return A tuple containing an Element instance and a dictionary. +# @defreturn (Element, dictionary) + +def XMLID(text): + parser = XMLTreeBuilder() + parser.feed(text) + tree = parser.close() + ids = {} + for elem in tree.getiterator(): + id = elem.get("id") + if id: + ids[id] = elem + return tree, ids + +## +# Parses an XML document from a string constant. Same as {@link #XML}. +# +# @def fromstring(text) +# @param source A string containing XML data. +# @return An Element instance. +# @defreturn Element + +fromstring = XML + +## +# Generates a string representation of an XML element, including all +# subelements. +# +# @param element An Element instance. +# @return An encoded string containing the XML data. +# @defreturn string + +def tostring(element, encoding=None): + class dummy: + pass + data = [] + file = dummy() + file.write = data.append + ElementTree(element).write(file, encoding) + return string.join(data, "") + +## +# Generic element structure builder. This builder converts a sequence +# of {@link #TreeBuilder.start}, {@link #TreeBuilder.data}, and {@link +# #TreeBuilder.end} method calls to a well-formed element structure. +# <p> +# You can use this class to build an element structure using a custom XML +# parser, or a parser for some other XML-like format. +# +# @param element_factory Optional element factory. This factory +# is called to create new Element instances, as necessary. + +class TreeBuilder: + + def __init__(self, element_factory=None): + self._data = [] # data collector + self._elem = [] # element stack + self._last = None # last element + self._tail = None # true if we're after an end tag + if element_factory is None: + element_factory = _ElementInterface + self._factory = element_factory + + ## + # Flushes the parser buffers, and returns the toplevel documen + # element. + # + # @return An Element instance. + # @defreturn Element + + def close(self): + assert len(self._elem) == 0, "missing end tags" + assert self._last != None, "missing toplevel element" + return self._last + + def _flush(self): + if self._data: + if self._last is not None: + text = string.join(self._data, "") + if self._tail: + assert self._last.tail is None, "internal error (tail)" + self._last.tail = text + else: + assert self._last.text is None, "internal error (text)" + self._last.text = text + self._data = [] + + ## + # Adds text to the current element. + # + # @param data A string. This should be either an 8-bit string + # containing ASCII text, or a Unicode string. + + def data(self, data): + self._data.append(data) + + ## + # Opens a new element. + # + # @param tag The element name. + # @param attrib A dictionary containing element attributes. + # @return The opened element. + # @defreturn Element + + def start(self, tag, attrs): + self._flush() + self._last = elem = self._factory(tag, attrs) + if self._elem: + self._elem[-1].append(elem) + self._elem.append(elem) + self._tail = 0 + return elem + + ## + # Closes the current element. + # + # @param tag The element name. + # @return The closed element. + # @defreturn Element + + def end(self, tag): + self._flush() + self._last = self._elem.pop() + assert self._last.tag == tag,\ + "end tag mismatch (expected %s, got %s)" % ( + self._last.tag, tag) + self._tail = 1 + return self._last + +## +# Element structure builder for XML source data, based on the +# <b>expat</b> parser. +# +# @keyparam target Target object. If omitted, the builder uses an +# instance of the standard {@link #TreeBuilder} class. +# @keyparam html Predefine HTML entities. This flag is not supported +# by the current implementation. +# @see #ElementTree +# @see #TreeBuilder + +class XMLTreeBuilder: + + def __init__(self, html=0, target=None): + try: + from xml.parsers import expat + except ImportError: + raise ImportError( + "No module named expat; use SimpleXMLTreeBuilder instead" + ) + self._parser = parser = expat.ParserCreate(None, "}") + if target is None: + target = TreeBuilder() + self._target = target + self._names = {} # name memo cache + # callbacks + parser.DefaultHandlerExpand = self._default + parser.StartElementHandler = self._start + parser.EndElementHandler = self._end + parser.CharacterDataHandler = self._data + # let expat do the buffering, if supported + try: + self._parser.buffer_text = 1 + except AttributeError: + pass + # use new-style attribute handling, if supported + try: + self._parser.ordered_attributes = 1 + self._parser.specified_attributes = 1 + parser.StartElementHandler = self._start_list + except AttributeError: + pass + encoding = None + if not parser.returns_unicode: + encoding = "utf-8" + # target.xml(encoding, None) + self._doctype = None + self.entity = {} + + def _fixtext(self, text): + # convert text string to ascii, if possible + try: + return _encode(text, "ascii") + except UnicodeError: + return text + + def _fixname(self, key): + # expand qname, and convert name string to ascii, if possible + try: + name = self._names[key] + except KeyError: + name = key + if "}" in name: + name = "{" + name + self._names[key] = name = self._fixtext(name) + return name + + def _start(self, tag, attrib_in): + fixname = self._fixname + tag = fixname(tag) + attrib = {} + for key, value in attrib_in.items(): + attrib[fixname(key)] = self._fixtext(value) + return self._target.start(tag, attrib) + + def _start_list(self, tag, attrib_in): + fixname = self._fixname + tag = fixname(tag) + attrib = {} + if attrib_in: + for i in range(0, len(attrib_in), 2): + attrib[fixname(attrib_in[i])] = self._fixtext(attrib_in[i+1]) + return self._target.start(tag, attrib) + + def _data(self, text): + return self._target.data(self._fixtext(text)) + + def _end(self, tag): + return self._target.end(self._fixname(tag)) + + def _default(self, text): + prefix = text[:1] + if prefix == "&": + # deal with undefined entities + try: + self._target.data(self.entity[text[1:-1]]) + except KeyError: + from xml.parsers import expat + raise expat.error( + "undefined entity %s: line %d, column %d" % + (text, self._parser.ErrorLineNumber, + self._parser.ErrorColumnNumber) + ) + elif prefix == "<" and text[:9] == "<!DOCTYPE": + self._doctype = [] # inside a doctype declaration + elif self._doctype is not None: + # parse doctype contents + if prefix == ">": + self._doctype = None + return + text = string.strip(text) + if not text: + return + self._doctype.append(text) + n = len(self._doctype) + if n > 2: + type = self._doctype[1] + if type == "PUBLIC" and n == 4: + name, type, pubid, system = self._doctype + elif type == "SYSTEM" and n == 3: + name, type, system = self._doctype + pubid = None + else: + return + if pubid: + pubid = pubid[1:-1] + self.doctype(name, pubid, system[1:-1]) + self._doctype = None + + ## + # Handles a doctype declaration. + # + # @param name Doctype name. + # @param pubid Public identifier. + # @param system System identifier. + + def doctype(self, name, pubid, system): + pass + + ## + # Feeds data to the parser. + # + # @param data Encoded data. + + def feed(self, data): + self._parser.Parse(data, 0) + + ## + # Finishes feeding data to the parser. + # + # @return An element structure. + # @defreturn Element + + def close(self): + self._parser.Parse("", 1) # end of data + tree = self._target.close() + del self._target, self._parser # get rid of circular references + return tree + +# compatibility +XMLParser = XMLTreeBuilder This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-09 17:18:38
|
Revision: 7010 http://jython.svn.sourceforge.net/jython/?rev=7010&view=rev Author: amak Date: 2010-04-09 17:18:31 +0000 (Fri, 09 Apr 2010) Log Message: ----------- Disabling the AI_PASSIVE test. It cannot be written in way that is portable between systems. The only way around this is to configure expected results, on a per-system basis, outside of the test suite. Modified Paths: -------------- trunk/jython/Lib/test/test_socket.py Modified: trunk/jython/Lib/test/test_socket.py =================================================================== --- trunk/jython/Lib/test/test_socket.py 2010-04-09 05:06:08 UTC (rev 7009) +++ trunk/jython/Lib/test/test_socket.py 2010-04-09 17:18:31 UTC (rev 7010) @@ -1464,6 +1464,12 @@ self.assert_(isinstance(sockaddr[0], str)) def testAI_PASSIVE(self): + # Disabling this test for now; it's expectations are not portable. + # Expected results are too dependent on system config to be made portable between systems. + # And the only way to determine what configuration to test is to use the + # java.net.InetAddress.getAllByName() method, which is what is used to + # implement the getaddrinfo() function. Therefore, no real point in the test. + return IPV4_LOOPBACK = "127.0.0.1" local_hostname = java.net.InetAddress.getLocalHost().getHostName() local_ip_address = java.net.InetAddress.getLocalHost().getHostAddress() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |