Merged revisions 76259,76326,76376-76377,76430,76471,76517 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

................
  r76259 | georg.brandl | 2009-11-14 05:50:51 -0600 (Sat, 14 Nov 2009) | 1 line

  Fix terminology.
................
  r76326 | georg.brandl | 2009-11-16 10:44:05 -0600 (Mon, 16 Nov 2009) | 1 line

  #7302: fix link.
................
  r76376 | georg.brandl | 2009-11-18 13:39:14 -0600 (Wed, 18 Nov 2009) | 1 line

  upcase Python
................
  r76377 | georg.brandl | 2009-11-18 14:05:15 -0600 (Wed, 18 Nov 2009) | 1 line

  Fix markup.
................
  r76430 | r.david.murray | 2009-11-20 07:29:43 -0600 (Fri, 20 Nov 2009) | 2 lines

  Issue 7363: fix indentation in socketserver udpserver example.
................
  r76471 | georg.brandl | 2009-11-23 13:53:19 -0600 (Mon, 23 Nov 2009) | 1 line

  #7345: fix arguments of formatyear().
................
  r76517 | benjamin.peterson | 2009-11-25 12:16:46 -0600 (Wed, 25 Nov 2009) | 29 lines

  Merged revisions 76160-76161,76250,76252,76447,76506 via svnmerge from
  svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3

  ........
    r76160 | benjamin.peterson | 2009-11-08 18:53:48 -0600 (Sun, 08 Nov 2009) | 1 line

    undeprecate the -p option; it's useful for converting python3 sources
  ........
    r76161 | benjamin.peterson | 2009-11-08 19:05:37 -0600 (Sun, 08 Nov 2009) | 1 line

    simplify condition
  ........
    r76250 | benjamin.peterson | 2009-11-13 16:56:48 -0600 (Fri, 13 Nov 2009) | 1 line

    fix handling of a utf-8 bom #7313
  ........
    r76252 | benjamin.peterson | 2009-11-13 16:58:36 -0600 (Fri, 13 Nov 2009) | 1 line

    remove pdb turd
  ........
    r76447 | benjamin.peterson | 2009-11-22 18:17:40 -0600 (Sun, 22 Nov 2009) | 1 line

    #7375 fix nested transformations in fix_urllib
  ........
    r76506 | benjamin.peterson | 2009-11-24 18:34:31 -0600 (Tue, 24 Nov 2009) | 1 line

    use generator expressions in any()
  ........
................
This commit is contained in:
Benjamin Peterson 2009-11-25 18:34:42 +00:00
parent a591cde305
commit 2021100d6d
16 changed files with 83 additions and 66 deletions

View File

@ -123,7 +123,7 @@ it's the base calendar for all computations.
Print a month's calendar as returned by :meth:`formatmonth`. Print a month's calendar as returned by :meth:`formatmonth`.
.. method:: formatyear(theyear, themonth, w=2, l=1, c=6, m=3) .. method:: formatyear(theyear, w=2, l=1, c=6, m=3)
Return a *m*-column calendar for an entire year as a multi-line string. Return a *m*-column calendar for an entire year as a multi-line string.
Optional parameters *w*, *l*, and *c* are for date column width, lines per Optional parameters *w*, *l*, and *c* are for date column width, lines per
@ -152,7 +152,7 @@ it's the base calendar for all computations.
used. used.
.. method:: formatyear(theyear, themonth, width=3) .. method:: formatyear(theyear, width=3)
Return a year's calendar as an HTML table. *width* (defaulting to 3) Return a year's calendar as an HTML table. *width* (defaulting to 3)
specifies the number of months per row. specifies the number of months per row.

View File

@ -176,7 +176,7 @@ are always available. They are listed here in alphabetical order.
.. note:: .. note::
When compiling a string with multi-line statements in ``'single'`` or When compiling a string with multi-line code in ``'single'`` or
``'eval'`` mode, input must be terminated by at least one newline ``'eval'`` mode, input must be terminated by at least one newline
character. This is to facilitate detection of incomplete and complete character. This is to facilitate detection of incomplete and complete
statements in the :mod:`code` module. statements in the :mod:`code` module.

View File

@ -446,9 +446,9 @@ This is the server side::
socket.sendto(data.upper(), self.client_address) socket.sendto(data.upper(), self.client_address)
if __name__ == "__main__": if __name__ == "__main__":
HOST, PORT = "localhost", 9999 HOST, PORT = "localhost", 9999
server = socketserver.UDPServer((HOST, PORT), MyUDPHandler) server = socketserver.UDPServer((HOST, PORT), MyUDPHandler)
server.serve_forever() server.serve_forever()
This is the client side:: This is the client side::

View File

@ -521,13 +521,12 @@ these rules. The methods of :class:`Template` are:
templates containing dangling delimiters, unmatched braces, or templates containing dangling delimiters, unmatched braces, or
placeholders that are not valid Python identifiers. placeholders that are not valid Python identifiers.
:class:`Template` instances also provide one public data attribute: :class:`Template` instances also provide one public data attribute:
.. attribute:: template
.. attribute:: string.template This is the object passed to the constructor's *template* argument. In
general, you shouldn't change it, but read-only access is not enforced.
This is the object passed to the constructor's *template* argument. In general,
you shouldn't change it, but read-only access is not enforced.
Here is an example of how to use a Template: Here is an example of how to use a Template:

View File

@ -76,7 +76,7 @@ implementations are free to support the strict mapping from IDL). See section
`Document Object Model (DOM) Level 1 Specification <http://www.w3.org/TR/REC-DOM-Level-1/>`_ `Document Object Model (DOM) Level 1 Specification <http://www.w3.org/TR/REC-DOM-Level-1/>`_
The W3C recommendation for the DOM supported by :mod:`xml.dom.minidom`. The W3C recommendation for the DOM supported by :mod:`xml.dom.minidom`.
`Python Language Mapping Specification <http://www.omg.org/docs/formal/02-11-05.pdf>`_ `Python Language Mapping Specification <http://www.omg.org/spec/PYTH/1.2/PDF>`_
This specifies the mapping from OMG IDL to Python. This specifies the mapping from OMG IDL to Python.

View File

@ -19,7 +19,7 @@ documentation). It can handle ZIP files that use the ZIP64 extensions
(that is ZIP files that are more than 4 GByte in size). It supports (that is ZIP files that are more than 4 GByte in size). It supports
decryption of encrypted files in ZIP archives, but it currently cannot decryption of encrypted files in ZIP archives, but it currently cannot
create an encrypted file. Decryption is extremely slow as it is create an encrypted file. Decryption is extremely slow as it is
implemented in native python rather than C. implemented in native Python rather than C.
For other archive formats, see the :mod:`bz2`, :mod:`gzip`, and For other archive formats, see the :mod:`bz2`, :mod:`gzip`, and
:mod:`tarfile` modules. :mod:`tarfile` modules.

View File

@ -108,7 +108,7 @@ class FixImports(fixer_base.BaseFix):
# Module usage could be in the trailer of an attribute lookup, so we # Module usage could be in the trailer of an attribute lookup, so we
# might have nested matches when "bare_with_attr" is present. # might have nested matches when "bare_with_attr" is present.
if "bare_with_attr" not in results and \ if "bare_with_attr" not in results and \
any([match(obj) for obj in attr_chain(node, "parent")]): any(match(obj) for obj in attr_chain(node, "parent")):
return False return False
return results return results
return False return False

View File

@ -99,4 +99,4 @@ def find_assign(node):
def is_subtree(root, node): def is_subtree(root, node):
if root == node: if root == node:
return True return True
return any([is_subtree(c, node) for c in root.children]) return any(is_subtree(c, node) for c in root.children)

View File

