Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bf77c46

Browse files
committed
Undo change from list to dict for handling varnames, consts, etc.
As the doc string for _lookupName() explains: This routine uses a list instead of a dictionary, because a dictionary can't store two different keys if the keys have the same value but different types, e.g. 2 and 2L. The compiler must treat these two separately, so it does an explicit type comparison before comparing the values.
1 parent 5a9ac97 commit bf77c46

2 files changed

Lines changed: 44 additions & 98 deletions

File tree

Lib/compiler/pyassem.py

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,6 @@ def sorter(a, b):
1515
l.sort(sorter)
1616
return l
1717

18-
def list2dict(l):
19-
d = {}
20-
for i in range(len(l)):
21-
d[l[i]] = i
22-
return d
23-
24-
def dict2list(d):
25-
l = [(v, k) for k, v in d.items()]
26-
l.sort()
27-
return [k for v, k in l]
28-
2918
class FlowGraph:
3019
def __init__(self):
3120
self.current = self.entry = Block()
@@ -457,25 +446,13 @@ def convertArgs(self):
457446
assert self.stage == FLAT
458447
self.consts.insert(0, self.docstring)
459448
self.sort_cellvars()
460-
461-
self.c_varnames = list2dict(self.varnames)
462-
self.c_names = list2dict(self.names)
463-
self.c_consts = list2dict(self.consts)
464-
self.c_closure = list2dict(self.closure)
465-
466449
for i in range(len(self.insts)):
467450
t = self.insts[i]
468451
if len(t) == 2:
469452
opname, oparg = t
470453
conv = self._converters.get(opname, None)
471454
if conv:
472455
self.insts[i] = opname, conv(self, oparg)
473-
474-
self.varnames = dict2list(self.c_varnames)
475-
self.names = dict2list(self.c_names)
476-
self.consts = dict2list(self.c_consts)
477-
self.closure = dict2list(self.c_closure)
478-
479456
self.stage = CONV
480457

481458
def sort_cellvars(self):
@@ -491,23 +468,18 @@ def sort_cellvars(self):
491468
self.cellvars = self.cellvars + cells.keys()
492469
self.closure = self.cellvars + self.freevars
493470

494-
def _lookupName(self, name, dict):
495-
i = dict.get(name, None)
496-
if i is None:
497-
i = dict[name] = len(dict)
498-
return i
471+
def _lookupName(self, name, list):
472+
"""Return index of name in list, appending if necessary
499473
500-
def XXX_lookupName(self, name, list):
501-
"""Return index of name in list, appending if necessary"""
502-
# XXX It should be possible to replace this with some
503-
# dictionary operations, but not sure how
474+
This routine uses a list instead of a dictionary, because a
475+
dictionary can't store two different keys if the keys have the
476+
same value but different types, e.g. 2 and 2L. The compiler
477+
must treat these two separately, so it does an explicit type
478+
comparison before comparing the values.
479+
"""
504480
t = type(name)
505481
for i in range(len(list)):
506-
# must do a comparison on type first to prevent UnicodeErrors
507-
# not clear that a dictionary would work, because we could
508-
# get UnicodeErrors on lookups
509-
elt = list[i]
510-
if isinstance(elt, t) and elt == name:
482+
if t == type(list[i]) and list[i] == name:
511483
return i
512484
end = len(list)
513485
list.append(name)
@@ -517,21 +489,22 @@ def XXX_lookupName(self, name, list):
517489
def _convert_LOAD_CONST(self, arg):
518490
if hasattr(arg, 'getCode'):
519491
arg = arg.getCode()
520-
return self._lookupName(arg, self.c_consts)
492+
return self._lookupName(arg, self.consts)
521493

522494
def _convert_LOAD_FAST(self, arg):
523-
self._lookupName(arg, self.c_names)
524-
return self._lookupName(arg, self.c_varnames)
495+
self._lookupName(arg, self.names)
496+
return self._lookupName(arg, self.varnames)
525497
_convert_STORE_FAST = _convert_LOAD_FAST
526498
_convert_DELETE_FAST = _convert_LOAD_FAST
527499

528500
def _convert_LOAD_NAME(self, arg):
529-
return self._lookupName(arg, self.c_names)
501+
if self.klass is None:
502+
self._lookupName(arg, self.varnames)
503+
return self._lookupName(arg, self.names)
530504

531505
def _convert_NAME(self, arg):
532-
if self.klass is None:
533-
self._lookupName(arg, self.c_varnames)
534-
return self._lookupName(arg, self.c_names)
506+
self._lookupName(arg, self.varnames)
507+
return self._lookupName(arg, self.names)
535508
_convert_STORE_NAME = _convert_NAME
536509
_convert_DELETE_NAME = _convert_NAME
537510
_convert_IMPORT_NAME = _convert_NAME
@@ -544,15 +517,15 @@ def _convert_NAME(self, arg):
544517
_convert_DELETE_GLOBAL = _convert_NAME
545518

546519
def _convert_DEREF(self, arg):
547-
self._lookupName(arg, self.c_names)
548-
self._lookupName(arg, self.c_varnames)
549-
return self._lookupName(arg, self.c_closure)
520+
self._lookupName(arg, self.names)
521+
self._lookupName(arg, self.varnames)
522+
return self._lookupName(arg, self.closure)
550523
_convert_LOAD_DEREF = _convert_DEREF
551524
_convert_STORE_DEREF = _convert_DEREF
552525

553526
def _convert_LOAD_CLOSURE(self, arg):
554-
self._lookupName(arg, self.c_varnames)
555-
return self._lookupName(arg, self.c_closure)
527+
self._lookupName(arg, self.varnames)
528+
return self._lookupName(arg, self.closure)
556529

557530
_cmp = list(dis.cmp_op)
558531
def _convert_COMPARE_OP(self, arg):

Tools/compiler/compiler/pyassem.py

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,6 @@ def sorter(a, b):
1515
l.sort(sorter)
1616
return l
1717

18-
def list2dict(l):
19-
d = {}
20-
for i in range(len(l)):
21-
d[l[i]] = i
22-
return d
23-
24-
def dict2list(d):
25-
l = [(v, k) for k, v in d.items()]
26-
l.sort()
27-
return [k for v, k in l]
28-
2918
class FlowGraph:
3019
def __init__(self):
3120
self.current = self.entry = Block()
@@ -457,25 +446,13 @@ def convertArgs(self):
457446
assert self.stage == FLAT
458447
self.consts.insert(0, self.docstring)
459448
self.sort_cellvars()
460-
461-
self.c_varnames = list2dict(self.varnames)
462-
self.c_names = list2dict(self.names)
463-
self.c_consts = list2dict(self.consts)
464-
self.c_closure = list2dict(self.closure)
465-
466449
for i in range(len(self.insts)):
467450
t = self.insts[i]
468451
if len(t) == 2:
469452
opname, oparg = t
470453
conv = self._converters.get(opname, None)
471454
if conv:
472455
self.insts[i] = opname, conv(self, oparg)
473-
474-
self.varnames = dict2list(self.c_varnames)
475-
self.names = dict2list(self.c_names)
476-
self.consts = dict2list(self.c_consts)
477-
self.closure = dict2list(self.c_closure)
478-
479456
self.stage = CONV
480457

481458
def sort_cellvars(self):
@@ -491,23 +468,18 @@ def sort_cellvars(self):
491468
self.cellvars = self.cellvars + cells.keys()
492469
self.closure = self.cellvars + self.freevars
493470

494-
def _lookupName(self, name, dict):
495-
i = dict.get(name, None)
496-
if i is None:
497-
i = dict[name] = len(dict)
498-
return i
471+
def _lookupName(self, name, list):
472+
"""Return index of name in list, appending if necessary
499473
500-
def XXX_lookupName(self, name, list):
501-
"""Return index of name in list, appending if necessary"""
502-
# XXX It should be possible to replace this with some
503-
# dictionary operations, but not sure how
474+
This routine uses a list instead of a dictionary, because a
475+
dictionary can't store two different keys if the keys have the
476+
same value but different types, e.g. 2 and 2L. The compiler
477+
must treat these two separately, so it does an explicit type
478+
comparison before comparing the values.
479+
"""
504480
t = type(name)
505481
for i in range(len(list)):
506-
# must do a comparison on type first to prevent UnicodeErrors
507-
# not clear that a dictionary would work, because we could
508-
# get UnicodeErrors on lookups
509-
elt = list[i]
510-
if isinstance(elt, t) and elt == name:
482+
if t == type(list[i]) and list[i] == name:
511483
return i
512484
end = len(list)
513485
list.append(name)
@@ -517,21 +489,22 @@ def XXX_lookupName(self, name, list):
517489
def _convert_LOAD_CONST(self, arg):
518490
if hasattr(arg, 'getCode'):
519491
arg = arg.getCode()
520-
return self._lookupName(arg, self.c_consts)
492+
return self._lookupName(arg, self.consts)
521493

522494
def _convert_LOAD_FAST(self, arg):
523-
self._lookupName(arg, self.c_names)
524-
return self._lookupName(arg, self.c_varnames)
495+
self._lookupName(arg, self.names)
496+
return self._lookupName(arg, self.varnames)
525497
_convert_STORE_FAST = _convert_LOAD_FAST
526498
_convert_DELETE_FAST = _convert_LOAD_FAST
527499

528500
def _convert_LOAD_NAME(self, arg):
529-
return self._lookupName(arg, self.c_names)
501+
if self.klass is None:
502+
self._lookupName(arg, self.varnames)
503+
return self._lookupName(arg, self.names)
530504

531505
def _convert_NAME(self, arg):
532-
if self.klass is None:
533-
self._lookupName(arg, self.c_varnames)
534-
return self._lookupName(arg, self.c_names)
506+
self._lookupName(arg, self.varnames)
507+
return self._lookupName(arg, self.names)
535508
_convert_STORE_NAME = _convert_NAME
536509
_convert_DELETE_NAME = _convert_NAME
537510
_convert_IMPORT_NAME = _convert_NAME
@@ -544,15 +517,15 @@ def _convert_NAME(self, arg):
544517
_convert_DELETE_GLOBAL = _convert_NAME
545518

546519
def _convert_DEREF(self, arg):
547-
self._lookupName(arg, self.c_names)
548-
self._lookupName(arg, self.c_varnames)
549-
return self._lookupName(arg, self.c_closure)
520+
self._lookupName(arg, self.names)
521+
self._lookupName(arg, self.varnames)
522+
return self._lookupName(arg, self.closure)
550523
_convert_LOAD_DEREF = _convert_DEREF
551524
_convert_STORE_DEREF = _convert_DEREF
552525

553526
def _convert_LOAD_CLOSURE(self, arg):
554-
self._lookupName(arg, self.c_varnames)
555-
return self._lookupName(arg, self.c_closure)
527+
self._lookupName(arg, self.varnames)
528+
return self._lookupName(arg, self.closure)
556529

557530
_cmp = list(dis.cmp_op)
558531
def _convert_COMPARE_OP(self, arg):

0 commit comments

Comments
 (0)