def test_general_to_from(self): old = parse_imports("import pathlib") new = parse_imports("from pathlib import Path") assert ( str(pi.ImportedNames.compare(old, new)) == "New imported ``Path'' from ``pathlib'' (previously, full ``pathlib'' was imported)" )
def test_from_to_general(self): old = parse_imports("from pathlib import Path") new = parse_imports("import pathlib") assert ( str(pi.ImportedNames.compare(old, new)) == "New imported package ``pathlib'' (previously, only ``Path'' was imported from ``pathlib'')" )
def test_message_removed_fromimport_module(self): # pylint: disable=invalid-name old = parse_imports("from module import one") new = parse_imports("") assert ( str(pi.ImportedNames.compare(old, new)) == "Removed import of ``one'' from removed ``module''" )
def test_message_new_import(self): old = parse_imports("") new_one = parse_imports("import one") new_more = parse_imports("import one, two") assert str(pi.ImportedNames.compare(old, new_one)) == "New imported package ``one''" assert ( str(pi.ImportedNames.compare(old, new_more)) == "New imported packages ``one'', ``two''" )
def test_external_name_usage(self): old = self._make_summary("def function(): return some_path") new = self._make_summary("def function(): return pathy.join(lst)") old_imports = parse_imports("from os import path") new_imports = parse_imports("from os import path as pathy") pyfference = pf.pyff_function(old, new, old_imports, new_imports) assert len(pyfference.implementation) == 2
def test_new_importfrom_module(self): old = parse_imports("from os import path") new = parse_imports("from module import name") change = pi.ImportedNames.compare(old, new) assert len(change.fromimports.new) == 1 assert len(change.fromimports.new_modules) == 1 assert change.fromimports.new_modules == {"module"}
def test_message_new_fromimport(self): old = parse_imports("from module import one") new_one = parse_imports("from module import one, two") new_more = parse_imports("from module import one, two, three") assert str(pi.ImportedNames.compare(old, new_one)) == "New imported ``two'' from ``module''" assert ( str(pi.ImportedNames.compare(old, new_more)) == "New imported ``three'', ``two'' from ``module''" )
def test_example_04(self): old_import = parse_imports("from pathlib import Path") new_import = parse_imports("import pathlib") old = ast.parse("Path.home()") new = ast.parse("pathlib.Path.home()") change = ps.find_external_name_matches(old, new, old_import, new_import) assert change is not None
def test_message_remove_import(self): old = parse_imports("import one, two") new_one = parse_imports("import one") new_more = parse_imports("") assert str(pi.ImportedNames.compare(old, new_one)) == "Removed import of package ``two''" assert ( str(pi.ImportedNames.compare(old, new_more)) == "Removed import of packages ``one'', ``two''" ) # pylint: disable=line-too-long
def test_no_external(self): old_imports = parse_imports( "import os; from ast import Name; import sys as system") new_imports = parse_imports("from os import path; import unittest") old_function = ast.parse("def function(a, b, c): return a if b else c") new_function = ast.parse( "def function(a, b, c): temp = a / c; return temp if b else None") assert pf.compare_import_usage(old_function, new_function, old_imports, new_imports) is None
def test_removed_import(self): old = parse_imports("import os; import sys") old_with_comma = parse_imports("import os, sys") new = parse_imports("import os") change = pi.ImportedNames.compare(old, new) assert len(change.removed_imports) == 1 assert max(change.removed_imports).canonical_name == "sys" change = pi.ImportedNames.compare(old_with_comma, new) assert len(change.removed_imports) == 1 assert max(change.removed_imports).canonical_name == "sys"
def test_message_new_fromimport_module(self): # pylint: disable=invalid-name old = parse_imports("") new_one = parse_imports("from module import one") new_more = parse_imports("from module import one, two") assert ( str(pi.ImportedNames.compare(old, new_one)) == "New imported ``one'' from new ``module''" ) assert ( str(pi.ImportedNames.compare(old, new_more)) == "New imported ``one'', ``two'' from new ``module''" )
def test_appeared(self): old_imports = parse_imports( "import os; from ast import Name; import sys as system") new_imports = parse_imports("import os; import unit") old_function = ast.parse( "def function(a, b, c): return os.path.join([a, b, c])") new_function = ast.parse( "def function(a, b, c): unit.method(); return os.path.join([a,b,c])" ) change = pf.compare_import_usage(old_function, new_function, old_imports, new_imports) assert change.appeared == {"unit"}
def test_removed_importfrom(self): old = parse_imports("from os import path; from os import environ") old_with_comma = parse_imports("from os import path, environ") new = parse_imports("from os import path") change = pi.ImportedNames.compare(old, new) assert len(change.fromimports.removed) == 1 assert not change.fromimports.removed_modules assert change.fromimports.removed["os"].pop().canonical_name == "os.environ" change_with_comma = pi.ImportedNames.compare(old_with_comma, new) assert len(change_with_comma.fromimports.removed) == 1 assert not change.fromimports.removed_modules assert change_with_comma.fromimports.removed["os"].pop().canonical_name == "os.environ"
def test_gone(self): old_imports = parse_imports( "import os; from ast import Name; import sys as system") new_imports = parse_imports( "from os.path import join; import unittest") old_function = ast.parse( "def function(a, b, c): return os.path.join([a, b, c])") new_function = ast.parse( "def function(a, b, c): return join([a, b, c])") change = pf.compare_import_usage(old_function, new_function, old_imports, new_imports) assert change.appeared == {"join"} assert change.gone == {"os"}
def _check_fqn(imports, code, expected_subs, expected_qualified_code): imports = parse_imports(imports) qualifier = ps.FullyQualifyNames(imports) original_ast = ast.parse(code) qualified_ast = qualifier.visit(original_ast) assert qualifier.substitutions == expected_subs assert ast.dump( ast.parse(expected_qualified_code)) == ast.dump(qualified_ast)
def test_different_statement_count(self): old = self._make_summary("def function(): do_some_useless_stuff();") new = self._make_summary( "def function(): do_some_useless_stuff(); return None") no_imports = parse_imports("") pyfference = pf.pyff_function(old, new, no_imports, no_imports) assert len(pyfference.implementation) == 1
def test_external_names(self): change = ps.pyff_statement( ast.parse("p = path.join(lst)"), ast.parse("p = pathy.join(lst)"), pi.ImportedNames(), pi.ImportedNames(), ) # alone, the statements are different assert change.semantically_different() another_change = ps.pyff_statement( ast.parse("p = path.join(lst)"), ast.parse("p = pathy.join(lst)"), parse_imports("from os import path"), parse_imports("from os import path as pathy"), ) # with information about imports, we can deduce the statements are semantically equivalent assert not another_change.semantically_different()
def test_sanity(self): old = parse_imports("import four; from five import six, seven") new = parse_imports("import one, two, three; " "from module import fst, snd; " "from five import seven; " "from eight import nine") imports = pi.ImportedNames.compare(old, new) functions = pf.FunctionsPyfference( new={ "function": pf.FunctionSummary("function", node=Mock(spec=ast.FunctionDef)), "funktion": pf.FunctionSummary("funktion", node=Mock(spec=ast.FunctionDef)), }, changed={ "name": pf.FunctionPyfference("name", old_name="old_name", implementation=set()) }, removed={}, ) classes = pc.ClassesPyfference(new={"NewClass2", "NewClass"}, changed=set()) change = pm.ModulePyfference(imports, classes, functions) assert change.classes is not None assert change.functions is not None assert change.imports is not None assert str(change) == ( "Removed import of package ``four''\n" "New imported packages ``one'', ``three'', ``two''\n" "Removed import of ``six'' from ``five''\n" "New imported ``fst'', ``snd'' from new ``module''\n" "New imported ``nine'' from new ``eight''\n" "New NewClass\n" "New NewClass2\n" "Function ``old_name'' renamed to ``name''\n" "New function ``function''\n" "New function ``funktion''") assert change.simplify() is change
def test_import(self): package_imports = parse_imports("import os") alias_imports = parse_imports("import os as operatingsystem") parse_pkg = lambda: ast.parse( "def function(): return os.path.join([1, 2, 3])") parse_alias = lambda: ast.parse( "def function(): return operatingsystem.path.join([1, 2, 3])") assert (ps.find_external_name_matches( parse_pkg(), parse_pkg(), package_imports, package_imports) is None) changes = ps.find_external_name_matches(parse_pkg(), parse_alias(), package_imports, alias_imports) assert changes is not None assert len(changes.changes) == 1 change = changes.changes.pop() assert change.old == "os" assert change.new == "operatingsystem"
def test_extract_external_baseclass(self): code = "from module import BaseKlass\n" "class Klass(BaseKlass):\n" " pass" names = parse_imports(code) extractor = pc.ClassesExtractor(names) extractor.visit(ast.parse(code)) assert len(extractor.classes) == 1 summary = extractor.classes["Klass"] assert ( str(summary) == "class ``Klass'' derived from imported ``BaseKlass'' with 0 public methods" )
def test_import(self): imported_names = parse_imports( "import package, pkg.module, something as alias") package_names = extract_names_from_function( "def function(): a = package.function()", imported_names) assert package_names == {"package"} module_names = extract_names_from_function( "def function(): a = pkg.module.attribute + 3", imported_names) assert module_names == {"pkg.module"} alias_names = extract_names_from_function( "def f(): a = alias.C().package + pkg.module.p", imported_names) assert alias_names == {"alias", "pkg.module"}
def test_importfrom(self): imported_names = parse_imports("from pk import name, other as alias; " "from pk.mod import other") package_names = extract_names_from_function( "def function(): a = name()", imported_names) assert package_names == {"name"} alias_names = extract_names_from_function( "def function(): a = alias + 3", imported_names) assert alias_names == {"alias"} module_names = extract_names_from_function( "def function(): a = other(3) + pkg + mod", imported_names) assert module_names == {"other"}
def test_extract_local_baseclass(self): code = ("import os\n" "class BaseKlass:\n" " pass\n" "class Klass(BaseKlass):\n" " pass\n") names = parse_imports(code) extractor = pc.ClassesExtractor(names) extractor.visit(ast.parse(code)) assert len(extractor.classes) == 2 summary = extractor.classes["Klass"] assert ( str(summary) == "class ``Klass'' derived from local ``BaseKlass'' with 0 public methods" )
def test_importfrom(self): # package_import = parse_imports("import os.path") from_import = parse_imports("from os import path") alias_import = parse_imports("from os import path as pathy") # parse_pkg = lambda: ast.parse("def f(): return os.path.join([1,2,3])") parse_from = lambda: ast.parse("def f(): return path.join([1,2,3])") parse_alias = lambda: ast.parse("def f(): return pathy.join([1,2,3])") # BUG: We do not detect this # package_to_from = ps.find_external_name_matches(parse_pkg(), parse_from(), # package_import, from_import) # _check_matches(package_to_from, 1, "os.path", "path") # BUG: We do not detect this # package_to_alias = ps.find_external_name_matches(parse_pkg(), parse_alias(), # package_import, alias_import) # _check_matches(package_to_alias, 1, "os.path", "pathy") from_to_alias = ps.find_external_name_matches(parse_from(), parse_alias(), from_import, alias_import) self._check_matches(from_to_alias, 1, "path", "pathy")
def _check_references(imports, code, references): imports = parse_imports(imports) qualifier = ps.FullyQualifyNames(imports) qualifier.visit(ast.parse(code)) assert qualifier.references == references
def test_importfrom_alias(self): names = parse_imports("from os import path, environ as environment") assert len(names) == 2 assert "path" in names assert "environment" in names
def test_importfrom_multiple(self): names = parse_imports("from os import path, environ") assert len(names) == 2 assert "path" in names assert "environ" in names
def test_importfrom_simple(self): names = parse_imports("from os import path") assert len(names) == 1 assert "path" in names
def test_import_alias(self): names = parse_imports("import os as operating_system, sys") assert len(names) == 2 assert "operating_system" in names assert "sys" in names