Repository: marshmallow-code/webargs

Issue:
Use tox for running tests and task running
https://github.com/marshmallow-code/marshmallow/issues/1020#issuecomment-433544037


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -2,8 +2,34 @@
 import re
 from setuptools import setup, find_packages
 
-# Requirements
-REQUIREMENTS = ["marshmallow>=2.15.2"]
+INSTALL_REQUIRES = ["marshmallow>=2.15.2"]
+FRAMEWORKS = [
+    "Flask>=0.10.1",
+    "Django>=1.6.5",
+    "bottle>=0.12.10",
+    "tornado>=4.0",
+    "pyramid>=1.5.2",
+    "webapp2>=3.0.0b1",
+    "falcon>=0.3.0",
+    'aiohttp>=3.0.0; python_version >= "3.5"',
+]
+EXTRAS_REQUIRE = {
+    "frameworks": FRAMEWORKS,
+    "tests": [
+        "pytest",
+        "mock",
+        "webtest==2.0.32",
+        'webtest-aiohttp==2.0.0; python_version >= "3.5"',
+        'pytest-aiohttp>=0.3.0; python_version >= "3.5"',
+    ]
+    + FRAMEWORKS,
+    "lint": [
+        "flake8==3.6.0",
+        'flake8-bugbear==18.8.0; python_version >= "3.5"',
+        "pre-commit==1.12.0",
+    ],
+}
+EXTRAS_REQUIRE["dev"] = EXTRAS_REQUIRE["tests"] + EXTRAS_REQUIRE["lint"] + ["tox"]
 
 
 def find_version(fname):
@@ -46,7 +72,8 @@ def read(fname):
     url="https://github.com/sloria/webargs",
     packages=find_packages(exclude=("test*", "examples")),
     package_dir={"webargs": "webargs"},
-    install_requires=REQUIREMENTS,
+    install_requires=INSTALL_REQUIRES,
+    extras_require=EXTRAS_REQUIRE,
     license="MIT",
     zip_safe=False,
     keywords=(
@@ -76,6 +103,7 @@ def read(fname):
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: Implementation :: CPython",
         "Programming Language :: Python :: Implementation :: PyPy",
         "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
diff --git a/tasks.py b/tasks.py
deleted file mode 100644
--- a/tasks.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# -*- coding: utf-8 -*-
-import os
-import sys
-import webbrowser
-
-from invoke import task
-
-docs_dir = "docs"
-build_dir = os.path.join(docs_dir, "_build")
-
-
-@task
-def test(ctx, syntax=True, coverage=False, browse=False):
-    import pytest
-
-    if syntax:
-        precommit(ctx)
-        flake(ctx)
-    args = []
-    if coverage:
-        args.extend(["--cov=webargs", "--cov-report=term", "--cov-report=html"])
-
-    ignores = []
-    if sys.version_info < (3,):
-        ignores += [
-            os.path.join("tests", "test_aiohttpparser.py"),
-            os.path.join("tests", "test_aiohttpparser_async_functions.py"),
-        ]
-    if ignores:
-        for each in ignores:
-            args.append("--ignore={0}".format(each))
-    retcode = pytest.main(args)
-    if coverage and browse:
-        webbrowser.open_new_tab(os.path.join("htmlcov", "index.html"))
-    sys.exit(retcode)
-
-
-@task
-def precommit(ctx):
-    ctx.run("pre-commit run --all-files --show-diff-on-failure", echo=True)
-
-
-@task
-def flake(ctx):
-    """Run flake8 on codebase."""
-    cmd = "flake8 ."
-    excludes = []
-    if sys.version_info < (3,):
-        excludes += [
-            os.path.join("webargs", "async_decorators.py"),
-            os.path.join("tests", "test_aiohttpparser_async_functions.py"),
-            os.path.join("tests", "apps", "aiohttp_app.py"),
-            os.path.join("tests", "test_aiohttparser.py"),
-            os.path.join("webargs", "asyncparser.py"),
-            os.path.join("webargs", "aiohttpparser.py"),
-            os.path.join("examples", "annotations_example.py"),
-            "build",
-        ]
-    if excludes:
-        cmd += " --exclude={0}".format(",".join(excludes))
-    ctx.run(cmd, echo=True)
-
-
-@task
-def clean(ctx):
-    ctx.run("rm -rf build")
-    ctx.run("rm -rf dist")
-    ctx.run("rm -rf webargs.egg-info")
-    clean_docs(ctx)
-    print("Cleaned up.")
-
-
-@task
-def readme(ctx, browse=False):
-    ctx.run("rst2html.py README.rst > README.html")
-    if browse:
-        webbrowser.open_new_tab("README.html")
-
-
-@task
-def clean_docs(ctx):
-    ctx.run("rm -rf %s" % build_dir)
-
-
-@task
-def browse_docs(ctx):
-    path = os.path.join(build_dir, "index.html")
-    webbrowser.open_new_tab(path)
-
-
-def build_docs(ctx, browse):
-    ctx.run("sphinx-build %s %s" % (docs_dir, build_dir), echo=True)
-    if browse:
-        browse_docs(ctx)
-
-
-@task
-def docs(ctx, clean=False, browse=False, watch=False):
-    """Build the docs."""
-    if clean:
-        clean_docs(ctx)
-    if watch:
-        watch_docs(ctx, browse=browse)
-    else:
-        build_docs(ctx, browse=browse)
-
-
-@task
-def watch_docs(ctx, browse=False):
-    """Run build the docs when a file changes."""
-    try:
-        import sphinx_autobuild  # noqa
-    except ImportError:
-        print("ERROR: watch task requires the sphinx_autobuild package.")
-        print("Install it with:")
-        print("    pip install sphinx-autobuild")
-        sys.exit(1)
-    ctx.run(
-        "sphinx-autobuild {0} {1} {2} -z webargs".format(
-            "--open-browser" if browse else "", docs_dir, build_dir
-        ),
-        echo=True,
-        pty=True,
-    )


Test patch:
diff --git a/tests/test_aiohttpparser.py b/tests/test_py3/test_aiohttpparser.py
similarity index 100%
rename from tests/test_aiohttpparser.py
rename to tests/test_py3/test_aiohttpparser.py
diff --git a/tests/test_aiohttpparser_async_functions.py b/tests/test_py3/test_aiohttpparser_async_functions.py
similarity index 100%
rename from tests/test_aiohttpparser_async_functions.py
rename to tests/test_py3/test_aiohttpparser_async_functions.py