diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 427f070..e6c98c6 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -7,10 +7,11 @@ on: [push, pull_request] jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 strategy: + fail-fast: false matrix: - python-version: [3.5, 3.6, 3.7, 3.8, 3.9, "pypy3"] + python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "pypy3"] steps: - uses: actions/checkout@v2 diff --git a/CHANGES.rst b/CHANGES.rst index 0be7820..eb23369 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,15 @@ premailer Changes Peter's note: Unfortunately, ``premailer`` didn't use to keep a change log. But it's never too late to start, so let's start here and now. +Unreleased +---------- + +* Add support for Python 3.9, 3.10 and 3.11. The code for the distributed code was unchanged, + only some tests needed to be adapted. + +* Moved from nose test runner to pytest, as nose is no longer supported and has some known issues + with Python 3.9+. + 3.10.0 ------ diff --git a/README.rst b/README.rst index 1b6b8cc..320a7a9 100644 --- a/README.rst +++ b/README.rst @@ -30,6 +30,9 @@ makes sure premailer works in: - Python 3.6 - Python 3.7 - Python 3.8 +- Python 3.9 +- Python 3.10 +- Python 3.11 - PyPy Turns CSS blocks into style attributes diff --git a/premailer/tests/test_premailer.py b/premailer/tests/test_premailer.py index c1e803e..1a1772b 100644 --- a/premailer/tests/test_premailer.py +++ b/premailer/tests/test_premailer.py @@ -3,15 +3,15 @@ import sys import os import unittest +import tempfile from contextlib import contextmanager from io import StringIO -import tempfile +from unittest import mock +import pytest from lxml.etree import XMLSyntaxError, fromstring from requests.exceptions import HTTPError -import mock import premailer.premailer # lint:ok -from nose.tools import assert_raises, eq_, ok_ from premailer.__main__ import main from premailer.premailer import ( ExternalNotFoundError, @@ -23,6 +23,32 @@ ) +def ok_(expr, msg=None): + """ + Shorthand for assert. + + Copied from Nose. + """ + if not expr: + raise AssertionError(msg) + + +def eq_(a, b, msg=None): + """ + Shorthand for 'assert a == b, "%r != %r" % (a, b). + + Copied from Nose. + """ + if not a == b: + raise AssertionError(msg or "%r != %r" % (a, b)) + + +def assert_raises(exc_class, func, *args): + """Compatibility with Nose API for pytest.""" + with pytest.raises(exc_class): + func(*args) + + whitespace_between_tags = re.compile(r">\s*<") diff --git a/setup.py b/setup.py index 86a6cf4..68d5799 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ def find_version(*file_paths): install_requires = ["lxml", "cssselect", "cssutils", "requests", "cachetools"] -tests_require = ["nose", "mock"] +tests_require = ["pytest", "pytest-cov"] setup( name="premailer", @@ -45,6 +45,9 @@ def find_version(*file_paths): "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Communications", diff --git a/tox.ini b/tox.ini index 3d33e62..11d79a7 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,8 @@ envlist = py37, py38, py39, + py310, + py311, pypy3, [gh-actions] @@ -15,6 +17,8 @@ python = 3.7: py37 3.8: py38 3.9: py39, lint + 3.10: py310 + 3.11: py311 pypy3: pypy3 [testenv] @@ -24,7 +28,7 @@ install_command = extras = test commands = - nosetests --with-coverage --cover-package=premailer + pytest --cov=premailer [testenv:lint-py39] extras = dev