def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="modernize [options] file|dir ...") parser.add_option("-d", "--doctests_only", action="store_true", help="Fix up doctests only") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default: all") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") parser.add_option("-p", "--print-function", action="store_true", help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") parser.add_option("--compat-unicode", action="store_true", default=False, help="Leave u'' and b'' prefixes unchanged (requires " "Python 3.3 and higher).") parser.add_option("--future-unicode", action="store_true", default=False, help="Use unicode_strings future_feature instead of the six.u function " "(only useful for Python 2.6+).") parser.add_option("--no-six", action="store_true", default=False, help="Exclude fixes that depend on the six package") fixer_pkg = 'libmodernize.fixes' avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) avail_fixes.update(lib2to3_fix_names) # Parse command line arguments refactor_stdin = False flags = {} options, args = parser.parse_args(args) if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.list_fixes: print "Available transformations for the -f/--fix option:" for fixname in sorted(avail_fixes): print fixname if not args: return 0 if not args: print >> sys.stderr, "At least one file or directory argument required." print >> sys.stderr, "Use --help to show usage." return 2 if "-" in args: refactor_stdin = True if options.write: print >> sys.stderr, "Can't write to stdin." return 2 if options.print_function: flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) # Initialize the refactoring tool unwanted_fixes = set(options.nofix) # Remove unicode fixers depending on command line options if options.compat_unicode: unwanted_fixes.add('libmodernize.fixes.fix_unicode') unwanted_fixes.add('libmodernize.fixes.fix_unicode_future') elif options.future_unicode: unwanted_fixes.add('libmodernize.fixes.fix_unicode') else: unwanted_fixes.add('libmodernize.fixes.fix_unicode_future') if options.no_six: unwanted_fixes.update(six_fix_names) explicit = set() if options.fix: all_present = False for fix in options.fix: if fix == "all": all_present = True else: explicit.add(fix) requested = avail_fixes.union(explicit) if all_present else explicit else: requested = avail_fixes.union(explicit) fixer_names = requested.difference(unwanted_fixes) rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, options.doctests_only, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print >> sys.stderr, "Sorry, -j isn't " \ "supported on this platform." return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))
def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="futurize [options] file|dir ...") parser.add_option( "-a", "--all-imports", action="store_true", help="Adds all __future__ and future imports to each module") parser.add_option("-d", "--doctests_only", action="store_true", help="Fix up doctests only") parser.add_option( "-b", "--tobytes", action="store_true", help="Convert all unadorned string literals to bytes objects") parser.add_option( "-1", "--stage1", action="store_true", help= "Modernize Python 2 code only; no compatibility with Python 3 (or dependency on ``future``)" ) parser.add_option( "-2", "--stage2", action="store_true", help= "Take modernized (stage1) code and add a dependency on ``future`` to provide Py3 compatibility." ) parser.add_option("-0", "--both-stages", action="store_true", help="Apply both stages 1 and 2") # parser.add_option("-f", "--fix", action="append", default=[], # help="Each FIX specifies a transformation; default: all") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") # parser.add_option("-p", "--print-function", action="store_true", # help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") parser.add_option("--from3", action="store_true", default=False, help="Assume the code is already Python 3 and just " "requires ``__future__`` and ``future`` imports.") # Parse command line arguments refactor_stdin = False flags = {} options, args = parser.parse_args(args) if options.tobytes: raise NotImplementedError( 'the fixer for this is not yet written. ' 'Please open an issue on:\n' ' https://github.com/PythonCharmers/python-future\n' 'if you need it.') if options.from3: assert not (options.stage1 or options.stage2) fixer_pkg = 'libfuturize.fixes3' avail_fixes = libfuturize_3fix_names flags["print_function"] = True else: fixer_pkg = 'libfuturize.fixes2' avail_fixes = set() if not (options.stage1 or options.stage2): options.both_stages = True else: assert options.both_stages is None options.both_stages = False if options.stage1 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage1) avail_fixes.update(libfuturize_2fix_names_stage1) if options.stage2 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage2) avail_fixes.update(libfuturize_2fix_names_stage2) if not options.write and options.no_diffs: warn( "not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.list_fixes: print("Available transformations for the -f/--fix option:") for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # If this option were ever needed, it would probably mean the --from3 flag # had been forgotten. # if options.print_function: # flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) # Initialize the refactoring tool unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) # The 'all-imports' option forces adding all imports __future__ and "from # future import standard_library", even if they don't seem necessary for # the current state of each module. (This can simplify testing, and can # reduce the need to think about Py2 compatibility when editing the code # further.) extra_fixes = set() if options.all_imports: prefix = 'libfuturize.fixes2.' if options.stage1: extra_fixes.add(prefix + 'fix_add__future__imports_except_unicode_literals') else: # In case the user hasn't run stage1 for some reason: extra_fixes.add(prefix + 'fix_add__future__imports') extra_fixes.add(prefix + 'fix_add_future_standard_library_import') extra_fixes.add(prefix + 'fix_add_all_future_builtins') fixer_names = avail_fixes | extra_fixes - unwanted_fixes rt = StdoutRefactoringTool(sorted(fixer_names), flags, set(), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, options.doctests_only, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't " \ "supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))
def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="pasteurize [options] file|dir ...") parser.add_option("-V", "--version", action="store_true", help="Report the version number of pasteurize") parser.add_option( "-a", "--all-imports", action="store_true", help="Adds all __future__ and future imports to each module") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default: all") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") # parser.add_option("-p", "--print-function", action="store_true", # help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") # Parse command line arguments refactor_stdin = False flags = {} options, args = parser.parse_args(args) fixer_pkg = 'libpasteurize.fixes' avail_fixes = fix_names flags["print_function"] = True if not options.write and options.no_diffs: warn( "not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.version: print(__version__) return 0 if options.list_fixes: print("Available transformations for the -f/--fix option:") for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) unwanted_fixes = set() for fix in options.nofix: if ".fix_" in fix: unwanted_fixes.add(fix) else: # Infer the full module name for the fixer. # First ensure that no names clash (e.g. # lib2to3.fixes.fix_blah and libfuturize.fixes.fix_blah): found = [ f for f in avail_fixes if f.endswith('fix_{0}'.format(fix)) ] if len(found) > 1: print("Ambiguous fixer name. Choose a fully qualified " "module name instead from these:\n" + "\n".join(" " + myf for myf in found), file=sys.stderr) return 2 elif len(found) == 0: print("Unknown fixer. Use --list-fixes or -l for a list.", file=sys.stderr) return 2 unwanted_fixes.add(found[0]) extra_fixes = set() if options.all_imports: prefix = 'libpasteurize.fixes.' extra_fixes.add(prefix + 'fix_add_all__future__imports') extra_fixes.add(prefix + 'fix_add_future_standard_library_import') extra_fixes.add(prefix + 'fix_add_all_future_builtins') explicit = set() if options.fix: all_present = False for fix in options.fix: if fix == 'all': all_present = True else: if ".fix_" in fix: explicit.add(fix) else: # Infer the full module name for the fixer. # First ensure that no names clash (e.g. # lib2to3.fixes.fix_blah and libpasteurize.fixes.fix_blah): found = [ f for f in avail_fixes if f.endswith('fix_{0}'.format(fix)) ] if len(found) > 1: print("Ambiguous fixer name. Choose a fully qualified " "module name instead from these:\n" + "\n".join(" " + myf for myf in found), file=sys.stderr) return 2 elif len(found) == 0: print( "Unknown fixer. Use --list-fixes or -l for a list.", file=sys.stderr) return 2 explicit.add(found[0]) if len(explicit & unwanted_fixes) > 0: print("Conflicting usage: the following fixers have been " "simultaneously requested and disallowed:\n" + "\n".join(" " + myf for myf in (explicit & unwanted_fixes)), file=sys.stderr) return 2 requested = avail_fixes.union(explicit) if all_present else explicit else: requested = avail_fixes.union(explicit) fixer_names = requested | extra_fixes - unwanted_fixes # Initialize the refactoring tool rt = StdoutRefactoringTool(sorted(fixer_names), flags, set(), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, None, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't " \ "supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))
def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage=usage, version="modernize %s" % __version__) parser.formatter.format_usage = format_usage parser.add_option("-v", "--verbose", action="store_true", help="Show more verbose logging.") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring.") parser.add_option("-l", "--list-fixes", action="store_true", help="List standard transformations.") parser.add_option("-d", "--doctests_only", action="store_true", help="Fix up doctests only.") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; '-f default' includes default fixers.") parser.add_option("--fixers-here", action="store_true", help="Add current working directory to python path (so fixers can be found)") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently.") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-p", "--print-function", action="store_true", help="Modify the grammar so that print() is a function.") parser.add_option("-w", "--write", action="store_true", help="Write back modified files.") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") parser.add_option("--six-unicode", action="store_true", default=False, help="Wrap unicode literals in six.u().") parser.add_option("--future-unicode", action="store_true", default=False, help="Use 'from __future__ import unicode_literals'" "(only useful for Python 2.6+).") parser.add_option("--no-six", action="store_true", default=False, help="Exclude fixes that depend on the six package.") parser.add_option("--enforce", action="store_true", default=False, help="Returns non-zero exit code if any fixers had to be applied. " "Useful for enforcing Python 3 compatibility.") fixer_pkg = 'libmodernize.fixes' avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) avail_fixes.update(lib2to3_fix_names) # Parse command line arguments refactor_stdin = False flags = {} options, args = parser.parse_args(args) if not options.write and options.no_diffs: warn("Not writing files and not printing diffs; that's not very useful.") if not options.write and options.nobackups: parser.error("Can't use '-n' without '-w'.") if options.list_fixes: print("Standard transformations available for the -f/--fix and -x/--nofix options:") for fixname in sorted(avail_fixes): print(" {} ({})".format(fixname, fixname.split(".fix_", 1)[1])) print() if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 if options.print_function: flags["print_function"] = True if options.fixers_here: sys.path.append(os.getcwd()) # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) # Initialize the refactoring tool unwanted_fixes = set() splitfixes = [] for fix in options.nofix: splitfixes.extend(fix.split(',')) for fix in splitfixes: matched = None for tgt in avail_fixes: if tgt == fix or tgt.endswith(".fix_{}".format(fix)): matched = tgt unwanted_fixes.add(matched) break else: print("Error: fix '{}' was not found".format(fix), file=sys.stderr) return 2 default_fixes = avail_fixes.difference(opt_in_fix_names) # Remove unicode fixers depending on command line options if options.six_unicode: unwanted_fixes.add('libmodernize.fixes.fix_unicode_future') elif options.future_unicode: unwanted_fixes.add('libmodernize.fixes.fix_unicode') else: unwanted_fixes.add('libmodernize.fixes.fix_unicode') unwanted_fixes.add('libmodernize.fixes.fix_unicode_future') if options.no_six: unwanted_fixes.update(six_fix_names) explicit = set() if options.fix: default_present = False splitfixes = [] for fix in options.fix: splitfixes.extend(fix.split(',')) for fix in splitfixes: if fix == "default": default_present = True else: matched = None for tgt in avail_fixes: if tgt == fix or tgt.endswith(".fix_{}".format(fix)): matched = tgt explicit.add(matched) break else: # A non-standard fix -- trust user to have supplied path explicit.add(fix) requested = default_fixes.union(explicit) if default_present else explicit else: requested = default_fixes fixer_names = requested.difference(unwanted_fixes) # Filter out unwanted fixers explicit = explicit.intersection(fixer_names) # Filter `explicit` fixers vs remaining fixers print(" Loading the following fixers:", file=sys.stderr) if fixer_names: for fixname in sorted(fixer_names): print(" {} ({})".format(fixname, fixname.split(".fix_", 1)[1]), file=sys.stderr) else: print(" (None)", file=sys.stderr) print(" Applying the following explicit transformations:", file=sys.stderr) if explicit: for fixname in sorted(explicit): print(" {} ({})".format(fixname, fixname.split(".fix_", 1)[1]), file=sys.stderr) else: print(" (None)", file=sys.stderr) print(file=sys.stderr) # Refactor all files and directories passed as arguments rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs) if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, options.doctests_only, options.processes) except refactor.MultiprocessingUnsupported: # pragma: no cover assert options.processes > 1 print("Sorry, -j isn't supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return_code = int(bool(rt.errors)) # If we are enforcing python 3 compatibility, return a non-zero exit code if we had to modify # any files. if options.enforce and rt.files: return_code |= 2 return return_code
from future.builtins import * import sys import logging import optparse from lib2to3.main import main, warn, StdoutRefactoringTool from lib2to3 import refactor import future from libpasteurize.fixes import fix_names __version__ = '0.12.4' if __version__ != future.__version__: warn('The libfuturize and future packages have different versions. ' 'This may break the pasteurize script. Please ensure the versions ' 'are consistent.') def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="pasteurize [options] file|dir ...") parser.add_option("-V", "--version", action="store_true", help="Report the version number of pasteurize") parser.add_option("-a", "--all-imports", action="store_true", help="Adds all __future__ and future imports to each module")
def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="pasteurize [options] file|dir ...") parser.add_option("-V", "--version", action="store_true", help="Report the version number of pasteurize") parser.add_option("-a", "--all-imports", action="store_true", help="Adds all __future__ and future imports to each module") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default: all") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") # parser.add_option("-p", "--print-function", action="store_true", # help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") # Parse command line arguments refactor_stdin = False flags = {} options, args = parser.parse_args(args) fixer_pkg = 'libpasteurize.fixes' avail_fixes = fix_names flags["print_function"] = True if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.version: print(__version__) return 0 if options.list_fixes: print("Available transformations for the -f/--fix option:") for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) # Initialize the refactoring tool unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) extra_fixes = set() if options.all_imports: prefix = 'libpasteurize.fixes.' extra_fixes.add(prefix + 'fix_add_all__future__imports') extra_fixes.add(prefix + 'fix_add_future_standard_library_import') extra_fixes.add(prefix + 'fix_add_all_future_builtins') fixer_names = avail_fixes | extra_fixes - unwanted_fixes rt = StdoutRefactoringTool(sorted(fixer_names), flags, set(), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, None, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't " \ "supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))
def main(): """Main program.""" parser = argparse.ArgumentParser(prog='python-modernize') parser.add_argument('--version', action='version', version='%(prog)s ' + __version__) parser.add_argument('-d', '--doctests', action='store_true', help='fix up doctests') parser.add_argument('-f', '--fix', action='append', default=[], help='each FIX specifies a transformation; ' 'default: all') parser.add_argument('-j', '--processes', action='store', default=1, type=int, help='Run 2to3 concurrently') parser.add_argument('-x', '--nofix', action='append', default=[], help='prevent a fixer from being run') parser.add_argument('-l', '--list-fixes', action='store_true', help='list available transformations') parser.add_argument('-p', '--print-function', action='store_true', help='modify the grammar so that print() is a ' 'function') parser.add_argument('-v', '--verbose', action='count', default=0, help='more verbose logging') parser.add_argument('--no-diffs', action='store_true', help="don't show diffs of the refactoring") parser.add_argument('-w', '--write', action='store_true', help='write back modified files') parser.add_argument('-n', '--nobackups', action='store_true', default=False, help="don't write backups for modified files.") parser.add_argument('--future-unicode', action='store_true', default=False, help='use unicode_strings __future__ feature ' '(only useful for Python 2.6+)') parser.add_argument('files', nargs='*', help="files to fix or '-' for standard in") fixer_pkg = 'libmodernize.fixes' avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) avail_fixes.update(lib2to3_fix_names) refactor_stdin = False flags = {} args = parser.parse_args() if args.processes < 1: import multiprocessing args.processes = multiprocessing.cpu_count() if not args.write and args.no_diffs: warn( "not writing files and not printing diffs; that's not very useful") if not args.write and args.nobackups: parser.error("Can't use -n without -w") if args.list_fixes: print('Available transformations for the -f/--fix option:') for fixname in sorted(avail_fixes): print(fixname) if not args.files: return 0 if '-' in args.files: refactor_stdin = True if len(args.files) > 1: parser.error('Cannot mix stdin and regular files') if args.write: parser.error("Can't write to stdin") if args.print_function: flags['print_function'] = True if args.verbose == 0: level = logging.ERROR elif args.verbose == 1: level = logging.INFO else: level = logging.DEBUG logging.basicConfig(format='%(name)s: %(message)s', level=level) unwanted_fixes = set(args.nofix) if not args.future_unicode: unwanted_fixes.add('libmodernize.fixes.fix_unicode_future') if args.doctests: unwanted_fixes.add('libmodernize.fixes.fix_print') unwanted_fixes.add('libmodernize.fixes.fix_absolute_import_future') else: # Use fix_absolute_import_future instead. unwanted_fixes.add('lib2to3.fixes.fix_import') explicit = set() if args.fix: all_present = False for fix in args.fix: if fix == 'all': all_present = True else: explicit.add(fix) requested = avail_fixes.union(explicit) if all_present else explicit else: requested = avail_fixes.union(explicit) fixer_names = requested.difference(unwanted_fixes) rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), args.nobackups, not args.no_diffs) if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args.files, args.write, args.doctests, args.processes) except refactor.MultiprocessingUnsupported: assert args.processes > 1 parser.error("Sorry, -j isn't supported on this platform") rt.summarize() return int(bool(rt.errors))
def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage=usage, version="modernize %s" % __version__) parser.formatter.format_usage = format_usage parser.add_option("-v", "--verbose", action="store_true", help="Show more verbose logging.") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations.") parser.add_option("-d", "--doctests_only", action="store_true", help="Fix up doctests only.") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; '-f default' includes default fixers.") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently.") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-p", "--print-function", action="store_true", help="Modify the grammar so that print() is a function.") parser.add_option("-w", "--write", action="store_true", help="Write back modified files.") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") parser.add_option("--six-unicode", action="store_true", default=False, help="Wrap unicode literals in six.u().") parser.add_option("--future-unicode", action="store_true", default=False, help="Use 'from __future__ import unicode_literals'" "(only useful for Python 2.6+).") parser.add_option("--no-six", action="store_true", default=False, help="Exclude fixes that depend on the six package.") parser.add_option("--enforce", action="store_true", default=False, help="Returns non-zero exit code of any fixers had to be applied. " "Useful for enforcing Python 3 compatibility.") fixer_pkg = 'libmodernize.fixes' avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) avail_fixes.update(lib2to3_fix_names) # Parse command line arguments refactor_stdin = False flags = {} options, args = parser.parse_args(args) if not options.write and options.no_diffs: warn("Not writing files and not printing diffs; that's not very useful.") if not options.write and options.nobackups: parser.error("Can't use '-n' without '-w'.") if options.list_fixes: print("Available transformations for the -f/--fix option:") for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 if options.print_function: flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) # Initialize the refactoring tool unwanted_fixes = set(options.nofix) default_fixes = avail_fixes.difference(opt_in_fix_names) # Remove unicode fixers depending on command line options if options.six_unicode: unwanted_fixes.add('libmodernize.fixes.fix_unicode_future') elif options.future_unicode: unwanted_fixes.add('libmodernize.fixes.fix_unicode') else: unwanted_fixes.add('libmodernize.fixes.fix_unicode') unwanted_fixes.add('libmodernize.fixes.fix_unicode_future') if options.no_six: unwanted_fixes.update(six_fix_names) explicit = set() if options.fix: default_present = False for fix in options.fix: if fix == "default": default_present = True else: explicit.add(fix) requested = default_fixes.union(explicit) if default_present else explicit else: requested = default_fixes fixer_names = requested.difference(unwanted_fixes) rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, options.doctests_only, options.processes) except refactor.MultiprocessingUnsupported: # pragma: no cover assert options.processes > 1 print("Sorry, -j isn't supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return_code = int(bool(rt.errors)) # If we are enforcing python 3 compatibility, return a non-zero exit code if we had to modify # any files. if options.enforce and rt.files: return_code |= 2 return return_code
def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage='modernize [options] file|dir ...', version='%prog {0}'.format(__version__)) parser.add_option('-d', '--doctests-only', '--doctests_only', action='store_true', help='Fix up doctests only') parser.add_option('-f', '--fix', action='append', default=[], help='Each FIX specifies a transformation; default: all') parser.add_option('-j', '--processes', action='store', default=1, type='int', help='Run 2to3 concurrently') parser.add_option('-x', '--nofix', action='append', default=[], help='Prevent a fixer from being run.') parser.add_option('-l', '--list-fixes', action='store_true', help='List available transformations') parser.add_option('-p', '--print-function', action='store_true', help='Modify the grammar so that print() is a function') parser.add_option('-v', '--verbose', action='store_true', help='More verbose logging') parser.add_option('--no-diffs', action='store_true', help="Don't show diffs of the refactoring") parser.add_option('-w', '--write', action='store_true', help='Write back modified files') parser.add_option('-n', '--nobackups', action='store_true', default=False, help="Don't write backups for modified files.") parser.add_option('--compat-unicode', action='store_true', default=False, help="Leave u'' and b'' prefixes unchanged (requires " 'Python 3.3 and higher).') parser.add_option('--future-unicode', action='store_true', default=False, help='Use unicode_strings future_feature instead of the ' 'six.u function ' '(only useful for Python 2.6+).') parser.add_option('--six', action='store_true', default=False, help='Include fixes that depend on the six package') fixer_pkg = 'libmodernize.fixes' avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) avail_fixes.update(lib2to3_fix_names) # Parse command line arguments refactor_stdin = False flags = {} options, args = parser.parse_args(args) if not options.write and options.no_diffs: warn( "not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.list_fixes: print('Available transformations for the -f/--fix option:') for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print('At least one file or directory argument required.', file=sys.stderr) print('Use --help to show usage.', file=sys.stderr) return 2 if '-' in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 if options.print_function: flags['print_function'] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) # Initialize the refactoring tool unwanted_fixes = set(options.nofix) # Remove unicode fixers depending on command line options if options.compat_unicode: unwanted_fixes.add('libmodernize.fixes.fix_unicode') unwanted_fixes.add('libmodernize.fixes.fix_unicode_future') elif options.future_unicode: unwanted_fixes.add('libmodernize.fixes.fix_unicode') else: unwanted_fixes.add('libmodernize.fixes.fix_unicode_future') if options.doctests_only: unwanted_fixes.add('libmodernize.fixes.fix_print') if not options.six: unwanted_fixes.update(six_fix_names) explicit = set() if options.fix: all_present = False for fix in options.fix: if fix == 'all': all_present = True else: explicit.add(fix) requested = avail_fixes.union(explicit) if all_present else explicit else: requested = avail_fixes.union(explicit) fixer_names = requested.difference(unwanted_fixes) rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, options.doctests_only, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't " 'supported on this platform.', file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))
def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="pasteurize [options] file|dir ...") parser.add_option("-V", "--version", action="store_true", help="Report the version number of pasteurize") parser.add_option("-a", "--all-imports", action="store_true", help="Adds all __future__ and future imports to each module") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default: all") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") # parser.add_option("-p", "--print-function", action="store_true", # help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") # Parse command line arguments refactor_stdin = False flags = {} options, args = parser.parse_args(args) fixer_pkg = 'libpasteurize.fixes' avail_fixes = fix_names flags["print_function"] = True if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.version: print(__version__) return 0 if options.list_fixes: print("Available transformations for the -f/--fix option:") for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) unwanted_fixes = set() for fix in options.nofix: if ".fix_" in fix: unwanted_fixes.add(fix) else: # Infer the full module name for the fixer. # First ensure that no names clash (e.g. # lib2to3.fixes.fix_blah and libfuturize.fixes.fix_blah): found = [f for f in avail_fixes if f.endswith('fix_{0}'.format(fix))] if len(found) > 1: print("Ambiguous fixer name. Choose a fully qualified " "module name instead from these:\n" + "\n".join(" " + myf for myf in found), file=sys.stderr) return 2 elif len(found) == 0: print("Unknown fixer. Use --list-fixes or -l for a list.", file=sys.stderr) return 2 unwanted_fixes.add(found[0]) extra_fixes = set() if options.all_imports: prefix = 'libpasteurize.fixes.' extra_fixes.add(prefix + 'fix_add_all__future__imports') extra_fixes.add(prefix + 'fix_add_future_standard_library_import') extra_fixes.add(prefix + 'fix_add_all_future_builtins') explicit = set() if options.fix: all_present = False for fix in options.fix: if fix == 'all': all_present = True else: if ".fix_" in fix: explicit.add(fix) else: # Infer the full module name for the fixer. # First ensure that no names clash (e.g. # lib2to3.fixes.fix_blah and libpasteurize.fixes.fix_blah): found = [f for f in avail_fixes if f.endswith('fix_{0}'.format(fix))] if len(found) > 1: print("Ambiguous fixer name. Choose a fully qualified " "module name instead from these:\n" + "\n".join(" " + myf for myf in found), file=sys.stderr) return 2 elif len(found) == 0: print("Unknown fixer. Use --list-fixes or -l for a list.", file=sys.stderr) return 2 explicit.add(found[0]) if len(explicit & unwanted_fixes) > 0: print("Conflicting usage: the following fixers have been " "simultaneously requested and disallowed:\n" + "\n".join(" " + myf for myf in (explicit & unwanted_fixes)), file=sys.stderr) return 2 requested = avail_fixes.union(explicit) if all_present else explicit else: requested = avail_fixes.union(explicit) fixer_names = requested | extra_fixes - unwanted_fixes # Initialize the refactoring tool rt = StdoutRefactoringTool(sorted(fixer_names), flags, set(), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, None, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't " \ "supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))
def _main(args=None): # Set up option parser parser = optparse.OptionParser(usage="doc484 [options] file|dir ...", description=__doc__, version="doc484 {}".format(__version__)) parser.add_option("-f", "--format", choices=sorted(doc484.formats.format_map.keys()), help="Specify the docstring convention used within " "files to be converted (by default this is " "automatically determined by inspecting each docstring " "but it is faster and more reliable to specify this " "explicitly)") parser.add_option("--default-return-type", default='Any', help="Default type to use for undocumented return " "values (defaults to 'Any'") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Number of concurrent processes to use" "for conversion (using more than the number of physical" "cores is usually beneficial)") # parser.add_option("-f", "--fix", action="append", default=[], # help="Each FIX specifies a transformation; default: all") # parser.add_option("-x", "--nofix", action="append", default=[], # help="Prevent a transformation from being run") # parser.add_option("-l", "--list-fixes", action="store_true", default=False, # help="List available transformations") parser.add_option("-v", "--verbose", action="store_true", default=False, help="More verbose logging") parser.add_option("--show-diffs", action="store_true", default=False, help="Show diffs of the refactoring when writing. " "(always true when --write is not present)") parser.add_option("-w", "--write", action="store_true", default=False, help="Write back modified files") parser.add_option( "-c", "--config", action="store", type="str", default=None, help="Read settings from the specified " "ini-style configuration file (defaults to `./setup.cfg'") parser.add_option("-o", "--output-dir", action="store", type="str", default="", help="Put output files in this directory " "instead of overwriting the input files. Requires -n.") parser.add_option("-W", "--write-unchanged-files", action="store_true", default=False, help="Also write files even if no changes were required" " (useful with --output-dir); implies -w.") # Parse command line arguments refactor_stdin = False flags = {} # pass in `values` to prevent defaults from being populated, so that # values read from the config file can take precedence over defaults. # order of precedence: specified options > config options > parser defaults options, args = parser.parse_args(args, values=optparse.Values({})) default_arg_types = apply_config(_get_options_data(parser), options, path=getattr(options, 'config', None)) doc484.formats.default_arg_types.update(default_arg_types) doc484.formats.default_return_type = options.default_return_type # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(message)s', level=level) logger = logging.getLogger('doc484.main') # logging.getLogger("RefactoringTool").setLevel(level) if options.format: logger.info("Using %r format" % options.format) doc484.formats.set_default_format(options.format) if options.write_unchanged_files: flags["write_unchanged_files"] = True if not options.write: warn("--write-unchanged-files/-W implies -w.") options.write = True show_diffs = not options.write or options.show_diffs # if options.list_fixes: # print("Available transformations for the -f/--fix option:") # for fixname in refactor.get_all_fix_names(fixer_pkg): # print(fixname) # if not args: # return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # NOTE: removing this until we have more fixes # Initialize the refactoring tool # avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) # unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) explicit = set() # if options.fix: # all_present = False # for fix in options.fix: # if fix == "all": # all_present = True # else: # explicit.add(fixer_pkg + ".fix_" + fix) # requested = avail_fixes.union(explicit) if all_present else explicit # else: # requested = avail_fixes.union(explicit) # fixer_names = requested.difference(unwanted_fixes) fixer_names = {'doc484.fixes.fix_type_comments'} input_base_dir = os.path.commonprefix(args) if (input_base_dir and not input_base_dir.endswith(os.sep) and not os.path.isdir(input_base_dir)): # One or more similar names were passed, their directory is the base. # os.path.commonprefix() is ignorant of path elements, this corrects # for that weird API. input_base_dir = os.path.dirname(input_base_dir) if options.output_dir: input_base_dir = input_base_dir.rstrip(os.sep) logger.info('Output in %r will mirror the input directory %r layout.', options.output_dir, input_base_dir) rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), nobackups=True, show_diffs=show_diffs, input_base_dir=input_base_dir, output_dir=options.output_dir) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, num_processes=options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't supported on this platform.", file=sys.stderr) return 1 rt.summarize() return rt.errors
def main(args=None): """Main program. Args: fixer_pkg: the name of a package where the fixers are located. args: optional; a list of command line arguments. If omitted, sys.argv[1:] is used. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="futurize [options] file|dir ...") parser.add_option("-a", "--all-imports", action="store_true", help="Adds all __future__ and future imports to each module") parser.add_option("-d", "--doctests_only", action="store_true", help="Fix up doctests only") parser.add_option("-1", "--stage1", action="store_true", help="Modernize Python 2 code only; no compatibility with Python 3 (or dependency on ``future``)") parser.add_option("-2", "--stage2", action="store_true", help="Take modernized (stage1) code and add a dependency on ``future`` to provide Py3 compatibility.") parser.add_option("-0", "--both-stages", action="store_true", help="Apply both stages 1 and 2") parser.add_option("-u", "--unicode-literals", action="store_true", help="Add ``from __future__ import unicode_literals`` to implicitly convert all unadorned string literals '' into unicode strings") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default: all.\nEither use '-f division -f metaclass' etc. or use the fully-qualified module name: '-f lib2to3.fixes.fix_types -f libfuturize.fixes.fix_unicode_keep_u'") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") parser.add_option("-p", "--print-function", action="store_true", help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") parser.add_option("-o", "--output-dir", action="store", type="str", default="", help="Put output files in this directory " "instead of overwriting the input files. Requires -n. " "For Python >= 2.7 only.") parser.add_option("-W", "--write-unchanged-files", action="store_true", help="Also write files even if no changes were required" " (useful with --output-dir); implies -w.") parser.add_option("--add-suffix", action="store", type="str", default="", help="Append this string to all output filenames." " Requires -n if non-empty. For Python >= 2.7 only." "ex: --add-suffix='3' will generate .py3 files.") avail_fixes = set() # Parse command line arguments refactor_stdin = False options, args = parser.parse_args(args) if options.write_unchanged_files: flags["write_unchanged_files"] = True if not options.write: warn("--write-unchanged-files/-W implies -w.") options.write = True # If we allowed these, the original files would be renamed to backup names # but not replaced. if options.output_dir and not options.nobackups: parser.error("Can't use --output-dir/-o without -n.") if options.add_suffix and not options.nobackups: parser.error("Can't use --add-suffix without -n.") if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # Is this ever necessary? if options.print_function: flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) if options.stage1 or options.stage2: assert options.both_stages is None options.both_stages = False else: options.both_stages = True if options.stage1 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage1) avail_fixes.update(libfuturize_fix_names_stage1) if options.stage2 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage2) avail_fixes.update(libfuturize_fix_names_stage2) if options.unicode_literals: avail_fixes.add('libfuturize.fixes.fix_unicode_literals_import') if options.list_fixes: print("Available transformations for the -f/--fix option:") # for fixname in sorted(refactor.get_all_fix_names(fixer_pkg)): for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 flags = {} unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) # The 'all-imports' option forces adding all __future__ imports and "from # future import standard_library", even if they don't seem necessary for # the current state of each module. (This can simplify testing, and can # reduce the need to think about Py2 compatibility when editing the code # further.) extra_fixes = set() if options.all_imports: prefix = 'libfuturize.fixes.' if options.stage1: extra_fixes.add(prefix + 'fix_add__future__imports_except_unicode_literals') else: # In case the user hasn't run stage1 for some reason: extra_fixes.add(prefix + 'fix_add__future__imports') extra_fixes.add(prefix + 'fix_add_future_standard_library_import') extra_fixes.add(prefix + 'fix_add_all_future_builtins') explicit = set() if options.fix: all_present = False for fix in options.fix: if fix == 'all': all_present = True else: if ".fix_" in fix: explicit.add(fix) else: # Infer the full module name for the fixer. # First ensure that no names clash (e.g. # lib2to3.fixes.fix_blah and libfuturize.fixes.fix_blah): found = [f for f in avail_fixes if 'fix_{}'.format(fix) in f] if len(found) > 1: print("Ambiguous fixer name. Choose a fully qualified " "module name instead from these:\n" + "\n".join(" " + myf for myf in found), file=sys.stderr) return 2 elif len(found) == 0: print("Unknown fixer. Use --list-fixes or -l for a list.", file=sys.stderr) return 2 explicit.add(found[0]) requested = avail_fixes.union(explicit) if all_present else explicit else: requested = avail_fixes.union(explicit) fixer_names = requested | extra_fixes - unwanted_fixes input_base_dir = os.path.commonprefix(args) if (input_base_dir and not input_base_dir.endswith(os.sep) and not os.path.isdir(input_base_dir)): # One or more similar names were passed, their directory is the base. # os.path.commonprefix() is ignorant of path elements, this corrects # for that weird API. input_base_dir = os.path.dirname(input_base_dir) if options.output_dir: input_base_dir = input_base_dir.rstrip(os.sep) logger.info('Output in %r will mirror the input directory %r layout.', options.output_dir, input_base_dir) # Initialize the refactoring tool if utils.PY26: extra_kwargs = {} else: extra_kwargs = { 'append_suffix': options.add_suffix, 'output_dir': options.output_dir, 'input_base_dir': input_base_dir, } rt = StdoutRefactoringTool( sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs, **extra_kwargs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, options.doctests_only, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't " \ "supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))
def main(args=None): """Main program. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="futurize [options] file|dir ...") parser.add_option("-a", "--all-imports", action="store_true", help="Adds all __future__ and future imports to each module") parser.add_option("-d", "--doctests_only", action="store_true", help="Fix up doctests only") parser.add_option("-b", "--tobytes", action="store_true", help="Convert all unadorned string literals to bytes objects") parser.add_option("-1", "--stage1", action="store_true", help="Modernize Python 2 code only; no compatibility with Python 3 (or dependency on ``future``)") parser.add_option("-2", "--stage2", action="store_true", help="Take modernized (stage1) code and add a dependency on ``future`` to provide Py3 compatibility.") parser.add_option("-0", "--both-stages", action="store_true", help="Apply both stages 1 and 2") # parser.add_option("-f", "--fix", action="append", default=[], # help="Each FIX specifies a transformation; default: all") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") # parser.add_option("-p", "--print-function", action="store_true", # help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") parser.add_option("--from3", action="store_true", default=False, help="Assume the code is already Python 3 and just " "requires ``__future__`` and ``future`` imports.") # Parse command line arguments refactor_stdin = False flags = {} options, args = parser.parse_args(args) if options.from3: assert not (options.stage1 or options.stage2) assert not options.tobytes fixer_pkg = 'libfuturize.fixes3' avail_fixes = libfuturize_3fix_names flags["print_function"] = True else: fixer_pkg = 'libfuturize.fixes2' avail_fixes = set() if not (options.stage1 or options.stage2): options.both_stages = True else: assert options.both_stages is None options.both_stages = False if options.stage1 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage1) avail_fixes.update(libfuturize_2fix_names_stage1) if options.stage2 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage2) avail_fixes.update(libfuturize_2fix_names_stage2) if options.tobytes: avail_fixes.add('libfuturize.fixes2.fix_bytes') if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if options.list_fixes: print("Available transformations for the -f/--fix option:") for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # If this option were ever needed, it would probably mean the --from3 flag # had been forgotten. # if options.print_function: # flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) # Initialize the refactoring tool unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) # The 'all-imports' option forces adding all imports __future__ and "from # future import standard_library", even if they don't seem necessary for # the current state of each module. (This can simplify testing, and can # reduce the need to think about Py2 compatibility when editing the code # further.) extra_fixes = set() if options.all_imports: prefix = 'libfuturize.fixes2.' if options.stage1: extra_fixes.add(prefix + 'fix_add__future__imports_except_unicode_literals') else: # In case the user hasn't run stage1 for some reason: extra_fixes.add(prefix + 'fix_add__future__imports') extra_fixes.add(prefix + 'fix_add_future_standard_library_import') extra_fixes.add(prefix + 'fix_add_all_future_builtins') fixer_names = avail_fixes | extra_fixes - unwanted_fixes rt = StdoutRefactoringTool(sorted(fixer_names), flags, set(), options.nobackups, not options.no_diffs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, options.doctests_only, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't " \ "supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))
def main(args=None): """Main program. Args: fixer_pkg: the name of a package where the fixers are located. args: optional; a list of command line arguments. If omitted, sys.argv[1:] is used. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="futurize [options] file|dir ...") parser.add_option( "-V", "--version", action="store_true", help="Report the version number of futurize", ) parser.add_option( "-a", "--all-imports", action="store_true", help="Add all __future__ and future imports to each module", ) parser.add_option( "-1", "--stage1", action="store_true", help= "Modernize Python 2 code only; no compatibility with Python 3 (or dependency on ``future``)", ) parser.add_option( "-2", "--stage2", action="store_true", help= "Take modernized (stage1) code and add a dependency on ``future`` to provide Py3 compatibility.", ) parser.add_option("-0", "--both-stages", action="store_true", help="Apply both stages 1 and 2") parser.add_option( "-u", "--unicode-literals", action="store_true", help= "Add ``from __future__ import unicode_literals`` to implicitly convert all unadorned string literals '' into unicode strings", ) parser.add_option( "-f", "--fix", action="append", default=[], help= "Each FIX specifies a transformation; default: all.\nEither use '-f division -f metaclass' etc. or use the fully-qualified module name: '-f lib2to3.fixes.fix_types -f libfuturize.fixes.fix_unicode_keep_u'", ) parser.add_option( "-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently", ) parser.add_option( "-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.", ) parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") parser.add_option( "-p", "--print-function", action="store_true", help="Modify the grammar so that print() is a function", ) parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option( "-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.", ) parser.add_option( "-o", "--output-dir", action="store", type="str", default="", help="Put output files in this directory " "instead of overwriting the input files. Requires -n. " "For Python >= 2.7 only.", ) parser.add_option( "-W", "--write-unchanged-files", action="store_true", help="Also write files even if no changes were required" " (useful with --output-dir); implies -w.", ) parser.add_option( "--add-suffix", action="store", type="str", default="", help="Append this string to all output filenames." " Requires -n if non-empty. For Python >= 2.7 only." "ex: --add-suffix='3' will generate .py3 files.", ) # Parse command line arguments flags = {} refactor_stdin = False options, args = parser.parse_args(args) if options.write_unchanged_files: flags["write_unchanged_files"] = True if not options.write: warn("--write-unchanged-files/-W implies -w.") options.write = True # If we allowed these, the original files would be renamed to backup names # but not replaced. if options.output_dir and not options.nobackups: parser.error("Can't use --output-dir/-o without -n.") if options.add_suffix and not options.nobackups: parser.error("Can't use --add-suffix without -n.") if not options.write and options.no_diffs: warn( "not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # Is this ever necessary? if options.print_function: flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format="%(name)s: %(message)s", level=level) logger = logging.getLogger("libfuturize.main") if options.stage1 or options.stage2: assert options.both_stages is None options.both_stages = False else: options.both_stages = True avail_fixes = set() if options.stage1 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage1) avail_fixes.update(libfuturize_fix_names_stage1) if options.stage2 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage2) avail_fixes.update(libfuturize_fix_names_stage2) if options.unicode_literals: avail_fixes.add("libfuturize.fixes.fix_unicode_literals_import") if options.version: print(__version__) return 0 if options.list_fixes: print("Available transformations for the -f/--fix option:") # for fixname in sorted(refactor.get_all_fix_names(fixer_pkg)): for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 unwanted_fixes = set() for fix in options.nofix: if ".fix_" in fix: unwanted_fixes.add(fix) else: # Infer the full module name for the fixer. # First ensure that no names clash (e.g. # lib2to3.fixes.fix_blah and libfuturize.fixes.fix_blah): found = [ f for f in avail_fixes if f.endswith("fix_{0}".format(fix)) ] if len(found) > 1: print( "Ambiguous fixer name. Choose a fully qualified " "module name instead from these:\n" + "\n".join(" " + myf for myf in found), file=sys.stderr, ) return 2 elif len(found) == 0: print("Unknown fixer. Use --list-fixes or -l for a list.", file=sys.stderr) return 2 unwanted_fixes.add(found[0]) extra_fixes = set() if options.all_imports: if options.stage1: prefix = "libfuturize.fixes." extra_fixes.add(prefix + "fix_add__future__imports_except_unicode_literals") else: # In case the user hasn't run stage1 for some reason: prefix = "libpasteurize.fixes." extra_fixes.add(prefix + "fix_add_all__future__imports") extra_fixes.add(prefix + "fix_add_future_standard_library_import") extra_fixes.add(prefix + "fix_add_all_future_builtins") explicit = set() if options.fix: all_present = False for fix in options.fix: if fix == "all": all_present = True else: if ".fix_" in fix: explicit.add(fix) else: # Infer the full module name for the fixer. # First ensure that no names clash (e.g. # lib2to3.fixes.fix_blah and libfuturize.fixes.fix_blah): found = [ f for f in avail_fixes if f.endswith("fix_{0}".format(fix)) ] if len(found) > 1: print( "Ambiguous fixer name. Choose a fully qualified " "module name instead from these:\n" + "\n".join(" " + myf for myf in found), file=sys.stderr, ) return 2 elif len(found) == 0: print( "Unknown fixer. Use --list-fixes or -l for a list.", file=sys.stderr, ) return 2 explicit.add(found[0]) if len(explicit & unwanted_fixes) > 0: print( "Conflicting usage: the following fixers have been " "simultaneously requested and disallowed:\n" + "\n".join(" " + myf for myf in (explicit & unwanted_fixes)), file=sys.stderr, ) return 2 requested = avail_fixes.union(explicit) if all_present else explicit else: requested = avail_fixes.union(explicit) fixer_names = (requested | extra_fixes) - unwanted_fixes input_base_dir = os.path.commonprefix(args) if (input_base_dir and not input_base_dir.endswith(os.sep) and not os.path.isdir(input_base_dir)): # One or more similar names were passed, their directory is the base. # os.path.commonprefix() is ignorant of path elements, this corrects # for that weird API. input_base_dir = os.path.dirname(input_base_dir) if options.output_dir: input_base_dir = input_base_dir.rstrip(os.sep) logger.info( "Output in %r will mirror the input directory %r layout.", options.output_dir, input_base_dir, ) # Initialize the refactoring tool if future.utils.PY26: extra_kwargs = {} else: extra_kwargs = { "append_suffix": options.add_suffix, "output_dir": options.output_dir, "input_base_dir": input_base_dir, } rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs, **extra_kwargs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, None, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't " "supported on this platform.", file=sys.stderr) return 1 rt.summarize() # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))
def futurize_code(args=None): """Main program. Args: fixer_pkg: the name of a package where the fixers are located. args: optional; a list of command line arguments. If omitted, sys.argv[1:] is used. Returns a suggested exit status (0, 1, 2). """ # Set up option parser parser = optparse.OptionParser(usage="futurize [options] file|dir ...") parser.add_option("-V", "--version", action="store_true", help="Report the version number of futurize") parser.add_option("-a", "--all-imports", action="store_true", help="Add all __future__ and future imports to each module") parser.add_option("-1", "--stage1", action="store_true", help="Modernize Python 2 code only; no compatibility with Python 3 (or dependency on ``future``)") parser.add_option("-2", "--stage2", action="store_true", help="Take modernized (stage1) code and add a dependency on ``future`` to provide Py3 compatibility.") parser.add_option("-0", "--both-stages", action="store_true", help="Apply both stages 1 and 2") parser.add_option("-u", "--unicode-literals", action="store_true", help="Add ``from __future__ import unicode_literals`` to implicitly convert all unadorned string literals '' into unicode strings") parser.add_option("-f", "--fix", action="append", default=[], help="Each FIX specifies a transformation; default: all.\nEither use '-f division -f metaclass' etc. or use the fully-qualified module name: '-f lib2to3.fixes.fix_types -f libfuturize.fixes.fix_unicode_keep_u'") parser.add_option("-j", "--processes", action="store", default=1, type="int", help="Run 2to3 concurrently") parser.add_option("-x", "--nofix", action="append", default=[], help="Prevent a fixer from being run.") parser.add_option("-l", "--list-fixes", action="store_true", help="List available transformations") parser.add_option("-p", "--print-function", action="store_true", help="Modify the grammar so that print() is a function") parser.add_option("-v", "--verbose", action="store_true", help="More verbose logging") parser.add_option("--no-diffs", action="store_true", help="Don't show diffs of the refactoring") parser.add_option("-w", "--write", action="store_true", help="Write back modified files") parser.add_option("-n", "--nobackups", action="store_true", default=False, help="Don't write backups for modified files.") parser.add_option("-o", "--output-dir", action="store", type="str", default="", help="Put output files in this directory " "instead of overwriting the input files. Requires -n. " "For Python >= 2.7 only.") parser.add_option("-W", "--write-unchanged-files", action="store_true", help="Also write files even if no changes were required" " (useful with --output-dir); implies -w.") parser.add_option("--add-suffix", action="store", type="str", default="", help="Append this string to all output filenames." " Requires -n if non-empty. For Python >= 2.7 only." "ex: --add-suffix='3' will generate .py3 files.") # Parse command line arguments flags = {} refactor_stdin = False options, args = parser.parse_args(args) if options.write_unchanged_files: flags["write_unchanged_files"] = True if not options.write: warn("--write-unchanged-files/-W implies -w.") options.write = True # If we allowed these, the original files would be renamed to backup names # but not replaced. if options.output_dir and not options.nobackups: parser.error("Can't use --output-dir/-o without -n.") if options.add_suffix and not options.nobackups: parser.error("Can't use --add-suffix without -n.") if not options.write and options.no_diffs: warn("not writing files and not printing diffs; that's not very useful") if not options.write and options.nobackups: parser.error("Can't use -n without -w") if "-" in args: refactor_stdin = True if options.write: print("Can't write to stdin.", file=sys.stderr) return 2 # Is this ever necessary? if options.print_function: flags["print_function"] = True # Set up logging handler level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(name)s: %(message)s', level=level) logger = logging.getLogger('libfuturize.main') if options.stage1 or options.stage2: assert options.both_stages is None options.both_stages = False else: options.both_stages = True avail_fixes = set() if options.stage1 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage1) avail_fixes.update(libfuturize_fix_names_stage1) if options.stage2 or options.both_stages: avail_fixes.update(lib2to3_fix_names_stage2) avail_fixes.update(libfuturize_fix_names_stage2) if options.unicode_literals: avail_fixes.add('libfuturize.fixes.fix_unicode_literals_import') if options.version: print(__version__) return 0 if options.list_fixes: print("Available transformations for the -f/--fix option:") # for fixname in sorted(refactor.get_all_fix_names(fixer_pkg)): for fixname in sorted(avail_fixes): print(fixname) if not args: return 0 if not args: print("At least one file or directory argument required.", file=sys.stderr) print("Use --help to show usage.", file=sys.stderr) return 2 unwanted_fixes = set() for fix in options.nofix: if ".fix_" in fix: unwanted_fixes.add(fix) else: # Infer the full module name for the fixer. # First ensure that no names clash (e.g. # lib2to3.fixes.fix_blah and libfuturize.fixes.fix_blah): found = [f for f in avail_fixes if f.endswith('fix_{0}'.format(fix))] if len(found) > 1: print("Ambiguous fixer name. Choose a fully qualified " "module name instead from these:\n" + "\n".join(" " + myf for myf in found), file=sys.stderr) return 2 elif len(found) == 0: print("Unknown fixer. Use --list-fixes or -l for a list.", file=sys.stderr) return 2 unwanted_fixes.add(found[0]) extra_fixes = set() if options.all_imports: if options.stage1: prefix = 'libfuturize.fixes.' extra_fixes.add(prefix + 'fix_add__future__imports_except_unicode_literals') else: # In case the user hasn't run stage1 for some reason: prefix = 'libpasteurize.fixes.' extra_fixes.add(prefix + 'fix_add_all__future__imports') extra_fixes.add(prefix + 'fix_add_future_standard_library_import') extra_fixes.add(prefix + 'fix_add_all_future_builtins') explicit = set() if options.fix: all_present = False for fix in options.fix: if fix == 'all': all_present = True else: if ".fix_" in fix: explicit.add(fix) else: # Infer the full module name for the fixer. # First ensure that no names clash (e.g. # lib2to3.fixes.fix_blah and libfuturize.fixes.fix_blah): found = [f for f in avail_fixes if f.endswith('fix_{0}'.format(fix))] if len(found) > 1: print("Ambiguous fixer name. Choose a fully qualified " "module name instead from these:\n" + "\n".join(" " + myf for myf in found), file=sys.stderr) return 2 elif len(found) == 0: print("Unknown fixer. Use --list-fixes or -l for a list.", file=sys.stderr) return 2 explicit.add(found[0]) if len(explicit & unwanted_fixes) > 0: print("Conflicting usage: the following fixers have been " "simultaneously requested and disallowed:\n" + "\n".join(" " + myf for myf in (explicit & unwanted_fixes)), file=sys.stderr) return 2 requested = avail_fixes.union(explicit) if all_present else explicit else: requested = avail_fixes.union(explicit) fixer_names = (requested | extra_fixes) - unwanted_fixes input_base_dir = os.path.commonprefix(args) if (input_base_dir and not input_base_dir.endswith(os.sep) and not os.path.isdir(input_base_dir)): # One or more similar names were passed, their directory is the base. # os.path.commonprefix() is ignorant of path elements, this corrects # for that weird API. input_base_dir = os.path.dirname(input_base_dir) # if options.output_dir: # input_base_dir = input_base_dir.rstrip(os.sep) # logger.info('Output in %r will mirror the input directory %r layout.', # options.output_dir, input_base_dir) # Initialize the refactoring tool if future.utils.PY26: extra_kwargs = {} else: extra_kwargs = { 'append_suffix': options.add_suffix, 'output_dir': options.output_dir, 'input_base_dir': input_base_dir, } # Remove results directory. if os.path.isdir(RESULTS_DIR): shutil.rmtree(RESULTS_DIR) os.mkdir(RESULTS_DIR) if os.path.isdir(DIFF_DIR): shutil.rmtree(DIFF_DIR) os.mkdir(DIFF_DIR) # We override their RefactoringTool with `FileRefactoringTool` rt = FileRefactoringTool( sorted(fixer_names), flags, sorted(explicit), options.nobackups, not options.no_diffs, **extra_kwargs) # Refactor all files and directories passed as arguments if not rt.errors: if refactor_stdin: rt.refactor_stdin() else: try: rt.refactor(args, options.write, None, options.processes) except refactor.MultiprocessingUnsupported: assert options.processes > 1 print("Sorry, -j isn't supported on this platform.", file=sys.stderr) return 1 rt.summarize() # This is our own custom html reporting. table_body = tbody() remove_line_count_total = 0 with table_body: for file_name, file_summary in DiffSummary.list_all(): with tr(): td(a(file_name, href=file_summary.href)) td(file_summary.add_line_count, style="text-align:right") td(file_summary.remove_line_count, style="text-align:right") td(file_summary.percent_coverage, style="text-align:right") remove_line_count_total += file_summary.remove_line_count with document(title='2/3 Summary') as doc: h1('2/3 Summary', style='padding: 0 40px;') p('Total lines that need to be removed:', style='padding: 0 40px;').add(b(remove_line_count_total)) summary_table = table(width='100%', style="padding: 20px 40px; margin: 0 auto;") with summary_table.add(thead()): with tr(): th('File Name', style="text-align:left") th('Add Lines', style="text-align:right") th('Remove Lines', style="text-align:right") th('Coverage %', style="text-align:right") summary_table.add(table_body) with open('{results_dir}/summary.html'.format(results_dir=RESULTS_DIR), 'w+') as summary_file: summary_file.write(doc.render()) # Write a machine readable report that can be parsed later. json_report = { 'summary': { 'remove_line_count_total': remove_line_count_total }, 'files': [ { 'file_name': file_name, 'add_line_count': file_summary.add_line_count, 'remove_line_count': file_summary.remove_line_count, 'percent_coverage': file_summary.percent_coverage, } for file_name, file_summary in DiffSummary.list_all() ] } json.dump(json_report, open('{results_dir}/report.json'.format(results_dir=RESULTS_DIR), 'w+')) # Return error status (0 if rt.errors is zero) return int(bool(rt.errors))