You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(107) |
Dec
(67) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(76) |
Feb
(125) |
Mar
(72) |
Apr
(13) |
May
(18) |
Jun
(12) |
Jul
(129) |
Aug
(47) |
Sep
(1) |
Oct
(36) |
Nov
(128) |
Dec
(124) |
2002 |
Jan
(59) |
Feb
|
Mar
(14) |
Apr
(14) |
May
(72) |
Jun
(9) |
Jul
(3) |
Aug
(5) |
Sep
(18) |
Oct
(65) |
Nov
(28) |
Dec
(12) |
2003 |
Jan
(10) |
Feb
(2) |
Mar
(4) |
Apr
(33) |
May
(21) |
Jun
(9) |
Jul
(29) |
Aug
(34) |
Sep
(4) |
Oct
(8) |
Nov
(15) |
Dec
(4) |
2004 |
Jan
(26) |
Feb
(12) |
Mar
(11) |
Apr
(9) |
May
(7) |
Jun
|
Jul
(5) |
Aug
|
Sep
(3) |
Oct
(7) |
Nov
(1) |
Dec
(10) |
2005 |
Jan
(2) |
Feb
(72) |
Mar
(16) |
Apr
(39) |
May
(48) |
Jun
(97) |
Jul
(57) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(100) |
Dec
(24) |
2006 |
Jan
(15) |
Feb
(34) |
Mar
(33) |
Apr
(31) |
May
(79) |
Jun
(64) |
Jul
(41) |
Aug
(64) |
Sep
(31) |
Oct
(46) |
Nov
(55) |
Dec
(37) |
2007 |
Jan
(32) |
Feb
(61) |
Mar
(11) |
Apr
(58) |
May
(46) |
Jun
(30) |
Jul
(94) |
Aug
(93) |
Sep
(86) |
Oct
(69) |
Nov
(125) |
Dec
(177) |
2008 |
Jan
(169) |
Feb
(97) |
Mar
(74) |
Apr
(113) |
May
(120) |
Jun
(334) |
Jul
(215) |
Aug
(237) |
Sep
(72) |
Oct
(189) |
Nov
(126) |
Dec
(160) |
2009 |
Jan
(180) |
Feb
(45) |
Mar
(98) |
Apr
(140) |
May
(151) |
Jun
(71) |
Jul
(107) |
Aug
(119) |
Sep
(73) |
Oct
(121) |
Nov
(14) |
Dec
(6) |
2010 |
Jan
(13) |
Feb
(9) |
Mar
(10) |
Apr
(64) |
May
(3) |
Jun
(16) |
Jul
(7) |
Aug
(23) |
Sep
(17) |
Oct
(37) |
Nov
(5) |
Dec
(8) |
2011 |
Jan
(10) |
Feb
(11) |
Mar
(77) |
Apr
(11) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <th...@us...> - 2008-07-14 11:37:11
|
Revision: 4921 http://jython.svn.sourceforge.net/jython/?rev=4921&view=rev Author: thobes Date: 2008-07-14 04:37:10 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Forgot committing the CodeFlag enum file. Added Paths: ----------- branches/advanced/src/org/python/core/CodeFlag.java Added: branches/advanced/src/org/python/core/CodeFlag.java =================================================================== --- branches/advanced/src/org/python/core/CodeFlag.java (rev 0) +++ branches/advanced/src/org/python/core/CodeFlag.java 2008-07-14 11:37:10 UTC (rev 4921) @@ -0,0 +1,101 @@ +package org.python.core; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Set; + +public enum CodeFlag { + /** + * Denotes that the code block uses fast locals. + */ + CO_OPTIMIZED(0x0001), + /** + * Denotes that a new dictionary should be created for the code block. + */ + CO_NEWLOCALS(0x0002), + /** + * The compiled code block has a varargs argument. + */ + CO_VARARGS(0x0004), + /** + * The compiled code block has a varkeyword argument. + */ + CO_VARKEYWORDS(0x0008), + /** + * The compiled code block is a generator code block. + */ + CO_GENERATOR(0x0020), + /** + * Denotes that nested scopes are enabled in the code block. + */ + CO_NESTED(0x0010), + /** + * Denotes that generators are enabled in the code block. + */ + CO_GENERATOR_ALLOWED(0x1000), + /** + * Standard division of integers returns float, truncating division needs to + * be enforced. + */ + CO_FUTURE_DIVISION(0x2000), + /** + * Absolute import. + */ + CO_FUTURE_ABSOLUTE_IMPORT(0x4000), + /** + * With statement. + */ + CO_FUTURE_WITH_STATEMENT(0x8000); + + public final int flag; + private static Iterable<CodeFlag> allFlags = Arrays.asList(values()); + + private CodeFlag(int flag) { + this.flag = flag; + } + + public boolean isFlagBitSetIn(int flags) { + return (flags & flag) != 0; + } + + static Iterable<CodeFlag> parse(final int flags) { + return new Iterable<CodeFlag>() { + + public Iterator<CodeFlag> iterator() { + return new Iterator<CodeFlag>() { + Iterator<CodeFlag> all = allFlags.iterator(); + CodeFlag next = null; + + public boolean hasNext() { + if (next != null) { + return true; + } + while (all.hasNext()) { + CodeFlag flag = all.next(); + if (flag.isFlagBitSetIn(flags)) { + next = flag; + return true; + } + } + return false; + } + + public CodeFlag next() { + if (hasNext()) try { + return next; + } finally { + next = null; + } + throw new IllegalStateException(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + }; + } + + }; + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2008-07-14 11:27:26
|
Revision: 4920 http://jython.svn.sourceforge.net/jython/?rev=4920&view=rev Author: thobes Date: 2008-07-14 04:27:24 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Intermediate commit of the advanced compiler, contains a bunch of stuff: * Restructured the imported stuff from the newcompiler and pyasm work. * Changed CompilerFlags and Future imports to use enums. * Started work with pluggable compiler subsystems by moving functionlity from org.python.core.Py to facade classes with smaller areas of responsibility. This has been done for methods for creating code objects and for compiling, this should also be done for the createion of classes and adaptors. * Moved the responsibility for checking for the PyCF_ONLY_AST to the compile builtin function, this enables more static typing in the internals and moves the resposibilities to where it should be. * Removed all dependancies upon a specific implementation of PyCode (PyTableCode), if we want to be able to do interesting compilation optimizations we have to allow for different code implementations. * Changed the contract for how code objects are loaded to a more indirect aproach where the implementation is in charge of loading itself, this is also for better supporting different implementations of code. * Started an outline of code for iterating over a PyObject in java. {@see org.python.core.Py#iter(PyObject)}, this is just something I thought could be nice for projects integrating Jython, it's probalby broken at the moment... Modified Paths: -------------- branches/advanced/.classpath branches/advanced/compiler/org/python/bytecode/ReferenceResolver.java branches/advanced/compiler/org/python/compiler/advanced/ast/AstToBytecode.java branches/advanced/compiler/org/python/javaagent/InstrumentationProxy.java branches/advanced/src/org/python/Version.java branches/advanced/src/org/python/compiler/ClassConstants.java branches/advanced/src/org/python/compiler/CodeCompiler.java branches/advanced/src/org/python/compiler/Future.java branches/advanced/src/org/python/compiler/Module.java branches/advanced/src/org/python/core/BytecodeLoader.java branches/advanced/src/org/python/core/Py.java branches/advanced/src/org/python/core/PyCode.java branches/advanced/src/org/python/core/PyFrame.java branches/advanced/src/org/python/core/PyFunction.java branches/advanced/src/org/python/core/PyRunnable.java branches/advanced/src/org/python/core/PyTableCode.java branches/advanced/src/org/python/core/__builtin__.java branches/advanced/src/org/python/core/imp.java branches/advanced/src/org/python/util/InteractiveInterpreter.java branches/advanced/src/org/python/util/PythonInterpreter.java branches/advanced/src/org/python/util/jython.java Added Paths: ----------- branches/advanced/compiler/org/python/code/ branches/advanced/compiler/org/python/code/CodeTable.java branches/advanced/compiler/org/python/code/SpecializedCode.java branches/advanced/compiler/org/python/compiler/bytecode/ branches/advanced/compiler/org/python/compiler/bytecode/BytecodeCompiler.java branches/advanced/compiler/org/python/compiler/bytecode/PythonBytecodeCompilingBundle.java branches/advanced/compiler/org/python/hash/ branches/advanced/compiler/org/python/hash/CzechHavasMajewski.java branches/advanced/compiler/org/python/hash/PerfectHash.java branches/advanced/compiler/org/python/hash/Simple.java branches/advanced/compiler/org/python/hash/Single.java branches/advanced/src/org/python/core/ClassFacade.java branches/advanced/src/org/python/core/CodeBootstrap.java branches/advanced/src/org/python/core/CodeFacade.java branches/advanced/src/org/python/core/CodeLoader.java branches/advanced/src/org/python/core/CompilerFacade.java branches/advanced/src/org/python/core/CompilerFlags.java branches/advanced/src/org/python/core/FutureFeature.java branches/advanced/src/org/python/core/ProxyFacade.java branches/advanced/src/org/python/core/PyRunnableBootstrap.java branches/advanced/src/org/python/core/PythonCompiler.java Removed Paths: ------------- branches/advanced/compiler/org/python/compiler/advanced/bytecode/ branches/advanced/compiler/org/python/compiler/bytecode/BytecodeCompiler.java branches/advanced/compiler/org/python/compiler/bytecode/PythonBytecodeCompilingBundle.java branches/advanced/src/org/python/core/CompilerFlags.java Modified: branches/advanced/.classpath =================================================================== --- branches/advanced/.classpath 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/.classpath 2008-07-14 11:27:24 UTC (rev 4920) @@ -9,7 +9,7 @@ <classpathentry kind="src" path="compiler"/> <classpathentry kind="src" path="continuations"/> <classpathentry kind="src" path="interpreter"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/JVM 1.5"/> <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> <classpathentry kind="lib" path="extlibs/jline-0.9.94.jar"/> <classpathentry kind="lib" path="extlibs/junit-3.8.2.jar"/> Modified: branches/advanced/compiler/org/python/bytecode/ReferenceResolver.java =================================================================== --- branches/advanced/compiler/org/python/bytecode/ReferenceResolver.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/compiler/org/python/bytecode/ReferenceResolver.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -10,7 +10,7 @@ import org.python.core.PyObject; import org.python.compiler.advanced.YieldPoint; -import org.python.compiler.advanced.bytecode.BytecodeCompiler; +import org.python.compiler.bytecode.BytecodeCompiler; /** * Added: branches/advanced/compiler/org/python/code/CodeTable.java =================================================================== --- branches/advanced/compiler/org/python/code/CodeTable.java (rev 0) +++ branches/advanced/compiler/org/python/code/CodeTable.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,62 @@ +package org.python.code; + +import org.python.core.PyCode; +import org.python.core.PyFrame; +import org.python.core.PyObject; + +public abstract class CodeTable extends PyCode { + + private final int index; + + protected CodeTable(int tableIndex) { + this.index = tableIndex; + } + + @Override + public PyObject call(PyFrame frame, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject[] args, String[] keywords, PyObject globals, + PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject self, PyObject[] args, String[] keywords, + PyObject globals, PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject globals, PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject arg1, PyObject globals, PyObject[] defaults, + PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject arg1, PyObject arg2, PyObject globals, + PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject arg1, PyObject arg2, PyObject arg3, + PyObject globals, PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + +} Added: branches/advanced/compiler/org/python/code/SpecializedCode.java =================================================================== --- branches/advanced/compiler/org/python/code/SpecializedCode.java (rev 0) +++ branches/advanced/compiler/org/python/code/SpecializedCode.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,56 @@ +package org.python.code; + +import org.python.core.PyCode; +import org.python.core.PyFrame; +import org.python.core.PyObject; + +public abstract class SpecializedCode extends PyCode { + + @Override + public PyObject call(PyFrame frame, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject[] args, String[] keywords, PyObject globals, + PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject self, PyObject[] args, String[] keywords, + PyObject globals, PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject globals, PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject arg1, PyObject globals, PyObject[] defaults, + PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject arg1, PyObject arg2, PyObject globals, + PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + + @Override + public PyObject call(PyObject arg1, PyObject arg2, PyObject arg3, + PyObject globals, PyObject[] defaults, PyObject closure) { + // TODO Auto-generated method stub + return null; + } + +} Modified: branches/advanced/compiler/org/python/compiler/advanced/ast/AstToBytecode.java =================================================================== --- branches/advanced/compiler/org/python/compiler/advanced/ast/AstToBytecode.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/compiler/org/python/compiler/advanced/ast/AstToBytecode.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -79,8 +79,6 @@ import org.python.compiler.advanced.EnvironmentHolder; import org.python.compiler.advanced.EnvironmentInfo; import org.python.compiler.advanced.YieldPoint; -import org.python.compiler.advanced.bytecode.BytecodeCompiler; -import org.python.compiler.advanced.bytecode.PythonBytecodeCompilingBundle; import org.python.core.Py; import org.python.core.PyInteger; import org.python.core.PyLong; @@ -88,6 +86,8 @@ import org.python.core.PyString; import org.python.core.PyUnicode; import org.python.compiler.advanced.CompilerPolicy; +import org.python.compiler.bytecode.BytecodeCompiler; +import org.python.compiler.bytecode.PythonBytecodeCompilingBundle; /** * An AST visitor that feeds a Bytecode visitor. Copied: branches/advanced/compiler/org/python/compiler/bytecode (from rev 4887, branches/advanced/compiler/org/python/compiler/advanced/bytecode) Deleted: branches/advanced/compiler/org/python/compiler/bytecode/BytecodeCompiler.java =================================================================== --- branches/advanced/compiler/org/python/compiler/advanced/bytecode/BytecodeCompiler.java 2008-07-11 11:52:55 UTC (rev 4887) +++ branches/advanced/compiler/org/python/compiler/bytecode/BytecodeCompiler.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -1,32 +0,0 @@ -package org.python.compiler.advanced.bytecode; - -import java.util.Set; - -import org.python.bytecode.BytecodeVisitor; -import org.python.bytecode.Label; -import org.python.compiler.advanced.CompilerFlag; -import org.python.compiler.advanced.CompilerVariable; - -public interface BytecodeCompiler extends BytecodeVisitor { - - void visitResumeTable(Label start, Iterable<Label> entryPoints); - - BytecodeCompiler constructFunction(Iterable<String> closureNames, - int numDefault, - Set<CompilerFlag> flags); - - BytecodeCompiler constructFunction(Iterable<String> closureNames, - int numDefault, - Set<CompilerFlag> flags, - String name); - - BytecodeCompiler constructClass(String name, - Iterable<String> closureNames, - Set<CompilerFlag> flags); - - CompilerVariable storeContextManagerExit(); - - CompilerVariable enterContextManager(); - - void loadVariable(CompilerVariable contextVariable); -} Copied: branches/advanced/compiler/org/python/compiler/bytecode/BytecodeCompiler.java (from rev 4916, branches/advanced/compiler/org/python/compiler/advanced/bytecode/BytecodeCompiler.java) =================================================================== --- branches/advanced/compiler/org/python/compiler/bytecode/BytecodeCompiler.java (rev 0) +++ branches/advanced/compiler/org/python/compiler/bytecode/BytecodeCompiler.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,32 @@ +package org.python.compiler.bytecode; + +import java.util.Set; + +import org.python.bytecode.BytecodeVisitor; +import org.python.bytecode.Label; +import org.python.compiler.advanced.CompilerFlag; +import org.python.compiler.advanced.CompilerVariable; + +public interface BytecodeCompiler extends BytecodeVisitor { + + void visitResumeTable(Label start, Iterable<Label> entryPoints); + + BytecodeCompiler constructFunction(Iterable<String> closureNames, + int numDefault, + Set<CompilerFlag> flags); + + BytecodeCompiler constructFunction(Iterable<String> closureNames, + int numDefault, + Set<CompilerFlag> flags, + String name); + + BytecodeCompiler constructClass(String name, + Iterable<String> closureNames, + Set<CompilerFlag> flags); + + CompilerVariable storeContextManagerExit(); + + CompilerVariable enterContextManager(); + + void loadVariable(CompilerVariable contextVariable); +} Deleted: branches/advanced/compiler/org/python/compiler/bytecode/PythonBytecodeCompilingBundle.java =================================================================== --- branches/advanced/compiler/org/python/compiler/advanced/bytecode/PythonBytecodeCompilingBundle.java 2008-07-11 11:52:55 UTC (rev 4887) +++ branches/advanced/compiler/org/python/compiler/bytecode/PythonBytecodeCompilingBundle.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -1,15 +0,0 @@ -package org.python.compiler.advanced.bytecode; - -import java.util.Set; - -import org.python.compiler.advanced.BytecodeBundle; -import org.python.compiler.advanced.CodeInfo; -import org.python.compiler.advanced.CompilerFlag; - -public interface PythonBytecodeCompilingBundle extends BytecodeBundle { - - BytecodeCompiler compile(String signature, - CodeInfo info, - Set<CompilerFlag> flags, - boolean storeable); -} Copied: branches/advanced/compiler/org/python/compiler/bytecode/PythonBytecodeCompilingBundle.java (from rev 4916, branches/advanced/compiler/org/python/compiler/advanced/bytecode/PythonBytecodeCompilingBundle.java) =================================================================== --- branches/advanced/compiler/org/python/compiler/bytecode/PythonBytecodeCompilingBundle.java (rev 0) +++ branches/advanced/compiler/org/python/compiler/bytecode/PythonBytecodeCompilingBundle.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,15 @@ +package org.python.compiler.bytecode; + +import java.util.Set; + +import org.python.compiler.advanced.BytecodeBundle; +import org.python.compiler.advanced.CodeInfo; +import org.python.compiler.advanced.CompilerFlag; + +public interface PythonBytecodeCompilingBundle extends BytecodeBundle { + + BytecodeCompiler compile(String signature, + CodeInfo info, + Set<CompilerFlag> flags, + boolean storeable); +} Added: branches/advanced/compiler/org/python/hash/CzechHavasMajewski.java =================================================================== --- branches/advanced/compiler/org/python/hash/CzechHavasMajewski.java (rev 0) +++ branches/advanced/compiler/org/python/hash/CzechHavasMajewski.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,94 @@ +package org.python.hash; + +import java.util.Arrays; +import java.util.Random; + +/** + * An implementation of the minimal perfect hash generation algorithm described + * in "An optimal algorithm for generating minimal perfect hash functions", + * Zbigniew J. Czech, George Havas, Bohdan S. Majewski, Information Processing + * Letters, 43(5):257\xD0264, October 1992. + * + * @author Tobias Ivarsson + */ +public class CzechHavasMajewski extends PerfectHash { + private final int[] table; + private final String prefix1; + private final String prefix2; + + /** + * Instantiate a new CzechHavasMajewski minimal perfect hash. Verifies the + * hash to assert the it really is perfect. + * + * @param keys the set of keys used in this hash. + * @param table the lookup table for making the hash perfect. + * @param prefix1 the prefix for the first hash sub function. + * @param prefix2 the prefix for the second hash sub function. + */ + public CzechHavasMajewski(String[] keys, int[] table, String prefix1, + String prefix2) { + super(keys); + if (table == null) { + throw new IllegalArgumentException(""); + } + this.table = table; + this.prefix1 = prefix1; + this.prefix2 = prefix2; + verify(); + } + + @Override + int compute(String key) { + return (table[compute(prefix1, key, table.length)] + table[compute( + prefix2, key, table.length)]) + % table.length; + } + + private static int compute(String prefix, String key, int N) { + return mod((prefix + key).hashCode(), N); + } + + @Override + public String getFunctionRepresentation() { + String tableDef = "table=" + Arrays.toString(table); + String function = "(table[hash(\"" + prefix1 + + "\" + key)] + table[hash(\"" + prefix2 + "\" + key)]) % " + + table.length; + return tableDef + "; " + function; + } + + static class RandomHash { + private static final Random random = new Random(); + private static final char[] chars = ("ABCDEFGHIJKLMNOPQRSTWXYZ" + + "abcdefghijklmnopqrstuvwxyz" + "1234567890").toCharArray(); + private final int N; + private final String prefix1; + private final String prefix2; + + RandomHash(int N) { + this.N = N; + this.prefix1 = randomString(10); + this.prefix2 = randomString(10); + } + + boolean computeConnection(String key, Graph graph, int value) { + int hash1 = CzechHavasMajewski.compute(prefix1, key, N); + int hash2 = CzechHavasMajewski.compute(prefix2, key, N); + return graph.connect(hash1, hash2, value); + } + + PerfectHash makePerfectHash(String[] keys, Graph graph) { + return new CzechHavasMajewski(keys, graph.values(), prefix1, + prefix2); + } + + private static String randomString(int size) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < size; i++) { + builder.append(chars[random.nextInt(chars.length)]); + } + return builder.toString(); + } + } + +} Added: branches/advanced/compiler/org/python/hash/PerfectHash.java =================================================================== --- branches/advanced/compiler/org/python/hash/PerfectHash.java (rev 0) +++ branches/advanced/compiler/org/python/hash/PerfectHash.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,303 @@ +package org.python.hash; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Stack; + +import org.python.hash.CzechHavasMajewski.RandomHash; + +/** + * Base class for the perfect hash function implementations in this package. + * + * Also contains a factory method for computing the the most appropriate + * implementation of the hash functions in this package. + * + * @author Tobias Ivarsson + */ +public abstract class PerfectHash { + + /** + * Compute the hash code for a given key from the key set. + * + * @param key the key to generate the hash code for. + * @return the hash code for the given key in this perfect hash. + * @throws IllegalArgumentException if the given key is not in the key set + * for the perfect hash. + */ + public int hashCode(String key) { + int hashCode = compute(key); + if (keys[hashCode].equals(key)) { + return hashCode; + } else { + throw new IllegalArgumentException("No such key!"); + } + } + + /** + * Compute the hash code for a given key. If the key is not in the key set, + * return a fallback value + * + * @param key the key to compute the hash code for. + * @param fallback the fallback value. + * @return the hash code for the given key in this perfect hash, or the + * fallback value if the given key is not in the key set of this + * perfect hash. + */ + public int hashCodeWithFallback(String key, int fallback) { + int hashCode = compute(key); + if (keys[hashCode].equals(key)) { + return hashCode; + } else { + return fallback; + } + } + + /** + * Generate a perfect hash function for a given set of keys. + * + * @param keys the keys to generate the perfect hash function for. + * @return the perfect hash function for the given key set. + */ + public static PerfectHash generatePerfectHash(String... keys) { + if (keys == null || keys.length == 0) { + throw new IllegalArgumentException(""); + } + PerfectHash hash; + if (keys.length == 1) { + return new Single(keys[0]); + } + hash = generateSimple(keys); + if (hash != null) { + return hash; + } + hash = generateCzechHavasMajewski(keys); + if (hash != null) { + return hash; + } + throw new IllegalArgumentException( + "failed to compute a perfect hash for the given keys."); + } + + PerfectHash(String[] keys) { + if (keys == null || keys.length == 0) { + throw new IllegalArgumentException( + "No keys specified for the hash function."); + } + this.keys = keys; + } + + private final String[] keys; + + abstract int compute(String key); + + void verify() { + for (String key : keys) { + if (hashCodeWithFallback(key, -1) == -1) { + throw new IllegalArgumentException( + "The specified arguments does not define a perfect hash."); + } + } + } + + private static PerfectHash generateSimple(String[] keys) { + int[] table = new int[keys.length]; + Arrays.fill(table, -1); + for (int i = 0; i < keys.length; i++) { + String key = keys[i]; + int hash = mod(key.hashCode(), table.length); + if (table[hash] != -1) { + return null; + } + table[hash] = i; + } + return new Simple(keys, table); + } + + private static PerfectHash generateCzechHavasMajewski(String[] keys) { + double c = 1.1; + int times = 0; + while (true) { + int N = (int) (keys.length * c); + times += 1; + if ((times % 5) == 0) { + c += 0.1; + } + if (times == 10000) { + return null; + } + RandomHash hash = new RandomHash(N); + Graph G = new Graph(N); + boolean ok = true; + for (int i = 0; ok && (i < keys.length); i++) { + ok &= hash.computeConnection(keys[i], G, i); + } + if (ok & G.isAcyclic()) { + return hash.makePerfectHash(keys, G); + } + } + } + + private static class Edge { + final int start; + final int end; + private final int hash; + + Edge(int start, int end, int N) { + if (end < start) { + int temp = start; + start = end; + end = temp; + } + this.start = start; + this.end = end; + hash = end * N + start; + } + + Edge(int start, int end) { + this.start = start; + this.end = end; + this.hash = 0; + } + + @Override + public int hashCode() { + return hash; + } + + @Override + public boolean equals(Object other) { + if (other instanceof Edge) { + Edge edge = (Edge) other; + return edge.start == start && edge.end == end; + } else { + return false; + } + } + } + + static class Graph { + private enum VertexState { + UNVISITED, VISITED + } + + private final Map<Edge, Integer> edgeValues = new HashMap<Edge, Integer>(); + private final Map<Integer, Set<Integer>> reachable = new HashMap<Integer, Set<Integer>>(); + private final int num_vertices; + + private Graph(int N) { + this.num_vertices = N; + } + + private Set<Integer> getReachable(int vertex) { + Set<Integer> result = reachable.get(vertex); + if (result == null) { + reachable.put(vertex, result = new HashSet<Integer>()); + } + return result; + } + + boolean connect(int first, int second, int value) { + edgeValues.put(new Edge(first, second, num_vertices), value); + return getReachable(first).add(second) + && getReachable(second).add(first); + } + + int[] values() { + return dfs(new ValueBuilder(num_vertices)).values; + } + + private boolean isAcyclic() { + return dfs(new CycleTest()).acyclic; + } + + private <T extends Searcher> T dfs(T action) { + VertexState[] state = new VertexState[num_vertices]; + Arrays.fill(state, VertexState.UNVISITED); + for (int i = 0; i < num_vertices; i++) { + if (state[i] == VertexState.UNVISITED) { + Stack<Edge> visitStack = new Stack<Edge>(); + visitStack.push(new Edge(-1, i)); + while (!visitStack.isEmpty()) { + Edge edge = visitStack.pop(); + state[edge.end] = VertexState.VISITED; // OR rather + // "VISITING" + for (int neighbour : getReachable(edge.end)) { + if (neighbour != edge.start) { + if (state[neighbour] == VertexState.UNVISITED) { + visitStack.push(new Edge(edge.end, + neighbour)); + action.apply(edge.end, neighbour, + edgeValues); + } else { + action.fail(); + return action; + } + } + } + state[edge.end] = VertexState.VISITED; + } + } + } + return action; + } + } + + private static abstract class Searcher { + abstract void fail(); + + void apply(int vertex, int neighbour, Map<Edge, Integer> edgeValues) { + } + } + + private static class CycleTest extends Searcher { + boolean acyclic = true; + + @Override + void fail() { + acyclic = false; + } + } + + private static class ValueBuilder extends Searcher { + int[] values; + + ValueBuilder(int N) { + values = new int[N]; + Arrays.fill(values, 0); + } + + @Override + void fail() { + values = null; + } + + @Override + void apply(int vertex, int neighbour, Map<Edge, Integer> edgeValues) { + int newValue = edgeValues.get(new Edge(vertex, neighbour, + values.length)) + - values[vertex]; + values[neighbour] = mod(newValue, values.length); + } + } + + @Override + public final String toString() { + return "PerfectHash{type=" + getClass().getSimpleName() + "; " + + getFunctionRepresentation() + "}"; + } + + abstract String getFunctionRepresentation(); + + static int mod(int value, int n) { + value %= n; + if (value < 0) { + return n + value; + } else { + return value; + } + } + +} Added: branches/advanced/compiler/org/python/hash/Simple.java =================================================================== --- branches/advanced/compiler/org/python/hash/Simple.java (rev 0) +++ branches/advanced/compiler/org/python/hash/Simple.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,42 @@ +package org.python.hash; + +import java.util.Arrays; + +/** + * A simple implementation of a minimal perfect hash, usable in the cases where + * the standard {@link String#hashCode()} yields a perfect hash for the set of + * keys. + * + * @author Tobias Ivarsson + */ +public class Simple extends PerfectHash { + + private final int[] table; + + /** + * Instantiate a new minimal perfect hash that uses + * {@link String#hashCode()}. Verifies the hash to assert the it really is + * perfect. + * + * @param keys the set of keys used in this hash. + * @param table the reordering table for the hash. + */ + public Simple(String[] keys, int[] table) { + super(keys); + this.table = table; + verify(); + } + + @Override + int compute(String key) { + return table[mod(key.hashCode(), table.length)]; + } + + @Override + String getFunctionRepresentation() { + String tableDef = "table=" + Arrays.toString(table); + String body = "table[hash(key) % table.length]"; + return tableDef + "; " + body; + } + +} Added: branches/advanced/compiler/org/python/hash/Single.java =================================================================== --- branches/advanced/compiler/org/python/hash/Single.java (rev 0) +++ branches/advanced/compiler/org/python/hash/Single.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,31 @@ +package org.python.hash; + +/** + * A simple implementation of a minimal perfect hash for the cases where the key + * set is minimal. + * + * @author Tobias Ivarsson + */ +public class Single extends PerfectHash { + + /** + * Instantiate a new single value minimal perfect hash. Verifies the hash to + * assert the it really is perfect. + * + * @param key the key used in this hash. + */ + public Single(String key) { + super(new String[] { key }); + } + + @Override + int compute(String key) { + return 0; + } + + @Override + String getFunctionRepresentation() { + return "0"; + } + +} \ No newline at end of file Modified: branches/advanced/compiler/org/python/javaagent/InstrumentationProxy.java =================================================================== --- branches/advanced/compiler/org/python/javaagent/InstrumentationProxy.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/compiler/org/python/javaagent/InstrumentationProxy.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -13,7 +13,6 @@ private static volatile InstrumentationProxy proxy; private final Instrumentation instrumentation; private static final Runnable attacher = new Runnable() { - @Override public void run() { // TODO: add means to attach an agent to this, already running, JVM } Modified: branches/advanced/src/org/python/Version.java =================================================================== --- branches/advanced/src/org/python/Version.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/src/org/python/Version.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -3,8 +3,14 @@ import java.io.InputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; import java.util.Properties; +import java.util.Set; +import org.python.core.CodeFlag; + /** * Jython version information. * @@ -36,6 +42,10 @@ /** Short version of branch, e.g. asm. */ public static String SHORT_BRANCH; + /** The flags that are set by default in a code object. */ + private static final Collection<CodeFlag> defaultCodeFlags = Arrays.asList( + CodeFlag.CO_NESTED, CodeFlag.CO_GENERATOR_ALLOWED); + private static final String headURL = "$HeadURL$"; @@ -144,4 +154,8 @@ public static String getVersion() { return String.format("%.80s (%.80s) %.80s", PY_VERSION, getBuildInfo(), getVM()); } + + public static Set<CodeFlag> getDefaultCodeFlags() { + return EnumSet.copyOf(defaultCodeFlags); + } } Modified: branches/advanced/src/org/python/compiler/ClassConstants.java =================================================================== --- branches/advanced/src/org/python/compiler/ClassConstants.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/src/org/python/compiler/ClassConstants.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -1,21 +1,34 @@ package org.python.compiler; +import org.python.core.PyCode; +import org.python.core.PyComplex; +import org.python.core.PyException; +import org.python.core.PyFloat; +import org.python.core.PyFrame; +import org.python.core.PyFunctionTable; +import org.python.core.PyInteger; +import org.python.core.PyLong; +import org.python.core.PyObject; +import org.python.core.PyProxy; +import org.python.core.PyString; +import org.python.core.PyUnicode; +import org.python.objectweb.asm.Type; + public interface ClassConstants { - final static String $pyObj = "Lorg/python/core/PyObject;"; - final static String $pyObjArr = "[Lorg/python/core/PyObject;"; - final static String $pyStr = "Lorg/python/core/PyString;"; - final static String $pyUnicode = "Lorg/python/core/PyUnicode;"; - final static String $pyExc = "Lorg/python/core/PyException;"; - final static String $pyFrame = "Lorg/python/core/PyFrame;"; - final static String $pyCode = "Lorg/python/core/PyCode;"; - final static String $pyInteger = "Lorg/python/core/PyInteger;"; - final static String $pyLong = "Lorg/python/core/PyLong;"; - final static String $pyFloat = "Lorg/python/core/PyFloat;"; - final static String $pyComplex = "Lorg/python/core/PyComplex;"; - final static String $pyRunnable = "Lorg/python/core/PyRunnable;"; - final static String $pyFuncTbl = "Lorg/python/core/PyFunctionTable;"; - final static String $pyProxy = "Lorg/python/core/PyProxy;"; + final static String $pyObj = Type.getDescriptor(PyObject.class); + final static String $pyObjArr = "[" + $pyObj; + final static String $pyStr = Type.getDescriptor(PyString.class); + final static String $pyUnicode = Type.getDescriptor(PyUnicode.class); + final static String $pyExc = Type.getDescriptor(PyException.class); + final static String $pyFrame = Type.getDescriptor(PyFrame.class); + final static String $pyCode = Type.getDescriptor(PyCode.class); + final static String $pyInteger = Type.getDescriptor(PyInteger.class); + final static String $pyLong = Type.getDescriptor(PyLong.class); + final static String $pyFloat = Type.getDescriptor(PyFloat.class); + final static String $pyComplex = Type.getDescriptor(PyComplex.class); + final static String $pyFuncTbl = Type.getDescriptor(PyFunctionTable.class); + final static String $pyProxy = Type.getDescriptor(PyProxy.class); final static String $obj = "Ljava/lang/Object;"; final static String $objArr = "[Ljava/lang/Object;"; Modified: branches/advanced/src/org/python/compiler/CodeCompiler.java =================================================================== --- branches/advanced/src/org/python/compiler/CodeCompiler.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/src/org/python/compiler/CodeCompiler.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -1308,7 +1308,7 @@ case FloorDiv: name = "_floordiv"; break; } - if (node.op == operatorType.Div && module.getFutures().areDivisionOn()) { + if (node.op == operatorType.Div && module.getFutures().isDivisionOn()) { name = "_truediv"; } code.invokevirtual("org/python/core/PyObject", name, "(" + $pyObj + ")" + $pyObj); @@ -1353,7 +1353,7 @@ case BitAnd: name = "_iand"; break; case FloorDiv: name = "_ifloordiv"; break; } - if (node.op == operatorType.Div && module.getFutures().areDivisionOn()) { + if (node.op == operatorType.Div && module.getFutures().isDivisionOn()) { name = "_itruediv"; } code.invokevirtual("org/python/core/PyObject", name, "(" + $pyObj + ")" + $pyObj); Modified: branches/advanced/src/org/python/compiler/Future.java =================================================================== --- branches/advanced/src/org/python/compiler/Future.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/src/org/python/compiler/Future.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -2,55 +2,28 @@ package org.python.compiler; +import java.util.EnumSet; +import java.util.Set; + import org.python.antlr.*; import org.python.antlr.ast.*; import org.python.antlr.ast.Module; +import org.python.core.CodeFlag; +import org.python.core.FutureFeature; public class Future { + + private final Set<FutureFeature> features = EnumSet.noneOf(FutureFeature.class); - private boolean division = false; - private boolean with_statement = false; - private boolean absolute_import = false; - - private static final String FUTURE = "__future__"; - private boolean check(ImportFrom cand) throws Exception { - if (!cand.module.equals(FUTURE)) + if (!cand.module.equals(FutureFeature.MODULE_NAME)) return false; - int n = cand.names.length; - if (n == 0) { + if (cand.names.length == 0) { throw new ParseException( "future statement does not support import *",cand); } - for (int i = 0; i < n; i++) { - String feature = cand.names[i].name; - // *known* features - if (feature.equals("nested_scopes")) { - continue; - } - if (feature.equals("division")) { - division = true; - continue; - } - if (feature.equals("generators")) { - continue; - } - if (feature.equals("with_statement")) { - with_statement = true; - continue; - } - if (feature.equals("absolute_import")) { - absolute_import = true; - continue; - } - if (feature.equals("braces")) { - throw new ParseException("not a chance"); - } - if (feature.equals("GIL") || feature.equals("global_interpreter_lock")) { - throw new ParseException("Never going to happen!"); - } - throw new ParseException("future feature "+feature+ - " is not defined",cand); + for (aliasType feature : cand.names) { + FutureFeature.addFeature(feature.name, features); } return true; } @@ -59,8 +32,8 @@ org.python.core.CompilerFlags cflags) throws Exception { - if (cflags != null) { - division = cflags.division; + if (cflags != null && cflags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) { + FutureFeature.division.addTo(features); } int beg = 0; stmtType[] suite = null; @@ -86,33 +59,33 @@ } if (cflags != null) { - cflags.division = cflags.division || division; + for (FutureFeature feature : features) { + feature.setFlag(cflags); + } } - if (cflags != null) { - cflags.with_statement = cflags.with_statement || with_statement; - } - if (cflags != null) { - cflags.absolute_import = cflags.absolute_import || absolute_import; - } } public static void checkFromFuture(ImportFrom node) throws Exception { if (node.from_future_checked) return; - if (node.module.equals(FUTURE)) { + if (node.module.equals(FutureFeature.MODULE_NAME)) { throw new ParseException("from __future__ imports must occur " + "at the beginning of the file",node); } node.from_future_checked = true; } - public boolean areDivisionOn() { - return division; + public boolean isDivisionOn() { + return features.contains(FutureFeature.division); } public boolean withStatementSupported() { - return with_statement; + return features.contains(FutureFeature.with_statement); } + + public boolean useAbsoluteImport() { + return features.contains(FutureFeature.absolute_import); + } } Modified: branches/advanced/src/org/python/compiler/Module.java =================================================================== --- branches/advanced/src/org/python/compiler/Module.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/src/org/python/compiler/Module.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -10,9 +10,14 @@ import org.python.objectweb.asm.Label; import org.python.objectweb.asm.Opcodes; +import org.python.objectweb.asm.Type; +import org.python.core.CodeBootstrap; +import org.python.core.CodeFlag; +import org.python.core.CodeLoader; import org.python.core.CompilerFlags; import org.python.core.Py; import org.python.core.PyException; +import org.python.core.PyRunnableBootstrap; import org.python.antlr.ParseException; import org.python.antlr.PythonTree; import org.python.antlr.ast.Suite; @@ -261,7 +266,7 @@ c.iconst(moreflags); - c.invokestatic("org/python/core/Py", "newCode", "(I" + $strArr + $str + $str + "IZZ" + $pyFuncTbl + "I" + $strArr + $strArr + "II)" + $pyCode); + c.invokestatic("org/python/core/CodeFacade", "newCode", "(I" + $strArr + $str + $str + "IZZ" + $pyFuncTbl + "I" + $strArr + $strArr + "II)" + $pyCode); c.putstatic(module.classfile.name, name, $pyCode); } } @@ -469,17 +474,17 @@ code.jy_npurecell = scope.jy_npurecell; if (compiler.optimizeGlobals) { - code.moreflags |= org.python.core.PyTableCode.CO_OPTIMIZED; + code.moreflags |= CodeFlag.CO_OPTIMIZED.flag; } if (compiler.my_scope.generator) { - code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR; + code.moreflags |= CodeFlag.CO_GENERATOR.flag; } if (cflags != null) { - if (cflags.generator_allowed) { - code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR_ALLOWED; + if (cflags.isFlagSet(CodeFlag.CO_GENERATOR_ALLOWED)) { + code.moreflags |= CodeFlag.CO_GENERATOR_ALLOWED.flag; } - if (cflags.division) { - code.moreflags |= org.python.core.PyTableCode.CO_FUTUREDIVISION; + if (cflags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) { + code.moreflags |= CodeFlag.CO_FUTURE_DIVISION.flag; } } @@ -509,10 +514,26 @@ c.dup(); c.ldc(classfile.name); c.invokespecial(classfile.name, "<init>", "(" + $str + ")V"); + c.invokevirtual(classfile.name, "getMain", "()" + $pyCode); + String bootstrap = Type.getDescriptor(CodeBootstrap.class); + c.invokestatic(Type.getInternalName(CodeLoader.class), + CodeLoader.SIMPLE_FACTORY_METHOD_NAME, + "(" + $pyCode + ")" + bootstrap); c.aload(0); - c.invokestatic("org/python/core/Py", "runMain", "(" + $pyRunnable + $strArr + ")V"); + c.invokestatic("org/python/core/Py", "runMain", "(" + bootstrap + $strArr + ")V"); c.return_(); } + + public void addBootstrap() throws IOException { + Code c = classfile.addMethod(CodeLoader.GET_BOOTSTRAP_METHOD_NAME, + "()" + Type.getDescriptor(CodeBootstrap.class), + ACC_PUBLIC | ACC_STATIC); + c.ldc(Type.getType("L" + classfile.name + ";")); + c.invokestatic(Type.getInternalName(PyRunnableBootstrap.class), + PyRunnableBootstrap.REFLECTION_METHOD_NAME, + "(" + $clss + ")" + Type.getDescriptor(CodeBootstrap.class)); + c.areturn(); + } public void addConstants(Code c) throws IOException { classfile.addField("self", "L"+classfile.name+";", @@ -567,6 +588,7 @@ addInit(); addRunnable(); addMain(); + addBootstrap(); addFunctions(); Modified: branches/advanced/src/org/python/core/BytecodeLoader.java =================================================================== --- branches/advanced/src/org/python/core/BytecodeLoader.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/src/org/python/core/BytecodeLoader.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -63,9 +63,12 @@ public static PyCode makeCode(String name, byte[] data, String filename) { try { Class<?> c = makeClass(name, data); + return CodeLoader.loadCode(c, name, filename); + /* Object o = c.getConstructor(new Class[] {String.class}) .newInstance(new Object[] {filename}); return ((PyRunnable)o).getMain(); + */ } catch (Exception e) { throw Py.JavaError(e); } Added: branches/advanced/src/org/python/core/ClassFacade.java =================================================================== --- branches/advanced/src/org/python/core/ClassFacade.java (rev 0) +++ branches/advanced/src/org/python/core/ClassFacade.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,12 @@ +package org.python.core; + +/** + * For classes that inherit from java-classes: + * {@link org.python.core.Py#initProxy(org.python.core.PyProxy, String, String, Object[])} + * + * For creating classes: {@link org.python.core.Py#makeClass} + * Linked to from: {@link org.python.compiler.CodeCompiler} + */ +public class ClassFacade { + +} Added: branches/advanced/src/org/python/core/CodeBootstrap.java =================================================================== --- branches/advanced/src/org/python/core/CodeBootstrap.java (rev 0) +++ branches/advanced/src/org/python/core/CodeBootstrap.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,7 @@ +package org.python.core; + +public interface CodeBootstrap { + + PyCode loadCode(CodeLoader loader); + +} Added: branches/advanced/src/org/python/core/CodeFacade.java =================================================================== --- branches/advanced/src/org/python/core/CodeFacade.java (rev 0) +++ branches/advanced/src/org/python/core/CodeFacade.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,50 @@ +package org.python.core; + + +public class CodeFacade { + public static PyCode newCode(int argcount, String varnames[], + String filename, String name, + boolean args, boolean keywords, + PyFunctionTable funcs, int func_id, + String[] cellvars, String[] freevars, + int npurecell, int moreflags) { + return new PyTableCode(argcount, varnames, + filename, name, 0, args, keywords, funcs, + func_id, cellvars, freevars, npurecell, + moreflags); + } + + public static PyCode newCode(int argcount, String varnames[], + String filename, String name, + int firstlineno, + boolean args, boolean keywords, + PyFunctionTable funcs, int func_id, + String[] cellvars, String[] freevars, + int npurecell, int moreflags) { + return new PyTableCode(argcount, varnames, + filename, name, firstlineno, args, keywords, + funcs, func_id, cellvars, freevars, npurecell, + moreflags); + } + + // -- + public static PyCode newCode(int argcount, String varnames[], + String filename, String name, + boolean args, boolean keywords, + PyFunctionTable funcs, int func_id) { + return new PyTableCode(argcount, varnames, + filename, name, 0, args, keywords, funcs, + func_id); + } + + public static PyCode newCode(int argcount, String varnames[], + String filename, String name, + int firstlineno, + boolean args, boolean keywords, + PyFunctionTable funcs, int func_id) { + return new PyTableCode(argcount, varnames, + filename, name, firstlineno, args, keywords, + funcs, func_id); + } + +} Added: branches/advanced/src/org/python/core/CodeLoader.java =================================================================== --- branches/advanced/src/org/python/core/CodeLoader.java (rev 0) +++ branches/advanced/src/org/python/core/CodeLoader.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,63 @@ +package org.python.core; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.python.compiler.ClassConstants; +import org.python.objectweb.asm.Type; + +public final class CodeLoader { + + public static final String GET_BOOTSTRAP_METHOD_NAME = "getCodeBootstrap"; + public final String name; + public final String filename; + + private CodeLoader(String name, String filename) { + this.name = name; + this.filename = filename; + } + + public static boolean canLoad(Class<?> cls) { + try { + Method getBootstrap = cls.getMethod(GET_BOOTSTRAP_METHOD_NAME); + return Modifier.isStatic(getBootstrap.getModifiers()); + } catch (Exception e) { + return false; + } + } + + public static PyCode loadCode(Class<?> cls, String name, String filename) + throws SecurityException, NoSuchMethodException, + IllegalArgumentException, IllegalAccessException, + InvocationTargetException { + Method getBootstrap = cls.getMethod(GET_BOOTSTRAP_METHOD_NAME); + CodeBootstrap bootstrap = (CodeBootstrap) getBootstrap.invoke(null); + return loadCode(bootstrap, name, filename); + } + + public static PyCode loadCode(Class<?> cls) throws SecurityException, + IllegalArgumentException, NoSuchMethodException, + IllegalAccessException, InvocationTargetException { + return loadCode(cls, null, null); + } + + public static PyCode loadCode(CodeBootstrap bootstrap, String name, + String filename) { + return bootstrap.loadCode(new CodeLoader(name, filename)); + } + + public static PyCode loadCode(CodeBootstrap bootstrap) { + return loadCode(bootstrap, null, null); + } + + public static final String SIMPLE_FACTORY_METHOD_NAME = "createSimpleBootstrap"; + + public static CodeBootstrap createSimpleBootstrap(final PyCode code) { + return new CodeBootstrap() { + public PyCode loadCode(CodeLoader loader) { + return code; + } + }; + } +} Added: branches/advanced/src/org/python/core/CompilerFacade.java =================================================================== --- branches/advanced/src/org/python/core/CompilerFacade.java (rev 0) +++ branches/advanced/src/org/python/core/CompilerFacade.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,91 @@ +package org.python.core; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStream; + +import org.python.compiler.Module; +import org.python.core.util.StringUtil; +import org.python.antlr.ast.modType; + +/** + * Facade for different compiler implementations. + * + * The static methods of this class act as a Facade for the compiler subsystem. + * This is so that the rest of Jython (even generated code) can statically link + * to the static interface of this class, while allowing for different + * implementations of the various components of the compiler subsystem. + * + * @author Tobias Ivarsson + */ +public class CompilerFacade { + + private static int nameindex = 0; + + static synchronized String newClassName() { + String name = "org.python.pycode._pyx" + nameindex; + nameindex += 1; + return name; + } + + private static PythonCompiler compiler; + + // w/o compiler-flags + + public static PyCode compile(InputStream istream, String filename, + String type) { + return compile_flags(istream, filename, type, null); + } + + // with compiler-flags + + static PyCode compile_flags(modType node, String name, + String filename, boolean linenumbers, boolean printResults, + CompilerFlags cflags) { + try { + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + Module.compile(node, ostream, name, filename, linenumbers, + printResults, false, cflags); + + Py.saveClassFile(name, ostream); + + return BytecodeLoader.makeCode(name, ostream.toByteArray(), + filename); + } catch (Throwable t) { + throw ParserFacade.fixParseError(null, t, filename); + } + } + + public static PyCode compile_flags(InputStream istream, String filename, + String type, CompilerFlags cflags) { + modType node = ParserFacade.parse(istream, type, filename, cflags); + boolean printResults = false; + if (type.equals("single")) printResults = true; + return compile_flags(node, newClassName(), filename, true, printResults, + cflags); + } + + public static PyCode compile_flags(String data, String filename, + String type, CompilerFlags cflags) { + return compile_flags(new ByteArrayInputStream(StringUtil.toBytes(data + + "\n\n")), filename, type, cflags); + } + + public static PyObject compile_command_flags(String string, + String filename, String kind, CompilerFlags cflags, + boolean stdprompt) { + modType node = ParserFacade.partialParse(string + "\n", kind, filename, + cflags, stdprompt); + + if (node == null) return Py.None; + return compile_flags(node, newClassName(), filename, true, true, cflags); + } + + public static void compile(modType node, OutputStream ostream, String name, + String filename, boolean linenumbers, boolean printResults, + boolean setFile, CompilerFlags cflags) throws Exception { + org.python.compiler.Module.compile(node, ostream, name, filename, + linenumbers, printResults, setFile, cflags); + } +} Deleted: branches/advanced/src/org/python/core/CompilerFlags.java =================================================================== --- branches/advanced/src/org/python/core/CompilerFlags.java 2008-07-14 11:03:54 UTC (rev 4919) +++ branches/advanced/src/org/python/core/CompilerFlags.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -1,44 +0,0 @@ - -package org.python.core; - -public class CompilerFlags { - - public boolean nested_scopes = true; - public boolean division; - public boolean generator_allowed = true; - public boolean only_ast = false; - public boolean with_statement = false; - public boolean absolute_import = false; - - public String encoding; - - public CompilerFlags(){} - - public CompilerFlags(int co_flags) { - if ((co_flags & org.python.core.PyTableCode.CO_NESTED) != 0) { - this.nested_scopes = true; - } - if ((co_flags & org.python.core.PyTableCode.CO_FUTUREDIVISION) != 0) { - this.division = true; - } - if ((co_flags & org.python.core.PyTableCode.CO_GENERATOR_ALLOWED) != 0) { - this.generator_allowed = true; - } - if ((co_flags & org.python.core.PyTableCode.CO_FUTURE_ABSOLUTE_IMPORT) != 0) { - this.absolute_import = true; - } - if ((co_flags & org.python.core.PyTableCode.CO_WITH_STATEMENT) != 0) { - this.with_statement = true; - } - if ((co_flags & org.python.core.PyTableCode.PyCF_ONLY_AST) != 0) { - this.only_ast = true; - } - } - - public String toString() { - return String.format("CompilerFlags[division=%s nested_scopes=%s generators=%s " - + "with_statement=%s absolute_import=%s]", division, nested_scopes, generator_allowed, - with_statement, absolute_import); - } - -} Added: branches/advanced/src/org/python/core/CompilerFlags.java =================================================================== --- branches/advanced/src/org/python/core/CompilerFlags.java (rev 0) +++ branches/advanced/src/org/python/core/CompilerFlags.java 2008-07-14 11:27:24 UTC (rev 4920) @@ -0,0 +1,65 @@ +package org.python.core; + +import java.util.Set; + +import org.python.Version; + +public class CompilerFlags { + // XXX: I'm not positive that this is the right place for this constant. + public static final int PyCF_ONLY_AST = 0x0400; + @Deprecated + public boolean only_ast = false; + + public String encoding; + private final Set<CodeFlag> flags = Version.getDefaultCodeFlags(); + + public CompilerFlags() { + } + + public CompilerFlags(int co_flags) { + for (CodeFlag flag : CodeFlag.parse(co_flags)) { + setFlag(flag); + } + // This is deprecated + if ((co_flags & PyCF_ONLY_AST) != 0) { + this.only_ast = true; + } + } + + public void setFlag(CodeFlag flag) { + flags.add(flag); + } + + public boolean isFlagSet(CodeFlag flag) { + return flags.contains(flag); + } + + public String toString() { + return String.format( + "CompilerFlags[division=%s nested_scopes=%s generators=%s " + + "with_statement=%s absolute_import=%s]", + isFlagSet(CodeFlag.CO_FUTURE_DIVISION), + isFlagSet(CodeFlag.CO_NESTED), + isFlagSet(CodeFlag.CO_GENERATOR_ALLOWED), + ... [truncated message content] |
From: <zy...@us...> - 2008-07-14 11:03:56
|
Revision: 4919 http://jython.svn.sourceforge.net/jython/?rev=4919&view=rev Author: zyasoft Date: 2008-07-14 04:03:54 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Removed inapplicable test due to different algorithm in expandtabs which cannot overflow in Jython Modified Paths: -------------- branches/asm/Lib/test/string_tests.py branches/asm/Lib/test/test_str.py Modified: branches/asm/Lib/test/string_tests.py =================================================================== --- branches/asm/Lib/test/string_tests.py 2008-07-14 10:52:18 UTC (rev 4918) +++ branches/asm/Lib/test/string_tests.py 2008-07-14 11:03:54 UTC (rev 4919) @@ -251,7 +251,11 @@ self.checkraises(TypeError, 'hello', 'expandtabs', 42, 42) # This test is only valid when sizeof(int) == sizeof(void*) == 4. - if sys.maxint < (1 << 32) and struct.calcsize('P') == 4: + + # Jython uses a different algorithm for which overflows cannot occur; + # but memory exhaustion of course can. So not applicable. + if (sys.maxint < (1 << 32) and not test_support.is_jython + and struct.calcsize('P') == 4): self.checkraises(OverflowError, '\ta\n\tb', 'expandtabs', sys.maxint) @@ -678,7 +682,7 @@ def test_replace_overflow(self): # Check for overflow checking on 32 bit machines - if sys.maxint != 2147483647 or struct.calcsize("P") > 4: + if sys.maxint != 2147483647 or test_support.is_jython or struct.calcsize("P") > 4: return A2_16 = "A" * (2**16) self.checkraises(OverflowError, A2_16, "replace", "", A2_16) Modified: branches/asm/Lib/test/test_str.py =================================================================== --- branches/asm/Lib/test/test_str.py 2008-07-14 10:52:18 UTC (rev 4918) +++ branches/asm/Lib/test/test_str.py 2008-07-14 11:03:54 UTC (rev 4919) @@ -89,7 +89,10 @@ # This test only affects 32-bit platforms because expandtabs can only take # an int as the max value, not a 64-bit C long. If expandtabs is changed # to take a 64-bit long, this test should apply to all platforms. - if sys.maxint > (1 << 32) or struct.calcsize('P') != 4: + + # Jython uses a different algorithm for which overflows cannot occur; + # but memory exhaustion of course can. So not applicable. + if sys.maxint > (1 << 32) or test_support.is_jython or struct.calcsize('P') != 4: return self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxint) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-14 10:52:21
|
Revision: 4918 http://jython.svn.sourceforge.net/jython/?rev=4918&view=rev Author: zyasoft Date: 2008-07-14 03:52:18 -0700 (Mon, 14 Jul 2008) Log Message: ----------- From http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_str@64946 Added Paths: ----------- branches/asm/Lib/test/test_str.py Added: branches/asm/Lib/test/test_str.py =================================================================== --- branches/asm/Lib/test/test_str.py (rev 0) +++ branches/asm/Lib/test/test_str.py 2008-07-14 10:52:18 UTC (rev 4918) @@ -0,0 +1,101 @@ + +import unittest +import struct +import sys +from test import test_support, string_tests + + +class StrTest( + string_tests.CommonTest, + string_tests.MixinStrUnicodeUserStringTest, + string_tests.MixinStrUserStringTest, + string_tests.MixinStrUnicodeTest, + ): + + type2test = str + + # We don't need to propagate to str + def fixtype(self, obj): + return obj + + def test_formatting(self): + string_tests.MixinStrUnicodeUserStringTest.test_formatting(self) + self.assertRaises(OverflowError, '%c'.__mod__, 0x1234) + + def test_conversion(self): + # Make sure __str__() behaves properly + class Foo0: + def __unicode__(self): + return u"foo" + + class Foo1: + def __str__(self): + return "foo" + + class Foo2(object): + def __str__(self): + return "foo" + + class Foo3(object): + def __str__(self): + return u"foo" + + class Foo4(unicode): + def __str__(self): + return u"foo" + + class Foo5(str): + def __str__(self): + return u"foo" + + class Foo6(str): + def __str__(self): + return "foos" + + def __unicode__(self): + return u"foou" + + class Foo7(unicode): + def __str__(self): + return "foos" + def __unicode__(self): + return u"foou" + + class Foo8(str): + def __new__(cls, content=""): + return str.__new__(cls, 2*content) + def __str__(self): + return self + + class Foo9(str): + def __str__(self): + return "string" + def __unicode__(self): + return "not unicode" + + self.assert_(str(Foo0()).startswith("<")) # this is different from __unicode__ + self.assertEqual(str(Foo1()), "foo") + self.assertEqual(str(Foo2()), "foo") + self.assertEqual(str(Foo3()), "foo") + self.assertEqual(str(Foo4("bar")), "foo") + self.assertEqual(str(Foo5("bar")), "foo") + self.assertEqual(str(Foo6("bar")), "foos") + self.assertEqual(str(Foo7("bar")), "foos") + self.assertEqual(str(Foo8("foo")), "foofoo") + self.assertEqual(str(Foo9("foo")), "string") + self.assertEqual(unicode(Foo9("foo")), u"not unicode") + + def test_expandtabs_overflows_gracefully(self): + # This test only affects 32-bit platforms because expandtabs can only take + # an int as the max value, not a 64-bit C long. If expandtabs is changed + # to take a 64-bit long, this test should apply to all platforms. + if sys.maxint > (1 << 32) or struct.calcsize('P') != 4: + return + self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxint) + + +def test_main(): + test_support.run_unittest(StrTest) + +if __name__ == "__main__": + test_main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-14 10:47:04
|
Revision: 4917 http://jython.svn.sourceforge.net/jython/?rev=4917&view=rev Author: zyasoft Date: 2008-07-14 03:47:01 -0700 (Mon, 14 Jul 2008) Log Message: ----------- split and rsplit do not need to be UTF-16 aware Modified Paths: -------------- branches/asm/src/org/python/core/PyUnicode.java Modified: branches/asm/src/org/python/core/PyUnicode.java =================================================================== --- branches/asm/src/org/python/core/PyUnicode.java 2008-07-13 03:36:31 UTC (rev 4916) +++ branches/asm/src/org/python/core/PyUnicode.java 2008-07-14 10:47:01 UTC (rev 4917) @@ -803,7 +803,7 @@ super(maxsplit); this.sep = sep; } - + public PyUnicode next() { StringBuilder buffer = new StringBuilder(); @@ -853,7 +853,7 @@ return new SepSplitIterator(sep, maxsplit); } } - + @ExposedMethod final PyTuple unicode_rpartition(PyObject sep) { return unicodeRpartition(sep); @@ -862,16 +862,23 @@ @ExposedMethod(defaults = {"null", "-1"}) final PyList unicode_split(PyObject sepObj, int maxsplit) { PyUnicode sep = coerceToUnicode(sepObj); - if (isBasicPlane() && (sep == null || sep.isBasicPlane())) { - if (sep != null) { - return str_split(sep.string, maxsplit); - } else { - return str_split(null, maxsplit); - } + if (sep != null) { + return str_split(sep.string, maxsplit); + } else { + return str_split(null, maxsplit); } - return new PyList(newSplitIterator(sep, maxsplit)); } + @ExposedMethod(defaults = {"null", "-1"}) + final PyList unicode_rsplit(PyObject sepObj, int maxsplit) { + PyUnicode sep = coerceToUnicode(sepObj); + if (sep != null) { + return str_rsplit(sep.string, maxsplit); + } else { + return str_rsplit(null, maxsplit); + } + } + @ExposedMethod(defaults = "false") final PyList unicode_splitlines(boolean keepends) { if (isBasicPlane()) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-13 03:36:33
|
Revision: 4916 http://jython.svn.sourceforge.net/jython/?rev=4916&view=rev Author: pjenvey Date: 2008-07-12 20:36:31 -0700 (Sat, 12 Jul 2008) Log Message: ----------- fix to make the 'g' formatter closer to CPython's. fixes test_tokenize Modified Paths: -------------- branches/asm/Lib/test/test_float_jy.py branches/asm/src/org/python/core/PyString.java Modified: branches/asm/Lib/test/test_float_jy.py =================================================================== --- branches/asm/Lib/test/test_float_jy.py 2008-07-13 02:59:32 UTC (rev 4915) +++ branches/asm/Lib/test/test_float_jy.py 2008-07-13 03:36:31 UTC (rev 4916) @@ -4,8 +4,8 @@ """ import math import sys -import test_support import unittest +from test import test_support jython = sys.platform.startswith('java') @@ -28,8 +28,7 @@ self.assertEqual(str(12345678.00005), jython and '12345678.0' or '12345678.0001') self.assertEqual(str(12345678.0005), '12345678.0005') - self.assertEqual(str(math.pi**-100), - jython and '1.927581416056e-50' or '1.92758141606e-50') + self.assertEqual(str(math.pi**-100), '1.92758141606e-50') self.assertEqual(str(0.0), '0.0') self.assertEqual(str(-1.0), '-1.0') self.assertEqual(str(-9876.543210), '-9876.54321') @@ -43,8 +42,7 @@ self.assertEqual('%.11g' % 12345678.00005, '12345678') # XXX: The exponential formatter isn't totally correct, e.g. our # output here is really .13g - self.assertEqual('%.12g' % math.pi**-100, - jython and '1.927581416056e-50' or '1.92758141606e-50') + self.assertEqual('%.12g' % math.pi**-100, '1.92758141606e-50') self.assertEqual('%.5g' % 123.005, '123') self.assertEqual('%#.5g' % 123.005, '123.00') self.assertEqual('%#g' % 0.001, '0.00100000') @@ -53,8 +51,7 @@ self.assertEqual('%#.4g' % 100, '100.0') self.assertEqual('%#.4g' % 100.25, '100.2') self.assertEqual('%g' % 0.00001, '1e-05') - self.assertEqual('%#g' % 0.00001, - jython and '1.000000e-05' or '1.00000e-05') + self.assertEqual('%#g' % 0.00001, '1.00000e-05') self.assertEqual('%e' % -400.0, '-4.000000e+02') self.assertEqual('%.2g' % 99, '99') self.assertEqual('%.2g' % 100, '1e+02') Modified: branches/asm/src/org/python/core/PyString.java =================================================================== --- branches/asm/src/org/python/core/PyString.java 2008-07-13 02:59:32 UTC (rev 4915) +++ branches/asm/src/org/python/core/PyString.java 2008-07-13 03:36:31 UTC (rev 4916) @@ -2900,6 +2900,11 @@ } } } else { + // Exponential precision is the number of digits after the decimal + // point, whereas 'g' precision is the number of significant digits -- + // and expontential always provides one significant digit before the + // decimal point + precision--; string = formatFloatExponential(arg, (char)(c-2), !altFlag); } break; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-13 02:59:35
|
Revision: 4915 http://jython.svn.sourceforge.net/jython/?rev=4915&view=rev Author: pjenvey Date: 2008-07-12 19:59:32 -0700 (Sat, 12 Jul 2008) Log Message: ----------- use bin instead of Scripts Modified Paths: -------------- trunk/jython/Lib/distutils/command/install.py Modified: trunk/jython/Lib/distutils/command/install.py =================================================================== --- trunk/jython/Lib/distutils/command/install.py 2008-07-13 02:07:51 UTC (rev 4914) +++ trunk/jython/Lib/distutils/command/install.py 2008-07-13 02:59:32 UTC (rev 4915) @@ -70,7 +70,7 @@ 'purelib': '$base/Lib/site-packages', 'platlib': '$base/Lib/site-packages', 'headers': '$base/Include/$dist_name', - 'scripts': '$base/Scripts', + 'scripts': '$base/bin', 'data' : '$base', } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-13 02:08:01
|
Revision: 4914 http://jython.svn.sourceforge.net/jython/?rev=4914&view=rev Author: pjenvey Date: 2008-07-12 19:07:51 -0700 (Sat, 12 Jul 2008) Log Message: ----------- add C_EXTENSION because pkgutil references it Modified Paths: -------------- branches/asm/src/org/python/modules/imp.java Modified: branches/asm/src/org/python/modules/imp.java =================================================================== --- branches/asm/src/org/python/modules/imp.java 2008-07-13 00:47:08 UTC (rev 4913) +++ branches/asm/src/org/python/modules/imp.java 2008-07-13 02:07:51 UTC (rev 4914) @@ -31,6 +31,7 @@ public static final int PY_SOURCE = 1; public static final int PY_COMPILED = 2; + public static final int C_EXTENSION = 3; public static final int PKG_DIRECTORY = 5; public static final int PY_FROZEN = 7; public static final int IMP_HOOK = 9; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-13 00:47:10
|
Revision: 4913 http://jython.svn.sourceforge.net/jython/?rev=4913&view=rev Author: pjenvey Date: 2008-07-12 17:47:08 -0700 (Sat, 12 Jul 2008) Log Message: ----------- max_read_chunk of 10mb kills test_gzip.test_many_append's performance due to repeated 10mb reads. CPython doesn't suffer from this -- maybe its allocator recycles the same 10mb. lowering to 256K speeds test time from 15 to 1 second Modified Paths: -------------- branches/asm/Lib/gzip.py Modified: branches/asm/Lib/gzip.py =================================================================== --- branches/asm/Lib/gzip.py 2008-07-12 19:57:48 UTC (rev 4912) +++ branches/asm/Lib/gzip.py 2008-07-13 00:47:08 UTC (rev 4913) @@ -55,7 +55,11 @@ """ myfileobj = None - max_read_chunk = 10 * 1024 * 1024 # 10Mb + # XXX: repeated 10mb chunk reads hurt test_gzip.test_many_append's + # performance on Jython (maybe CPython's allocator recycles the same + # 10mb buffer whereas Java's doesn't) + #max_read_chunk = 10 * 1024 * 1024 # 10Mb + max_read_chunk = 256 * 1024 # 256kb def __init__(self, filename=None, mode=None, compresslevel=9, fileobj=None): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-12 19:57:55
|
Revision: 4912 http://jython.svn.sourceforge.net/jython/?rev=4912&view=rev Author: pjenvey Date: 2008-07-12 12:57:48 -0700 (Sat, 12 Jul 2008) Log Message: ----------- o add popen2.cleanup for CPython compat. and to fix test_popen2 o make threading.currentThread() is threading.currentThread() (with the help of a WeakKeyDictionary) to allow _threading_local to work Modified Paths: -------------- branches/asm/CPythonLib.includes branches/asm/Lib/popen2.py branches/asm/Lib/threading.py Modified: branches/asm/CPythonLib.includes =================================================================== --- branches/asm/CPythonLib.includes 2008-07-12 19:52:59 UTC (rev 4911) +++ branches/asm/CPythonLib.includes 2008-07-12 19:57:48 UTC (rev 4912) @@ -14,6 +14,7 @@ _LWPCookieJar.py _MozillaCookieJar.py _strptime.py +_threading_local.py aifc.py anydbm.py atexit.py Modified: branches/asm/Lib/popen2.py =================================================================== --- branches/asm/Lib/popen2.py 2008-07-12 19:52:59 UTC (rev 4911) +++ branches/asm/Lib/popen2.py 2008-07-12 19:57:48 UTC (rev 4912) @@ -34,6 +34,10 @@ _active = [] +def _cleanup(): + """For CPython compatibility""" + pass + class _ProcessFile: """Python file object that returns the process exit status from the close method. Modified: branches/asm/Lib/threading.py =================================================================== --- branches/asm/Lib/threading.py 2008-07-12 19:52:59 UTC (rev 4911) +++ branches/asm/Lib/threading.py 2008-07-12 19:57:48 UTC (rev 4912) @@ -1,7 +1,6 @@ from java.util.concurrent import Semaphore, CyclicBarrier from java.util.concurrent.locks import ReentrantLock from org.python.core import FunctionThread -from java.lang import Thread from thread import _local as local import java.lang.Thread import weakref @@ -147,12 +146,12 @@ ThreadStates = { - Thread.State.NEW : 'initial', - Thread.State.RUNNABLE: 'runnable', - Thread.State.BLOCKED: 'blocked', - Thread.State.WAITING: 'waiting', - Thread.State.TIMED_WAITING: 'timed_waiting', - Thread.State.TERMINATED: 'stopped', + java.lang.Thread.State.NEW : 'initial', + java.lang.Thread.State.RUNNABLE: 'runnable', + java.lang.Thread.State.BLOCKED: 'blocked', + java.lang.Thread.State.WAITING: 'waiting', + java.lang.Thread.State.TIMED_WAITING: 'timed_waiting', + java.lang.Thread.State.TERMINATED: 'stopped', } class JavaThread(object): @@ -207,6 +206,7 @@ # relies on the fact that this is a CHM _threads = weakref.WeakValueDictionary() _active = _threads +_jthread_to_pythread = weakref.WeakKeyDictionary() class Thread(JavaThread): def __init__(self, group=None, target=None, name=None, args=None, kwargs=None): @@ -217,11 +217,15 @@ self._target = target self._args = args self._kwargs = kwargs - self._thread = _thread = FunctionThread(self.__bootstrap, ()) + self._thread = _thread = self._create_thread() if name: self._thread.setName(name) + _jthread_to_pythread[_thread] = self _threads[_thread.getId()] = self + def _create_thread(self): + return FunctionThread(self.__bootstrap, ()) + def run(self): if self._target: self._target(*self._args, **self._kwargs) @@ -287,10 +291,14 @@ import atexit atexit.register(self.__exitfunc) + def _create_thread(self): + return java.lang.Thread.currentThread() + def _set_daemon(self): return False def __exitfunc(self): + del _threads[self._thread.getId()] t = _pickSomeNonDaemonThread() while t: t.join() @@ -303,9 +311,8 @@ return None def currentThread(): - id = java.lang.Thread.currentThread().getId() try: - return _threads[id] + return _jthread_to_pythread[java.lang.Thread.currentThread()] except KeyError: return JavaThread(java.lang.Thread.currentThread()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2008-07-12 19:53:03
|
Revision: 4911 http://jython.svn.sourceforge.net/jython/?rev=4911&view=rev Author: leosoto Date: 2008-07-12 12:52:59 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Removing a duplicate line on CPythonLib.includes I introduced on r4910 Modified Paths: -------------- branches/asm/CPythonLib.includes Modified: branches/asm/CPythonLib.includes =================================================================== --- branches/asm/CPythonLib.includes 2008-07-12 19:50:43 UTC (rev 4910) +++ branches/asm/CPythonLib.includes 2008-07-12 19:52:59 UTC (rev 4911) @@ -11,7 +11,6 @@ # Lib files, in alphabetical order: __future__.py -_strptime.py _LWPCookieJar.py _MozillaCookieJar.py _strptime.py This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2008-07-12 19:50:46
|
Revision: 4910 http://jython.svn.sourceforge.net/jython/?rev=4910&view=rev Author: leosoto Date: 2008-07-12 12:50:43 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Now test_strptime pass. This is done by improving the current SimpleDateFormat-backed implementation a bit, and delegating to _strptime.strptime for formats not supported by SimpleDateFormat. Modified Paths: -------------- branches/asm/CPythonLib.includes branches/asm/Lib/test/test_time.py branches/asm/src/org/python/modules/time/Time.java Modified: branches/asm/CPythonLib.includes =================================================================== --- branches/asm/CPythonLib.includes 2008-07-12 16:50:22 UTC (rev 4909) +++ branches/asm/CPythonLib.includes 2008-07-12 19:50:43 UTC (rev 4910) @@ -11,6 +11,7 @@ # Lib files, in alphabetical order: __future__.py +_strptime.py _LWPCookieJar.py _MozillaCookieJar.py _strptime.py Modified: branches/asm/Lib/test/test_time.py =================================================================== --- branches/asm/Lib/test/test_time.py 2008-07-12 16:50:22 UTC (rev 4909) +++ branches/asm/Lib/test/test_time.py 2008-07-12 19:50:43 UTC (rev 4910) @@ -99,11 +99,13 @@ # Make sure that using all zeros uses the proper default values. # No test for daylight savings since strftime() does not change output # based on its value. - # XXX: Java's SimpleDateFormat does 2 digit weekdays if not test_support.is_jython: expected = "2000 01 01 00 00 00 1 001" else: - expected = "0000 01 01 00 00 00 01 001" + # XXX: Jython doesn't support the "two digits years" hack (turned + # on/off by time.accept2dyears), so year 0 means exactly that + # and it is not converted to 2000. + expected = "0000 01 01 00 00 00 1 001" result = time.strftime("%Y %m %d %H %M %S %w %j", (0,)*9) self.assertEquals(expected, result) Modified: branches/asm/src/org/python/modules/time/Time.java =================================================================== --- branches/asm/src/org/python/modules/time/Time.java 2008-07-12 16:50:22 UTC (rev 4909) +++ branches/asm/src/org/python/modules/time/Time.java 2008-07-12 19:50:43 UTC (rev 4910) @@ -13,11 +13,13 @@ package org.python.modules.time; import java.text.DateFormatSymbols; +import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.TimeZone; import java.text.ParseException; @@ -31,7 +33,7 @@ import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyTuple; -import org.python.core.PyType; +import org.python.core.__builtin__; class TimeFunctions extends PyBuiltinFunctionSet { @@ -134,12 +136,12 @@ // rather than a value of initialClock since the initial call to // System.nanoTime can yield anything and that could lead to initialTime // being set twice. - if(!clockInitialized) { + if(!clockInitialized) { initialClock = System.nanoTime(); clockInitialized = true; return 0; } - return (System.nanoTime() - initialClock) / NANOS_PER_SECOND; + return (System.nanoTime() - initialClock) / NANOS_PER_SECOND; } private static final double NANOS_PER_SECOND = 1000000000.0; private static long initialClock; @@ -577,7 +579,7 @@ // weekday as decimal (0=Sunday-6) // tuple format has monday=0 j = (items[6] + 1) % 7; - s = s + _twodigit(j); + s = s + j; break; case 'W': // week of year (monday is first day) (00-53). all days in @@ -662,14 +664,21 @@ } } - - // from patch by Tri...@jc... - // NOTE: these functions have not been roubustly tested, but that's what unit - // tests are for. works with Django. please verify before merging into trunk. public static PyTuple strptime(String data_string) { return strptime(data_string, DEFAULT_FORMAT_PY); } + /** + * Calls _strptime.strptime(), for cases that our SimpleDateFormat backed + * strptime can't handle. + */ + private static PyTuple pystrptime(String data_string, String format) { + return (PyTuple) __builtin__.__import__("_strptime") + .__getattr__("strptime") + .__call__(Py.newUnicode(data_string), + Py.newUnicode(format)); + } + public static PyTuple strptime(String data_string, String format) { if (format == null || data_string == null) { // this is not a very interesting error message, but it's the same @@ -677,6 +686,10 @@ throw Py.TypeError("expected string of buffer"); } String jformat = py2java_format(format); + if (jformat == null) { + // Format not translatable to java, fallback to _strptime + return pystrptime(data_string, format); + } SimpleDateFormat d = new SimpleDateFormat(jformat); Calendar cal = Calendar.getInstance(); try { @@ -702,7 +715,6 @@ } private static final String DEFAULT_FORMAT_PY = "%a %b %d %H:%M:%S %Y"; - private static final String DEFAULT_FORMAT_JA = "EEE MMM dd HH:mm:ss zzz yyyy"; private static final HashMap<Character, String> py2java = new HashMap<Character, String>() {{ put('a', "EEE"); put('A', "EEEE"); @@ -711,14 +723,13 @@ put('c', "EEE MMM dd HH:mm:ss yyyy"); put('d', "dd"); put('H', "HH"); - put('I', "kk"); + put('I', "hh"); put('j', "DDD"); put('m', "MM"); put('M', "mm"); put('p', "a"); put('S', "ss"); put('U', "ww"); - put('w', "0"); // unsupported in java put('W', "ww"); // same as U ?? put('x', "MM/dd/yy"); put('X', "HH:mm:ss"); @@ -726,8 +737,19 @@ put('Y', "yyyy"); put('Z', "zzz"); put('%', "%"); - }}; + }}; + // strptime formats not supported by SimpleDateFormat: + private static final List<Character> notSupported = new ArrayList<Character>() {{ + add('w'); + }}; + + + /** + * @return the {@link SimpleDateFormat} format string equivalent to the + * strptime format string supplied as parameter, or <b>null</b> if there is + * no equivalent for SimpleDateFormat. + */ private static String py2java_format(String format) { StringBuilder builder = new StringBuilder(); boolean directive = false; @@ -758,6 +780,9 @@ } String translated = py2java.get(charAt); + if (translated == null && notSupported.contains(charAt)) { + return null; + } builder.append(translated != null ? translated : charAt); directive = false; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-12 16:50:25
|
Revision: 4909 http://jython.svn.sourceforge.net/jython/?rev=4909&view=rev Author: zyasoft Date: 2008-07-12 09:50:22 -0700 (Sat, 12 Jul 2008) Log Message: ----------- ascii codec will always be in basic plane, so at least optimize setting of that when constructing unicode Modified Paths: -------------- branches/asm/src/org/python/core/Py.java branches/asm/src/org/python/core/PyUnicode.java branches/asm/src/org/python/core/codecs.java Modified: branches/asm/src/org/python/core/Py.java =================================================================== --- branches/asm/src/org/python/core/Py.java 2008-07-12 15:55:44 UTC (rev 4908) +++ branches/asm/src/org/python/core/Py.java 2008-07-12 16:50:22 UTC (rev 4909) @@ -571,7 +571,11 @@ public static PyUnicode newUnicode(String s) { return new PyUnicode(s); } - + + public static PyUnicode newUnicode(String s, boolean isBasic) { + return new PyUnicode(s, isBasic); + } + public static PyBoolean newBoolean(boolean t) { return t ? Py.True : Py.False; } Modified: branches/asm/src/org/python/core/PyUnicode.java =================================================================== --- branches/asm/src/org/python/core/PyUnicode.java 2008-07-12 15:55:44 UTC (rev 4908) +++ branches/asm/src/org/python/core/PyUnicode.java 2008-07-12 16:50:22 UTC (rev 4909) @@ -37,6 +37,11 @@ this(TYPE, string); } + public PyUnicode(String string, boolean isBasic) { + this(TYPE, string); + plane = isBasic ? Plane.BASIC : Plane.UNKNOWN; + } + public PyUnicode(PyType subtype, String string) { super(subtype, string); } @@ -190,9 +195,7 @@ // case of deletes. So optimize by providing a tainting mechanism. @Override protected PyString createInstance(String str, boolean isBasic) { - PyUnicode uni = new PyUnicode(str); - uni.plane = isBasic ? Plane.BASIC : Plane.UNKNOWN; - return uni; + return new PyUnicode(str, isBasic); } @Override Modified: branches/asm/src/org/python/core/codecs.java =================================================================== --- branches/asm/src/org/python/core/codecs.java 2008-07-12 15:55:44 UTC (rev 4908) +++ branches/asm/src/org/python/core/codecs.java 2008-07-12 16:50:22 UTC (rev 4909) @@ -135,8 +135,9 @@ /* Shortcut for ascii encoding */ if (encoding.equals("ascii")) { - return new PyUnicode(PyUnicode_DecodeASCII(v.toString(), - v.__len__(), errors)); + return new PyUnicode( + PyUnicode_DecodeASCII(v.toString(), v.__len__(), errors), + true); } /* Decode via the codec registry */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-12 15:55:49
|
Revision: 4908 http://jython.svn.sourceforge.net/jython/?rev=4908&view=rev Author: zyasoft Date: 2008-07-12 08:55:44 -0700 (Sat, 12 Jul 2008) Log Message: ----------- datetime.fromtimestamp now rounds seconds,microseconds within 1 microsecond of an integer second to that second Modified Paths: -------------- branches/asm/Lib/datetime.py Modified: branches/asm/Lib/datetime.py =================================================================== --- branches/asm/Lib/datetime.py 2008-07-12 15:42:09 UTC (rev 4907) +++ branches/asm/Lib/datetime.py 2008-07-12 15:55:44 UTC (rev 4908) @@ -1399,8 +1399,17 @@ converter = _time.gmtime y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) us = int((t % 1.0) * 1000000) + + if us == 1000001 or us == 999999: + us = 0 + rounded = True + else: + rounded = False + ss = min(ss, 59) # clamp out leap seconds if the platform has them result = cls(y, m, d, hh, mm, ss, us, tz) + if rounded: + result += timedelta(seconds=1) if tz is not None: result = tz.fromutc(result) return result This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-12 15:42:11
|
Revision: 4907 http://jython.svn.sourceforge.net/jython/?rev=4907&view=rev Author: zyasoft Date: 2008-07-12 08:42:09 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Added datetime.strptime Modified Paths: -------------- branches/asm/Lib/datetime.py Modified: branches/asm/Lib/datetime.py =================================================================== --- branches/asm/Lib/datetime.py 2008-07-12 14:09:20 UTC (rev 4906) +++ branches/asm/Lib/datetime.py 2008-07-12 15:42:09 UTC (rev 4907) @@ -1442,6 +1442,15 @@ time.tzinfo) combine = classmethod(combine) + def strptime(cls, date_string, format): + """datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]]) + + The year, month and day arguments are required. tzinfo may be None, or an + instance of a tzinfo subclass. The remaining arguments may be ints or longs.""" + return cls(*(_time.strptime(date_string, format))[0:6]) + + strptime = classmethod(strptime) + def timetuple(self): "Return local time tuple compatible with time.localtime()." dst = self._dst() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-12 14:09:25
|
Revision: 4906 http://jython.svn.sourceforge.net/jython/?rev=4906&view=rev Author: zyasoft Date: 2008-07-12 07:09:20 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Operations on unicode objs in basic plane can only result in basic plane objs (btw, not true of astral) Modified Paths: -------------- branches/asm/src/org/python/core/PyString.java branches/asm/src/org/python/core/PyUnicode.java Modified: branches/asm/src/org/python/core/PyString.java =================================================================== --- branches/asm/src/org/python/core/PyString.java 2008-07-12 13:51:06 UTC (rev 4905) +++ branches/asm/src/org/python/core/PyString.java 2008-07-12 14:09:20 UTC (rev 4906) @@ -625,7 +625,7 @@ for (int i=start; j<n; i+=step) new_chars[j++] = string.charAt(i); - return createInstance(new String(new_chars)); + return createInstance(new String(new_chars), true); } } @@ -666,7 +666,7 @@ for(int i = 0; i < count; i++) { string.getChars(0, s, new_chars, i * s); } - return createInstance(new String(new_chars)); + return createInstance(new String(new_chars), true); } @ExposedMethod(type = MethodType.BINARY) @@ -697,7 +697,7 @@ if (generic_other instanceof PyUnicode) { return new PyUnicode(result); } - return createInstance(result); + return createInstance(result, true); } else return null; } @@ -1354,7 +1354,7 @@ } protected PyString fromSubstring(int begin, int end) { - return createInstance(string.substring(begin, end)); + return createInstance(string.substring(begin, end), true); } public int index(String sub) { @@ -1798,9 +1798,9 @@ int old_len = oldPiece.string.length(); if (len == 0) { if (maxsplit == -1 && old_len == 0) { - return createInstance(newPiece.string); + return createInstance(newPiece.string, true); } - return createInstance(string); + return createInstance(string, true); } if (old_len == 0 && newPiece.string.length() != 0 && maxsplit !=0) { @@ -1813,7 +1813,7 @@ buffer.append(newPiece.string); } buffer.append(string.substring(i)); - return createInstance(buffer.toString()); + return createInstance(buffer.toString(), true); } if(maxsplit == -1) { @@ -1844,7 +1844,7 @@ PyObject item; int seqlen = seq.__len__(); if (seqlen == 0) { - return createInstance(""); + return createInstance("", true); } if (seqlen == 1) { item = seq.pyget(0); @@ -1881,7 +1881,7 @@ if (needsUnicode){ return new PyUnicode(buf.toString()); } - return createInstance(buf.toString()); + return createInstance(buf.toString(), true); } Modified: branches/asm/src/org/python/core/PyUnicode.java =================================================================== --- branches/asm/src/org/python/core/PyUnicode.java 2008-07-12 13:51:06 UTC (rev 4905) +++ branches/asm/src/org/python/core/PyUnicode.java 2008-07-12 14:09:20 UTC (rev 4906) @@ -253,6 +253,9 @@ @Override protected PyObject getslice(int start, int stop, int step) { + if (isBasicPlane()) { + return super.getslice(start, stop, step); + } if (step > 0 && stop < start) { stop = start; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-12 13:51:08
|
Revision: 4905 http://jython.svn.sourceforge.net/jython/?rev=4905&view=rev Author: zyasoft Date: 2008-07-12 06:51:06 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Removed tests not relevant to Jython around CPython code compilation Modified Paths: -------------- branches/asm/Lib/test/regrtest.py Modified: branches/asm/Lib/test/regrtest.py =================================================================== --- branches/asm/Lib/test/regrtest.py 2008-07-12 13:50:19 UTC (rev 4904) +++ branches/asm/Lib/test/regrtest.py 2008-07-12 13:51:06 UTC (rev 4905) @@ -1389,6 +1389,7 @@ test_capi test_cd test_cl + test_code test_codeccallbacks test_codeop test_commands @@ -1451,6 +1452,7 @@ test_threadsignals test_timeout test_timing + test_transformer test_unicode_file test_unicodedata test_wait3 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-12 13:50:23
|
Revision: 4904 http://jython.svn.sourceforge.net/jython/?rev=4904&view=rev Author: zyasoft Date: 2008-07-12 06:50:19 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Fixed str|string|unicode.replace for PyString or PyUnicode in the basic plane Modified Paths: -------------- branches/asm/Lib/test/string_tests.py branches/asm/src/org/python/core/PyString.java branches/asm/src/org/python/core/PyUnicode.java Modified: branches/asm/Lib/test/string_tests.py =================================================================== --- branches/asm/Lib/test/string_tests.py 2008-07-12 10:08:11 UTC (rev 4903) +++ branches/asm/Lib/test/string_tests.py 2008-07-12 13:50:19 UTC (rev 4904) @@ -641,11 +641,13 @@ EQ("bobobXbobob", "bobobobXbobobob", "replace", "bobob", "bob") EQ("BOBOBOB", "BOBOBOB", "replace", "bob", "bobby") - ba = buffer('a') - bb = buffer('b') - EQ("bbc", "abc", "replace", ba, bb) - EQ("aac", "abc", "replace", bb, ba) + # XXX - Jython does not support the buffer protocol; perhaps + # it's possible for things like strings. Not likely to be in 2.5 + # ba = buffer('a') + # bb = buffer('b') + # EQ("bbc", "abc", "replace", ba, bb) + # EQ("aac", "abc", "replace", bb, ba) # self.checkequal('one@two!three!', 'one!two!three!', 'replace', '!', '@', 1) self.checkequal('onetwothree', 'one!two!three!', 'replace', '!', '') Modified: branches/asm/src/org/python/core/PyString.java =================================================================== --- branches/asm/src/org/python/core/PyString.java 2008-07-12 10:08:11 UTC (rev 4903) +++ branches/asm/src/org/python/core/PyString.java 2008-07-12 13:50:19 UTC (rev 4904) @@ -633,6 +633,11 @@ return new PyString(str); } + protected PyString createInstance(String str, boolean isBasic) { + // ignore isBasic, doesn't apply to PyString, just PyUnicode + return new PyString(str); + } + public boolean __contains__(PyObject o) { return str___contains__(o); } @@ -1784,20 +1789,42 @@ if(!(oldPiece instanceof PyString) || !(newPiece instanceof PyString)) { throw Py.TypeError("str or unicode required for replace"); } - if(string.length() == 0) { + + return replace((PyString)oldPiece, (PyString)newPiece, maxsplit == null ? -1 : maxsplit.asInt()); + } + + protected PyString replace(PyString oldPiece, PyString newPiece, int maxsplit) { + int len = string.length(); + int old_len = oldPiece.string.length(); + if (len == 0) { + if (maxsplit == -1 && old_len == 0) { + return createInstance(newPiece.string); + } return createInstance(string); } - int iMaxsplit; - if(maxsplit == null) { - if(oldPiece.__len__() == 0) { - iMaxsplit = string.length() + 1; + + if (old_len == 0 && newPiece.string.length() != 0 && maxsplit !=0) { + // old="" and new != "", interleave new piece with each char in original, taking in effect maxsplit + StringBuilder buffer = new StringBuilder(); + int i = 0; + buffer.append(newPiece.string); + for (; i < len && (i < maxsplit-1 || maxsplit == -1); i++) { + buffer.append(string.charAt(i)); + buffer.append(newPiece.string); + } + buffer.append(string.substring(i)); + return createInstance(buffer.toString()); + } + + if(maxsplit == -1) { + if(old_len == 0) { + maxsplit = len + 1; } else { - iMaxsplit = string.length(); + maxsplit = len; } - } else { - iMaxsplit = maxsplit.asInt(); } - return ((PyString)newPiece).str_join(splitfields(((PyString)oldPiece).string, iMaxsplit)); + + return newPiece.str_join(splitfields(oldPiece.string, maxsplit)); } public String join(PyObject seq) { Modified: branches/asm/src/org/python/core/PyUnicode.java =================================================================== --- branches/asm/src/org/python/core/PyUnicode.java 2008-07-12 10:08:11 UTC (rev 4903) +++ branches/asm/src/org/python/core/PyUnicode.java 2008-07-12 13:50:19 UTC (rev 4904) @@ -185,7 +185,17 @@ return new PyUnicode(str); } + // Unicode ops consisting of basic strings can only produce basic strings; + // this may not be the case for astral ones - they also might be basic, in + // case of deletes. So optimize by providing a tainting mechanism. @Override + protected PyString createInstance(String str, boolean isBasic) { + PyUnicode uni = new PyUnicode(str); + uni.plane = isBasic ? Plane.BASIC : Plane.UNKNOWN; + return uni; + } + + @Override public PyObject __mod__(PyObject other) { return unicode___mod__(other); } @@ -1033,10 +1043,14 @@ @ExposedMethod(defaults = "-1") final PyObject unicode_replace(PyObject oldPieceObj, PyObject newPieceObj, int maxsplit) { - StringBuilder buffer = new StringBuilder(); PyUnicode newPiece = coerceToUnicode(newPieceObj); PyUnicode oldPiece = coerceToUnicode(oldPieceObj); - + if (isBasicPlane() && newPiece.isBasicPlane() && oldPiece.isBasicPlane()) { + return replace(oldPiece, newPiece, maxsplit); + } + + StringBuilder buffer = new StringBuilder(); + if (oldPiece.getCodePointCount() == 0) { Iterator<Integer> iter = newSubsequenceIterator(); for (int i = 1; (maxsplit == -1 || i < maxsplit) && iter.hasNext(); i++) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-12 10:08:16
|
Revision: 4903 http://jython.svn.sourceforge.net/jython/?rev=4903&view=rev Author: zyasoft Date: 2008-07-12 03:08:11 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Replaced Lib/datetime.py with version from PyPy, http://codespeak.net/svn/pypy/dist/pypy/lib/datetime.py@56484 Modified Paths: -------------- branches/asm/Lib/datetime.py Modified: branches/asm/Lib/datetime.py =================================================================== --- branches/asm/Lib/datetime.py 2008-07-12 09:13:38 UTC (rev 4902) +++ branches/asm/Lib/datetime.py 2008-07-12 10:08:11 UTC (rev 4903) @@ -12,6 +12,8 @@ Sources for time zone and DST data: http://www.twinsun.com/tz/tz-link.htm +This was originally copied from the sandbox of the CPython CVS repository. +Thanks to Tim Peters for suggesting using it. """ import time as _time @@ -575,6 +577,8 @@ def __add__(self, other): if isinstance(other, timedelta): + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta return timedelta(self.__days + other.__days, self.__seconds + other.__seconds, self.__microseconds + other.__microseconds) @@ -593,9 +597,11 @@ return NotImplemented def __neg__(self): - return self.__class__(-self.__days, - -self.__seconds, - -self.__microseconds) + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(-self.__days, + -self.__seconds, + -self.__microseconds) def __pos__(self): return self @@ -608,9 +614,11 @@ def __mul__(self, other): if isinstance(other, (int, long)): - return self.__class__(self.__days * other, - self.__seconds * other, - self.__microseconds * other) + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self.__days * other, + self.__seconds * other, + self.__microseconds * other) return NotImplemented __rmul__ = __mul__ @@ -619,7 +627,7 @@ if isinstance(other, (int, long)): usec = ((self.__days * (24*3600L) + self.__seconds) * 1000000 + self.__microseconds) - return self.__class__(0, 0, usec // other) + return timedelta(0, 0, usec // other) return NotImplemented __floordiv__ = __div__ @@ -728,7 +736,7 @@ if isinstance(year, str): # Pickle support self = object.__new__(cls) - self.__setstate((year,)) + self.__setstate(year) return self _check_date_fields(year, month, day) self = object.__new__(cls) @@ -901,9 +909,10 @@ self.__month, self.__day + other.days) self._checkOverflow(t.year) - result = self.__class__(t.year, t.month, t.day) + result = date(t.year, t.month, t.day) return result - return NotImplemented + raise TypeError + # XXX Should be 'return NotImplemented', but there's a bug in 2.2... __radd__ = __add__ @@ -963,10 +972,9 @@ yhi, ylo = divmod(self.__year, 256) return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) - def __setstate(self, t): - assert isinstance(t, tuple) and len(t) == 1, `t` - string = t[0] - assert len(string) == 4 + def __setstate(self, string): + if len(string) != 4 or not (1 <= ord(string[2]) <= 12): + raise TypeError("not enough arguments") yhi, ylo, self.__month, self.__day = map(ord, string) self.__year = yhi * 256 + ylo @@ -1089,7 +1097,7 @@ self = object.__new__(cls) if isinstance(hour, str): # Pickle support - self.__setstate((hour, minute or None)) + self.__setstate(hour, minute or None) return self _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) @@ -1327,21 +1335,16 @@ else: return (basestate, self._tzinfo) - def __setstate(self, state): - assert isinstance(state, tuple) - assert 1 <= len(state) <= 2 - string = state[0] - assert len(string) == 6 + def __setstate(self, string, tzinfo): + if len(string) != 6 or ord(string[0]) >= 24: + raise TypeError("an integer is required") self.__hour, self.__minute, self.__second, us1, us2, us3 = \ map(ord, string) self.__microsecond = (((us1 << 8) | us2) << 8) | us3 - if len(state) == 1: - self._tzinfo = None - else: - self._tzinfo = state[1] + self._tzinfo = tzinfo def __reduce__(self): - return (self.__class__, self.__getstate()) + return (time, self.__getstate()) _time_class = time # so functions w/ args named "time" can get at the class @@ -1359,7 +1362,7 @@ if isinstance(year, str): # Pickle support self = date.__new__(cls, year[:4]) - self.__setstate((year, month)) + self.__setstate(year, month) return self _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) @@ -1561,7 +1564,7 @@ if L[-1] == 0: del L[-1] if L[-1] == 0: - del L[-1] + del L[-1] s = ", ".join(map(str, L)) s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s) if self._tzinfo is not None: @@ -1625,7 +1628,7 @@ def __eq__(self, other): if isinstance(other, datetime): return self.__cmp(other) == 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: return False @@ -1633,7 +1636,7 @@ def __ne__(self, other): if isinstance(other, datetime): return self.__cmp(other) != 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: return True @@ -1641,7 +1644,7 @@ def __le__(self, other): if isinstance(other, datetime): return self.__cmp(other) <= 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1649,7 +1652,7 @@ def __lt__(self, other): if isinstance(other, datetime): return self.__cmp(other) < 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1657,7 +1660,7 @@ def __ge__(self, other): if isinstance(other, datetime): return self.__cmp(other) >= 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1665,7 +1668,7 @@ def __gt__(self, other): if isinstance(other, datetime): return self.__cmp(other) > 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1713,7 +1716,7 @@ self.__second + other.seconds, self.__microsecond + other.microseconds) self._checkOverflow(t.year) - result = self.__class__(t.year, t.month, t.day, + result = datetime(t.year, t.month, t.day, t.hour, t.minute, t.second, t.microsecond, tzinfo=self._tzinfo) return result @@ -1768,19 +1771,12 @@ else: return (basestate, self._tzinfo) - def __setstate(self, state): - assert isinstance(state, tuple) - assert 1 <= len(state) <= 2 - string = state[0] - assert len(string) == 10 + def __setstate(self, string, tzinfo): (yhi, ylo, self.__month, self.__day, self.__hour, self.__minute, self.__second, us1, us2, us3) = map(ord, string) self.__year = yhi * 256 + ylo self.__microsecond = (((us1 << 8) | us2) << 8) | us3 - if len(state) == 1: - self._tzinfo = None - else: - self._tzinfo = state[1] + self._tzinfo = tzinfo def __reduce__(self): return (self.__class__, self.__getstate()) @@ -2000,9 +1996,3 @@ pretty bizarre, and a tzinfo subclass can override fromutc() if it is. """ -def _test(): - import test_datetime - test_datetime.test_main() - -if __name__ == "__main__": - _test() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-12 09:13:41
|
Revision: 4902 http://jython.svn.sourceforge.net/jython/?rev=4902&view=rev Author: zyasoft Date: 2008-07-12 02:13:38 -0700 (Sat, 12 Jul 2008) Log Message: ----------- Removed tests not appropriate for Jython, test_peepholer, test_profile; added test_strptime, test_csv Modified Paths: -------------- branches/asm/CPythonLib.includes branches/asm/Lib/test/regrtest.py Modified: branches/asm/CPythonLib.includes =================================================================== --- branches/asm/CPythonLib.includes 2008-07-12 01:28:39 UTC (rev 4901) +++ branches/asm/CPythonLib.includes 2008-07-12 09:13:38 UTC (rev 4902) @@ -13,6 +13,7 @@ __future__.py _LWPCookieJar.py _MozillaCookieJar.py +_strptime.py aifc.py anydbm.py atexit.py Modified: branches/asm/Lib/test/regrtest.py =================================================================== --- branches/asm/Lib/test/regrtest.py 2008-07-12 01:28:39 UTC (rev 4901) +++ branches/asm/Lib/test/regrtest.py 2008-07-12 09:13:38 UTC (rev 4902) @@ -1393,7 +1393,6 @@ test_codeop test_commands test_crypt - test_csv test_ctypes test_curses test_dbm @@ -1425,12 +1424,13 @@ test_openpty test_ossaudiodev test_parser + test_peepholer test_plistlib test_poll + test_profile test_pty test_pwd test_pyexpat - test_regex test_resource test_rgbimg test_robotparser @@ -1443,10 +1443,9 @@ test_startfile test_stringprep test_strop - test_strptime + test_structmembers test_sunaudiodev test_sundry - test_structmembers test_symtable test_tcl test_threadsignals @@ -1456,10 +1455,10 @@ test_unicodedata test_wait3 test_wait4 - test_xml_etree_c test_wave test_winreg test_winsound + test_xml_etree_c """ } _expectations['freebsd5'] = _expectations['freebsd4'] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-12 01:28:42
|
Revision: 4901 http://jython.svn.sourceforge.net/jython/?rev=4901&view=rev Author: pjenvey Date: 2008-07-11 18:28:39 -0700 (Fri, 11 Jul 2008) Log Message: ----------- expect test_mhlib to pass on posix and skip elsewhere Modified Paths: -------------- branches/asm/Lib/test/regrtest.py branches/asm/Lib/test/test_mhlib.py Modified: branches/asm/Lib/test/regrtest.py =================================================================== --- branches/asm/Lib/test/regrtest.py 2008-07-12 01:02:08 UTC (rev 4900) +++ branches/asm/Lib/test/regrtest.py 2008-07-12 01:28:39 UTC (rev 4901) @@ -1543,6 +1543,9 @@ for skip in WIN_ONLY: self.expected.add(skip) + if test_support.is_jython and os._name != 'posix': + self.expected.add('test_mhlib') + self.valid = True def isvalid(self): Modified: branches/asm/Lib/test/test_mhlib.py =================================================================== --- branches/asm/Lib/test/test_mhlib.py 2008-07-12 01:02:08 UTC (rev 4900) +++ branches/asm/Lib/test/test_mhlib.py 2008-07-12 01:28:39 UTC (rev 4901) @@ -7,15 +7,13 @@ ### mhlib. It should. import unittest -from test.test_support import run_unittest, TESTFN, TestSkipped, underlying_system +from test.test_support import is_jython, run_unittest, TESTFN, TestSkipped import os, StringIO import sys import mhlib - - -if (underlying_system.startswith("win") or underlying_system=="riscos" or - underlying_system.startswith("atheos")): +if (sys.platform.startswith("win") or sys.platform=="riscos" or + sys.platform.startswith("atheos") or (is_jython and os._name != 'posix')): # mhlib.updateline() renames a file to the name of a file that already # exists. That causes a reasonable OS <wink> to complain in test_sequence # here, like the "OSError: [Errno 17] File exists" raised on Windows. @@ -23,7 +21,7 @@ # link counts, and that causes test_listfolders() here to get back # an empty list from its call of listallfolders(). # The other tests here pass on Windows. - raise TestSkipped("skipped on %s -- " % underlying_system + + raise TestSkipped("skipped on %s -- " % sys.platform + "too many Unix assumptions") _mhroot = TESTFN+"_MH" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-12 01:02:10
|
Revision: 4900 http://jython.svn.sourceforge.net/jython/?rev=4900&view=rev Author: pjenvey Date: 2008-07-11 18:02:08 -0700 (Fri, 11 Jul 2008) Log Message: ----------- Merged revisions 4898-4899 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4899 | pjenvey | 2008-07-11 18:01:18 -0700 (Fri, 11 Jul 2008) | 1 line only match letters and fix end quote situations ........ Modified Paths: -------------- branches/asm/src/org/python/modules/time/Time.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4897 + /trunk/jython:1-4899 Modified: branches/asm/src/org/python/modules/time/Time.java =================================================================== --- branches/asm/src/org/python/modules/time/Time.java 2008-07-12 01:01:18 UTC (rev 4899) +++ branches/asm/src/org/python/modules/time/Time.java 2008-07-12 01:02:08 UTC (rev 4900) @@ -744,7 +744,8 @@ if (!directive) { // ascii letters are considered SimpleDateFormat directive patterns unless // escaped - boolean needsQuote = charAt >= 'A' && charAt <= 'z'; + boolean needsQuote = (charAt >= 'A' && charAt <= 'Z') || + (charAt >= 'a' && charAt <= 'z'); if (needsQuote && !inQuote || !needsQuote && inQuote) { builder.append("'"); inQuote = needsQuote; @@ -753,6 +754,7 @@ continue; } else if (inQuote) { builder.append("'"); + inQuote = false; } String translated = py2java.get(charAt); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-12 01:01:21
|
Revision: 4899 http://jython.svn.sourceforge.net/jython/?rev=4899&view=rev Author: pjenvey Date: 2008-07-11 18:01:18 -0700 (Fri, 11 Jul 2008) Log Message: ----------- only match letters and fix end quote situations Modified Paths: -------------- trunk/jython/src/org/python/modules/time/Time.java Modified: trunk/jython/src/org/python/modules/time/Time.java =================================================================== --- trunk/jython/src/org/python/modules/time/Time.java 2008-07-12 00:54:20 UTC (rev 4898) +++ trunk/jython/src/org/python/modules/time/Time.java 2008-07-12 01:01:18 UTC (rev 4899) @@ -744,7 +744,8 @@ if (!directive) { // ascii letters are considered SimpleDateFormat directive patterns unless // escaped - boolean needsQuote = charAt >= 'A' && charAt <= 'z'; + boolean needsQuote = (charAt >= 'A' && charAt <= 'Z') || + (charAt >= 'a' && charAt <= 'z'); if (needsQuote && !inQuote || !needsQuote && inQuote) { builder.append("'"); inQuote = needsQuote; @@ -753,6 +754,7 @@ continue; } else if (inQuote) { builder.append("'"); + inQuote = false; } String translated = py2java.get(charAt); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-12 00:54:21
|
Revision: 4898 http://jython.svn.sourceforge.net/jython/?rev=4898&view=rev Author: pjenvey Date: 2008-07-11 17:54:20 -0700 (Fri, 11 Jul 2008) Log Message: ----------- Merged revisions 4862-4897 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4886 | pjenvey | 2008-07-10 21:05:51 -0700 (Thu, 10 Jul 2008) | 3 lines preserve and escape strptime format characters that aren't SimpleDateFormat directives ........ Modified Paths: -------------- branches/asm/src/org/python/modules/time/Time.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4861 + /trunk/jython:1-4897 Modified: branches/asm/src/org/python/modules/time/Time.java =================================================================== --- branches/asm/src/org/python/modules/time/Time.java 2008-07-12 00:53:44 UTC (rev 4897) +++ branches/asm/src/org/python/modules/time/Time.java 2008-07-12 00:54:20 UTC (rev 4898) @@ -17,6 +17,7 @@ import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; +import java.util.HashMap; import java.util.Locale; import java.util.TimeZone; import java.text.ParseException; @@ -702,31 +703,62 @@ private static final String DEFAULT_FORMAT_PY = "%a %b %d %H:%M:%S %Y"; private static final String DEFAULT_FORMAT_JA = "EEE MMM dd HH:mm:ss zzz yyyy"; + private static final HashMap<Character, String> py2java = new HashMap<Character, String>() {{ + put('a', "EEE"); + put('A', "EEEE"); + put('b', "MMM"); + put('B', "MMMM"); + put('c', "EEE MMM dd HH:mm:ss yyyy"); + put('d', "dd"); + put('H', "HH"); + put('I', "kk"); + put('j', "DDD"); + put('m', "MM"); + put('M', "mm"); + put('p', "a"); + put('S', "ss"); + put('U', "ww"); + put('w', "0"); // unsupported in java + put('W', "ww"); // same as U ?? + put('x', "MM/dd/yy"); + put('X', "HH:mm:ss"); + put('y', "yy"); + put('Y', "yyyy"); + put('Z', "zzz"); + put('%', "%"); + }}; + private static String py2java_format(String format) { - format = format - .replaceAll("%a", "EEE") - .replaceAll("%A", "EEEE") - .replaceAll("%b", "MMM") - .replaceAll("%B", "MMMM") - .replaceAll("%c", "EEE MMM dd HH:mm:ss yyyy") - .replaceAll("%d", "dd") - .replaceAll("%H", "HH") - .replaceAll("%I", "kk") - .replaceAll("%j", "DDD") - .replaceAll("%m", "MM") - .replaceAll("%M", "mm") - .replaceAll("%p", "a") - .replaceAll("%S", "ss") - .replaceAll("%U", "ww") - .replaceAll("%w", "0") // unsupported in java - .replaceAll("%W", "ww") // same as %U ?? - .replaceAll("%x", "MM/dd/yy") - .replaceAll("%X", "HH:mm:ss") - .replaceAll("%y", "yy") - .replaceAll("%Y", "yyyy") - .replaceAll("%Z", "zzz") - .replaceAll("%%", "%") - ; - return format; + StringBuilder builder = new StringBuilder(); + boolean directive = false; + boolean inQuote = false; + + for (int i = 0; i < format.length(); i++) { + char charAt = format.charAt(i); + + if (charAt == '%' && !directive) { + directive = true; + continue; + } + + if (!directive) { + // ascii letters are considered SimpleDateFormat directive patterns unless + // escaped + boolean needsQuote = charAt >= 'A' && charAt <= 'z'; + if (needsQuote && !inQuote || !needsQuote && inQuote) { + builder.append("'"); + inQuote = needsQuote; + } + builder.append(charAt); + continue; + } else if (inQuote) { + builder.append("'"); + } + + String translated = py2java.get(charAt); + builder.append(translated != null ? translated : charAt); + directive = false; + } + return builder.toString(); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-12 00:53:45
|
Revision: 4897 http://jython.svn.sourceforge.net/jython/?rev=4897&view=rev Author: pjenvey Date: 2008-07-11 17:53:44 -0700 (Fri, 11 Jul 2008) Log Message: ----------- fake reload(sys), like reload(PyJavaClass). fix ClassCastException in reload Modified Paths: -------------- branches/asm/src/org/python/core/__builtin__.java Modified: branches/asm/src/org/python/core/__builtin__.java =================================================================== --- branches/asm/src/org/python/core/__builtin__.java 2008-07-12 00:33:21 UTC (rev 4896) +++ branches/asm/src/org/python/core/__builtin__.java 2008-07-12 00:53:44 UTC (rev 4897) @@ -94,7 +94,10 @@ if (o == Py.NoConversion) { o = arg1.__tojava__(PyJavaClass.class); if (o == Py.NoConversion) { - Py.TypeError("reload() argument must be a module"); + if (arg1 instanceof PySystemState) { + return __builtin__.reload((PySystemState)arg1); + } + throw Py.TypeError("reload() argument must be a module"); } return __builtin__.reload((PyJavaClass) o); } @@ -988,6 +991,11 @@ return imp.reload(o); } + public static PyObject reload(PySystemState o) { + // fake it like imp.reload(PyJavaClass) does + return o; + } + public static PyString repr(PyObject o) { return o.__repr__(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |