Changeset 391 for python/trunk/Lib/lib2to3/main.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/lib2to3/main.py
r2 r391 2 2 Main program for 2to3. 3 3 """ 4 5 from __future__ import with_statement 4 6 5 7 import sys … … 24 26 class StdoutRefactoringTool(refactor.MultiprocessRefactoringTool): 25 27 """ 28 A refactoring tool that can avoid overwriting its input files. 26 29 Prints output to stdout. 30 31 Output files can optionally be written to a different directory and or 32 have an extra file suffix appended to their name for use in situations 33 where you do not want to replace the input files. 27 34 """ 28 35 29 def __init__(self, fixers, options, explicit, nobackups, show_diffs): 36 def __init__(self, fixers, options, explicit, nobackups, show_diffs, 37 input_base_dir='', output_dir='', append_suffix=''): 38 """ 39 Args: 40 fixers: A list of fixers to import. 41 options: A dict with RefactoringTool configuration. 42 explicit: A list of fixers to run even if they are explicit. 43 nobackups: If true no backup '.bak' files will be created for those 44 files that are being refactored. 45 show_diffs: Should diffs of the refactoring be printed to stdout? 46 input_base_dir: The base directory for all input files. This class 47 will strip this path prefix off of filenames before substituting 48 it with output_dir. Only meaningful if output_dir is supplied. 49 All files processed by refactor() must start with this path. 50 output_dir: If supplied, all converted files will be written into 51 this directory tree instead of input_base_dir. 52 append_suffix: If supplied, all files output by this tool will have 53 this appended to their filename. Useful for changing .py to 54 .py3 for example by passing append_suffix='3'. 55 """ 30 56 self.nobackups = nobackups 31 57 self.show_diffs = show_diffs 58 if input_base_dir and not input_base_dir.endswith(os.sep): 59 input_base_dir += os.sep 60 self._input_base_dir = input_base_dir 61 self._output_dir = output_dir 62 self._append_suffix = append_suffix 32 63 super(StdoutRefactoringTool, self).__init__(fixers, options, explicit) 33 64 … … 37 68 38 69 def write_file(self, new_text, filename, old_text, encoding): 70 orig_filename = filename 71 if self._output_dir: 72 if filename.startswith(self._input_base_dir): 73 filename = os.path.join(self._output_dir, 74 filename[len(self._input_base_dir):]) 75 else: 76 raise ValueError('filename %s does not start with the ' 77 'input_base_dir %s' % ( 78 filename, self._input_base_dir)) 79 if self._append_suffix: 80 filename += self._append_suffix 81 if orig_filename != filename: 82 output_dir = os.path.dirname(filename) 83 if not os.path.isdir(output_dir): 84 os.makedirs(output_dir) 85 self.log_message('Writing converted %s to %s.', orig_filename, 86 filename) 39 87 if not self.nobackups: 40 88 # Make backup … … 54 102 if not self.nobackups: 55 103 shutil.copymode(backup, filename) 104 if orig_filename != filename: 105 # Preserve the file mode in the new output directory. 106 shutil.copymode(orig_filename, filename) 56 107 57 108 def print_output(self, old, new, filename, equal): … … 63 114 diff_lines = diff_texts(old, new, filename) 64 115 try: 65 for line in diff_lines: 66 print line 116 if self.output_lock is not None: 117 with self.output_lock: 118 for line in diff_lines: 119 print line 120 sys.stdout.flush() 121 else: 122 for line in diff_lines: 123 print line 67 124 except UnicodeEncodeError: 68 125 warn("couldn't encode %s's diff for your terminal" % … … 94 151 type="int", help="Run 2to3 concurrently") 95 152 parser.add_option("-x", "--nofix", action="append", default=[], 96 help="Prevent a fixer from being run.")153 help="Prevent a transformation from being run") 97 154 parser.add_option("-l", "--list-fixes", action="store_true", 98 help="List available transformations (fixes/fix_*.py)")155 help="List available transformations") 99 156 parser.add_option("-p", "--print-function", action="store_true", 100 157 help="Modify the grammar so that print() is a function") … … 106 163 help="Write back modified files") 107 164 parser.add_option("-n", "--nobackups", action="store_true", default=False, 108 help="Don't write backups for modified files.") 165 help="Don't write backups for modified files") 166 parser.add_option("-o", "--output-dir", action="store", type="str", 167 default="", help="Put output files in this directory " 168 "instead of overwriting the input files. Requires -n.") 169 parser.add_option("-W", "--write-unchanged-files", action="store_true", 170 help="Also write files even if no changes were required" 171 " (useful with --output-dir); implies -w.") 172 parser.add_option("--add-suffix", action="store", type="str", default="", 173 help="Append this string to all output filenames." 174 " Requires -n if non-empty. " 175 "ex: --add-suffix='3' will generate .py3 files.") 109 176 110 177 # Parse command line arguments … … 112 179 flags = {} 113 180 options, args = parser.parse_args(args) 181 if options.write_unchanged_files: 182 flags["write_unchanged_files"] = True 183 if not options.write: 184 warn("--write-unchanged-files/-W implies -w.") 185 options.write = True 186 # If we allowed these, the original files would be renamed to backup names 187 # but not replaced. 188 if options.output_dir and not options.nobackups: 189 parser.error("Can't use --output-dir/-o without -n.") 190 if options.add_suffix and not options.nobackups: 191 parser.error("Can't use --add-suffix without -n.") 192 114 193 if not options.write and options.no_diffs: 115 194 warn("not writing files and not printing diffs; that's not very useful") … … 137 216 level = logging.DEBUG if options.verbose else logging.INFO 138 217 logging.basicConfig(format='%(name)s: %(message)s', level=level) 218 logger = logging.getLogger('lib2to3.main') 139 219 140 220 # Initialize the refactoring tool … … 153 233 requested = avail_fixes.union(explicit) 154 234 fixer_names = requested.difference(unwanted_fixes) 155 rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), 156 options.nobackups, not options.no_diffs) 235 input_base_dir = os.path.commonprefix(args) 236 if (input_base_dir and not input_base_dir.endswith(os.sep) 237 and not os.path.isdir(input_base_dir)): 238 # One or more similar names were passed, their directory is the base. 239 # os.path.commonprefix() is ignorant of path elements, this corrects 240 # for that weird API. 241 input_base_dir = os.path.dirname(input_base_dir) 242 if options.output_dir: 243 input_base_dir = input_base_dir.rstrip(os.sep) 244 logger.info('Output in %r will mirror the input directory %r layout.', 245 options.output_dir, input_base_dir) 246 rt = StdoutRefactoringTool( 247 sorted(fixer_names), flags, sorted(explicit), 248 options.nobackups, not options.no_diffs, 249 input_base_dir=input_base_dir, 250 output_dir=options.output_dir, 251 append_suffix=options.add_suffix) 157 252 158 253 # Refactor all files and directories passed as arguments
Note:
See TracChangeset
for help on using the changeset viewer.