Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved the behavior of the contract checking new_setattr function #929

Merged
merged 11 commits into from
Jul 17, 2023

Conversation

Bruce-8
Copy link
Contributor

@Bruce-8 Bruce-8 commented Jul 14, 2023

Motivation and Context

For the new_setattr function in python_ta/contracts/__init__.py, this pull request re-organizes certain variable definitions, changes the use of certain inspect functions, and fixes a bug with attribute value restoration when representation invariants are violated.

Your Changes

Description:

  • Moved any variables that depend only on klass, but not self/name/value, to be defined in the outer function rather than inside new_setattr.
  • Replaced inspect.getouterframes with the f_back to improve efficiency of code.
  • The attribute value is restored to the original value if the _check_invariants call raises an error.

Type of change (select all that apply):

  • New feature (non-breaking change which adds functionality)

Testing

  • Used an example in another file to ensure that f_back represents the frame that's currently being checked in the code.
  • Added test case for the restoration of the attribute value to its original value if the _check_invariants call raises an error.
  • Added test case for the attribute not existing if the _check_invariants call raises an error.

Questions and Comments (if applicable)

For the 10 tests that didn't pass in test_class_contracts, I believe it was due to my change of moving ENABLE_CONTRACT_CHECKING to the top of the function body, so I don't think there's a way to make this test pass unless I don't don't move the constant. Additionally, for the 6 tests that didn't pass in test_contracts, the tests all passed in PyCharm when I ran them on my own branch, and I'm not too sure why that's the case because I double checked that the tests were the same both here and on my branch.

Checklist

  • I have performed a self-review of my own code.
  • I have verified that the CI tests have passed.
  • I have reviewed the test coverage changes reported on Coveralls.
  • I have added tests for my changes.
  • I have updated the CHANGELOG.md file.

Copy link
Contributor

@david-yz-liu david-yz-liu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Bruce-8 good work. Revert the changes you made to the ENABLE_CONTRACT_CHECKING constant and keep everything else and I'll take another look. You can (afterwards) do that part in a separate PR.

@coveralls
Copy link
Collaborator

coveralls commented Jul 15, 2023

Pull Request Test Coverage Report for Build 5569447533

  • 8 of 8 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.004%) to 94.087%

Totals Coverage Status
Change from base Build 5554308096: 0.004%
Covered Lines: 3055
Relevant Lines: 3247

💛 - Coveralls

CHANGELOG.md Outdated
@@ -26,6 +26,10 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- When running `check_contracts` on a class with type aliases as type annotations for its attributes, the `NameError`
that appears (which indicates that the type alias is undefined) is now resolved.
- The default value of `pyta-number-of-messages` is now 0. This automatically displays all occurrences of the same error.
- For the contract checking `new_setattr` function, the check for `ENABLE_CONTRACT_CHECKING` is now at the top of the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this to remove the reference to ENABLE_CONTRACT_CHECKING. Also you don't need to go into details about the efficiency improvements: reword to just say "improve efficiency" in the changelog entry.

if klass_mod is not None and ENABLE_CONTRACT_CHECKING:
try:
_check_invariants(self, klass, klass_mod.__dict__)
except PyTAContractError as e:
if original_attr_value is None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check doesn't work if the original attribute value was None, which is a different case from the original attribute note existing at all. You can use a separate variable to track whether there was an original attribute. And make sure to add a test for this case as well.

from python_ta.contracts import check_contracts


def test_class_attr_value_restores_to_original_if_violates_rep_inv() -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always make sure to add a docstring describing the purpose of each test case.

@david-yz-liu david-yz-liu merged commit 5da03c0 into pyta-uoft:master Jul 17, 2023
@Bruce-8 Bruce-8 deleted the improve-behaviour-new_setattr branch July 18, 2023 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants