Skip to content

Commit c9e833f

Browse files
committed
Merged revisions 80936 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ................ r80936 | benjamin.peterson | 2010-05-07 14:10:11 -0500 (Fri, 07 May 2010) | 76 lines Merged revisions 80934 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ................ r80934 | benjamin.peterson | 2010-05-07 13:58:23 -0500 (Fri, 07 May 2010) | 69 lines Merged revisions 79911,79916-79917,80018,80418,80572-80573,80635-80639,80668,80922 via svnmerge from svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3 ........ r79911 | benjamin.peterson | 2010-04-09 15:38:53 -0500 (Fri, 09 Apr 2010) | 1 line use absolute import ........ r79916 | benjamin.peterson | 2010-04-09 16:05:21 -0500 (Fri, 09 Apr 2010) | 1 line generalize detection of __future__ imports and attach them to the tree ........ r79917 | benjamin.peterson | 2010-04-09 16:11:44 -0500 (Fri, 09 Apr 2010) | 1 line don't try to 'fix' relative imports when absolute_import is enabled #8858 ........ r80018 | benjamin.peterson | 2010-04-12 16:12:12 -0500 (Mon, 12 Apr 2010) | 4 lines prevent diffs from being mangled is multiprocess mode #6409 Patch by George Boutsioukis. ........ r80418 | benjamin.peterson | 2010-04-23 16:00:03 -0500 (Fri, 23 Apr 2010) | 1 line remove unhelpful description ........ r80572 | benjamin.peterson | 2010-04-27 20:33:54 -0500 (Tue, 27 Apr 2010) | 1 line use unicode literals ........ r80573 | jeffrey.yasskin | 2010-04-27 23:08:27 -0500 (Tue, 27 Apr 2010) | 6 lines Don't transform imports that are already relative. 2to3 turned from . import refactor into from .. import refactor which broke the transformation of 2to3 itself. ........ r80635 | benjamin.peterson | 2010-04-29 16:02:23 -0500 (Thu, 29 Apr 2010) | 1 line remove imports ........ r80636 | benjamin.peterson | 2010-04-29 16:02:41 -0500 (Thu, 29 Apr 2010) | 1 line unicode literal ........ r80637 | benjamin.peterson | 2010-04-29 16:03:42 -0500 (Thu, 29 Apr 2010) | 1 line must pass a string to Number ........ r80638 | benjamin.peterson | 2010-04-29 16:05:34 -0500 (Thu, 29 Apr 2010) | 1 line unicode literals ........ r80639 | benjamin.peterson | 2010-04-29 16:06:09 -0500 (Thu, 29 Apr 2010) | 1 line pass string to Number ........ r80668 | jeffrey.yasskin | 2010-04-30 18:02:47 -0500 (Fri, 30 Apr 2010) | 4 lines Make 2to3 run under Python 2.5 so that the benchmark suite at http://hg.python.org/benchmarks/ can use it and still run on implementations that haven't gotten to 2.6 yet. Fixes issue 8566. ........ r80922 | benjamin.peterson | 2010-05-07 11:06:25 -0500 (Fri, 07 May 2010) | 1 line prevent xrange transformation from wrapping range calls it produces in list ........ ................ ................
1 parent 3a3bba3 commit c9e833f

13 files changed

+165
-88
lines changed

Lib/lib2to3/fixes/fix_import.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ class FixImport(fixer_base.BaseFix):
4343
import_name< 'import' imp=any >
4444
"""
4545

46+
def start_tree(self, tree, name):
47+
super(FixImport, self).start_tree(tree, name)
48+
self.skip = "absolute_import" in tree.future_features
49+
4650
def transform(self, node, results):
51+
if self.skip:
52+
return
4753
imp = results['imp']
4854

4955
if node.type == syms.import_from:
@@ -71,19 +77,22 @@ def transform(self, node, results):
7177
self.warning(node, "absolute and local imports together")
7278
return
7379

74-
new = FromImport('.', [imp])
80+
new = FromImport(".", [imp])
7581
new.prefix = node.prefix
7682
return new
7783

7884
def probably_a_local_import(self, imp_name):
79-
imp_name = imp_name.split('.', 1)[0]
85+
if imp_name.startswith("."):
86+
# Relative imports are certainly not local imports.
87+
return False
88+
imp_name = imp_name.split(".", 1)[0]
8089
base_path = dirname(self.filename)
8190
base_path = join(base_path, imp_name)
8291
# If there is no __init__.py next to the file its not in a package
8392
# so can't be a relative import.
84-
if not exists(join(dirname(base_path), '__init__.py')):
93+
if not exists(join(dirname(base_path), "__init__.py")):
8594
return False
86-
for ext in ['.py', sep, '.pyc', '.so', '.sl', '.pyd']:
95+
for ext in [".py", sep, ".pyc", ".so", ".sl", ".pyd"]:
8796
if exists(base_path + ext):
8897
return True
8998
return False

Lib/lib2to3/fixes/fix_operator.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ class FixOperator(fixer_base.BaseFix):
1414
func = "'(' func=any ')'"
1515
PATTERN = """
1616
power< module='operator'
17-
trailer< '.' {methods} > trailer< {func} > >
17+
trailer< '.' %(methods)s > trailer< %(func)s > >
1818
|
19-
power< {methods} trailer< {func} > >
20-
""".format(methods=methods, func=func)
19+
power< %(methods)s trailer< %(func)s > >
20+
""" % dict(methods=methods, func=func)
2121

