1
# Copyright 2007 Google, Inc. All Rights Reserved.
2
# Licensed to PSF under a Contributor Agreement.
4
"""Fixer that changes xrange(...) into range(...)."""
7
from .. import fixer_base
8
from ..fixer_util import Name, Call, consuming_calls
12
class FixXrange(fixer_base.BaseFix):
16
(name='range'|name='xrange') trailer< '(' args=any ')' >
20
def transform(self, node, results):
21
name = results["name"]
22
if name.value == "xrange":
23
return self.transform_xrange(node, results)
24
elif name.value == "range":
25
return self.transform_range(node, results)
27
raise ValueError(repr(name))
29
def transform_xrange(self, node, results):
30
name = results["name"]
31
name.replace(Name("range", prefix=name.get_prefix()))
33
def transform_range(self, node, results):
34
if not self.in_special_context(node):
35
range_call = Call(Name("range"), [results["args"].clone()])
36
# Encase the range call in list().
37
list_call = Call(Name("list"), [range_call],
38
prefix=node.get_prefix())
39
# Put things that were after the range() call after the list call.
40
for n in results["rest"]:
41
list_call.append_child(n)
45
P1 = "power< func=NAME trailer< '(' node=any ')' > any* >"
46
p1 = patcomp.compile_pattern(P1)
48
P2 = """for_stmt< 'for' any 'in' node=any ':' any* >
49
| comp_for< 'for' any 'in' node=any any* >
50
| comparison< any 'in' node=any any*>
52
p2 = patcomp.compile_pattern(P2)
54
def in_special_context(self, node):
55
if node.parent is None:
58
if (node.parent.parent is not None and
59
self.p1.match(node.parent.parent, results) and
60
results["node"] is node):
61
# list(d.keys()) -> list(d.keys()), etc.
62
return results["func"].value in consuming_calls
63
# for ... in d.iterkeys() -> for ... in d.keys(), etc.
64
return self.p2.match(node.parent, results) and results["node"] is node