Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
patterns = [pattern]
return patterns
def find(self, module_name: str) -> Optional[str]:
# Try to find most specific placement instruction match (if any)
parts = module_name.split(".")
module_names_to_check = (".".join(parts[:first_k]) for first_k in range(len(parts), 0, -1))
for module_name_to_check in module_names_to_check:
for pattern, placement in self.known_patterns:
if pattern.match(module_name_to_check):
return placement
return None
class PathFinder(BaseFinder):
def __init__(self, config: Config) -> None:
super().__init__(config)
# restore the original import path (i.e. not the path to bin/isort)
root_dir = os.getcwd()
src_dir = f"{root_dir}/src"
self.paths = [root_dir, src_dir]
# virtual env
self.virtual_env = self.config.virtual_env or os.environ.get("VIRTUAL_ENV")
if self.virtual_env:
self.virtual_env = os.path.realpath(self.virtual_env)
self.virtual_env_src = ""
if self.virtual_env:
self.virtual_env_src = f"{self.virtual_env}/src/"
for path in glob(f"{self.virtual_env}/lib/python*/site-packages"):
class ForcedSeparateFinder(BaseFinder):
def find(self, module_name: str) -> Optional[str]:
for forced_separate in self.config.forced_separate:
# Ensure all forced_separate patterns will match to end of string
path_glob = forced_separate
if not forced_separate.endswith("*"):
path_glob = "%s*" % forced_separate
if fnmatch(module_name, path_glob) or fnmatch(module_name, "." + path_glob):
return forced_separate
return None
class LocalFinder(BaseFinder):
def find(self, module_name: str) -> Optional[str]:
if module_name.startswith("."):
return "LOCALFOLDER"
return None
class KnownPatternFinder(BaseFinder):
def __init__(self, config: Config) -> None:
super().__init__(config)
self.known_patterns: List[Tuple[Pattern[str], str]] = []
for placement in reversed(config.sections):
known_placement = KNOWN_SECTION_MAPPING.get(placement, placement).lower()
config_key = f"known_{known_placement}"
known_patterns = list(
getattr(self.config, config_key, self.config.known_other.get(known_placement, []))
class PipfileFinder(ReqsBaseFinder):
enabled = bool(Pipfile)
def _get_names(self, path: str) -> Iterator[str]:
with chdir(path):
project = Pipfile.load(path)
for req in project.packages:
yield req.name
def _get_files_from_dir(self, path: str) -> Iterator[str]:
if "Pipfile" in os.listdir(path):
yield path
class DefaultFinder(BaseFinder):
def find(self, module_name: str) -> Optional[str]:
return self.config.default_section
class FindersManager:
_default_finders_classes: Sequence[Type[BaseFinder]] = (
ForcedSeparateFinder,
LocalFinder,
KnownPatternFinder,
PathFinder,
PipfileFinder,
RequirementsFinder,
DefaultFinder,
)
def __init__(
if finder_classes is None:
finder_classes = self._default_finders_classes
finders: List[BaseFinder] = []
for finder_cls in finder_classes:
try:
finders.append(finder_cls(config))
except Exception as exception:
# if one finder fails to instantiate isort can continue using the rest
if self.verbose:
print(
(
f"{finder_cls.__name__} encountered an error ({exception}) during "
"instantiation and cannot be used"
)
)
self.finders: Tuple[BaseFinder, ...] = tuple(finders)
if not forced_separate.endswith("*"):
path_glob = "%s*" % forced_separate
if fnmatch(module_name, path_glob) or fnmatch(module_name, "." + path_glob):
return forced_separate
return None
class LocalFinder(BaseFinder):
def find(self, module_name: str) -> Optional[str]:
if module_name.startswith("."):
return "LOCALFOLDER"
return None
class KnownPatternFinder(BaseFinder):
def __init__(self, config: Config) -> None:
super().__init__(config)
self.known_patterns: List[Tuple[Pattern[str], str]] = []
for placement in reversed(config.sections):
known_placement = KNOWN_SECTION_MAPPING.get(placement, placement).lower()
config_key = f"known_{known_placement}"
known_patterns = list(
getattr(self.config, config_key, self.config.known_other.get(known_placement, []))
)
known_patterns = [
pattern
for known_pattern in known_patterns
for pattern in self._parse_known_pattern(known_pattern)
]
for known_pattern in known_patterns:
sections.FUTURE: "FUTURE_LIBRARY",
sections.FIRSTPARTY: "FIRST_PARTY",
sections.THIRDPARTY: "THIRD_PARTY",
}
class BaseFinder(metaclass=ABCMeta):
def __init__(self, config: Config) -> None:
self.config = config
@abstractmethod
def find(self, module_name: str) -> Optional[str]:
raise NotImplementedError
class ForcedSeparateFinder(BaseFinder):
def find(self, module_name: str) -> Optional[str]:
for forced_separate in self.config.forced_separate:
# Ensure all forced_separate patterns will match to end of string
path_glob = forced_separate
if not forced_separate.endswith("*"):
path_glob = "%s*" % forced_separate
if fnmatch(module_name, path_glob) or fnmatch(module_name, "." + path_glob):
return forced_separate
return None
class LocalFinder(BaseFinder):
def find(self, module_name: str) -> Optional[str]:
if module_name.startswith("."):
return "LOCALFOLDER"
return sections.THIRDPARTY
if "dist-packages" in prefix:
return sections.THIRDPARTY
if self.virtual_env and self.virtual_env_src in prefix:
return sections.THIRDPARTY
if os.path.normcase(prefix) == self.stdlib_lib_prefix:
return sections.STDLIB
if self.conda_env and self.conda_env in prefix:
return sections.THIRDPARTY
if os.path.normcase(prefix).startswith(self.stdlib_lib_prefix):
return sections.STDLIB
return self.config.default_section
return None
class ReqsBaseFinder(BaseFinder):
enabled = False
def __init__(self, config: Config, path: str = ".") -> None:
super().__init__(config)
self.path = path
if self.enabled:
self.mapping = self._load_mapping()
self.names = self._load_names()
@abstractmethod
def _get_names(self, path: str) -> Iterator[str]:
raise NotImplementedError
@abstractmethod
def _get_files_from_dir(self, path: str) -> Iterator[str]:
raise NotImplementedError