def test_isort_warns_when_known_sections_dont_match_issue_1331(): """Test to ensure that isort warns if there is a mismatch between sections and known_sections. See: https://github.com/pycqa/isort/issues/1331. """ assert ( isort.place_module( "bot_core", config=Config( known_robotlocomotion_upstream=["bot_core"], sections=["ROBOTLOCOMOTION_UPSTREAM", "THIRDPARTY"], ), ) == "ROBOTLOCOMOTION_UPSTREAM" ) with pytest.warns(UserWarning): assert ( isort.place_module( "bot_core", config=Config( known_robotlocomotion_upstream=["bot_core"], sections=["ROBOTLOOMOTION_UPSTREAM", "THIRDPARTY"], ), ) == "THIRDPARTY" ) with pytest.warns(UserWarning): assert ( isort.place_module( "bot_core", config=Config(known_robotlocomotion_upstream=["bot_core"]) ) == "THIRDPARTY" )
def test_ensure_sre_parse_is_identified_as_stdlib_issue_1304(): """Ensure sre_parse is idenified as STDLIB. See: https://github.com/pycqa/isort/issues/1304. """ assert (isort.place_module("sre_parse") == isort.place_module("sre") == isort.settings.STDLIB # type: ignore # noqa )
def test_ensure_sre_parse_is_identified_as_stdlib_issue_1304(): """Ensure sre_parse is idenified as STDLIB. See: https://github.com/timothycrosley/isort/issues/1304. """ assert isort.place_module("sre_parse") == isort.place_module( "sre") == isort.settings.STDLIB
def process_import(node: LN, capture: Capture, filename: Filename) -> Optional[LN]: # Skip any imports at file scope if node.parent.parent.type == python_symbols.file_input: return IMPORT_WHITELIST = { "importlib", "math", "optparse", "os", "os.path", "six.moves.cPickle as pickle", "six.moves", "sys", "urllib2", "uuid", } module_name = str(node.children[1]).strip() always_float = module_name in IMPORT_WHITELIST # if STDLIB_ONLY: # if : # return # See if this is rejected if ONLY_FLOAT: isort_class = None if any(x.isupper() for x in ONLY_FLOAT): isort_class = isort.place_module( module_name, config=get_isort_config_for(filename)) if (module_name not in ONLY_FLOAT and not any(module_name.startswith(x + ".") for x in ONLY_FLOAT) and isort_class not in ONLY_FLOAT): return # if not always_float: # Bypass nodes with comments for now if node.get_suffix().strip() or get_complete_prefix(node).strip(): print( f"Not floating {filename}:{node.get_lineno()} ({module_name}) as has comments" ) return if "matplotlib" in str(node): print(f"Not floating {filename}:{node.get_lineno()} as matplotlib") return # Find the root node. While doing so, check that we aren't inside a try root = node while root.parent: # Handle always-float and try blocks - don't leave invalid if root.type == python_symbols.try_stmt: if always_float: # Check that we aren't the only entry in this suite assert node.parent.parent.type == python_symbols.suite if len(node.parent.parent.children) == 4: print( f"Not floating always-float {filename}:{node.get_lineno()} ({module_name}) as only statement inside try" ) return else: print( f"Not floating {filename}:{node.get_lineno()} ({module_name}) as inside try" ) return if not always_float: # Give a special message to the user for __main__ if non-floating if (root.type == python_symbols.if_stmt and not IGNORE_IF and "__main__" in str(root.children[1])): print( f"Not floating {filename}:{node.get_lineno()} ({module_name}) as inside __main__ test if" ) return if root.type == python_symbols.if_stmt and not IGNORE_IF: print( f"Not floating {filename}:{node.get_lineno()} ({module_name}) as inside if" ) return root = root.parent # Find the insertion point for this root node insert_point = find_import_insert_point(root) # Get the actual statement node statement = node.parent prev_sibling = statement.prev_sibling next_sibling = statement.next_sibling assert statement.type == python_symbols.simple_stmt # Are we are the start of a scope? parent_index = statement.parent.children.index(statement) # From suite definition; parent_index of first statement is either 0 or 2: # suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT # But for our purposes can be 3 if we have a docstring. assert parent_index != 0, "Inline statement functions not supported ATM" prev_sibiling_is_string = (prev_sibling.type == python_symbols.simple_stmt and prev_sibling.children[0].type == token.STRING) if parent_index == 2 or (parent_index == 3 and prev_sibiling_is_string): # We're the first statement, or the first non-docstring statement. # If we have a trailing newline, remove it. Indentation handled later. if next_sibling and next_sibling.prefix.startswith("\n"): next_sibling.prefix = next_sibling.prefix[1:] # Get the previous node. This might be the sibling, or some tree-child thereof prev_node = list(prev_sibling.leaves())[-1] # print_node(prev_node) if prev_node.type in {token.INDENT, token.DEDENT}: # If we just indented(dedented) then tree looks like: # [INDENT] " " # [simple_stmt] "" <- statement # ... # [NEWLINE] "" "\n" # [LN] " " # e.g. this next sibling node holds it's own indent but the # statement node's indentation is handled by the indent. So we # need to remove the indentation from the next sibling. next_sibling.prefix = next_sibling.prefix.lstrip(" ") if prev_node.type == token.INDENT and prev_node.prefix.isspace(): # We've got leading newlines we want to strip - # If a function starts with a blank line(s), the "\n" and any # stray indentation are attached to the [INDENT] as a prefix. # Our reasoning for removing this blank line: It was showing the # user that the import was special. # This might be flimsy reasoning. prev_node.prefix = "" # We could be transplanting a node with a prefix. Move it to the sibling next_sibling.prefix = node.prefix.rstrip(" ") + next_sibling.prefix # Do the actual moving statement.remove() root.insert_child(insert_point, statement) node.prefix = ""