Add fixes to setup.py for the inability to import pip for parsing requirements files. Update tox with new coverage commands and only test on a single Python3 version. Create venv if one doesn't exist with direnv. Remove encoding pragma as this is no longer necessary as of ~Python3.6? Remove _compat.py as six does a better job and Python2.7 shouldn't be in use anymore. Add the requirements directory text files to the Manifest.in. Update versions of pre-commit repos.master
@@ -1,2 +1,5 @@ | |||
if [ ! -d venv ]; then | |||
python3 -m venv venv | |||
fi | |||
source venv/bin/activate | |||
unset PS1 |
@@ -1,10 +1,10 @@ | |||
exclude: '^$' | |||
exclude: '^(.*\.(svg))?$' | |||
fail_fast: false | |||
default_language_version: | |||
python: python3.9 | |||
repos: | |||
- repo: https://github.com/pre-commit/pre-commit-hooks | |||
rev: v3.3.0 | |||
rev: v4.1.0 | |||
hooks: | |||
- id: check-added-large-files | |||
- id: check-ast | |||
@@ -22,8 +22,6 @@ repos: | |||
types: [file, text] | |||
- id: end-of-file-fixer | |||
types: [file, python] | |||
- id: fix-encoding-pragma | |||
types: [file, python] | |||
- id: requirements-txt-fixer | |||
types: [file, text] | |||
- id: trailing-whitespace | |||
@@ -31,7 +29,7 @@ repos: | |||
types: [file, text] | |||
exclude: ^docs/.*/coverage/.*\.html$ | |||
- repo: https://github.com/PyCQA/isort | |||
rev: 5.6.4 | |||
rev: 5.10.1 | |||
hooks: | |||
- id: isort | |||
types: [file, python] | |||
@@ -39,9 +37,9 @@ repos: | |||
rev: stable | |||
hooks: | |||
- id: black | |||
language_version: python3.8 | |||
language_version: python3.9 | |||
- repo: https://gitlab.com/pycqa/flake8 | |||
rev: 3.8.4 | |||
rev: 4.0.1 | |||
hooks: | |||
- id: flake8 | |||
exclude: ^setup.py$ |
@@ -12,6 +12,7 @@ include docs/[mM]ake* | |||
recursive-include . *.gitkeep | |||
recursive-include docs/source *.rst | |||
recursive-include docs/source/coverage *.source.html | |||
recursive-include requirements *.txt | |||
recursive-include tests * | |||
recursive-exclude * __pycache__ | |||
recursive-exclude * *.py[co] |
@@ -1,5 +1,4 @@ | |||
#!/usr/bin/env python | |||
# -*- coding: utf-8 -*- | |||
import os | |||
import re |
@@ -0,0 +1,3 @@ | |||
-r requirements/dev.txt | |||
-r requirements/prod.txt | |||
-r requirements/test.txt |
@@ -9,6 +9,7 @@ pylint==1.9.4; python_version >= "2.7" and python_version < "3.0" | |||
pylint; python_version >= "3.4" | |||
pylint-fail-under | |||
pytest | |||
pytest-asyncio | |||
pytest-cov | |||
pytest-mock | |||
pytest-runner |
@@ -1,51 +1,49 @@ | |||
#!/usr/bin/env python | |||
# -*- coding: utf-8 -*- | |||
import pip | |||
try: # for pip >= 10 | |||
from pip._internal.req import parse_requirements | |||
except ImportError: # for pip <= 9.0.3 | |||
from pip.req import parse_requirements | |||
try: | |||
from setuptools import setup | |||
except ImportError: | |||
from distutils.core import setup | |||
with open("README.md") as readme_file: | |||
readme = readme_file.read() | |||
with open("HISTORY.md") as history_file: | |||
history = history_file.read() | |||
github_url = "https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}" | |||
## workaround derived from: https://github.com/pypa/pip/issues/7645#issuecomment-578210649 | |||
parsed_requirements = parse_requirements("requirements/prod.txt", session="workaround") | |||
parsed_dev_requirements = parse_requirements( | |||
"requirements/dev.txt", session="workaround" | |||
) | |||
parsed_test_requirements = parse_requirements( | |||
"requirements/test.txt", session="workaround" | |||
) | |||
requirements = [str(ir.req) for ir in parsed_requirements] | |||
dev_requirements = [str(ir.req) for ir in parsed_dev_requirements] | |||
test_requirements = [str(tr.req) for tr in parsed_test_requirements] | |||
DESCRIPTION = "{{ cookiecutter.project_short_description }}" | |||
GITHUB_URL = "https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}" | |||
with open("requirements/prod.txt", encoding="utf-8") as file: | |||
requirements = file.read().split("\n") | |||
with open("requirements/test.txt", encoding="utf-8") as file: | |||
test_requirements = list( | |||
filter( | |||
lambda req: not req.startswith("-"), | |||
file.read().split("\n"), | |||
) | |||
) | |||
with open("requirements/dev.txt", encoding="utf-8") as file: | |||
dev_requirements = list( | |||
filter( | |||
lambda req: not req.startswith("-"), | |||
file.read().split("\n"), | |||
) | |||
) | |||
test_requirements.extend(requirements) | |||
dev_requirements.extend(test_requirements) | |||
with open("README.md", encoding="utf-8") as file: | |||
readme = file.read() | |||
with open("HISTORY.md", encoding="utf-8") as file: | |||
history = file.read() | |||
setup( | |||
name="{{ cookiecutter.project_slug }}", | |||
version="{{ cookiecutter.version }}", | |||
description="{{ cookiecutter.project_short_description }}", | |||
description=DESCRIPTION, | |||
long_description=readme + "\n\n" + history, | |||
long_description_content_type="text/markdown", | |||
author="{{ cookiecutter.full_name }}", | |||
author_email="{{ cookiecutter.email }}", | |||
url=github_url, | |||
url=GITHUB_URL, | |||
license="LGPL-3", | |||
keywords="{{ cookiecutter.project_slug }}", | |||
project_urls={"Source": github_url}, | |||
project_urls={"Source": GITHUB_URL}, | |||
packages=[ | |||
"{{ cookiecutter.project_slug }}", | |||
], |
@@ -1 +0,0 @@ | |||
# -*- coding: utf-8 -*- |
@@ -1,4 +1,3 @@ | |||
# -*- coding: utf-8 -*- | |||
""" | |||
Conftest Fixtures | |||
@@ -12,8 +11,8 @@ from __future__ import ( | |||
absolute_import, | |||
division, | |||
print_function, | |||
with_statement, | |||
unicode_literals, | |||
with_statement, | |||
) | |||
import logging | |||
@@ -22,7 +21,6 @@ import os | |||
import mock | |||
import pytest | |||
logger = logging.getLogger(__name__) # pylint: disable=invalid-name | |||
FIXTURE_PATH = "{}/fixtures".format(os.path.dirname(os.path.abspath(__file__))) |
@@ -1,4 +1,3 @@ | |||
# -*- coding: utf-8 -*- | |||
""" | |||
Tests for `{{ cookiecutter.project_slug }}` module. | |||
""" | |||
@@ -7,16 +6,23 @@ from __future__ import ( | |||
absolute_import, | |||
division, | |||
print_function, | |||
unicode_literals, | |||
with_statement, | |||
unicode_literals | |||
) | |||
import logging | |||
import pytest | |||
from {{ cookiecutter.project_slug }} import {{ (cookiecutter.project_slug.title()).replace('_', '') }} | |||
logger = logging.getLogger(__name__) # pylint: disable=invalid-name | |||
import pytest | |||
from {{cookiecutter.project_slug}} import ( # pylint: disable=invalid-name | |||
'' }}, | |||
'_', | |||
.replace, | |||
=, | |||
__name__, | |||
logger, | |||
logging.getLogger, | |||
{{ cookiecutter.project_slug.title, | |||
) | |||
FIXTURE_PATH = "{}/fixtures".format(os.path.dirname(os.path.abspath(__file__))) | |||
@@ -1,14 +1,14 @@ | |||
[tox] | |||
envlist = cov_init, py{37,38,39}, cov_report, docs, bandit, pylint | |||
envlist = cov_init, py3, cov_report, docs, bandit, pylint | |||
[testenv] | |||
basepython = | |||
py3: {env:TOXPYTHON:python3} | |||
py37: {env:TOXPYTHON:python3.7} | |||
py38: {env:TOXPYTHON:python3.8} | |||
py39: {env:TOXPYTHON:python3.9} | |||
{bandit,cov_init,cov_report,docs,lint,pur,pylint}: {env:TOXPYTHON:python3} | |||
setenv = | |||
COVERAGE_FILE=.coverage.{envname} | |||
PYTHONPATH={toxinidir}:{toxinidir}/{{ cookiecutter.project_slug }} | |||
PYTHONUNBUFFERED=yes | |||
HOME={env:HOME:/tmp} | |||
@@ -22,6 +22,7 @@ commands = | |||
--basetemp={envtmpdir} \ | |||
--confcutdir=.. \ | |||
--cov \ | |||
--cov-append \ | |||
-n 0 \ | |||
{posargs} | |||
@@ -37,7 +38,6 @@ deps = | |||
coverage | |||
skip_install = True | |||
commands = | |||
coverage combine | |||
coverage html | |||
{toxinidir}/docs/source/coverage/extract_source.py | |||
@@ -82,5 +82,4 @@ skip_install = True | |||
description = | |||
Invoke sphinx-build to build the HTML docs | |||
commands = | |||
sphinx-build -b linkcheck | |||
sphinx-build -b html -q {posargs} | |||
python setup.py build_sphinx -q {posargs} |
@@ -1,5 +1,4 @@ | |||
#!/usr/bin/env python | |||
# -*- coding: utf-8 -*- | |||
""" | |||
{{ cookiecutter.project_slug }} | |||
@@ -12,14 +11,21 @@ from __future__ import ( | |||
absolute_import, | |||
division, | |||
print_function, | |||
with_statement, | |||
unicode_literals, | |||
with_statement, | |||
) | |||
from pkgutil import extend_path | |||
__path__ = extend_path(__path__, __name__) | |||
from .{{ cookiecutter.project_slug }} import {{ (cookiecutter.project_slug.title()).replace('_', '') }} | |||
__all__ = ["{{ (cookiecutter.project_slug.title()).replace('_', '') }}"] | |||
from .{{cookiecutter.project_slug}} import ( | |||
'' }}, | |||
'' }}"], | |||
'_', | |||
.replace, | |||
=, | |||
["{{ cookiecutter.project_slug.title, | |||
__all__, | |||
{{ cookiecutter.project_slug.title, | |||
) |
@@ -1,86 +0,0 @@ | |||
import sys | |||
# https://lucumr.pocoo.org/2013/5/21/porting-to-python-3-redux/ | |||
# https://github.com/tony/cookiecutter-pypackage-pythonic/blob/master/%7B%7Bcookiecutter.repo_name%7D%7D/%7B%7Bcookiecutter.repo_name%7D%7D/_compat.py | |||
PY2 = sys.version_info[0] == 2 | |||
_identity = lambda x: x | |||
if PY2: | |||
unichr = unichr | |||
text_type = unicode | |||
string_types = (str, unicode) | |||
integer_types = (int, long) | |||
from urllib import urlretrieve | |||
text_to_native = lambda s, enc: s.encode(enc) | |||
iterkeys = lambda d: d.iterkeys() | |||
itervalues = lambda d: d.itervalues() | |||
iteritems = lambda d: d.iteritems() | |||
from cStringIO import StringIO as BytesIO | |||
from StringIO import StringIO | |||
import cPickle as pickle | |||
import ConfigParser as configparser | |||
from itertools import izip, imap | |||
range_type = xrange | |||
cmp = cmp | |||
input = raw_input | |||
from string import lower as ascii_lowercase | |||
import urlparse | |||
def console_to_str(s): | |||
return s.decode("utf_8") | |||
exec("def reraise(tp, value, tb=None):\n raise tp, value, tb") | |||
else: | |||
unichr = chr | |||
text_type = str | |||
string_types = (str,) | |||
integer_types = (int,) | |||
text_to_native = lambda s, enc: s | |||
iterkeys = lambda d: iter(d.keys()) | |||
itervalues = lambda d: iter(d.values()) | |||
iteritems = lambda d: iter(d.items()) | |||
from io import StringIO, BytesIO | |||
import pickle | |||
import configparser | |||
izip = zip | |||
imap = map | |||
range_type = range | |||
cmp = lambda a, b: (a > b) - (a < b) | |||
input = input | |||
from string import ascii_lowercase | |||
import urllib.parse as urllib | |||
import urllib.parse as urlparse | |||
from urllib.request import urlretrieve | |||
console_encoding = sys.__stdout__.encoding | |||
def console_to_str(s): | |||
""" From pypa/pip project, pip.backwardwardcompat. License MIT. """ | |||
try: | |||
return s.decode(console_encoding) | |||
except UnicodeDecodeError: | |||
return s.decode("utf_8") | |||
def reraise(tp, value, tb=None): | |||
if value.__traceback__ is not tb: | |||
raise (value.with_traceback(tb)) | |||
raise value | |||
number_types = integer_types + (float,) |
@@ -1,12 +1,11 @@ | |||
#!/usr/bin/env python | |||
# -*- coding: utf-8 -*- | |||
from __future__ import ( | |||
absolute_import, | |||
division, | |||
print_function, | |||
unicode_literals, | |||
with_statement, | |||
unicode_literals | |||
) | |||
import logging |