@ -49,7 +49,7 @@ class FixRenames(fixer_base.BaseFix):
match = super(FixRenames, self).match match = super(FixRenames, self).match
results = match(node) results = match(node)
if results: if results:
if any([match(obj) for obj in attr_chain(node, "parent")]): if any(match(obj) for obj in attr_chain(node, "parent")):
return False return False
return results return results
return False return False

View File

@ -63,7 +63,8 @@ def build_pattern():
yield """import_name< 'import' yield """import_name< 'import'
dotted_as_name< module_as=%r 'as' any > > dotted_as_name< module_as=%r 'as' any > >
""" % old_module """ % old_module
yield """power< module_dot=%r trailer< '.' member=%s > any* > # bare_with_attr has a special significance for FixImports.match().
yield """power< bare_with_attr=%r trailer< '.' member=%s > any* >
""" % (old_module, members) """ % (old_module, members)
@ -150,12 +151,11 @@ class FixUrllib(FixImports):
def transform_dot(self, node, results): def transform_dot(self, node, results):
"""Transform for calls to module members in code.""" """Transform for calls to module members in code."""
module_dot = results.get('module_dot') module_dot = results.get('bare_with_attr')
member = results.get('member') member = results.get('member')
# this may be a list of length one, or just a node new_name = None
if isinstance(member, list): if isinstance(member, list):
member = member[0] member = member[0]
new_name = None
for change in MAPPING[module_dot.value]: for change in MAPPING[module_dot.value]:
if member.value in change[1]: if member.value in change[1]:
new_name = change[0] new_name = change[0]
@ -171,7 +171,7 @@ class FixUrllib(FixImports):
self.transform_import(node, results) self.transform_import(node, results)
elif results.get('mod_member'): elif results.get('mod_member'):
self.transform_member(node, results) self.transform_member(node, results)
elif results.get('module_dot'): elif results.get('bare_with_attr'):
self.transform_dot(node, results) self.transform_dot(node, results)
# Renaming and star imports are not supported for these modules. # Renaming and star imports are not supported for these modules.
elif results.get('module_star'): elif results.get('module_star'):

View File

@ -90,8 +90,7 @@ def main(fixer_pkg, args=None):
parser.add_option("-l", "--list-fixes", action="store_true", parser.add_option("-l", "--list-fixes", action="store_true",
help="List available transformations (fixes/fix_*.py)") help="List available transformations (fixes/fix_*.py)")
parser.add_option("-p", "--print-function", action="store_true", parser.add_option("-p", "--print-function", action="store_true",
help="DEPRECATED Modify the grammar so that print() is " help="Modify the grammar so that print() is a function")
"a function")
parser.add_option("-v", "--verbose", action="store_true", parser.add_option("-v", "--verbose", action="store_true",
help="More verbose logging") help="More verbose logging")
parser.add_option("--no-diffs", action="store_true", parser.add_option("--no-diffs", action="store_true",
@ -103,12 +102,10 @@ def main(fixer_pkg, args=None):
# Parse command line arguments # Parse command line arguments
refactor_stdin = False refactor_stdin = False
flags = {}
options, args = parser.parse_args(args) options, args = parser.parse_args(args)
if not options.write and options.no_diffs: if not options.write and options.no_diffs:
warn("not writing files and not printing diffs; that's not very useful") warn("not writing files and not printing diffs; that's not very useful")
if options.print_function:
warn("-p is deprecated; "
"detection of from __future__ import print_function is automatic")
if not options.write and options.nobackups: if not options.write and options.nobackups:
parser.error("Can't use -n without -w") parser.error("Can't use -n without -w")
if options.list_fixes: if options.list_fixes:
@ -126,6 +123,8 @@ def main(fixer_pkg, args=None):
if options.write: if options.write:
print("Can't write to stdin.", file=sys.stderr) print("Can't write to stdin.", file=sys.stderr)
return 2 return 2
if options.print_function:
flags["print_function"] = True
# Set up logging handler # Set up logging handler
level = logging.DEBUG if options.verbose else logging.INFO level = logging.DEBUG if options.verbose else logging.INFO
@ -146,7 +145,7 @@ def main(fixer_pkg, args=None):
else: else:
requested = avail_fixes.union(explicit) requested = avail_fixes.union(explicit)
fixer_names = requested.difference(unwanted_fixes) fixer_names = requested.difference(unwanted_fixes)
rt = StdoutRefactoringTool(sorted(fixer_names), None, sorted(explicit), rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit),
options.nobackups, not options.no_diffs) options.nobackups, not options.no_diffs)
# Refactor all files and directories passed as arguments # Refactor all files and directories passed as arguments

