diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-07-27 12:01:10 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-07-27 12:34:21 -0400 |
commit | 338cad687a1f49b021e81d33fd16847a4c5c7731 (patch) | |
tree | ceb6b8a2574a950705b8421913fe380a797d05a6 | |
parent | a79fbaad5fe507e6fce76c891d0793444be6d6e1 (diff) | |
download | mako-338cad687a1f49b021e81d33fd16847a4c5c7731.tar.gz |
Bump Python versions, remove conditional imports
Mako 1.1 now supports Python versions:
* 2.7
* 3.4 and higher
This includes that setup.py no longer includes any conditionals, allowing
for a pure Python wheel build, however this is not necessarily part of the
Pypi release process as of yet. The test suite also raises for Python
deprecation warnings.
Fixes: #249
Replaced usage of ``inspect.getfullargspec()`` with the vendored version
used by SQLAlchemy, Alembic to avoid future deprecation warnings. Also
cleans up an additional version of the same function that's apparently
been floating around for some time.
Fixes: #295
Change-Id: I98274c16b6022289d1890f4daf532bab323ab112
-rw-r--r-- | doc/build/unreleased/249.rst | 14 | ||||
-rw-r--r-- | doc/build/unreleased/295.rst | 9 | ||||
-rw-r--r-- | mako/codegen.py | 3 | ||||
-rw-r--r-- | mako/compat.py | 120 | ||||
-rw-r--r-- | mako/ext/pygmentplugin.py | 2 | ||||
-rw-r--r-- | mako/runtime.py | 19 | ||||
-rw-r--r-- | mako/template.py | 3 | ||||
-rw-r--r-- | setup.cfg | 3 | ||||
-rw-r--r-- | setup.py | 25 | ||||
-rw-r--r-- | test/__init__.py | 3 | ||||
-rw-r--r-- | tox.ini | 4 |
11 files changed, 78 insertions, 127 deletions
diff --git a/doc/build/unreleased/249.rst b/doc/build/unreleased/249.rst new file mode 100644 index 0000000..206a72a --- /dev/null +++ b/doc/build/unreleased/249.rst @@ -0,0 +1,14 @@ +.. change:: + :tags: change, py3k, installer + :tickets: 249 + + Mako 1.1 now supports Python versions: + + * 2.7 + * 3.4 and higher + + This includes that setup.py no longer includes any conditionals, allowing + for a pure Python wheel build, however this is not necessarily part of the + Pypi release process as of yet. The test suite also raises for Python + deprecation warnings. + diff --git a/doc/build/unreleased/295.rst b/doc/build/unreleased/295.rst new file mode 100644 index 0000000..147d23b --- /dev/null +++ b/doc/build/unreleased/295.rst @@ -0,0 +1,9 @@ +.. change:: + :tags: bug, py3k + :tickets: 295 + + Replaced usage of ``inspect.getfullargspec()`` with the vendored version + used by SQLAlchemy, Alembic to avoid future deprecation warnings. Also + cleans up an additional version of the same function that's apparently + been floating around for some time. + diff --git a/mako/codegen.py b/mako/codegen.py index 5ca7b04..8f9eef4 100644 --- a/mako/codegen.py +++ b/mako/codegen.py @@ -7,6 +7,7 @@ """provides functionality for rendering a parsetree constructing into module source code.""" +import json import re import time @@ -176,7 +177,7 @@ class _GenerateRenderMethod(object): self.printer.writelines( '"""', "__M_BEGIN_METADATA", - compat.json.dumps(struct), + json.dumps(struct), "__M_END_METADATA\n" '"""', ) diff --git a/mako/compat.py b/mako/compat.py index 2444cad..4460fde 100644 --- a/mako/compat.py +++ b/mako/compat.py @@ -4,37 +4,49 @@ # This module is part of Mako and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -import json # noqa +import collections +import inspect import sys py3k = sys.version_info >= (3, 0) -py33 = sys.version_info >= (3, 3) py2k = sys.version_info < (3,) py27 = sys.version_info >= (2, 7) jython = sys.platform.startswith("java") win32 = sys.platform.startswith("win") pypy = hasattr(sys, "pypy_version_info") -if py3k: - # create a "getargspec" from getfullargspec(), which is not deprecated - # in Py3K; getargspec() has started to emit warnings as of Py3.5. - # As of Py3.4, now they are trying to move from getfullargspec() - # to "signature()", but getfullargspec() is not deprecated, so stick - # with that for now. +ArgSpec = collections.namedtuple( + "ArgSpec", ["args", "varargs", "keywords", "defaults"] +) - import collections - ArgSpec = collections.namedtuple( - "ArgSpec", ["args", "varargs", "keywords", "defaults"] - ) - from inspect import getfullargspec as inspect_getfullargspec +def inspect_getargspec(func): + """getargspec based on fully vendored getfullargspec from Python 3.3.""" - def inspect_getargspec(func): - return ArgSpec(*inspect_getfullargspec(func)[0:4]) + if inspect.ismethod(func): + func = func.__func__ + if not inspect.isfunction(func): + raise TypeError("{!r} is not a Python function".format(func)) + co = func.__code__ + if not inspect.iscode(co): + raise TypeError("{!r} is not a code object".format(co)) -else: - from inspect import getargspec as inspect_getargspec # noqa + nargs = co.co_argcount + names = co.co_varnames + nkwargs = co.co_kwonlyargcount if py3k else 0 + args = list(names[:nargs]) + + nargs += nkwargs + varargs = None + if co.co_flags & inspect.CO_VARARGS: + varargs = co.co_varnames[nargs] + nargs = nargs + 1 + varkw = None + if co.co_flags & inspect.CO_VARKEYWORDS: + varkw = co.co_varnames[nargs] + + return ArgSpec(args, varargs, varkw, func.__defaults__) if py3k: @@ -86,7 +98,7 @@ else: return eval("0" + lit) -if py33: +if py3k: from importlib import machinery def load_module(module_id, path): @@ -125,34 +137,6 @@ def exception_as(): return sys.exc_info()[1] -try: - import threading - - if py3k: - import _thread as thread - else: - import thread -except ImportError: - import dummy_threading as threading # noqa - - if py3k: - import _dummy_thread as thread - else: - import dummy_thread as thread # noqa - -try: - from functools import partial -except: - - def partial(func, *args, **keywords): - def newfunc(*fargs, **fkeywords): - newkeywords = keywords.copy() - newkeywords.update(fkeywords) - return func(*(args + fargs), **newkeywords) - - return newfunc - - all = all # noqa @@ -160,50 +144,6 @@ def exception_name(exc): return exc.__class__.__name__ -try: - from inspect import CO_VARKEYWORDS, CO_VARARGS - - def inspect_func_args(fn): - if py3k: - co = fn.__code__ - else: - co = fn.func_code - - nargs = co.co_argcount - names = co.co_varnames - args = list(names[:nargs]) - - varargs = None - if co.co_flags & CO_VARARGS: - varargs = co.co_varnames[nargs] - nargs = nargs + 1 - varkw = None - if co.co_flags & CO_VARKEYWORDS: - varkw = co.co_varnames[nargs] - - if py3k: - return args, varargs, varkw, fn.__defaults__ - else: - return args, varargs, varkw, fn.func_defaults - - -except ImportError: - import inspect - - def inspect_func_args(fn): - return inspect.getargspec(fn) - - -if py3k: - # TODO: this has been restored in py3k - def callable(fn): # noqa - return hasattr(fn, "__call__") - - -else: - callable = callable # noqa - - ################################################ # cross-compatible metaclass implementation # Copyright (c) 2010-2012 Benjamin Peterson diff --git a/mako/ext/pygmentplugin.py b/mako/ext/pygmentplugin.py index 2824693..1734ccd 100644 --- a/mako/ext/pygmentplugin.py +++ b/mako/ext/pygmentplugin.py @@ -59,7 +59,7 @@ class MakoLexer(RegexLexer): ), (r"<%(?=([\w\.\:]+))", Comment.Preproc, "ondeftags"), ( - r"(<%(?:!?))(.*?)(%>)(?s)", + r"(?s)(<%(?:!?))(.*?)(%>)", bygroups(Comment.Preproc, using(PythonLexer), Comment.Preproc), ), ( diff --git a/mako/runtime.py b/mako/runtime.py index 0956cd0..0e7149b 100644 --- a/mako/runtime.py +++ b/mako/runtime.py @@ -7,6 +7,7 @@ """provides runtime services for templates, including Context, Namespace, and various helper functions.""" +import functools import sys from mako import compat @@ -37,7 +38,7 @@ class Context(object): # "capture" function which proxies to the # generic "capture" function - self._data["capture"] = compat.partial(capture, self) + self._data["capture"] = functools.partial(capture, self) # "caller" stack used by def calls with content self.caller_stack = self._data["caller"] = CallerStack() @@ -625,7 +626,7 @@ class TemplateNamespace(Namespace): def get(key): callable_ = self.template._get_def_callable(key) - return compat.partial(callable_, self.context) + return functools.partial(callable_, self.context) for k in self.template.module._exports: yield (k, get(k)) @@ -635,7 +636,7 @@ class TemplateNamespace(Namespace): val = self.callables[key] elif self.template.has_def(key): callable_ = self.template._get_def_callable(key) - val = compat.partial(callable_, self.context) + val = functools.partial(callable_, self.context) elif self.inherits: val = getattr(self.inherits, key) @@ -686,15 +687,15 @@ class ModuleNamespace(Namespace): for key in dir(self.module): if key[0] != "_": callable_ = getattr(self.module, key) - if compat.callable(callable_): - yield key, compat.partial(callable_, self.context) + if callable(callable_): + yield key, functools.partial(callable_, self.context) def __getattr__(self, key): if key in self.callables: val = self.callables[key] elif hasattr(self.module, key): callable_ = getattr(self.module, key) - val = compat.partial(callable_, self.context) + val = functools.partial(callable_, self.context) elif self.inherits: val = getattr(self.inherits, key) else: @@ -731,7 +732,7 @@ def capture(context, callable_, *args, **kwargs): """ - if not compat.callable(callable_): + if not callable(callable_): raise exceptions.RuntimeException( "capture() function expects a callable as " "its argument (i.e. capture(func, *args, **kwargs))" @@ -885,7 +886,7 @@ def _render(template, callable_, args, data, as_unicode=False): def _kwargs_for_callable(callable_, data): - argspec = compat.inspect_func_args(callable_) + argspec = compat.inspect_getargspec(callable_) # for normal pages, **pageargs is usually present if argspec[2]: return data @@ -900,7 +901,7 @@ def _kwargs_for_callable(callable_, data): def _kwargs_for_include(callable_, data, **kwargs): - argspec = compat.inspect_func_args(callable_) + argspec = compat.inspect_getargspec(callable_) namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None] for arg in namedargs: if arg != "context" and arg in data and arg not in kwargs: diff --git a/mako/template.py b/mako/template.py index 8e87d50..937d15b 100644 --- a/mako/template.py +++ b/mako/template.py @@ -7,6 +7,7 @@ """Provides the Template class, a facade for parsing, generating and executing template strings, as well as template runtime operations.""" +import json import os import re import shutil @@ -659,7 +660,7 @@ class ModuleInfo(object): source_map = re.search( r"__M_BEGIN_METADATA(.+?)__M_END_METADATA", module_source, re.S ).group(1) - source_map = compat.json.loads(source_map) + source_map = json.loads(source_map) source_map["line_map"] = dict( (int(k), int(v)) for k, v in source_map["line_map"].items() ) @@ -4,7 +4,7 @@ tag_build = dev [tool:pytest] -addopts= --tb native -v -r fxX +addopts= --tb native -v -r fxX -W error python_files=test/*test_*.py @@ -13,6 +13,7 @@ sign = 1 identity = C4DAFEE1 [flake8] +show-source = true enable-extensions = G # E203 is due to https://github.com/PyCQA/pycodestyle/issues/373 ignore = @@ -14,24 +14,9 @@ VERSION = ( ) v.close() -readme = open(os.path.join(os.path.dirname(__file__), "README.rst")).read() +readme = os.path.join(os.path.dirname(__file__), "README.rst") -if sys.version_info < (2, 6): - raise Exception("Mako requires Python 2.6 or higher.") - -markupsafe_installs = ( - sys.version_info >= (2, 6) and sys.version_info < (3, 0) -) or sys.version_info >= (3, 3) - -install_requires = [] - -if markupsafe_installs: - install_requires.append("MarkupSafe>=0.9.2") - -try: - import argparse # noqa -except ImportError: - install_requires.append("argparse") +install_requires = ["MarkupSafe>=0.9.2"] class PyTest(TestCommand): @@ -59,7 +44,8 @@ setup( version=VERSION, description="A super-fast templating language that borrows the \ best ideas from the existing templating languages.", - long_description=readme, + long_description=open(readme).read(), + python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", classifiers=[ "Development Status :: 5 - Production/Stable", "License :: OSI Approved :: MIT License", @@ -77,14 +63,13 @@ setup( url="https://www.makotemplates.org/", project_urls={ "Documentation": "https://docs.makotemplates.org", - "Issue Tracker": "https://github.com/sqlalchemy/mako" + "Issue Tracker": "https://github.com/sqlalchemy/mako", }, license="MIT", packages=find_packages(".", exclude=["examples*", "test*"]), tests_require=["pytest", "mock"], cmdclass={"test": PyTest}, zip_safe=False, - python_requires=">=2.6", install_requires=install_requires, extras_require={}, entry_points=""" diff --git a/test/__init__.py b/test/__init__.py index b91e709..c5c9e91 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -6,7 +6,6 @@ import unittest from mako import compat from mako.cache import CacheImpl from mako.cache import register_plugin -from mako.compat import py33 from mako.compat import py3k from mako.template import Template from mako.util import update_wrapper @@ -106,7 +105,7 @@ def teardown(): shutil.rmtree(module_base, True) -if py33: +if py3k: from unittest import mock # noqa else: import mock # noqa @@ -1,10 +1,10 @@ [tox] -envlist = py{27,35,36,37,38} +envlist = py{27,34,35,36,37,38} [testenv] cov_args=--cov=mako --cov-report term --cov-report xml -deps=pytest +deps=pytest>=3.1.0 mock beaker markupsafe |