Coverage for C:\Repos\ekr-pylint\pylint\lint\utils.py: 32%

44 statements  

« prev     ^ index     » next       coverage.py v6.4, created at 2022-05-24 10:21 -0500

1# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html 

2# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE 

3# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt 

4 

5from __future__ import annotations 

6 

7import contextlib 

8import sys 

9import traceback 

10from collections.abc import Iterator, Sequence 

11from datetime import datetime 

12from pathlib import Path 

13 

14from pylint.config import PYLINT_HOME 

15from pylint.lint.expand_modules import get_python_path 

16 

17 

18def prepare_crash_report(ex: Exception, filepath: str, crash_file_path: str) -> Path: 

19 issue_template_path = ( 

20 Path(PYLINT_HOME) / datetime.now().strftime(str(crash_file_path)) 

21 ).resolve() 

22 with open(filepath, encoding="utf8") as f: 

23 file_content = f.read() 

24 template = "" 

25 if not issue_template_path.exists(): 

26 template = """\ 

27First, please verify that the bug is not already filled: 

28https://github.com/PyCQA/pylint/issues/ 

29 

30Then create a new crash issue: 

31https://github.com/PyCQA/pylint/issues/new?assignees=&labels=crash%2Cneeds+triage&template=BUG-REPORT.yml 

32 

33""" 

34 template += f"""\ 

35 

36Issue title: 

37Crash ``{ex}`` (if possible, be more specific about what made pylint crash) 

38Content: 

39When parsing the following file: 

40 

41<!-- 

42 If sharing the code is not an option, please state so, 

43 but providing only the stacktrace would still be helpful. 

44 --> 

45 

46```python 

47{file_content} 

48``` 

49 

50pylint crashed with a ``{ex.__class__.__name__}`` and with the following stacktrace: 

51``` 

52""" 

53 template += traceback.format_exc() 

54 template += "```\n" 

55 try: 

56 with open(issue_template_path, "a", encoding="utf8") as f: 

57 f.write(template) 

58 except Exception as exc: # pylint: disable=broad-except 

59 print( 

60 f"Can't write the issue template for the crash in {issue_template_path} " 

61 f"because of: '{exc}'\nHere's the content anyway:\n{template}." 

62 ) 

63 return issue_template_path 

64 

65 

66def get_fatal_error_message(filepath: str, issue_template_path: Path) -> str: 

67 return ( 

68 f"Fatal error while checking '{filepath}'. " 

69 f"Please open an issue in our bug tracker so we address this. " 

70 f"There is a pre-filled template that you can use in '{issue_template_path}'." 

71 ) 

72 

73 

74def _patch_sys_path(args: Sequence[str]) -> list[str]: 

75 original = list(sys.path) 

76 changes = [] 

77 seen = set() 

78 for arg in args: 

79 path = get_python_path(arg) 

80 if path not in seen: 

81 changes.append(path) 

82 seen.add(path) 

83 

84 sys.path[:] = changes + sys.path 

85 return original 

86 

87 

88@contextlib.contextmanager 

89def fix_import_path(args: Sequence[str]) -> Iterator[None]: 

90 """Prepare 'sys.path' for running the linter checks. 

91 

92 Within this context, each of the given arguments is importable. 

93 Paths are added to 'sys.path' in corresponding order to the arguments. 

94 We avoid adding duplicate directories to sys.path. 

95 `sys.path` is reset to its original value upon exiting this context. 

96 """ 

97 original = _patch_sys_path(args) 

98 try: 

99 yield 

100 finally: 

101 sys.path[:] = original