summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Dufresne <jon.dufresne@gmail.com>2018-11-21 19:15:27 -0800
committerJon Dufresne <jon.dufresne@gmail.com>2018-11-22 19:05:14 -0800
commitd99e2cae1981940437f073dc07f1420efa2c0bea (patch)
treee4c572d660e30b2351817ea2c52a4a8a7d134520
parent318cfadfe0a3aa242ad250f6e3a2af8f8791cb5b (diff)
downloadsphinx-git-d99e2cae1981940437f073dc07f1420efa2c0bea.tar.gz
Deprecate evaluating Python 2 syntax in configuration files
-rw-r--r--CHANGES2
-rw-r--r--sphinx/config.py3
-rw-r--r--sphinx/util/pycompat.py23
-rw-r--r--tests/test_util_pycompat.py43
4 files changed, 62 insertions, 9 deletions
diff --git a/CHANGES b/CHANGES
index c19fde3ef..8f1906c9e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -33,6 +33,8 @@ Incompatible changes
Deprecated
----------
+* Support for evaluating Python 2 syntax is deprecated. This includes
+ configuration files which should be converted to Python 3.
* The ``encoding`` argument of ``autodoc.Documenter.get_doc()``,
``autodoc.DocstringSignatureMixin.get_doc()``,
``autodoc.DocstringSignatureMixin._find_signature()``, and
diff --git a/sphinx/config.py b/sphinx/config.py
index e12889c61..5948becf4 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -361,8 +361,7 @@ def eval_config_file(filename, tags):
try:
execfile_(filename, namespace)
except SyntaxError as err:
- msg = __("There is a syntax error in your configuration file: %s\n"
- "Did you change the syntax from 2.x to 3.x?")
+ msg = __("There is a syntax error in your configuration file: %s\n")
raise ConfigError(msg % err)
except SystemExit:
msg = __("The configuration file (or one of the modules it imports) "
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index 7c2b0dad3..1107427b6 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -16,11 +16,17 @@ from textwrap import indent # type: ignore # NOQA
from six import text_type
+from sphinx.locale import __
+from sphinx.util import logging
+
if False:
# For type annotation
from typing import Any, Callable, Generator # NOQA
+logger = logging.getLogger(__name__)
+
+
NoneType = type(None)
# ------------------------------------------------------------------------------
@@ -79,11 +85,14 @@ def execfile_(filepath, _globals, open=open):
try:
code = compile(source, filepath_enc, 'exec')
except SyntaxError:
- if convert_with_2to3:
- # maybe the file uses 2.x syntax; try to refactor to
- # 3.x syntax using 2to3
- source = convert_with_2to3(filepath)
- code = compile(source, filepath_enc, 'exec')
- else:
- raise
+ # maybe the file uses 2.x syntax; try to refactor to
+ # 3.x syntax using 2to3
+ source = convert_with_2to3(filepath)
+ code = compile(source, filepath_enc, 'exec')
+ # TODO: When support for evaluating Python 2 syntax is removed,
+ # deprecate convert_with_2to3().
+ logger.warning(__('Support for evaluating Python 2 syntax is deprecated '
+ 'and will be removed in Sphinx 4.0. '
+ 'Convert %s to Python 3 syntax.'),
+ filepath)
exec(code, _globals)
diff --git a/tests/test_util_pycompat.py b/tests/test_util_pycompat.py
new file mode 100644
index 000000000..333664975
--- /dev/null
+++ b/tests/test_util_pycompat.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+"""
+ test_util_pycompat
+ ~~~~~~~~~~~~~~~~~~
+
+ Tests sphinx.util.pycompat functions.
+
+ :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import tempfile
+
+from sphinx.testing.util import strip_escseq
+from sphinx.util import logging
+from sphinx.util.pycompat import execfile_
+
+
+def test_execfile_python2(capsys, app, status, warning):
+ logging.setup(app, status, warning)
+
+ ns = {}
+ with tempfile.NamedTemporaryFile() as tmp:
+ tmp.write(b'print "hello"\n')
+ tmp.flush()
+ execfile_(tmp.name, ns)
+ msg = (
+ 'Support for evaluating Python 2 syntax is deprecated '
+ 'and will be removed in Sphinx 4.0. '
+ 'Convert %s to Python 3 syntax.\n' % tmp.name)
+ assert msg in strip_escseq(warning.getvalue())
+ captured = capsys.readouterr()
+ assert captured.out == 'hello\n'
+
+
+def test_execfile(capsys):
+ ns = {}
+ with tempfile.NamedTemporaryFile() as tmp:
+ tmp.write(b'print("hello")\n')
+ tmp.flush()
+ execfile_(tmp.name, ns)
+ captured = capsys.readouterr()
+ assert captured.out == 'hello\n'