2222
def transform(self, node, results):
2323
method = results["method"][0]

Lib/lib2to3/fixes/fix_reduce.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
used in that module.
88
"""
99

10-
from .. import pytree
11-
from .. import fixer_base
12-
from ..fixer_util import Name, Attr, touch_import
10+
from lib2to3 import fixer_base
11+
from lib2to3.fixer_util import touch_import
1312

1413

1514

Lib/lib2to3/fixes/fix_tuple_params.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ def map_to_index(param_list, prefix=[], d=None):
154154
if d is None:
155155
d = {}
156156
for i, obj in enumerate(param_list):
157-
trailer = [Subscript(Number(i))]
157+
trailer = [Subscript(Number(str(i)))]
158158
if isinstance(obj, list):
159159
map_to_index(obj, trailer, d=d)
160160
else:

Lib/lib2to3/fixes/fix_xrange.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ class FixXrange(fixer_base.BaseFix):
1717
rest=any* >
1818
"""
1919

20+
def start_tree(self, tree, filename):
21+
super(FixXrange, self).start_tree(tree, filename)
22+
self.transformed_xranges = set()
23+
24+
def finish_tree(self, tree, filename):
25+
self.transformed_xranges = None
26+
2027
def transform(self, node, results):
2128
name = results["name"]
2229
if name.value == "xrange":
@@ -29,9 +36,12 @@ def transform(self, node, results):
2936
def transform_xrange(self, node, results):
3037
name = results["name"]
3138
name.replace(Name("range", prefix=name.prefix))
39+
# This prevents the new range call from being wrapped in a list later.
40+
self.transformed_xranges.add(id(node))
3241

