python-ta 2.8.0__tar.gz → 2.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. {python_ta-2.8.0/python_ta.egg-info → python_ta-2.9.0}/PKG-INFO +162 -159
  2. {python_ta-2.8.0 → python_ta-2.9.0}/README.md +1 -0
  3. {python_ta-2.8.0 → python_ta-2.9.0}/pyproject.toml +6 -4
  4. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/__init__.py +10 -11
  5. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/__main__.py +4 -2
  6. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/cfg/cfg_generator.py +26 -7
  7. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/cfg/graph.py +86 -36
  8. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/cfg/visitor.py +2 -1
  9. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/global_variables_checker.py +3 -2
  10. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/inconsistent_or_missing_returns_checker.py +20 -0
  11. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/invalid_name_checker.py +11 -9
  12. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/one_iteration_checker.py +24 -0
  13. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/possibly_undefined_checker.py +31 -8
  14. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/pycodestyle_checker.py +2 -2
  15. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/redundant_assignment_checker.py +64 -15
  16. python_ta-2.9.0/python_ta/checkers/unmentioned_parameter_checker.py +54 -0
  17. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/unnecessary_indexing_checker.py +4 -2
  18. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/config/.pylintrc +2 -1
  19. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/contracts/__init__.py +92 -17
  20. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/contracts/__main__.py +6 -4
  21. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/debug/__init__.py +1 -0
  22. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/debug/snapshot.py +53 -6
  23. python_ta-2.9.0/python_ta/debug/snapshot_tracer.py +181 -0
  24. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/patches/__init__.py +2 -2
  25. python_ta-2.9.0/python_ta/patches/transforms.py +36 -0
  26. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/core.py +7 -5
  27. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/json_reporter.py +4 -3
  28. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/node_printers.py +3 -3
  29. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/plain_reporter.py +2 -2
  30. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/stat_reporter.py +1 -1
  31. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/transforms/z3_visitor.py +7 -5
  32. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/upload.py +5 -3
  33. python_ta-2.9.0/python_ta/util/__init__.py +0 -0
  34. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/utils.py +0 -11
  35. python_ta-2.9.0/python_ta/z3/__init__.py +0 -0
  36. python_ta-2.8.0/python_ta/transforms/ExprWrapper.py → python_ta-2.9.0/python_ta/z3/z3_parser.py +27 -33
  37. {python_ta-2.8.0 → python_ta-2.9.0/python_ta.egg-info}/PKG-INFO +162 -159
  38. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta.egg-info/SOURCES.txt +4 -1
  39. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta.egg-info/not-zip-safe +1 -1
  40. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta.egg-info/requires.txt +5 -3
  41. {python_ta-2.8.0 → python_ta-2.9.0}/setup.cfg +4 -4
  42. {python_ta-2.8.0 → python_ta-2.9.0}/tests/test_check.py +1 -9
  43. {python_ta-2.8.0 → python_ta-2.9.0}/tests/test_examples.py +10 -7
  44. {python_ta-2.8.0 → python_ta-2.9.0}/tests/test_init_logging.py +0 -12
  45. {python_ta-2.8.0 → python_ta-2.9.0}/tests/test_setendings.py +19 -19
  46. {python_ta-2.8.0 → python_ta-2.9.0}/tests/test_subclass_contracts.py +2 -0
  47. {python_ta-2.8.0 → python_ta-2.9.0}/tests/test_validate_invariants.py +2 -0
  48. python_ta-2.8.0/python_ta/patches/transforms.py +0 -21
  49. python_ta-2.8.0/python_ta/transforms/__init__.py +0 -1
  50. {python_ta-2.8.0 → python_ta-2.9.0}/LICENSE +0 -0
  51. {python_ta-2.8.0 → python_ta-2.9.0}/MANIFEST.in +0 -0
  52. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/cfg/__init__.py +0 -0
  53. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/__init__.py +0 -0
  54. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/forbidden_import_checker.py +0 -0
  55. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/forbidden_io_function_checker.py +0 -0
  56. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/forbidden_python_syntax_checker.py +0 -0
  57. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/invalid_for_target_checker.py +0 -0
  58. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/invalid_range_index_checker.py +0 -0
  59. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/missing_space_in_doctest_checker.py +0 -0
  60. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/shadowing_in_comprehension_checker.py +0 -0
  61. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/top_level_code_checker.py +0 -0
  62. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/checkers/type_annotation_checker.py +0 -0
  63. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/config/__init__.py +0 -0
  64. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/config/messages_config.toml +0 -0
  65. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/debug/accumulation_table.py +0 -0
  66. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/debug/recursion_table.py +0 -0
  67. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/patches/checkers.py +0 -0
  68. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/patches/error_messages.py +0 -0
  69. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/patches/messages.py +0 -0
  70. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/__init__.py +0 -0
  71. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/color_reporter.py +0 -0
  72. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/html_reporter.py +0 -0
  73. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/templates/jquery-3.7.1.slim.min.js +0 -0
  74. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/templates/pyta_logo_markdown.png +0 -0
  75. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/templates/script.js +0 -0
  76. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/templates/stylesheet.css +0 -0
  77. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/reporters/templates/template.html.jinja +0 -0
  78. {python_ta-2.8.0/python_ta/util → python_ta-2.9.0/python_ta/transforms}/__init__.py +0 -0
  79. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/transforms/setendings.py +0 -0
  80. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta/util/tree.py +0 -0
  81. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta.egg-info/dependency_links.txt +0 -0
  82. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta.egg-info/entry_points.txt +0 -0
  83. {python_ta-2.8.0 → python_ta-2.9.0}/python_ta.egg-info/top_level.txt +0 -0
  84. {python_ta-2.8.0 → python_ta-2.9.0}/setup.py +0 -0
  85. {python_ta-2.8.0 → python_ta-2.9.0}/tests/test_black.py +0 -0
  86. {python_ta-2.8.0 → python_ta-2.9.0}/tests/test_main.py +0 -0
  87. {python_ta-2.8.0 → python_ta-2.9.0}/tests/test_z3_visitor.py +0 -0
