__init__.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. __all__ = [
  6. "__version__",
  7. "modify_sys_path",
  8. "run_pylint",
  9. "run_pyreverse",
  10. "run_symilar",
  11. "version",
  12. ]
  13. import os
  14. import sys
  15. from collections.abc import Sequence
  16. from typing import NoReturn
  17. from pylint.__pkginfo__ import __version__
  18. # pylint: disable=import-outside-toplevel
  19. def run_pylint(argv: Sequence[str] | None = None) -> None:
  20. """Run pylint.
  21. argv can be a sequence of strings normally supplied as arguments on the command line
  22. """
  23. from pylint.lint import Run as PylintRun
  24. try:
  25. PylintRun(argv or sys.argv[1:])
  26. except KeyboardInterrupt:
  27. sys.exit(1)
  28. def _run_pylint_config(argv: Sequence[str] | None = None) -> None:
  29. """Run pylint-config.
  30. argv can be a sequence of strings normally supplied as arguments on the command line
  31. """
  32. from pylint.lint.run import _PylintConfigRun
  33. _PylintConfigRun(argv or sys.argv[1:])
  34. def run_pyreverse(argv: Sequence[str] | None = None) -> NoReturn:
  35. """Run pyreverse.
  36. argv can be a sequence of strings normally supplied as arguments on the command line
  37. """
  38. from pylint.pyreverse.main import Run as PyreverseRun
  39. sys.exit(PyreverseRun(argv or sys.argv[1:]).run())
  40. def run_symilar(argv: Sequence[str] | None = None) -> NoReturn:
  41. """Run symilar.
  42. argv can be a sequence of strings normally supplied as arguments on the command line
  43. """
  44. from pylint.checkers.symilar import Run as SymilarRun
  45. SymilarRun(argv or sys.argv[1:])
  46. def modify_sys_path() -> None:
  47. """Modify sys path for execution as Python module.
  48. Strip out the current working directory from sys.path.
  49. Having the working directory in `sys.path` means that `pylint` might
  50. inadvertently import user code from modules having the same name as
  51. stdlib or pylint's own modules.
  52. CPython issue: https://bugs.python.org/issue33053
  53. - Remove the first entry. This will always be either "" or the working directory
  54. - Remove the working directory from the second and third entries
  55. if PYTHONPATH includes a ":" at the beginning or the end.
  56. https://github.com/pylint-dev/pylint/issues/3636
  57. Don't remove it if PYTHONPATH contains the cwd or '.' as the entry will
  58. only be added once.
  59. - Don't remove the working directory from the rest. It will be included
  60. if pylint is installed in an editable configuration (as the last item).
  61. https://github.com/pylint-dev/pylint/issues/4161
  62. """
  63. cwd = os.getcwd()
  64. if sys.path[0] in ("", ".", cwd):
  65. sys.path.pop(0)
  66. env_pythonpath = os.environ.get("PYTHONPATH", "")
  67. if env_pythonpath.startswith(":") and env_pythonpath not in (f":{cwd}", ":."):
  68. sys.path.pop(0)
  69. elif env_pythonpath.endswith(":") and env_pythonpath not in (f"{cwd}:", ".:"):
  70. sys.path.pop(1)
  71. def _catch_valueerror(unraisable: sys.UnraisableHookArgs) -> None: # pragma: no cover
  72. """Overwrite sys.unraisablehook to catch incorrect ValueError.
  73. Python 3.12 introduced changes that sometimes cause astroid to emit ValueErrors
  74. with 'generator already executing'. Fixed in Python 3.12.3 and 3.13.
  75. https://github.com/pylint-dev/pylint/issues/9138
  76. """
  77. if (
  78. isinstance(unraisable.exc_value, ValueError)
  79. and unraisable.exc_value.args[0] == "generator already executing"
  80. ):
  81. return
  82. sys.__unraisablehook__(unraisable)
  83. if (3, 12, 0) <= sys.version_info[:3] < (3, 12, 3) or sys.version_info >= (3, 12, 5):
  84. sys.unraisablehook = _catch_valueerror
  85. version = __version__