3342
def transform_range(self, node, results):
34-
if not self.in_special_context(node):
43+
if (id(node) not in self.transformed_xranges and
44+
not self.in_special_context(node)):
3545
range_call = Call(Name("range"), [results["args"].clone()])
3646
# Encase the range call in list().
3747
list_call = Call(Name("list"), [range_call],

Lib/lib2to3/main.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Main program for 2to3.
33
"""
44

5+
from __future__ import with_statement
6+
57
import sys
68
import os
79
import difflib
@@ -62,8 +64,14 @@ def print_output(self, old, new, filename, equal):
6264
if self.show_diffs:
6365
diff_lines = diff_texts(old, new, filename)
6466
try:
65-
for line in diff_lines:
66-
print(line)
67+
if self.output_lock is not None:
68+
with self.output_lock:
69+
for line in diff_lines:
70+
print(line)
71+
sys.stdout.flush()
72+
else:
73+
for line in diff_lines:
74+
print(line)
6775
except UnicodeEncodeError:
6876
warn("couldn't encode %s's diff for your terminal" %
6977
(filename,))
@@ -94,7 +102,7 @@ def main(fixer_pkg, args=None):
94102
parser.add_option("-x", "--nofix", action="append", default=[],
95103
help="Prevent a fixer from being run.")
96104
parser.add_option("-l", "--list-fixes", action="store_true",
97-
help="List available transformations (fixes/fix_*.py)")
105+
help="List available transformations")
98106
parser.add_option("-p", "--print-function", action="store_true",
99107
help="Modify the grammar so that print() is a function")
100108
parser.add_option("-v", "--verbose", action="store_true",

Lib/lib2to3/pgen2/tokenize.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@
3838
"generate_tokens", "untokenize"]
3939
del token
4040

41+
try:
42+
bytes
43+
except NameError:
44+
# Support bytes type in Python <= 2.5, so 2to3 turns itself into
45+
# valid Python 3 code.
46+
bytes = str
47+
4148
def group(*choices): return '(' + '|'.join(choices) + ')'
4249
def any(*choices): return group(*choices) + '*'
4350
def maybe(*choices): return group(*choices) + '?'
@@ -267,7 +274,7 @@ def read_or_stop():
267274
try:
268275
return readline()
269276
except StopIteration:
270-
return b''
277+
return bytes()
271278

272279
def find_cookie(line):
273280
try:

Lib/lib2to3/pytree.py

+7-8
Original file line numberDiff line numberDiff line change
@@ -289,20 +289,20 @@ def pre_order(self):
289289
for node in child.post_order():
290290
yield node
291291

292-
@property
293-
def prefix(self):
292+
def _prefix_getter(self):
294293
"""
295294
The whitespace and comments preceding this node in the input.
296295
"""
297296
if not self.children:
298297
return ""
299298
return self.children[0].prefix
300299

301-
@prefix.setter
302-
def prefix(self, prefix):
300+
def _prefix_setter(self, prefix):
303301
if self.children:
304302
self.children[0].prefix = prefix
305303

304+
prefix = property(_prefix_getter, _prefix_setter)
305+
306306
def set_child(self, i, child):
307307
"""
308308
Equivalent to 'node.children[i] = child'. This method also sets the
@@ -390,18 +390,17 @@ def pre_order(self):
390390
"""Return a pre-order iterator for the tree."""
391391
yield self
392392

393-
@property
394-
def prefix(self):
393+
def _prefix_getter(self):
395394
"""
396395
The whitespace and comments preceding this token in the input.
397396
"""
398397
return self._prefix
399398

400-
@prefix.setter
401-
def prefix(self, prefix):
399+
def _prefix_setter(self, prefix):
402400
self.changed()
403401
self._prefix = prefix
404402

403+
prefix = property(_prefix_getter, _prefix_setter)
405404

406405
def convert(gr, raw_node):
407406
"""

Lib/lib2to3/refactor.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
provides infrastructure to write your own refactoring tool.
99
"""
1010

11+
from __future__ import with_statement
12+
1113
__author__ = "Guido van Rossum <guido@python.org>"
1214

1315

@@ -122,13 +124,14 @@ def _to_system_newlines(input):
122124
_to_system_newlines = _identity
123125

124126

125-
def _detect_future_print(source):
127+
def _detect_future_features(source):
126128
have_docstring = False
127129
gen = tokenize.generate_tokens(io.StringIO(source).readline)
128130
def advance():
129131
tok = next(gen)
130132
return tok[0], tok[1]
131133
ignore = frozenset((token.NEWLINE, tokenize.NL, token.COMMENT))
134+
features = set()
132135
try:
133136
while True:
134137
tp, value = advance()
@@ -140,26 +143,25 @@ def advance():
140143
have_docstring = True
141144
elif tp == token.NAME and value == "from":
142145
tp, value = advance()
143-
if tp != token.NAME and value != "__future__":
146+
if tp != token.NAME or value != "__future__":
144147
break
145148
tp, value = advance()
146-
if tp != token.NAME and value != "import":
149+
if tp != token.NAME or value != "import":
147150
break
148151
tp, value = advance()
149152
if tp == token.OP and value == "(":
150153
tp, value = advance()
151154
while tp == token.NAME:
152-
if value == "print_function":
153-
return True
155+
features.add(value)
154156
tp, value = advance()
155-
if tp != token.OP and value != ",":
157+
if tp != token.OP or value != ",":
156158
break
157159
tp, value = advance()
158160
else:
159161
break
160162
except StopIteration:
161163
pass
162-
return False
164+
return frozenset(features)
163165

164166

165167
class FixerError(Exception):
@@ -341,7 +343,8 @@ def refactor_string(self, data, name):
341343
An AST corresponding to the refactored input stream; None if
342344
there were errors during the parse.
343345
"""
344-
if _detect_future_print(data):
346+
features = _detect_future_features(data)
347+
if "print_function" in features:
345348
self.driver.grammar = pygram.python_grammar_no_print_statement
346349
try:
347350
tree = self.driver.parse_string(data)
@@ -351,6 +354,7 @@ def refactor_string(self, data, name):
351354
return
352355
finally:
353356
self.driver.grammar = self.grammar
357+
tree.future_features = features
354358
self.log_debug("Refactoring %s", name)
355359
self.refactor_tree(tree, name)
356360
return tree
@@ -605,6 +609,7 @@ class MultiprocessRefactoringTool(RefactoringTool):
605609
def __init__(self, *args, **kwargs):
606610
super(MultiprocessRefactoringTool, self).__init__(*args, **kwargs)
607611
self.queue = None
612+
self.output_lock = None
608613

609614
def refactor(self, items, write=False, doctests_only=False,
610615
num_processes=1):
@@ -618,6 +623,7 @@ def refactor(self, items, write=False, doctests_only=False,
618623
if self.queue is not None:
619624
raise RuntimeError("already doing multiple processes")
620625
self.queue = multiprocessing.JoinableQueue()
626+
self.output_lock = multiprocessing.Lock()
621627
processes = [multiprocessing.Process(target=self._child)
622628
for i in range(num_processes)]
623629
try:

Lib/lib2to3/tests/test_fixers.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,17 @@ def test_in_consuming_context(self):
14971497
for call in fixer_util.consuming_calls:
14981498
self.unchanged("a = %s(range(10))" % call)
14991499

1500+
class Test_xrange_with_reduce(FixerTestCase):
1501+
1502+
def setUp(self):
1503+
super(Test_xrange_with_reduce, self).setUp(["xrange", "reduce"])
1504+
1505+
def test_double_transform(self):
1506+
b = """reduce(x, xrange(5))"""
1507+
a = """from functools import reduce
1508+
reduce(x, range(5))"""
1509+
self.check(b, a)
1510+
15001511
class Test_raw_input(FixerTestCase):
15011512
fixer = "raw_input"
15021513

@@ -3679,7 +3690,7 @@ def fake_exists(name):
36793690
self.files_checked.append(name)
36803691
return self.always_exists or (name in self.present_files)
36813692

3682-
from ..fixes import fix_import
3693+
from lib2to3.fixes import fix_import
36833694
fix_import.exists = fake_exists
36843695

36853696
def tearDown(self):
@@ -3722,6 +3733,12 @@ def test_not_in_package(self):
37223733
self.present_files = set(["bar.py"])
37233734
self.unchanged(s)
37243735

3736+
def test_with_absolute_import_enabled(self):
3737+
s = "from __future__ import absolute_import\nimport bar"
3738+
self.always_exists = False
3739+
self.present_files = set(["__init__.py", "bar.py"])
3740+
self.unchanged(s)
3741+
37253742
def test_in_package(self):
37263743
b = "import bar"
37273744
a = "from . import bar"
@@ -3736,6 +3753,10 @@ def test_import_from_package(self):
37363753
self.present_files = set(["__init__.py", "bar" + os.path.sep])
37373754
self.check(b, a)
37383755

3756+
def test_already_relative_import(self):
3757+
s = "from . import bar"
3758+
self.unchanged(s)
3759+
37393760
def test_comments_and_indent(self):
37403761
b = "import bar # Foo"
37413762
a = "from . import bar # Foo"

Lib/lib2to3/tests/test_parser.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
test_grammar.py files from both Python 2 and Python 3.
77
"""
88

9+
from __future__ import with_statement
10+
911
# Testing imports
1012
from . import support
1113
from .support import driver, test_dir
@@ -149,10 +151,11 @@ def test_all_project_files(self):
149151
for filepath in support.all_project_files():
150152
with open(filepath, "rb") as fp:
151153
encoding = tokenize.detect_encoding(fp.readline)[0]
152-
fp.seek(0)
154+
self.assertTrue(encoding is not None,
155+
"can't detect encoding for %s" % filepath)
156+
with open(filepath, "r") as fp:
153157
source = fp.read()
154-
if encoding:
155-
source = source.decode(encoding)
158+
source = source.decode(encoding)
156159
tree = driver.parse_string(source)
157160
new = str(tree)
158161
if encoding:
@@ -199,10 +202,10 @@ def test_multiline_str_literals(self):
199202
self.validate(s)
200203

201204

202-
def diff(fn, result):
203-
f = open("@", "wb")
205+
def diff(fn, result, encoding):
206+
f = open("@", "w")
204207
try:
205-
f.write(result)
208+
f.write(result.encode(encoding))
206209
finally:
207210
f.close()
208211
try:

0 commit comments

Comments
 (0)