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

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. 

5 

6from dataclasses import dataclass, replace 

7from typing import Optional 

8 

9from libcst.helpers import get_absolute_module_from_package 

10 

11 

12@dataclass(frozen=True) 

13class ImportItem: 

14 """Representation of individual import items for codemods.""" 

15 

16 module_name: str 

17 obj_name: Optional[str] = None 

18 alias: Optional[str] = None 

19 relative: int = 0 

20 

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) 

29 

30 @property 

31 def module(self) -> str: 

32 return "." * self.relative + self.module_name 

33 

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)