From 1fbd19b8cb20d100d608f7c593732fa945401329 Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Tue, 22 Mar 2016 14:29:13 +0400 Subject: [PATCH 1/4] Fix pytest.mark.skip mark when used in strict mode --- AUTHORS | 1 + CHANGELOG.rst | 5 ++++- _pytest/skipping.py | 5 +++++ testing/test_skipping.py | 13 +++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index dfc0a542e..92750acc3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -69,6 +69,7 @@ Nicolas Delaby Pieter Mulder Piotr Banaszkiewicz Punyashloka Biswal +Quentin Pradet Ralf Schmitt Raphael Pierzina Ronny Pfannschmidt diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 93197bba9..a64d64a12 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,7 +7,9 @@ * -* +* Fix ``pytest.mark.skip`` mark when used in strict mode. + Thanks `@pquentin`_ for the PR and `@RonnyPfannschmidt`_ for + showing how to fix the bug. * Minor improvements and fixes to the documentation. Thanks `@omarkohl`_ for the PR. @@ -165,6 +167,7 @@ .. _@rabbbit: https://github.com/rabbbit .. _@hackebrot: https://github.com/hackebrot .. _@omarkohl: https://github.com/omarkohl +.. _@pquentin: https://github.com/pquentin 2.8.7 ===== diff --git a/_pytest/skipping.py b/_pytest/skipping.py index 69157f485..07359b5c2 100644 --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -30,6 +30,11 @@ def pytest_configure(config): nop.Exception = XFailed setattr(pytest, "xfail", nop) + config.addinivalue_line("markers", + "skip(reason=None): skip the given test function with an optional reason. " + "Example: skip(reason=\"no way of currently testing this\") skips the " + "test." + ) config.addinivalue_line("markers", "skipif(condition): skip the given test function if eval(condition) " "results in a True value. Evaluation happens within the " diff --git a/testing/test_skipping.py b/testing/test_skipping.py index 3464974e0..b872c8b6e 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -539,6 +539,19 @@ class TestSkip: "*1 passed*2 skipped*", ]) + def test_strict_and_skip(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.mark.skip + def test_hello(): + pass + """) + result = testdir.runpytest("-rs --strict") + result.stdout.fnmatch_lines([ + "*unconditional skip*", + "*1 skipped*", + ]) + class TestSkipif: def test_skipif_conditional(self, testdir): item = testdir.getitem(""" From 653a53226ac58e4e5482baf4a037054c7fb5998a Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Tue, 22 Mar 2016 15:26:56 +0400 Subject: [PATCH 2/4] Add strict parameter to xfail marker doc --- _pytest/skipping.py | 14 +++++++------- testing/test_skipping.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/_pytest/skipping.py b/_pytest/skipping.py index 07359b5c2..55a24ddb9 100644 --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -43,13 +43,13 @@ def pytest_configure(config): "http://pytest.org/latest/skipping.html" ) config.addinivalue_line("markers", - "xfail(condition, reason=None, run=True, raises=None): mark the the test function " - "as an expected failure if eval(condition) has a True value. " - "Optionally specify a reason for better reporting and run=False if " - "you don't even want to execute the test function. If only specific " - "exception(s) are expected, you can list them in raises, and if the test fails " - "in other ways, it will be reported as a true failure. " - "See http://pytest.org/latest/skipping.html" + "xfail(condition, reason=None, run=True, raises=None, strict=False): " + "mark the the test function as an expected failure if eval(condition) " + "has a True value. Optionally specify a reason for better reporting " + "and run=False if you don't even want to execute the test function. " + "If only specific exception(s) are expected, you can list them in " + "raises, and if the test fails in other ways, it will be reported as " + "a true failure. See http://pytest.org/latest/skipping.html" ) diff --git a/testing/test_skipping.py b/testing/test_skipping.py index b872c8b6e..194c8692b 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -825,7 +825,7 @@ def test_default_markers(testdir): result = testdir.runpytest("--markers") result.stdout.fnmatch_lines([ "*skipif(*condition)*skip*", - "*xfail(*condition, reason=None, run=True, raises=None)*expected failure*", + "*xfail(*condition, reason=None, run=True, raises=None, strict=False)*expected failure*", ]) def test_xfail_test_setup_exception(testdir): From 53d319144d59745d9370dd90a39f23b6f03ab3cb Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Tue, 22 Mar 2016 20:42:52 -0300 Subject: [PATCH 3/4] Mention Pytest::Framework PyPI classifier on docs --- doc/en/writing_plugins.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/en/writing_plugins.rst b/doc/en/writing_plugins.rst index 41fd0335e..9240a9aac 100644 --- a/doc/en/writing_plugins.rst +++ b/doc/en/writing_plugins.rst @@ -158,13 +158,22 @@ it in your setuptools-invocation: 'name_of_plugin = myproject.pluginmodule', ] }, + + # custom PyPI classifier for pytest plugins + classifiers=[ + "Framework :: Pytest", + ], ) If a package is installed this way, ``pytest`` will load ``myproject.pluginmodule`` as a plugin which can define `well specified hooks`_. +.. note:: + Make sure to include ``Framework :: Pytest`` in your list of + `PyPI classifiers `_ + to make it easy for users to find your plugin. Requiring/Loading plugins in a test module or conftest file From e048315d9b9a0cb6bdf55ad3d9b7d55f99a980b5 Mon Sep 17 00:00:00 2001 From: Omar Kohl Date: Mon, 28 Mar 2016 19:51:26 +0200 Subject: [PATCH 4/4] Adapt get_issues.py script for GitHub (instead of Bitbucket) --- extra/get_issues.py | 70 ++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/extra/get_issues.py b/extra/get_issues.py index 6437ba4c3..2a8f8c316 100644 --- a/extra/get_issues.py +++ b/extra/get_issues.py @@ -2,30 +2,34 @@ import json import py import textwrap -issues_url = "http://bitbucket.org/api/1.0/repositories/pytest-dev/pytest/issues" +issues_url = "https://api.github.com/repos/pytest-dev/pytest/issues" import requests + def get_issues(): - chunksize = 50 - start = 0 issues = [] + url = issues_url while 1: - post_data = {"accountname": "pytest-dev", - "repo_slug": "pytest", - "start": start, - "limit": chunksize} - print ("getting from", start) - r = requests.get(issues_url, params=post_data) + get_data = {"state": "all"} + r = requests.get(url, params=get_data) data = r.json() - issues.extend(data["issues"]) - if start + chunksize >= data["count"]: + if r.status_code == 403: + # API request limit exceeded + print(data['message']) + exit(1) + issues.extend(data) + + # Look for next page + links = requests.utils.parse_header_links(r.headers['Link']) + another_page = False + for link in links: + if link['rel'] == 'next': + url = link['url'] + another_page = True + if not another_page: return issues - start += chunksize -kind2num = "bug enhancement task proposal".split() - -status2num = "new open resolved duplicate invalid wontfix".split() def main(args): cachefile = py.path.local(args.cache) @@ -35,33 +39,38 @@ def main(args): else: issues = json.loads(cachefile.read()) - open_issues = [x for x in issues - if x["status"] in ("new", "open")] + open_issues = [x for x in issues if x["state"] == "open"] - def kind_and_id(x): - kind = x["metadata"]["kind"] - return kind2num.index(kind), len(issues)-int(x["local_id"]) - open_issues.sort(key=kind_and_id) + open_issues.sort(key=lambda x: x["number"]) report(open_issues) + +def _get_kind(issue): + labels = [l['name'] for l in issue['labels']] + for key in ('bug', 'enhancement', 'proposal'): + if key in labels: + return key + return 'issue' + + def report(issues): for issue in issues: - metadata = issue["metadata"] - priority = issue["priority"] title = issue["title"] - content = issue["content"] - kind = metadata["kind"] - status = issue["status"] - id = issue["local_id"] - link = "https://bitbucket.org/pytest-dev/pytest/issue/%s/" % id + body = issue["body"] + kind = _get_kind(issue) + status = issue["state"] + number = issue["number"] + link = "https://github.com/pytest-dev/pytest/issues/%s/" % number print("----") print(status, kind, link) print(title) #print() - #lines = content.split("\n") + #lines = body.split("\n") #print ("\n".join(lines[:3])) - #if len(lines) > 3 or len(content) > 240: + #if len(lines) > 3 or len(body) > 240: # print ("...") + print("\n\nFound %s open issues" % len(issues)) + if __name__ == "__main__": import argparse @@ -72,3 +81,4 @@ if __name__ == "__main__": help="cache file") args = parser.parse_args() main(args) +