def test_fixers_importable(): fixers = refactor.get_fixers_from_package(MODERNIZE_FIXES_PKG) for module_name in fixers: try: __import__(module_name) except ImportError: raise AssertionError(f"{module_name!r} cannot be imported")
def test_fixer_loading_helpers(self): contents = ["explicit", "first", "last", "parrot", "preorder"] non_prefixed = refactor.get_all_fix_names("myfixes") prefixed = refactor.get_all_fix_names("myfixes", False) full_names = refactor.get_fixers_from_package("myfixes") self.assertEqual(prefixed, ["fix_" + name for name in contents]) self.assertEqual(non_prefixed, contents) self.assertEqual(full_names, ["myfixes.fix_" + name for name in contents])
def test_crlf_newlines(self): old_sep = os.linesep os.linesep = "\r\n" try: fn = os.path.join(TEST_DATA_DIR, "crlf.py") fixes = refactor.get_fixers_from_package("fissix.fixes") self.check_file_refactoring(fn, fixes) finally: os.linesep = old_sep
def get_refactorer(fixer_pkg="fissix", fixers=None, options=None): """ A convenience function for creating a RefactoringTool for tests. fixers is a list of fixers for the RefactoringTool to use. By default "fissix.fixes.*" is used. options is an optional dictionary of options to be passed to the RefactoringTool. """ if fixers is not None: fixers = [fixer_pkg + ".fixes.fix_" + fix for fix in fixers] else: fixers = refactor.get_fixers_from_package(fixer_pkg + ".fixes") options = options or {} return refactor.RefactoringTool(fixers, options, explicit=True)
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(fissix_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
import codecs import io import re import tempfile import shutil import unittest from fissix import refactor, pygram, fixer_base from fissix.pgen2 import token TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data") FIXER_DIR = os.path.join(TEST_DATA_DIR, "fixers") sys.path.append(FIXER_DIR) try: _DEFAULT_FIXERS = refactor.get_fixers_from_package("myfixes") finally: sys.path.pop() _2TO3_FIXERS = refactor.get_fixers_from_package("fissix.fixes") class TestRefactoringTool(unittest.TestCase): def setUp(self): sys.path.append(FIXER_DIR) def tearDown(self): sys.path.pop() def check_instances(self, instances, classes): for inst, cls in zip(instances, classes):