From 8472dab1086325327af09a13a3df88ca1ebac900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ionel=20Cristian=20M=C4=83rie=C8=99?= Date: Sun, 11 Apr 2021 16:43:49 +0300 Subject: [PATCH] Update skel and test deps. --- .bumpversion.cfg | 7 +- .cookiecutterrc | 27 +++++-- .editorconfig | 11 ++- .gitignore | 11 ++- .pre-commit-config.yaml | 20 +++++ .readthedocs.yml | 10 +++ .travis.yml | 165 ++++++++++++++++++++++++++++++++-------- CHANGELOG.rst | 2 +- CONTRIBUTING.rst | 11 +-- LICENSE | 3 +- MANIFEST.in | 4 +- README.rst | 54 +++++++++---- ci/bootstrap.py | 60 +++++++++++---- ci/requirements.txt | 4 + docs/conf.py | 11 +-- docs/index.rst | 1 - docs/requirements.txt | 1 - setup.cfg | 17 +++-- setup.py | 25 ++++-- tests/test_app/tests.py | 1 + tox.ini | 83 ++++++++++---------- 21 files changed, 379 insertions(+), 149 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 .readthedocs.yml create mode 100644 ci/requirements.txt mode change 100644 => 100755 setup.py diff --git a/.bumpversion.cfg b/.bumpversion.cfg index e8c4464..03785c0 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -8,14 +8,13 @@ search = version='{current_version}' replace = version='{new_version}' [bumpversion:file:README.rst] -search = v{current_version}. -replace = v{new_version}. +search = /v{current_version}.svg +replace = /v{new_version}.svg [bumpversion:file:docs/conf.py] search = version = release = '{current_version}' replace = version = release = '{new_version}' -[bumpversion:file:src/prefetch.py] +[bumpversion:file:src/prefetch/__init__.py] search = __version__ = '{current_version}' replace = __version__ = '{new_version}' - diff --git a/.cookiecutterrc b/.cookiecutterrc index 6a2f560..60f35db 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -1,38 +1,53 @@ # Generated by cookiepatcher, a small shim around cookiecutter (pip install cookiepatcher) -cookiecutter: - _template: gh:ionelmc/cookiecutter-pylibrary +default_context: + allow_tests_inside_package: no appveyor: no c_extension_function: '-' c_extension_module: '-' c_extension_optional: no c_extension_support: no + c_extension_test_pypi: no + c_extension_test_pypi_username: '-' codacy: yes + codacy_projectid: 11d1f80103ca434db15e2804b61c522f codeclimate: yes codecov: yes command_line_interface: no command_line_interface_bin_name: '-' coveralls: yes + coveralls_token: '[Required for Appveyor, take it from https://coveralls.io/github/ionelmc/django-prefetch]' distribution_name: django-prefetch email: contact@ionelmc.ro full_name: Ionel Cristian Mărieș - github_username: ionelmc - landscape: no + legacy_python: yes license: BSD 2-Clause License linter: flake8 package_name: prefetch + pre_commit: yes project_name: django-prefetch project_short_description: Simple and generic model related data prefetch framework for Django solving the "1+N queries" problem that happens when you need related data for your objects. + pypi_badge: yes + pypi_disable_upload: no release_date: today + repo_hosting: github.com + repo_hosting_domain: github.com repo_name: django-prefetch + repo_username: ionelmc requiresio: yes scrutinizer: yes + setup_py_uses_setuptools_scm: no + setup_py_uses_test_runner: no + sphinx_docs: yes + sphinx_docs_hosting: https://django-prefetch.readthedocs.io/ sphinx_doctest: no sphinx_theme: sphinx-py3doc-enhanced-theme test_matrix_configurator: no test_matrix_separate_coverage: no test_runner: pytest travis: yes - version: 1.1.0 + travis_osx: no + version: 1.2.1 website: http://blog.ionelmc.ro - year: 2012-2017 + year_from: '2012' + year_to: '2021' diff --git a/.editorconfig b/.editorconfig index 4000618..586c736 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,13 +1,20 @@ -# see http://editorconfig.org +# see https://editorconfig.org/ root = true [*] +# Use Unix-style newlines for most files (except Windows files, see below). end_of_line = lf trim_trailing_whitespace = true -insert_final_newline = true indent_style = space +insert_final_newline = true indent_size = 4 charset = utf-8 [*.{bat,cmd,ps1}] end_of_line = crlf + +[*.{yml,yaml}] +indent_size = 2 + +[*.tsv] +indent_style = tab diff --git a/.gitignore b/.gitignore index 5a2da94..83a43fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.py[cod] +__pycache__ # C extensions *.so @@ -21,6 +22,7 @@ lib lib64 venv*/ pyvenv*/ +pip-wheel-metadata/ # Installer logs pip-log.txt @@ -37,11 +39,14 @@ htmlcov # Translations *.mo -# Mr Developer +# Buildout .mr.developer.cfg + +# IDE project files .project .pydevproject .idea +.vscode *.iml *.komodoproject @@ -60,6 +65,10 @@ docs/_build .env .cache .pytest +.benchmarks .bootstrap .appveyor.token *.bak + +# Mypy Cache +.mypy_cache/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..6e974cb --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,20 @@ +# To install the git pre-commit hook run: +# pre-commit install +# To update the pre-commit hooks run: +# pre-commit install-hooks +exclude: '^(\.tox|ci/templates|\.bumpversion\.cfg)(/|$)' +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: master + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: debug-statements + - repo: https://github.com/timothycrosley/isort + rev: master + hooks: + - id: isort + - repo: https://gitlab.com/pycqa/flake8 + rev: master + hooks: + - id: flake8 diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..59ff5c0 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,10 @@ +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +version: 2 +sphinx: + configuration: docs/conf.py +formats: all +python: + install: + - requirements: docs/requirements.txt + - method: pip + path: . diff --git a/.travis.yml b/.travis.yml index acb5941..b07ea5a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,71 +19,176 @@ matrix: - python: '2.7' env: - TOXENV=py27-dj111,report,coveralls,codecov - - python: '3.4' + - python: '3.6' + env: + - TOXENV=py36-dj19,report,coveralls,codecov + - python: '3.6' + env: + - TOXENV=py36-dj110,report,coveralls,codecov + - python: '3.6' + env: + - TOXENV=py36-dj111,report,coveralls,codecov + - python: '3.7' + dist: xenial + sudo: required + env: + - TOXENV=py37-dj19,report,coveralls,codecov + - python: '3.7' + dist: xenial + sudo: required + env: + - TOXENV=py37-dj110,report,coveralls,codecov + - python: '3.7' + dist: xenial + sudo: required + env: + - TOXENV=py37-dj111,report,coveralls,codecov + - python: '3.8' env: - - TOXENV=py34-dj19,report,coveralls,codecov - - python: '3.4' + - TOXENV=py38-dj19,report,coveralls,codecov + - python: '3.8' env: - - TOXENV=py34-dj110,report,coveralls,codecov - - python: '3.4' + - TOXENV=py38-dj110,report,coveralls,codecov + - python: '3.8' env: - - TOXENV=py34-dj111,report,coveralls,codecov - - python: '3.4' + - TOXENV=py38-dj111,report,coveralls,codecov + - python: '3.9' env: - - TOXENV=py34-dj20,report,coveralls,codecov - - python: '3.5' + - TOXENV=py39-dj19,report,coveralls,codecov + - python: '3.9' env: - - TOXENV=py35-dj19,report,coveralls,codecov - - python: '3.5' + - TOXENV=py39-dj110,report,coveralls,codecov + - python: '3.9' env: - - TOXENV=py35-dj110,report,coveralls,codecov - - python: '3.5' + - TOXENV=py39-dj111,report,coveralls,codecov + - python: 'pypy-5.4' env: - - TOXENV=py35-dj111,report,coveralls,codecov - - python: '3.5' + - TOXENV=pypy-dj19,report,coveralls,codecov + - python: 'pypy-5.4' + env: + - TOXENV=pypy-dj110,report,coveralls,codecov + - python: 'pypy-5.4' env: - - TOXENV=py35-dj20,report,coveralls,codecov + - TOXENV=pypy-dj111,report,coveralls,codecov - python: '3.6' env: - - TOXENV=py36-dj19,report,coveralls,codecov + - TOXENV=py36-dj111,report,coveralls,codecov - python: '3.6' env: - - TOXENV=py36-dj110,report,coveralls,codecov + - TOXENV=py36-dj20,report,coveralls,codecov - python: '3.6' env: - - TOXENV=py36-dj111,report,coveralls,codecov + - TOXENV=py36-dj21,report,coveralls,codecov + - python: '3.6' + env: + - TOXENV=py36-dj22,report,coveralls,codecov + - python: '3.6' + env: + - TOXENV=py36-dj30,report,coveralls,codecov + - python: '3.6' + env: + - TOXENV=py36-dj31,report,coveralls,codecov - python: '3.6' env: - - TOXENV=py36-dj20,report,coveralls,codecov + - TOXENV=py36-dj32,report,coveralls,codecov - python: '3.7' dist: xenial sudo: required env: - - TOXENV=py37-dj19,report,coveralls,codecov + - TOXENV=py37-dj111,report,coveralls,codecov - python: '3.7' dist: xenial sudo: required env: - - TOXENV=py37-dj110,report,coveralls,codecov + - TOXENV=py37-dj20,report,coveralls,codecov - python: '3.7' dist: xenial sudo: required env: - - TOXENV=py37-dj111,report,coveralls,codecov + - TOXENV=py37-dj21,report,coveralls,codecov - python: '3.7' dist: xenial sudo: required env: - - TOXENV=py37-dj20,report,coveralls,codecov - - python: 'pypy2' + - TOXENV=py37-dj22,report,coveralls,codecov + - python: '3.7' + dist: xenial + sudo: required env: - - TOXENV=pypy-dj19,report,coveralls,codecov - - python: 'pypy2' + - TOXENV=py37-dj30,report,coveralls,codecov + - python: '3.7' + dist: xenial + sudo: required env: - - TOXENV=pypy-dj110,report,coveralls,codecov - - python: 'pypy2' + - TOXENV=py37-dj31,report,coveralls,codecov + - python: '3.7' + dist: xenial + sudo: required env: - - TOXENV=pypy-dj111,report,coveralls,codecov + - TOXENV=py37-dj32,report,coveralls,codecov + - python: '3.8' + env: + - TOXENV=py38-dj111,report,coveralls,codecov + - python: '3.8' + env: + - TOXENV=py38-dj20,report,coveralls,codecov + - python: '3.8' + env: + - TOXENV=py38-dj21,report,coveralls,codecov + - python: '3.8' + env: + - TOXENV=py38-dj22,report,coveralls,codecov + - python: '3.8' + env: + - TOXENV=py38-dj30,report,coveralls,codecov + - python: '3.8' + env: + - TOXENV=py38-dj31,report,coveralls,codecov + - python: '3.8' + env: + - TOXENV=py38-dj32,report,coveralls,codecov + - python: '3.9' + env: + - TOXENV=py39-dj111,report,coveralls,codecov + - python: '3.9' + env: + - TOXENV=py39-dj20,report,coveralls,codecov + - python: '3.9' + env: + - TOXENV=py39-dj21,report,coveralls,codecov + - python: '3.9' + env: + - TOXENV=py39-dj22,report,coveralls,codecov + - python: '3.9' + env: + - TOXENV=py39-dj30,report,coveralls,codecov + - python: '3.9' + env: + - TOXENV=py39-dj31,report,coveralls,codecov + - python: '3.9' + env: + - TOXENV=py39-dj32,report,coveralls,codecov + - python: 'pypy3-5.4' + env: + - TOXENV=pypy3-dj111,report,coveralls,codecov + - python: 'pypy3-5.4' + env: + - TOXENV=pypy3-dj20,report,coveralls,codecov + - python: 'pypy3-5.4' + env: + - TOXENV=pypy3-dj21,report,coveralls,codecov + - python: 'pypy3-5.4' + env: + - TOXENV=pypy3-dj22,report,coveralls,codecov + - python: 'pypy3-5.4' + env: + - TOXENV=pypy3-dj30,report,coveralls,codecov + - python: 'pypy3-5.4' + env: + - TOXENV=pypy3-dj31,report,coveralls,codecov + - python: 'pypy3-5.4' + env: + - TOXENV=pypy3-dj32,report,coveralls,codecov before_install: - python --version - uname -a diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 65ed8e3..ccd248b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,7 +2,7 @@ Changelog ========= -1.2.2 (2021-02-14) +1.2.2 (2021-04-11) ------------------ * Added support for Django 2.0 diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 91f5aab..7416f1d 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -41,7 +41,7 @@ To set up `django-prefetch` for local development: (look for the "Fork" button). 2. Clone your fork locally:: - git clone git@github.com:your_name_here/django-prefetch.git + git clone git@github.com:YOURGITHUBNAME/django-prefetch.git 3. Create a branch for local development:: @@ -49,7 +49,7 @@ To set up `django-prefetch` for local development: Now you can make your changes locally. -4. When you're done making changes, run all the checks, doc builder and spell checker with `tox `_ one command:: +4. When you're done making changes run all the checks and docs builder with `tox `_ one command:: tox @@ -74,7 +74,8 @@ For merging, you should: 4. Add yourself to ``AUTHORS.rst``. .. [1] If you don't have all the necessary python versions available locally you can rely on Travis - it will - `run the tests `_ for each change you add in the pull request. + `run the tests `_ + for each change you add in the pull request. It will be slower though ... @@ -85,6 +86,6 @@ To run a subset of tests:: tox -e envname -- pytest -k test_myfeature -To run all the test environments in *parallel* (you need to ``pip install detox``):: +To run all the test environments in *parallel*:: - detox + tox -p auto diff --git a/LICENSE b/LICENSE index 3ede4bb..663bfe2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,6 @@ BSD 2-Clause License -Copyright (c) 2012-2017, Ionel Cristian Mărieș -All rights reserved. +Copyright (c) 2012-2021, Ionel Cristian Mărieș. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/MANIFEST.in b/MANIFEST.in index 3ae9b54..cc2fdc5 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -14,6 +14,6 @@ include CONTRIBUTING.rst include LICENSE include README.rst -include tox.ini .travis.yml appveyor.yml +include tox.ini .travis.yml .appveyor.yml .readthedocs.yml .pre-commit-config.yaml -global-exclude *.py[cod] __pycache__ *.so *.dylib +global-exclude *.py[cod] __pycache__/* *.so *.dylib diff --git a/README.rst b/README.rst index 44883ed..07fbd31 100644 --- a/README.rst +++ b/README.rst @@ -16,14 +16,13 @@ Overview * - package - | |version| |wheel| |supported-versions| |supported-implementations| | |commits-since| - .. |docs| image:: https://readthedocs.org/projects/django-prefetch/badge/?style=flat - :target: https://readthedocs.org/projects/django-prefetch + :target: https://django-prefetch.readthedocs.io/ :alt: Documentation Status -.. |travis| image:: https://travis-ci.org/ionelmc/django-prefetch.svg?branch=master +.. |travis| image:: https://api.travis-ci.com/ionelmc/django-prefetch.svg?branch=master :alt: Travis-CI Build Status - :target: https://travis-ci.org/ionelmc/django-prefetch + :target: https://travis-ci.com/github/ionelmc/django-prefetch .. |requires| image:: https://requires.io/github/ionelmc/django-prefetch/requirements.svg?branch=master :alt: Requirements Status @@ -33,11 +32,11 @@ Overview :alt: Coverage Status :target: https://coveralls.io/r/ionelmc/django-prefetch -.. |codecov| image:: https://codecov.io/github/ionelmc/django-prefetch/coverage.svg?branch=master +.. |codecov| image:: https://codecov.io/gh/ionelmc/django-prefetch/branch/master/graphs/badge.svg?branch=master :alt: Coverage Status :target: https://codecov.io/github/ionelmc/django-prefetch -.. |codacy| image:: https://img.shields.io/codacy/REPLACE_WITH_PROJECT_ID.svg +.. |codacy| image:: https://img.shields.io/codacy/grade/11d1f80103ca434db15e2804b61c522f.svg :target: https://www.codacy.com/app/ionelmc/django-prefetch :alt: Codacy Code Quality Status @@ -47,25 +46,26 @@ Overview .. |version| image:: https://img.shields.io/pypi/v/django-prefetch.svg :alt: PyPI Package latest release - :target: https://pypi.python.org/pypi/django-prefetch - -.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/django-prefetch/v1.2.1.svg - :alt: Commits since latest release - :target: https://github.com/ionelmc/django-prefetch/compare/v1.2.1...master + :target: https://pypi.org/project/django-prefetch .. |wheel| image:: https://img.shields.io/pypi/wheel/django-prefetch.svg :alt: PyPI Wheel - :target: https://pypi.python.org/pypi/django-prefetch + :target: https://pypi.org/project/django-prefetch .. |supported-versions| image:: https://img.shields.io/pypi/pyversions/django-prefetch.svg :alt: Supported versions - :target: https://pypi.python.org/pypi/django-prefetch + :target: https://pypi.org/project/django-prefetch .. |supported-implementations| image:: https://img.shields.io/pypi/implementation/django-prefetch.svg :alt: Supported implementations - :target: https://pypi.python.org/pypi/django-prefetch + :target: https://pypi.org/project/django-prefetch -.. |scrutinizer| image:: https://img.shields.io/scrutinizer/g/ionelmc/django-prefetch/master.svg +.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/django-prefetch/v1.2.1.svg + :alt: Commits since latest release + :target: https://github.com/ionelmc/django-prefetch/compare/v1.2.1...master + + +.. |scrutinizer| image:: https://img.shields.io/scrutinizer/quality/g/ionelmc/django-prefetch/master.svg :alt: Scrutinizer Status :target: https://scrutinizer-ci.com/g/ionelmc/django-prefetch/ @@ -201,3 +201,27 @@ TODO * Document ``collect`` option of ``Prefetcher`` * Create tests covering custom ``collect`` and ``mapper`` + +Development +=========== + +To run all the tests run:: + + tox + +Note, to combine the coverage data from all the tox environments run: + +.. list-table:: + :widths: 10 90 + :stub-columns: 1 + + - - Windows + - :: + + set PYTEST_ADDOPTS=--cov-append + tox + + - - Other + - :: + + PYTEST_ADDOPTS=--cov-append tox diff --git a/ci/bootstrap.py b/ci/bootstrap.py index e5292aa..2eb7723 100755 --- a/ci/bootstrap.py +++ b/ci/bootstrap.py @@ -1,18 +1,26 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from __future__ import absolute_import, print_function, unicode_literals +from __future__ import absolute_import +from __future__ import print_function +from __future__ import unicode_literals import os +import subprocess import sys from os.path import abspath from os.path import dirname from os.path import exists from os.path import join +base_path = dirname(dirname(abspath(__file__))) -if __name__ == "__main__": - base_path = dirname(dirname(abspath(__file__))) - print("Project path: {0}".format(base_path)) + +def check_call(args): + print("+", *args) + subprocess.check_call(args) + + +def exec_in_env(): env_path = join(base_path, ".tox", "bootstrap") if sys.platform == "win32": bin_path = join(env_path, "Scripts") @@ -23,18 +31,27 @@ print("Making bootstrap env in: {0} ...".format(env_path)) try: - subprocess.check_call(["virtualenv", env_path]) + check_call([sys.executable, "-m", "venv", env_path]) except subprocess.CalledProcessError: - subprocess.check_call([sys.executable, "-m", "virtualenv", env_path]) + try: + check_call([sys.executable, "-m", "virtualenv", env_path]) + except subprocess.CalledProcessError: + check_call(["virtualenv", env_path]) print("Installing `jinja2` into bootstrap environment...") - subprocess.check_call([join(bin_path, "pip"), "install", "jinja2"]) - activate = join(bin_path, "activate_this.py") - # noinspection PyCompatibility - exec(compile(open(activate, "rb").read(), activate, "exec"), dict(__file__=activate)) + check_call([join(bin_path, "pip"), "install", "jinja2", "tox"]) + python_executable = join(bin_path, "python") + if not os.path.exists(python_executable): + python_executable += '.exe' + + print("Re-executing with: {0}".format(python_executable)) + print("+ exec", python_executable, __file__, "--no-env") + os.execv(python_executable, [python_executable, __file__, "--no-env"]) + +def main(): import jinja2 - import subprocess + print("Project path: {0}".format(base_path)) jinja = jinja2.Environment( loader=jinja2.FileSystemLoader(join(base_path, "ci", "templates")), @@ -45,13 +62,28 @@ tox_environments = [ line.strip() - # WARNING: 'tox' must be installed globally or in the project's virtualenv - for line in subprocess.check_output(['tox', '--listenvs'], universal_newlines=True).splitlines() + # 'tox' need not be installed globally, but must be importable + # by the Python that is running this script. + # This uses sys.executable the same way that the call in + # cookiecutter-pylibrary/hooks/post_gen_project.py + # invokes this bootstrap.py itself. + for line in subprocess.check_output([sys.executable, '-m', 'tox', '--listenvs'], universal_newlines=True).splitlines() ] - tox_environments = [line for line in tox_environments if line not in ['clean', 'report', 'docs', 'check']] + tox_environments = [line for line in tox_environments if line.startswith('py')] for name in os.listdir(join("ci", "templates")): with open(join(base_path, name), "w") as fh: fh.write(jinja.get_template(name).render(tox_environments=tox_environments)) print("Wrote {}".format(name)) print("DONE.") + + +if __name__ == "__main__": + args = sys.argv[1:] + if args == ["--no-env"]: + main() + elif not args: + exec_in_env() + else: + print("Unexpected arguments {0}".format(args), file=sys.stderr) + sys.exit(1) diff --git a/ci/requirements.txt b/ci/requirements.txt new file mode 100644 index 0000000..d7f5177 --- /dev/null +++ b/ci/requirements.txt @@ -0,0 +1,4 @@ +virtualenv>=16.6.0 +pip>=19.1.1 +setuptools>=18.0.1 +six>=1.14.0 diff --git a/docs/conf.py b/docs/conf.py index 24e3b8b..fd59608 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -import os - +import sphinx_py3doc_enhanced_theme extensions = [ 'sphinx.ext.autodoc', @@ -15,15 +14,10 @@ 'sphinx.ext.todo', 'sphinx.ext.viewcode', ] -if os.getenv('SPELLCHECK'): - extensions += 'sphinxcontrib.spelling', - spelling_show_suggestions = True - spelling_lang = 'en_US' - source_suffix = '.rst' master_doc = 'index' project = 'django-prefetch' -year = '2012-2017' +year = '2012-2021' author = 'Ionel Cristian Mărieș' copyright = '{0}, {1}'.format(year, author) version = release = '1.2.1' @@ -34,7 +28,6 @@ 'issue': ('https://github.com/ionelmc/django-prefetch/issues/%s', '#'), 'pr': ('https://github.com/ionelmc/django-prefetch/pull/%s', 'PR #'), } -import sphinx_py3doc_enhanced_theme html_theme = "sphinx_py3doc_enhanced_theme" html_theme_path = [sphinx_py3doc_enhanced_theme.get_html_theme_path()] html_theme_options = { diff --git a/docs/index.rst b/docs/index.rst index 40f35b5..ad842d5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -19,4 +19,3 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` - diff --git a/docs/requirements.txt b/docs/requirements.txt index ef4a013..62bc14e 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,2 @@ sphinx>=1.3 sphinx-py3doc-enhanced-theme --e . diff --git a/setup.cfg b/setup.cfg index 225de90..a72645e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,13 +1,15 @@ [bdist_wheel] universal = 1 - [flake8] max-line-length = 140 -exclude = */migrations/* +exclude = .tox,.eggs,ci/templates,build,dist [tool:pytest] -testpaths = tests +# If a pytest section is found in one of the possible config files +# (pytest.ini, tox.ini or setup.cfg), then pytest will not look for any others, +# so if you add a pytest config section elsewhere, +# you will need to delete this section from setup.cfg. norecursedirs = migrations @@ -17,16 +19,17 @@ python_files = tests.py addopts = -ra - --strict + --strict-markers --doctest-modules --doctest-glob=\*.rst --tb=short +testpaths = + tests -[isort] +[tool:isort] force_single_line = True line_length = 120 known_first_party = prefetch default_section = THIRDPARTY forced_separate = test_prefetch -not_skip = __init__.py -skip = migrations +skip = .tox,.eggs,ci/templates,build,dist diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index 83766ee..a1c69eb --- a/setup.py +++ b/setup.py @@ -16,18 +16,18 @@ def read(*names, **kwargs): - return io.open( + with io.open( join(dirname(__file__), *names), encoding=kwargs.get('encoding', 'utf8') - ).read() + ) as fh: + return fh.read() setup( name='django-prefetch', version='1.2.1', - license='BSD 2-Clause License', - description='Simple and generic model related data prefetch framework for Django solving the ' - '"1+N queries" problem that happens when you need related data for your objects.', + license='BSD-2-Clause', + description='Simple and generic model related data prefetch framework for Django solving the "1+N queries" problem that happens when you need related data for your objects.', long_description='%s\n%s' % ( re.compile('^.. start-badges.*^.. end-badges', re.M | re.S).sub('', read('README.rst')), re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst')) @@ -41,6 +41,7 @@ def read(*names, **kwargs): include_package_data=True, zip_safe=False, classifiers=[ + # complete classifier list: http://pypi.python.org/pypi?%3Aaction=list_classifiers 'Development Status :: 5 - Production/Stable', 'Framework :: Django', 'Intended Audience :: Developers', @@ -54,9 +55,10 @@ def read(*names, **kwargs): 'Programming Language :: Python', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', '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 :: Implementation :: PyPy', # uncomment if you test on these interpreters: @@ -65,5 +67,14 @@ def read(*names, **kwargs): # 'Programming Language :: Python :: Implementation :: Stackless', 'Topic :: Utilities', ], + project_urls={ + 'Documentation': 'https://django-prefetch.readthedocs.io/', + 'Changelog': 'https://django-prefetch.readthedocs.io/en/latest/changelog.html', + 'Issue Tracker': 'https://github.com/ionelmc/django-prefetch/issues', + }, + keywords=[ + # eg: 'keyword1', 'keyword2', 'keyword3', + ], + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*', install_requires=['Django>=1.9'] ) diff --git a/tests/test_app/tests.py b/tests/test_app/tests.py index 602d40e..38bc0f0 100644 --- a/tests/test_app/tests.py +++ b/tests/test_app/tests.py @@ -68,6 +68,7 @@ def __exit__(self, exc_type, exc_value, tb): class PrefetchTests(TestCase): + databases = ['default', 'secondary'] def setUp(self): super(PrefetchTests, self).setUp() diff --git a/tox.ini b/tox.ini index 1200cfb..dae1482 100644 --- a/tox.ini +++ b/tox.ini @@ -1,22 +1,34 @@ +[testenv:bootstrap] +deps = + jinja2 + tox +skip_install = true +commands = + python ci/bootstrap.py --no-env +passenv = + * ; a generative tox configuration, see: https://tox.readthedocs.io/en/latest/config.html#generative-envlist [tox] envlist = clean, check, - {py27,py34,py35,py36,py37,pypy}-{dj19,dj110,dj111,dj20}, - report, - docs + docs, + {py27,py36,py37,py38,py39,pypy}-{dj19,dj110,dj111}, + {py36,py37,py38,py39,pypy3}-{dj111,dj20,dj21,dj22,dj30,dj31,dj32}, + report +ignore_basepython_conflict = true [testenv] basepython = pypy: {env:TOXPYTHON:pypy} - {py27,docs,spell}: {env:TOXPYTHON:python2.7} - py34: {env:TOXPYTHON:python3.4} - py35: {env:TOXPYTHON:python3.5} + pypy3: {env:TOXPYTHON:pypy3} + py27: {env:TOXPYTHON:python2.7} py36: {env:TOXPYTHON:python3.6} py37: {env:TOXPYTHON:python3.7} - {bootstrap,clean,check,report,coveralls,codecov}: {env:TOXPYTHON:python3} + py38: {env:TOXPYTHON:python3.8} + py39: {env:TOXPYTHON:python3.9} + {bootstrap,clean,check,report,docs,codecov,coveralls}: {env:TOXPYTHON:python3} setenv = PYTHONPATH={toxinidir}/tests PYTHONUNBUFFERED=yes @@ -25,42 +37,22 @@ passenv = * usedevelop = false deps = - pytest==3.10.1 - pytest-django==3.2.1 + pytest-django + pytest pytest-travis-fold pytest-cov dj19: Django==1.9.13 dj110: Django==1.10.8 - dj111: Django==1.11.15 + dj111: Django==1.11.29 dj20: Django==2.0.13 + dj21: Django==2.1.15 + dj22: Django==2.2.20 + dj30: Django==3.0.14 + dj31: Django==3.1.8 + dj32: Django==3.2 commands = {posargs:pytest --cov --cov-report=term-missing -vv tests} -[testenv:bootstrap] -deps = - jinja2 - matrix -skip_install = true -commands = - python ci/bootstrap.py -[testenv:spell] -setenv = - SPELLCHECK=1 -commands = - sphinx-build -b spelling docs dist/docs -skip_install = true -deps = - -r{toxinidir}/docs/requirements.txt - sphinxcontrib-spelling - pyenchant - -[testenv:docs] -deps = - -r{toxinidir}/docs/requirements.txt -commands = - sphinx-build {posargs:-E} -b html docs dist/docs - sphinx-build -b linkcheck docs dist/docs - [testenv:check] deps = docutils @@ -73,8 +65,16 @@ skip_install = true commands = python setup.py check --strict --metadata --restructuredtext check-manifest {toxinidir} - flake8 src tests setup.py - isort --verbose --check-only --diff --recursive src tests setup.py + flake8 + isort --verbose --check-only --diff --filter-files . + +[testenv:docs] +usedevelop = true +deps = + -r{toxinidir}/docs/requirements.txt +commands = + sphinx-build {posargs:-E} -b html docs dist/docs + sphinx-build -b linkcheck docs dist/docs [testenv:coveralls] deps = @@ -88,12 +88,11 @@ deps = codecov skip_install = true commands = - coverage xml --ignore-errors codecov [] - [testenv:report] -deps = coverage +deps = + coverage skip_install = true commands = coverage report @@ -102,5 +101,5 @@ commands = [testenv:clean] commands = coverage erase skip_install = true -deps = coverage - +deps = + coverage