View File

@ -283,9 +283,13 @@ def detect_encoding(readline):
# This behaviour mimics the Python interpreter # This behaviour mimics the Python interpreter
raise SyntaxError("unknown encoding: " + encoding) raise SyntaxError("unknown encoding: " + encoding)
if bom_found and codec.name != 'utf-8': if bom_found:
# This behaviour mimics the Python interpreter if codec.name != 'utf-8':
raise SyntaxError('encoding problem: utf-8') # This behaviour mimics the Python interpreter
raise SyntaxError('encoding problem: utf-8')
else:
# Allow it to be properly encoded and decoded.
encoding = 'utf-8-sig'
return encoding return encoding
first = read_or_stop() first = read_or_stop()

View File

@ -18,7 +18,6 @@ import logging
import operator import operator
import collections import collections
import io import io
import warnings
from itertools import chain from itertools import chain
# Local imports # Local imports
@ -139,26 +138,23 @@ def _detect_future_print(source):
if have_docstring: if have_docstring:
break break
have_docstring = True have_docstring = True
elif tp == token.NAME: elif tp == token.NAME and value == "from":
if value == "from": tp, value = advance()
tp, value = advance() if tp != token.NAME and value != "__future__":
if tp != token.NAME and value != "__future__":
break
tp, value = advance()
if tp != token.NAME and value != "import":
break
tp, value = advance()
if tp == token.OP and value == "(":
tp, value = advance()
while tp == token.NAME:
if value == "print_function":
return True
tp, value = advance()
if tp != token.OP and value != ",":
break
tp, value = advance()
else:
break break
tp, value = advance()
if tp != token.NAME and value != "import":
break
tp, value = advance()
if tp == token.OP and value == "(":
tp, value = advance()
while tp == token.NAME:
if value == "print_function":
return True
tp, value = advance()
if tp != token.OP and value != ",":
break
tp, value = advance()
else: else:
break break
except StopIteration: except StopIteration:
@ -172,7 +168,7 @@ class FixerError(Exception):
class RefactoringTool(object): class RefactoringTool(object):
_default_options = {} _default_options = {"print_function" : False}
CLASS_PREFIX = "Fix" # The prefix for fixer classes CLASS_PREFIX = "Fix" # The prefix for fixer classes
FILE_PREFIX = "fix_" # The prefix for modules with a fixer within FILE_PREFIX = "fix_" # The prefix for modules with a fixer within
@ -189,15 +185,16 @@ class RefactoringTool(object):
self.explicit = explicit or [] self.explicit = explicit or []
self.options = self._default_options.copy() self.options = self._default_options.copy()
if options is not None: if options is not None:
if "print_function" in options:
warnings.warn("the 'print_function' option is deprecated",
DeprecationWarning)
self.options.update(options) self.options.update(options)
if self.options["print_function"]:
self.grammar = pygram.python_grammar_no_print_statement
else:
self.grammar = pygram.python_grammar
self.errors = [] self.errors = []
self.logger = logging.getLogger("RefactoringTool") self.logger = logging.getLogger("RefactoringTool")
self.fixer_log = [] self.fixer_log = []
self.wrote = False self.wrote = False
self.driver = driver.Driver(pygram.python_grammar, self.driver = driver.Driver(self.grammar,
convert=pytree.convert, convert=pytree.convert,
logger=self.logger) logger=self.logger)
self.pre_order, self.post_order = self.get_fixers() self.pre_order, self.post_order = self.get_fixers()
@ -353,7 +350,7 @@ class RefactoringTool(object):
name, err.__class__.__name__, err) name, err.__class__.__name__, err)
return return
finally: finally:
self.driver.grammar = pygram.python_grammar self.driver.grammar = self.grammar
self.log_debug("Refactoring %s", name) self.log_debug("Refactoring %s", name)
self.refactor_tree(tree, name) self.refactor_tree(tree, name)
return tree return tree

