From: <zy...@us...> - 2009-01-26 05:02:26
|
Revision: 5984 http://jython.svn.sourceforge.net/jython/?rev=5984&view=rev Author: zyasoft Date: 2009-01-26 05:02:21 +0000 (Mon, 26 Jan 2009) Log Message: ----------- Added extract tool (to be run by CPython) for creating test modules. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Added Paths: ----------- branches/pbcvm/Tools/pbcvm/ branches/pbcvm/Tools/pbcvm/extract.py Added: branches/pbcvm/Tools/pbcvm/extract.py =================================================================== --- branches/pbcvm/Tools/pbcvm/extract.py (rev 0) +++ branches/pbcvm/Tools/pbcvm/extract.py 2009-01-26 05:02:21 UTC (rev 5984) @@ -0,0 +1,106 @@ +"""Given a module, codegens a new module where all functions imported +from it (using __all__ ?) are replaced with functions tied to +PyBytecode, including references to code objs in co_consts. Other +objects are simply imported from the original object. Hopefully this +provides an opportunity to test something two different ways, which +seems nice.""" + +import inspect +import sys +from collections import defaultdict + +attrs = ["co_" + x for x in """ + argcount nlocals stacksize flags + code consts names varnames + filename name firstlineno lnotab +""".split()] # add freevars cellvars? + +# this has to be instantiated per module! so simply move into a class +_codeobjs = {} +_codeobjs_names = {} +counters = defaultdict(int) + +# XXX - need to capture with a toposort the dependencies of +# recursive code objects and emit in that order + +def extract(mod): + functionobjs = candidate_functions(mod) + for name, f in functionobjs: + #print >> sys.stderr, "Extracting", f + extract_code_obj(f) + codes = {} + for code, definition in _codeobjs.iteritems(): + codes[_codeobjs_names[code]] = definition + print "from %s import *" % mod.__name__ + print "from org.python.core import PyBytecode, PyFunction" + print + print "_codeobjs = {}" + print + for name, obj in sorted(codes.iteritems()): + print "_codeobjs[%r] = %s" % (name, obj) + print + for name, f in functionobjs: + print "%s.func_code = _codeobjs[%r]" % (name, _codeobjs_names[f.func_code]) + + print + print 'if __name__ == "__main__":' + print ' test_main()' + + +def candidate_functions(mod): + """functions and methods we will retrieve code objects""" + + functions = inspect.getmembers(mod, inspect.isfunction) + functions = [(name, f) for (name, f) in functions if not inspect.isbuiltin(f)] + + classes = inspect.getmembers(mod, inspect.isclass) + for classname, cls in classes: + #print >> sys.stderr, "Extracting from", cls + for methodname, method in inspect.getmembers(cls, inspect.ismethod): + #print >> sys.stderr, "Extracting method", method + if inspect.getmodule(method) == mod: + functions.append(("%s.%s" % (classname, methodname), method)) + return functions + +# what if we are passed a builtin? need to identify that signature +def extract_code_obj(f_or_code): + if inspect.iscode(f_or_code): + code = f_or_code + else: + code = f_or_code.func_code + extract_def(code) + +def extract_def(code): + if code in _codeobjs_names: + print >> sys.stderr, "Already seen", code + return "_codeobjs[%r]" % (_codeobjs_names[code],) + + co_name = code.co_name + print >> sys.stderr, "Processing", code + name = co_name + "." + str(counters[co_name]) + counters[co_name] += 1 + _codeobjs_names[code] = name + # need to treat co_consts specially - maybe use pickling if repr is not suitable? + values = [] + for attr in attrs: + if attr == 'co_consts': + co_consts = [] + for const in getattr(code, attr): + if inspect.iscode(const): + print >> sys.stderr, "Extracting code const " + str(const) + co_consts.append(extract_def(const)) + else: + co_consts.append(repr(const)) + values.append("["+', '.join(co_consts)+"]") + elif attr == 'co_lnotab': + values.append(repr(None)) + else: + values.append(repr(getattr(code, attr))) + _codeobjs[code] = "PyBytecode(\n" + ',\n'.join([' '* 4 + v for v in values])+")" + return "_codeobjs[%r]" % (name,) + + +if __name__ == '__main__': + modname = sys.argv[1] + mod = __import__(modname) + extract(mod) Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-26 03:36:25 UTC (rev 5983) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-26 05:02:21 UTC (rev 5984) @@ -38,7 +38,7 @@ // follows new.code's interface public PyBytecode(int argcount, int nlocals, int stacksize, int flags, String codestring, PyObject[] constants, String[] names, String varnames[], - String filename, String name, int firstlineno, PyObject[] lnotab) { + String filename, String name, int firstlineno, String lnotab) { this(argcount, nlocals, stacksize, flags, codestring, constants, names, varnames, filename, name, firstlineno, lnotab, null, null); @@ -46,7 +46,7 @@ public PyBytecode(int argcount, int nlocals, int stacksize, int flags, String codestring, PyObject[] constants, String[] names, String varnames[], - String filename, String name, int firstlineno, PyObject[] lnotab, + String filename, String name, int firstlineno, String lnotab, String[] cellvars, String[] freevars) { co_argcount = nargs = argcount; co_varnames = varnames; @@ -56,18 +56,6 @@ co_cellvars = cellvars; co_freevars = freevars; co_name = name; - -// need to look at how this is used, since it's not part of the standard new.code interface -// this.varargs = varargs; -// if (varargs) { -// co_argcount -= 1; -// co_flags |= CO_VARARGS; -// } -// this.varkwargs = varkwargs; -// if (varkwargs) { -// co_argcount -= 1; -// co_flags |= CO_VARKEYWORDS; -// } varargs = (flags & CO_VARARGS) != 0; varkwargs = (flags & CO_VARKEYWORDS) != 0; co_flags |= flags; @@ -76,8 +64,9 @@ co_consts = constants; co_names = names; co_code = codestring.toCharArray(); - co_lnotab = lnotab; + co_lnotab = null; // ignore } + private static final String[] __members__ = { "co_name", "co_argcount", "co_varnames", "co_filename", "co_firstlineno", This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-27 02:59:52
|
Revision: 5987 http://jython.svn.sourceforge.net/jython/?rev=5987&view=rev Author: zyasoft Date: 2009-01-27 01:45:48 +0000 (Tue, 27 Jan 2009) Log Message: ----------- Fixed raising of exceptions and PyStack.rot Modified Paths: -------------- branches/pbcvm/Tools/pbcvm/extract.py branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/Tools/pbcvm/extract.py =================================================================== --- branches/pbcvm/Tools/pbcvm/extract.py 2009-01-26 18:11:57 UTC (rev 5986) +++ branches/pbcvm/Tools/pbcvm/extract.py 2009-01-27 01:45:48 UTC (rev 5987) @@ -62,7 +62,6 @@ functions.append(("%s.%s" % (classname, methodname), method)) return functions -# what if we are passed a builtin? need to identify that signature def extract_code_obj(f_or_code): if inspect.iscode(f_or_code): code = f_or_code @@ -91,12 +90,10 @@ co_consts.append(extract_def(const)) else: co_consts.append(repr(const)) - values.append("["+', '.join(co_consts)+"]") - elif attr == 'co_lnotab': - values.append(repr(None)) + values.append((attr, "["+', '.join(co_consts)+"]")) else: - values.append(repr(getattr(code, attr))) - _codeobjs[code] = "PyBytecode(\n" + ',\n'.join([' '* 4 + v for v in values])+")" + values.append((attr, repr(getattr(code, attr)))) + _codeobjs[code] = "PyBytecode(\n" + ',\n'.join([' '* 4 + v + ' # ' + attr for (attr, v) in values])+")" return "_codeobjs[%r]" % (name,) Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-26 18:11:57 UTC (rev 5986) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-27 01:45:48 UTC (rev 5987) @@ -17,8 +17,8 @@ } return opname; } - private boolean debug = false; + public PyObject _debug(int maxCount) { debug = maxCount > 0; this.maxCount = maxCount; @@ -66,7 +66,6 @@ co_code = codestring.toCharArray(); co_lnotab = null; // ignore } - private static final String[] __members__ = { "co_name", "co_argcount", "co_varnames", "co_filename", "co_firstlineno", @@ -173,15 +172,6 @@ } } - private static Why do_raise(ThreadState ts, PyObject type, PyObject value, PyTraceback traceback) { - PyException pye = type == null ? ts.exception : new PyException(type, value, traceback); - if (traceback == null) { - return Why.EXCEPTION; - } else { - return Why.RERAISE; - } - } - private static String stringify_blocks(PyFrame f) { if (f.f_exits == null || f.f_blockstate[0] == 0) { return "[]"; @@ -635,22 +625,22 @@ PyTraceback tb = (PyTraceback) (stack.pop()); PyObject value = stack.pop(); PyObject type = stack.pop(); - why = do_raise(ts, type, value, tb); + PyException.doRaise(type, value, tb); break; } case 2: { PyObject value = stack.pop(); PyObject type = stack.pop(); - why = do_raise(ts, type, value, null); + PyException.doRaise(type, value, null); break; } case 1: { PyObject type = stack.pop(); - why = do_raise(ts, type, null, null); + PyException.doRaise(type, null, null); break; } case 0: - why = do_raise(ts, null, null, null); + PyException.doRaise(null, null, null); break; default: throw Py.SystemError("bad RAISE_VARARGS oparg"); @@ -798,6 +788,7 @@ case Opcode.BUILD_MAP: stack.push(new PyDictionary()); + break; case Opcode.LOAD_ATTR: stack.push(stack.pop().__getattr__(co_names[oparg])); @@ -1073,6 +1064,7 @@ while (why != Why.NOT && blocksLeft(f)) { PyTryBlock b = popBlock(f); +// System.err.println("Processing block: " + b); assert (why != Why.YIELD); if (b.b_type == Opcode.SETUP_LOOP && why == Why.CONTINUE) { pushBlock(f, b); @@ -1282,7 +1274,9 @@ void rot(int n) { int end = stack.size(); List<PyObject> lastN = stack.subList(end - n, end); - Collections.rotate(lastN, n); +// System.err.print("rot(" + n + "): " + lastN.toString() + " -> "); + Collections.rotate(lastN, n - 1); +// System.err.println("rot(" + n + "): " + lastN.toString()); } int size() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-27 03:22:18
|
Revision: 5988 http://jython.svn.sourceforge.net/jython/?rev=5988&view=rev Author: zyasoft Date: 2009-01-27 02:16:49 +0000 (Tue, 27 Jan 2009) Log Message: ----------- Fixed opcode support for LOAD/STORE/DELETE_NAME and BUILD_CLASS. Modified Paths: -------------- branches/pbcvm/Tools/pbcvm/extract.py branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/Tools/pbcvm/extract.py =================================================================== --- branches/pbcvm/Tools/pbcvm/extract.py 2009-01-27 01:45:48 UTC (rev 5987) +++ branches/pbcvm/Tools/pbcvm/extract.py 2009-01-27 02:16:49 UTC (rev 5988) @@ -93,7 +93,7 @@ values.append((attr, "["+', '.join(co_consts)+"]")) else: values.append((attr, repr(getattr(code, attr)))) - _codeobjs[code] = "PyBytecode(\n" + ',\n'.join([' '* 4 + v + ' # ' + attr for (attr, v) in values])+")" + _codeobjs[code] = "PyBytecode(\n" + '\n'.join([' '* 4 + v + ', # ' + attr for (attr, v) in values])+"\n )" return "_codeobjs[%r]" % (name,) Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-27 01:45:48 UTC (rev 5987) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-27 02:16:49 UTC (rev 5988) @@ -193,7 +193,7 @@ System.err.println(co_name + ":" + count + "," + f.f_lasti + "> opcode: " + getOpname().__getitem__(Py.newInteger(opcode)) + - (opcode > Opcode.HAVE_ARGUMENT ? ", oparg: " + oparg : "") + + (opcode >= Opcode.HAVE_ARGUMENT ? ", oparg: " + oparg : "") + ", stack: " + stack.toString() + ", blocks: " + stringify_blocks(f)); } @@ -267,7 +267,7 @@ } opcode = co_code[next_instr]; - if (opcode > Opcode.HAVE_ARGUMENT) { + if (opcode >= Opcode.HAVE_ARGUMENT) { next_instr += 2; oparg = (co_code[next_instr] << 8) + co_code[next_instr - 1]; } @@ -705,18 +705,18 @@ case Opcode.BUILD_CLASS: { PyObject methods = stack.pop(); - PyObject bases[] = (new PyTuple(stack.pop())).getArray(); + PyObject bases[] = ((PyTuple)(stack.pop())).getArray(); // new PyTuple(stack.pop())).getArray(); String name = stack.pop().toString(); stack.push(Py.makeClass(name, bases, methods)); break; } case Opcode.STORE_NAME: - f.setlocal(oparg, stack.pop()); + f.setlocal(co_names[oparg], stack.pop()); break; case Opcode.DELETE_NAME: - f.dellocal(oparg); + f.dellocal(co_names[oparg]); break; case Opcode.UNPACK_SEQUENCE: { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-01-29 03:45:03
|
Revision: 5998 http://jython.svn.sourceforge.net/jython/?rev=5998&view=rev Author: zyasoft Date: 2009-01-29 03:44:58 +0000 (Thu, 29 Jan 2009) Log Message: ----------- extract.py now creates modules where codeobjects respect their dependency relationships (via a tsort). Modified Paths: -------------- branches/pbcvm/Tools/pbcvm/extract.py branches/pbcvm/src/org/python/core/PyBytecode.java Modified: branches/pbcvm/Tools/pbcvm/extract.py =================================================================== --- branches/pbcvm/Tools/pbcvm/extract.py 2009-01-29 03:23:40 UTC (rev 5997) +++ branches/pbcvm/Tools/pbcvm/extract.py 2009-01-29 03:44:58 UTC (rev 5998) @@ -1,11 +1,11 @@ -"""Given a module, codegens a new module where all functions imported -from it (using __all__ ?) are replaced with functions tied to -PyBytecode, including references to code objs in co_consts. Other -objects are simply imported from the original object. Hopefully this -provides an opportunity to test something two different ways, which -seems nice.""" +"""Given a module, generates a new module where all functions that are + not builtin (including within classes) have their func_code pointed + to a PyBytecode constructor. This enables CPython to generate for + Jython the desired PBC. +""" import inspect +import networkx # add dependency to a setup script? probably overkill import sys from collections import defaultdict @@ -19,10 +19,9 @@ _codeobjs = {} _codeobjs_names = {} counters = defaultdict(int) +depend = networkx.DiGraph() +root = "root" -# XXX - need to capture with a toposort the dependencies of -# recursive code objects and emit in that order - def extract(mod): functionobjs = candidate_functions(mod) for name, f in functionobjs: @@ -32,12 +31,17 @@ for code, definition in _codeobjs.iteritems(): codes[_codeobjs_names[code]] = definition print "from %s import *" % mod.__name__ - print "from org.python.core import PyBytecode, PyFunction" + print "from org.python.core import PyBytecode" print print "_codeobjs = {}" print - for name, obj in sorted(codes.iteritems()): - print "_codeobjs[%r] = %s" % (name, obj) + + objs = networkx.topological_sort(depend) + for obj in objs: + if not inspect.iscode(obj): + continue + name = _codeobjs_names[obj] + print "_codeobjs[%r] = %s" % (name, _codeobjs[obj]) print for name, f in functionobjs: print "%s.func_code = _codeobjs[%r]" % (name, _codeobjs_names[f.func_code]) @@ -81,6 +85,7 @@ _codeobjs_names[code] = name # need to treat co_consts specially - maybe use pickling if repr is not suitable? values = [] + depend.add_edge(code, root) for attr in attrs: if attr == 'co_consts': co_consts = [] @@ -88,6 +93,7 @@ if inspect.iscode(const): print >> sys.stderr, "Extracting code const " + str(const) co_consts.append(extract_def(const)) + depend.add_edge(const, code) else: co_consts.append(repr(const)) values.append((attr, "["+', '.join(co_consts)+"]")) Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-29 03:23:40 UTC (rev 5997) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-01-29 03:44:58 UTC (rev 5998) @@ -27,10 +27,10 @@ // end debugging public final static int CO_MAXBLOCKS = 20; // same as in CPython - public final char[] co_code; // to avoid sign issues + public final char[] co_code; // widened to char to avoid signed byte issues public final PyObject[] co_consts; public final String[] co_names; - public final int co_stacksize; // ignored, probably shouldn't be + public final int co_stacksize; // XXX - use to convert PyStack to use PyObject[] instead of ArrayList<PyObject> public final PyObject[] co_lnotab; // ignored private final static int CALL_FLAG_VAR = 1; private final static int CALL_FLAG_KW = 2; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-02-01 08:24:15
|
Revision: 6005 http://jython.svn.sourceforge.net/jython/?rev=6005&view=rev Author: zyasoft Date: 2009-02-01 08:24:06 +0000 (Sun, 01 Feb 2009) Log Message: ----------- Added _marshal, a Java implementation of the Python module, and made current. test_marshal now passes (with minor modifications around GC and floating point accuracy on to/from string representation), except for support of code objects. That's next. Pulled IOFile (now PyIOFile) from cPickle to share its duck typing with _marshal A historical note: from what I can discern in the log, the original marshal.py was written by Guido van Rossum specifically for "JPython" in 1997, one of the few bits he apparently did. Now it survives only as a shell, to import in _marshal. Modified Paths: -------------- branches/pbcvm/Lib/marshal.py branches/pbcvm/Lib/new.py branches/pbcvm/Lib/test/test_marshal.py branches/pbcvm/src/org/python/modules/Setup.java branches/pbcvm/src/org/python/modules/cPickle.java branches/pbcvm/src/org/python/modules/struct.java Added Paths: ----------- branches/pbcvm/src/org/python/modules/PyIOFile.java branches/pbcvm/src/org/python/modules/PyIOFileFactory.java branches/pbcvm/src/org/python/modules/_marshal.java Modified: branches/pbcvm/Lib/marshal.py =================================================================== --- branches/pbcvm/Lib/marshal.py 2009-02-01 08:12:13 UTC (rev 6004) +++ branches/pbcvm/Lib/marshal.py 2009-02-01 08:24:06 UTC (rev 6005) @@ -5,332 +5,24 @@ """ -import StringIO -import string -from types import * -try: - import new -except ImportError: - new = None +import cStringIO +from _marshal import Marshaller, Unmarshaller -TYPE_NULL = '0' -TYPE_NONE = 'N' -TYPE_FALSE = 'F' -TYPE_TRUE = 'T' -TYPE_ELLIPSIS = '.' -TYPE_INT = 'i' -TYPE_INT64 = 'I' -TYPE_FLOAT = 'f' -TYPE_COMPLEX = 'x' -TYPE_LONG = 'l' -TYPE_STRING = 's' -TYPE_TUPLE = '(' -TYPE_LIST = '[' -TYPE_DICT = '{' -TYPE_CODE = 'c' -TYPE_UNKNOWN = '?' +def dump(x, f, version=2): + Marshaller(f, version).dump(x) +# XXX - added just for debugging. remove! +def load(f, debug=False): + u = Unmarshaller(f) + if debug: + u._debug() + return u.load() -class Marshaller: - - dispatch = {} - - def __init__(self, f): - self.f = f - - def dump(self, x): - self.dispatch[type(x)](self, x) - - def w_long64(self, x): - self.w_long(x) - self.w_long(x>>32) - - def w_long(self, x): - write = self.f.write - write(chr((x) & 0xff)) - write(chr((x>> 8) & 0xff)) - write(chr((x>>16) & 0xff)) - write(chr((x>>24) & 0xff)) - - def w_short(self, x): - write = self.f.write - write(chr((x) & 0xff)) - write(chr((x>> 8) & 0xff)) - - def dump_none(self, x): - self.f.write(TYPE_NONE) - dispatch[NoneType] = dump_none - - def dump_bool(self, x): - if x: - self.f.write(TYPE_TRUE) - else: - self.f.write(TYPE_FALSE) - dispatch[BooleanType] = dump_bool - - def dump_ellipsis(self, x): - self.f.write(TYPE_ELLIPSIS) - try: - dispatch[EllipsisType] = dump_ellipsis - except NameError: - pass - - def dump_int(self, x): - y = x>>31 - if y and y != -1: - self.f.write(TYPE_INT64) - self.w_long64(x) - else: - self.f.write(TYPE_INT) - self.w_long(x) - dispatch[IntType] = dump_int - - def dump_long(self, x): - self.f.write(TYPE_LONG) - sign = 1 - if x < 0: - sign = -1 - x = -x - digits = [] - while x: - digits.append(x & 0x7FFF) - x = x>>15 - self.w_long(len(digits) * sign) - for d in digits: - self.w_short(d) - dispatch[LongType] = dump_long - - def dump_float(self, x): - write = self.f.write - write(TYPE_FLOAT) - s = `x` - write(chr(len(s))) - write(s) - dispatch[FloatType] = dump_float - - def dump_complex(self, x): - write = self.f.write - write(TYPE_COMPLEX) - s = `x.real` - write(chr(len(s))) - write(s) - s = `x.imag` - write(chr(len(s))) - write(s) - try: - dispatch[ComplexType] = dump_complex - except NameError: - pass - - def dump_string(self, x): - self.f.write(TYPE_STRING) - self.w_long(len(x)) - self.f.write(x) - dispatch[StringType] = dump_string - - def dump_tuple(self, x): - self.f.write(TYPE_TUPLE) - self.w_long(len(x)) - for item in x: - self.dump(item) - dispatch[TupleType] = dump_tuple - - def dump_list(self, x): - self.f.write(TYPE_LIST) - self.w_long(len(x)) - for item in x: - self.dump(item) - dispatch[ListType] = dump_list - - def dump_dict(self, x): - self.f.write(TYPE_DICT) - for key, value in x.items(): - self.dump(key) - self.dump(value) - self.f.write(TYPE_NULL) - dispatch[DictionaryType] = dump_dict - - def dump_code(self, x): - self.f.write(TYPE_CODE) - self.w_short(x.co_argcount) - self.w_short(x.co_nlocals) - self.w_short(x.co_stacksize) - self.w_short(x.co_flags) - self.dump(x.co_code) - self.dump(x.co_consts) - self.dump(x.co_names) - self.dump(x.co_varnames) - self.dump(x.co_filename) - self.dump(x.co_name) - self.w_short(x.co_firstlineno) - self.dump(x.co_lnotab) - try: - dispatch[CodeType] = dump_code - except NameError: - pass - - -class NULL: - pass - -class Unmarshaller: - - dispatch = {} - - def __init__(self, f): - self.f = f - - def load(self): - c = self.f.read(1) - if not c: - raise EOFError - return self.dispatch[c](self) - - def r_short(self): - read = self.f.read - lo = ord(read(1)) - hi = ord(read(1)) - x = lo | (hi<<8) - if x & 0x8000: - x = x - 0x10000 - return x - - def r_long(self): - read = self.f.read - a = ord(read(1)) - b = ord(read(1)) - c = ord(read(1)) - d = ord(read(1)) - # convert unsigned d to signed to avoid d << 24 possibly - # overflowing into a long value - if d > 127: - d -= 256 - x = a | (b<<8) | (c<<16) | (d<<24) - if x & 0x80000000 and x > 0: - x = string.atoi(x - 0x100000000L) - return x - - def r_long64(self): - a = self.r_long() - b = self.r_long() - return a | (b<<32) - - def load_null(self): - return NULL - dispatch[TYPE_NULL] = load_null - - def load_none(self): - return None - dispatch[TYPE_NONE] = load_none - - def load_False(self): - return False - dispatch[TYPE_FALSE] = load_False - - def load_True(self): - return True - dispatch[TYPE_TRUE] = load_True - - def load_ellipsis(self): - return EllipsisType - dispatch[TYPE_ELLIPSIS] = load_ellipsis - - def load_int(self): - return self.r_long() - dispatch[TYPE_INT] = load_int - - def load_int64(self): - return self.r_long64() - dispatch[TYPE_INT64] = load_int64 - - def load_long(self): - size = self.r_long() - sign = 1 - if size < 0: - sign = -1 - size = -size - x = 0L - for i in range(size): - d = self.r_short() - x = x | (d<<(i*15L)) - return x * sign - dispatch[TYPE_LONG] = load_long - - def load_float(self): - n = ord(self.f.read(1)) - s = self.f.read(n) - return string.atof(s) - dispatch[TYPE_FLOAT] = load_float - - def load_complex(self): - n = ord(self.f.read(1)) - s = self.f.read(n) - real = float(s) - n = ord(self.f.read(1)) - s = self.f.read(n) - imag = float(s) - return complex(real, imag) - dispatch[TYPE_COMPLEX] = load_complex - - def load_string(self): - n = self.r_long() - return self.f.read(n) - dispatch[TYPE_STRING] = load_string - - def load_tuple(self): - return tuple(self.load_list()) - dispatch[TYPE_TUPLE] = load_tuple - - def load_list(self): - n = self.r_long() - list = [] - for i in range(n): - list.append(self.load()) - return list - dispatch[TYPE_LIST] = load_list - - def load_dict(self): - d = {} - while 1: - key = self.load() - if key is NULL: - break - value = self.load() - d[key] = value - return d - dispatch[TYPE_DICT] = load_dict - - def load_code(self): - argcount = self.r_short() - nlocals = self.r_short() - stacksize = self.r_short() - flags = self.r_short() - code = self.load() - consts = self.load() - names = self.load() - varnames = self.load() - filename = self.load() - name = self.load() - firstlineno = self.r_short() - lnotab = self.load() - if not new: - raise RuntimeError, "can't unmarshal code objects; no 'new' module" - return new.code(argcount, nlocals, stacksize, flags, code, consts, - names, varnames, filename, name, firstlineno, lnotab) - dispatch[TYPE_CODE] = load_code - - -def dump(x, f): - Marshaller(f).dump(x) - -def load(f): - return Unmarshaller(f).load() - -def dumps(x): - f = StringIO.StringIO() - dump(x, f) +def dumps(x, version=2): + f = cStringIO.StringIO() + dump(x, f, version) return f.getvalue() def loads(s): - f = StringIO.StringIO(s) + f = cStringIO.StringIO(s) return load(f) Modified: branches/pbcvm/Lib/new.py =================================================================== --- branches/pbcvm/Lib/new.py 2009-02-01 08:12:13 UTC (rev 6004) +++ branches/pbcvm/Lib/new.py 2009-02-01 08:24:06 UTC (rev 6005) @@ -20,3 +20,5 @@ # from types import CodeType as code #except ImportError: # pass + +from org.python.core import PyBytecode as code Modified: branches/pbcvm/Lib/test/test_marshal.py =================================================================== --- branches/pbcvm/Lib/test/test_marshal.py 2009-02-01 08:12:13 UTC (rev 6004) +++ branches/pbcvm/Lib/test/test_marshal.py 2009-02-01 08:24:06 UTC (rev 6005) @@ -1,12 +1,25 @@ #!/usr/bin/env python # -*- coding: iso-8859-1 -*- +from __future__ import with_statement from test import test_support import marshal import sys import unittest import os +# the original had incorrect semantics for non-refcounting GCs: +# marshal.dump(expected, file(test_support.TESTFN, "wb")) +# got = marshal.load(file(test_support.TESTFN, "rb")) + +def roundtrip(item): + with open(test_support.TESTFN, "wb") as test_file: + marshal.dump(item, test_file) + with open(test_support.TESTFN, "rb") as test_file: + got = marshal.load(file(test_support.TESTFN, "rb")) #, debug=True) + return got + + class IntTestCase(unittest.TestCase): def test_ints(self): # Test the full range of Python ints. @@ -16,9 +29,7 @@ s = marshal.dumps(expected) got = marshal.loads(s) self.assertEqual(expected, got) - marshal.dump(expected, file(test_support.TESTFN, "wb")) - got = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(expected, got) + self.assertEqual(expected, roundtrip(expected)) n = n >> 1 os.unlink(test_support.TESTFN) @@ -51,8 +62,7 @@ new = marshal.loads(marshal.dumps(b)) self.assertEqual(b, new) self.assertEqual(type(b), type(new)) - marshal.dump(b, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) + new = roundtrip(b) self.assertEqual(b, new) self.assertEqual(type(b), type(new)) @@ -67,8 +77,7 @@ s = marshal.dumps(f) got = marshal.loads(s) self.assertEqual(f, got) - marshal.dump(f, file(test_support.TESTFN, "wb")) - got = marshal.load(file(test_support.TESTFN, "rb")) + got = roundtrip(f) self.assertEqual(f, got) n /= 123.4567 @@ -92,15 +101,18 @@ s = marshal.dumps(f, 1) got = marshal.loads(s) - self.assertEqual(f, got) + if test_support.is_jython: + self.assertAlmostEqual(f, got) + else: + self.assertEqual(f, got) - marshal.dump(f, file(test_support.TESTFN, "wb")) - got = marshal.load(file(test_support.TESTFN, "rb")) + got = roundtrip(f) self.assertEqual(f, got) - marshal.dump(f, file(test_support.TESTFN, "wb"), 1) - got = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(f, got) + # XXX - not certain what this extra arg to dump is! + #marshal.dump(f, file(test_support.TESTFN, "wb"), 1) + #got = marshal.load(file(test_support.TESTFN, "rb")) + #self.assertEqual(f, got) n *= 123.4567 os.unlink(test_support.TESTFN) @@ -110,8 +122,7 @@ new = marshal.loads(marshal.dumps(s)) self.assertEqual(s, new) self.assertEqual(type(s), type(new)) - marshal.dump(s, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) + new = roundtrip(s) self.assertEqual(s, new) self.assertEqual(type(s), type(new)) os.unlink(test_support.TESTFN) @@ -121,21 +132,20 @@ new = marshal.loads(marshal.dumps(s)) self.assertEqual(s, new) self.assertEqual(type(s), type(new)) - marshal.dump(s, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) + new = roundtrip(s) self.assertEqual(s, new) self.assertEqual(type(s), type(new)) os.unlink(test_support.TESTFN) - def test_buffer(self): - for s in ["", "Andr\xE8 Previn", "abc", " "*10000]: - b = buffer(s) - new = marshal.loads(marshal.dumps(b)) - self.assertEqual(s, new) - marshal.dump(b, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) - self.assertEqual(s, new) - os.unlink(test_support.TESTFN) + if not test_support.is_jython: + def test_buffer(self): + for s in ["", "Andr\xE8 Previn", "abc", " "*10000]: + b = buffer(s) + new = marshal.loads(marshal.dumps(b)) + self.assertEqual(s, new) + new = roundtrip(b) + self.assertEqual(s, new) + os.unlink(test_support.TESTFN) class ExceptionTestCase(unittest.TestCase): def test_exceptions(self): @@ -143,10 +153,11 @@ self.assertEqual(StopIteration, new) class CodeTestCase(unittest.TestCase): - def test_code(self): - co = ExceptionTestCase.test_exceptions.func_code - new = marshal.loads(marshal.dumps(co)) - self.assertEqual(co, new) + if not test_support.is_jython: # XXX - need to use the PBC compilation backend, which doesn't exist yet + def test_code(self): + co = ExceptionTestCase.test_exceptions.func_code + new = marshal.loads(marshal.dumps(co)) + self.assertEqual(co, new) class ContainerTestCase(unittest.TestCase): d = {'astring': 'fo...@ba...z.spam', @@ -161,8 +172,7 @@ def test_dict(self): new = marshal.loads(marshal.dumps(self.d)) self.assertEqual(self.d, new) - marshal.dump(self.d, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) + new = roundtrip(self.d) self.assertEqual(self.d, new) os.unlink(test_support.TESTFN) @@ -170,8 +180,7 @@ lst = self.d.items() new = marshal.loads(marshal.dumps(lst)) self.assertEqual(lst, new) - marshal.dump(lst, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) + new = roundtrip(lst) self.assertEqual(lst, new) os.unlink(test_support.TESTFN) @@ -179,8 +188,7 @@ t = tuple(self.d.keys()) new = marshal.loads(marshal.dumps(t)) self.assertEqual(t, new) - marshal.dump(t, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) + new = roundtrip(t) self.assertEqual(t, new) os.unlink(test_support.TESTFN) @@ -191,8 +199,7 @@ self.assertEqual(t, new) self.assert_(isinstance(new, constructor)) self.assertNotEqual(id(t), id(new)) - marshal.dump(t, file(test_support.TESTFN, "wb")) - new = marshal.load(file(test_support.TESTFN, "rb")) + new = roundtrip(t) self.assertEqual(t, new) os.unlink(test_support.TESTFN) Added: branches/pbcvm/src/org/python/modules/PyIOFile.java =================================================================== --- branches/pbcvm/src/org/python/modules/PyIOFile.java (rev 0) +++ branches/pbcvm/src/org/python/modules/PyIOFile.java 2009-02-01 08:24:06 UTC (rev 6005) @@ -0,0 +1,24 @@ + + +package org.python.modules; + +/** +PyIOFiles encapsulates and optimise access to the different file +representation. Used by cPickle and marshall. + */ + +public interface PyIOFile { + + public abstract void write(String str); + // Usefull optimization since most data written are chars. + + public abstract void write(char str); + + public abstract void flush(); + + public abstract String read(int len); + // Usefull optimization since all readlines removes the + // trainling newline. + + public abstract String readlineNoNl(); +} \ No newline at end of file Added: branches/pbcvm/src/org/python/modules/PyIOFileFactory.java =================================================================== --- branches/pbcvm/src/org/python/modules/PyIOFileFactory.java (rev 0) +++ branches/pbcvm/src/org/python/modules/PyIOFileFactory.java 2009-02-01 08:24:06 UTC (rev 6005) @@ -0,0 +1,141 @@ +package org.python.modules; + +import org.python.core.Py; +import org.python.core.PyFile; +import org.python.core.PyInteger; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PyType; +import org.python.core.__builtin__; + +// XXX - add support for StringIO, not just cStringIO + +public class PyIOFileFactory { + + private PyIOFileFactory() { + } + + public static PyIOFile createIOFile(PyObject file) { + Object f = file.__tojava__(cStringIO.StringIO.class); + if (f != Py.NoConversion) { + return new cStringIOFile(file); + } else if (__builtin__.isinstance(file, FileType)) { + return new FileIOFile(file); + } else { + return new ObjectIOFile(file); + } + } + + private static PyType FileType = PyType.fromClass(PyFile.class); + + // Use a cStringIO as a file. + static class cStringIOFile implements PyIOFile { + + cStringIO.StringIO file; + + cStringIOFile(PyObject file) { + this.file = (cStringIO.StringIO) file.__tojava__(Object.class); + } + + public void write(String str) { + file.write(str); + } + + public void write(char ch) { + file.writeChar(ch); + } + + public void flush() { + } + + public String read(int len) { + return file.read(len).asString(); + } + + public String readlineNoNl() { + return file.readlineNoNl().asString(); + } + } + + + // Use a PyFile as a file. + static class FileIOFile implements PyIOFile { + + PyFile file; + + FileIOFile(PyObject file) { + this.file = (PyFile) file.__tojava__(PyFile.class); + if (this.file.getClosed()) { + throw Py.ValueError("I/O operation on closed file"); + } + } + + public void write(String str) { + file.write(str); + } + + public void write(char ch) { + file.write(cStringIO.getString(ch)); + } + + public void flush() { + } + + public String read(int len) { + return file.read(len).toString(); + } + + public String readlineNoNl() { + String line = file.readline().toString(); + return line.substring(0, line.length() - 1); + } + } + + + // Use any python object as a file. + static class ObjectIOFile implements PyIOFile { + + char[] charr = new char[1]; + StringBuilder buff = new StringBuilder(); + PyObject write; + PyObject read; + PyObject readline; + final int BUF_SIZE = 256; + + ObjectIOFile(PyObject file) { +// this.file = file; + write = file.__findattr__("write"); + read = file.__findattr__("read"); + readline = file.__findattr__("readline"); + } + + public void write(String str) { + buff.append(str); + if (buff.length() > BUF_SIZE) { + flush(); + } + } + + public void write(char ch) { + buff.append(ch); + if (buff.length() > BUF_SIZE) { + flush(); + } + } + + public void flush() { + write.__call__(new PyString(buff.toString())); + buff.setLength(0); + } + + public String read(int len) { + return read.__call__(new PyInteger(len)).toString(); + } + + public String readlineNoNl() { + String line = readline.__call__().toString(); + return line.substring(0, line.length() - 1); + } + } +} + Modified: branches/pbcvm/src/org/python/modules/Setup.java =================================================================== --- branches/pbcvm/src/org/python/modules/Setup.java 2009-02-01 08:12:13 UTC (rev 6004) +++ branches/pbcvm/src/org/python/modules/Setup.java 2009-02-01 08:24:06 UTC (rev 6005) @@ -55,6 +55,7 @@ "_functools:org.python.modules._functools._functools", "_csv:org.python.modules._csv._csv", "_systemrestart", - "_ast:org.python.antlr.ast.AstModule" + "_ast:org.python.antlr.ast.AstModule", + "_marshal" }; } Added: branches/pbcvm/src/org/python/modules/_marshal.java =================================================================== --- branches/pbcvm/src/org/python/modules/_marshal.java (rev 0) +++ branches/pbcvm/src/org/python/modules/_marshal.java 2009-02-01 08:24:06 UTC (rev 6005) @@ -0,0 +1,528 @@ +package org.python.modules; + +import java.math.BigInteger; +import org.python.core.BaseSet; +import org.python.core.ClassDictInit; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.Py; +import org.python.core.PyBytecode; +import org.python.core.PyComplex; +import org.python.core.PyDictionary; +import org.python.core.PyFloat; +import org.python.core.PyFrozenSet; +import org.python.core.PyInteger; +import org.python.core.PyList; +import org.python.core.PyLong; +import org.python.core.PySet; +import org.python.core.PyTuple; +import org.python.core.PyUnicode; + +public class _marshal implements ClassDictInit { + + public static void classDictInit(PyObject dict) { + dict.__setitem__("__name__", Py.newString("_marshal")); + } + private final static char TYPE_NULL = '0'; + private final static char TYPE_NONE = 'N'; + private final static char TYPE_FALSE = 'F'; + private final static char TYPE_TRUE = 'T'; + private final static char TYPE_STOPITER = 'S'; + private final static char TYPE_ELLIPSIS = '.'; + private final static char TYPE_INT = 'i'; + private final static char TYPE_INT64 = 'I'; + private final static char TYPE_FLOAT = 'f'; + private final static char TYPE_BINARY_FLOAT = 'g'; + private final static char TYPE_COMPLEX = 'x'; + private final static char TYPE_BINARY_COMPLEX = 'y'; + private final static char TYPE_LONG = 'l'; + private final static char TYPE_STRING = 's'; + private final static char TYPE_INTERNED = 't'; + private final static char TYPE_STRINGREF = 'R'; + private final static char TYPE_TUPLE = '('; + private final static char TYPE_LIST = '['; + private final static char TYPE_DICT = '{'; + private final static char TYPE_CODE = 'c'; + private final static char TYPE_UNICODE = 'u'; + private final static char TYPE_UNKNOWN = '?'; + private final static char TYPE_SET = '<'; + private final static char TYPE_FROZENSET = '>'; + private final static int MAX_MARSHAL_STACK_DEPTH = 2000; + private final static int CURRENT_VERSION = 2; + + public static class Marshaller extends PyObject { + + private final PyIOFile file; + private final int version; + + public Marshaller(PyObject file) { + this(file, CURRENT_VERSION); + } + + public Marshaller(PyObject file, int version) { + this.file = PyIOFileFactory.createIOFile(file); + this.version = version; + } + private boolean debug = false; + + public void _debug() { + debug = true; + } + + public void dump(PyObject obj) { + write_object(obj, 0); + } + + private void write_byte(char c) { + if (debug) { + System.err.print("[" + (int) c + "]"); + } + file.write(c); + } + + private void write_string(String s) { + file.write(s); + } + + private void write_strings(String[] some_strings, int depth) { + PyObject items[] = new PyObject[some_strings.length]; + for (int i = 0; i < some_strings.length; i++) { + items[i] = Py.newString(some_strings[i]); + } + write_object(new PyTuple(items), depth + 1); + } + + private void write_short(short x) { + write_byte((char) (x & 0xff)); + write_byte((char) ((x >> 8) & 0xff)); + } + + private void write_int(int x) { + write_byte((char) (x & 0xff)); + write_byte((char) ((x >> 8) & 0xff)); + write_byte((char) ((x >> 16) & 0xff)); + write_byte((char) ((x >> 24) & 0xff)); + } + + private void write_long64(long x) { + write_int((int) (x & 0xff)); + write_int((int) ((x >> 32) & 0xff)); + } + + // writes output in 15 bit "digits" + private void write_long(BigInteger x) { + int sign = x.signum(); + if (sign < 0) { + x = x.negate(); + } + int num_bits = x.bitLength(); + int num_digits = num_bits / 15 + (num_bits % 15 == 0 ? 0 : 1); + write_int(sign < 0 ? -num_digits : num_digits); + BigInteger mask = BigInteger.valueOf(0x7FFF); + for (int i = 0; i < num_digits; i++) { + write_short(x.and(mask).shortValue()); + x = x.shiftRight(15); + } + } + + private void write_float(PyFloat f) { + write_string(f.__repr__().toString()); + } + + // XXX - cache this struct object + // XXX - also fix reversed struct stuff! + private void write_binary_float(PyFloat f) { + write_string(struct.pack(new PyObject[]{Py.newString("d"), f}).toString()); + } + + private void write_object(PyObject v, int depth) { + if (depth >= MAX_MARSHAL_STACK_DEPTH) { + throw Py.ValueError("Maximum marshal stack depth"); // XXX - fix this exception + } else if (v == null) { + write_byte(TYPE_NULL); + } else if (v == Py.None) { + write_byte(TYPE_NONE); + } else if (v == Py.StopIteration) { + write_byte(TYPE_STOPITER); + } else if (v == Py.Ellipsis) { + write_byte(TYPE_ELLIPSIS); + } else if (v == Py.False) { + write_byte(TYPE_FALSE); + } else if (v == Py.True) { + write_byte(TYPE_TRUE); + } else if (v instanceof PyInteger) { + write_byte(TYPE_INT); + write_int(((PyInteger) v).asInt()); + } else if (v instanceof PyLong) { + write_byte(TYPE_LONG); + write_long(((PyLong) v).getValue()); + } else if (v instanceof PyFloat) { + if (version == CURRENT_VERSION) { + write_byte(TYPE_BINARY_FLOAT); + write_binary_float((PyFloat) v); + } else { + write_byte(TYPE_FLOAT); + write_float((PyFloat) v); + } + } else if (v instanceof PyComplex) { + PyComplex x = (PyComplex) v; + if (version == CURRENT_VERSION) { + write_byte(TYPE_BINARY_COMPLEX); + write_binary_float(x.getReal()); + write_binary_float(x.getImag()); + } else { + write_byte(TYPE_COMPLEX); + write_float(x.getReal()); + write_float(x.getImag()); + } + } else if (v instanceof PyUnicode) { + write_byte(TYPE_UNICODE); + String buffer = ((PyUnicode) v).encode("utf-8").toString(); + write_int(buffer.length()); + write_string(buffer); + } else if (v instanceof PyString) { + // ignore interning + write_byte(TYPE_STRING); + write_int(v.__len__()); + write_string(v.toString()); + } else if (v instanceof PyTuple) { + write_byte(TYPE_TUPLE); + PyTuple t = (PyTuple) v; + int n = t.__len__(); + write_int(n); + for (int i = 0; i < n; i++) { + write_object(t.__getitem__(i), depth + 1); + } + } else if (v instanceof PyList) { + write_byte(TYPE_LIST); + PyList list = (PyList) v; + int n = list.__len__(); + write_int(n); + for (int i = 0; i < n; i++) { + write_object(list.__getitem__(i), depth + 1); + } + } else if (v instanceof PyDictionary) { + write_byte(TYPE_DICT); + PyDictionary dict = (PyDictionary) v; + for (PyObject item : dict.iteritems().asIterable()) { + PyTuple pair = (PyTuple) item; + write_object(pair.__getitem__(0), depth + 1); + write_object(pair.__getitem__(1), depth + 1); + } + write_object(null, depth + 1); + } else if (v instanceof BaseSet) { + if (v instanceof PySet) { + write_byte(TYPE_SET); + } else { + write_byte(TYPE_FROZENSET); + } + int n = v.__len__(); + write_int(n); + BaseSet set = (BaseSet) v; + for (PyObject item : set.asIterable()) { + write_object(item, depth + 1); + } + } else if (v instanceof PyBytecode) { + PyBytecode code = (PyBytecode) v; + write_byte(TYPE_CODE); + write_int(code.co_argcount); + write_int(code.co_nlocals); + write_int(code.co_stacksize); + write_int(code.co_flags); + write_object(Py.newString(new String(code.co_code)), depth + 1); + write_object(new PyTuple(code.co_consts), depth + 1); + write_strings(code.co_names, depth + 1); + write_strings(code.co_varnames, depth + 1); + write_strings(code.co_freevars, depth + 1); + write_strings(code.co_cellvars, depth + 1); + write_object(Py.newString(code.co_name), depth + 1); + write_int(code.co_firstlineno); + write_object(new PyTuple(code.co_lnotab), depth + 1); + } else { + write_byte(TYPE_UNKNOWN); + } + + depth--; + + } + } + + public static class Unmarshaller extends PyObject { + + private final PyIOFile file; + private final PyList strings = new PyList(); + private final int version; + int depth = 0; + + public Unmarshaller(PyObject file) { + this(file, CURRENT_VERSION); + } + + public Unmarshaller(PyObject file, int version) { + this.file = PyIOFileFactory.createIOFile(file); + this.version = version; + } + private boolean debug = false; + + public void _debug() { + debug = true; + } + + public PyObject load() { + try { + PyObject obj = read_object(0); + if (obj == null) { + throw Py.TypeError("NULL object in marshal data"); + } + return obj; + } catch (StringIndexOutOfBoundsException e) { + // convert from our PyIOFile abstraction to what marshal in CPython returns + // (although it's really just looking for no bombing) + throw Py.EOFError("EOF read where object expected"); + } + } + + private int read_byte() { + int b = file.read(1).charAt(0); + if (debug) { + System.err.print("[" + b + "]"); + } + return b; + } + + private String read_string(int n) { + return file.read(n); + } + + private int read_short() { + int x = read_byte(); + x |= read_byte() << 8; + return x; + } + + private int read_int() { // cpython calls this r_long + int x = read_byte(); + x |= read_byte() << 8; + x |= read_byte() << 16; + x |= read_byte() << 24; + return x; + } + + private long read_long64() { // cpython calls this r_long64 + long lo4 = read_int(); + long hi4 = read_int(); + long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL); + return x; + } + + private BigInteger read_long() { + int size = read_int(); + int sign = 1; + if (size < 0) { + sign = -1; + size = -size; + } + BigInteger result = BigInteger.ZERO; + for (int i = 0; i < size; i++) { + String digits = String.valueOf(read_short()); + result = result.or(new BigInteger(digits).shiftLeft(i * 15)); + } + if (sign < 0) { + result = result.negate(); + } + return result; + } + + private double read_float() { + int size = read_byte(); + return Py.newString(read_string(size)).atof(); + } + + private double read_binary_float() { + String buffer = read_string(8); + PyFloat num = (PyFloat) ((struct.unpack("d", buffer)).__getitem__(0)); + return num.asDouble(); + } + + private PyObject read_object_notnull(int depth) { + PyObject v = read_object(depth); + if (v == null) { + throw Py.ValueError("bad marshal data"); + } + return v; + } + + private String[] read_strings(int depth) { + PyTuple t = (PyTuple) read_object_notnull(depth); + String some_strings[] = new String[t.__len__()]; + int i = 0; + for (PyObject item : t.asIterable()) { + some_strings[i++] = item.toString(); + } + return some_strings; + } + + private PyObject read_object(int depth) { + if (depth >= MAX_MARSHAL_STACK_DEPTH) { + throw Py.ValueError("Maximum marshal stack depth"); // XXX - fix this exception + } + int type = read_byte(); + switch (type) { + + case TYPE_NULL: + return null; + + case TYPE_NONE: + return Py.None; + + case TYPE_STOPITER: + return Py.StopIteration; + + case TYPE_ELLIPSIS: + return Py.Ellipsis; + + case TYPE_FALSE: + return Py.False; + + case TYPE_TRUE: + return Py.True; + + case TYPE_INT: + return Py.newInteger(read_int()); + + case TYPE_INT64: + return Py.newInteger(read_long64()); + + case TYPE_LONG: { + return Py.newLong(read_long()); + } + + case TYPE_FLOAT: + return Py.newFloat(read_float()); + + case TYPE_BINARY_FLOAT: + return Py.newFloat(read_binary_float()); + + case TYPE_COMPLEX: { + double real = read_float(); + double imag = read_float(); + return new PyComplex(real, imag); + } + + case TYPE_BINARY_COMPLEX: { + double real = read_binary_float(); + double imag = read_binary_float(); + return new PyComplex(real, imag); + } + + case TYPE_INTERNED: + case TYPE_STRING: { + int size = read_int(); + String s = read_string(size); + if (type == TYPE_INTERNED) { + s.intern(); // do we really honor like this? + PyString pys = PyString.fromInterned(s); + strings.append(pys); + return pys; + } else { + return Py.newString(s); + } + } + + case TYPE_STRINGREF: { + int i = read_int(); + return strings.__getitem__(i); + } + + case TYPE_UNICODE: { + int n = read_int(); + PyString buffer = Py.newString(read_string(n)); + return buffer.decode("utf-8"); + } + + case TYPE_TUPLE: { + int n = read_int(); + if (n < 0) { + throw Py.ValueError("bad marshal data"); + } + PyObject items[] = new PyObject[n]; + for (int i = 0; i < n; i++) { + items[i] = read_object_notnull(depth + 1); + } + return new PyTuple(items); + } + + case TYPE_LIST: { + int n = read_int(); + if (n < 0) { + throw Py.ValueError("bad marshal data"); + } + PyObject items[] = new PyObject[n]; + for (int i = 0; i < n; i++) { + items[i] = read_object_notnull(depth + 1); + } + return new PyList(items); + } + + case TYPE_DICT: { + PyDictionary d = new PyDictionary(); + while (true) { + PyObject key = read_object(depth + 1); + if (key == null) { + break; + } + PyObject value = read_object(depth + 1); + if (value != null) { + d.__setitem__(key, value); + } + } + return d; + } + + case TYPE_SET: + case TYPE_FROZENSET: { + int n = read_int(); + PyObject items[] = new PyObject[n]; + for (int i = 0; i < n; i++) { + items[i] = read_object(depth + 1); + } + PyTuple v = new PyTuple(items); + if (type == TYPE_SET) { + return new PySet(v); + } else { + return new PyFrozenSet(v); + } + } + + + case TYPE_CODE: { + // XXX - support restricted execution mode? not certain if this is just legacy + int argcount = read_int(); + int nlocals = read_int(); + int stacksize = read_int(); + int flags = read_int(); + String code = read_object_notnull(depth + 1).toString(); + PyObject consts[] = ((PyTuple) read_object_notnull(depth + 1)).getArray(); + String names[] = read_strings(depth + 1); + String varnames[] = read_strings(depth + 1); + String freevars[] = read_strings(depth + 1); + String cellvars[] = read_strings(depth + 1); + String filename = read_object_notnull(depth + 1).toString(); + String name = read_object_notnull(depth + 1).toString(); + int firstlineno = read_int(); + String lnotab = read_object_notnull(depth + 1).toString(); + + return new PyBytecode( + argcount, nlocals, stacksize, flags, + code, consts, names, varnames, + filename, name, firstlineno, lnotab, + cellvars, freevars); + } + + default: + throw Py.ValueError("bad marshal data"); + } + } + } +} + Modified: branches/pbcvm/src/org/python/modules/cPickle.java =================================================================== --- branches/pbcvm/src/org/python/modules/cPickle.java 2009-02-01 08:12:13 UTC (rev 6004) +++ branches/pbcvm/src/org/python/modules/cPickle.java 2009-02-01 08:24:06 UTC (rev 6005) @@ -658,143 +658,15 @@ - // Factory for creating IOFile representation. - private static IOFile createIOFile(PyObject file) { - Object f = file.__tojava__(cStringIO.StringIO.class); - if (f != Py.NoConversion) - return new cStringIOFile(file); - else if (__builtin__.isinstance(file, FileType)) - return new FileIOFile(file); - else - return new ObjectIOFile(file); - } - - - // IOFiles encapsulates and optimise access to the different file - // representation. - interface IOFile { - public abstract void write(String str); - // Usefull optimization since most data written are chars. - public abstract void write(char str); - public abstract void flush(); - public abstract String read(int len); - // Usefull optimization since all readlines removes the - // trainling newline. - public abstract String readlineNoNl(); - - } - - - // Use a cStringIO as a file. - static class cStringIOFile implements IOFile { - cStringIO.StringIO file; - - cStringIOFile(PyObject file) { - this.file = (cStringIO.StringIO)file.__tojava__(Object.class); - } - - public void write(String str) { - file.write(str); - } - - public void write(char ch) { - file.writeChar(ch); - } - - public void flush() {} - - public String read(int len) { - return file.read(len).asString(); - } - - public String readlineNoNl() { - return file.readlineNoNl().asString(); - } - } - - - // Use a PyFile as a file. - static class FileIOFile implements IOFile { - PyFile file; - - FileIOFile(PyObject file) { - this.file = (PyFile)file.__tojava__(PyFile.class); - if (this.file.getClosed()) - throw Py.ValueError("I/O operation on closed file"); - } - - public void write(String str) { - file.write(str); - } - - public void write(char ch) { - file.write(cStringIO.getString(ch)); - } - - public void flush() {} - - public String read(int len) { - return file.read(len).toString(); - } - - public String readlineNoNl() { - String line = file.readline().toString(); - return line.substring(0, line.length()-1); - } - } - - - // Use any python object as a file. - static class ObjectIOFile implements IOFile { - char[] charr = new char[1]; - StringBuilder buff = new StringBuilder(); - PyObject write; - PyObject read; - PyObject readline; - final int BUF_SIZE = 256; - - ObjectIOFile(PyObject file) { -// this.file = file; - write = file.__findattr__("write"); - read = file.__findattr__("read"); - readline = file.__findattr__("readline"); - } - - public void write(String str) { - buff.append(str); - if (buff.length() > BUF_SIZE) - flush(); - } - - public void write(char ch) { - buff.append(ch); - if (buff.length() > BUF_SIZE) - flush(); - } - - public void flush() { - write.__call__(new PyString(buff.toString())); - buff.setLength(0); - } - - public String read(int len) { - return read.__call__(new PyInteger(len)).toString(); - } - - public String readlineNoNl() { - String line = readline.__call__().toString(); - return line.substring(0, line.length()-1); - } - } - - + // Factory for creating PyIOFile representation. + /** * The Pickler object * @see cPickle#Pickler(PyObject) * @see cPickle#Pickler(PyObject,int) */ static public class Pickler { - private IOFile file; + private PyIOFile file; private int protocol; /** @@ -827,7 +699,7 @@ public Pickler(PyObject file, int protocol) { - this.file = createIOFile(file); + this.file = PyIOFileFactory.createIOFile(file); this.protocol = protocol; } @@ -1700,7 +1572,7 @@ */ static public class Unpickler { - private IOFile file; + private PyIOFile file; public Map<String,PyObject> memo = Generic.map(); @@ -1723,7 +1595,7 @@ Unpickler(PyObject file) { - this.file = createIOFile(file); + this.file = PyIOFileFactory.createIOFile(file); } Modified: branches/pbcvm/src/org/python/modules/struct.java =================================================================== --- branches/pbcvm/src/org/python/modules/struct.java 2009-02-01 08:12:13 UTC (rev 6004) +++ branches/pbcvm/src/org/python/modules/struct.java 2009-02-01 08:24:06 UTC (rev 6005) @@ -11,7 +11,6 @@ import org.python.core.Py; import org.python.core.PyException; import org.python.core.PyFloat; -import org.python.core.PyInteger; import org.python.core.PyList; import org.python.core.PyLong; import org.python.core.PyObject; @@ -20,13 +19,7 @@ import org.python.core.PyTuple; import java.math.BigInteger; -import java.util.Arrays; -import org.python.core.ClassDictInit; import org.python.core.PyArray; -import org.python.core.PyType; -import org.python.expose.ExposedGet; -import org.python.expose.ExposedNew; -import org.python.expose.ExposedType; /** * This module performs conversions between Python values and C @@ -103,7 +96,7 @@ * <tr><td align=center><samp>I</samp></td> * <td><tt>unsigned int</tt></td> * <td>integer</td> - * <tr><td align=center><samp>l</samp></td> + * <tr><td align=center><samp>size</samp></td> * <td><tt>long</tt></td> * <td>integer</td> * <tr><td align=center><samp>L</samp></td> @@ -410,13 +403,13 @@ } ByteStream(String s, int offset) { - int l = s.length() - offset; - data = new char[l]; + int size = s.length() - offset; + data = new char[size]; s.getChars(offset, s.length(), data, 0); - len = l; + len = size; pos = 0; -// System.out.println("s.length()=" + s.length() + ",offset=" + offset + ",l=" + l + ",data=" + Arrays.toString(data)); +// System.out.println("s.length()=" + s.length() + ",offset=" + offset + ",size=" + size + ",data=" + Arrays.toString(data)); } int readByte() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-02-06 07:07:47
|
Revision: 6016 http://jython.svn.sourceforge.net/jython/?rev=6016&view=rev Author: zyasoft Date: 2009-02-06 07:07:45 +0000 (Fri, 06 Feb 2009) Log Message: ----------- Fixed some cellvar/freevar nested scope issues, with work to continue. Added a slightly modified version of pycimport.py from Tobias' pyasm implementation in the sandbox. This, in conjunction with compileall (run from CPython; compileall.compile_dir against the unit tests) is allowing a significant fraction of the regrtest to run against PBC-VM. Modified Paths: -------------- branches/pbcvm/src/org/python/core/PyBytecode.java Added Paths: ----------- branches/pbcvm/Lib/pycimport.py Added: branches/pbcvm/Lib/pycimport.py =================================================================== --- branches/pbcvm/Lib/pycimport.py (rev 0) +++ branches/pbcvm/Lib/pycimport.py 2009-02-06 07:07:45 UTC (rev 6016) @@ -0,0 +1,84 @@ +import sys +import os + +from org.python.core import imp as _imp, PyFrame as _Frame, Py as _Py +from marshal import Unmarshaller + +__debugging__ = False + +def __readPycHeader(file): + def read(): + return ord(file.read(1)) + magic = read() | (read()<<8) + if not ( file.read(1) == '\r' and file.read(1) == '\n' ): + raise TypeError("not valid pyc-file") + mtime = read() | (read()<<8) | (read()<<16) | (read()<<24) + return magic, mtime + +def __makeModule(name, code, path): + module = _imp.addModule(name) + builtins = _Py.getSystemState().builtins + frame = _Frame(code, module.__dict__, module.__dict__, builtins) + module.__file__ = path + code.call(frame) # execute module code + return module + +class __Importer(object): + def __init__(self, path): + if __debugging__: print "Importer invoked" + self.__path = path + def find_module(self, fullname, path=None): + if __debugging__: + print "Importer.find_module(fullname=%s, path=%s)" % ( + repr(fullname), repr(path)) + path = fullname.split('.') + filename = path[-1] + path = path[:-1] + pycfile = os.path.join(self.__path, *(path + [filename + '.pyc'])) + pyfile = os.path.join(self.__path, *(path + [filename + '.py'])) + if os.path.exists(pycfile): + f = open(pycfile, 'rb') + try: + magic, mtime = __readPycHeader(f) + except: + return None # abort! not a valid pyc-file + f.close() + if os.path.exists(pyfile): + pytime = os.stat(pyfile).st_mtime + if pytime > mtime: + return None # abort! py-file was newer + return self + else: + return None # abort! pyc-file does not exist + def load_module(self, fullname): + path = fullname.split('.') + path[-1] += '.pyc' + filename = os.path.join(self.__path, *path) + f = open(filename, 'rb') + magic, mtime = __readPycHeader(f) + #code = Unmarshaller(f, magic=magic).load() + code = Unmarshaller(f).load() + if __debugging__: print "Successfully loaded:", fullname + return __makeModule( fullname, code, filename ) + +class __MetaImporter(object): + def __init__(self): + self.__importers = {} + def find_module(self, fullname, path): + if __debugging__: print "MetaImporter.find_module(%s, %s)" % ( + repr(fullname), repr(path)) + for _path in sys.path: + if _path not in self.__importers: + try: + self.__importers[_path] = __Importer(_path) + except: + self.__importers[_path] = None + importer = self.__importers[_path] + if importer is not None: + loader = importer.find_module(fullname, path) + if loader is not None: + return loader + else: + return None + +sys.meta_path.insert(0, __MetaImporter()) Modified: branches/pbcvm/src/org/python/core/PyBytecode.java =================================================================== --- branches/pbcvm/src/org/python/core/PyBytecode.java 2009-02-06 03:50:10 UTC (rev 6015) +++ branches/pbcvm/src/org/python/core/PyBytecode.java 2009-02-06 07:07:45 UTC (rev 6016) @@ -1,6 +1,7 @@ package org.python.core; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -234,7 +235,8 @@ // in a shadow version of the frame that we copy back to on entry/exit and downcalls if (debug) { - System.err.println("Entry with " + f.f_lasti + " into " + co_code.length); + System.err.println(co_name + ":" + f.f_lasti + "/" + co_code.length + + ", cells:" + Arrays.toString(co_cellvars) + ", free:" + Arrays.toString(co_freevars)); } if (f.f_lasti >= co_code.length) { throw Py.SystemError(""); @@ -700,7 +702,7 @@ case Opcode.BUILD_CLASS: { PyObject methods = stack.pop(); - PyObject bases[] = ((PyTuple)(stack.pop())).getArray(); // new PyTuple(stack.pop())).getArray(); + PyObject bases[] = ((PySequenceList)(stack.pop())).getArray(); String name = stack.pop().toString(); stack.push(Py.makeClass(name, bases, methods)); break; @@ -761,13 +763,26 @@ f.dellocal(oparg); break; - case Opcode.LOAD_CLOSURE: - stack.push(f.getclosure(oparg)); + case Opcode.LOAD_CLOSURE: { + if (debug) { + System.err.println("LOAD_CLOSURE: " + Arrays.toString(f.f_env)); + } + PyCell cell = (PyCell)(f.getclosure(oparg)); + if (cell.ob_ref == null) { + cell.ob_ref = f.getlocal(oparg); + } +// cell.ob_ref = f.getname(co_freevars[oparg]); + stack.push(cell); break; + } - case Opcode.LOAD_DEREF: + case Opcode.LOAD_DEREF: { + if (debug) { + System.err.println("LOAD_DEREF: " + Arrays.toString(f.f_env)); + } stack.push(f.getderef(oparg)); break; + } case Opcode.STORE_DEREF: f.setderef(oparg, stack.pop()); @@ -864,7 +879,7 @@ case Opcode.IMPORT_FROM: String name = co_names[oparg]; try { - stack.push(stack.pop().__getattr__(name)); + stack.push(stack.top().__getattr__(name)); } catch (PyException pye) { if (Py.matchException(pye, Py.AttributeError)) { @@ -1012,7 +1027,16 @@ case Opcode.MAKE_CLOSURE: { PyCode code = (PyCode) stack.pop(); - PyObject[] closure_cells = new PyTuple(stack.pop()).getArray(); + PyObject[] closure_cells = ((PySequenceList)(stack.pop())).getArray(); +// PyObject[] closure_cells = new PyCell[src_closure_cells.length]; +// for (int i = 0; i < src_closure_cells.length; i++) { +// PyCell cell = new PyCell(); +// cell.ob_ref = src_closure_cells[i]; +// closure_cells[i] = cell; +// } +//// for (int i = 0; i < src_closure_cells.length; i++) { +//// closure_cells[i] = f.getclosure(i); +//// } PyObject[] defaults = stack.popN(oparg); PyFunction func = new PyFunction(f.f_globals, defaults, code, closure_cells); stack.push(func); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-02-11 03:11:14
|
Revision: 6024 http://jython.svn.sourceforge.net/jython/?rev=6024&view=rev Author: zyasoft Date: 2009-02-11 03:11:10 +0000 (Wed, 11 Feb 2009) Log Message: ----------- Support tostring/fromstring of unsigned types so that they can be stored in the same size as their signed representation. This fixes an issues with peak.util.assembler where it expects that unsigned bytes (typecode 'B') take one byte to store and therefore are directly interoperable with co_code. Modified Paths: -------------- branches/pbcvm/Lib/test/test_array.py branches/pbcvm/src/org/python/core/PyArray.java Modified: branches/pbcvm/Lib/test/test_array.py =================================================================== --- branches/pbcvm/Lib/test/test_array.py 2009-02-09 01:40:53 UTC (rev 6023) +++ branches/pbcvm/Lib/test/test_array.py 2009-02-11 03:11:10 UTC (rev 6024) @@ -213,7 +213,7 @@ self.assertRaises(TypeError, b.fromstring, 42) b.fromstring(a.tostring()) self.assertEqual(a, b) - if a.itemsize>1: + if a.itemsize>1 and self.typecode not in ('b', 'B'): self.assertRaises(ValueError, b.fromstring, "x") def test_repr(self): Modified: branches/pbcvm/src/org/python/core/PyArray.java =================================================================== --- branches/pbcvm/src/org/python/core/PyArray.java 2009-02-09 01:40:53 UTC (rev 6023) +++ branches/pbcvm/src/org/python/core/PyArray.java 2009-02-11 03:11:10 UTC (rev 6024) @@ -491,7 +491,7 @@ * written on a machine with a different byte order. */ public void byteswap() { - if (getItemsize() == 0 || "u".equals(typecode)) { + if (getStorageSize() == 0 || "u".equals(typecode)) { throw Py.RuntimeError("don't know how to byteswap this array type"); } ByteSwapper.swap(data); @@ -591,6 +591,39 @@ } } + private static Class char2storageClass(char type) throws PyIgnoreMethodTag { + switch(type){ + case 'z': + return Boolean.TYPE; + case 'b': + return Byte.TYPE; + case 'B': + return Byte.TYPE; + case 'u': + return Integer.TYPE; + case 'c': + return Character.TYPE; + case 'h': + return Short.TYPE; + case 'H': + return Short.TYPE; + case 'i': + return Integer.TYPE; + case 'I': + return Integer.TYPE; + case 'l': + return Long.TYPE; + case 'L': + return Long.TYPE; + case 'f': + return Float.TYPE; + case 'd': + return Double.TYPE; + default: + throw Py.ValueError("bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)"); + } + } + private static String class2char(Class cls) { if(cls.equals(Boolean.TYPE)) return "z"; @@ -800,13 +833,13 @@ throw Py.TypeError("file needs to be in read mode"); } // read the data via the PyFile - int readbytes = count * getItemsize(); + int readbytes = count * getStorageSize(); String buffer = file.read(readbytes).toString(); // load whatever was collected into the array fromstring(buffer); // check for underflow if(buffer.length() < readbytes) { - int readcount = buffer.length() / getItemsize(); + int readcount = buffer.length() / getStorageSize(); throw Py.EOFError("not enough items in file. " + Integer.toString(count) + " requested, " + Integer.toString(readcount) + " actually read"); @@ -854,7 +887,7 @@ * @throws EOFException */ private int fromStream(InputStream is) throws IOException, EOFException { - return fromStream(is, is.available() / getItemsize()); + return fromStream(is, is.available() / getStorageSize()); } /** @@ -880,47 +913,87 @@ int index = origsize; // create capacity for 'count' items delegate.ensureCapacity(index + count); - if(type.isPrimitive()) { - if(type == Boolean.TYPE) { - for(int i = 0; i < count; i++, index++) { - Array.setBoolean(data, index, dis.readBoolean()); - delegate.size++; - } - } else if(type == Byte.TYPE) { - for(int i = 0; i < count; i++, index++) { - Array.setByte(data, index, dis.readByte()); - delegate.size++; - } - } else if(type == Character.TYPE) { - for(int i = 0; i < count; i++, index++) { - Array.setChar(data, index, (char)(dis.readByte() & 0xff)); - delegate.size++; - } - } else if(type == Integer.TYPE) { - for(int i = 0; i < count; i++, index++) { - Array.setInt(data, index, dis.readInt()); - delegate.size++; - } - } else if(type == Short.TYPE) { - for(int i = 0; i < count; i++, index++) { - Array.setShort(data, index, dis.readShort()); - delegate.size++; - } - } else if(type == Long.TYPE) { - for(int i = 0; i < count; i++, index++) { - Array.setLong(data, index, dis.readLong()); - delegate.size++; - } - } else if(type == Float.TYPE) { - for(int i = 0; i < count; i++, index++) { - Array.setFloat(data, index, dis.readFloat()); - delegate.size++; - } - } else if(type == Double.TYPE) { - for(int i = 0; i < count; i++, index++) { - Array.setDouble(data, index, dis.readDouble()); - delegate.size++; - } + if (type.isPrimitive()) { + switch (typecode.charAt(0)) { + case 'z': + for (int i = 0; i < count; i++, index++) { + Array.setBoolean(data, index, dis.readBoolean()); + delegate.size++; + } + break; + case 'b': + for (int i = 0; i < count; i++, index++) { + Array.setByte(data, index, dis.readByte()); + delegate.size++; + } + break; + case 'B': + for (int i = 0; i < count; i++, index++) { + Array.setShort(data, index, unsignedByte(dis.readByte())); + delegate.size++; + } + break; + case 'u': + // use 32-bit integers since we want UCS-4 storage + for (int i = 0; i < count; i++, index++) { + Array.setInt(data, index, dis.readInt()); + delegate.size++; + } + break; + case 'c': + for (int i = 0; i < count; i++, index++) { + Array.setChar(data, index, (char) (dis.readByte() & 0xff)); + delegate.size++; + } + break; + case 'h': + for (int i = 0; i < count; i++, index++) { + Array.setShort(data, index, dis.readShort()); + delegate.size++; + } + break; + case 'H': + for (int i = 0; i < count; i++, index++) { + Array.setInt(data, index, unsignedShort(dis.readShort())); + delegate.size++; + } + break; + case 'i': + for (int i = 0; i < count; i++, index++) { + Array.setInt(data, index, dis.readInt()); + delegate.size++; + } + break; + case 'I': + for (int i = 0; i < count; i++, index++) { + Array.setLong(data, index, unsignedInt(dis.readInt())); + delegate.size++; + } + break; + case 'l': + for (int i = 0; i < count; i++, index++) { + Array.setLong(data, index, dis.readLong()); + delegate.size++; + } + break; + case 'L': // faking it + for (int i = 0; i < count; i++, index++) { + Array.setLong(data, index, dis.readLong()); + delegate.size++; + } + break; + case 'f': + for (int i = 0; i < count; i++, index++) { + Array.setFloat(data, index, dis.readFloat()); + delegate.size++; + } + break; + case 'd': + for (int i = 0; i < count; i++, index++) { + Array.setDouble(data, index, dis.readDouble()); + delegate.size++; + } + break; } } dis.close(); @@ -941,7 +1014,7 @@ */ @ExposedMethod final void array_fromstring(String input) { - int itemsize = getItemsize(); + int itemsize = getStorageSize(); int strlen = input.length(); if((strlen % itemsize) != 0) { throw Py.ValueError("string length not a multiple of item size"); @@ -1077,6 +1150,43 @@ return 0; } + public int getStorageSize() { + if (type.isPrimitive()) { + switch (typecode.charAt(0)) { + case 'z': + return 1; + case 'b': + return 1; + case 'B': + return 1; + case 'u': + return 4; + case 'c': + return 1; + case 'h': + return 2; + case 'H': + return 2; + case 'i': + return 4; + case 'I': + return 4; + case 'l': + return 8; + case 'L': + return 8; + case 'f': + return 4; + case 'd': + return 8; + default: + throw Py.ValueError("bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)"); + } + } + // return something here... could be a calculated size? + return 0; + } + /** * Retrieve a slice from the array specified by the <em>start</em>, * <em>stop</em> and <em>step</em>. @@ -1543,36 +1653,128 @@ */ private int toStream(OutputStream os) throws IOException { DataOutputStream dos = new DataOutputStream(os); - if(type.isPrimitive()) { - if(type == Boolean.TYPE) { + switch (typecode.charAt(0)) { + case 'z': for(int i = 0; i < delegate.getSize(); i++) dos.writeBoolean(Array.getBoolean(data, i)); - } else if(type == Byte.TYPE) { + break; + case 'b': for(int i = 0; i < delegate.getSize(); i++) dos.writeByte(Array.getByte(data, i)); - } else if(type == Character.TYPE) { + break; + case 'B': for(int i = 0; i < delegate.getSize(); i++) - dos.writeByte((byte)Array.getChar(data, i)); - } else if(type == Integer.TYPE) { + dos.writeByte(signedByte(Array.getShort(data, i))); + break; + case 'u': + // use 32-bit integers since we want UCS-4 storage for(int i = 0; i < delegate.getSize(); i++) dos.writeInt(Array.getInt(data, i)); - } else if(type == Short.TYPE) { + break; + case 'c': for(int i = 0; i < delegate.getSize(); i++) + dos.writeByte((byte)Array.getChar(data, i)); + break; + case 'h': + for(int i = 0; i < delegate.getSize(); i++) dos.writeShort(Array.getShort(data, i)); - } else if(type == Long.TYPE) { + break; + case 'H': for(int i = 0; i < delegate.getSize(); i++) + dos.writeShort(signedShort(Array.getInt(data, i))); + break; + case 'i': + for(int i = 0; i < delegate.getSize(); i++) + dos.writeInt(Array.getInt(data, i)); + break; + case 'I': + for(int i = 0; i < delegate.getSize(); i++) + dos.writeInt(signedInt(Array.getLong(data, i))); + break; + case 'l': + for(int i = 0; i < delegate.getSize(); i++) dos.writeLong(Array.getLong(data, i)); - } else if(type == Float.TYPE) { + break; + case 'L': // faking it for(int i = 0; i < delegate.getSize(); i++) + dos.writeLong(Array.getLong(data, i)); + break; + case 'f': + for(int i = 0; i < delegate.getSize(); i++) dos.writeFloat(Array.getFloat(data, i)); - } else if(type == Double.TYPE) { + break; + case 'd': for(int i = 0; i < delegate.getSize(); i++) dos.writeDouble(Array.getDouble(data, i)); - } + break; } return dos.size(); } + private static byte signedByte(short x) { + if (x >= 128 && x < 256) { + return (byte)(x - 256); + } + else if (x >= 0) { + return (byte)x; + } + else { + throw Py.ValueError("invalid storage"); + } + } + + private static short signedShort(int x) { + if (x >= 32768 && x < 65536) { + return (short)(x - 65536); + } + else if (x >= 0) { + return (short)x; + } + else { + throw Py.ValueError("invalid storage"); + } + } + + private static int signedInt(long x) { + if (x >= 2147483648L && x < 4294967296L) { + return (int)(x - 4294967296L); + } + else if (x >= 0) { + return (int)x; + } + else { + throw Py.ValueError("invalid storage"); + } + } + + private static short unsignedByte(byte x) { + if (x < 0) { + return (short)(x + 256); + } + else { + return x; + } + } + + private static int unsignedShort(short x) { + if (x < 0) { + return x + 65536; + } + else { + return x; + } + } + + private static long unsignedInt(int x) { + if (x < 0) { + return x + 4294967296L; + } + else { + return x; + } + + } + @ExposedMethod public final PyObject array_tostring(){ return new PyString(tostring()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-02-24 04:58:03
|
Revision: 6044 http://jython.svn.sourceforge.net/jython/?rev=6044&view=rev Author: zyasoft Date: 2009-02-24 04:57:56 +0000 (Tue, 24 Feb 2009) Log Message: ----------- Merged revisions 5950-5951,5953-5957,5959,5961,5965-5966,5971-5976,5978-5979,5981-5983,5992,6001,6003,6006-6014,6023,6031-6037,6039-6040 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r5950 | zyasoft | 2009-01-20 11:28:03 -0700 (Tue, 20 Jan 2009) | 4 lines Added os.getcwdu. This fixes #1219 (necessary for Django 1.0.2 support), but not the larger question of better Unicode handling in the os module, specifically around os.path. ........ r5951 | leosoto | 2009-01-20 12:29:17 -0700 (Tue, 20 Jan 2009) | 1 line Use the new getcwdu on POSIXHandler, to avoid unnecesary conversions from unicode to bytestring. Also added getcwdu to os.__all__ ........ r5953 | cgroves | 2009-01-21 13:47:19 -0700 (Wed, 21 Jan 2009) | 1 line Break out the compile method for use in subclasses ........ r5954 | cgroves | 2009-01-21 14:26:50 -0700 (Wed, 21 Jan 2009) | 1 line Turn includeJavaStackInExceptions on by default as it was always done in previous versions. ........ r5955 | cgroves | 2009-01-21 16:32:55 -0700 (Wed, 21 Jan 2009) | 8 lines Add a jython initializer service. If META-INF/services/org.python.core.JythonInitializer is on the classpath, the class named in that file will be instantiated and used in Jython's initialization. This is useful when Jython is initialized by a library outside of your control, but some customization still needs to be done to Jython's environment. I promise not to add a JythonFactory or a JythonFactoryFactory. ........ r5956 | fwierzbicki | 2009-01-21 19:21:08 -0700 (Wed, 21 Jan 2009) | 4 lines Fix for http://bugs.jython.org/issue1239. When jars where added to sys.path, they did not always trigger package caching, leading to unexpected import failures. This is Charlie Grove's fix, which was much better than mine. ........ r5957 | fwierzbicki | 2009-01-21 21:16:47 -0700 (Wed, 21 Jan 2009) | 7 lines Thanks to Marc Downie for this patch that fixes http://bugs.jython.org/issue1230 importing with '*' from java packages does not work with 2.5b1. Also added a test to test_java_integration.py. ........ r5959 | cgroves | 2009-01-22 12:50:18 -0700 (Thu, 22 Jan 2009) | 1 line Expose rich comparision methods on Java classes implementing Comparable ........ r5961 | fwierzbicki | 2009-01-22 18:03:39 -0700 (Thu, 22 Jan 2009) | 3 lines Over-ride pyset in PyTuple so our tuples go back to being immutable. Fixes http://bugs.jython.org/issue1242. ........ r5965 | pjenvey | 2009-01-23 16:40:46 -0700 (Fri, 23 Jan 2009) | 2 lines more java.lang.Strings to regular str instead of unicode ........ r5966 | pjenvey | 2009-01-23 17:17:40 -0700 (Fri, 23 Jan 2009) | 3 lines merge from: http://svn.python.org/projects/python/branches/release25-maint/Lib/platform.py -c 66214 ........ r5971 | cgroves | 2009-01-24 13:10:59 -0700 (Sat, 24 Jan 2009) | 1 line Run the java import * test from a sub-interpreter to allow regrtest to be run with python.cachedir.skip=true ........ r5972 | cgroves | 2009-01-24 13:11:54 -0700 (Sat, 24 Jan 2009) | 1 line Try the current classloader for places where the context classloader isn't set ........ r5973 | cgroves | 2009-01-24 13:17:39 -0700 (Sat, 24 Jan 2009) | 1 line Exclude the xerces service declaration as our jarjar'd version doesn't match the names in the declaration ........ r5974 | cgroves | 2009-01-25 05:15:25 -0700 (Sun, 25 Jan 2009) | 1 line Bring up to the current state of affairs ........ r5975 | cgroves | 2009-01-25 05:19:27 -0700 (Sun, 25 Jan 2009) | 3 lines Use Python's mro to determine an mro for Java classes and interfaces. If the Java class has an mro conflict, resolve it by arbitrarily choosing an interface or class. If an interface or class involved in an mro conflict has had its dict modified, or has its dict modified, raise a TypeError. ........ r5976 | cgroves | 2009-01-25 05:19:58 -0700 (Sun, 25 Jan 2009) | 1 line Test support classes for the last commit ........ r5978 | nriley | 2009-01-25 14:06:04 -0700 (Sun, 25 Jan 2009) | 1 line Typo fix. ........ r5979 | cgroves | 2009-01-25 17:33:21 -0700 (Sun, 25 Jan 2009) | 4 lines Include Python Java subclasses as bases as well as the Java proxy type, as it may have additional methods in its Python. Return the proxyClass directly from getProxyType as we're setting that on Python subclasses now. ........ r5981 | cgroves | 2009-01-25 19:21:05 -0700 (Sun, 25 Jan 2009) | 1 line Defer resolving inner classes till the containing class is fully resolved. Fixes issue #1234. ........ r5982 | cgroves | 2009-01-25 20:10:36 -0700 (Sun, 25 Jan 2009) | 1 line Try to assign to a static field for a given name in __setattr__ on a Java type before filling something in on the dict. Fixes bug #1241 ........ r5983 | cgroves | 2009-01-25 20:36:25 -0700 (Sun, 25 Jan 2009) | 1 line Fix javatests ........ r5992 | amak | 2009-01-28 09:05:59 -0700 (Wed, 28 Jan 2009) | 3 lines Fix and unit test for bug 1244. Problem letting system choose the port for binding UDP socket http://bugs.jython.org/issue1244 ........ r6001 | amak | 2009-01-29 10:59:04 -0700 (Thu, 29 Jan 2009) | 2 lines Re-arranging the socket shutdown methods. TCP client sockets can shutdown their input streams, but this is not appropriate for either TCP server sockets or UDP sockets, which don't have input and output streams. For these latter two types, the shutdown method should have the same effect as the close method, and thus the shutdown method is a no-op for these types. I have documented this difference between cpython and jython on the wiki. This should finally resolve bug 1121: listening socket shutdown expects the wrong kind of socket http://bugs.jython.org/issue1121 ........ r6003 | pjenvey | 2009-01-30 19:20:48 -0700 (Fri, 30 Jan 2009) | 1 line make --version resemble CPython ........ r6006 | amak | 2009-02-02 08:50:25 -0700 (Mon, 02 Feb 2009) | 4 lines Fix for bug 1258. select() semantics differ from CPython, causing pydoc HTTPd to fail http://bugs.jython.org/issue1258 Thanks to Ryan Blair for reporting the bug and providing a patch. ........ r6007 | amak | 2009-02-03 05:01:46 -0700 (Tue, 03 Feb 2009) | 2 lines Committing the latest version of modjy. See the release notes for details. ........ r6008 | pjenvey | 2009-02-03 13:19:57 -0700 (Tue, 03 Feb 2009) | 1 line fix test_version per r6003 ........ r6009 | pjenvey | 2009-02-03 14:25:23 -0700 (Tue, 03 Feb 2009) | 2 lines include PATH for platforms lacking bash in /bin ........ r6010 | leosoto | 2009-02-03 17:51:47 -0700 (Tue, 03 Feb 2009) | 1 line PyObject#reduce_2: Use invoke("iteritems") instead of this.iteritems() to avoid problems with dict subclasses which override iteritems on python code. Fixes #1257 ........ r6011 | amak | 2009-02-04 08:20:56 -0700 (Wed, 04 Feb 2009) | 4 lines Our asyncore is completely broken; see bug 1237. Asnycore does not seem to work in Jython 2.5 (b0 or b1) http://bugs.jython.org/issue1237 Starting again from scratch; Step 1: remove existing module. ........ r6012 | amak | 2009-02-04 08:22:21 -0700 (Wed, 04 Feb 2009) | 1 line Fresh start with asyncore; step 2: copy over asyncore from cpython 2.5.2. ........ r6013 | amak | 2009-02-04 08:27:59 -0700 (Wed, 04 Feb 2009) | 3 lines Fresh start with asycnore; step 3: make necessary changes to cpython 2.5 module to work on jython 2.5. The code in this bug report now works identically to cpython. http://bugs.jython.org/issue1237 ........ r6014 | otmarhumbel | 2009-02-05 11:08:10 -0700 (Thu, 05 Feb 2009) | 1 line added dummy_thread.py and dummy_threading.py ........ r6023 | fwierzbicki | 2009-02-08 18:40:53 -0700 (Sun, 08 Feb 2009) | 2 lines Fix for http://bugs.jython.org/issue1243. Thanks RJ Ryan for suggesting the fix. ........ r6031 | fwierzbicki | 2009-02-15 07:23:28 -0700 (Sun, 15 Feb 2009) | 3 lines Fix potential infinite loop (and wrong slice behavior) -- found with FindBugs ........ r6032 | fwierzbicki | 2009-02-15 11:22:18 -0700 (Sun, 15 Feb 2009) | 2 lines Fixed two infinite recursions found with FindBugs. ........ r6033 | fwierzbicki | 2009-02-15 11:31:27 -0700 (Sun, 15 Feb 2009) | 2 lines Fixed NPE found with FindBugs. ........ r6034 | amak | 2009-02-15 11:35:41 -0700 (Sun, 15 Feb 2009) | 2 lines A new version of modjy, containing some bug fixes kindly contributed by Philip Jenvey; see contained release notes for more information. http://github.com/pjenvey/modjy-pjenvey ........ r6035 | pjenvey | 2009-02-15 16:27:44 -0700 (Sun, 15 Feb 2009) | 3 lines double antlr's conversiontimeout for slower environments, in particular the hudson buildot ........ r6036 | fwierzbicki | 2009-02-16 08:41:50 -0700 (Mon, 16 Feb 2009) | 2 lines Useless double assignment. ........ r6037 | fwierzbicki | 2009-02-16 19:38:09 -0700 (Mon, 16 Feb 2009) | 2 lines Make the public adapters in AstAdapters final. ........ r6039 | amak | 2009-02-18 06:21:13 -0700 (Wed, 18 Feb 2009) | 1 line Updating the zip file for modjy 0.25.3; previously checked in version had the wrong version of modjy.jar in WEB-INF/lib. ........ r6040 | fwierzbicki | 2009-02-19 13:16:18 -0700 (Thu, 19 Feb 2009) | 4 lines Our handling of writes after a seek beyond the end of cStringIO was not consistent with CPython (or even our own use of StringIO). Found while trying to get Mercurial to respond to "hg log". ........ Modified Paths: -------------- branches/pbcvm/CPythonLib.includes branches/pbcvm/Lib/os.py branches/pbcvm/Lib/platform.py branches/pbcvm/Lib/pydoc.py branches/pbcvm/Lib/socket.py branches/pbcvm/Lib/test/test_StringIO_jy.py branches/pbcvm/Lib/test/test_classpathimporter.py branches/pbcvm/Lib/test/test_cmd_line.py branches/pbcvm/Lib/test/test_import_jy.py branches/pbcvm/Lib/test/test_java_integration.py branches/pbcvm/Lib/test/test_java_subclasses.py branches/pbcvm/Lib/test/test_java_visibility.py branches/pbcvm/Lib/test/test_socket.py branches/pbcvm/Lib/test/test_tuple.py branches/pbcvm/build.xml branches/pbcvm/registry branches/pbcvm/src/org/python/antlr/adapter/AstAdapters.java branches/pbcvm/src/org/python/compiler/JavaMaker.java branches/pbcvm/src/org/python/core/AstList.java branches/pbcvm/src/org/python/core/ClasspathPyImporter.java branches/pbcvm/src/org/python/core/Options.java branches/pbcvm/src/org/python/core/Py.java branches/pbcvm/src/org/python/core/PyJavaType.java branches/pbcvm/src/org/python/core/PyNewWrapper.java branches/pbcvm/src/org/python/core/PyObject.java branches/pbcvm/src/org/python/core/PySequence.java branches/pbcvm/src/org/python/core/PySystemState.java branches/pbcvm/src/org/python/core/PyTuple.java branches/pbcvm/src/org/python/core/PyType.java branches/pbcvm/src/org/python/core/SyspathJavaLoader.java branches/pbcvm/src/org/python/core/ThreadStateMapping.java branches/pbcvm/src/org/python/core/imp.java branches/pbcvm/src/org/python/core/packagecache/PackageManager.java branches/pbcvm/src/org/python/core/packagecache/PathPackageManager.java branches/pbcvm/src/org/python/modules/_csv/PyWriter.java branches/pbcvm/src/org/python/modules/cStringIO.java branches/pbcvm/src/org/python/modules/thread/PyLocal.java branches/pbcvm/src/org/python/util/JycompileAntTask.java branches/pbcvm/src/org/python/util/jython.java branches/pbcvm/tests/java/org/python/expose/generate/TypeExposerTest.java branches/pbcvm/tests/java/org/python/tests/Coercions.java branches/pbcvm/tests/java/org/python/tests/Visible.java Added Paths: ----------- branches/pbcvm/Lib/asyncore.py branches/pbcvm/Lib/test/bug1239.jar branches/pbcvm/Lib/test/check_for_initializer_in_syspath.py branches/pbcvm/Lib/test/import_star_from_java.py branches/pbcvm/Lib/test/test_jython_initializer.py branches/pbcvm/extlibs/modjy_0_25_3.zip branches/pbcvm/src/org/python/core/JythonInitializer.java branches/pbcvm/tests/data/ branches/pbcvm/tests/data/initializer/ branches/pbcvm/tests/data/initializer/META-INF/ branches/pbcvm/tests/data/initializer/META-INF/services/ branches/pbcvm/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer branches/pbcvm/tests/data/initializer/SyspathAppendingInitializer.java branches/pbcvm/tests/java/org/python/tests/inbred/ branches/pbcvm/tests/java/org/python/tests/inbred/Metis.java branches/pbcvm/tests/java/org/python/tests/inbred/Zeus.java branches/pbcvm/tests/java/org/python/tests/mro/ branches/pbcvm/tests/java/org/python/tests/mro/ConfusedOnGetitemAdd.java branches/pbcvm/tests/java/org/python/tests/mro/ConfusedOnImport.java branches/pbcvm/tests/java/org/python/tests/mro/FirstAndPost.java branches/pbcvm/tests/java/org/python/tests/mro/FirstAndSecond.java branches/pbcvm/tests/java/org/python/tests/mro/FirstPredefinedGetitem.java branches/pbcvm/tests/java/org/python/tests/mro/GetitemAdder.java branches/pbcvm/tests/java/org/python/tests/mro/PostAndFirst.java branches/pbcvm/tests/java/org/python/tests/mro/PostdefinedGetitem.java branches/pbcvm/tests/java/org/python/tests/mro/SecondAndFirst.java branches/pbcvm/tests/java/org/python/tests/mro/SecondPredefinedGetitem.java Removed Paths: ------------- branches/pbcvm/Lib/asyncore.py branches/pbcvm/extlibs/modjy_0_25_1.zip branches/pbcvm/tests/data/initializer/ branches/pbcvm/tests/data/initializer/META-INF/ branches/pbcvm/tests/data/initializer/META-INF/services/ branches/pbcvm/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer branches/pbcvm/tests/data/initializer/SyspathAppendingInitializer.java branches/pbcvm/tests/java/org/python/tests/inbred/Metis.java branches/pbcvm/tests/java/org/python/tests/inbred/Zeus.java branches/pbcvm/tests/java/org/python/tests/mro/ConfusedOnGetitemAdd.java branches/pbcvm/tests/java/org/python/tests/mro/ConfusedOnImport.java branches/pbcvm/tests/java/org/python/tests/mro/FirstAndPost.java branches/pbcvm/tests/java/org/python/tests/mro/FirstAndSecond.java branches/pbcvm/tests/java/org/python/tests/mro/FirstPredefinedGetitem.java branches/pbcvm/tests/java/org/python/tests/mro/GetitemAdder.java branches/pbcvm/tests/java/org/python/tests/mro/PostAndFirst.java branches/pbcvm/tests/java/org/python/tests/mro/PostdefinedGetitem.java branches/pbcvm/tests/java/org/python/tests/mro/SecondAndFirst.java branches/pbcvm/tests/java/org/python/tests/mro/SecondPredefinedGetitem.java Property Changed: ---------------- branches/pbcvm/ Property changes on: branches/pbcvm ___________________________________________________________________ Modified: svnmerge-integrated - /trunk/jython:1-5947 + /trunk/jython:1-6043 Modified: branches/pbcvm/CPythonLib.includes =================================================================== --- branches/pbcvm/CPythonLib.includes 2009-02-24 04:37:39 UTC (rev 6043) +++ branches/pbcvm/CPythonLib.includes 2009-02-24 04:57:56 UTC (rev 6044) @@ -52,6 +52,8 @@ DocXMLRPCServer.py dospath.py dumbdbm.py +dummy_thread.py +dummy_threading.py exceptions.py fileinput.py fnmatch.py Deleted: branches/pbcvm/Lib/asyncore.py =================================================================== --- branches/pbcvm/Lib/asyncore.py 2009-02-24 04:37:39 UTC (rev 6043) +++ branches/pbcvm/Lib/asyncore.py 2009-02-24 04:57:56 UTC (rev 6044) @@ -1,561 +0,0 @@ -# -*- Mode: Python -*- -# Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp -# Author: Sam Rushing <ru...@ni...> - -# ====================================================================== -# Copyright 1996 by Sam Rushing -# -# All Rights Reserved -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose and without fee is hereby -# granted, provided that the above copyright notice appear in all -# copies and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of Sam -# Rushing not be used in advertising or publicity pertaining to -# distribution of the software without specific, written prior -# permission. -# -# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -# NO EVENT SHALL SAM RUSHING 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. -# ====================================================================== - -"""Basic infrastructure for asynchronous socket service clients and servers. - -There are only two ways to have a program on a single processor do "more -than one thing at a time". Multi-threaded programming is the simplest and -most popular way to do it, but there is another very different technique, -that lets you have nearly all the advantages of multi-threading, without -actually using multiple threads. it's really only practical if your program -is largely I/O bound. If your program is CPU bound, then pre-emptive -scheduled threads are probably what you really need. Network servers are -rarely CPU-bound, however. - -If your operating system supports the select() system call in its I/O -library (and nearly all do), then you can use it to juggle multiple -communication channels at once; doing other work while your I/O is taking -place in the "background." Although this strategy can seem strange and -complex, especially at first, it is in many ways easier to understand and -control than multi-threaded programming. The module documented here solves -many of the difficult problems for you, making the task of building -sophisticated high-performance network servers and clients a snap. -""" - -import exceptions -import select -import socket -import sys -import time - -import os -from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \ - ENOTCONN, ESHUTDOWN, EINTR, EISCONN - -try: - socket_map -except NameError: - socket_map = {} - -class ExitNow(exceptions.Exception): - pass - -def read(obj): - try: - obj.handle_read_event() - except ExitNow: - raise - except: - obj.handle_error() - -def write(obj): - try: - obj.handle_write_event() - except ExitNow: - raise - except: - obj.handle_error() - -def readwrite(obj, flags): - try: - if flags & select.POLLIN: - obj.handle_read_event() - if flags & select.POLLOUT: - obj.handle_write_event() - except ExitNow: - raise - except: - obj.handle_error() - -def poll(timeout=0.0, map=None): - if map is None: - map = socket_map - if map: - r = []; w = []; e = [] - for fd, obj in map.items(): - if obj.readable(): - r.append(fd) - if obj.writable(): - w.append(fd) - if [] == r == w == e: - time.sleep(timeout) - else: - try: - r, w, e = select.select(r, w, e, timeout) - except select.error, err: - if err[0] != EINTR: - raise - else: - return - - for fd in r: - obj = map.get(fd) - if obj is None: - continue - read(obj) - - for fd in w: - obj = map.get(fd) - if obj is None: - continue - write(obj) - -def poll2(timeout=0.0, map=None): - import poll - if map is None: - map = socket_map - if timeout is not None: - # timeout is in milliseconds - timeout = int(timeout*1000) - if map: - l = [] - for fd, obj in map.items(): - flags = 0 - if obj.readable(): - flags = poll.POLLIN - if obj.writable(): - flags = flags | poll.POLLOUT - if flags: - l.append((fd, flags)) - r = poll.poll(l, timeout) - for fd, flags in r: - obj = map.get(fd) - if obj is None: - continue - readwrite(obj, flags) - -def poll3(timeout=0.0, map=None): - # Use the poll() support added to the select module in Python 2.0 - if map is None: - map = socket_map - if timeout is not None: - # timeout is in milliseconds - timeout = int(timeout*1000) - pollster = select.poll() - if map: - for fd, obj in map.items(): - flags = 0 - if obj.readable(): - flags = select.POLLIN - if obj.writable(): - flags = flags | select.POLLOUT - if flags: - pollster.register(fd, flags) - try: - r = pollster.poll(timeout) - except select.error, err: - if err[0] != EINTR: - raise - r = [] - for fd, flags in r: - obj = map.get(fd) - if obj is None: - continue - readwrite(obj, flags) - -def loop(timeout=30.0, use_poll=0, map=None): - if map is None: - map = socket_map - - if use_poll: - if hasattr(select, 'poll'): - poll_fun = poll3 - else: - poll_fun = poll2 - else: - poll_fun = poll - - while map: - poll_fun(timeout, map) - -class dispatcher: - - debug = 0 - connected = 0 - accepting = 0 - closing = 0 - addr = None - - def __init__(self, sock=None, map=None): - if sock: - self.set_socket(sock, map) - # I think it should inherit this anyway - self.socket.setblocking(0) - self.connected = 1 - # XXX Does the constructor require that the socket passed - # be connected? - try: - self.addr = sock.getpeername() - except socket.error: - # The addr isn't crucial - pass - else: - self.socket = None - - def __repr__(self): - status = [self.__class__.__module__+"."+self.__class__.__name__] - if self.accepting and self.addr: - status.append('listening') - elif self.connected: - status.append('connected') - if self.addr is not None: - try: - status.append('%s:%d' % self.addr) - except TypeError: - status.append(repr(self.addr)) - # On some systems (RH10) id() can be a negative number. - # work around this. - MAX = 2L*sys.maxint+1 - return '<%s at %#x>' % (' '.join(status), id(self)&MAX) - - def add_channel(self, map=None): - #self.log_info('adding channel %s' % self) - if map is None: - if hasattr(self, '_map'): - map = self._map - del self._map - else: - map = socket_map - if not hasattr(self, '_fileno'): - self._fileno = self.socket.fileno() - map[self._fileno] = self - - def del_channel(self, map=None): - fd = self._fileno - if map is None: - map = socket_map - if map.has_key(fd): - #self.log_info('closing channel %d:%s' % (fd, self)) - del map[fd] - - def create_socket(self, family, type): - self.family_and_type = family, type - self.socket = socket.socket(family, type) - self.socket.setblocking(0) - - def set_socket(self, sock, map=None): - self.socket = sock -## self.__dict__['socket'] = sock - if sock.fileno(): - self.add_channel(map) - else: - self._map = map - - def set_reuse_addr(self): - # try to re-use a server port if possible - try: - self.socket.setsockopt( - socket.SOL_SOCKET, socket.SO_REUSEADDR, - self.socket.getsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR) | 1 - ) - except socket.error: - pass - - # ================================================== - # predicates for select() - # these are used as filters for the lists of sockets - # to pass to select(). - # ================================================== - - def readable(self): - return True - - if os.name == 'mac': - # The macintosh will select a listening socket for - # write if you let it. What might this mean? - def writable(self): - return not self.accepting - else: - def writable(self): - return True - - # ================================================== - # socket object methods. - # ================================================== - - def listen(self, num): - self.accepting = 1 - if os.name == 'nt' and num > 5: - num = 1 - ret = self.socket.listen(num) - self.add_channel() - return ret - - def bind(self, addr): - self.addr = addr - return self.socket.bind(addr) - - def connect(self, address): - self.connected = 0 - err = self.socket.connect_ex(address) - # XXX Should interpret Winsock return values - if err in (EINPROGRESS, EALREADY, EWOULDBLOCK): - return - if err in (0, EISCONN): - self.add_channel() - self.addr = address - self.connected = 1 - self.handle_connect() - else: - raise socket.error, err - - def accept(self): - # XXX can return either an address pair or None - try: - conn, addr = self.socket.accept() - self.add_channel() - return conn, addr - except socket.error, why: - if why[0] == EWOULDBLOCK: - pass - else: - raise socket.error, why - - def send(self, data): - try: - result = self.socket.send(data) - return result - except socket.error, why: - if why[0] == EWOULDBLOCK: - return 0 - else: - raise socket.error, why - return 0 - - def recv(self, buffer_size): - try: - data = self.socket.recv(buffer_size) - if not data: - # a closed connection is indicated by signaling - # a read condition, and having recv() return 0. - self.handle_close() - return '' - else: - return data - except socket.error, why: - # winsock sometimes throws ENOTCONN - if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]: - self.handle_close() - return '' - else: - raise socket.error, why - - def close(self): - self.del_channel() - self.socket.close() - - # cheap inheritance, used to pass all other attribute - # references to the underlying socket object. - def __getattr__(self, attr): - return getattr(self.socket, attr) - - # log and log_info may be overridden to provide more sophisticated - # logging and warning methods. In general, log is for 'hit' logging - # and 'log_info' is for informational, warning and error logging. - - def log(self, message): - sys.stderr.write('log: %s\n' % str(message)) - - def log_info(self, message, type='info'): - if __debug__ or type != 'info': - print '%s: %s' % (type, message) - - def handle_read_event(self): - if self.accepting: - # for an accepting socket, getting a read implies - # that we are connected - if not self.connected: - self.connected = 1 - self.handle_accept() - elif not self.connected: - self.handle_connect() - self.connected = 1 - self.handle_read() - else: - self.handle_read() - - def handle_write_event(self): - # getting a write implies that we are connected - if not self.connected: - self.handle_connect() - self.connected = 1 - self.handle_write() - - def handle_expt_event(self): - self.handle_expt() - - def handle_error(self): - nil, t, v, tbinfo = compact_traceback() - - # sometimes a user repr method will crash. - try: - self_repr = repr(self) - except: - self_repr = '<__repr__(self) failed for object at %0x>' % id(self) - - self.log_info( - 'uncaptured python exception, closing channel %s (%s:%s %s)' % ( - self_repr, - t, - v, - tbinfo - ), - 'error' - ) - self.close() - - def handle_expt(self): - self.log_info('unhandled exception', 'warning') - - def handle_read(self): - self.log_info('unhandled read event', 'warning') - - def handle_write(self): - self.log_info('unhandled write event', 'warning') - - def handle_connect(self): - self.log_info('unhandled connect event', 'warning') - - def handle_accept(self): - self.log_info('unhandled accept event', 'warning') - - def handle_close(self): - self.log_info('unhandled close event', 'warning') - self.close() - -# --------------------------------------------------------------------------- -# adds simple buffered output capability, useful for simple clients. -# [for more sophisticated usage use asynchat.async_chat] -# --------------------------------------------------------------------------- - -class dispatcher_with_send(dispatcher): - - def __init__(self, sock=None): - dispatcher.__init__(self, sock) - self.out_buffer = '' - - def initiate_send(self): - num_sent = 0 - num_sent = dispatcher.send(self, self.out_buffer[:512]) - self.out_buffer = self.out_buffer[num_sent:] - - def handle_write(self): - self.initiate_send() - - def writable(self): - return (not self.connected) or len(self.out_buffer) - - def send(self, data): - if self.debug: - self.log_info('sending %s' % repr(data)) - self.out_buffer = self.out_buffer + data - self.initiate_send() - -# --------------------------------------------------------------------------- -# used for debugging. -# --------------------------------------------------------------------------- - -def compact_traceback(): - t, v, tb = sys.exc_info() - tbinfo = [] - assert tb # Must have a traceback - while tb: - tbinfo.append(( - tb.tb_frame.f_code.co_filename, - tb.tb_frame.f_code.co_name, - str(tb.tb_lineno) - )) - tb = tb.tb_next - - # just to be safe - del tb - - file, function, line = tbinfo[-1] - info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo]) - return (file, function, line), t, v, info - -def close_all(map=None): - if map is None: - map = socket_map - for x in map.values(): - x.socket.close() - map.clear() - -# Asynchronous File I/O: -# -# After a little research (reading man pages on various unixen, and -# digging through the linux kernel), I've determined that select() -# isn't meant for doing asynchronous file i/o. -# Heartening, though - reading linux/mm/filemap.c shows that linux -# supports asynchronous read-ahead. So _MOST_ of the time, the data -# will be sitting in memory for us already when we go to read it. -# -# What other OS's (besides NT) support async file i/o? [VMS?] -# -# Regardless, this is useful for pipes, and stdin/stdout... - -if os.name == 'posix': - import fcntl - - class file_wrapper: - # here we override just enough to make a file - # look like a socket for the purposes of asyncore. - - def __init__(self, fd): - self.fd = fd - - def recv(self, *args): - return os.read(self.fd, *args) - - def send(self, *args): - return os.write(self.fd, *args) - - read = recv - write = send - - def close(self): - return os.close(self.fd) - - def fileno(self): - return self.fd - - class file_dispatcher(dispatcher): - - def __init__(self, fd): - dispatcher.__init__(self) - self.connected = 1 - # set it to non-blocking mode - flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) - self.set_file(fd) - - def set_file(self, fd): - self._fileno = fd - self.socket = file_wrapper(fd) - self.add_channel() Copied: branches/pbcvm/Lib/asyncore.py (from rev 6040, trunk/jython/Lib/asyncore.py) =================================================================== --- branches/pbcvm/Lib/asyncore.py (rev 0) +++ branches/pbcvm/Lib/asyncore.py 2009-02-24 04:57:56 UTC (rev 6044) @@ -0,0 +1,551 @@ +# -*- Mode: Python -*- +# Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp +# Author: Sam Rushing <ru...@ni...> + +# ====================================================================== +# Copyright 1996 by Sam Rushing +# +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and +# its documentation for any purpose and without fee is hereby +# granted, provided that the above copyright notice appear in all +# copies and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of Sam +# Rushing not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. +# +# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +# NO EVENT SHALL SAM RUSHING 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. +# ====================================================================== + +"""Basic infrastructure for asynchronous socket service clients and servers. + +There are only two ways to have a program on a single processor do "more +than one thing at a time". Multi-threaded programming is the simplest and +most popular way to do it, but there is another very different technique, +that lets you have nearly all the advantages of multi-threading, without +actually using multiple threads. it's really only practical if your program +is largely I/O bound. If your program is CPU bound, then pre-emptive +scheduled threads are probably what you really need. Network servers are +rarely CPU-bound, however. + +If your operating system supports the select() system call in its I/O +library (and nearly all do), then you can use it to juggle multiple +communication channels at once; doing other work while your I/O is taking +place in the "background." Although this strategy can seem strange and +complex, especially at first, it is in many ways easier to understand and +control than multi-threaded programming. The module documented here solves +many of the difficult problems for you, making the task of building +sophisticated high-performance network servers and clients a snap. +""" + +import select +import socket +import sys +import time + +import os +from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \ + ENOTCONN, ESHUTDOWN, EINTR, EISCONN, errorcode + +try: + socket_map +except NameError: + socket_map = {} + +class ExitNow(Exception): + pass + +def read(obj): + try: + obj.handle_read_event() + except ExitNow: + raise + except: + obj.handle_error() + +def write(obj): + try: + obj.handle_write_event() + except ExitNow: + raise + except: + obj.handle_error() + +def _exception (obj): + try: + obj.handle_expt_event() + except ExitNow: + raise + except: + obj.handle_error() + +def readwrite(obj, flags): + try: + if flags & (select.POLLIN | select.POLLPRI): + obj.handle_read_event() + if flags & select.POLLOUT: + obj.handle_write_event() + if flags & (select.POLLERR | select.POLLHUP | select.POLLNVAL): + obj.handle_expt_event() + except ExitNow: + raise + except: + obj.handle_error() + +def poll(timeout=0.0, map=None): + if map is None: + map = socket_map + if map: + r = []; w = []; e = [] + for fd, obj in map.items(): + is_r = obj.readable() + is_w = obj.writable() + if is_r: + r.append(fd) + if is_w: + w.append(fd) + if is_r or is_w: + e.append(fd) + if [] == r == w == e: + time.sleep(timeout) + else: + try: + r, w, e = select.select(r, w, e, timeout) + except select.error, err: + if err[0] != EINTR: + raise + else: + return + + for fd in r: + obj = map.get(fd) + if obj is None: + continue + read(obj) + + for fd in w: + obj = map.get(fd) + if obj is None: + continue + write(obj) + + for fd in e: + obj = map.get(fd) + if obj is None: + continue + _exception(obj) + +def poll2(timeout=0.0, map=None): + # Use the poll() support added to the select module in Python 2.0 + if map is None: + map = socket_map + if timeout is not None: + # timeout is in milliseconds + timeout = int(timeout*1000) + pollster = select.poll() + if map: + for fd, obj in map.items(): + flags = 0 + if obj.readable(): + flags |= select.POLLIN | select.POLLPRI + if obj.writable(): + flags |= select.POLLOUT + if flags: + # Only check for exceptions if object was either readable + # or writable. + flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL + pollster.register(fd, flags) + try: + r = pollster.poll(timeout) + except select.error, err: + if err[0] != EINTR: + raise + r = [] + for fd, flags in r: + obj = map.get(fd) + if obj is None: + continue + readwrite(obj, flags) + +poll3 = poll2 # Alias for backward compatibility + +def loop(timeout=30.0, use_poll=True, map=None, count=None): + if map is None: + map = socket_map + + if use_poll and hasattr(select, 'poll'): + poll_fun = poll2 + else: + poll_fun = poll + + if count is None: + while map: + poll_fun(timeout, map) + + else: + while map and count > 0: + poll_fun(timeout, map) + count = count - 1 + +class dispatcher: + + debug = False + connected = False + accepting = False + closing = False + addr = None + + def __init__(self, sock=None, map=None): + if map is None: + self._map = socket_map + else: + self._map = map + + if sock: + self.set_socket(sock, map) + # I think it should inherit this anyway + self.socket.setblocking(0) + self.connected = True + # XXX Does the constructor require that the socket passed + # be connected? + try: + self.addr = sock.getpeername() + except socket.error: + # The addr isn't crucial + pass + else: + self.socket = None + + def __repr__(self): + status = [self.__class__.__module__+"."+self.__class__.__name__] + if self.accepting and self.addr: + status.append('listening') + elif self.connected: + status.append('connected') + if self.addr is not None: + try: + status.append('%s:%d' % self.addr) + except TypeError: + status.append(repr(self.addr)) + return '<%s at %#x>' % (' '.join(status), id(self)) + + def add_channel(self, map=None): + #self.log_info('adding channel %s' % self) + if map is None: + map = self._map + map[self._fileno] = self + + def del_channel(self, map=None): + fd = self._fileno + if map is None: + map = self._map + if map.has_key(fd): + #self.log_info('closing channel %d:%s' % (fd, self)) + del map[fd] + self._fileno = None + + def create_socket(self, family, type): + self.family_and_type = family, type + self.socket = socket.socket(family, type) + self.socket.setblocking(0) + self._fileno = self.socket + self.add_channel() + + def set_socket(self, sock, map=None): + self.socket = sock +## self.__dict__['socket'] = sock + self._fileno = sock + self.add_channel(map) + + def set_reuse_addr(self): + # try to re-use a server port if possible + try: + self.socket.setsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR, + self.socket.getsockopt(socket.SOL_SOCKET, + socket.SO_REUSEADDR) | 1 + ) + except socket.error: + pass + + # ================================================== + # predicates for select() + # these are used as filters for the lists of sockets + # to pass to select(). + # ================================================== + + def readable(self): + return True + + def writable(self): + return True + + # ================================================== + # socket object methods. + # ================================================== + + def listen(self, num): + self.accepting = True + if os.name == 'nt' and num > 5: + num = 1 + return self.socket.listen(num) + + def bind(self, addr): + self.addr = addr + return self.socket.bind(addr) + + def connect(self, address): + self.connected = False + err = self.socket.connect_ex(address) + # XXX Should interpret Winsock return values + if err in (EINPROGRESS, EALREADY, EWOULDBLOCK): + return + if err in (0, EISCONN): + self.addr = address + self.connected = True + self.handle_connect() + else: + raise socket.error, (err, errorcode[err]) + + def accept(self): + # XXX can return either an address pair or None + try: + conn, addr = self.socket.accept() + return conn, addr + except socket.error, why: + if why[0] == EWOULDBLOCK: + pass + else: + raise + + def send(self, data): + try: + result = self.socket.send(data) + return result + except socket.error, why: + if why[0] == EWOULDBLOCK: + return 0 + else: + raise + return 0 + + def recv(self, buffer_size): + try: + data = self.socket.recv(buffer_size) + if not data: + # a closed connection is indicated by signaling + # a read condition, and having recv() return 0. + self.handle_close() + return '' + else: + return data + except socket.error, why: + # winsock sometimes throws ENOTCONN + if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]: + self.handle_close() + return '' + else: + raise + + def close(self): + self.del_channel() + self.socket.close() + + # cheap inheritance, used to pass all other attribute + # references to the underlying socket object. + def __getattr__(self, attr): + return getattr(self.socket, attr) + + # log and log_info may be overridden to provide more sophisticated + # logging and warning methods. In general, log is for 'hit' logging + # and 'log_info' is for informational, warning and error logging. + + def log(self, message): + sys.stderr.write('log: %s\n' % str(message)) + + def log_info(self, message, type='info'): + if __debug__ or type != 'info': + print '%s: %s' % (type, message) + + def handle_read_event(self): + if self.accepting: + # for an accepting socket, getting a read implies + # that we are connected + if not self.connected: + self.connected = True + self.handle_accept() + elif not self.connected: + self.handle_connect() + self.connected = True + self.handle_read() + else: + self.handle_read() + + def handle_write_event(self): + # getting a write implies that we are connected + if not self.connected: + self.handle_connect() + self.connected = True + self.handle_write() + + def handle_expt_event(self): + self.handle_expt() + + def handle_error(self): + nil, t, v, tbinfo = compact_traceback() + + # sometimes a user repr method will crash. + try: + self_repr = repr(self) + except: + self_repr = '<__repr__(self) failed for object at %0x>' % id(self) + + self.log_info( + 'uncaptured python exception, closing channel %s (%s:%s %s)' % ( + self_repr, + t, + v, + tbinfo + ), + 'error' + ) + self.close() + + def handle_expt(self): + self.log_info('unhandled exception', 'warning') + + def handle_read(self): + self.log_info('unhandled read event', 'warning') + + def handle_write(self): + self.log_info('unhandled write event', 'warning') + + def handle_connect(self): + self.log_info('unhandled connect event', 'warning') + + def handle_accept(self): + self.log_info('unhandled accept event', 'warning') + + def handle_close(self): + self.log_info('unhandled close event', 'warning') + self.close() + +# --------------------------------------------------------------------------- +# adds simple buffered output capability, useful for simple clients. +# [for more sophisticated usage use asynchat.async_chat] +# --------------------------------------------------------------------------- + +class dispatcher_with_send(dispatcher): + + def __init__(self, sock=None, map=None): + dispatcher.__init__(self, sock, map) + self.out_buffer = '' + + def initiate_send(self): + num_sent = 0 + num_sent = dispatcher.send(self, self.out_buffer[:512]) + self.out_buffer = self.out_buffer[num_sent:] + + def handle_write(self): + self.initiate_send() + + def writable(self): + return (not self.connected) or len(self.out_buffer) + + def send(self, data): + if self.debug: + self.log_info('sending %s' % repr(data)) + self.out_buffer = self.out_buffer + data + self.initiate_send() + +# --------------------------------------------------------------------------- +# used for debugging. +# --------------------------------------------------------------------------- + +def compact_traceback(): + t, v, tb = sys.exc_info() + tbinfo = [] + assert tb # Must have a traceback + while tb: + tbinfo.append(( + tb.tb_frame.f_code.co_filename, + tb.tb_frame.f_code.co_name, + str(tb.tb_lineno) + )) + tb = tb.tb_next + + # just to be safe + del tb + + file, function, line = tbinfo[-1] + info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo]) + return (file, function, line), t, v, info + +def close_all(map=None): + if map is None: + map = socket_map + for x in map.values(): + x.socket.close() + map.clear() + +# Asynchronous File I/O: +# +# After a little research (reading man pages on various unixen, and +# digging through the linux kernel), I've determined that select() +# isn't meant for doing asynchronous file i/o. +# Heartening, though - reading linux/mm/filemap.c shows that linux +# supports asynchronous read-ahead. So _MOST_ of the time, the data +# will be sitting in memory for us already when we go to read it. +# +# What other OS's (besides NT) support async file i/o? [VMS?] +# +# Regardless, this is useful for pipes, and stdin/stdout... + +if os.name == 'posix': + import fcntl + + class file_wrapper: + # here we override just enough to make a file + # look like a socket for the purposes of asyncore. + + def __init__(self, fd): + self.fd = fd + + def recv(self, *args): + return os.read(self.fd, *args) + + def send(self, *args): + return os.write(self.fd, *args) + + read = recv + write = send + + def close(self): + os.close(self.fd) + + def fileno(self): + return self.fd + + class file_dispatcher(dispatcher): + + def __init__(self, fd, map=None): + dispatcher.__init__(self, None, map) + self.connected = True + self.set_file(fd) + # set it to non-blocking mode + flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) + flags = flags | os.O_NONBLOCK + fcntl.fcntl(fd, fcntl.F_SETFL, flags) + + def set_file(self, fd): + self._fileno = fd + self.socket = file_wrapper(fd) + self.add_channel() Modified: branches/pbcvm/Lib/os.py =================================================================== --- branches/pbcvm/Lib/os.py 2009-02-24 04:37:39 UTC (rev 6043) +++ branches/pbcvm/Lib/os.py 2009-02-24 04:57:56 UTC (rev 6044) @@ -30,8 +30,8 @@ 'O_RDWR', 'O_SYNC', 'O_TRUNC', 'O_WRONLY', 'R_OK', 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'W_OK', 'X_OK', '_exit', 'access', 'altsep', 'chdir', 'chmod', 'close', 'curdir', 'defpath', - 'environ', 'error', 'fdopen', 'getcwd', 'getegid', 'getenv', - 'geteuid', 'getgid', 'getlogin', 'getlogin', 'getpgrp', + 'environ', 'error', 'fdopen', 'getcwd', 'getcwdu', 'getegid', + 'getenv','geteuid', 'getgid', 'getlogin', 'getlogin', 'getpgrp', 'getpid', 'getppid', 'getuid', 'isatty', 'linesep', 'listdir', 'lseek', 'lstat', 'makedirs', 'mkdir', 'name', 'open', 'pardir', 'path', 'pathsep', 'popen', 'popen2', 'popen3', 'popen4', @@ -83,9 +83,9 @@ """ os_name = sys.registry.getProperty('python.os') if os_name: - return str(os_name) + return asPyString(os_name) - os_name = str(java.lang.System.getProperty('os.name')) + os_name = asPyString(java.lang.System.getProperty('os.name')) os_type = None for type, (patterns, shell_commands) in _os_map.iteritems(): for pattern in patterns: @@ -118,7 +118,7 @@ def isVerbose(self): return False def getCurrentWorkingDirectory(self): - return File(getcwd()) + return File(getcwdu()) def getEnv(self): return ['%s=%s' % (key, val) for key, val in environ.iteritems()] def getInputStream(self): @@ -251,6 +251,13 @@ """ return asPyString(sys.getCurrentWorkingDir()) +def getcwdu(): + """getcwd() -> path + + Return a unicode string representing the current working directory. + """ + return sys.getCurrentWorkingDir() + def chdir(path): """chdir(path) Modified: branches/pbcvm/Lib/platform.py =================================================================== --- branches/pbcvm/Lib/platform.py 2009-02-24 04:37:39 UTC (rev 6043) +++ branches/pbcvm/Lib/platform.py 2009-02-24 04:57:56 UTC (rev 6044) @@ -624,8 +624,9 @@ def _java_getprop(name,default): from java.lang import System + from org.python.core.Py import newString try: - return System.getProperty(name) + return newString(System.getProperty(name)) except: return default @@ -793,7 +794,7 @@ filepath = _abspath(filepath) while os.path.islink(filepath): filepath = os.path.normpath( - os.path.join(filepath,os.readlink(filepath))) + os.path.join(os.path.dirname(filepath),os.readlink(filepath))) return filepath def _syscmd_uname(option,default=''): Modified: branches/pbcvm/Lib/pydoc.py =================================================================== --- branches/pbcvm/Lib/pydoc.py 2009-02-24 04:37:39 UTC (rev 6043) +++ branches/pbcvm/Lib/pydoc.py 2009-02-24 04:57:56 UTC (rev 6044) @@ -1959,13 +1959,17 @@ self.callback = callback self.base.__init__(self, self.address, self.handler) - def serve_until_quit(self): - import select - self.quit = False - while not self.quit: - rd, wr, ex = select.select([self.socket.fileno()], [], [], 1) - if rd: self.handle_request() - + def serve_until_quit(self): + import sys + if sys.platform.startswith('java'): + from select import cpython_compatible_select as select + else: + from select import select + self.quit = False + while not self.quit: + rd, wr, ex = select([self.socket], [], [], 1) + if rd: self.handle_request() + def server_activate(self): self.base.server_activate(self) if self.callback: self.callback(self) @@ -1976,7 +1980,7 @@ try: try: DocServer(port, callback).serve_until_quit() - except (KeyboardInterrupt, select.error): + except (KeyboardInterrupt, select.error): pass finally: if completer: completer() Modified: branches/pbcvm/Lib/socket.py =================================================================== --- branches/pbcvm/Lib/socket.py 2009-02-24 04:37:39 UTC (rev 6043) +++ branches/pbcvm/Lib/socket.py 2009-02-24 04:57:56 UTC (rev 6044) @@ -248,22 +248,6 @@ def close(self): self.jsocket.close() - def shutdownInput(self): - try: - self.jsocket.shutdownInput() - except AttributeError, ax: - pass # Fail silently server sockets - except java.lang.Exception, jlx: - raise _map_exception(jlx) - - def shutdownOutput(self): - try: - self.jsocket.shutdownOutput() - except AttributeError, ax: - pass # Fail silently server sockets - except java.lang.Exception, jlx: - raise _map_exception(jlx) - def getchannel(self): return self.jchannel @@ -340,6 +324,12 @@ else: return self._do_write_nio(buf) + def shutdown(self, how): + if how in (SHUT_RD, SHUT_RDWR): + self.jsocket.shutdownInput() + if how in (SHUT_WR, SHUT_RDWR): + self.jsocket.shutdownOutput() + class _server_socket_impl(_nio_impl): options = { @@ -371,6 +361,13 @@ new_cli_sock = self.jsocket.accept() return _client_socket_impl(new_cli_sock) + def shutdown(self, how): + # This is no-op on java, for server sockets. + # What the user wants to achieve is achieved by calling close() on + # java/jython. But we can't call that here because that would then + # later cause the user explicit close() call to fail + pass + class _datagram_socket_impl(_nio_impl): options = { @@ -384,7 +381,7 @@ def __init__(self, port=None, address=None, reuse_addr=0): self.jchannel = java.nio.channels.DatagramChannel.open() self.jsocket = self.jchannel.socket() - if port: + if port is not None: if address is not None: local_address = java.net.InetSocketAddress(address, port) else: @@ -406,6 +403,13 @@ """ self.jchannel.disconnect() + def shutdown(self, how): + # This is no-op on java, for datagram sockets. + # What the user wants to achieve is achieved by calling close() on + # java/jython. But we can't call that here because that would then + # later cause the user explicit close() call to fail + pass + def _do_send_net(self, byte_array, socket_address, flags): # Need two separate implementations because the java.nio APIs do not support timeouts num_bytes = len(byte_array) @@ -689,6 +693,22 @@ except java.lang.Exception, jlx: raise _map_exception(jlx) + def shutdown(self, how): + assert how in (SHUT_RD, SHUT_WR, SHUT_RDWR) + if not self.sock_impl: + raise error(errno.ENOTCONN, "Transport endpoint is not connected") + try: + self.sock_impl.shutdown(how) + except java.lang.Exception, jlx: + raise _map_exception(jlx) + + def close(self): + try: + if self.sock_impl: + self.sock_impl.close() + except java.lang.Exception, jlx: + raise _map_exception(jlx) + def _config(self): assert self.mode in _permitted_modes if self.sock_impl: @@ -878,15 +898,6 @@ except java.lang.Exception, jlx: raise _map_exception(jlx) - def shutdown(self, how): - if not self.sock_impl: - raise error(errno.ENOTCONN, "Transport endpoint is not connected") - assert how in (SHUT_RD, SHUT_WR, SHUT_RDWR) - if how in (SHUT_RD, SHUT_RDWR): - self.sock_impl.shutdownInput() - if how in (SHUT_WR, SHUT_RDWR): - self.sock_impl.shutdownOutput() - def close(self): try: if self.istream: @@ -1015,13 +1026,6 @@ def __del__(self): self.close() - def close(self): - try: - if self.sock_impl: - self.sock_impl.close() - except java.lang.Exception, jlx: - raise _map_exception(jlx) - _socketmethods = ( 'bind', 'connect', 'connect_ex', 'fileno', 'listen', 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', Copied: branches/pbcvm/Lib/test/bug1239.jar (from rev 6040, trunk/jython/Lib/test/bug1239.jar) =================================================================== (Binary files differ) Copied: branches/pbcvm/Lib/test/check_for_initializer_in_syspath.py (from rev 6040, trunk/jython/Lib/test/check_for_initializer_in_syspath.py) =================================================================== --- branches/pbcvm/Lib/test/check_for_initializer_in_syspath.py (rev 0) +++ branches/pbcvm/Lib/test/check_for_initializer_in_syspath.py 2009-02-24 04:57:56 UTC (rev 6044) @@ -0,0 +1,2 @@ +import sys +assert "/from_SyspathAppendingInitializer_with_love" in sys.path Copied: branches/pbcvm/Lib/test/import_star_from_java.py (from rev 6040, trunk/jython/Lib/test/import_star_from_java.py) =================================================================== --- branches/pbcvm/Lib/te... [truncated message content] |