Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/libcst/codemod/visitors/_imports.py: 46%
28 statements
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-25 06:43 +0000
« prev ^ index » next coverage.py v7.3.1, created at 2023-09-25 06:43 +0000
1# Copyright (c) Meta Platforms, Inc. and affiliates.
2#
3# This source code is licensed under the MIT license found in the
4# LICENSE file in the root directory of this source tree.
6from dataclasses import dataclass, replace
7from typing import Optional
9from libcst.helpers import get_absolute_module_from_package
12@dataclass(frozen=True)
13class ImportItem:
14 """Representation of individual import items for codemods."""
16 module_name: str
17 obj_name: Optional[str] = None
18 alias: Optional[str] = None
19 relative: int = 0
21 def __post_init__(self) -> None:
22 if self.module_name is None:
23 object.__setattr__(self, "module_name", "")
24 elif self.module_name.startswith("."):
25 mod = self.module_name.lstrip(".")
26 rel = self.relative + len(self.module_name) - len(mod)
27 object.__setattr__(self, "module_name", mod)
28 object.__setattr__(self, "relative", rel)
30 @property
31 def module(self) -> str:
32 return "." * self.relative + self.module_name
34 def resolve_relative(self, package_name: Optional[str]) -> "ImportItem":
35 """Return an ImportItem with an absolute module name if possible."""
36 mod = self
37 # `import ..a` -> `from .. import a`
38 if mod.relative and mod.obj_name is None:
39 mod = replace(mod, module_name="", obj_name=mod.module_name)
40 if package_name is None:
41 return mod
42 m = get_absolute_module_from_package(
43 package_name, mod.module_name or None, self.relative
44 )
45 return mod if m is None else replace(mod, module_name=m, relative=0)