@@ -1,159 +1,162 @@
1
- Metadata-Version: 2.1
2
- Name: python-ta
3
- Version: 2.8.0
4
- Summary: Code checking tool for teaching Python
5
- Author-email: David Liu <david@cs.toronto.edu>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/pyta-uoft/pyta
8
- Project-URL: Documentation, https://www.cs.toronto.edu/~david/pyta/
9
- Project-URL: Repository, https://github.com/pyta-uoft/pyta.git
10
- Project-URL: Changelog, https://github.com/pyta-uoft/pyta/blob/master/CHANGELOG.md
11
- Requires-Python: >=3.8
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: astroid~=3.2.4
15
- Requires-Dist: click<9,>=8.0.1
16
- Requires-Dist: colorama~=0.4.6
17
- Requires-Dist: jinja2~=3.1.2
18
- Requires-Dist: pycodestyle~=2.11
19
- Requires-Dist: pygments<2.19,>=2.14
20
- Requires-Dist: pylint~=3.2.6
21
- Requires-Dist: requests<2.33,>=2.28
22
- Requires-Dist: six
23
- Requires-Dist: tabulate~=0.9.0
24
- Requires-Dist: toml~=0.10.2
25
- Requires-Dist: typeguard<5,>=4.1.0
26
- Requires-Dist: wrapt<2,>=1.15.0
27
- Requires-Dist: black
28
- Provides-Extra: dev
29
- Requires-Dist: hypothesis; extra == "dev"
30
- Requires-Dist: inflection; extra == "dev"
31
- Requires-Dist: myst-parser; extra == "dev"
32
- Requires-Dist: pre-commit; extra == "dev"
33
- Requires-Dist: pytest; extra == "dev"
34
- Requires-Dist: pytest-snapshot; extra == "dev"
35
- Requires-Dist: pytest-cov<5.1,>=4.0; extra == "dev"
36
- Requires-Dist: sphinx; extra == "dev"
37
- Requires-Dist: sphinx-rtd-theme; extra == "dev"
38
- Provides-Extra: cfg
39
- Requires-Dist: graphviz; extra == "cfg"
40
- Provides-Extra: z3
41
- Requires-Dist: z3-solver; extra == "z3"
42
- Requires-Dist: importlib_resources; python_version < "3.9" and extra == "z3"
43
-
44
- # PyTA
45
-
46
- PyTA is a Python program which uses static code analysis to help students find
47
- and fix common coding errors in introductory Python courses. Python already
48
- has great static analysis tools like pep8 and pylint, but these tools do not
49
- necessarily have the most beginner-friendly format. PyTA has two central goals:
50
-
51
- 1. Statically identify common coding errors by using existing linting tools and
52
- building custom linters (e.g., as pylint checkers).
53
- 2. Present beautiful, intuitive messages to students that are both helpful for
54
- fixing errors, and good preparation for the terser messages they will see
55
- in their careers.
56
-
57
- This is a new project started in the Summer of 2016, and takes the form
58
- of a wrapper around [pylint](https://pylint.org) (with custom checkers) that operates
59
- directly on Python modules, as well as a website with some supplementary
60
- material going into further detail for the emitted errors.
61
-
62
- For greater details on the errors PyTA checks for: [Help Documentation](https://www.cs.toronto.edu/~david/pyta/).
63
-
64
- For help getting started using PyTA: [Quick Start](https://www.cs.toronto.edu/~david/pyta/usage/quick_start.html).
65
-
66
- ## Installation
67
-
68
- If you're interested in using PyTA, you can install it using `pip` (or `pip3`, on OSX/Linux):
69
-
70
- ```console
71
- > pip install python-ta
72
- ```
73
-
74
- ### Development
75
-
76
- If you're developing PyTA:
77
-
78
- 1. First, clone this repository.
79
- 2. Open a terminal in this repo, and run `pip install -e ".[dev, cfg, z3]"` to install the dependencies.
80
- 3. Then run `pre-commit install` to install the pre-commit hooks (for automatically formatting and checking your code on each commit).
81
-
82
- While not strictly necessary for debugging, some debugging tools require [graphviz](https://www.graphviz.org/download/) to be installed on your system.
83
-
84
- ### Tests
85
-
86
- To run the test suite, run the following command from inside the `pyta` directory:
87
-
88
- ```console
89
- > python -m pytest tests # Or python3 on OSX/Linux
90
- ```
91
-
92
- ## Generating the docs
93
-
94
- The PyTA documentation is generated using [Sphinx](https://www.sphinx-doc.org/en/master/index.html).
95
- To generate the documentation locally, run the commands:
96
-
97
- ```console
98
- > cd docs
99
- > make html
100
- ```
101
-
102
- Then open the file `docs/_build/html/index.html` in your web browser!
103
-
104
- ## Demo
105
-
106
- You can currently see a proof of concept in this repository. Clone it,
107
- and then run `python` in this directory (PyTA is primarily meant to be
108
- included as a library). In the Python interpreter, try running:
109
-
110
- ```python
111
- >>> import python_ta
112
- >>> python_ta.check_all('examples.custom_checkers.e9999_forbidden_import')
113
- [Some output should be shown]
114
- >>> python_ta.doc('E9999')
115
- ```
116
-
117
- ## Contributors
118
-
119
- Lorena Buciu,
120
- Simon Chen,
121
- Freeman Cheng,
122
- Ivan Chepelev,
123
- Nigel Fong,
124
- Adam Gleizer,
125
- Ibrahim Hasan,
126
- Niayesh Ilkhani,
127
- Craig Katsube,
128
- Rebecca Kay,
129
- Christopher Koehler,
130
- David Kim,
131
- Simeon Krastnikov,
132
- Ryan Lee,
133
- Christopher Li,
134
- Hayley Lin,
135
- Bruce Liu,
136
- Merrick Liu,
137
- Wendy Liu,
138
- Yibing (Amy) Lu,
139
- Maria Shurui Ma,
140
- Aina Fatema Asim Merchant,
141
- Shweta Mogalapalli,
142
- Ignas Panero Armoska,
143
- Justin Park,
144
- Harshkumar Patel,
145
- Varun Sahni,
146
- Eleonora Scognamiglio,
147
- Stephen Scott,
148
- Amr Sharaf,
149
- Richard Shi,
150
- Kavin Singh,
151
- Alexey Strokach,
152
- Sophy Sun,
153
- Utku Egemen Umut,
154
- Sarah Wang,
155
- Lana Wehbeh,
156
- Jasmine Wu,
157
- Raine Yang,
158
- Philippe Yu,
159
- Yi Cheng (Michael) Zhao
1
+ Metadata-Version: 2.1
2
+ Name: python-ta
3
+ Version: 2.9.0
4
+ Summary: Code checking tool for teaching Python
5
+ Author-email: David Liu <david@cs.toronto.edu>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/pyta-uoft/pyta
8
+ Project-URL: Documentation, https://www.cs.toronto.edu/~david/pyta/
9
+ Project-URL: Repository, https://github.com/pyta-uoft/pyta.git
10
+ Project-URL: Changelog, https://github.com/pyta-uoft/pyta/blob/master/CHANGELOG.md
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: astroid~=3.3.5
15
+ Requires-Dist: click<9,>=8.0.1
16
+ Requires-Dist: colorama~=0.4.6
17
+ Requires-Dist: jinja2~=3.1.2
18
+ Requires-Dist: pycodestyle~=2.11
19
+ Requires-Dist: pygments<2.19,>=2.14
20
+ Requires-Dist: pylint~=3.3.1
21
+ Requires-Dist: requests<2.33,>=2.28
22
+ Requires-Dist: six
23
+ Requires-Dist: tabulate~=0.9.0
24
+ Requires-Dist: toml~=0.10.2
25
+ Requires-Dist: typeguard<5,>=4.1.0
26
+ Requires-Dist: wrapt<2,>=1.15.0
27
+ Requires-Dist: black
28
+ Requires-Dist: beautifulsoup4
29
+ Provides-Extra: dev
30
+ Requires-Dist: hypothesis; extra == "dev"
31
+ Requires-Dist: inflection; extra == "dev"
32
+ Requires-Dist: myst-parser; extra == "dev"
33
+ Requires-Dist: pre-commit; extra == "dev"
34
+ Requires-Dist: pytest; extra == "dev"
35
+ Requires-Dist: pytest-cov<6.1,>=4.0; extra == "dev"
36
+ Requires-Dist: pytest-mock; extra == "dev"
37
+ Requires-Dist: pytest-snapshot; extra == "dev"
38
+ Requires-Dist: sphinx; extra == "dev"
39
+ Requires-Dist: sphinx-rtd-theme; extra == "dev"
40
+ Provides-Extra: cfg
41
+ Requires-Dist: graphviz; extra == "cfg"
42
+ Provides-Extra: z3
43
+ Requires-Dist: z3-solver; extra == "z3"
44
+ Requires-Dist: importlib_resources; python_version < "3.9" and extra == "z3"
45
+
46
+ # PyTA
47
+
48
+ PyTA is a Python program which uses static code analysis to help students find
49
+ and fix common coding errors in introductory Python courses. Python already
50
+ has great static analysis tools like pep8 and pylint, but these tools do not
51
+ necessarily have the most beginner-friendly format. PyTA has two central goals:
52
+
53
+ 1. Statically identify common coding errors by using existing linting tools and
54
+ building custom linters (e.g., as pylint checkers).
55
+ 2. Present beautiful, intuitive messages to students that are both helpful for
56
+ fixing errors, and good preparation for the terser messages they will see
57
+ in their careers.
58
+
59
+ This is a new project started in the Summer of 2016, and takes the form
60
+ of a wrapper around [pylint](https://pylint.org) (with custom checkers) that operates
61
+ directly on Python modules, as well as a website with some supplementary
62
+ material going into further detail for the emitted errors.
63
+
64
+ For greater details on the errors PyTA checks for: [Help Documentation](https://www.cs.toronto.edu/~david/pyta/).
65
+
66
+ For help getting started using PyTA: [Quick Start](https://www.cs.toronto.edu/~david/pyta/usage/quick_start.html).
67
+
68
+ ## Installation
69
+
70
+ If you're interested in using PyTA, you can install it using `pip` (or `pip3`, on OSX/Linux):
71
+
72
+ ```console
73
+ > pip install python-ta
74
+ ```
75
+
76
+ ### Development
77
+
78
+ If you're developing PyTA:
79
+
80
+ 1. First, clone this repository.
81
+ 2. Open a terminal in this repo, and run `pip install -e ".[dev, cfg, z3]"` to install the dependencies.
82
+ 3. Then run `pre-commit install` to install the pre-commit hooks (for automatically formatting and checking your code on each commit).
83
+
84
+ While not strictly necessary for debugging, some debugging tools require [graphviz](https://www.graphviz.org/download/) to be installed on your system.
85
+
86
+ ### Tests
87
+
88
+ To run the test suite, run the following command from inside the `pyta` directory:
89
+
90
+ ```console
91
+ > python -m pytest tests # Or python3 on OSX/Linux
92
+ ```
93
+
94
+ ## Generating the docs
95
+
96
+ The PyTA documentation is generated using [Sphinx](https://www.sphinx-doc.org/en/master/index.html).
97
+ To generate the documentation locally, run the commands:
98
+
99
+ ```console
100
+ > cd docs
101
+ > make html
102
+ ```
103
+
104
+ Then open the file `docs/_build/html/index.html` in your web browser!
105
+
106
+ ## Demo
107
+
108
+ You can currently see a proof of concept in this repository. Clone it,
109
+ and then run `python` in this directory (PyTA is primarily meant to be
110
+ included as a library). In the Python interpreter, try running:
111
+
112
+ ```python
113
+ >>> import python_ta
114
+ >>> python_ta.check_all('examples.custom_checkers.e9999_forbidden_import')
115
+ [Some output should be shown]
116
+ >>> python_ta.doc('E9999')
117
+ ```
118
+
119
+ ## Contributors
120
+
121
+ Lorena Buciu,
122
+ Simon Chen,
123
+ Freeman Cheng,
124
+ Ivan Chepelev,
125
+ Yianni Culmone,
126
+ Nigel Fong,
127
+ Adam Gleizer,
128
+ Ibrahim Hasan,
129
+ Niayesh Ilkhani,
130
+ Craig Katsube,
131
+ Rebecca Kay,
132
+ Christopher Koehler,
133
+ David Kim,
134
+ Simeon Krastnikov,
135
+ Ryan Lee,
136
+ Christopher Li,
137
+ Hayley Lin,
138
+ Bruce Liu,
139
+ Merrick Liu,
140
+ Wendy Liu,
141
+ Yibing (Amy) Lu,
142
+ Maria Shurui Ma,
143
+ Aina Fatema Asim Merchant,
144
+ Shweta Mogalapalli,
145
+ Ignas Panero Armoska,
146
+ Justin Park,
147
+ Harshkumar Patel,
148
+ Varun Sahni,
149
+ Eleonora Scognamiglio,
150
+ Stephen Scott,
151
+ Amr Sharaf,
152
+ Richard Shi,
153
+ Kavin Singh,
154
+ Alexey Strokach,
155
+ Sophy Sun,
156
+ Utku Egemen Umut,
157
+ Sarah Wang,
158
+ Lana Wehbeh,
159
+ Jasmine Wu,
160
+ Raine Yang,
161
+ Philippe Yu,
162
+ Yi Cheng (Michael) Zhao
@@ -77,6 +77,7 @@ Lorena Buciu,
77
77
  Simon Chen,
78
78
  Freeman Cheng,
79
79
  Ivan Chepelev,
80
+ Yianni Culmone,
80
81
  Nigel Fong,
81
82
  Adam Gleizer,
82
83
  Ibrahim Hasan,
@@ -7,13 +7,13 @@ authors = [
7
7
  license = {text = "MIT"}
8
8
  readme = "README.md"
9
9
  dependencies = [
10
- "astroid ~= 3.2.4",
10
+ "astroid ~= 3.3.5",
11
11
  "click >= 8.0.1, < 9",
12
12
  "colorama ~= 0.4.6",
13
13
  "jinja2 ~= 3.1.2",
14
14
  "pycodestyle ~= 2.11",
15
15
  "pygments >= 2.14,< 2.19",
16
- "pylint ~= 3.2.6",
16
+ "pylint ~= 3.3.1",
17
17
  "requests >= 2.28,< 2.33",
18
18
  "six",
19
19
  "tabulate ~= 0.9.0",
@@ -21,9 +21,10 @@ dependencies = [
21
21
  "typeguard >= 4.1.0, < 5",
22
22
  "wrapt >= 1.15.0, < 2",
23
23
  "black",
24
+ "beautifulsoup4"
24
25
  ]
25
26
  dynamic = ["version"]
26
- requires-python = ">=3.8"
27
+ requires-python = ">=3.9"
27
28
 
28
29
  [project.optional-dependencies]
29
30
  dev = [
@@ -32,8 +33,9 @@ dev = [
32
33
  "myst-parser",
33
34
  "pre-commit",
34
35
  "pytest",
36
+ "pytest-cov >= 4.0,< 6.1",
37
+ "pytest-mock",
35
38
  "pytest-snapshot",
36
- "pytest-cov >= 4.0,< 5.1",
37
39
  "sphinx",
38
40
  "sphinx-rtd-theme",
39
41
  ]
@@ -15,8 +15,9 @@ if __name__ == '__main__':
15
15
  python_ta.check_all()
16
16
  """
17
17
 
18
- __version__ = "2.8.0" # Version number
18
+ from __future__ import annotations
19
19
 
20
+ __version__ = "2.9.0" # Version number
20
21
  # First, remove underscore from builtins if it has been bound in the REPL.
21
22
  # Must appear before other imports from pylint/python_ta.
22
23
  import builtins
@@ -36,7 +37,7 @@ import tokenize
36
37
  import webbrowser
37
38
  from builtins import FileNotFoundError
38
39
  from os import listdir
39
- from typing import AnyStr, Generator, List, Optional, TextIO, Union
40
+ from typing import AnyStr, Generator, Optional, TextIO, Union
40
41
 
41
42
  import pylint.config
42
43
  import pylint.lint
@@ -64,7 +65,7 @@ PYLINT_PATCHED = False
64
65
 
65
66
 
66
67
  def check_errors(
67
- module_name: Union[List[str], str] = "",
68
+ module_name: Union[list[str], str] = "",
68
69
  config: Union[dict, str] = "",
69
70
  output: Optional[TextIO] = None,
70
71
  load_default_config: bool = True,
@@ -82,7 +83,7 @@ def check_errors(
82
83
 
83
84
 
84
85
  def check_all(
85
- module_name: Union[List[str], str] = "",
86
+ module_name: Union[list[str], str] = "",
86
87
  config: Union[dict, str] = "",
87
88
  output: Optional[TextIO] = None,
88
89
  load_default_config: bool = True,
@@ -100,7 +101,7 @@ def check_all(
100
101
 
101
102
 
102
103
  def _check(
103
- module_name: Union[List[str], str] = "",
104
+ module_name: Union[list[str], str] = "",
104
105
  level: str = "all",
105
106
  local_config: Union[dict, str] = "",
106
107
  output: Optional[TextIO] = None,
@@ -123,10 +124,6 @@ def _check(
123
124
  # Configuring logger
124
125
  logging.basicConfig(format="[%(levelname)s] %(message)s", level=logging.NOTSET)
125
126
 
126
- # check the python version
127
- if sys.version_info < (3, 7, 0):
128
- logging.warning("You need Python 3.7 or later to run PythonTA.")
129
-
130
127
  linter = reset_linter(config=local_config, load_default_config=load_default_config)
131
128
  current_reporter = linter.reporter
132
129
  current_reporter.set_output(output)
@@ -139,7 +136,9 @@ def _check(
139
136
 
140
137
  global PYLINT_PATCHED
141
138
  if not PYLINT_PATCHED:
142
- patch_all(messages_config) # Monkeypatch pylint (override certain methods)
139
+ patch_all(
140
+ messages_config, linter.config.z3
141
+ ) # Monkeypatch pylint (override certain methods)
143
142
  PYLINT_PATCHED = True
144
143
 
145
144
  # Try to check file, issue error message for invalid files.
@@ -441,7 +440,7 @@ def _verify_pre_check(filepath: AnyStr, allow_pylint_comments: bool) -> bool:
441
440
  return True
442
441
 
443
442
 
444
- def _get_valid_files_to_check(module_name: Union[List[str], str]) -> Generator[AnyStr, None, None]:
443
+ def _get_valid_files_to_check(module_name: Union[list[str], str]) -> Generator[AnyStr, None, None]:
445
444
  """A generator for all valid files to check."""
446
445
  # Allow call to check with empty args
447
446
  if module_name == "":
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
2
+
1
3
  import sys
2
4
  from os import path
3
- from typing import List, Optional
5
+ from typing import Optional
4
6
 
5
7
  import click
6
8
 
@@ -41,7 +43,7 @@ def main(
41
43
  version: bool,
42
44
  config: Optional[str],
43
45
  errors_only: bool,
44
- filenames: List[str],
46
+ filenames: list[str],
45
47
  exit_zero: bool,
46
48
  generate_config: bool,
47
49
  output_format: str,
@@ -2,15 +2,25 @@
2
2
  Provides a function to generate and display the control flow graph of a given module.
3
3
  """
4
4
 
5
+ from __future__ import annotations
6
+
5
7
  import importlib.util
6
8
  import os.path
7
9
  import sys
8
- from typing import Any, Dict, Optional, Set
10
+ from typing import Any, Optional
9
11
 
10
12
  import graphviz
11
13
  from astroid import nodes
12
14
  from astroid.builder import AstroidBuilder
13
15
 
16
+ try:
17
+ from ..transforms.z3_visitor import Z3Visitor
18
+
19
+ z3_dependency_available = True
20
+ except ImportError:
21
+ Z3Visitor = Any
22
+ z3_dependency_available = False
23
+
14
24
  from .graph import CFGBlock, ControlFlowGraph
15
25
  from .visitor import CFGVisitor
16
26
 
@@ -19,7 +29,7 @@ SUBGRAPH_OPTIONS = {"fontname": "Courier New"}
19
29
 
20
30
 
21
31
  def generate_cfg(
22
- mod: str = "", auto_open: bool = False, visitor_options: Optional[Dict[str, Any]] = None
32
+ mod: str = "", auto_open: bool = False, visitor_options: Optional[dict[str, Any]] = None
23
33
  ) -> None:
24
34
  """Generate a control flow graph for the given module.
25
35
 
@@ -43,7 +53,7 @@ def generate_cfg(
43
53
 
44
54
 
45
55
  def _generate(
46
- mod: str = "", auto_open: bool = False, visitor_options: Optional[Dict[str, Any]] = None
56
+ mod: str = "", auto_open: bool = False, visitor_options: Optional[dict[str, Any]] = None
47
57
  ) -> None:
48
58
  """Generate a control flow graph for the given module.
49
59
 
@@ -59,6 +69,12 @@ def _generate(
59
69
 
60
70
  file_name = os.path.splitext(os.path.basename(abs_path))[0]
61
71
  module = AstroidBuilder().file_build(abs_path)
72
+
73
+ # invoke Z3Visitor if z3 dependency is available
74
+ if z3_dependency_available:
75
+ z3v = Z3Visitor()
76
+ module = z3v.visitor.visit(module)
77
+
62
78
  visitor = CFGVisitor(options=visitor_options)
63
79
  module.accept(visitor)
64
80
 
@@ -92,7 +108,7 @@ def _get_valid_file_path(mod: str = "") -> Optional[str]:
92
108
 
93
109
 
94
110
  def _display(
95
- cfgs: Dict[nodes.NodeNG, ControlFlowGraph], filename: str, auto_open: bool = False
111
+ cfgs: dict[nodes.NodeNG, ControlFlowGraph], filename: str, auto_open: bool = False
96
112
  ) -> None:
97
113
  graph = graphviz.Digraph(name=filename, **GRAPH_OPTIONS)
98
114
  for node, cfg in cfgs.items():
@@ -116,7 +132,7 @@ def _display(
116
132
  graph.render(filename, view=auto_open)
117
133
 
118
134
 
119
- def _visit(block: CFGBlock, graph: graphviz.Digraph, visited: Set[int], end: CFGBlock) -> None:
135
+ def _visit(block: CFGBlock, graph: graphviz.Digraph, visited: set[int], end: CFGBlock) -> None:
120
136
  """
121
137
  Visit a CFGBlock and add it to the control flow graph.
122
138
  """
@@ -138,8 +154,11 @@ def _visit(block: CFGBlock, graph: graphviz.Digraph, visited: Set[int], end: CFG
138
154
  visited.add(node_id)
139
155
 
140
156
  for edge in block.successors:
157
+ color = "black" if edge.is_feasible else "lightgrey"
141
158
  if edge.get_label() is not None:
142
- graph.edge(node_id, f"{graph.name}_{edge.target.id}", edge.get_label())
159
+ graph.edge(
160
+ node_id, f"{graph.name}_{edge.target.id}", label=edge.get_label(), color=color
161
+ )
143
162
  else:
144
- graph.edge(node_id, f"{graph.name}_{edge.target.id}")
163
+ graph.edge(node_id, f"{graph.name}_{edge.target.id}", color=color)
145
164
  _visit(edge.target, graph, visited, end)