Skip to content

bpo-30587: Adds signature checking for mock autospec object method calls #1982

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

Closed
wants to merge 4 commits into from

Conversation

claudiubelu
Copy link

@claudiubelu claudiubelu commented Jun 7, 2017

Mock can accept an spec object / class as argument, making sure that accessing attributes that do not exist in the spec will cause an AttributeError to be raised, but there is no guarantee that the spec's methods signatures are respected in any way. This creates the possibility to have faulty code with passing unit tests and assertions.

Example:

import mock

class Something(object):
    def foo(self, a, b, c, d):
        pass

m = mock.Mock(spec=Something)
m.foo()

Adds the autospec argument to Mock, and its mock_add_spec method.

Passes the spec's attribute with the same name to the child mock (spec-ing the child), if the mock's autospec is True.

Sets _mock_check_sig if the given spec is callable.

Adds unit tests to validate the fact that the autospec method signatures are respected.

https://bugs.python.org/issue30587

@the-knights-who-say-ni
Copy link

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA).

Unfortunately we couldn't find an account corresponding to your GitHub username on bugs.python.org (b.p.o) to verify you have signed the CLA (this might be simply due to a missing "GitHub Name" entry in your b.p.o account settings). This is necessary for legal reasons before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

Thanks again to your contribution and we look forward to looking at it!

@Mariatta
Copy link
Member

Mariatta commented Jun 8, 2017

Thanks for the PR. This doesn't seem to be a trivial change. Can you please open an issue at https://bugs.python.org, and then reference the issue number in the PR title.

@claudiubelu
Copy link
Author

Hello. I actually reported a bug for this, but I didn't reference it in the commit message. Will do.

@claudiubelu claudiubelu changed the title Adds signature checking for mock autospec object method calls bpo-30587: Adds signature checking for mock autospec object method calls Jun 9, 2017
@claudiubelu claudiubelu force-pushed the mock-add-autospec branch 2 times, most recently from 90d48a0 to 51a9270 Compare November 20, 2017 14:37
@claudiubelu
Copy link
Author

@Mariatta Hi, can you take a look again? :)

Mock can accept an spec object / class as argument, making sure
that accessing attributes that do not exist in the spec will cause an
AttributeError to be raised, but there is no guarantee that the spec's
methods signatures are respected in any way. This creates the possibility
to have faulty code with passing unittests and assertions.

Example:

from unittest import mock

class Something(object):
    def foo(self, a, b, c, d):
        pass

m = mock.Mock(spec=Something)
m.foo()

Adds the autospec argument to Mock, and its mock_add_spec method.

Passes the spec's attribute with the same name to the child mock (spec-ing
the child), if the mock's autospec is True.

Sets _mock_check_sig if the given spec is callable.

Adds unit tests to validate the fact that the autospec method signatures are
respected.
@voidspace
Copy link
Contributor

I'm taking a look at this.

@voidspace
Copy link
Contributor

I'd like spec to have signature validation. I don't think the use case for "attribute validation only" (current spec behaviour) is very strong and I'd rather not add new keywords. The mock API is already too complex.

I'll take the existing PR and modify it to use spec instead of adding the new autospec.

@ben-reilly
Copy link

@voidspace Any status update on this change?

@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Feb 19, 2022
@MaxwellDupre
Copy link
Contributor

I have a small issue with _get_class method. It doesn't seem to be part of any module/standard lib.
Also, _get_class does not seem to appear in mock.py for 3.10.02 or 3.11.
Lastly, would it be possible to bring your patch up to latest 3.11?

@github-actions github-actions bot removed the stale Stale PR or inactive for long period of time. label Mar 17, 2022
@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Apr 16, 2022
@github-actions github-actions bot removed the stale Stale PR or inactive for long period of time. label Jul 28, 2022
@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Aug 28, 2022
@arhadthedev arhadthedev requested a review from cjw296 as a code owner February 5, 2023 17:11
@arhadthedev
Copy link
Member

@voidspace, would you mind to return to this PR? It would be great to have it finally merged in a worthy state after these three tumbly years. :)

@github-actions github-actions bot removed the stale Stale PR or inactive for long period of time. label Feb 6, 2023
@github-actions
Copy link

github-actions bot commented Mar 8, 2023

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Mar 8, 2023
@arhadthedev
Copy link
Member

@sobolevn (as a committer into mock.py who is still active)

@sobolevn sobolevn self-requested a review March 22, 2023 12:11
@github-actions github-actions bot removed the stale Stale PR or inactive for long period of time. label Mar 23, 2023
@github-actions
Copy link

This PR is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale Stale PR or inactive for long period of time. label Apr 23, 2023
@cjw296
Copy link
Contributor

cjw296 commented Apr 23, 2023

I'd like spec to have signature validation. I don't think the use case for "attribute validation only" (current spec behaviour) is very strong and I'd rather not add new keywords. The mock API is already too complex.

I'll take the existing PR and modify it to use spec instead of adding the new autospec.

@arhadthedev - I don't see that this feedback was addressed, and a few others appear to have raised issues in follow up.
It doesn't appear that @claudiubelu is still working on this patch so I'm going to close the PR.

It sounds like there's a good idea lurking here, but more discussion needs to happen on #74772 before a new PR is opened.

@cjw296 cjw296 closed this Apr 23, 2023
@claudiubelu
Copy link
Author

I'd like spec to have signature validation. I don't think the use case for "attribute validation only" (current spec behaviour) is very strong and I'd rather not add new keywords. The mock API is already too complex.

I'll take the existing PR and modify it to use spec instead of adding the new autospec.

Hello,

I haven't followed this in quite a while, and I've remembered this recently when I hit this issue again.

I technically agree with you, adding a new keyword may be a bit undesirable since it's already quite complex, but I'd have to say that changing the spec behaviour to the autospec one would be more confusing. That is because spec meaning is already well-established at this point and what it does, and there is already autospec in a few scenarios (mock.patch). Having mock.Mock spec behave like mock.patch autospec would be inconsistent and confusing.

So, it's not really a new keyword, this PR would just make the API more uniform, bringing the autospec capability to mock.Mock. Simplifying the API by reducing spec and autospec is another discussion, and a bit outside the scope of this PR, IMO.

I think we can reopen the PR. I can rebase it (though, I think it might be easier to cherry-pick the commit onto the current HEAD, though I'm not sure how to credit other contributors on this PR in that case), fix any failing test / linting issue if it appears (there is a new failing test, missing argument).

I have a small issue with _get_class method. It doesn't seem to be part of any module/standard lib. Also, _get_class does not seem to appear in mock.py for 3.10.02 or 3.11. Lastly, would it be possible to bring your patch up to latest 3.11?

_get_class was not touched / used in the original commit, and since then this issue has been addressed, _spec_class = type(spec) is now used instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting review stale Stale PR or inactive for long period of time.
Projects
None yet
Development

Successfully merging this pull request may close these issues.