From 981febd19034493a3aa100c62c866097562e67bb Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Mon, 30 Sep 2019 16:27:35 -0700 Subject: [PATCH] [mypyc] Fix some nondeterminism caused by iterating over sets/dicts Tested by compiling mypy and comparing outputs on Python 3.5. --- mypyc/emitclass.py | 3 ++- mypyc/emitwrapper.py | 3 ++- mypyc/genops.py | 5 +++-- mypyc/prebuildvisitor.py | 6 +++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/mypyc/emitclass.py b/mypyc/emitclass.py index 542e3ecd68d5..3d68bfe26dca 100644 --- a/mypyc/emitclass.py +++ b/mypyc/emitclass.py @@ -69,7 +69,8 @@ def wrapper_slot(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str: def generate_slots(cl: ClassIR, table: SlotTable, emitter: Emitter) -> Dict[str, str]: fields = OrderedDict() # type: Dict[str, str] - for name, (slot, generator) in table.items(): + # Sort for determinism on Python 3.5 + for name, (slot, generator) in sorted(table.items()): method = cl.get_method(name) if method: fields[slot] = generator(cl, method, emitter) diff --git a/mypyc/emitwrapper.py b/mypyc/emitwrapper.py index 3b99f495a8a5..40fc6c9e8bce 100644 --- a/mypyc/emitwrapper.py +++ b/mypyc/emitwrapper.py @@ -127,7 +127,8 @@ def generate_dunder_wrapper(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str: def generate_richcompare_wrapper(cl: ClassIR, emitter: Emitter) -> Optional[str]: """Generates a wrapper for richcompare dunder methods.""" - matches = [name for name in RICHCOMPARE_OPS if cl.has_method(name)] + # Sort for determinism on Python 3.5 + matches = sorted([name for name in RICHCOMPARE_OPS if cl.has_method(name)]) if not matches: return None diff --git a/mypyc/genops.py b/mypyc/genops.py index 9ef93f2baafd..f3221e321eeb 100644 --- a/mypyc/genops.py +++ b/mypyc/genops.py @@ -361,7 +361,7 @@ def __init__(self) -> None: self.type_to_ir = {} # type: Dict[TypeInfo, ClassIR] self.func_to_decl = {} # type: Dict[SymbolNode, FuncDecl] # Maps integer, float, and unicode literals to a static name - self.literals = {} # type: LiteralsMap + self.literals = OrderedDict() # type: LiteralsMap def type_to_rtype(self, typ: Optional[Type]) -> RType: if typ is None: @@ -1873,7 +1873,8 @@ def c() -> None: env_for_func = self.fn_info.callable_class if self.fn_info.fitem in self.free_variables: - for var in self.free_variables[self.fn_info.fitem]: + # Sort the variables to keep things deterministic + for var in sorted(self.free_variables[self.fn_info.fitem], key=lambda x: x.name()): if isinstance(var, Var): rtype = self.type_to_rtype(var.type) self.add_var_to_env_class(var, rtype, env_for_func, reassign=False) diff --git a/mypyc/prebuildvisitor.py b/mypyc/prebuildvisitor.py index f1599697cebb..1f21e080d098 100644 --- a/mypyc/prebuildvisitor.py +++ b/mypyc/prebuildvisitor.py @@ -27,9 +27,9 @@ def __init__(self) -> None: self.prop_setters = set() # type: Set[FuncDef] # A map from any function that contains nested functions to # a set of all the functions that are nested within it. - self.encapsulating_funcs = dict() # type: Dict[FuncItem, Set[FuncItem]] + self.encapsulating_funcs = {} # type: Dict[FuncItem, List[FuncItem]] # A map from a nested func to it's parent/encapsulating func. - self.nested_funcs = dict() # type: Dict[FuncItem, FuncItem] + self.nested_funcs = {} # type: Dict[FuncItem, FuncItem] self.funcs_to_decorators = {} # type: Dict[FuncDef, List[Expression]] def add_free_variable(self, symbol: SymbolNode) -> None: @@ -57,7 +57,7 @@ def visit_func(self, func: FuncItem) -> None: # being a nested function. if self.funcs: # Add the new func to the set of nested funcs within the func at top of the func stack. - self.encapsulating_funcs.setdefault(self.funcs[-1], set()).add(func) + self.encapsulating_funcs.setdefault(self.funcs[-1], []).append(func) # Add the func at top of the func stack as the parent of new func. self.nested_funcs[func] = self.funcs[-1] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy