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

Warns #897

Merged
merged 2 commits into from
Aug 4, 2015
Merged

Warns #897

merged 2 commits into from
Aug 4, 2015

Conversation

hunse
Copy link
Contributor

@hunse hunse commented Jul 28, 2015

The recwarn function argument is useful, but sometimes I just want to make sure that a warning of a particular type is thrown, and this takes a number of lines with recwarn. I added a warns fixture to ensure that warnings are thrown. Similar to raises, but for warnings.

@@ -120,6 +120,9 @@
2.7.3 (compared to 2.7.2)
-----------------------------

- Add 'warns' to assert that warnings are thrown (like 'raises').
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be in the changelog for 2.8.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh yeah, sorry, I rebased and forgot to move it.

(RuntimeWarning, SyntaxWarning),
lambda: warnings.warn('w3', UserWarning)))

@pytest.mark.skipif('sys.version < "2.5"')
Copy link
Member

Choose a reason for hiding this comment

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

This is not necessary as pytest supports 2.6+ only. 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, sweet! Again, just copying from raises.py.

@nicoddemus
Copy link
Member

Thanks for the PR @hunse! 😄

@nicoddemus
Copy link
Member

Hmmm could you write some docs for pytest.warns? I think you might add it to assert.txt... make sure to add a .. versionadded:: 2.8 directive as well. 😄

@hunse hunse force-pushed the warns branch 2 times, most recently from ed55cb0 to 684139b Compare July 29, 2015 15:56
@hunse
Copy link
Contributor Author

hunse commented Jul 29, 2015

Okay, doc is added.

warnings.warn("another warning", RuntimeWarning)

assert len(record) == 1 # check that only one warning was raised
assert record[0].message.message == "another warning"
Copy link
Member

Choose a reason for hiding this comment

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

message.message? Is this a typo?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, that's actually the way you have to do it, because of how warnings.WarningMessage is set up. WarningMessage.message returns the actual exception, not the message, so you have to call message again. Though your question made me realize that in Python3, warnings no longer have a message attribute, just an args one, so I've changed things to work in Python3 as well.

@nicoddemus
Copy link
Member

Nice @hunse, much appreciated!

If nobody has any more comments, I will merge this tomorrow. 😄

@hunse hunse force-pushed the warns branch 2 times, most recently from 3e6a12c to 8dc6102 Compare July 29, 2015 16:26
@hunse
Copy link
Contributor Author

hunse commented Jul 29, 2015

Okay, changed the docs around and added the link to recwarn. The only thing I'm worried about now is that the recwarn page says it's about "Asserting deprecation and other warnings", which makes it sound like it's the way to do that, and it's always confusing when there are two ways to do things. Should the recwarn page be rewritten so it's more about recording warnings? I'm not quite sure how I would word it, though.

@nicoddemus
Copy link
Member

Hmm good point. I see two options:

  • Add a link back to pytest.warns in recwarn, explaining its intended use for simple cases;
  • Move pytest.warns docs to recwarn and keep it all in the same place;

After your points I'm thinking the latter. What do you think?

@hunse
Copy link
Contributor Author

hunse commented Jul 29, 2015

Yeah, I'm thinking the same thing. I was also wondering if it would be good to have the same interface for warnings recorded by recwarn and those recorded by pytest.warns.

@hunse
Copy link
Contributor Author

hunse commented Jul 29, 2015

Though it might be nice to have something after pytest.raises that at least points to the recwarn document. I think a lot of people might read through pytest.raises and then think "but how do I do this for warnings?"

@nicoddemus
Copy link
Member

I was also wondering if it would be good to have the same interface for warnings recorded by recwarn and those recorded by pytest.warns.

I think so, but don't know how difficult that would be to implement.

I think a lot of people might read through pytest.raises and then think "but how do I do this for warnings?"

Agreed. How about a one liner after pytest.raises docs like: "To capture warnings, take a look at <link to recwarn>"?

@hunse
Copy link
Contributor Author

hunse commented Jul 30, 2015

Okay, warns and recwarn use the same code, now. It seems a lot cleaner. @nicoddemus, let me know what you think, and I'll update the documentation.

warnings.warn_explicit = oldwarn_explicit
warnings.warn = oldwarn
if not l:
__tracebackhide__ = True
Copy link
Member

Choose a reason for hiding this comment

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

Keep __tracebackhide__ in the body of the function, this way when it fails the traceback will point to the point of the call, not to the internal details of this function.

@nicoddemus
Copy link
Member

@hunse excellent work, thanks for the nice refactoring! 😄

@nicoddemus
Copy link
Member

About the docs, I think it makes sense to add pytest.warns together with other documentation related to warnings in recwarn.txt, what do you think?

@hunse
Copy link
Contributor Author

hunse commented Jul 30, 2015

Agreed.

warnings.simplefilter('default')
def reset_filters():
warnings.filters[:] = oldfilters
request.addfinalizer(reset_filters)
wrec = WarningsRecorder()
Copy link
Member

Choose a reason for hiding this comment

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

Minor: this fits nicely as a yield_fixture:

@pytest.yield_fixture
def recwarn():
    wrec = WarningsRecorder()
    with wrec:
        warnings.simplefilter('default')
        yield wrec

(should've seen it before, sorry! 😅)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh wow, that's cool. I didn't even know that was possible!

return iter(self._list)

def __len__(self):
return len(self._list)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nicoddemus: how would I add documentation for these kinds of methods in recwarn.txt? There seems like there should be a clearer way than just adding them as .. method::.

Copy link
Member

Choose a reason for hiding this comment

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

You can use auto directives from sphinx... you can see them in action here.

hunse added 2 commits July 30, 2015 23:28
Works in a similar manner to `raises`, but for warnings instead
of exceptions. Also refactored `recwarn.py` so that all the
warning recording and checking use the same core code.
@nicoddemus
Copy link
Member

@hunse could you fix the flakes error? After this I think we can merge this. 😄

@hunse
Copy link
Contributor Author

hunse commented Aug 4, 2015

I have no idea why it's getting that error. The Travis build says it ran on bd3877b, which is not the most recent update. Can you force it to rerun? There's no reason that it should not be able to import WarningsChecker from raises.py; in fact, the file that it's complaining about runs fine, i.e. it can import WarningsChecker. It doesn't make any sense because that file must have run as part of the test suite, which passed, so I don't know why flakes is finding problems.

@nicoddemus
Copy link
Member

Oh I didn't even saw the error when I commented... it seems like travis misinterpreted some rebase done in the branch. I tried re-submitting the job, but it insists on running against commit bd3877b...

Anyway, I just tested it and locally and everything passes, so we can ignore that error. 😄

nicoddemus added a commit that referenced this pull request Aug 4, 2015
@nicoddemus nicoddemus merged commit d761bff into pytest-dev:master Aug 4, 2015
@nicoddemus
Copy link
Member

Thanks a lot for the work @hunse!

Cheers,
🍻

@The-Compiler
Copy link
Member

Hm - it seems the same error shows up on Travis now that it's merged to master.

@nicoddemus
Copy link
Member

Oh dear... I will take a look at this later then. No idea why flakes is acting up (if anybody wants to take a shot a it, please be my guest);

@hunse
Copy link
Contributor Author

hunse commented Aug 4, 2015

The other thing that is very confusing (and makes it very annoying to debug) is that this error doesn't seem to appear when running flakes locally. At least I didn't have it appear on my machine, and @nicoddemus didn't see it either. Maybe this is a bug in flakes that was fixed, and Travis just needs an update?

@The-Compiler
Copy link
Member

Travis uses tox for the tests, so it should use a recent pyflakes version.

Maybe try running git clean -xdf to clean up any cache files etc.? (Make sure there's nothing important untracked in git status first)

@The-Compiler
Copy link
Member

I can actually reproduce this when doing -i ALL=https://devpi.net/hpk/dev/ - in my experience, devpi sometimes fails to pick up new upstream versions, so I'm guessing that's what's happening...

@hpk42 - can you force an update? Can we somehow make tox only use devpi for the needed packages (pylib I guess?) and use PyPI directly for everything else?

@nicoddemus
Copy link
Member

As a workaround, I moved import WarningsChecker to a local import and then flakes passed, but we should update flakes on devpi when we can.

@hpk42
Copy link
Contributor

hpk42 commented Sep 28, 2015

Seems like this PR broke issue #1037

hunse added a commit to hunse/pytest that referenced this pull request Sep 28, 2015
`deprecated_call` now looks for PendingDeprecationWarnings,
as it did previously but was broken by pytest-dev#897. Fixes pytest-dev#1037.

Also added a test so this does not happen again.
hunse added a commit to hunse/pytest that referenced this pull request Sep 28, 2015
`deprecated_call` used to accept any warning. As of pytest-dev#897, it
is now specific to DeprecationWarnings, and another commit in
this PR extends this to PendingDeprecationWarnings. This commit
makes sure this stays the case.
hunse added a commit to hunse/pytest that referenced this pull request Sep 28, 2015
`deprecated_call` used to accept any warning. As of pytest-dev#897, it
is now specific to DeprecationWarnings, and another commit in
this PR extends this to PendingDeprecationWarnings. This commit
makes sure this stays the case.
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.

4 participants