brain_pathlib.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. # Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
  2. # For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
  3. # Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt
  4. from __future__ import annotations
  5. from collections.abc import Iterator
  6. from astroid import bases, context, inference_tip, nodes
  7. from astroid.builder import _extract_single_node
  8. from astroid.exceptions import InferenceError, UseInferenceDefault
  9. from astroid.manager import AstroidManager
  10. PATH_TEMPLATE = """
  11. from pathlib import Path
  12. Path
  13. """
  14. def _looks_like_parents_subscript(node: nodes.Subscript) -> bool:
  15. if not (
  16. isinstance(node.value, nodes.Attribute) and node.value.attrname == "parents"
  17. ):
  18. return False
  19. try:
  20. value = next(node.value.infer())
  21. except (InferenceError, StopIteration):
  22. return False
  23. return (
  24. isinstance(value, bases.Instance)
  25. and isinstance(value._proxied, nodes.ClassDef)
  26. and value.qname() == "pathlib._PathParents"
  27. )
  28. def infer_parents_subscript(
  29. subscript_node: nodes.Subscript, ctx: context.InferenceContext | None = None
  30. ) -> Iterator[bases.Instance]:
  31. if isinstance(subscript_node.slice, nodes.Const):
  32. path_cls = next(_extract_single_node(PATH_TEMPLATE).infer())
  33. return iter([path_cls.instantiate_class()])
  34. raise UseInferenceDefault
  35. AstroidManager().register_transform(
  36. nodes.Subscript,
  37. inference_tip(infer_parents_subscript),
  38. _looks_like_parents_subscript,
  39. )