Repository: hackebrot/pytest-cookies (language: python)

Issue:
Support python3.8 and python3.9
Currently, they are not:
1. Listed in `setup.py` as supported versions
2. Tested in CI
pytest<6.0.0 pin prevents installation
```
> tox -e py38
GLOB sdist-make: /home/jayvdb/projects/pytest/pytest-cookies/setup.py
"arrow<0.14.0"py38 create: /home/jayvdb/projects/pytest/pytest-cookies/.tox/py38
py38 installdeps: pytest
py38 inst: /home/jayvdb/projects/pytest/pytest-cookies/.tox/.tmp/package/1/pytest-cookies-0.5.1.zip
ERROR: invocation failed (exit code 1), logfile: /home/jayvdb/projects/pytest/pytest-cookies/.tox/py38/log/py38-2.log
===================================================================== log start =====================================================================
Processing ./.tox/.tmp/package/1/pytest-cookies-0.5.1.zip
Collecting cookiecutter<1.8.0,>=1.4.0
  Downloading cookiecutter-1.7.2-py2.py3-none-any.whl (34 kB)
Collecting pytest<6.0.0,>=3.3.0
  Using cached pytest-5.4.3-py3-none-any.whl (248 kB)
Requirement already satisfied: six>=1.10 in ./.tox/py38/lib/python3.8/site-packages (from cookiecutter<1.8.0,>=1.4.0->pytest-cookies==0.5.1) (1.15.0)
Collecting Jinja2<3.0.0
  Using cached Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
Collecting click>=7.0
  Using cached click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting binaryornot>=0.4.4
  Using cached binaryornot-0.4.4-py2.py3-none-any.whl (9.0 kB)
ERROR: Could not find a version that satisfies the requirement python-slugify>=4.0.0 (from cookiecutter<1.8.0,>=1.4.0->pytest-cookies==0.5.1) (from versions: none)
ERROR: No matching distribution found for python-slugify>=4.0.0 (from cookiecutter<1.8.0,>=1.4.0->pytest-cookies==0.5.1)
WARNING: You are using pip version 20.0.2; however, version 20.2.1 is available.
```


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/run-checks.yml b/.github/workflows/run-checks.yml
index fae4a9f..39df810 100644
--- a/.github/workflows/run-checks.yml
+++ b/.github/workflows/run-checks.yml
@@ -7,31 +7,33 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        platform: ["ubuntu-latest", "macos-latest", "windows-latest"]
-        environment: ["py35", "py36", "py37", "flake8"]
-        
+        os: ["ubuntu-latest", "macos-latest", "windows-latest"]
+        environment: ["py36", "py37", "py38", "py39", "flake8"]
+
         include:
-          - environment: "py35"
-            python: "3.5"
           - environment: "py36"
             python: "3.6"
           - environment: "py37"
             python: "3.7"
+          - environment: "py38"
+            python: "3.8"
+          - environment: "py39"
+            python: "3.9"
           - environment: "flake8"
             python: "3.7"
 
-    runs-on: ${{ matrix.platform }}
+    runs-on: ${{ matrix.os }}
 
     steps:
-    - uses: actions/checkout@v2
-    - name: Set up Python ${{ matrix.python }}
-      uses: actions/setup-python@v1
-      with:
-        python-version: ${{ matrix.python }}
-    - name: Install tox
-      run: |
-        python -m pip install --upgrade pip
-        python -m pip install tox
-    - name: Run tox
-      run: |
-        tox -e ${{ matrix.environment }}
+      - uses: actions/checkout@v2
+      - name: Set up Python ${{ matrix.python }}
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.python }}
+      - name: Install tox
+        run: |
+          python -m pip install --upgrade pip
+          python -m pip install tox
+      - name: Run tox
+        run: |
+          tox -e ${{ matrix.environment }}
diff --git a/.github/workflows/upload-to-pypi.yml b/.github/workflows/upload-to-pypi.yml
index 903c86d..2bc6e4d 100644
--- a/.github/workflows/upload-to-pypi.yml
+++ b/.github/workflows/upload-to-pypi.yml
@@ -8,21 +8,21 @@ jobs:
   upload:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v2
-    - name: Set up Python
-      uses: actions/setup-python@v1
-      with:
-        python-version: "3.7"
-    - name: Install dependencies
-      run: |
-        python -m pip install --upgrade pip
-        python -m pip install setuptools wheel twine
-    - name: Package project
-      run: |
-        python setup.py sdist bdist_wheel
-    - name: Upload distributions
-      env:
-        TWINE_USERNAME: __token__
-        TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
-      run: |
-        twine upload dist/*
+      - uses: actions/checkout@v2
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: "3.7"
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          python -m pip install setuptools wheel twine
+      - name: Package project
+        run: |
+          python setup.py sdist bdist_wheel
+      - name: Upload distributions
+        env:
+          TWINE_USERNAME: __token__
+          TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
+        run: |
+          twine upload dist/*
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 8757727..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-dist: xenial
-language: python
-
-cache:
-  directories:
-    - $HOME/.cache/pip
-
-matrix:
-    include:
-      - python: 2.7
-        env: TOXENV=py27
-      - python: 3.4
-        env: TOXENV=py34
-      - python: 3.5
-        env: TOXENV=py35
-      - python: 3.6
-        env: TOXENV=py36
-      - python: 3.7
-        env: TOXENV=py37
-      - python: pypy
-        env: TOXENV=pypy
-      - python: 3.7
-        env: TOXENV=flake8
-
-install:
-  - pip install tox
-
-script:
-  - tox
diff --git a/COMMUNITY.md b/COMMUNITY.md
index e01174a..1ad16e2 100644
--- a/COMMUNITY.md
+++ b/COMMUNITY.md
@@ -11,11 +11,13 @@
 - [@insspb]
 - [@jakirkham]
 - [@jamesmyatt]
+- [@jayvdb]
 - [@jsmedmar]
 - [@jyrno42]
 - [@nedbat]
 - [@obestwalter]
 - [@pydanny]
+- [@sobolevn]
 
 [@insspb]: https://github.com/insspb
 [@jakirkham]: https://github.com/jakirkham
@@ -25,3 +27,5 @@
 [@nedbat]: https://github.com/nedbat
 [@obestwalter]: https://github.com/obestwalter
 [@pydanny]: https://github.com/pydanny
+[@jayvdb]: https://github.com/jayvdb
+[@sobolevn]: https://github.com/sobolevn
diff --git a/README.md b/README.md
index 04e58f3..5cca434 100644
--- a/README.md
+++ b/README.md
@@ -33,10 +33,19 @@ def test_bake_project(cookies):
 
     assert result.exit_code == 0
     assert result.exception is None
+
+    assert result.project_path.name == "helloworld"
+    assert result.project_path.is_dir()
+
+    # The `project` attribute is deprecated
     assert result.project.basename == "helloworld"
     assert result.project.isdir()
 ```
 
+**Please note that the `project` attribute of the returned `Result` class is
+deprecated and will be removed in a future release, please use `project_path`
+instead.**
+
 The ``cookies.bake()`` method also accepts the ``extra_context`` keyword
 argument that will be passed to cookiecutter. The given dictionary will
 override the default values of the template context, effectively allowing you
@@ -76,8 +85,9 @@ def test_bake_custom_project(cookies, custom_template):
 
     assert result.exit_code == 0
     assert result.exception is None
-    assert result.project.basename == "example-project"
-    assert result.project.isdir()
+
+    assert result.project_path.name == "example-project"
+    assert result.project_path.is_dir()
 ```
 
 ## Keep output directories for debugging
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 72ac24b..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-environment:
-  matrix:
-  - TOXENV: py27
-  - TOXENV: py34
-  - TOXENV: py35
-  - TOXENV: py36
-  - TOXENV: py37
-
-build: off
-
-install:
-- pip install tox
-
-test_script:
-- tox
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 3c237e5..5b2cda5 100644
--- a/setup.py
+++ b/setup.py
@@ -13,7 +13,7 @@ def read(fname):
 
 setuptools.setup(
     name="pytest-cookies",
-    version="0.5.1",
+    version="0.6.0",
     author="Raphael Pierzina",
     author_email="raphael@hackebrot.de",
     maintainer="Raphael Pierzina",
@@ -31,22 +31,21 @@ def read(fname):
     package_dir={"": "src"},
     include_package_data=True,
     zip_safe=False,
-    python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
+    python_requires=">=3.6",
     install_requires=[
-        "arrow<0.14.0", "cookiecutter>=1.4.0,<1.8.0", "pytest>=3.3.0,<6.0.0"
+        "cookiecutter>=1.4.0",
+        "pytest>=3.3.0",
     ],
     classifiers=[
         "Development Status :: 5 - Production/Stable",
         "Intended Audience :: Developers",
         "License :: OSI Approved :: MIT License",
         "Operating System :: OS Independent",
-        "Programming Language :: Python :: 2",
-        "Programming Language :: Python :: 2.7",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.4",
-        "Programming Language :: Python :: 3.5",
+        "Programming Language :: Python :: 3 :: Only",
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: Implementation :: CPython",
         "Programming Language :: Python",
         "Topic :: Software Development :: Testing",
diff --git a/tox.ini b/tox.ini
index 0d37769..2c0f673 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,9 +1,12 @@
 [tox]
-envlist = py27,py34,py35,py36,py37,flake8
+envlist = py{36,37,38,39}-pytest{3,4,5,6},flake8
 
 [testenv]
-download = true
-deps = pytest
+deps =
+  pytest3: pytest>=3,<4
+  pytest4: pytest>=4,<5
+  pytest5: pytest>=5,<6
+  pytest6: pytest>=6,<7
 commands = pytest {posargs:tests}
 
 [testenv:flake8]


Test patch:
diff --git a/src/pytest_cookies/plugin.py b/src/pytest_cookies/plugin.py
index d1b016b..b6f91d1 100644
--- a/src/pytest_cookies/plugin.py
+++ b/src/pytest_cookies/plugin.py
@@ -1,12 +1,13 @@
 # -*- coding: utf-8 -*-
 
 import os
+import pathlib
+import warnings
 
 import py
 import pytest
-
-from cookiecutter.main import cookiecutter
 from cookiecutter.generate import generate_context
+from cookiecutter.main import cookiecutter
 from cookiecutter.prompt import prompt_for_config
 
 USER_CONFIG = u"""
@@ -26,11 +27,32 @@ def __init__(self, exception=None, exit_code=0, project_dir=None, context=None):
 
     @property
     def project(self):
+        """Return a py.path.local object if no exception occurred."""
+        warning_message = (
+            "project is deprecated and will be removed in a future release, "
+            "please use project_path instead."
+        )
+
+        warnings.warn(
+            warning_message,
+            DeprecationWarning,
+            stacklevel=1,
+        )
+
         if self.exception is None:
             return py.path.local(self._project_dir)
 
         return None
 
+    @property
+    def project_path(self):
+        """Return a pathlib.Path object if no exception occurred."""
+
+        if self.exception is None:
+            return pathlib.Path(self._project_dir)
+
+        return None
+
     def __repr__(self):
         if self.exception:
             return "<Result {!r}>".format(self.exception)
@@ -167,7 +189,7 @@ def pytest_addoption(parser):
         default=".",
         dest="template",
         help="specify the template to be rendered",
-        type="string",
+        type=str,
     )
 
     group.addoption(
diff --git a/tests/test_cookies.py b/tests/test_cookies.py
index 9041e06..3170f7e 100644
--- a/tests/test_cookies.py
+++ b/tests/test_cookies.py
@@ -101,8 +101,52 @@ def test_bake_project(cookies):
 
             assert result.exit_code == 0
             assert result.exception is None
+
+            assert result.project_path.name == 'helloworld'
+            assert result.project_path.is_dir()
+            assert str(result) == '<Result {}>'.format(result.project_path)
+
             assert result.project.basename == 'helloworld'
             assert result.project.isdir()
+            assert str(result) == '<Result {}>'.format(result.project)
+    """
+    )
+
+    result = testdir.runpytest("-v", "--template={}".format(cookiecutter_template))
+
+    result.stdout.fnmatch_lines(["*::test_bake_project PASSED*"])
+
+
+def test_cookies_bake_project_warning(testdir, cookiecutter_template):
+    """Programmatically create a **Cookiecutter** template and use `bake` to
+    create a project from it and check for warnings when accesssing the project
+    attribute.
+    """
+    testdir.makepyfile(
+        """
+        # -*- coding: utf-8 -*-
+        import warnings
+
+        def test_bake_project(cookies):
+            warning_message = (
+                "project is deprecated and will be removed in a future release, "
+                "please use project_path instead."
+            )
+
+            result = cookies.bake(extra_context={'repo_name': 'helloworld'})
+
+            assert result.exit_code == 0
+            assert result.exception is None
+
+            with warnings.catch_warnings(record=True) as w:
+                warnings.simplefilter("always")
+                project_basename = result.project.basename
+
+            assert project_basename == 'helloworld'
+
+            [warning] = w
+            assert issubclass(warning.category, DeprecationWarning)
+            assert str(warning.message) == warning_message
 
             assert str(result) == '<Result {}>'.format(result.project)
     """