constants.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  2. # For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
  3. # Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
  4. from __future__ import annotations
  5. import os
  6. import platform
  7. import sys
  8. import astroid
  9. import platformdirs
  10. from pylint.__pkginfo__ import __version__
  11. from pylint.typing import MessageTypesFullName
  12. PY311_PLUS = sys.version_info[:2] >= (3, 11)
  13. PY312_PLUS = sys.version_info[:2] >= (3, 12)
  14. PY314_PLUS = sys.version_info[:2] >= (3, 14)
  15. IS_PYPY = platform.python_implementation() == "PyPy"
  16. PY_EXTS = (".py", ".pyc", ".pyo", ".pyw", ".so", ".dll")
  17. MSG_STATE_CONFIDENCE = 2
  18. _MSG_ORDER = "EWRCIF"
  19. MSG_STATE_SCOPE_CONFIG = 0
  20. MSG_STATE_SCOPE_MODULE = 1
  21. # The line/node distinction does not apply to fatal errors and reports.
  22. _SCOPE_EXEMPT = "FR"
  23. MSG_TYPES: dict[str, MessageTypesFullName] = {
  24. "I": "info",
  25. "C": "convention",
  26. "R": "refactor",
  27. "W": "warning",
  28. "E": "error",
  29. "F": "fatal",
  30. }
  31. MSG_TYPES_LONG: dict[str, str] = {v: k for k, v in MSG_TYPES.items()}
  32. MSG_TYPES_STATUS = {"I": 0, "C": 16, "R": 8, "W": 4, "E": 2, "F": 1}
  33. # You probably don't want to change the MAIN_CHECKER_NAME
  34. # This would affect rcfile generation and retro-compatibility
  35. # on all project using [MAIN] in their rcfile.
  36. MAIN_CHECKER_NAME = "main"
  37. DEFAULT_PYLINT_HOME = platformdirs.user_cache_dir("pylint")
  38. DEFAULT_IGNORE_LIST = ("CVS",)
  39. class WarningScope:
  40. LINE = "line-based-msg"
  41. NODE = "node-based-msg"
  42. full_version = f"""pylint {__version__}
  43. astroid {astroid.__version__}
  44. Python {sys.version}"""
  45. HUMAN_READABLE_TYPES = {
  46. "file": "file",
  47. "module": "module",
  48. "const": "constant",
  49. "class": "class",
  50. "function": "function",
  51. "method": "method",
  52. "attr": "attribute",
  53. "argument": "argument",
  54. "variable": "variable",
  55. "class_attribute": "class attribute",
  56. "class_const": "class constant",
  57. "inlinevar": "inline iteration",
  58. "typevar": "type variable",
  59. "paramspec": "parameter specification variable",
  60. "typevartuple": "type variable tuple",
  61. "typealias": "type alias",
  62. }
  63. # ignore some messages when emitting useless-suppression:
  64. # - cyclic-import: can show false positives due to incomplete context
  65. # - deprecated-{module, argument, class, method, decorator}:
  66. # can cause false positives for multi-interpreter projects
  67. # when linting with an interpreter on a lower python version
  68. INCOMPATIBLE_WITH_USELESS_SUPPRESSION = frozenset(
  69. [
  70. "R0401", # cyclic-import
  71. "W0402", # deprecated-module
  72. "W1505", # deprecated-method
  73. "W1511", # deprecated-argument
  74. "W1512", # deprecated-class
  75. "W1513", # deprecated-decorator
  76. "R0801", # duplicate-code
  77. ]
  78. )
  79. def _get_pylint_home() -> str:
  80. """Return the pylint home."""
  81. if "PYLINTHOME" in os.environ:
  82. return os.environ["PYLINTHOME"]
  83. return DEFAULT_PYLINT_HOME
  84. PYLINT_HOME = _get_pylint_home()
  85. TYPING_NORETURN = frozenset(
  86. (
  87. "typing.NoReturn",
  88. "typing_extensions.NoReturn",
  89. )
  90. )
  91. TYPING_NEVER = frozenset(
  92. (
  93. "typing.Never",
  94. "typing_extensions.Never",
  95. )
  96. )
  97. DUNDER_METHODS: dict[tuple[int, int], dict[str, str]] = {
  98. (0, 0): {
  99. "__init__": "Instantiate class directly",
  100. "__del__": "Use del keyword",
  101. "__repr__": "Use repr built-in function",
  102. "__str__": "Use str built-in function",
  103. "__bytes__": "Use bytes built-in function",
  104. "__format__": "Use format built-in function, format string method, or f-string",
  105. "__lt__": "Use < operator",
  106. "__le__": "Use <= operator",
  107. "__eq__": "Use == operator",
  108. "__ne__": "Use != operator",
  109. "__gt__": "Use > operator",
  110. "__ge__": "Use >= operator",
  111. "__hash__": "Use hash built-in function",
  112. "__bool__": "Use bool built-in function",
  113. "__getattr__": "Access attribute directly or use getattr built-in function",
  114. "__getattribute__": "Access attribute directly or use getattr built-in function",
  115. "__setattr__": "Set attribute directly or use setattr built-in function",
  116. "__delattr__": "Use del keyword",
  117. "__dir__": "Use dir built-in function",
  118. "__get__": "Use get method",
  119. "__set__": "Use set method",
  120. "__delete__": "Use del keyword",
  121. "__instancecheck__": "Use isinstance built-in function",
  122. "__subclasscheck__": "Use issubclass built-in function",
  123. "__call__": "Invoke instance directly",
  124. "__len__": "Use len built-in function",
  125. "__length_hint__": "Use length_hint method",
  126. "__getitem__": "Access item via subscript",
  127. "__setitem__": "Set item via subscript",
  128. "__delitem__": "Use del keyword",
  129. "__iter__": "Use iter built-in function",
  130. "__next__": "Use next built-in function",
  131. "__reversed__": "Use reversed built-in function",
  132. "__contains__": "Use in keyword",
  133. "__add__": "Use + operator",
  134. "__sub__": "Use - operator",
  135. "__mul__": "Use * operator",
  136. "__matmul__": "Use @ operator",
  137. "__truediv__": "Use / operator",
  138. "__floordiv__": "Use // operator",
  139. "__mod__": "Use % operator",
  140. "__divmod__": "Use divmod built-in function",
  141. "__pow__": "Use ** operator or pow built-in function",
  142. "__lshift__": "Use << operator",
  143. "__rshift__": "Use >> operator",
  144. "__and__": "Use & operator",
  145. "__xor__": "Use ^ operator",
  146. "__or__": "Use | operator",
  147. "__radd__": "Use + operator",
  148. "__rsub__": "Use - operator",
  149. "__rmul__": "Use * operator",
  150. "__rmatmul__": "Use @ operator",
  151. "__rtruediv__": "Use / operator",
  152. "__rfloordiv__": "Use // operator",
  153. "__rmod__": "Use % operator",
  154. "__rdivmod__": "Use divmod built-in function",
  155. "__rpow__": "Use ** operator or pow built-in function",
  156. "__rlshift__": "Use << operator",
  157. "__rrshift__": "Use >> operator",
  158. "__rand__": "Use & operator",
  159. "__rxor__": "Use ^ operator",
  160. "__ror__": "Use | operator",
  161. "__iadd__": "Use += operator",
  162. "__isub__": "Use -= operator",
  163. "__imul__": "Use *= operator",
  164. "__imatmul__": "Use @= operator",
  165. "__itruediv__": "Use /= operator",
  166. "__ifloordiv__": "Use //= operator",
  167. "__imod__": "Use %= operator",
  168. "__ipow__": "Use **= operator",
  169. "__ilshift__": "Use <<= operator",
  170. "__irshift__": "Use >>= operator",
  171. "__iand__": "Use &= operator",
  172. "__ixor__": "Use ^= operator",
  173. "__ior__": "Use |= operator",
  174. "__neg__": "Multiply by -1 instead",
  175. "__pos__": "Multiply by +1 instead",
  176. "__abs__": "Use abs built-in function",
  177. "__invert__": "Use ~ operator",
  178. "__complex__": "Use complex built-in function",
  179. "__int__": "Use int built-in function",
  180. "__float__": "Use float built-in function",
  181. "__round__": "Use round built-in function",
  182. "__trunc__": "Use math.trunc function",
  183. "__floor__": "Use math.floor function",
  184. "__ceil__": "Use math.ceil function",
  185. "__enter__": "Invoke context manager directly",
  186. "__aenter__": "Invoke context manager directly",
  187. "__copy__": "Use copy.copy function",
  188. "__deepcopy__": "Use copy.deepcopy function",
  189. "__fspath__": "Use os.fspath function instead",
  190. },
  191. (3, 10): {
  192. "__aiter__": "Use aiter built-in function",
  193. "__anext__": "Use anext built-in function",
  194. },
  195. }
  196. EXTRA_DUNDER_METHODS: dict[tuple[int, int], list[str]] = {
  197. (0, 0): [
  198. "__new__",
  199. "__subclasses__",
  200. "__init_subclass__",
  201. "__set_name__",
  202. "__class_getitem__",
  203. "__missing__",
  204. "__exit__",
  205. "__await__",
  206. "__aexit__",
  207. "__getnewargs_ex__",
  208. "__getnewargs__",
  209. "__getstate__",
  210. "__index__",
  211. "__setstate__",
  212. "__reduce__",
  213. "__reduce_ex__",
  214. "__post_init__", # part of `dataclasses` module
  215. "_generate_next_value_",
  216. "_missing_",
  217. "_numeric_repr_",
  218. ],
  219. (3, 13): ["_add_alias_", "_add_value_alias_"],
  220. }
  221. DUNDER_PROPERTIES = [
  222. "__class__",
  223. "__dict__",
  224. "__doc__",
  225. "__format__",
  226. "__module__",
  227. "__sizeof__",
  228. "__subclasshook__",
  229. "__weakref__",
  230. ]
  231. # C2801 rule exceptions as their corresponding function/method/operator
  232. # is not valid python syntax in a lambda definition
  233. UNNECESSARY_DUNDER_CALL_LAMBDA_EXCEPTIONS = [
  234. "__init__",
  235. "__del__",
  236. "__delattr__",
  237. "__set__",
  238. "__delete__",
  239. "__setitem__",
  240. "__delitem__",
  241. "__iadd__",
  242. "__isub__",
  243. "__imul__",
  244. "__imatmul__",
  245. "__itruediv__",
  246. "__ifloordiv__",
  247. "__imod__",
  248. "__ipow__",
  249. "__ilshift__",
  250. "__irshift__",
  251. "__iand__",
  252. "__ixor__",
  253. "__ior__",
  254. ]
  255. MAX_NUMBER_OF_IMPORT_SHOWN = 6