All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and adheres to Semantic Versioning.
- Added
include_frames
filter tosnapshot
- Added
exclude_vars
filter tosnapshot
- Added new
python_ta.debug
module with anSnapshotTracer
context manager for generating memory models - Added
z3
option toinconsistent-or-missing-returns
,redundant-assignment
, andpossibly-undefined
checkers to only check for feasible code blocks based on edge z3 constraints - Included the name of redundant variable in
E9959 redundant-assignment
message - Update to pylint v3.3 and and astroid v3.3. This added support for Python 3.13 and dropped support for Python 3.8.
- Added a STRICT_NUMERIC_TYPES configuration to
python_ta.contracts
allowing to enable/disable stricter type checking of numeric types
unmentioned-parameter
: Provide error message when a function parameter is not mentioned by name in the function's docstring. By default, this checker is disabled.
- Fixed issue where
snapshot
errors on unserializable values - Fixed issue within
Snapshot.py
where thememory_viz_version
parameter was not respected - Fixed issue where parallel assignment statements and assignment to multiple targets were not checked by
redundant_assignment_checker
- Fixed issue where annotated assignment statements were not checked by
redundant_assignment_checker
- Fixed issue where empty preconditions were preventing CFGs from being generated
- Added strict numeric type checking to enforce type distinctions across the entire numeric hierarchy, including complex numbers.
- Added strict type checking support for nested and union types (e.g.,
list[int]
,dict[float, int]
,Union[int, float]
)
- Renamed
ExprWrapper
class toZ3Parser
- Renamed
ExprWrapper
module toz3_parser
and moved it to new directorypython_ta.z3
- Removed
node
attribute forZ3Parser
- Renamed
reduce
method ofZ3Parser
toparse
- Renamed
test_expr_wrapper
totest_z3_parser
- Added
is_feasible
attribute forCFGEdge
and implemented update to edge feasibility based on lists of Z3 constraints - Refactored codebase to use modern type annotations. Replaced
List
withlist
,Dict
withdict
,Set
withset
, andTuple
withtuple
- Checked for variable reassignment in
AugAssign
andAnnAssign
node in parsing edge Z3 constraints - Rendered logically infeasible control flow graph edges in light grey
- Modified
test_snapshot_to_json_sets_primitive
for Python 3.8 compatibility - Added unit tests for
one_iteration_checker
- Added mock
webbrowser.open
in tests to prevent browser tabs and HTTP requests duringpython_ta.check_all()
executions. - Added
pytest-mock
as a development dependency - Make
test_snapshot.py::test_snapshot_serializes_unserializable_value
able to run on Windows.
- Fix loading of setendings plugin when z3-solver is not installed
- Add new boolean configuration
allow-local-imports
to allow for local imports - Extended the
snasphot
function to include the relevant variables defined at the top level (global variables). - Include the pycodestyle error code to the error message for PEP8 style errors
- Added date and time display to
PlainReporter
andColorReporter
- Allowed specifying allowed names in configurations
allowed-import-modules
andextra-imports
instead of just modules - Improved error display for pycodestyle (E9989) errors E123, E203, E222, E226, and E262
- Added the configuration option to ignore naming convention violations (C9103 and C9104) for names matching the provided regular expression.
- Update to pylint v3.1 and and astroid v3.1
- Stored actual AST condition node in edges leading out of If/While blocks in generated control flow graphs.
- Stored valid Python function preconditions in initial edge to function code in generated function control flow graphs.
- Report warning when control flow graph creation encounters a syntax error related to control flow
- Added autoformat option that runs black formatting tool to python_ta.check_all()
- Extended the
snapshot
function to optionally generate a svg of the snapshot using MemoryViz when save parameter is true.
Pylint checkers v3.1:
use-yield-from
deprecated-attribute
For more information on these checkers, please see the Pylint release notes. Note that the above list only contains the Pylint checkers enabled by default in PythonTA.
Custom checkers:
inconsistent-returns
andmissing-return-statement
: Provide clearer error messages when reporting missing return statements. This replaces pylint's R1710 check.
- Fixed issue with error message of C0410 by reformating it to properly fit with the list of modules imported that are provided to it
- Fixed bug where
_
was marked as a built-in when running PythonTA after running doctest - Fixed issue where annotated constant variable assignment was not considered as permissible top level code and triggered error E9992
- Fixed issue where top level class attribute assignment was considered as permissible top level code
- Fixed issue where
check_contracts
fails silently when function preconditions contain precondition violations, and when a representation invariant contains a call to a top-level function (not built-in or imported library). - Fixed issue where methods called in representation invariants lead to infinite recursion.
- Fixed issue where
PossiblyUndefinedChecker
raised an error if the control flow graph was invalid due to syntax error
- Updated changelog and pull request template formats
- Added unit tests for PEP8 errors E115, E122, E125, E127, E129, E131 for
PycodestyleChecker
- Added unit tests for PEP8 errors E223, E224, E227, E228, E265 for
PycodestyleChecker
- Refactored
test_check_on_dir
intest_check.py
module to test onsample_dir
, a subset ofexamples
- Added unit test
test_examples_files_pyta
intest_examples.py
to check every file inexamples
with PythonTA - Added unit tests for PEP8 errors E266, E275, E301, E303, E304 for
PycodestyleChecker
- Moved tests related to
__main__.py
fromtest_check.py
totest_main.py
- Added more unit tests to
test_main.py
to increase coverage of__main__.py
to 100% - Updated
README.md
to reflect updated folder structure - Added unit test
test_pycodestyle_errors_pyta
intest_examples.py
to check every file ine9989_pycodestyle
with PythonTA for PEP8 errors - Parametrized tests for
PycodestyleChecker
- Moved tests related to
snapshot.py
out oftest_accumulation_table.py
and into new moduletest_snapshot.py
- Updated GitHub Action tests to avoid running
test_accumulation_table.py
andtest_recursion_table.py
with coverage and add verbose output for debug testing - Allowed GitHub Action tests to run on all pull requests, including drafts
- Updated dependencies for GitHub Actions to use the latest versions
- Updated dependabot configuration to auto-update dependencies for GitHub Actions in the future
- Updated usage messages in
examples/sample_usage/
ofdraw_cfg.py
andprint_ast.py
to be accurate on all operating systems - Removed redundant line from
tests/test_examples.py
- Fixed minor typo in an error message in
python_ta/cfg/visitor.py
- Updated
ExprWrapper
to supportset/list/tuple
literals andin/not in
operators - Updated
snapshot.py
andtest_snapshot.py
to align with MemoryViz 0.2.0 updates - Updated
ExprWrapper
to support string variables and==
,in/not in
, indexing and slicing operators - Added protected
_z3_vars
attribute toControlFlowGraph
to store variables to be used in Z3 solver - Removed unused imports from
python_ta/cfg/graph.py
- Extended functionality of
ExprWrapper
class to include function definitions' arguments and name assignments - Added
z3
to dependencies installed as part of thedocs
job in the GitHub Actions workflow - Added tests to maintain/increase coverage of
visitor.py
,graph.py
, andExprWrapper.py
- Removed deprecated and redundant
future
argument fromnode.frame()
call ininvalid_name_checker.py
- Updated pylint to v3.2.6 and astroid to v3.2.4 (no new checks were enabled by default)
- Excluded
node_modules/
folder from package autodiscovery - Updated
graph.py
to augment control flow graph edges with z3 constraints - Added support for the
!=
operator and replaced dictionary indexing with.get
inExprWrapper
. - Refactored
Z3Visitor
to usesafe_infer()
instead ofinferred()
and added handling ofAstroidError
. - Add
negate
attribute toCFGEdge
- Added new configuration option
use-pyta-error-messages
to let users choose whether PythonTA should overwrite pylint's error messages. - Both PlainReporter and ColorReporter emphasize specific code chunks by using overline characters under any part that is highlighted as ERROR.
- Added snapshot function for deriving a list of dictionaries containing local variables from relevant functions and/or stack frames.
- Added new configuration option
allow-pylint-comments
to let users choose whether PythonTA should allow comments beginning with pylint: or not. AccumulationTable
can now track variables initialized within thefor
loop. Prior, only variables initialized before thefor
loop could be tracked.AccumulationTable
now stores deep copies of objects rather than shallow copies, thus fixing issues that come up in case of mutation during loop.AccumulationTable
can now take in any accumulator expressions, for eg.x * 2
, instead of just variables.AccumulationTable
now has an optional initialization argumentoutput
which allows the users to choose whether they want to write the Accumulation Table to a file.- Created a
RecursionTable
context manager for recursive tracing using a tabular output. - Support Python 3.12 (requiring upgrade to pylint and astroid 3.0)
- Fix bug in ending location setting for
Attribute
andDelAttr
nodes when the same attribute was accessed twice on the same line. - Fix bug where the
naming-convention-violation
checker was checking variables defined in a module's main block. This was inconsistent with theforbidden-global-variables
checker. - Fixed bug with
invalid-range-index
: do not attempt any inference of variables inrange
expressions. All range arguments involving variables will be ignored by this checker.
Pylint checkers v3.0:
invalid-field-call
return-in-finally
kwarg-superseded-by-positional-arg
unnecessary-negation
(renamed fromunneeded-not
)
For more information on these checkers, please see the Pylint release notes. Note that the above list only contains the Pylint checkers enabled by default in PythonTA.
- Remove experimental type inference code.
- Fixed bug with
invalid-range-index
when variables are used inrange
expressions.
- Ensure pycodestyle W503, line break before binary operator, is disabled (regression from 2.6.2).
- Fix
check_contracts
typings so PyCharm static checking will work - Fix
invalid-range-index
bug where valid range calls were flagged as invalid
- Fix
naming-convention-violation
bug where_
was considered an invalid variable name. - Fix
naming-convention-violation
bug where top-level constants were being checked as regular variable names.
- Created many custom renderers to make the code snippets for
pep8-errors
easier to understand.
- Make
graphviz
an optional dependency, and clarify the installation requirements for visualizing control flow graphs. - Fix
check_contrats
handling of forward references in class type annotations when usingcheck_contracts
decorator. - Fix handling of
|
in type annotations (by updating totypeguard
v4.1.0).
- Can now create control flow graphs using
python_ta.control_flow_graphs
to visualize the execution paths of Python code. forbidden-top-level-code
andforbidden-global-variables
now allow top-level type alias assignment statements.- The
trailing-whitespace
error message now highlights the trailing whitespace. - The
unnecessary-indexing
error now checks for a greater variety of loop/comprehension indexes. - Provided configuration files are now merged with PythonTA defaults, so you now only
need to specify options that you want to be overridden. To ignore PythonTA defaults (the
old behaviour), pass
load_default_config=False
tocheck_errors
andcheck_all
. - Improved the code snippets for the
pep8-errors
"blank line" messages. Extra blank lines are now highlighted, and suggestions are added when blank lines are missing. - The default value of the
pyta-number-of-messages
configuration option is now 0 (changed from 5). This causes all error occurrences to be displayed. - Improved efficiency of the contract-checking custom
setattr
for classes. - Added new function
python_ta.contracts.validate_invariants
to manually check contracts for an object. - Updated to pycodestyle v2.11.
- Fixed bug where running
python3 -m python_ta --generate-config
yields aFileNotFoundError
. - Fixed bug in how PythonTA reports error messages that occur when parsing configuration files.
- Ensured some config file parsing errors no longer display incorrect lines in the error report.
- Fixed bug where the
HTMLReporter
andJSONReporter
would ignore thepyta-number-of-messages
option and always display all error occurrences. - Fixed bug in
check_contracts
where imported classes were not correctly resolved when checking types. - Fixed bug for class contract-checking when assigning an instance attribute that violates a class type constraint or representation invariant. Previously, the instance attribute changed to the new value after the error was raised, but now is correctly restored to the original value.
- Remove line double-spacing in PlainReporter and ColorReporter output code snippets.
Custom checkers:
invalid-name-checker
: Provide beginner-friendly error messages when reporting variable names that violate Python naming conventions. This replaces pylint's C0103 check.
Pylint checkers v2.16:
pointless-exception-statement
shadowed-import
unbalanced-dict-unpacking
nested-min-max
invalid-slice-step
Pylint checkers v2.17:
bad-chained-comparison
For more information on these checkers, please see the Pylint release notes. Note that the above list only contains the Pylint checkers enabled by default in PythonTA.
- Fixed bug in possibly-undefined checker where a comprehension variable is falsely flagged as possibly undefined.
- Fixed bug where
check_errors
andcheck_all
opens a webpage when a nonexistent or unreadable path is passed as an argument. - Fixed the CFG implementation to resolve a bug in the possibly-undefined checker where variables were falsely flagged as possibly undefined when the code conditionally raises an exception and the variable was referenced afterwards.
- Fixed bug where the generated CFGs will highlight the except block as unreachable if the same exception it is handling was raised in the body of the tryexcept.
Custom checkers:
forbidden-python-syntax
: Flag code that is not permitted to be used on an assessment.
- Pin dependency versions
- Fixed custom message formats based on Pylint 2.15 updates.
- Fixed bug in shadowing-in-comprehension checker when target is a subscript node.
- Ensured
check_contracts
andcheck_all_contracts
do nothing whenENABLE_CONTRACT_CHECKING
isFalse
.
- Fixed PyTA contract checking for method calls when running modules in PyCharm using the "Run File in Python Console" action.
unnecessary_indexing_checker
has now been extended to check comprehensions in addition to for loops.invalid_for_target_checker
has now been extended to check comprehensions in addition to for loops.forbidden_io_function_checker
is now able to check for calls to IO functions written at the top-level of a module, but outside the main block.python_ta.debug.AccumulationTable
is extended to support printing loop iterations for while loops.- Violated representation invariant error message now includes the class name and current values of the instance attributes.
- Added constant
python_ta.contracts.ENABLE_CONTRACT_CHECKING
to only check contracts when its value is set toTrue
. python_ta.debug.AccumulationTable
has extended loop detection to allow the loop to appear anywhere inside the with statement.
- Fixed Issue #831: Contract Checker Bug. Now raises
AssertionError
when the expected type isfloat
but gotint
instead. - PyTA contracts' type checking now raises
AssertionError
when the expected type isint
but gotbool
instead. - Fixed PyTA contract checking when running modules in PyCharm using the "Run File in Python Console" action.
Custom checkers:
forbidden-top-level-code
: Flag code written at the top level when it is not one of the four acceptable types.
- Restored 'line_end', 'column_end', and 'snippet' fields in JSON reporter output.
- Updated jsonreporter to get data from the new pylint Message class (#840)
- Added preliminary support for translation of constraints into Z3 solver. (This is currently not enabled by default in PythonTA.)
- Add missing
toml
package to library dependencies. - Improve formatting of
None
andfloat
s inAccumulationTable
display. Also make minor improvements to the documentation.
- Added new command line argument
-v/--version
. User can print out current PythonTA version usingpython -m python_ta -v
. - Preconditions, postconditions, and representation invariants are now parsed only once and compiled.
- Can configure custom error messages for pylint in a toml file.
missing_space_in_doctest_checker
is now able to check doctests in python modules and classes.- Updated to Pylint v2.14. See "New checks" below for the new checkers enabled by default.
- Added new
python_ta.debug
module with anAccumulationTable
context manager for loop print debugging. - Improve message for R1710 (inconsistent-return-statements)
- Function
check_all_contracts
skips contract checks for functions and classes which are not defined in a module whose name is passed as an argument. Ifdecorate_main
argument isTrue
, functions and classes defined in__main__
module will be checked without needing to pass in additional arguments.
Custom checkers:
type-is-assigned
: Flag when a type is not annotated but rather assigned in a function or class definition.
Pylint checkers v2.13:
modified-iterating-list
modified-iterating-dict
modified-iterating-set
unnecessary-ellipsis
bad-file-encoding
Pylint checkers v2.14:
comparison-of-constants
potential-index-error
unnecessary-list-index-lookup
duplicate-value
super-without-brackets
For more information on these checkers, please see the Pylint release notes. Note that the above list only contains the Pylint checkers enabled by default in PythonTA.
- Added support for postconditions in function docstring.
- Improve error message of
unncessary-indexing
checker. - Added CLI for
python_ta.contracts
module for executing a file with contract checking ($ python -m python_ta.contracts FILE
) - Added two new command line interfaces. User can print out the default PythonTA configuration file in the command line using
python -m python_ta -g
and can specify the output format of the reporter usingpython -m python_ta --output-format FILE
. - Updated to Pylint v2.12. See "New checks" below for the new checkers enabled by default.
- Register ending location setter as pylint plugin.
- Fix bugs in
unnecessary-indexing
checker:- False positive when the same loop variable is used in two loops in sequence.
- False negative when the loop variable can be simplified, but is also shadowed in the the loop body.
- Fix HTML report to link correctly to specific errors on the PythonTA documentation website.
- Fix bug when setting ending locations for
ClassDef
s that have no decorators.
Pylint checkers v2.12:
use-implicit-booleaness-not-len
(renamed fromlen-as-condition
)
Pylint checkers v2.11:
consider-using-f-string
For more information on these checkers, please see the Pylint release notes. Note that the above list only contains the Pylint checkers enabled by default in PythonTA.
- Fix HTML report to display file even when no errors are found.
- Fix pylint cache directory creation (backport of change from pylint 2.11)
- Added
line_end
andcolumn_end
toJSONReporter
output.
PythonTA's adopting semantic versioning as of this release, so we've bumped the version to 2.0.
- Added basic CLI. Users can now run PythonTA in the command line either as a standalone
script (
$ python_ta my_file
) or as a Python module ($ python -m python_ta my_file
). - Added new documentation website, hosted at https://www.cs.toronto.edu/~david/pyta.
- Added support for relative paths in
output
argument tocheck_all
. - Added new configuration option
pycodestyle-ignore
to customize the pycodestyle errors checked bypep8-errors
.
- Changed HTML report template to make it more user-friendly.
- Changed default HTML report output: by default now loads in a web browser without creating
a temporary file (previously,
pyta_report.html
). This file can still be generated by passingoutput='pyta_report.html'
to calls tocheck_all
. - Added new
output-format
option to specify reporter class. - Changed API of PythonTA custom reporters.
- Updated to Pylint v2.10. See "New checks" below for the new checks enabled by default.
- Renamed
for-target-subscript
checker toinvalid-for-target
, and added support checking for loop targets that are attributes (e.g.,for obj.x in [1, 2, 3]
). (#701)
- Fixed bug with
python_ta.contracts
: do not check representation invariants when a helper method is called within an initializer. - Fixed bug with
python_ta.contracts
: do not check class representation invariants in the initializer of a superclass. - Fixed bug with
shadowing-in-comprehension
checker: do not treat_
as a shadowed variable. - Fixed bug with
unnecessary-indexing
checker: handle case where loop variable is first assigned before the for loop. (#699) - Fixed bug where PythonTA would crash on files that used encodings other than UTF-8. PythonTA now reports an error and displays the invalid characters to the user.
- Deprecated
pyta-reporter
option; useoutput-format
instead.
Custom checkers:
missing-space-in-doctest
: Flag when a doctest prompt (>>>
) is not followed by a space. E.g.,>>>my_function(1)
.
Pylint checkers v2.10:
forgotten-debug-statement
format-string-without-interpolation
use-dict-literal
use-list-literal
Pylint checkers v2.9:
consider-using-from-import
unnecessary-dict-index-lookup
Pylint checkers v2.8:
consider-using-with
For more information on these checkers, please see the Pylint release notes. Note that the above list only contains the Pylint checkers enabled by default in PythonTA.
- Adopted semantic versioning.
- Created a Changelog.
- Added pre-commit hooks using pre-commit, black, isort, and prettier.
- Adopted Sphinx for documentation generation, using a Read the Docs template.
- Adopted
setup.cfg
file for configuration.