View File

@ -0,0 +1,3 @@
# coding: utf-8
print "BOM BOOM!"

View File

@ -1753,6 +1753,8 @@ class Test_urllib(FixerTestCase):
for old, changes in self.modules.items(): for old, changes in self.modules.items():
for new, members in changes: for new, members in changes:
for member in members: for member in members:
new_import = ", ".join([n for (n, mems)
in self.modules[old]])
b = """ b = """
import %s import %s
foo(%s.%s) foo(%s.%s)
@ -1760,9 +1762,16 @@ class Test_urllib(FixerTestCase):
a = """ a = """
import %s import %s
foo(%s.%s) foo(%s.%s)
""" % (", ".join([n for (n, mems) """ % (new_import, new, member)
in self.modules[old]]), self.check(b, a)
new, member) b = """
import %s
%s.%s(%s.%s)
""" % (old, old, member, old, member)
a = """
import %s
%s.%s(%s.%s)
""" % (new_import, new, member, new, member)
self.check(b, a) self.check(b, a)

View File

@ -4,6 +4,7 @@ Unit tests for refactor.py.
import sys import sys
import os import os
import codecs
import operator import operator
import io import io
import tempfile import tempfile
@ -45,12 +46,10 @@ class TestRefactoringTool(unittest.TestCase):
return refactor.RefactoringTool(fixers, options, explicit) return refactor.RefactoringTool(fixers, options, explicit)
def test_print_function_option(self): def test_print_function_option(self):
with warnings.catch_warnings(record=True) as w: rt = self.rt({"print_function" : True})
warnings.simplefilter("always", DeprecationWarning) self.assertTrue(rt.grammar is pygram.python_grammar_no_print_statement)
refactor.RefactoringTool(_DEFAULT_FIXERS, {"print_function" : True}) self.assertTrue(rt.driver.grammar is
self.assertEqual(len(w), 1) pygram.python_grammar_no_print_statement)
msg, = w
self.assertTrue(msg.category is DeprecationWarning)
def test_fixer_loading_helpers(self): def test_fixer_loading_helpers(self):
contents = ["explicit", "first", "last", "parrot", "preorder"] contents = ["explicit", "first", "last", "parrot", "preorder"]
@ -179,10 +178,12 @@ from __future__ import print_function"""
try: try:
rt.refactor_file(test_file, True) rt.refactor_file(test_file, True)
self.assertNotEqual(old_contents, read_file()) new_contents = read_file()
self.assertNotEqual(old_contents, new_contents)
finally: finally:
with open(test_file, "wb") as fp: with open(test_file, "wb") as fp:
fp.write(old_contents) fp.write(old_contents)
return new_contents
def test_refactor_file(self): def test_refactor_file(self):
test_file = os.path.join(FIXER_DIR, "parrot_example.py") test_file = os.path.join(FIXER_DIR, "parrot_example.py")
@ -223,6 +224,11 @@ from __future__ import print_function"""
fn = os.path.join(TEST_DATA_DIR, "different_encoding.py") fn = os.path.join(TEST_DATA_DIR, "different_encoding.py")
self.check_file_refactoring(fn) self.check_file_refactoring(fn)
def test_bom(self):
fn = os.path.join(TEST_DATA_DIR, "bom.py")
data = self.check_file_refactoring(fn)
self.assertTrue(data.startswith(codecs.BOM_UTF8))
def test_crlf_newlines(self): def test_crlf_newlines(self):
old_sep = os.linesep old_sep = os.linesep
os.linesep = "\r\n" os.linesep = "\r\n"