Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r60881:2b5161e7db07 Date: 2013-02-04 15:35 -0800 http://bitbucket.org/pypy/pypy/changeset/2b5161e7db07/
Log: merge default diff --git a/lib-python/2.7/collections.py b/lib-python/2.7/collections.py --- a/lib-python/2.7/collections.py +++ b/lib-python/2.7/collections.py @@ -6,7 +6,6 @@ __all__ += _abcoll.__all__ from _collections import deque, defaultdict -from operator import itemgetter as _itemgetter from keyword import iskeyword as _iskeyword import sys as _sys import heapq as _heapq @@ -298,7 +297,7 @@ _fields = %(field_names)r \n def __new__(_cls, %(argtxt)s): 'Create new instance of %(typename)s(%(argtxt)s)' - return _tuple.__new__(_cls, (%(argtxt)s)) \n + return tuple.__new__(_cls, (%(argtxt)s)) \n @classmethod def _make(cls, iterable, new=tuple.__new__, len=len): 'Make a new %(typename)s object from a sequence or iterable' @@ -323,14 +322,14 @@ 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) \n\n''' % locals() for i, name in enumerate(field_names): - template += " %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i) + template += " %s = property(lambda self: self[%d], doc='Alias for field number %d')\n" % (name, i, i) if verbose: print template # Execute the template string in a temporary namespace and # support tracing utilities by setting a value for frame.f_globals['__name__'] - namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, - OrderedDict=OrderedDict, _property=property, _tuple=tuple) + namespace = {'__name__': 'namedtuple_%s' % typename, + 'OrderedDict': OrderedDict} try: exec template in namespace except SyntaxError, e: diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -40,6 +40,7 @@ def gettopframe(self): return self.topframeref() + @jit.unroll_safe def gettopframe_nohidden(self): frame = self.topframeref() while frame and frame.hide(): diff --git a/pypy/interpreter/pytraceback.py b/pypy/interpreter/pytraceback.py --- a/pypy/interpreter/pytraceback.py +++ b/pypy/interpreter/pytraceback.py @@ -1,5 +1,6 @@ from pypy.interpreter import baseobjspace from pypy.interpreter.error import OperationError + from rpython.tool.error import offset2lineno @@ -27,10 +28,10 @@ def descr__reduce__(self, space): from pypy.interpreter.mixedmodule import MixedModule - w_mod = space.getbuiltinmodule('_pickle_support') - mod = space.interp_w(MixedModule, w_mod) + w_mod = space.getbuiltinmodule('_pickle_support') + mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('traceback_new') - w = space.wrap + w = space.wrap tup_base = [] tup_state = [ @@ -49,6 +50,7 @@ self.lasti = space.int_w(w_lasti) self.next = space.interp_w(PyTraceback, w_next, can_be_None=True) + def record_application_traceback(space, operror, frame, last_instruction): if frame.pycode.hidden_applevel: return @@ -56,10 +58,11 @@ tb = PyTraceback(space, frame, last_instruction, tb) operror.set_traceback(tb) + def check_traceback(space, w_tb, msg): from pypy.interpreter.typedef import PyTraceback tb = space.interpclass_w(w_tb) - if tb is None or not space.is_true(space.isinstance(tb, + if tb is None or not space.is_true(space.isinstance(tb, space.gettypeobject(PyTraceback.typedef))): raise OperationError(space.w_TypeError, space.wrap(msg)) return tb diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py --- a/pypy/interpreter/typedef.py +++ b/pypy/interpreter/typedef.py @@ -1,18 +1,17 @@ -""" +import py - -""" -import py -from pypy.interpreter.gateway import interp2app, BuiltinCode, unwrap_spec,\ - WrappedDefault from pypy.interpreter.argument import Arguments from pypy.interpreter.baseobjspace import Wrappable, DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec, + WrappedDefault) + +from rpython.rlib.jit import promote +from rpython.rlib.objectmodel import compute_identity_hash, specialize from rpython.tool.sourcetools import compile2, func_with_new_name -from rpython.rlib.objectmodel import instantiate, compute_identity_hash, specialize -from rpython.rlib.jit import promote -class TypeDef: + +class TypeDef(object): def __init__(self, __name, __base=None, __total_ordering__=None, **rawdict): "NOT_RPYTHON: initialization-time only" self.name = __name @@ -27,7 +26,7 @@ self.weakrefable = '__weakref__' in rawdict self.doc = rawdict.get('__doc__', None) for base in bases: - self.hasdict |= base.hasdict + self.hasdict |= base.hasdict self.weakrefable |= base.weakrefable self.rawdict = {} self.acceptable_as_base_class = '__new__' in rawdict @@ -426,7 +425,7 @@ return unknown_objclass_getter, cls miniglobals = {} if isinstance(cls, str): - assert cls.startswith('<'),"pythontype typecheck should begin with <" + assert cls.startswith('<'), "pythontype typecheck should begin with <" cls_name = cls[1:] typeexpr = "space.w_%s" % cls_name else: @@ -474,7 +473,7 @@ else: try: return self.fget(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: return w_obj.descr_call_mismatch( space, '__getattribute__', self.reqcls, Arguments(space, [w_obj, @@ -489,7 +488,7 @@ space.wrap("readonly attribute")) try: fset(self, space, w_obj, w_value) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__setattr__', self.reqcls, Arguments(space, [w_obj, @@ -505,7 +504,7 @@ space.wrap("cannot delete attribute")) try: fdel(self, space, w_obj) - except DescrMismatch, e: + except DescrMismatch: w_obj.descr_call_mismatch( space, '__delattr__', self.reqcls, Arguments(space, [w_obj, @@ -552,6 +551,7 @@ class Member(Wrappable): """For slots.""" _immutable_ = True + def __init__(self, index, name, w_cls): self.index = index self.name = name @@ -623,9 +623,8 @@ from pypy.interpreter.pyframe import PyFrame from pypy.interpreter.pyopcode import SuspendedUnroller, W_OperationError from pypy.interpreter.module import Module -from pypy.interpreter.function import Function, Method, StaticMethod -from pypy.interpreter.function import ClassMethod -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import (Function, Method, StaticMethod, + ClassMethod, BuiltinFunction, descr_function_get) from pypy.interpreter.pytraceback import PyTraceback from pypy.interpreter.generator import GeneratorIterator from pypy.interpreter.nestedscope import Cell @@ -669,8 +668,10 @@ def fget_co_flags(space, code): # unwrapping through unwrap_spec sig = code.signature() flags = 0 - if sig.has_vararg(): flags |= CO_VARARGS - if sig.has_kwarg(): flags |= CO_VARKEYWORDS + if sig.has_vararg(): + flags |= CO_VARARGS + if sig.has_kwarg(): + flags |= CO_VARKEYWORDS return space.wrap(flags) def fget_co_consts(space, code): # unwrapping through unwrap_spec @@ -734,7 +735,7 @@ __eq__ = interp2app(PyCode.descr_code__eq__), __ne__ = descr_generic_ne, __hash__ = interp2app(PyCode.descr_code__hash__), - __reduce__ = interp2app(PyCode.descr__reduce__), + __reduce__ = interp2app(PyCode.descr__reduce__), __repr__ = interp2app(PyCode.repr), co_argcount = interp_attrproperty('co_argcount', cls=PyCode), co_kwonlyargcount = interp_attrproperty('co_kwonlyargcount', cls=PyCode), @@ -744,9 +745,9 @@ co_code = interp_attrproperty_bytes('co_code', cls=PyCode), co_consts = GetSetProperty(PyCode.fget_co_consts), co_names = GetSetProperty(PyCode.fget_co_names), - co_varnames = GetSetProperty(PyCode.fget_co_varnames), - co_freevars = GetSetProperty(PyCode.fget_co_freevars), - co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), + co_varnames = GetSetProperty(PyCode.fget_co_varnames), + co_freevars = GetSetProperty(PyCode.fget_co_freevars), + co_cellvars = GetSetProperty(PyCode.fget_co_cellvars), co_filename = interp_attrproperty('co_filename', cls=PyCode), co_name = interp_attrproperty('co_name', cls=PyCode), co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode), @@ -756,7 +757,7 @@ PyCode.typedef.acceptable_as_base_class = False PyFrame.typedef = TypeDef('frame', - __reduce__ = interp2app(PyFrame.descr__reduce__), + __reduce__ = interp2app(PyFrame.descr__reduce__), __setstate__ = interp2app(PyFrame.descr__setstate__), f_builtins = GetSetProperty(PyFrame.fget_f_builtins), f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno), @@ -892,7 +893,7 @@ def always_none(self, obj): return None -BuiltinFunction.typedef = TypeDef("builtin_function",**Function.typedef.rawdict) +BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict) BuiltinFunction.typedef.rawdict.update({ '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func), '__self__': GetSetProperty(always_none, cls=BuiltinFunction), @@ -903,12 +904,12 @@ BuiltinFunction.typedef.acceptable_as_base_class = False PyTraceback.typedef = TypeDef("traceback", - __reduce__ = interp2app(PyTraceback.descr__reduce__), + __reduce__ = interp2app(PyTraceback.descr__reduce__), __setstate__ = interp2app(PyTraceback.descr__setstate__), - tb_frame = interp_attrproperty('frame', cls=PyTraceback), - tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), + tb_frame = interp_attrproperty('frame', cls=PyTraceback), + tb_lasti = interp_attrproperty('lasti', cls=PyTraceback), tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno), - tb_next = interp_attrproperty('next', cls=PyTraceback), + tb_next = interp_attrproperty('next', cls=PyTraceback), ) PyTraceback.typedef.acceptable_as_base_class = False @@ -945,12 +946,12 @@ Cell.typedef.acceptable_as_base_class = False Ellipsis.typedef = TypeDef("Ellipsis", - __repr__ = interp2app(Ellipsis.descr__repr__), + __repr__ = interp2app(Ellipsis.descr__repr__), ) Ellipsis.typedef.acceptable_as_base_class = False NotImplemented.typedef = TypeDef("NotImplemented", - __repr__ = interp2app(NotImplemented.descr__repr__), + __repr__ = interp2app(NotImplemented.descr__repr__), ) NotImplemented.typedef.acceptable_as_base_class = False diff --git a/pypy/module/__pypy__/interp_identitydict.py b/pypy/module/__pypy__/interp_identitydict.py --- a/pypy/module/__pypy__/interp_identitydict.py +++ b/pypy/module/__pypy__/interp_identitydict.py @@ -33,6 +33,11 @@ except KeyError: raise OperationError(space.w_KeyError, w_key) + def descr_iter(self, space): + raise OperationError(space.w_TypeError, + space.wrap("'identity_dict' object does not support iteration; " + "iterate over x.keys()")) + def get(self, space, w_key, w_default=None): if w_default is None: w_default = space.w_None @@ -50,8 +55,11 @@ W_IdentityDict.typedef = TypeDef("identity_dict", __doc__="""\ A dictionary that considers keys by object identity. -Distinct objects that compare equal will have separate entries. -All objects can be used as keys, even non-hashable ones. +Distinct objects will have separate entries even if they +compare equal. All objects can be used as keys, even +non-hashable ones --- but avoid using immutable objects +like integers: two int objects 42 may or may not be +internally the same object. """, __new__ = interp2app(W_IdentityDict.descr_new.im_func), __len__ = interp2app(W_IdentityDict.descr_len), @@ -59,6 +67,7 @@ __setitem__ = interp2app(W_IdentityDict.descr_setitem), __getitem__ = interp2app(W_IdentityDict.descr_getitem), __delitem__ = interp2app(W_IdentityDict.descr_delitem), + __iter__ = interp2app(W_IdentityDict.descr_iter), get = interp2app(W_IdentityDict.get), keys = interp2app(W_IdentityDict.keys), values = interp2app(W_IdentityDict.values), diff --git a/pypy/module/__pypy__/test/test_identitydict.py b/pypy/module/__pypy__/test/test_identitydict.py --- a/pypy/module/__pypy__/test/test_identitydict.py +++ b/pypy/module/__pypy__/test/test_identitydict.py @@ -55,3 +55,10 @@ assert None in d assert [] not in d + + def test_iterate(self): + from __pypy__ import identity_dict + d = identity_dict() + d[None] = 1 + raises(TypeError, iter, d) + raises(TypeError, list, d) diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py --- a/pypy/module/signal/interp_signal.py +++ b/pypy/module/signal/interp_signal.py @@ -60,7 +60,6 @@ def __init__(self, space): "NOT_RPYTHON" AsyncAction.__init__(self, space) - self.handlers_w = {} self.pending_signal = -1 self.fire_in_main_thread = False if self.space.config.objspace.usemodules.thread: @@ -91,7 +90,7 @@ # If we are in the main thread, report the signal now, # and poll more self.pending_signal = -1 - self._report_signal(n) + report_signal(self.space, n) n = self.pending_signal if n < 0: n = pypysig_poll() else: @@ -110,20 +109,31 @@ pypysig_pushback(cpy_signal.SIGINT) self.fire_in_main_thread = True - def _report_signal(self, n): - try: - w_handler = self.handlers_w[n] - except KeyError: - return # no handler, ignore signal - space = self.space - if not space.is_true(space.callable(w_handler)): - return # w_handler is SIG_IGN or SIG_DFL? - # re-install signal handler, for OSes that clear it - pypysig_reinstall(n) - # invoke the app-level handler - ec = space.getexecutioncontext() - w_frame = space.wrap(ec.gettopframe_nohidden()) - space.call_function(w_handler, space.wrap(n), w_frame) +# ____________________________________________________________ + + +class Handlers: + def __init__(self, space): + self.handlers_w = {} + +def _get_handlers(space): + return space.fromcache(Handlers).handlers_w + + +def report_signal(space, n): + handlers_w = _get_handlers(space) + try: + w_handler = handlers_w[n] + except KeyError: + return # no handler, ignore signal + if not space.is_true(space.callable(w_handler)): + return # w_handler is SIG_IGN or SIG_DFL? + # re-install signal handler, for OSes that clear it + pypysig_reinstall(n) + # invoke the app-level handler + ec = space.getexecutioncontext() + w_frame = space.wrap(ec.gettopframe_nohidden()) + space.call_function(w_handler, space.wrap(n), w_frame) @unwrap_spec(signum=int) @@ -141,9 +151,9 @@ check_signum_exists(space, signum) else: check_signum_in_range(space, signum) - action = space.check_signal_action - if signum in action.handlers_w: - return action.handlers_w[signum] + handlers_w = _get_handlers(space) + if signum in handlers_w: + return handlers_w[signum] return space.wrap(SIG_DFL) @@ -204,7 +214,6 @@ "main thread")) old_handler = getsignal(space, signum) - action = space.check_signal_action if space.eq_w(w_handler, space.wrap(SIG_DFL)): pypysig_default(signum) elif space.eq_w(w_handler, space.wrap(SIG_IGN)): @@ -215,7 +224,8 @@ space.wrap("'handler' must be a callable " "or SIG_DFL or SIG_IGN")) pypysig_setflag(signum) - action.handlers_w[signum] = w_handler + handlers_w = _get_handlers(space) + handlers_w[signum] = w_handler return old_handler diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py --- a/pypy/objspace/std/tupleobject.py +++ b/pypy/objspace/std/tupleobject.py @@ -80,6 +80,15 @@ start += step return space.newtuple(subitems) +THRESHOLD = 7 + +def unroll_tuple_contains(space, w_tuple, w_obj): + if (jit.isconstant(w_tuple) or jit.isvirtual(w_tuple) and + len(w_tuple.wrappeditems) < THRESHOLD): + return True + return False + +@jit.look_inside_iff(unroll_tuple_contains) def contains__Tuple_ANY(space, w_tuple, w_obj): for w_item in w_tuple.wrappeditems: if space.eq_w(w_item, w_obj): diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py --- a/pypy/objspace/std/typeobject.py +++ b/pypy/objspace/std/typeobject.py @@ -1,24 +1,23 @@ +from pypy.interpreter import gateway +from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.function import Function, StaticMethod +from pypy.interpreter.typedef import weakref_descr from pypy.objspace.std.model import W_Object from pypy.objspace.std.register_all import register_all -from pypy.interpreter.function import Function, StaticMethod -from pypy.interpreter import gateway -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.typedef import weakref_descr -from pypy.interpreter.baseobjspace import W_Root from pypy.objspace.std.stdtypedef import std_dict_descr, issubtypedef, Member -from pypy.objspace.std.objecttype import object_typedef -from pypy.objspace.std import identitydict -from rpython.rlib.objectmodel import we_are_translated + +from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted, + promote_string, elidable, dont_look_inside, unroll_safe) from rpython.rlib.objectmodel import current_object_addr_as_int, compute_hash -from rpython.rlib.jit import promote, elidable_promote, we_are_jitted,\ - promote_string -from rpython.rlib.jit import elidable, dont_look_inside, unroll_safe from rpython.rlib.rarithmetic import intmask, r_uint + class TypeCell(W_Root): def __init__(self, w_value=None): self.w_value = w_value + def unwrap_cell(space, w_value): if (space.config.objspace.std.withtypeversion and isinstance(w_value, TypeCell)): @@ -276,7 +275,7 @@ if attr in w_self.lazyloaders: # very clever next line: it forces the attr string # to be interned. - w_attr = space.new_interned_str(attr) + space.new_interned_str(attr) loader = w_self.lazyloaders[attr] del w_self.lazyloaders[attr] w_value = loader() @@ -495,7 +494,7 @@ def get_module(w_self): space = w_self.space - if w_self.is_heaptype() and '__module__' in w_self.dict_w: + if w_self.is_heaptype() and w_self.getdictvalue(space, '__module__') is not None: return w_self.getdictvalue(space, '__module__') else: # for non-heap types, CPython checks for a module.name in the @@ -558,13 +557,15 @@ subclasses_w.append(w_ob) return subclasses_w - # for now, weakref support for W_TypeObject is hard to get automatically _lifeline_ = None + def getweakref(self): return self._lifeline_ + def setweakref(self, space, weakreflifeline): self._lifeline_ = weakreflifeline + def delweakref(self): self._lifeline_ = None @@ -691,9 +692,12 @@ else: create_slot(w_self, slot_name) wantdict = wantdict or hasoldstylebase - if wantdict: create_dict_slot(w_self) - if wantweakref: create_weakref_slot(w_self) - if '__del__' in dict_w: w_self.needsdel = True + if wantdict: + create_dict_slot(w_self) + if wantweakref: + create_weakref_slot(w_self) + if '__del__' in dict_w: + w_self.needsdel = True def create_slot(w_self, slot_name): space = w_self.space @@ -869,7 +873,7 @@ mod = None else: mod = space.str_w(w_mod) - if mod is not None and mod !='builtins': + if mod is not None and mod != 'builtins': return space.wrap("<class '%s.%s'>" % (mod, w_obj.name)) else: return space.wrap("<class '%s'>" % (w_obj.name)) @@ -888,7 +892,7 @@ # __get__(None, type): turns e.g. functions into unbound methods return space.get(w_value, space.w_None, w_type) if w_descr is not None: - return space.get(w_descr,w_type) + return space.get(w_descr, w_type) raise operationerrfmt(space.w_AttributeError, "type object '%s' has no attribute '%s'", w_type.name, name) @@ -934,7 +938,7 @@ return mro_error(space, orderlists) # no candidate found assert candidate not in order order.append(candidate) - for i in range(len(orderlists)-1, -1, -1): + for i in range(len(orderlists) - 1, -1, -1): if orderlists[i][0] is candidate: del orderlists[i][0] if len(orderlists[i]) == 0: diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py --- a/pypy/objspace/std/typetype.py +++ b/pypy/objspace/std/typetype.py @@ -1,5 +1,4 @@ from pypy.interpreter import gateway -from pypy.interpreter.argument import Arguments from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, weakref_descr) @@ -92,9 +91,9 @@ return space.wrap(w_type.name) def descr_set__name__(space, w_type, w_value): - w_type = _check(space, w_type) + w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "can't set %s.__name__", w_type.name) w_type.name = space.str_w(w_value) @@ -121,10 +120,9 @@ def descr_set__bases__(space, w_type, w_value): # this assumes all app-level type objects are W_TypeObject - from pypy.objspace.std.typeobject import W_TypeObject - from pypy.objspace.std.typeobject import check_and_find_best_base - from pypy.objspace.std.typeobject import get_parent_layout - from pypy.objspace.std.typeobject import is_mro_purely_of_types + from pypy.objspace.std.typeobject import (W_TypeObject, get_parent_layout, + check_and_find_best_base, is_mro_purely_of_types) + w_type = _check(space, w_type) if not w_type.is_heaptype(): raise operationerrfmt(space.w_TypeError, @@ -215,9 +213,12 @@ # w_type = _check(space, w_type) flags = 0 - if w_type.flag_heaptype: flags |= _HEAPTYPE - if w_type.flag_cpytype: flags |= _CPYTYPE - if w_type.flag_abstract: flags |= _ABSTRACT + if w_type.flag_heaptype: + flags |= _HEAPTYPE + if w_type.flag_cpytype: + flags |= _CPYTYPE + if w_type.flag_abstract: + flags |= _ABSTRACT return space.wrap(flags) def descr_get__module(space, w_type): diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py --- a/rpython/flowspace/specialcase.py +++ b/rpython/flowspace/specialcase.py @@ -65,8 +65,18 @@ def sc_we_are_translated(space, we_are_translated, args): return Constant(True) +def sc_locals(space, locals, args): + raise Exception( + "A function calling locals() is not RPython. " + "Note that if you're translating code outside the PyPy " + "repository, a likely cause is that py.test's --assert=rewrite " + "mode is getting in the way. You should copy the file " + "pytest.ini from the root of the PyPy repository into your " + "own project.") + SPECIAL_CASES = {__import__: sc_import, r_uint: sc_r_uint, - we_are_translated: sc_we_are_translated} + we_are_translated: sc_we_are_translated, + locals: sc_locals} for fn in OperationName: SPECIAL_CASES[fn] = sc_operator diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py --- a/rpython/translator/c/genc.py +++ b/rpython/translator/c/genc.py @@ -761,6 +761,7 @@ srcdir / 'exception.c', srcdir / 'rtyper.c', # ifdef HAVE_RTYPER srcdir / 'support.c', + srcdir / 'profiling.c', srcdir / 'debug_print.c', srcdir / 'debug_traceback.c', # ifdef HAVE_RTYPER srcdir / 'asm.c', diff --git a/rpython/translator/platform/__init__.py b/rpython/translator/platform/__init__.py --- a/rpython/translator/platform/__init__.py +++ b/rpython/translator/platform/__init__.py @@ -53,9 +53,18 @@ ofiles = self._compile_o_files(cfiles, eci, standalone) return self._finish_linking(ofiles, eci, outputfilename, standalone) + def _all_cfiles(self, cfiles, eci): + seen = set() + result = [] + for cfile in list(cfiles) + list(eci.separate_module_files): + cfile = py.path.local(cfile) + if cfile not in seen: + seen.add(cfile) + result.append(cfile) + return result + def _compile_o_files(self, cfiles, eci, standalone=True): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) compile_args = self._compile_args_from_eci(eci, standalone) ofiles = [] for cfile in cfiles: diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -84,8 +84,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py --- a/rpython/translator/platform/windows.py +++ b/rpython/translator/platform/windows.py @@ -248,8 +248,7 @@ def gen_makefile(self, cfiles, eci, exe_name=None, path=None, shared=False): - cfiles = [py.path.local(f) for f in cfiles] - cfiles += [py.path.local(f) for f in eci.separate_module_files] + cfiles = self._all_cfiles(cfiles, eci) if path is None: path = cfiles[0].dirpath() _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit