base_options.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  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. """Functions that creates the basic options for the Run and PyLinter classes."""
  5. from __future__ import annotations
  6. import re
  7. import sys
  8. from typing import TYPE_CHECKING
  9. from pylint import constants, interfaces
  10. from pylint.config.callback_actions import (
  11. _DisableAction,
  12. _DoNothingAction,
  13. _EnableAction,
  14. _ErrorsOnlyModeAction,
  15. _FullDocumentationAction,
  16. _GenerateConfigFileAction,
  17. _GenerateRCFileAction,
  18. _ListCheckGroupsAction,
  19. _ListConfidenceLevelsAction,
  20. _ListExtensionsAction,
  21. _ListMessagesAction,
  22. _ListMessagesEnabledAction,
  23. _LongHelpAction,
  24. _MessageHelpAction,
  25. _OutputFormatAction,
  26. )
  27. from pylint.typing import Options
  28. if TYPE_CHECKING:
  29. from pylint.lint import PyLinter, Run
  30. def _make_linter_options(linter: PyLinter) -> Options:
  31. """Return the options used in a PyLinter class."""
  32. return (
  33. (
  34. "ignore",
  35. {
  36. "type": "csv",
  37. "metavar": "<file>[,<file>...]",
  38. "dest": "black_list",
  39. "kwargs": {"old_names": ["black_list"]},
  40. "default": constants.DEFAULT_IGNORE_LIST,
  41. "help": "Files or directories to be skipped. "
  42. "They should be base names, not paths.",
  43. },
  44. ),
  45. (
  46. "ignore-patterns",
  47. {
  48. "type": "regexp_csv",
  49. "metavar": "<pattern>[,<pattern>...]",
  50. "dest": "black_list_re",
  51. "default": (re.compile(r"^\.#"),),
  52. "help": "Files or directories matching the regular expression patterns are"
  53. " skipped. The regex matches against base names, not paths. The default value "
  54. "ignores Emacs file locks",
  55. },
  56. ),
  57. (
  58. "ignore-paths",
  59. {
  60. "type": "regexp_paths_csv",
  61. "metavar": "<pattern>[,<pattern>...]",
  62. "default": [],
  63. "help": "Add files or directories matching the regular expressions patterns to the "
  64. "ignore-list. The regex matches against paths and can be in "
  65. "Posix or Windows format. Because '\\\\' represents the directory delimiter "
  66. "on Windows systems, it can't be used as an escape character.",
  67. },
  68. ),
  69. (
  70. "persistent",
  71. {
  72. "default": True,
  73. "type": "yn",
  74. "metavar": "<y or n>",
  75. "help": "Pickle collected data for later comparisons.",
  76. },
  77. ),
  78. (
  79. "load-plugins",
  80. {
  81. "type": "csv",
  82. "metavar": "<modules>",
  83. "default": (),
  84. "help": "List of plugins (as comma separated values of "
  85. "python module names) to load, usually to register "
  86. "additional checkers.",
  87. },
  88. ),
  89. (
  90. "output-format",
  91. {
  92. "default": "text",
  93. "action": _OutputFormatAction,
  94. "callback": lambda x: x,
  95. "metavar": "<format>",
  96. "short": "f",
  97. "group": "Reports",
  98. "help": "Set the output format. Available formats are: 'text', "
  99. "'parseable', 'colorized', 'json2' (improved json format), 'json' "
  100. "(old json format), msvs (visual studio) and 'github' (GitHub actions). "
  101. "You can also give a reporter class, e.g. mypackage.mymodule."
  102. "MyReporterClass.",
  103. "kwargs": {"linter": linter},
  104. },
  105. ),
  106. (
  107. "reports",
  108. {
  109. "default": False,
  110. "type": "yn",
  111. "metavar": "<y or n>",
  112. "short": "r",
  113. "group": "Reports",
  114. "help": "Tells whether to display a full report or only the "
  115. "messages.",
  116. },
  117. ),
  118. (
  119. "evaluation",
  120. {
  121. "type": "string",
  122. "metavar": "<python_expression>",
  123. "group": "Reports",
  124. "default": "max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + "
  125. "convention) / statement) * 10))",
  126. "help": "Python expression which should return a score less "
  127. "than or equal to 10. You have access to the variables 'fatal', "
  128. "'error', 'warning', 'refactor', 'convention', and 'info' which "
  129. "contain the number of messages in each category, as well as "
  130. "'statement' which is the total number of statements "
  131. "analyzed. This score is used by the global "
  132. "evaluation report (RP0004).",
  133. },
  134. ),
  135. (
  136. "score",
  137. {
  138. "default": True,
  139. "type": "yn",
  140. "metavar": "<y or n>",
  141. "short": "s",
  142. "group": "Reports",
  143. "help": "Activate the evaluation score.",
  144. },
  145. ),
  146. (
  147. "fail-under",
  148. {
  149. "default": 10,
  150. "type": "float",
  151. "metavar": "<score>",
  152. "help": "Specify a score threshold under which the program will exit with error.",
  153. },
  154. ),
  155. (
  156. "fail-on",
  157. {
  158. "default": "",
  159. "type": "csv",
  160. "metavar": "<msg ids>",
  161. "help": "Return non-zero exit code if any of these messages/categories are detected,"
  162. " even if score is above --fail-under value. Syntax same as enable."
  163. " Messages specified are enabled, while categories only check already-enabled messages.",
  164. },
  165. ),
  166. (
  167. "confidence",
  168. {
  169. "type": "confidence",
  170. "metavar": "<levels>",
  171. "default": interfaces.CONFIDENCE_LEVEL_NAMES,
  172. "group": "Messages control",
  173. "help": "Only show warnings with the listed confidence levels."
  174. f" Leave empty to show all. Valid levels: {', '.join(interfaces.CONFIDENCE_LEVEL_NAMES)}.",
  175. },
  176. ),
  177. (
  178. "enable",
  179. {
  180. "action": _EnableAction,
  181. "callback": lambda x1, x2, x3, x4: x1,
  182. "default": (),
  183. "metavar": "<msg ids>",
  184. "short": "e",
  185. "group": "Messages control",
  186. "help": "Enable the message, report, category or checker with the "
  187. "given id(s). You can either give multiple identifier "
  188. "separated by comma (,) or put this option multiple time "
  189. "(only on the command line, not in the configuration file "
  190. "where it should appear only once). "
  191. 'See also the "--disable" option for examples.',
  192. "kwargs": {"linter": linter},
  193. },
  194. ),
  195. (
  196. "disable",
  197. {
  198. "action": _DisableAction,
  199. "callback": lambda x1, x2, x3, x4: x1,
  200. "metavar": "<msg ids>",
  201. "default": (),
  202. "short": "d",
  203. "group": "Messages control",
  204. "help": "Disable the message, report, category or checker "
  205. "with the given id(s). You can either give multiple identifiers "
  206. "separated by comma (,) or put this option multiple times "
  207. "(only on the command line, not in the configuration file "
  208. "where it should appear only once). "
  209. 'You can also use "--disable=all" to disable everything first '
  210. "and then re-enable specific checks. For example, if you want "
  211. "to run only the similarities checker, you can use "
  212. '"--disable=all --enable=similarities". '
  213. "If you want to run only the classes checker, but have no "
  214. "Warning level messages displayed, use "
  215. '"--disable=all --enable=classes --disable=W".',
  216. "kwargs": {"linter": linter},
  217. },
  218. ),
  219. (
  220. "msg-template",
  221. {
  222. "type": "string",
  223. "default": "",
  224. "metavar": "<template>",
  225. "group": "Reports",
  226. "help": (
  227. "Template used to display messages. "
  228. "This is a python new-style format string "
  229. "used to format the message information. "
  230. "See doc for all details."
  231. ),
  232. },
  233. ),
  234. (
  235. "jobs",
  236. {
  237. "type": "int",
  238. "metavar": "<n-processes>",
  239. "short": "j",
  240. "default": 1,
  241. "help": "Use multiple processes to speed up Pylint. Specifying 0 will "
  242. "auto-detect the number of processors available to use, and will cap "
  243. "the count on Windows to avoid hangs.",
  244. },
  245. ),
  246. (
  247. "unsafe-load-any-extension",
  248. {
  249. "type": "yn",
  250. "metavar": "<y or n>",
  251. "default": False,
  252. "hide": True,
  253. "help": (
  254. "Allow loading of arbitrary C extensions. Extensions"
  255. " are imported into the active Python interpreter and"
  256. " may run arbitrary code."
  257. ),
  258. },
  259. ),
  260. (
  261. "limit-inference-results",
  262. {
  263. "type": "int",
  264. "metavar": "<number-of-results>",
  265. "default": 100,
  266. "help": (
  267. "Control the amount of potential inferred values when inferring "
  268. "a single object. This can help the performance when dealing with "
  269. "large functions or complex, nested conditions."
  270. ),
  271. },
  272. ),
  273. (
  274. "extension-pkg-allow-list",
  275. {
  276. "type": "csv",
  277. "metavar": "<pkg[,pkg]>",
  278. "default": [],
  279. "help": (
  280. "A comma-separated list of package or module names"
  281. " from where C extensions may be loaded. Extensions are"
  282. " loading into the active Python interpreter and may run"
  283. " arbitrary code."
  284. ),
  285. },
  286. ),
  287. (
  288. "extension-pkg-whitelist",
  289. {
  290. "type": "csv",
  291. "metavar": "<pkg[,pkg]>",
  292. "default": [],
  293. "help": (
  294. "A comma-separated list of package or module names"
  295. " from where C extensions may be loaded. Extensions are"
  296. " loading into the active Python interpreter and may run"
  297. " arbitrary code. (This is an alternative name to"
  298. " extension-pkg-allow-list for backward compatibility.)"
  299. ),
  300. },
  301. ),
  302. (
  303. "exit-zero",
  304. {
  305. "action": "store_true",
  306. "default": False,
  307. "metavar": "<flag>",
  308. "help": (
  309. "Always return a 0 (non-error) status code, even if "
  310. "lint errors are found. This is primarily useful in "
  311. "continuous integration scripts."
  312. ),
  313. },
  314. ),
  315. (
  316. "from-stdin",
  317. {
  318. "action": "store_true",
  319. "default": False,
  320. "metavar": "<flag>",
  321. "help": (
  322. "Interpret the stdin as a python script, whose filename "
  323. "needs to be passed as the module_or_package argument."
  324. ),
  325. },
  326. ),
  327. (
  328. "source-roots",
  329. {
  330. "type": "glob_paths_csv",
  331. "metavar": "<path>[,<path>...]",
  332. "default": (),
  333. "help": "Add paths to the list of the source roots. Supports globbing patterns. "
  334. "The source root is an absolute path or a path relative to the current working "
  335. "directory used to determine a package namespace for modules located under the "
  336. "source root.",
  337. },
  338. ),
  339. (
  340. "recursive",
  341. {
  342. "type": "yn",
  343. "metavar": "<yn>",
  344. "default": False,
  345. "help": "Discover python modules and packages in the file system subtree.",
  346. },
  347. ),
  348. (
  349. "py-version",
  350. {
  351. "default": sys.version_info[:2],
  352. "type": "py_version",
  353. "metavar": "<py_version>",
  354. "help": (
  355. "Minimum Python version to use for version dependent checks. "
  356. "Will default to the version used to run pylint."
  357. ),
  358. },
  359. ),
  360. (
  361. "ignored-modules",
  362. {
  363. "default": (),
  364. "type": "csv",
  365. "metavar": "<module names>",
  366. "help": "List of module names for which member attributes "
  367. "should not be checked and will not be imported "
  368. "(useful for modules/projects "
  369. "where namespaces are manipulated during runtime and "
  370. "thus existing member attributes cannot be "
  371. "deduced by static analysis). It supports qualified "
  372. "module names, as well as Unix pattern matching.",
  373. },
  374. ),
  375. (
  376. "analyse-fallback-blocks",
  377. {
  378. "default": False,
  379. "type": "yn",
  380. "metavar": "<y or n>",
  381. "help": "Analyse import fallback blocks. This can be used to "
  382. "support both Python 2 and 3 compatible code, which "
  383. "means that the block might have code that exists "
  384. "only in one or another interpreter, leading to false "
  385. "positives when analysed.",
  386. },
  387. ),
  388. (
  389. "clear-cache-post-run",
  390. {
  391. "default": False,
  392. "type": "yn",
  393. "metavar": "<y or n>",
  394. "help": "Clear in-memory caches upon conclusion of linting. "
  395. "Useful if running pylint in a server-like mode.",
  396. },
  397. ),
  398. (
  399. "prefer-stubs",
  400. {
  401. "default": False,
  402. "type": "yn",
  403. "metavar": "<y or n>",
  404. "help": "Resolve imports to .pyi stubs if available. May "
  405. "reduce no-member messages and increase not-an-iterable "
  406. "messages.",
  407. },
  408. ),
  409. )
  410. def _make_run_options(self: Run) -> Options:
  411. """Return the options used in a Run class."""
  412. return (
  413. (
  414. "rcfile",
  415. {
  416. "action": _DoNothingAction,
  417. "kwargs": {},
  418. "group": "Commands",
  419. "help": "Specify a configuration file to load.",
  420. "hide_from_config_file": True,
  421. },
  422. ),
  423. (
  424. "output",
  425. {
  426. "action": _DoNothingAction,
  427. "kwargs": {},
  428. "group": "Commands",
  429. "help": "Specify an output file.",
  430. "hide_from_config_file": True,
  431. },
  432. ),
  433. (
  434. "init-hook",
  435. {
  436. "action": _DoNothingAction,
  437. "kwargs": {},
  438. "help": "Python code to execute, usually for sys.path "
  439. "manipulation such as pygtk.require().",
  440. },
  441. ),
  442. (
  443. "help-msg",
  444. {
  445. "action": _MessageHelpAction,
  446. "kwargs": {"Run": self},
  447. "group": "Commands",
  448. "help": "Display a help message for the given message id and "
  449. "exit. The value may be a comma separated list of message ids.",
  450. "hide_from_config_file": True,
  451. },
  452. ),
  453. (
  454. "list-msgs",
  455. {
  456. "action": _ListMessagesAction,
  457. "kwargs": {"Run": self},
  458. "group": "Commands",
  459. "help": "Display a list of all pylint's messages divided by whether "
  460. "they are emittable with the given interpreter.",
  461. "hide_from_config_file": True,
  462. },
  463. ),
  464. (
  465. "list-msgs-enabled",
  466. {
  467. "action": _ListMessagesEnabledAction,
  468. "kwargs": {"Run": self},
  469. "group": "Commands",
  470. "help": "Display a list of what messages are enabled, "
  471. "disabled and non-emittable with the given configuration.",
  472. "hide_from_config_file": True,
  473. },
  474. ),
  475. (
  476. "list-groups",
  477. {
  478. "action": _ListCheckGroupsAction,
  479. "kwargs": {"Run": self},
  480. "group": "Commands",
  481. "help": "List pylint's message groups.",
  482. "hide_from_config_file": True,
  483. },
  484. ),
  485. (
  486. "list-conf-levels",
  487. {
  488. "action": _ListConfidenceLevelsAction,
  489. "kwargs": {"Run": self},
  490. "group": "Commands",
  491. "help": "Generate pylint's confidence levels.",
  492. "hide_from_config_file": True,
  493. },
  494. ),
  495. (
  496. "list-extensions",
  497. {
  498. "action": _ListExtensionsAction,
  499. "kwargs": {"Run": self},
  500. "group": "Commands",
  501. "help": "List available extensions.",
  502. "hide_from_config_file": True,
  503. },
  504. ),
  505. (
  506. "full-documentation",
  507. {
  508. "action": _FullDocumentationAction,
  509. "kwargs": {"Run": self},
  510. "group": "Commands",
  511. "help": "Generate pylint's full documentation.",
  512. "hide_from_config_file": True,
  513. },
  514. ),
  515. (
  516. "generate-rcfile",
  517. {
  518. "action": _GenerateRCFileAction,
  519. "kwargs": {"Run": self},
  520. "group": "Commands",
  521. "help": "Generate a sample configuration file according to "
  522. "the current configuration. You can put other options "
  523. "before this one to get them in the generated "
  524. "configuration.",
  525. "hide_from_config_file": True,
  526. },
  527. ),
  528. (
  529. "generate-toml-config",
  530. {
  531. "action": _GenerateConfigFileAction,
  532. "kwargs": {"Run": self},
  533. "group": "Commands",
  534. "help": "Generate a sample configuration file according to "
  535. "the current configuration. You can put other options "
  536. "before this one to get them in the generated "
  537. "configuration. The config is in the .toml format.",
  538. "hide_from_config_file": True,
  539. },
  540. ),
  541. (
  542. "errors-only",
  543. {
  544. "action": _ErrorsOnlyModeAction,
  545. "kwargs": {"Run": self},
  546. "short": "E",
  547. "help": "In error mode, messages with a category besides "
  548. "ERROR or FATAL are suppressed, and no reports are done by default. "
  549. "Error mode is compatible with disabling specific errors. ",
  550. "hide_from_config_file": True,
  551. },
  552. ),
  553. (
  554. "verbose",
  555. {
  556. "action": _DoNothingAction,
  557. "kwargs": {},
  558. "short": "v",
  559. "help": "In verbose mode, extra non-checker-related info "
  560. "will be displayed.",
  561. "hide_from_config_file": True,
  562. "metavar": "",
  563. },
  564. ),
  565. (
  566. "enable-all-extensions",
  567. {
  568. "action": _DoNothingAction,
  569. "kwargs": {},
  570. "help": "Load and enable all available extensions. "
  571. "Use --list-extensions to see a list all available extensions.",
  572. "hide_from_config_file": True,
  573. "metavar": "",
  574. },
  575. ),
  576. (
  577. "long-help",
  578. {
  579. "action": _LongHelpAction,
  580. "kwargs": {"Run": self},
  581. "help": "Show more verbose help.",
  582. "group": "Commands",
  583. "hide_from_config_file": True,
  584. },
  585. ),
  586. )