def replace_unicode(path): """ Run the bowler query on the input files for refactoring. """ (Query(path).select_function("__unicode__").rename('__str__').idiff()), (Query(path).select_method("__unicode__").is_call().rename( '__str__').idiff())
def main(): """Runs the query. Called by bowler if run as a script""" do_write = "--do" in sys.argv do_silent = "--silent" in sys.argv (Query().select(PATTERN).filter(do_filter).modify(process_class).execute( interactive=False, write=do_write, silent=do_silent))
def _patch_imports(self, resolver, output_path: Path) -> int: # select modules to patch imports query = Query() query.paths = [] for package in resolver.graph.metainfo.package.packages: for module_path in package: query.paths.append(str(module_path)) # patch vendors if it's outside of main package package_path = resolver.graph.metainfo.package.packages[0].path if package_path.resolve() not in output_path.resolve().parents: query.paths.append(str(output_path)) # set renamings root = Path(self.config['project']) for library in output_path.iterdir(): if library.name in self.config['vendor']['exclude']: continue library_module = '.'.join(library.resolve().relative_to( str(root)).parts) self.logger.debug('patch imports', extra=dict( old_name=library.name, new_name=library_module, )) query = transform_imports( query=query, old_name=library.name, new_name=library_module, ) # execute renaming query.execute(interactive=False, write=True, silent=True) return len(query.paths)
def run_bowler_modifier( self, input_text, selector=None, modifier=None, selector_func=None, modifier_func=None, in_process=True, ): """Returns the modified text.""" if not (selector or selector_func): raise ValueError("Pass selector") if not (modifier or modifier_func): raise ValueError("Pass modifier") exception_queue = multiprocessing.Queue() def local_modifier(node, capture, filename): # When in_process=False, this runs in another process. See notes below. try: return modifier(node, capture, filename) except Exception as e: exception_queue.put(e) with tempfile.NamedTemporaryFile(suffix=".py") as f: # TODO: I'm almost certain this will not work on Windows, since # NamedTemporaryFile has it already open for writing. Consider # using mktemp directly? with open(f.name, "w") as fw: fw.write(input_text + "\n") if selector_func: query = selector_func([f.name]) else: query = Query([f.name]).select(selector) if modifier_func: # N.b. exceptions may not work query = modifier_func(query) else: query = query.modify(local_modifier) # We require the in_process parameter in order to record coverage properly, # but it also helps in bubbling exceptions and letting tests read state set # by modifiers. query.execute(interactive=False, write=True, silent=False, in_process=in_process) # In the case of in_process=False (mirroring normal use of the tool) we use # the queue to ship back exceptions from local_process, which can actually # fail the test. Normally exceptions in modifiers are not printed unless # you pass --debug. if not exception_queue.empty(): raise AssertionError from exception_queue.get() with open(f.name, "r") as fr: return fr.read().rstrip()
def get_query(path): return ( Query(path) .select(PATTERN) .modify(remove_debugger_statements) .execute(interactive=False, write=True) )
def change_import_paths_to_deprecated(): from bowler import LN, TOKEN, Capture, Filename, Query from fissix.pytree import Leaf def remove_tags_modifier(node: LN, capture: Capture, filename: Filename) -> None: for node in capture['function_arguments'][0].post_order(): if isinstance( node, Leaf) and node.value == "tags" and node.type == TOKEN.NAME: if node.parent.next_sibling and node.parent.next_sibling.value == ",": node.parent.next_sibling.remove() node.parent.remove() def pure_airflow_models_filter(node: LN, capture: Capture, filename: Filename) -> bool: """Check if select is exactly [airflow, . , models]""" return len([ch for ch in node.children[1].leaves()]) == 3 changes = [ ("airflow.operators.bash", "airflow.operators.bash_operator"), ("airflow.operators.python", "airflow.operators.python_operator"), ("airflow.utils.session", "airflow.utils.db"), ] qry = Query() for new, old in changes: qry.select_module(new).rename(old) # Move and refactor imports for Dataflow copyfile( os.path.join(dirname(__file__), os.pardir, "airflow", "utils", "python_virtualenv.py"), os.path.join(dirname(__file__), "airflow", "providers", "google", "cloud", "utils", "python_virtualenv.py")) (qry.select_module("airflow.utils.python_virtualenv").rename( "airflow.providers.google.cloud.utils.python_virtualenv")) copyfile( os.path.join(dirname(__file__), os.pardir, "airflow", "utils", "process_utils.py"), os.path.join(dirname(__file__), "airflow", "providers", "google", "cloud", "utils", "process_utils.py")) (qry.select_module("airflow.utils.process_utils").rename( "airflow.providers.google.cloud.utils.process_utils")) # Remove tags qry.select_method("DAG").is_call().modify(remove_tags_modifier) # Fix KubernetesPodOperator imports to use old path qry.select_module( "airflow.providers.cncf.kubernetes.operators.kubernetes_pod").rename( "airflow.contrib.operators.kubernetes_pod_operator") # Fix BaseOperatorLinks imports files = r"bigquery\.py|mlengine\.py" # noqa qry.select_module("airflow.models").is_filename(include=files).filter( pure_airflow_models_filter).rename("airflow.models.baseoperator") qry.execute(write=True, silent=False, interactive=False)
def rewrite(paths, interactive=False, silent=False): """ Rewrite the passed in paths """ (Query(paths).select_module("tornado").filter(filter_tornado_imports). rename("salt.ext.tornado").select_root().select("classdef|funcdef"). filter(filter_not_decorated).modify(replace_decorators).execute( write=True, interactive=interactive, silent=silent))
def main(): parser = argparse.ArgumentParser() parser.add_argument("--log-level", dest="log_level", type=str, choices=["DEBUG", "INFO", "WARNING", "ERROR"], help="set log level, default is INFO") parser.add_argument("--no-log-file", dest="no_log_file", action='store_true', default=False, help="don't log to file") parser.add_argument("--log-filepath", dest="log_filepath", type=str, help='set log file path, default is "report.log"') parser.add_argument("--inpath", required=True, type=str, help='the file or directory path you want to upgrade.') parser.add_argument("--backup", type=str, nargs='?', default=None, const=None, help='backup directory, default is the "~/.paddle1to2/".') parser.add_argument("--write", action='store_true', default=False, help='modify files in-place.') parser.add_argument("--no-confirm", dest="no_confirm", action='store_true', default=False, help='write files in-place without confirm, ignored without --write.') parser.add_argument("--refactor", action='append', choices=refactor.__all__, help='this is a debug option. Specify refactor you want to run. If none, all refactors will be run.') parser.add_argument("--print-match", action='store_true', default=False, help='this is a debug option. Print matched code and node for each file.') args = parser.parse_args() if args.refactor: args.refactor = set(args.refactor) if args.backup is None: home = os.path.expanduser('~') args.backup = os.path.join(home, '.paddle1to2') else: args.backup = os.path.expanduser(args.backup) if args.log_level: logger.setLevel(args.log_level) if not args.no_log_file: log_to_file(args.log_filepath) if not should_convert(args.inpath): logger.error("convert abort!") sys.exit(1) # refactor code via "Query" step by step. q = Query(args.inpath) for fn in refactor.__all__: refactor_func = getattr(refactor, fn) if args.refactor and fn not in args.refactor: continue assert callable(refactor_func), "{} is not callable.".format(fn) logger.debug("run refactor: {}".format(fn)) if args.print_match: refactor_func(q, change_spec).filter(filters.print_match) else: refactor_func(q, change_spec) if args.write: # backup args.inpath backup = backup_inpath(args.inpath, args.backup) # print diff to stdout, and modify file in place. if utils.is_windows(): q.execute(write=True, silent=False, need_confirm=not args.no_confirm, backup=backup, in_process=True) else: q.execute(write=True, silent=False, need_confirm=not args.no_confirm, backup=backup) else: # print diff to stdout if utils.is_windows(): q.execute(write=False, silent=False, in_process=True) else: q.execute(write=False, silent=False) click.secho('Refactor finished without touching source files, add "--write" to modify source files in-place if everything is ok.', fg="red", bold=True)
def run(models, interactive: bool = False) -> Query: query = ( Query(models) .select_method("ForeignKey") .modify(on_delete_modifier) .select_method("OneToOneField") .modify(on_delete_modifier) ) return query.diff(interactive=interactive)
def test_remove_marker(src, expected, tmpdir): pyfile = tmpdir.join("t.py") pyfile.write(src) (Query([str(pyfile)]).select("funcdef").modify(remove_marker).execute( interactive=False, write=True, silent=False, in_process=True)) modified = pyfile.read() assert modified == expected
def main(): (Query("fake.py").select(""" power< obj=NAME trailer< '.' attr=NAME > > """).modify(modify_attr).select( """atom< "{" dictsetmaker< body=any* > "}" >""").filter( filter_dict_literal).modify(modify_dict_literal).diff())
def run_query(files, write=True, silent=False): ( # Look for files in the current working directory Query(*files).select_root().modify(callback=sort_imports) # Actually run both of the above. .execute( # interactive diff implies write (for the bits the user says 'y' to) interactive=False, write=write, silent=silent, ))
def rewrite(paths, interactive=False, silent=False): """ Rewrite the passed in paths """ # Don't waste time on non-test files paths = utils.filter_test_files(paths) if not paths: return (Query(paths).select("classdef|funcdef").filter( filter_not_decorated).modify(replace_decorator).execute( write=True, interactive=interactive, silent=silent))
def filtered_testfuncs(src_file, filter): results = [] def get_testfunc(node, capture, filename): results.append(TestFunc.from_node(node, filename)) (Query([str(src_file) ]).select("funcdef").filter(filter).modify(get_testfunc).execute( interactive=False, write=False, silent=False, in_process=True)) return results
def main(argv=None): """Runs the query. Called by bowler if run as a script""" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--do", action="store_true", help="Actually write the changes") parser.add_argument("--silent", action="store_true", help="Do the processing quietly") parser.add_argument("filenames", metavar="FILE", nargs="*", help="Specific filenames to process") parser.add_argument( "--logger", metavar="NAME", default="logger", help="The conventional name for loggers", ) args = parser.parse_args(argv) # Logger might be a lookup pattern. Split it. logger_pattern = f"'{args.logger}'" if "." in args.logger: parts = args.logger.split(".") logger_pattern = f"'{parts[0]}' " + " ".join(f"trailer < '.' '{x}' >" for x in parts[1:]) PERCENT_PATTERN = f""" power < {logger_pattern} trailer call=trailer < '(' term < formatstr=any '%' vars=any > ')' > >""" FORMAT_PATTERN = f""" power < {logger_pattern} trailer call=trailer < '(' formatblock=any < formatstr=STRING trailer < "." "format" > any < '(' arglist=any ')'> > ')' > > """ (Query( args.filenames).select(PERCENT_PATTERN).modify(process_percent_format). select(FORMAT_PATTERN).modify(process_format_format).execute( interactive=False, write=args.do, silent=args.silent))
def default_query_func(files): if selector_func: q = selector_func(files) else: q = Query(files).select(selector) if modifier_func: q = modifier_func(q) else: q = q.modify(modifier) return q
def run_removal_query(path): """ Run the bowler query on the input files for refactoring. """ ( Query(path) .select("decorator<'@' name='python_2_unicode_compatible' any>") .modify(remove_node) .select("import_from<'from' module_name=any 'import' 'python_2_unicode_compatible'>") .modify(remove_node) .write() )
def main(): parser = argparse.ArgumentParser( description= "Adds some py2&3 compatibility that modernize/futurize missed") parser.add_argument( '--no-input', dest='interactive', default=True, action='store_false', help="Non-interactive mode", ) parser.add_argument( '--no-write', dest='write', default=True, action='store_false', help= "Don't write the changes to the source file, just output a diff to stdout", ) parser.add_argument( '--debug', dest='debug', default=False, action='store_true', help="Spit out debugging information", ) parser.add_argument('files', nargs='+', help="The python source file(s) to operate on.") args = parser.parse_args() # No way to pass this to .modify() callables, so we just set it at module level flags['debug'] = args.debug ( # Look for files in the current working directory Query(*args.files).select(""" classdef< "class" classname=NAME any* ":" suite=suite< any* func=funcdef< "def" funcname="__unicode__" parameters< "(" NAME ")" > any* > any* > > """).modify(callback=replace_unicode_methods) # Actually run all of the above. .execute( # interactive diff implies write (for the bits the user says 'y' to) interactive=(args.interactive and args.write), write=args.write, ))
def test_transform_imports(code_in: str, code_out: str, old_name: str, new_name: str, temp_path: Path): code_in += '\n' code_out += '\n' path = temp_path / 'tmp.py' path.write_text(code_in) query = transform_imports(query=Query(str(path)), old_name=old_name, new_name=new_name) query.execute(silent=True, write=True, interactive=False) result = path.read_text() if code_in == code_out: assert result == code_out, 'unexpected changes' else: assert result != code_in, 'nothing was changed' assert result == code_out, 'invalid changes'
def __init__(self, input, nobackups, show_diffs): """ Args: input: path to file to be refactored. nobackups: If true no backup '.bak' files will be created for those files that are being refactored. show_diffs: Should diffs of the refactoring be printed to stdout? """ self.nobackups = nobackups self.show_diffs = show_diffs self.fn = input self.query = Query([self.fn])
def main(): """Runs the query. Called by bowler if run as a script""" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--do", action="store_true", help="Actually write the changes") parser.add_argument("--silent", action="store_true", help="Do the processing quietly") parser.add_argument("--ignoreif", action="store_true", help="Float from inside if statements") parser.add_argument( "--stdlib", action="store_true", help="Only float standard library imports. Same as --only=STDLIB", ) parser.add_argument( "--only", action="store", help= "Comma-separated list of modules to float. All others will be ignored. Can pass in all caps e.g. STDLIB and the isort classification will be used.", ) parser.add_argument("filenames", metavar="FILE", nargs="*", help="Specific filenames to process") args = parser.parse_args() global IGNORE_IF, ONLY_FLOAT IGNORE_IF = args.ignoreif # Don't allow stdlib floating if isort is not available if args.stdlib and isort is None: sys.exit( "Can not classify standard library modules; isort not installed") # Handle specific subsets of floating if args.only: only_list_prep = [x.strip() for x in args.only.split(",")] if any(x.isupper() for x in only_list_prep) and isort is None: sys.exit( "Can not use isort classification as isort is not available") ONLY_FLOAT = set(only_list_prep) if args.stdlib: ONLY_FLOAT.add("STDLIB") (Query(args.filenames).select(PATTERN) # .select_root() .modify(process_import).execute(interactive=False, write=args.do, silent=args.silent))
def change_import_paths_to_deprecated(): changes = [ ("airflow.operators.bash", "airflow.operators.bash_operator"), ("airflow.operators.python", "airflow.operators.python_operator"), ("airflow.utils.session", "airflow.utils.db"), ] qry = Query() for new, old in changes: qry.select_module(new).rename(old) # Move and refactor imports for Dataflow copyfile( os.path.join(dirname(__file__), os.pardir, "airflow", "utils", "python_virtualenv.py"), os.path.join(dirname(__file__), "airflow", "providers", "google", "cloud", "utils", "python_virtualenv.py" ) ) ( qry .select_module("airflow.utils.python_virtualenv") .rename("airflow.providers.google.cloud.utils.python_virtualenv") ) copyfile( os.path.join(dirname(__file__), os.pardir, "airflow", "utils", "process_utils.py"), os.path.join(dirname(__file__), "airflow", "providers", "google", "cloud", "utils", "process_utils.py" ) ) ( qry .select_module("airflow.utils.process_utils") .rename("airflow.providers.google.cloud.utils.process_utils") ) # Remove tags qry.select_method("DAG").is_call().modify(remove_tags_modifier) # Fix KubernetesPodOperator imports to use old path qry.select_module( "airflow.providers.cncf.kubernetes.operators.kubernetes_pod").rename( "airflow.contrib.operators.kubernetes_pod_operator" ) # Fix BaseOperatorLinks imports files = r"bigquery\.py|mlengine\.py" # noqa qry.select_module("airflow.models").is_filename(include=files).filter(pure_airflow_models_filter).rename( "airflow.models.baseoperator") qry.execute(write=True, silent=False, interactive=False)
def main(): parser = argparse.ArgumentParser( description="Removes bytestring literals. Be careful with this!" ) parser.add_argument( '--no-input', dest='interactive', default=True, action='store_false', help="Non-interactive mode", ) parser.add_argument( '--no-write', dest='write', default=True, action='store_false', help="Don't write the changes to the source file, just output a diff to stdout", ) parser.add_argument( '--debug', dest='debug', default=False, action='store_true', help="Spit out debugging information", ) parser.add_argument( 'files', nargs='+', help="The python source file(s) to operate on." ) args = parser.parse_args() # No way to pass this to .modify() callables, so we just set it at module level flags['debug'] = args.debug ( # Look for files in the current working directory Query(*args.files) .select( """ STRING """ ) .modify(callback=debytesify) # Actually run all of the above. .execute( # interactive diff implies write (for the bits the user says 'y' to) interactive=(args.interactive and args.write), write=args.write, ) )
def rewrite(paths, interactive=False, silent=False): """ Rewrite the passed in paths """ (Query(paths).select(""" ( file_input< simple_stmt< [STRING] docstring=any* > any* > | class_def=classdef< any* suite< any* simple_stmt< [STRING] docstring=any* > any* > any* > | funcdef< any* suite< any* simple_stmt< [STRING] docstring=any* > any* > any* > ) """).filter(filter_no_module_docstrings).modify( fix_module_docstrings).execute(write=True, interactive=interactive, silent=silent))
def _refactor_helper(refactor_func, input_src, change_spec): try: ntf = NamedTemporaryFile(suffix='.py', delete=False) ntf.write(input_src.encode('utf-8')) ntf.close() q = Query(ntf.name) if utils.is_windows(): refactor_func(q, change_spec).execute(write=True, silent=True, need_confirm=False, print_hint=False, in_process=True) else: refactor_func(q, change_spec).execute(write=True, silent=True, need_confirm=False, print_hint=False) with open(ntf.name, 'r') as f: output_src = f.read() return output_src finally: os.remove(ntf.name)
def main(): """Runs the query. Called by bowler if run as a script""" global LIBS global LIB_USES parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--do", action="store_true", help="Actually write the changes") parser.add_argument( "--silent", action="store_true", help="Do the processing quietly" ) # parser.add_argument( # "--ignoreif", action="store_true", help="Float from inside if statements" # ) parser.add_argument( "library_path", metavar="LIBDIR", nargs="?", help="Where to find built libraries", ) args = parser.parse_args() LIBS = [x.stem for x in Path(args.library_path).glob("*.so")] print(f"Looking for {len(LIBS)} library imports") # print(", ".join(LIBS)) # global IGNORE_IF # IGNORE_IF = args.ignoreif ( Query() .select(PATTERN) # .select_root() .modify(process_import) .execute(interactive=False, write=args.do, silent=args.silent) ) with open("libs.list", "w") as f: f.write(pprint.pformat(LIB_USES)) print("Wrote results to libs.list")
def main(): """Runs the query. Called by bowler if run as a script""" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--do", action="store_true", help="Actually write the changes") parser.add_argument("--silent", action="store_true", help="Do the processing quietly") parser.add_argument("--onlyfloat", action="store_true", help="Only float, don't also fixup") parser.add_argument("filenames", metavar="FILE", nargs="*", help="Specific filenames to process") args = parser.parse_args() # Hack in a separate mode for updating everything for py3 global FLOAT_MODE FLOAT_MODE = args.onlyfloat (Query(args.filenames).select_root().modify(process_root).execute( interactive=False, write=args.do, silent=args.silent))
def __init__(self): self.qry = Query()
def change_import_paths_to_deprecated(): from bowler import LN, TOKEN, Capture, Filename, Query from fissix.pytree import Leaf from fissix.fixer_util import KeywordArg, Name, Comma def remove_tags_modifier(node: LN, capture: Capture, filename: Filename) -> None: for node in capture['function_arguments'][0].post_order(): if isinstance(node, Leaf) and node.value == "tags" and node.type == TOKEN.NAME: if node.parent.next_sibling and node.parent.next_sibling.value == ",": node.parent.next_sibling.remove() node.parent.remove() def pure_airflow_models_filter(node: LN, capture: Capture, filename: Filename) -> bool: """Check if select is exactly [airflow, . , models]""" return len([ch for ch in node.children[1].leaves()]) == 3 def remove_super_init_call(node: LN, capture: Capture, filename: Filename) -> None: for ch in node.post_order(): if isinstance(ch, Leaf) and ch.value == "super": if any(c.value for c in ch.parent.post_order() if isinstance(c, Leaf)): ch.parent.remove() def add_provide_context_to_python_operator(node: LN, capture: Capture, filename: Filename) -> None: fn_args = capture['function_arguments'][0] fn_args.append_child(Comma()) provide_context_arg = KeywordArg(Name('provide_context'), Name('True')) provide_context_arg.prefix = fn_args.children[0].prefix fn_args.append_child(provide_context_arg) def remove_class(qry, class_name) -> None: def _remover(node: LN, capture: Capture, filename: Filename) -> None: if node.type not in (300, 311): # remove only definition node.remove() qry.select_class(class_name).modify(_remover) changes = [ ("airflow.operators.bash", "airflow.operators.bash_operator"), ("airflow.operators.python", "airflow.operators.python_operator"), ("airflow.utils.session", "airflow.utils.db"), ( "airflow.providers.cncf.kubernetes.operators.kubernetes_pod", "airflow.contrib.operators.kubernetes_pod_operator" ), ] qry = Query() for new, old in changes: qry.select_module(new).rename(old) # Move and refactor imports for Dataflow copyfile( os.path.join(dirname(__file__), os.pardir, "airflow", "utils", "python_virtualenv.py"), os.path.join( dirname(__file__), "airflow", "providers", "google", "cloud", "utils", "python_virtualenv.py" ) ) ( qry .select_module("airflow.utils.python_virtualenv") .rename("airflow.providers.google.cloud.utils.python_virtualenv") ) copyfile( os.path.join(dirname(__file__), os.pardir, "airflow", "utils", "process_utils.py"), os.path.join( dirname(__file__), "airflow", "providers", "google", "cloud", "utils", "process_utils.py" ) ) ( qry .select_module("airflow.utils.process_utils") .rename("airflow.providers.google.cloud.utils.process_utils") ) # Remove tags qry.select_method("DAG").is_call().modify(remove_tags_modifier) # Fix AWS import in Google Cloud Transfer Service ( qry .select_module("airflow.providers.amazon.aws.hooks.base_aws") .is_filename(include=r"cloud_storage_transfer_service\.py") .rename("airflow.contrib.hooks.aws_hook") ) ( qry .select_class("AwsBaseHook") .is_filename(include=r"cloud_storage_transfer_service\.py") .filter(lambda n, c, f: n.type == 300) .rename("AwsHook") ) # Fix BaseOperatorLinks imports files = r"bigquery\.py|mlengine\.py" # noqa qry.select_module("airflow.models").is_filename(include=files).filter(pure_airflow_models_filter).rename( "airflow.models.baseoperator") # Fix super().__init__() call in hooks qry.select_subclass("BaseHook").modify(remove_super_init_call) ( qry.select_function("PythonOperator") .is_call() .is_filename(include=r"mlengine_operator_utils.py$") .modify(add_provide_context_to_python_operator) ) ( qry.select_function("BranchPythonOperator") .is_call() .is_filename(include=r"example_google_api_to_s3_transfer_advanced.py$") .modify(add_provide_context_to_python_operator) ) # Remove new class and rename usages of old remove_class(qry, "GKEStartPodOperator") ( qry .select_class("GKEStartPodOperator") .is_filename(include=r"example_kubernetes_engine\.py") .rename("GKEPodOperator") ) qry.execute(write=True, silent=False, interactive=False) # Add old import to GKE gke_path = os.path.join( dirname(__file__), "airflow", "providers", "google", "cloud", "operators", "kubernetes_engine.py" ) with open(gke_path, "a") as f: f.writelines(["", "from airflow.contrib.operators.gcp_container_operator import GKEPodOperator"]) gke_path = os.path.join( dirname(__file__), "airflow", "providers", "google", "cloud", "operators", "kubernetes_engine.py" )
def rewrite(paths, interactive=False, silent=False): """ Rewrite the passed in paths """ # Don't waste time on non-test files paths = filter_test_files(paths) if not paths: return (Query(paths).select_class("TestCase") # NOTE: You can append as many .select().modify() bits as you want to one query. # Each .modify() acts only on the .select[_*]() immediately prior. .select_method("assertEqual").modify( callback=assertmethod_to_assert).select_method("assertEquals").modify( callback=assertmethod_to_assert).select_method( "failUnlessEqual").modify(callback=assertmethod_to_assert). select_method("assertNotEqual").modify( callback=assertmethod_to_assert).select_method("failIfEqual").modify( callback=assertmethod_to_assert).select_method("assertIs").modify( callback=assertmethod_to_assert).select_method("assertIsNot"). modify(callback=assertmethod_to_assert).select_method("assertIn").modify( callback=assertmethod_to_assert).select_method("assertNotIn").modify( callback=assertmethod_to_assert).select_method("assertTrue"). modify( callback=assertmethod_to_assert).select_method("assertFalse").modify( callback=assertmethod_to_assert).select_method("assert_").modify( callback=assertmethod_to_assert).select_method("failUnless"). modify(callback=assertmethod_to_assert).select_method("failIf").modify( callback=assertmethod_to_assert).select_method("assertIsNone").modify( callback=assertmethod_to_assert).select_method("assertIsNotNone"). modify(callback=assertmethod_to_assert).select_method( "assertGreater").modify(callback=assertmethod_to_assert). select_method("assertGreaterEqual").modify( callback=assertmethod_to_assert).select_method("assertLess").modify( callback=assertmethod_to_assert).select_method("assertLessEqual"). modify(callback=assertmethod_to_assert).select_method("assertIsInstance"). modify(callback=assertmethod_to_assert).select_method( "assertNotIsInstance").modify( callback=assertmethod_to_assert).select_method("assertDictEqual"). modify(callback=assertmethod_to_assert).select_method( "assertSetEqual").modify( callback=assertmethod_to_assert).select_method( "assertListEqual").modify(callback=assertmethod_to_assert). select_method("assertTupleEqual").modify( callback=assertmethod_to_assert).select_method("assertSequenceEqual"). modify(callback=assertmethod_to_assert).select_method( "assertMultiLineEqual").modify( callback=assertmethod_to_assert).select_method( "assertAlmostEqual").modify( callback=assertalmostequal_to_assert).select_method( "assertNotAlmostEqual").modify( callback=assertalmostequal_to_assert).select(""" function_call=power< self_attr="self" raises_attr=trailer< "." "assertRaises" > trailer< '(' function_arguments=any* ')' > > """).modify(callback=handle_assertraises).select_method("assertRegex"). modify( callback=handle_assert_regex).select_method("assertNotRegex").modify( callback=handle_assert_regex) # Actually run all of the above. .execute(write=True, interactive=interactive, silent=silent))