diff --git a/.travis.yml b/.travis.yml index 1be196f2..7bb5a89f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,11 @@ env: - TOX_ENV=py27 - TOX_ENV=py33 - TOX_ENV=py34 +matrix: + include: + - python: 3.5 + env: + - TOX_ENV=py35 addons: apt_packages: - pandoc diff --git a/pelican/log.py b/pelican/log.py index 12eb7371..747aa38d 100644 --- a/pelican/log.py +++ b/pelican/log.py @@ -178,21 +178,49 @@ class LimitLogger(SafeLogger): logging.setLoggerClass(LimitLogger) -def init(level=None, handler=logging.StreamHandler()): +def supports_color(): + """ + Returns True if the running system's terminal supports color, + and False otherwise. - logger = logging.getLogger() + from django.core.management.color + """ + plat = sys.platform + supported_platform = plat != 'Pocket PC' and \ + (plat != 'win32' or 'ANSICON' in os.environ) - if os.isatty(sys.stdout.fileno()) and not sys.platform.startswith('win'): - fmt = ANSIFormatter() + # isatty is not always implemented, #6223. + is_a_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() + if not supported_platform or not is_a_tty: + return False + return True + + +def get_formatter(): + if supports_color(): + return ANSIFormatter() else: - fmt = TextFormatter() - handler.setFormatter(fmt) + return TextFormatter() + + +def init(level=None, handler=logging.StreamHandler(), name=None): + + logger = logging.getLogger(name) + + handler.setFormatter(get_formatter()) logger.addHandler(handler) if level: logger.setLevel(level) +def log_warnings(): + import warnings + logging.captureWarnings(True) + warnings.simplefilter("default", DeprecationWarning) + init(logging.DEBUG, name='py.warnings') + + if __name__ == '__main__': init(level=logging.DEBUG) diff --git a/pelican/tests/__init__.py b/pelican/tests/__init__.py index 32353ea2..4605a02b 100644 --- a/pelican/tests/__init__.py +++ b/pelican/tests/__init__.py @@ -1,2 +1,15 @@ import logging +import warnings + +from pelican.log import log_warnings + +# redirect warnings modulole to use logging instead +log_warnings() + +# setup warnings to log DeprecationWarning's and error on +# warnings in pelican's codebase +warnings.simplefilter("default", DeprecationWarning) +warnings.filterwarnings("error", ".*", Warning, "pelican") + +# Add a NullHandler to silence warning about no available handlers logging.getLogger().addHandler(logging.NullHandler()) diff --git a/pelican/tests/test_readers.py b/pelican/tests/test_readers.py index dc434835..db4aa44f 100644 --- a/pelican/tests/test_readers.py +++ b/pelican/tests/test_readers.py @@ -3,6 +3,8 @@ from __future__ import print_function, unicode_literals import os +import six + from pelican import readers from pelican.tests.support import get_settings, unittest from pelican.utils import SafeDatetime @@ -55,7 +57,8 @@ class TestAssertDictHasSubset(ReaderTest): self.assertDictHasSubset(self.dictionary, self.dictionary) def test_fail_not_set(self): - self.assertRaisesRegexp( + six.assertRaisesRegex( + self, AssertionError, 'Expected.*key-c.*to have value.*val-c.*but was not in Dict', self.assertDictHasSubset, @@ -63,7 +66,8 @@ class TestAssertDictHasSubset(ReaderTest): {'key-c': 'val-c'}) def test_fail_wrong_val(self): - self.assertRaisesRegexp( + six.assertRaisesRegex( + self, AssertionError, 'Expected .*key-a.* to have value .*val-b.* but was .*val-a.*', self.assertDictHasSubset, diff --git a/pelican/tests/test_testsuite.py b/pelican/tests/test_testsuite.py new file mode 100644 index 00000000..5dc92bb1 --- /dev/null +++ b/pelican/tests/test_testsuite.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +from __future__ import print_function, unicode_literals + +import sys +import warnings + +from pelican.tests.support import unittest + + +class TestSuiteTest(unittest.TestCase): + + @unittest.skipIf(sys.version_info[:2] == (3, 3), + "does not throw an exception on python 3.3") + def test_error_on_warning(self): + with self.assertRaises(UserWarning): + warnings.warn('test warning') diff --git a/pelican/utils.py b/pelican/utils.py index 1422a979..d2e896c6 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -429,7 +429,11 @@ class _HTMLWordTruncator(HTMLParser): def __init__(self, max_words): # In Python 2, HTMLParser is not a new-style class, # hence super() cannot be used. - HTMLParser.__init__(self) + try: + HTMLParser.__init__(self, convert_charrefs=False) + except TypeError: + # pre Python 3.3 + HTMLParser.__init__(self) self.max_words = max_words self.words_found = 0 diff --git a/setup.py b/setup.py index 86028424..99cf7cb0 100755 --- a/setup.py +++ b/setup.py @@ -55,6 +55,7 @@ setup( 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Software Development :: Libraries :: Python Modules', ], diff --git a/tox.ini b/tox.ini index 56ad0c14..609be886 100644 --- a/tox.ini +++ b/tox.ini @@ -1,11 +1,12 @@ [tox] -envlist = py{27,33,34},docs,flake8 +envlist = py{27,33,34,35},docs,flake8 [testenv] basepython = py27: python2.7 py33: python3.3 py34: python3.4 + py35: python3.5 passenv = * usedevelop=True deps = @@ -17,7 +18,7 @@ deps = commands = {envpython} --version nosetests -sv --with-coverage --cover-package=pelican pelican - coveralls + - coveralls [testenv:docs] basepython = python2.7