From 169de85aca1a527ea42ef102aa32a40ba1740168 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: May 02 2011 18:46:32 +0000 Subject: Rebase to 1.5 (rhbz#701121) Update patches: patch 0: pypy-1.4-config.patch -> pypy-1.5-config.patch patch 4: pypy-1.4.1-more-readable-c-code.patch -> pypy-1.5-more-readable-c-code.patch Remove references to *.inl files, no longer present Add the following tests to the skip list: test_audioop, test_capi, test_distutils, test_gc, test_gdb, test_generators, test_getargs2, test_hotshot, test_io, test_multiprocessing, test_posix, test_readline, test_scope, test_strop, test_structmembers, test_subprocess, test_symtable, test_sys_settrace, test_tempfile, test_thread, test_uuid, test_zipimport_support Add a couple of text files to the payload (TODO, stdlib-version.txt) --- diff --git a/.gitignore b/.gitignore index 2878978..017cf34 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /pypy-1.4.1-src.tar.bz2 +/pypy-1.5-src.tar.bz2 diff --git a/pypy-1.4-config.patch b/pypy-1.4-config.patch deleted file mode 100644 index 0b82ac8..0000000 --- a/pypy-1.4-config.patch +++ /dev/null @@ -1,44 +0,0 @@ -Index: pypy-1.4/pypy/translator/platform/linux.py -=================================================================== ---- pypy-1.4.orig/pypy/translator/platform/linux.py -+++ pypy-1.4/pypy/translator/platform/linux.py -@@ -3,17 +3,22 @@ import py, os - from pypy.translator.platform import _run_subprocess - from pypy.translator.platform.posix import BasePosix - -+CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer', -+ '-Wall', '-Wno-unused'] -+if os.environ.get('CFLAGS', None): -+ CFLAGS.extend(os.environ['CFLAGS'].split()) -+CFLAGS = tuple(CFLAGS) -+ - class BaseLinux(BasePosix): - name = "linux" - - link_flags = ('-pthread', '-lrt') -- cflags = ('-O3', '-pthread', '-fomit-frame-pointer', -- '-Wall', '-Wno-unused') -+ cflags = CFLAGS - standalone_only = () - shared_only = ('-fPIC',) - so_ext = 'so' - so_prefixes = ('lib', '') -- -+ - def _args_for_shared(self, args): - return ['-shared'] + args - -@@ -29,9 +34,10 @@ class BaseLinux(BasePosix): - class Linux(BaseLinux): - shared_only = () # it seems that on 32-bit linux, compiling with -fPIC - # gives assembler that asmgcc is not happy about. -- def library_dirs_for_libffi_a(self): -- # places where we need to look for libffi.a -- return self.library_dirs_for_libffi() + ['/usr/lib'] -+ # Fedora Linux, at least, has the shared version but not the static -+ #def library_dirs_for_libffi_a(self): -+ # # places where we need to look for libffi.a -+ # return self.library_dirs_for_libffi() + ['/usr/lib'] - - - class Linux64(BaseLinux): diff --git a/pypy-1.4.1-more-readable-c-code.patch b/pypy-1.4.1-more-readable-c-code.patch deleted file mode 100644 index 45fa534..0000000 --- a/pypy-1.4.1-more-readable-c-code.patch +++ /dev/null @@ -1,695 +0,0 @@ -diff -r cd083843b67a pypy/interpreter/pycode.py ---- a/pypy/interpreter/pycode.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/interpreter/pycode.py Wed Jan 05 16:14:35 2011 -0500 -@@ -14,6 +14,7 @@ - from pypy.interpreter.astcompiler.consts import (CO_OPTIMIZED, - CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED, - CO_GENERATOR, CO_CONTAINSGLOBALS) -+from pypy.interpreter.pytraceback import offset2lineno - from pypy.rlib.rarithmetic import intmask - from pypy.rlib.debug import make_sure_not_resized - from pypy.rlib import jit -@@ -81,6 +82,7 @@ - self.hidden_applevel = hidden_applevel - self.magic = magic - self._signature = cpython_code_signature(self) -+ self._cached_source = None - self._initialize() - - def _initialize(self): -@@ -403,3 +405,25 @@ - def repr(self, space): - return space.wrap(self.get_repr()) - repr.unwrap_spec = ['self', ObjSpace] -+ -+ def get_linenum_for_offset(self, offset): -+ # Given a bytecode offset, return a 1-based index into the lines of the -+ # source code -+ return offset2lineno(self, offset) -+ -+ def _ensure_source(self): -+ # Lazily grab the source lines into self._cached_source (or raise -+ # an IOError) -+ if not self._cached_source: -+ f = open(self.co_filename, 'r') -+ source = [line.rstrip() for line in f.readlines()] -+ f.close() -+ self._cached_source = source -+ -+ def get_source_text(self, linenum): -+ # Given a 1-based index, get the corresponding line of source code (or -+ # raise an IOError) -+ self._ensure_source() -+ return self._cached_source[linenum - 1] -+ -+ -diff -r cd083843b67a pypy/objspace/flow/model.py ---- a/pypy/objspace/flow/model.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/objspace/flow/model.py Wed Jan 05 16:14:35 2011 -0500 -@@ -31,6 +31,120 @@ - - __metaclass__ = type - -+class SourceLoc(object): -+ # A srcloc is a specific location within the RPython source code, -+ # intended for human display -+ __slots__ = ('code', # code object -+ 'linenum' # 1-based index, as displayed to a user -+ ) -+ def __init__(self, code, linenum): -+ self.code = code -+ self.linenum = linenum -+ -+ def get_text(self): -+ # Get the actual source text of this line -+ return self.code.get_source_text(self.linenum) -+ -+ def __eq__(self, other): -+ return self.code == other.code and self.linenum == other.linenum -+ -+ def __ne__(self, other): -+ if other: -+ return self.code != other.code or self.linenum != other.linenum -+ else: -+ return True -+ -+class CodeLoc(object): -+ # A codeloc is a specific location within the RPython bytecode -+ __slots__ = ('code', # code object -+ 'offset' # int index into bytecode, or -1 -+ ) -+ -+ def __init__(self, code, offset): -+ self.code = code -+ self.offset = offset -+ -+ def __str__(self): -+ if self.offset >= 0: -+ return "%s@%d" % (self.code.co_name, self.offset) -+ else: -+ return "" -+ -+ def __ne__(self, other): -+ if other: -+ return self.code != other.code or self.offset != other.offset -+ else: -+ return True -+ -+ def __cmp__(self, other): -+ # Partial ordering, for those locations that have an offset: -+ if other: -+ if self.offset >= 0 and other.offset >= 0: -+ return self.offset - other.offset -+ return 0 -+ -+ def get_source_loc(self): -+ # Convert to a SourceLoc: -+ return SourceLoc(self.code, self.code.get_linenum_for_offset(self.offset)) -+ -+class OperationLoc(object): -+ # An oploc is the location within the RPython source code of a given -+ # operation -+ # -+ # This is a list consisting of CodeLoc instances, some of which may be None -+ # -+ # For the simple case, this is list of length 1 with a single CodeLoc -+ # -+ # For an operation inside an inlined callsite, we have a list of length 2: -+ # [codeloc of callsite, -+ # codeloc of operation within inlined body] -+ # -+ # For more interesting inlined cases, we have a chain of source locations: -+ # [codeloc of callsite, -+ # codeloc of inner callsite, -+ # ... , -+ # codeloc of innermost inlined callsite, -+ # codeloc of operation within inlined body] -+ # -+ -+ __slots__ = ('codelocs', ) -+ -+ def __init__(self, codelocs): -+ self.codelocs = codelocs -+ -+ def __str__(self): -+ return '[' + ' > '.join(str(codeloc) for codeloc in self.codelocs) + ']' -+ -+ def __cmp__(self, other): -+ return cmp(self.codelocs, other.codelocs) -+ -+def block_comparator(blk0, blk1): -+ ''' -+ Sort function for blocks, putting them in an ordering that attempts to -+ maximize readability of the generated C code -+ ''' -+ # print 'comparing %r and %r' % (blk0, blk1) -+ # Put the start/end block at the top/bottom: -+ if blk0.isstartblock: -+ return -1 -+ -+ if blk1.isstartblock: -+ return 1 -+ -+ # Order blocks by the offset, where present: -+ if blk0.operations: -+ if blk1.operations: -+ return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc) -+ else: -+ return -1 -+ else: -+ if blk1.operations: -+ return 1 -+ else: -+ return 0 -+ -+def edge_comparator(edge0, edge1): -+ return block_comparator(edge0.target, edge1.target) - - class FunctionGraph(object): - __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__'] -@@ -94,6 +208,21 @@ - seen[block] = True - stack += block.exits[::-1] - -+ def iterblocks_by_source(self): -+ # Try to preserve logical source ordering in the blocks -+ block = self.startblock -+ yield block -+ seen = {block: True} -+ stack = list(block.exits[::-1]) -+ stack.sort(edge_comparator) -+ while stack: -+ block = stack.pop().target -+ if block not in seen: -+ yield block -+ seen[block] = True -+ stack += block.exits[::-1] -+ stack.sort(edge_comparator) -+ - def iterlinks(self): - block = self.startblock - seen = {block: True} -@@ -183,14 +312,14 @@ - self.exits = [] # list of Link(s) - - def at(self): -- if self.operations and self.operations[0].offset >= 0: -- return "@%d" % self.operations[0].offset -+ if self.operations: -+ return str(self.operations[0].oploc) - else: - return "" - - def __str__(self): - if self.operations: -- txt = "block@%d" % self.operations[0].offset -+ txt = "block%s" % self.operations[0].oploc - else: - if (not self.exits) and len(self.inputargs) == 1: - txt = "return block" -@@ -245,6 +374,21 @@ - from pypy.translator.tool.graphpage import try_show - try_show(self) - -+ def isreturnblock(self): -+ return (not self.operations) and (not self.exits) and len(self.inputargs) == 1 -+ -+ def get_base_label(self, blocknum): -+ # Generate a more friendly C label for this block -+ if self.operations: -+ txt = "block" -+ elif (not self.exits) and len(self.inputargs) == 1: -+ txt = "return_block" -+ elif (not self.exits) and len(self.inputargs) == 2: -+ txt = "raise_block" -+ else: -+ txt = "codeless_block" -+ return '%s%d' % (txt, blocknum) -+ - - class Variable(object): - __slots__ = ["_name", "_nr", "concretetype"] -@@ -331,13 +475,15 @@ - - - class SpaceOperation(object): -- __slots__ = "opname args result offset".split() -+ __slots__ = "opname args result oploc".split() - -- def __init__(self, opname, args, result, offset=-1): -+ def __init__(self, opname, args, result, oploc=None): - self.opname = intern(opname) # operation name - self.args = list(args) # mixed list of var/const - self.result = result # either Variable or Constant instance -- self.offset = offset # offset in code string -+ if oploc is None: -+ oploc = OperationLoc([None]) -+ self.oploc = oploc - - def __eq__(self, other): - return (self.__class__ is other.__class__ and -@@ -352,8 +498,9 @@ - return hash((self.opname,tuple(self.args),self.result)) - - def __repr__(self): -- return "%r = %s(%s)" % (self.result, self.opname, -- ", ".join(map(repr, self.args))) -+ return "%r = %s(%s) (%s)" % (self.result, self.opname, -+ ", ".join(map(repr, self.args)), -+ self.oploc) - - class Atom(object): - def __init__(self, name): -@@ -448,8 +595,7 @@ - for op in oplist: - copyop = SpaceOperation(op.opname, - [copyvar(v) for v in op.args], -- copyvar(op.result), op.offset) -- #copyop.offset = op.offset -+ copyvar(op.result), op.oploc) - result.append(copyop) - return result - newblock.operations = copyoplist(block.operations) -diff -r cd083843b67a pypy/objspace/flow/objspace.py ---- a/pypy/objspace/flow/objspace.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/objspace/flow/objspace.py Wed Jan 05 16:14:35 2011 -0500 -@@ -310,7 +310,9 @@ - def do_operation(self, name, *args_w): - spaceop = SpaceOperation(name, args_w, Variable()) - if hasattr(self, 'executioncontext'): # not here during bootstrapping -- spaceop.offset = self.executioncontext.crnt_offset -+ codeloc = CodeLoc(self.executioncontext.code, -+ self.executioncontext.crnt_offset) -+ spaceop.oploc = OperationLoc([codeloc]) - self.executioncontext.recorder.append(spaceop) - return spaceop.result - -diff -r cd083843b67a pypy/objspace/flow/test/test_model.py ---- a/pypy/objspace/flow/test/test_model.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/objspace/flow/test/test_model.py Wed Jan 05 16:14:35 2011 -0500 -@@ -132,3 +132,25 @@ - assert v2.renamed - assert v2.name.startswith("foobar_") and v2.name != v.name - assert v2.name.split('_', 1)[1].isdigit() -+ -+def test_source_locations(): -+ # Invent some random offsets into the code: -+ co = sample_function.__code__ -+ codelocA = CodeLoc(co, 42) -+ codelocB = CodeLoc(co, 87) -+ -+ assert str(codelocA) == 'sample_function@42' -+ assert str(codelocB) == 'sample_function@87' -+ -+ assert cmp(codelocA, codelocB) < 0 -+ assert cmp(codelocB, codelocA) > 0 -+ -+ oplocA = OperationLoc([codelocA]) -+ oplocB = OperationLoc([codelocB]) -+ -+ assert str(oplocA) == '[sample_function@42]' -+ assert str(oplocB) == '[sample_function@87]' -+ -+ assert cmp(oplocA, oplocB) < 0 -+ assert cmp(oplocB, oplocA) > 0 -+ -diff -r cd083843b67a pypy/rpython/rtyper.py ---- a/pypy/rpython/rtyper.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/rpython/rtyper.py Wed Jan 05 16:14:35 2011 -0500 -@@ -800,7 +800,7 @@ - return vars - - def genop(self, opname, args_v, resulttype=None): -- return self.llops.genop(opname, args_v, resulttype) -+ return self.llops.genop(opname, args_v, resulttype, self.spaceop.oploc) - - def gendirectcall(self, ll_function, *args_v): - return self.llops.gendirectcall(ll_function, *args_v) -@@ -935,7 +935,7 @@ - v.concretetype)) - return v - -- def genop(self, opname, args_v, resulttype=None): -+ def genop(self, opname, args_v, resulttype=None, oploc=None): - try: - for v in args_v: - v.concretetype -@@ -944,7 +944,7 @@ - " and pass its result to genop()," - " never hop.args_v directly.") - vresult = Variable() -- self.append(SpaceOperation(opname, args_v, vresult)) -+ self.append(SpaceOperation(opname, args_v, vresult, oploc)) - if resulttype is None: - vresult.concretetype = Void - return None -diff -r cd083843b67a pypy/translator/backendopt/inline.py ---- a/pypy/translator/backendopt/inline.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/translator/backendopt/inline.py Wed Jan 05 16:14:35 2011 -0500 -@@ -4,6 +4,7 @@ - from pypy.translator.unsimplify import copyvar - from pypy.objspace.flow.model import Variable, Constant, Block, Link - from pypy.objspace.flow.model import SpaceOperation, c_last_exception -+from pypy.objspace.flow.model import OperationLoc - from pypy.objspace.flow.model import FunctionGraph - from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph - from pypy.annotation import model as annmodel -@@ -231,6 +232,7 @@ - self.varmap = {} - self._copied_blocks = {} - self.op = block.operations[index_operation] -+ self.callsite_oploc = self.op.oploc - self.graph_to_inline = self.get_graph_from_op(self.op) - self.exception_guarded = False - if (block.exitswitch == c_last_exception and -@@ -297,7 +299,9 @@ - - def copy_operation(self, op): - args = [self.get_new_name(arg) for arg in op.args] -- result = SpaceOperation(op.opname, args, self.get_new_name(op.result)) -+ new_oploc = OperationLoc(self.callsite_oploc.codelocs[:] + op.oploc.codelocs[:]) -+ result = SpaceOperation(op.opname, args, self.get_new_name(op.result), -+ new_oploc) - return result - - def copy_block(self, block): -diff -r cd083843b67a pypy/translator/c/funcgen.py ---- a/pypy/translator/c/funcgen.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/translator/c/funcgen.py Wed Jan 05 16:14:35 2011 -0500 -@@ -1,4 +1,6 @@ - import sys -+import inspect -+import dis - from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring - from pypy.translator.c.support import cdecl - from pypy.translator.c.support import llvalue_from_constant, gen_assignments -@@ -22,6 +24,38 @@ - - KEEP_INLINED_GRAPHS = False - -+def block_comparator(blk0, blk1): -+ ''' -+ Sort function for blocks, putting them in an ordering that attempts to -+ maximize readability of the generated C code -+ ''' -+ # print 'comparing %r and %r' % (blk0, blk1) -+ # Put the start/end block at the top/bottom: -+ if blk0.isstartblock: -+ return -1 -+ -+ if blk1.isstartblock: -+ return 1 -+ -+ # Order blocks by the offset, where present: -+ if blk0.operations: -+ if blk1.operations: -+ return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc) -+ else: -+ return -1 -+ else: -+ if blk1.operations: -+ return 1 -+ else: -+ return 0 -+ -+def escape_c_comments(py_src): -+ # Escape C comments within RPython source, to avoid generating bogus -+ # comments in our generated C source: -+ py_src = py_src.replace('/*', '') -+ py_src = py_src.replace('*/', '') -+ return py_src -+ - class FunctionCodeGenerator(object): - """ - Collects information about a function which we have to generate -@@ -210,14 +244,57 @@ - - def cfunction_body(self): - graph = self.graph -- yield 'goto block0;' # to avoid a warning "this label is not used" -+ # Try to print python source code: -+ if hasattr(graph, 'func'): -+ filename = inspect.getfile(graph.func) -+ #yield '/* name: %r */' % filename -+ try: -+ src, startline = inspect.getsourcelines(graph.func) -+ except IOError: -+ pass # No source found -+ except IndexError: -+ pass # Bulletproofing -+ else: -+ yield '/* Python source %r' % filename -+ for i, line in enumerate(src): -+ line = line.rstrip() -+ line = escape_c_comments(line) -+ # FuncNode.funcgen_implementation treats lines ending in ':' -+ # as C blocks, which messes up the formatting. -+ # Work around this: -+ if line.endswith(':'): -+ line += ' ' -+ yield ' * %4d : %s' % (startline + i, line) -+ yield ' */' -+ -+ label = graph.startblock.get_base_label(self.blocknum[graph.startblock]) -+ yield 'goto %s;' % label # to avoid a warning "this label is not used" -+ -+ # Sort the blocks into a (hopefully) readable order: -+ blocks = list(graph.iterblocks_by_source()) -+ blocks.sort(block_comparator) - - # generate the body of each block -- for block in graph.iterblocks(): -+ for block in blocks: -+ cursrcloc = None - myblocknum = self.blocknum[block] - yield '' -- yield 'block%d:' % myblocknum -+ yield '%s:' % block.get_base_label(myblocknum) -+ #yield "/* repr(block): %r */" % (block, ) -+ #yield "/* type(block): %r */" % (type(block), ) - for i, op in enumerate(block.operations): -+ #yield "/* type(op): %r */" % (type(op), ) -+ #yield "/* op.oploc: %s */" % (op.oploc, ) -+ codeloc = op.oploc.codelocs[-1] -+ if codeloc: -+ srcloc = codeloc.get_source_loc() -+ if srcloc != cursrcloc: -+ try: -+ yield "/* %s:%d : %s */" % (codeloc.code.co_name, srcloc.linenum, escape_c_comments(srcloc.get_text())) -+ cursrcloc = srcloc -+ except IOError: -+ pass -+ - for line in self.gen_op(op): - yield line - if len(block.exits) == 0: -@@ -310,7 +387,7 @@ - assignments.append((a2typename, dest, src)) - for line in gen_assignments(assignments): - yield line -- label = 'block%d' % self.blocknum[link.target] -+ label = link.target.get_base_label(self.blocknum[link.target]) - if link.target in self.innerloops: - loop = self.innerloops[link.target] - if link is loop.links[-1]: # link that ends a loop -diff -r cd083843b67a pypy/translator/c/test/test_genc.py ---- a/pypy/translator/c/test/test_genc.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/translator/c/test/test_genc.py Wed Jan 05 16:14:35 2011 -0500 -@@ -1,4 +1,5 @@ - import autopath, sys, os, py -+import re - from pypy.rpython.lltypesystem.lltype import * - from pypy.annotation import model as annmodel - from pypy.translator.translator import TranslationContext -@@ -498,3 +499,130 @@ - else: - assert 0, "the call was not found in the C source" - assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1] -+ -+def get_generated_c_source(fn, types): -+ # Return a (optimized fn, c source code, c source filename) 3-tuple -+ t = Translation(fn) -+ t.annotate(types) -+ c_filename_path = t.source_c() -+ h = c_filename_path.open() -+ src = h.read() -+ h.close() -+ c_fn = t.compile_c() -+ return (c_fn, src, c_filename_path) -+ -+def extract_c_function(c_src, fname): -+ # Extract the source for a given C function out of a the given src string -+ # Makes assumptions about the layout of the source -+ pattern = '^(.+) \**%s\(.*\) {$' % fname -+ within_fn = False -+ result = '' -+ for line in c_src.splitlines(): -+ if within_fn: -+ result += line + '\n' -+ if line.startswith('}'): -+ return result -+ else: -+ m = re.match(pattern, line) -+ if m: -+ within_fn = True -+ result += line + '\n' -+ return result -+ -+ -+ -+def test_generated_c_source(): -+ # Verify that generate C source "looks good" -+ # We'll use is_perfect_number, as it contains a loop and a conditional -+ -+ # Generate C source code -+ from pypy.translator.test.snippet import is_perfect_number -+ c_fn, c_src, c_filename_path = get_generated_c_source(is_perfect_number, -+ [int]) -+ -+ # Locate the C source for the type-specialized function: -+ c_fn_src = extract_c_function(c_src, 'pypy_g_is_perfect_number') -+ -+ # Verify that the C source contains embedded comments containing the lines -+ # of the python source: -+ expected_comment_lines = [ -+ '/* is_perfect_number:31 : while div < n: */', -+ '/* is_perfect_number:32 : if n % div == 0: */', -+ '/* is_perfect_number:33 : sum += div */', -+ '/* is_perfect_number:34 : div += 1 */', -+ '/* is_perfect_number:35 : return n == sum */'] -+ for exp_line in expected_comment_lines: -+ assert exp_line in c_fn_src -+ -+ # Verify that the lines occur in the correct order -+ # ...we do this by filtering the function's generated C source to just -+ # those lines containing our comments (and dropping whitespace): -+ lines = c_fn_src.splitlines() -+ lines = [line.strip() -+ for line in lines -+ if '/* is_perfect_number:' in line] -+ -+ # ...we should now have exact equality: the ordering should be as expected, -+ # and each comment should appear exactly once: -+ assert lines == expected_comment_lines -+ -+ # Ensure that the generated C function does the right thing: -+ assert c_fn(5) == False -+ assert c_fn(6) == True -+ assert c_fn(7) == False -+ -+ assert c_fn(5.0) == False -+ assert c_fn(6.0) == True -+ assert c_fn(7.0) == False -+ -+ assert c_fn(5L) == False -+ assert c_fn(6L) == True -+ assert c_fn(7L) == False -+ -+ try: -+ c_fn('hello world') -+ except: -+ pass -+ else: -+ raise 'Was expected exception' -+ -+def test_escaping_c_comments(): -+ # Ensure that c comments within RPython code get escaped when we generate -+ # our .c code (to avoid generating bogus C) -+ # See e.g. pypy.module.cpyext.dictobject's PyDict_Next, which has a -+ # docstring embedding a C comment -+ def c_style_comment(a, b): -+ '''Here is a C-style comment within an RPython docstring: -+ /* hello world */ -+ ''' -+ # and here's one in a string literal: -+ return '/* hello world a:%s b:%s */' % (a, b) -+ -+ def cplusplus_style_comment(a, b): -+ '''Here is a C++-style comment within an RPython docstring: -+ // hello world -+ ''' -+ # and here are some in string literals, and one as the floor division -+ # operator: -+ return '// hello world: a // b = %s' % (a // b) -+ -+ for fn_name, exp_output in [('c_style_comment', -+ '/* hello world a:6 b:3 */'), -+ ('cplusplus_style_comment', -+ '// hello world: a // b = 2')]: -+ fn = locals()[fn_name] -+ -+ c_fn, c_src, c_filename_path = get_generated_c_source(fn, [int, int]) -+ # If the above survived, then the C compiler managed to handle -+ # the generated C code -+ -+ # Verify that the generated code works (i.e. that we didn't -+ # accidentally change the meaning): -+ assert c_fn(6, 3) == exp_output -+ -+ # Ensure that at least part of the docstrings made it into the C -+ # code: -+ c_fn_src = extract_c_function(c_src, 'pypy_g_' + fn_name) -+ assert 'Here is a ' in c_fn_src -+ assert 'style comment within an RPython docstring' in c_fn_src -+ -diff -r cd083843b67a pypy/translator/driver.py ---- a/pypy/translator/driver.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/translator/driver.py Wed Jan 05 16:14:35 2011 -0500 -@@ -539,6 +539,7 @@ - dstname = self.compute_exe_name() + '.staticdata.info' - shutil.copy(str(fname), str(dstname)) - self.log.info('Static data info written to %s' % dstname) -+ return c_source_filename - - # - task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source") -diff -r cd083843b67a pypy/translator/gensupp.py ---- a/pypy/translator/gensupp.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/translator/gensupp.py Wed Jan 05 16:14:35 2011 -0500 -@@ -16,8 +16,8 @@ - def visit(block): - if isinstance(block, Block): - # first we order by offset in the code string -- if block.operations: -- ofs = block.operations[0].offset -+ if block.operations and block.operations[0].oploc.codelocs[0]: -+ ofs = block.operations[0].oploc.codelocs[0].offset - else: - ofs = sys.maxint - # then we order by input variable name or value -diff -r cd083843b67a pypy/translator/interactive.py ---- a/pypy/translator/interactive.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/translator/interactive.py Wed Jan 05 16:14:35 2011 -0500 -@@ -138,7 +138,7 @@ - def source_c(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) - self.ensure_backend('c') -- self.driver.source_c() -+ return self.driver.source_c() - - def source_cl(self, argtypes=None, **kwds): - self.update_options(argtypes, kwds) -diff -r cd083843b67a pypy/translator/llsupport/wrapper.py ---- a/pypy/translator/llsupport/wrapper.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/translator/llsupport/wrapper.py Wed Jan 05 16:14:35 2011 -0500 -@@ -59,6 +59,8 @@ - # "return result" - block = Block(wrapper_inputargs) - wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block) -+ if hasattr(graph, 'func'): -+ wgraph.func = graph.func - translator.update_call_graph(wgraph, graph, object()) - translator.graphs.append(wgraph) - block.operations[:] = newops -diff -r cd083843b67a pypy/translator/simplify.py ---- a/pypy/translator/simplify.py Mon Dec 20 17:17:45 2010 +0100 -+++ b/pypy/translator/simplify.py Wed Jan 05 16:14:35 2011 -0500 -@@ -294,7 +294,7 @@ - return renaming.get(v, v) - def rename_op(op): - args = [rename(a) for a in op.args] -- op = SpaceOperation(op.opname, args, rename(op.result), op.offset) -+ op = SpaceOperation(op.opname, args, rename(op.result), op.oploc) - # special case... - if op.opname == 'indirect_call': - if isinstance(op.args[0], Constant): diff --git a/pypy-1.5-config.patch b/pypy-1.5-config.patch new file mode 100644 index 0000000..82d8fc9 --- /dev/null +++ b/pypy-1.5-config.patch @@ -0,0 +1,39 @@ +diff -up pypy-1.5-src/pypy/translator/platform/linux.py.configure-fedora pypy-1.5-src/pypy/translator/platform/linux.py +--- pypy-1.5-src/pypy/translator/platform/linux.py.configure-fedora 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/translator/platform/linux.py 2011-04-30 18:59:24.041160978 -0400 +@@ -1,13 +1,18 @@ + """Support for Linux.""" +- ++import os + from pypy.translator.platform.posix import BasePosix + ++CFLAGS = ['-O3', '-pthread', '-fomit-frame-pointer', ++ '-Wall', '-Wno-unused'] ++if os.environ.get('CFLAGS', None): ++ CFLAGS.extend(os.environ['CFLAGS'].split()) ++CFLAGS = tuple(CFLAGS) ++ + class BaseLinux(BasePosix): + name = "linux" + + link_flags = ('-pthread', '-lrt') +- cflags = ('-O3', '-pthread', '-fomit-frame-pointer', +- '-Wall', '-Wno-unused') ++ cflags = CFLAGS + standalone_only = () + shared_only = ('-fPIC',) + so_ext = 'so' +@@ -29,9 +34,10 @@ class Linux(BaseLinux): + shared_only = () # it seems that on 32-bit linux, compiling with -fPIC + # gives assembler that asmgcc is not happy about. + +- def library_dirs_for_libffi_a(self): +- # places where we need to look for libffi.a +- return self.library_dirs_for_libffi() + ['/usr/lib'] ++ # Fedora Linux, at least, has the shared version but not the static ++ #def library_dirs_for_libffi_a(self): ++ # # places where we need to look for libffi.a ++ # return self.library_dirs_for_libffi() + ['/usr/lib'] + + + class Linux64(BaseLinux): diff --git a/pypy-1.5-more-readable-c-code.patch b/pypy-1.5-more-readable-c-code.patch new file mode 100644 index 0000000..b7103e2 --- /dev/null +++ b/pypy-1.5-more-readable-c-code.patch @@ -0,0 +1,693 @@ +diff -up pypy-1.5-src/pypy/interpreter/pycode.py.more-readable-c-code pypy-1.5-src/pypy/interpreter/pycode.py +--- pypy-1.5-src/pypy/interpreter/pycode.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/interpreter/pycode.py 2011-05-02 14:28:33.942161002 -0400 +@@ -13,6 +13,7 @@ from pypy.interpreter.gateway import Non + from pypy.interpreter.astcompiler.consts import (CO_OPTIMIZED, + CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED, + CO_GENERATOR, CO_CONTAINSGLOBALS) ++from pypy.interpreter.pytraceback import offset2lineno + from pypy.rlib.rarithmetic import intmask + from pypy.rlib.debug import make_sure_not_resized + from pypy.rlib import jit +@@ -80,6 +81,7 @@ class PyCode(eval.Code): + self.hidden_applevel = hidden_applevel + self.magic = magic + self._signature = cpython_code_signature(self) ++ self._cached_source = None + self._initialize() + + def _initialize(self): +@@ -396,3 +398,23 @@ class PyCode(eval.Code): + + def repr(self, space): + return space.wrap(self.get_repr()) ++ ++ def get_linenum_for_offset(self, offset): ++ # Given a bytecode offset, return a 1-based index into the lines of the ++ # source code ++ return offset2lineno(self, offset) ++ ++ def _ensure_source(self): ++ # Lazily grab the source lines into self._cached_source (or raise ++ # an IOError) ++ if not self._cached_source: ++ f = open(self.co_filename, 'r') ++ source = [line.rstrip() for line in f.readlines()] ++ f.close() ++ self._cached_source = source ++ ++ def get_source_text(self, linenum): ++ # Given a 1-based index, get the corresponding line of source code (or ++ # raise an IOError) ++ self._ensure_source() ++ return self._cached_source[linenum - 1] +diff -up pypy-1.5-src/pypy/objspace/flow/model.py.more-readable-c-code pypy-1.5-src/pypy/objspace/flow/model.py +--- pypy-1.5-src/pypy/objspace/flow/model.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/objspace/flow/model.py 2011-05-02 14:28:33.942161002 -0400 +@@ -31,6 +31,120 @@ from pypy.tool.identity_dict import iden + + __metaclass__ = type + ++class SourceLoc(object): ++ # A srcloc is a specific location within the RPython source code, ++ # intended for human display ++ __slots__ = ('code', # code object ++ 'linenum' # 1-based index, as displayed to a user ++ ) ++ def __init__(self, code, linenum): ++ self.code = code ++ self.linenum = linenum ++ ++ def get_text(self): ++ # Get the actual source text of this line ++ return self.code.get_source_text(self.linenum) ++ ++ def __eq__(self, other): ++ return self.code == other.code and self.linenum == other.linenum ++ ++ def __ne__(self, other): ++ if other: ++ return self.code != other.code or self.linenum != other.linenum ++ else: ++ return True ++ ++class CodeLoc(object): ++ # A codeloc is a specific location within the RPython bytecode ++ __slots__ = ('code', # code object ++ 'offset' # int index into bytecode, or -1 ++ ) ++ ++ def __init__(self, code, offset): ++ self.code = code ++ self.offset = offset ++ ++ def __str__(self): ++ if self.offset >= 0: ++ return "%s@%d" % (self.code.co_name, self.offset) ++ else: ++ return "" ++ ++ def __ne__(self, other): ++ if other: ++ return self.code != other.code or self.offset != other.offset ++ else: ++ return True ++ ++ def __cmp__(self, other): ++ # Partial ordering, for those locations that have an offset: ++ if other: ++ if self.offset >= 0 and other.offset >= 0: ++ return self.offset - other.offset ++ return 0 ++ ++ def get_source_loc(self): ++ # Convert to a SourceLoc: ++ return SourceLoc(self.code, self.code.get_linenum_for_offset(self.offset)) ++ ++class OperationLoc(object): ++ # An oploc is the location within the RPython source code of a given ++ # operation ++ # ++ # This is a list consisting of CodeLoc instances, some of which may be None ++ # ++ # For the simple case, this is list of length 1 with a single CodeLoc ++ # ++ # For an operation inside an inlined callsite, we have a list of length 2: ++ # [codeloc of callsite, ++ # codeloc of operation within inlined body] ++ # ++ # For more interesting inlined cases, we have a chain of source locations: ++ # [codeloc of callsite, ++ # codeloc of inner callsite, ++ # ... , ++ # codeloc of innermost inlined callsite, ++ # codeloc of operation within inlined body] ++ # ++ ++ __slots__ = ('codelocs', ) ++ ++ def __init__(self, codelocs): ++ self.codelocs = codelocs ++ ++ def __str__(self): ++ return '[' + ' > '.join(str(codeloc) for codeloc in self.codelocs) + ']' ++ ++ def __cmp__(self, other): ++ return cmp(self.codelocs, other.codelocs) ++ ++def block_comparator(blk0, blk1): ++ ''' ++ Sort function for blocks, putting them in an ordering that attempts to ++ maximize readability of the generated C code ++ ''' ++ # print 'comparing %r and %r' % (blk0, blk1) ++ # Put the start/end block at the top/bottom: ++ if blk0.isstartblock: ++ return -1 ++ ++ if blk1.isstartblock: ++ return 1 ++ ++ # Order blocks by the offset, where present: ++ if blk0.operations: ++ if blk1.operations: ++ return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc) ++ else: ++ return -1 ++ else: ++ if blk1.operations: ++ return 1 ++ else: ++ return 0 ++ ++def edge_comparator(edge0, edge1): ++ return block_comparator(edge0.target, edge1.target) + + class FunctionGraph(object): + __slots__ = ['startblock', 'returnblock', 'exceptblock', '__dict__'] +@@ -94,6 +208,21 @@ class FunctionGraph(object): + seen[block] = True + stack += block.exits[::-1] + ++ def iterblocks_by_source(self): ++ # Try to preserve logical source ordering in the blocks ++ block = self.startblock ++ yield block ++ seen = {block: True} ++ stack = list(block.exits[::-1]) ++ stack.sort(edge_comparator) ++ while stack: ++ block = stack.pop().target ++ if block not in seen: ++ yield block ++ seen[block] = True ++ stack += block.exits[::-1] ++ stack.sort(edge_comparator) ++ + def iterlinks(self): + block = self.startblock + seen = {block: True} +@@ -183,14 +312,14 @@ class Block(object): + self.exits = [] # list of Link(s) + + def at(self): +- if self.operations and self.operations[0].offset >= 0: +- return "@%d" % self.operations[0].offset ++ if self.operations: ++ return str(self.operations[0].oploc) + else: + return "" + + def __str__(self): + if self.operations: +- txt = "block@%d" % self.operations[0].offset ++ txt = "block%s" % self.operations[0].oploc + else: + if (not self.exits) and len(self.inputargs) == 1: + txt = "return block" +@@ -245,6 +374,21 @@ class Block(object): + from pypy.translator.tool.graphpage import try_show + try_show(self) + ++ def isreturnblock(self): ++ return (not self.operations) and (not self.exits) and len(self.inputargs) == 1 ++ ++ def get_base_label(self, blocknum): ++ # Generate a more friendly C label for this block ++ if self.operations: ++ txt = "block" ++ elif (not self.exits) and len(self.inputargs) == 1: ++ txt = "return_block" ++ elif (not self.exits) and len(self.inputargs) == 2: ++ txt = "raise_block" ++ else: ++ txt = "codeless_block" ++ return '%s%d' % (txt, blocknum) ++ + + class Variable(object): + __slots__ = ["_name", "_nr", "concretetype"] +@@ -331,13 +475,15 @@ class WrapException(Exception): + + + class SpaceOperation(object): +- __slots__ = "opname args result offset".split() ++ __slots__ = "opname args result oploc".split() + +- def __init__(self, opname, args, result, offset=-1): ++ def __init__(self, opname, args, result, oploc=None): + self.opname = intern(opname) # operation name + self.args = list(args) # mixed list of var/const + self.result = result # either Variable or Constant instance +- self.offset = offset # offset in code string ++ if oploc is None: ++ oploc = OperationLoc([None]) ++ self.oploc = oploc + + def __eq__(self, other): + return (self.__class__ is other.__class__ and +@@ -352,8 +498,9 @@ class SpaceOperation(object): + return hash((self.opname,tuple(self.args),self.result)) + + def __repr__(self): +- return "%r = %s(%s)" % (self.result, self.opname, +- ", ".join(map(repr, self.args))) ++ return "%r = %s(%s) (%s)" % (self.result, self.opname, ++ ", ".join(map(repr, self.args)), ++ self.oploc) + + class Atom(object): + def __init__(self, name): +@@ -427,8 +574,7 @@ def copygraph(graph, shallow=False, varm + for op in oplist: + copyop = SpaceOperation(op.opname, + [copyvar(v) for v in op.args], +- copyvar(op.result), op.offset) +- #copyop.offset = op.offset ++ copyvar(op.result), op.oploc) + result.append(copyop) + return result + newblock.operations = copyoplist(block.operations) +diff -up pypy-1.5-src/pypy/objspace/flow/objspace.py.more-readable-c-code pypy-1.5-src/pypy/objspace/flow/objspace.py +--- pypy-1.5-src/pypy/objspace/flow/objspace.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/objspace/flow/objspace.py 2011-05-02 14:28:33.943161001 -0400 +@@ -313,7 +313,9 @@ class FlowObjSpace(ObjSpace): + def do_operation(self, name, *args_w): + spaceop = SpaceOperation(name, args_w, Variable()) + if hasattr(self, 'executioncontext'): # not here during bootstrapping +- spaceop.offset = self.executioncontext.crnt_offset ++ codeloc = CodeLoc(self.executioncontext.code, ++ self.executioncontext.crnt_offset) ++ spaceop.oploc = OperationLoc([codeloc]) + self.executioncontext.recorder.append(spaceop) + return spaceop.result + +diff -up pypy-1.5-src/pypy/objspace/flow/test/test_model.py.more-readable-c-code pypy-1.5-src/pypy/objspace/flow/test/test_model.py +--- pypy-1.5-src/pypy/objspace/flow/test/test_model.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/objspace/flow/test/test_model.py 2011-05-02 14:28:33.943161001 -0400 +@@ -119,3 +119,25 @@ def test_variable(): + assert v2.renamed + assert v2.name.startswith("foobar_") and v2.name != v.name + assert v2.name.split('_', 1)[1].isdigit() ++ ++def test_source_locations(): ++ # Invent some random offsets into the code: ++ co = sample_function.__code__ ++ codelocA = CodeLoc(co, 42) ++ codelocB = CodeLoc(co, 87) ++ ++ assert str(codelocA) == 'sample_function@42' ++ assert str(codelocB) == 'sample_function@87' ++ ++ assert cmp(codelocA, codelocB) < 0 ++ assert cmp(codelocB, codelocA) > 0 ++ ++ oplocA = OperationLoc([codelocA]) ++ oplocB = OperationLoc([codelocB]) ++ ++ assert str(oplocA) == '[sample_function@42]' ++ assert str(oplocB) == '[sample_function@87]' ++ ++ assert cmp(oplocA, oplocB) < 0 ++ assert cmp(oplocB, oplocA) > 0 ++ +diff -up pypy-1.5-src/pypy/rpython/rtyper.py.more-readable-c-code pypy-1.5-src/pypy/rpython/rtyper.py +--- pypy-1.5-src/pypy/rpython/rtyper.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/rpython/rtyper.py 2011-05-02 14:28:33.943161001 -0400 +@@ -800,7 +800,7 @@ class HighLevelOp(object): + return vars + + def genop(self, opname, args_v, resulttype=None): +- return self.llops.genop(opname, args_v, resulttype) ++ return self.llops.genop(opname, args_v, resulttype, self.spaceop.oploc) + + def gendirectcall(self, ll_function, *args_v): + return self.llops.gendirectcall(ll_function, *args_v) +@@ -935,7 +935,7 @@ class LowLevelOpList(list): + v.concretetype)) + return v + +- def genop(self, opname, args_v, resulttype=None): ++ def genop(self, opname, args_v, resulttype=None, oploc=None): + try: + for v in args_v: + v.concretetype +@@ -944,7 +944,7 @@ class LowLevelOpList(list): + " and pass its result to genop()," + " never hop.args_v directly.") + vresult = Variable() +- self.append(SpaceOperation(opname, args_v, vresult)) ++ self.append(SpaceOperation(opname, args_v, vresult, oploc)) + if resulttype is None: + vresult.concretetype = Void + return None +diff -up pypy-1.5-src/pypy/translator/backendopt/inline.py.more-readable-c-code pypy-1.5-src/pypy/translator/backendopt/inline.py +--- pypy-1.5-src/pypy/translator/backendopt/inline.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/translator/backendopt/inline.py 2011-05-02 14:32:26.975161005 -0400 +@@ -4,6 +4,7 @@ from pypy.translator.simplify import get + from pypy.translator.unsimplify import copyvar + from pypy.objspace.flow.model import Variable, Constant, Block, Link + from pypy.objspace.flow.model import SpaceOperation, c_last_exception ++from pypy.objspace.flow.model import OperationLoc + from pypy.objspace.flow.model import FunctionGraph + from pypy.objspace.flow.model import mkentrymap, checkgraph + from pypy.annotation import model as annmodel +@@ -231,6 +232,7 @@ class BaseInliner(object): + self.varmap = {} + self._copied_blocks = {} + self.op = block.operations[index_operation] ++ self.callsite_oploc = self.op.oploc + self.graph_to_inline = self.get_graph_from_op(self.op) + self.exception_guarded = False + if (block.exitswitch == c_last_exception and +@@ -290,7 +292,9 @@ class BaseInliner(object): + + def copy_operation(self, op): + args = [self.get_new_name(arg) for arg in op.args] +- result = SpaceOperation(op.opname, args, self.get_new_name(op.result)) ++ new_oploc = OperationLoc(self.callsite_oploc.codelocs[:] + op.oploc.codelocs[:]) ++ result = SpaceOperation(op.opname, args, self.get_new_name(op.result), ++ new_oploc) + return result + + def copy_block(self, block): +diff -up pypy-1.5-src/pypy/translator/c/funcgen.py.more-readable-c-code pypy-1.5-src/pypy/translator/c/funcgen.py +--- pypy-1.5-src/pypy/translator/c/funcgen.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/translator/c/funcgen.py 2011-05-02 14:28:33.944161001 -0400 +@@ -1,4 +1,6 @@ + import sys ++import inspect ++import dis + from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring + from pypy.translator.c.support import cdecl + from pypy.translator.c.support import llvalue_from_constant, gen_assignments +@@ -22,6 +24,38 @@ LOCALVAR = 'l_%s' + + KEEP_INLINED_GRAPHS = False + ++def block_comparator(blk0, blk1): ++ ''' ++ Sort function for blocks, putting them in an ordering that attempts to ++ maximize readability of the generated C code ++ ''' ++ # print 'comparing %r and %r' % (blk0, blk1) ++ # Put the start/end block at the top/bottom: ++ if blk0.isstartblock: ++ return -1 ++ ++ if blk1.isstartblock: ++ return 1 ++ ++ # Order blocks by the offset, where present: ++ if blk0.operations: ++ if blk1.operations: ++ return cmp(blk0.operations[0].oploc, blk1.operations[0].oploc) ++ else: ++ return -1 ++ else: ++ if blk1.operations: ++ return 1 ++ else: ++ return 0 ++ ++def escape_c_comments(py_src): ++ # Escape C comments within RPython source, to avoid generating bogus ++ # comments in our generated C source: ++ py_src = py_src.replace('/*', '') ++ py_src = py_src.replace('*/', '') ++ return py_src ++ + class FunctionCodeGenerator(object): + """ + Collects information about a function which we have to generate +@@ -210,14 +244,57 @@ class FunctionCodeGenerator(object): + + def cfunction_body(self): + graph = self.graph +- yield 'goto block0;' # to avoid a warning "this label is not used" ++ # Try to print python source code: ++ if hasattr(graph, 'func'): ++ filename = inspect.getfile(graph.func) ++ #yield '/* name: %r */' % filename ++ try: ++ src, startline = inspect.getsourcelines(graph.func) ++ except IOError: ++ pass # No source found ++ except IndexError: ++ pass # Bulletproofing ++ else: ++ yield '/* Python source %r' % filename ++ for i, line in enumerate(src): ++ line = line.rstrip() ++ line = escape_c_comments(line) ++ # FuncNode.funcgen_implementation treats lines ending in ':' ++ # as C blocks, which messes up the formatting. ++ # Work around this: ++ if line.endswith(':'): ++ line += ' ' ++ yield ' * %4d : %s' % (startline + i, line) ++ yield ' */' ++ ++ label = graph.startblock.get_base_label(self.blocknum[graph.startblock]) ++ yield 'goto %s;' % label # to avoid a warning "this label is not used" ++ ++ # Sort the blocks into a (hopefully) readable order: ++ blocks = list(graph.iterblocks_by_source()) ++ blocks.sort(block_comparator) + + # generate the body of each block +- for block in graph.iterblocks(): ++ for block in blocks: ++ cursrcloc = None + myblocknum = self.blocknum[block] + yield '' +- yield 'block%d:' % myblocknum ++ yield '%s:' % block.get_base_label(myblocknum) ++ #yield "/* repr(block): %r */" % (block, ) ++ #yield "/* type(block): %r */" % (type(block), ) + for i, op in enumerate(block.operations): ++ #yield "/* type(op): %r */" % (type(op), ) ++ #yield "/* op.oploc: %s */" % (op.oploc, ) ++ codeloc = op.oploc.codelocs[-1] ++ if codeloc: ++ srcloc = codeloc.get_source_loc() ++ if srcloc != cursrcloc: ++ try: ++ yield "/* %s:%d : %s */" % (codeloc.code.co_name, srcloc.linenum, escape_c_comments(srcloc.get_text())) ++ cursrcloc = srcloc ++ except IOError: ++ pass ++ + for line in self.gen_op(op): + yield line + if len(block.exits) == 0: +@@ -309,7 +386,7 @@ class FunctionCodeGenerator(object): + assignments.append((a2typename, dest, src)) + for line in gen_assignments(assignments): + yield line +- label = 'block%d' % self.blocknum[link.target] ++ label = link.target.get_base_label(self.blocknum[link.target]) + if link.target in self.innerloops: + loop = self.innerloops[link.target] + if link is loop.links[-1]: # link that ends a loop +diff -up pypy-1.5-src/pypy/translator/c/test/test_genc.py.more-readable-c-code pypy-1.5-src/pypy/translator/c/test/test_genc.py +--- pypy-1.5-src/pypy/translator/c/test/test_genc.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/translator/c/test/test_genc.py 2011-05-02 14:28:33.945161001 -0400 +@@ -1,4 +1,5 @@ + import autopath, sys, os, py ++import re + from pypy.rpython.lltypesystem.lltype import * + from pypy.annotation import model as annmodel + from pypy.translator.translator import TranslationContext +@@ -515,3 +516,130 @@ def test_inhibit_tail_call(): + else: + assert 0, "the call was not found in the C source" + assert 'PYPY_INHIBIT_TAIL_CALL();' in lines[i+1] ++ ++def get_generated_c_source(fn, types): ++ # Return a (optimized fn, c source code, c source filename) 3-tuple ++ t = Translation(fn) ++ t.annotate(types) ++ c_filename_path = t.source_c() ++ h = c_filename_path.open() ++ src = h.read() ++ h.close() ++ c_fn = t.compile_c() ++ return (c_fn, src, c_filename_path) ++ ++def extract_c_function(c_src, fname): ++ # Extract the source for a given C function out of a the given src string ++ # Makes assumptions about the layout of the source ++ pattern = '^(.+) \**%s\(.*\) {$' % fname ++ within_fn = False ++ result = '' ++ for line in c_src.splitlines(): ++ if within_fn: ++ result += line + '\n' ++ if line.startswith('}'): ++ return result ++ else: ++ m = re.match(pattern, line) ++ if m: ++ within_fn = True ++ result += line + '\n' ++ return result ++ ++ ++ ++def test_generated_c_source(): ++ # Verify that generate C source "looks good" ++ # We'll use is_perfect_number, as it contains a loop and a conditional ++ ++ # Generate C source code ++ from pypy.translator.test.snippet import is_perfect_number ++ c_fn, c_src, c_filename_path = get_generated_c_source(is_perfect_number, ++ [int]) ++ ++ # Locate the C source for the type-specialized function: ++ c_fn_src = extract_c_function(c_src, 'pypy_g_is_perfect_number') ++ ++ # Verify that the C source contains embedded comments containing the lines ++ # of the python source: ++ expected_comment_lines = [ ++ '/* is_perfect_number:31 : while div < n: */', ++ '/* is_perfect_number:32 : if n % div == 0: */', ++ '/* is_perfect_number:33 : sum += div */', ++ '/* is_perfect_number:34 : div += 1 */', ++ '/* is_perfect_number:35 : return n == sum */'] ++ for exp_line in expected_comment_lines: ++ assert exp_line in c_fn_src ++ ++ # Verify that the lines occur in the correct order ++ # ...we do this by filtering the function's generated C source to just ++ # those lines containing our comments (and dropping whitespace): ++ lines = c_fn_src.splitlines() ++ lines = [line.strip() ++ for line in lines ++ if '/* is_perfect_number:' in line] ++ ++ # ...we should now have exact equality: the ordering should be as expected, ++ # and each comment should appear exactly once: ++ assert lines == expected_comment_lines ++ ++ # Ensure that the generated C function does the right thing: ++ assert c_fn(5) == False ++ assert c_fn(6) == True ++ assert c_fn(7) == False ++ ++ assert c_fn(5.0) == False ++ assert c_fn(6.0) == True ++ assert c_fn(7.0) == False ++ ++ assert c_fn(5L) == False ++ assert c_fn(6L) == True ++ assert c_fn(7L) == False ++ ++ try: ++ c_fn('hello world') ++ except: ++ pass ++ else: ++ raise 'Was expected exception' ++ ++def test_escaping_c_comments(): ++ # Ensure that c comments within RPython code get escaped when we generate ++ # our .c code (to avoid generating bogus C) ++ # See e.g. pypy.module.cpyext.dictobject's PyDict_Next, which has a ++ # docstring embedding a C comment ++ def c_style_comment(a, b): ++ '''Here is a C-style comment within an RPython docstring: ++ /* hello world */ ++ ''' ++ # and here's one in a string literal: ++ return '/* hello world a:%s b:%s */' % (a, b) ++ ++ def cplusplus_style_comment(a, b): ++ '''Here is a C++-style comment within an RPython docstring: ++ // hello world ++ ''' ++ # and here are some in string literals, and one as the floor division ++ # operator: ++ return '// hello world: a // b = %s' % (a // b) ++ ++ for fn_name, exp_output in [('c_style_comment', ++ '/* hello world a:6 b:3 */'), ++ ('cplusplus_style_comment', ++ '// hello world: a // b = 2')]: ++ fn = locals()[fn_name] ++ ++ c_fn, c_src, c_filename_path = get_generated_c_source(fn, [int, int]) ++ # If the above survived, then the C compiler managed to handle ++ # the generated C code ++ ++ # Verify that the generated code works (i.e. that we didn't ++ # accidentally change the meaning): ++ assert c_fn(6, 3) == exp_output ++ ++ # Ensure that at least part of the docstrings made it into the C ++ # code: ++ c_fn_src = extract_c_function(c_src, 'pypy_g_' + fn_name) ++ assert 'Here is a ' in c_fn_src ++ assert 'style comment within an RPython docstring' in c_fn_src ++ +diff -up pypy-1.5-src/pypy/translator/driver.py.more-readable-c-code pypy-1.5-src/pypy/translator/driver.py +--- pypy-1.5-src/pypy/translator/driver.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/translator/driver.py 2011-05-02 14:28:33.945161001 -0400 +@@ -536,6 +536,7 @@ class TranslationDriver(SimpleTaskEngine + dstname = self.compute_exe_name() + '.staticdata.info' + shutil.copy(str(fname), str(dstname)) + self.log.info('Static data info written to %s' % dstname) ++ return c_source_filename + + # + task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source") +diff -up pypy-1.5-src/pypy/translator/gensupp.py.more-readable-c-code pypy-1.5-src/pypy/translator/gensupp.py +--- pypy-1.5-src/pypy/translator/gensupp.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/translator/gensupp.py 2011-05-02 14:33:31.026161001 -0400 +@@ -14,8 +14,8 @@ def ordered_blocks(graph): + allblocks = [] + for block in graph.iterblocks(): + # first we order by offset in the code string +- if block.operations: +- ofs = block.operations[0].offset ++ if block.operations and block.operations[0].oploc.codelocs[0]: ++ ofs = block.operations[0].oploc.codelocs[0].offset + else: + ofs = sys.maxint + # then we order by input variable name or value +diff -up pypy-1.5-src/pypy/translator/interactive.py.more-readable-c-code pypy-1.5-src/pypy/translator/interactive.py +--- pypy-1.5-src/pypy/translator/interactive.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/translator/interactive.py 2011-05-02 14:28:33.946161001 -0400 +@@ -138,7 +138,7 @@ class Translation(object): + def source_c(self, argtypes=None, **kwds): + self.update_options(argtypes, kwds) + self.ensure_backend('c') +- self.driver.source_c() ++ return self.driver.source_c() + + def source_cl(self, argtypes=None, **kwds): + self.update_options(argtypes, kwds) +diff -up pypy-1.5-src/pypy/translator/llsupport/wrapper.py.more-readable-c-code pypy-1.5-src/pypy/translator/llsupport/wrapper.py +--- pypy-1.5-src/pypy/translator/llsupport/wrapper.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/translator/llsupport/wrapper.py 2011-05-02 14:28:33.946161001 -0400 +@@ -59,6 +59,8 @@ def new_wrapper(func, translator, newnam + # "return result" + block = Block(wrapper_inputargs) + wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block) ++ if hasattr(graph, 'func'): ++ wgraph.func = graph.func + translator.update_call_graph(wgraph, graph, object()) + translator.graphs.append(wgraph) + block.operations[:] = newops +diff -up pypy-1.5-src/pypy/translator/simplify.py.more-readable-c-code pypy-1.5-src/pypy/translator/simplify.py +--- pypy-1.5-src/pypy/translator/simplify.py.more-readable-c-code 2011-04-30 10:18:50.000000000 -0400 ++++ pypy-1.5-src/pypy/translator/simplify.py 2011-05-02 14:28:33.952161001 -0400 +@@ -298,7 +298,7 @@ def join_blocks(graph): + return renaming.get(v, v) + def rename_op(op): + args = [rename(a) for a in op.args] +- op = SpaceOperation(op.opname, args, rename(op.result), op.offset) ++ op = SpaceOperation(op.opname, args, rename(op.result), op.oploc) + # special case... + if op.opname == 'indirect_call': + if isinstance(op.args[0], Constant): diff --git a/pypy.spec b/pypy.spec index c69893a..1a651e0 100644 --- a/pypy.spec +++ b/pypy.spec @@ -1,6 +1,6 @@ Name: pypy -Version: 1.4.1 -Release: 10%{?dist} +Version: 1.5 +Release: 1%{?dist} Summary: Python implementation with a Just-In-Time compiler Group: Development/Languages @@ -105,7 +105,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %global verbose_logs 0 %global pypyprefix %{_libdir}/pypy-%{version} -%global pylibver 2.5.2 +%global pylibver 2.7 # We refer to this subdir of the source tree in a few places during the build: %global goal_dir pypy/translator/goal @@ -120,7 +120,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Source0: http://pypy.org/download/pypy-%{version}-src.tar.bz2 # Edit a translator file for linux in order to configure our cflags and dynamic libffi -Patch0: pypy-1.4-config.patch +Patch0: pypy-1.5-config.patch # By default, if built at a tty, the translation process renders a Mandelbrot # set to indicate progress. @@ -150,7 +150,7 @@ Patch3: pypy-1.4.1-add-LIBRARY_INSTALLATION_PATH.patch # http://codespeak.net/pipermail/pypy-dev/2010q4/006532.html # TODO: get this into the upstream bug tracker, and finish inlining # support (rhbz#666963) -Patch4: pypy-1.4.1-more-readable-c-code.patch +Patch4: pypy-1.5-more-readable-c-code.patch # Build-time requirements: @@ -584,7 +584,7 @@ mkdir -p %{buildroot}/%{pypyprefix}/site-packages # interface going forward, so let's just mimic upstream for now. %global pypy_include_dir %{pypyprefix}/include mkdir -p %{buildroot}/%{pypy_include_dir} -cp include/*.h include/*.inl %{buildroot}/%{pypy_include_dir} +cp include/*.h %{buildroot}/%{pypy_include_dir} # Capture the RPython source code files from the build within the debuginfo @@ -698,6 +698,25 @@ CheckPyPy() { # seems to hang on this test, within test_line_terminator SkipTest test_asynchat + # test_audioop: + # test test_audioop crashed -- : No module named audioop + # Traceback (most recent call last): + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/regrtest.py", line 874, in runtest_inner + # the_package = __import__(abstest, globals(), locals(), []) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_audioop.py", line 1, in + # import audioop + # ImportError: No module named audioop + SkipTest test_audioop + + # test_capi: + # RPython traceback: + # RPython traceback: + # File "implement.c", line 243013, in _PyObject_New + # File "implement_1.c", line 31707, in _PyObject_NewVar + # File "implement.c", line 217060, in from_ref + # Fatal RPython error: AssertionError + SkipTest test_capi + # test_compiler: # 4 errors out of 13: # testSourceCodeEncodingsError @@ -710,10 +729,102 @@ CheckPyPy() { # failures=17, errors=20, out of 132 tests SkipTest test_ctypes + # test_distutils: + # Warning -- os.environ was modified by test_distutils + # test test_distutils failed -- multiple errors occurred; run in verbose mode for details + SkipTest test_distutils + # test_frozen: # TestFailed: import __hello__ failed:No module named __hello__ SkipTest test_frozen + # test_gc: + # test test_gc crashed -- : 'module' object has no attribute 'get_debug' + SkipTest test_gc + + # test_gdb: + # test test_gdb crashed -- : 'PY_CFLAGS' + SkipTest test_gdb + + # test_generators: + # ********************************************************************** + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine + # Failed example: + # del g; gc_collect() + # Expected: + # exiting + # Got nothing + # ********************************************************************** + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine + # Failed example: + # del g; gc_collect() + # Expected: + # exiting + # Got nothing + # ********************************************************************** + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine + # Failed example: + # del g; gc_collect() + # Expected: + # finally + # Got nothing + # ********************************************************************** + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.coroutine + # Failed example: + # sys.stderr.getvalue().startswith( + # "Exception RuntimeError: 'generator ignored GeneratorExit' in " + # ) + # Expected: + # True + # Got: + # False + # ********************************************************************** + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_generators.py", line ?, in test.test_generators.__test__.refleaks + # Failed example: + # try: + # sys.stderr = StringIO.StringIO() + # class Leaker: + # def __del__(self): + # raise RuntimeError + # l = Leaker() + # del l + # gc_collect() + # err = sys.stderr.getvalue().strip() + # err.startswith( + # "Exception RuntimeError: RuntimeError() in " + # ) + # err.endswith("> ignored") + # len(err.splitlines()) + # finally: + # sys.stderr = old + # Expected: + # True + # True + # 1 + # Got: + # False + # False + # 0 + # ********************************************************************** + # 2 items had failures: + # 4 of 107 in test.test_generators.__test__.coroutine + # 1 of 11 in test.test_generators.__test__.refleaks + # ***Test Failed*** 5 failures. + # test test_generators failed -- 5 of 294 doctests failed + SkipTest test_generators + + # test_getargs2: + # test test_getargs2 failed -- multiple errors occurred; run in verbose mode for details + SkipTest test_getargs2 + + # test_hotshot: + # test test_hotshot crashed -- : No module named _hotshot + SkipTest test_hotshot + + # test_io: + # test test_io failed -- multiple errors occurred; run in verbose mode for details + SkipTest test_io + # test_ioctl: # Failing in Koji with dist-f15 with: # ====================================================================== @@ -737,6 +848,23 @@ CheckPyPy() { # 24 failures out of 25, apparently all due to TypeError SkipTest test_iterlen + # test_multiprocessing: + # test test_multiprocessing failed -- multiple errors occurred; run in verbose mode for details + SkipTest test_multiprocessing + + # test_module: + # test test_module failed -- Traceback (most recent call last): + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_module.py", line 81, in test_clear_dict_in_ref_cycle + # self.assertEqual(destroyed, [1]) + # AssertionError: Lists differ: [] != [1] + # Second list contains 1 additional elements. + # First extra element 0: + # 1 + # - [] + # + [1] + # ? + + SkipTest test_module + # test_parser: # 12 failures out of 15 SkipTest test_parser @@ -746,6 +874,44 @@ CheckPyPy() { # test test_platform failed -- errors occurred in test.test_platform.PlatformTest SkipTest test_platform + # test_posix: + # test test_posix failed -- Traceback (most recent call last): + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 361, in test_getcwd_long_pathnames + # _create_and_do_getcwd(dirname) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 351, in _create_and_do_getcwd + # _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 351, in _create_and_do_getcwd + # _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1) + # [...repeats...] + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 351, in _create_and_do_getcwd + # _create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_posix.py", line 356, in _create_and_do_getcwd + # self.assertEqual(e.errno, expected_errno) + # AssertionError: 36 != 34 + SkipTest test_posix + + # test_readline: + # test test_readline failed -- Traceback (most recent call last): + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_readline.py", line 16, in testHistoryUpdates + # readline.clear_history() + # File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/readline.py", line 277, in clear_history + # del self.get_reader().history[:] + # File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/readline.py", line 186, in get_reader + # console = UnixConsole(self.f_in, self.f_out, encoding=ENCODING) + # File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/unix_console.py", line 103, in __init__ + # self._clear = _my_getstr("clear") + # File "/builddir/build/BUILD/pypy-1.5-src/lib_pypy/pyrepl/unix_console.py", line 45, in _my_getstr + # "terminal doesn't have the required '%s' capability"%cap + # InvalidTerminal: terminal doesn't have the required 'clear' capability + SkipTest test_readline + + # test_scope: + # test test_scope failed -- Traceback (most recent call last): + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_scope.py", line 437, in testLeaks + # self.assertEqual(Foo.count, 0) + # AssertionError: 100 != 0 + SkipTest test_scope + # test_socket: # testSockName can fail in Koji with: # my_ip_addr = socket.gethostbyname(socket.gethostname()) @@ -761,10 +927,138 @@ CheckPyPy() { # ProgrammingError: Incomplete statement '' SkipTest test_sqlite + # test_strop: + # test test_strop crashed -- : No module named strop + SkipTest test_strop + + # test_structmembers: + # test test_structmembers failed -- multiple errors occurred; run in verbose mode for details + SkipTest test_structmembers + + # test_subprocess: + # debug: WARNING: library path not found, using compiled-in sys.path and sys.prefix will be unset + # 'import site' failed + # . + # this bit of output is from a test of stdout in a different process ... + # /builddir/build/BUILD/pypy-1.5-src/lib_pypy/ctypes_support.py:26: RuntimeWarning: C function without declared arguments called + # return standard_c_lib.__errno_location() + # debug: WARNING: library path not found, using compiled-in sys.path and sys.prefix will be unset + # 'import site' failed + # . + # this bit of output is from a test of stdout in a different process ... + # test test_subprocess failed -- multiple errors occurred; run in verbose mode for details + SkipTest test_subprocess + + # test_symtable: + # test test_symtable crashed -- : No module named _symtable + SkipTest test_symtable + + # test_sys_settrace: + # test test_sys_settrace failed -- Traceback (most recent call last): + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 334, in test_13_genexp + # self.run_test(generator_example) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 280, in run_test + # self.run_and_compare(func, func.events) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 277, in run_and_compare + # tracer.events, events) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/test/test_sys_settrace.py", line 269, in compare_events + # [str(x) for x in events]))) + # AssertionError: events did not match expectation: + # (0, 'call') + # (2, 'line') + # (-6, 'call') + # (-5, 'line') + # (-4, 'line') + # (-4, 'return') + # - (-4, 'call') + # - (-4, 'exception') + # - (-1, 'line') + # - (-1, 'return') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (6, 'line') + # (5, 'line') + # (5, 'return') + SkipTest test_sys_settrace + + # test_tempfile: + # test test_tempfile failed -- multiple errors occurred; run in verbose mode for details + SkipTest test_tempfile + + # test_thread + # Koji build appears to hang here + SkipTest test_thread + # test_traceback: # works when run standalone; failures seen when run as part of a suite SkipTest test_traceback + # test_uuid: + # ====================================================================== + # ERROR: test_ifconfig_getnode (test.test_uuid.TestUUID) + # ---------------------------------------------------------------------- + # Traceback (most recent call last): + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_uuid.py", line 306, in test_ifconfig_getnode + # node = uuid._ifconfig_getnode() + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/uuid.py", line 326, in _ifconfig_getnode + # ip_addr = socket.gethostbyname(socket.gethostname()) + # gaierror: [Errno -3] Temporary failure in name resolution + # ---------------------------------------------------------------------- + # Ran 14 tests in 0.369s + # FAILED (errors=1) + SkipTest test_uuid + + # test_zipimport_support: + # ====================================================================== + # ERROR: test_doctest_main_issue4197 (test.test_zipimport_support.ZipSupportTests) + # ---------------------------------------------------------------------- + # Traceback (most recent call last): + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_zipimport_support.py", line 194, in test_doctest_main_issue4197 + # exit_code, data = run_python(script_name) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/script_helper.py", line 80, in run_python + # p = spawn_python(*args, **kwargs) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/script_helper.py", line 66, in spawn_python + # **kwargs) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 672, in __init__ + # errread, errwrite) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 1206, in _execute_child + # raise child_exception + # OSError: [Errno 13] Permission denied + # ====================================================================== + # ERROR: test_pdb_issue4201 (test.test_zipimport_support.ZipSupportTests) + # ---------------------------------------------------------------------- + # Traceback (most recent call last): + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/test_zipimport_support.py", line 221, in test_pdb_issue4201 + # p = spawn_python(script_name) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/2.7/test/script_helper.py", line 66, in spawn_python + # **kwargs) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 672, in __init__ + # errread, errwrite) + # File "/builddir/build/BUILD/pypy-1.5-src/lib-python/modified-2.7/subprocess.py", line 1206, in _execute_child + # raise child_exception + # OSError: [Errno 13] Permission denied + # ---------------------------------------------------------------------- + # Ran 4 tests in 0.726s + # FAILED (errors=2) + SkipTest test_zipimport_support + # test_zlib: # failure seen in Koji, not sure of reason why: # test test_zlib failed -- Traceback (most recent call last): @@ -832,6 +1126,8 @@ rm -rf $RPM_BUILD_ROOT %dir %{pypyprefix} %dir %{pypyprefix}/lib-python +%{pypyprefix}/lib-python/TODO +%{pypyprefix}/lib-python/stdlib-version.txt %{pypyprefix}/lib-python/%{pylibver}/ %{pypyprefix}/lib-python/modified-%{pylibver}/ %{pypyprefix}/lib-python/conftest.py* @@ -847,7 +1143,6 @@ rm -rf $RPM_BUILD_ROOT %defattr(-,root,root,-) %dir %{pypy_include_dir} %{pypy_include_dir}/*.h -%{pypy_include_dir}/*.inl %if 0%{with_stackless} %files stackless @@ -858,6 +1153,9 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Mon May 2 2011 David Malcolm - 1.5-1 +- 1.5 + * Wed Apr 20 2011 David Malcolm - 1.4.1-10 - build a /usr/bin/pypy (but without the JIT compiler) on architectures that don't support the JIT, so that they do at least have something that runs diff --git a/sources b/sources index 90f34be..a047407 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -ebbbb156b1eb842e9e65d909ed5f9f6d pypy-1.4.1-src.tar.bz2 +cb9ada2c50666318c3a2863da1fbe487 pypy-1.5-src.tar.bz2