brain_fstrings.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. # Copyright (c) 2017-2018, 2020 Claudiu Popa <pcmanticore@gmail.com>
  2. # Copyright (c) 2020-2021 hippo91 <guillaume.peillex@gmail.com>
  3. # Copyright (c) 2020 Karthikeyan Singaravelan <tir.karthi@gmail.com>
  4. # Copyright (c) 2021 Pierre Sassoulas <pierre.sassoulas@gmail.com>
  5. # Copyright (c) 2021 Marc Mueller <30130371+cdce8p@users.noreply.github.com>
  6. # Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
  7. # For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
  8. import collections.abc
  9. from astroid.manager import AstroidManager
  10. from astroid.nodes.node_classes import FormattedValue
  11. def _clone_node_with_lineno(node, parent, lineno):
  12. cls = node.__class__
  13. other_fields = node._other_fields
  14. _astroid_fields = node._astroid_fields
  15. init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent}
  16. postinit_params = {param: getattr(node, param) for param in _astroid_fields}
  17. if other_fields:
  18. init_params.update({param: getattr(node, param) for param in other_fields})
  19. new_node = cls(**init_params)
  20. if hasattr(node, "postinit") and _astroid_fields:
  21. for param, child in postinit_params.items():
  22. if child and not isinstance(child, collections.abc.Sequence):
  23. cloned_child = _clone_node_with_lineno(
  24. node=child, lineno=new_node.lineno, parent=new_node
  25. )
  26. postinit_params[param] = cloned_child
  27. new_node.postinit(**postinit_params)
  28. return new_node
  29. def _transform_formatted_value(node): # pylint: disable=inconsistent-return-statements
  30. if node.value and node.value.lineno == 1:
  31. if node.lineno != node.value.lineno:
  32. new_node = FormattedValue(
  33. lineno=node.lineno, col_offset=node.col_offset, parent=node.parent
  34. )
  35. new_value = _clone_node_with_lineno(
  36. node=node.value, lineno=node.lineno, parent=new_node
  37. )
  38. new_node.postinit(value=new_value, format_spec=node.format_spec)
  39. return new_node
  40. # TODO: this fix tries to *patch* http://bugs.python.org/issue29051
  41. # The problem is that FormattedValue.value, which is a Name node,
  42. # has wrong line numbers, usually 1. This creates problems for pylint,
  43. # which expects correct line numbers for things such as message control.
  44. AstroidManager().register_transform(FormattedValue, _transform_formatted_value)