Bump mako from 1.1.6 to 1.2.0 (#1684)

* Bump mako from 1.1.6 to 1.2.0

Bumps [mako](https://github.com/sqlalchemy/mako) from 1.1.6 to 1.2.0.
- [Release notes](https://github.com/sqlalchemy/mako/releases)
- [Changelog](https://github.com/sqlalchemy/mako/blob/main/CHANGES)
- [Commits](https://github.com/sqlalchemy/mako/commits)

---
updated-dependencies:
- dependency-name: mako
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update mako==1.2.0

* Update MarkupSafe==2.1.1

* Add importlib-metadata==4.11.3

* Update requirements.txt

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>

[skip ci]
This commit is contained in:
dependabot[bot] 2022-05-16 20:33:50 -07:00 committed by GitHub
parent aa0c58ef0e
commit 238afb4794
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 2948 additions and 848 deletions

View file

128
lib/mako/testing/_config.py Normal file
View file

@ -0,0 +1,128 @@
import configparser
import dataclasses
from dataclasses import dataclass
from pathlib import Path
from typing import Callable
from typing import ClassVar
from typing import Optional
from typing import Union
from .helpers import make_path
class ConfigError(BaseException):
pass
class MissingConfig(ConfigError):
pass
class MissingConfigSection(ConfigError):
pass
class MissingConfigItem(ConfigError):
pass
class ConfigValueTypeError(ConfigError):
pass
class _GetterDispatch:
def __init__(self, initialdata, default_getter: Callable):
self.default_getter = default_getter
self.data = initialdata
def get_fn_for_type(self, type_):
return self.data.get(type_, self.default_getter)
def get_typed_value(self, type_, name):
get_fn = self.get_fn_for_type(type_)
return get_fn(name)
def _parse_cfg_file(filespec: Union[Path, str]):
cfg = configparser.ConfigParser()
try:
filepath = make_path(filespec, check_exists=True)
except FileNotFoundError as e:
raise MissingConfig(f"No config file found at {filespec}") from e
else:
with open(filepath, encoding="utf-8") as f:
cfg.read_file(f)
return cfg
def _build_getter(cfg_obj, cfg_section, method, converter=None):
def caller(option, **kwargs):
try:
rv = getattr(cfg_obj, method)(cfg_section, option, **kwargs)
except configparser.NoSectionError as nse:
raise MissingConfigSection(
f"No config section named {cfg_section}"
) from nse
except configparser.NoOptionError as noe:
raise MissingConfigItem(f"No config item for {option}") from noe
except ValueError as ve:
# ConfigParser.getboolean, .getint, .getfloat raise ValueError
# on bad types
raise ConfigValueTypeError(
f"Wrong value type for {option}"
) from ve
else:
if converter:
try:
rv = converter(rv)
except Exception as e:
raise ConfigValueTypeError(
f"Wrong value type for {option}"
) from e
return rv
return caller
def _build_getter_dispatch(cfg_obj, cfg_section, converters=None):
converters = converters or {}
default_getter = _build_getter(cfg_obj, cfg_section, "get")
# support ConfigParser builtins
getters = {
int: _build_getter(cfg_obj, cfg_section, "getint"),
bool: _build_getter(cfg_obj, cfg_section, "getboolean"),
float: _build_getter(cfg_obj, cfg_section, "getfloat"),
str: default_getter,
}
# use ConfigParser.get and convert value
getters.update(
{
type_: _build_getter(
cfg_obj, cfg_section, "get", converter=converter_fn
)
for type_, converter_fn in converters.items()
}
)
return _GetterDispatch(getters, default_getter)
@dataclass
class ReadsCfg:
section_header: ClassVar[str]
converters: ClassVar[Optional[dict]] = None
@classmethod
def from_cfg_file(cls, filespec: Union[Path, str]):
cfg = _parse_cfg_file(filespec)
dispatch = _build_getter_dispatch(
cfg, cls.section_header, converters=cls.converters
)
kwargs = {
field.name: dispatch.get_typed_value(field.type, field.name)
for field in dataclasses.fields(cls)
}
return cls(**kwargs)

View file

@ -0,0 +1,167 @@
import contextlib
import re
import sys
def eq_(a, b, msg=None):
"""Assert a == b, with repr messaging on failure."""
assert a == b, msg or "%r != %r" % (a, b)
def ne_(a, b, msg=None):
"""Assert a != b, with repr messaging on failure."""
assert a != b, msg or "%r == %r" % (a, b)
def in_(a, b, msg=None):
"""Assert a in b, with repr messaging on failure."""
assert a in b, msg or "%r not in %r" % (a, b)
def not_in(a, b, msg=None):
"""Assert a in not b, with repr messaging on failure."""
assert a not in b, msg or "%r is in %r" % (a, b)
def _assert_proper_exception_context(exception):
"""assert that any exception we're catching does not have a __context__
without a __cause__, and that __suppress_context__ is never set.
Python 3 will report nested as exceptions as "during the handling of
error X, error Y occurred". That's not what we want to do. We want
these exceptions in a cause chain.
"""
if (
exception.__context__ is not exception.__cause__
and not exception.__suppress_context__
):
assert False, (
"Exception %r was correctly raised but did not set a cause, "
"within context %r as its cause."
% (exception, exception.__context__)
)
def _assert_proper_cause_cls(exception, cause_cls):
"""assert that any exception we're catching does not have a __context__
without a __cause__, and that __suppress_context__ is never set.
Python 3 will report nested as exceptions as "during the handling of
error X, error Y occurred". That's not what we want to do. We want
these exceptions in a cause chain.
"""
assert isinstance(exception.__cause__, cause_cls), (
"Exception %r was correctly raised but has cause %r, which does not "
"have the expected cause type %r."
% (exception, exception.__cause__, cause_cls)
)
def assert_raises(except_cls, callable_, *args, **kw):
return _assert_raises(except_cls, callable_, args, kw)
def assert_raises_with_proper_context(except_cls, callable_, *args, **kw):
return _assert_raises(except_cls, callable_, args, kw, check_context=True)
def assert_raises_with_given_cause(
except_cls, cause_cls, callable_, *args, **kw
):
return _assert_raises(except_cls, callable_, args, kw, cause_cls=cause_cls)
def assert_raises_message(except_cls, msg, callable_, *args, **kwargs):
return _assert_raises(except_cls, callable_, args, kwargs, msg=msg)
def assert_raises_message_with_proper_context(
except_cls, msg, callable_, *args, **kwargs
):
return _assert_raises(
except_cls, callable_, args, kwargs, msg=msg, check_context=True
)
def assert_raises_message_with_given_cause(
except_cls, msg, cause_cls, callable_, *args, **kwargs
):
return _assert_raises(
except_cls, callable_, args, kwargs, msg=msg, cause_cls=cause_cls
)
def _assert_raises(
except_cls,
callable_,
args,
kwargs,
msg=None,
check_context=False,
cause_cls=None,
):
with _expect_raises(except_cls, msg, check_context, cause_cls) as ec:
callable_(*args, **kwargs)
return ec.error
class _ErrorContainer:
error = None
@contextlib.contextmanager
def _expect_raises(except_cls, msg=None, check_context=False, cause_cls=None):
ec = _ErrorContainer()
if check_context:
are_we_already_in_a_traceback = sys.exc_info()[0]
try:
yield ec
success = False
except except_cls as err:
ec.error = err
success = True
if msg is not None:
# I'm often pdbing here, and "err" above isn't
# in scope, so assign the string explicitly
error_as_string = str(err)
assert re.search(msg, error_as_string, re.UNICODE), "%r !~ %s" % (
msg,
error_as_string,
)
if cause_cls is not None:
_assert_proper_cause_cls(err, cause_cls)
if check_context and not are_we_already_in_a_traceback:
_assert_proper_exception_context(err)
print(str(err).encode("utf-8"))
# it's generally a good idea to not carry traceback objects outside
# of the except: block, but in this case especially we seem to have
# hit some bug in either python 3.10.0b2 or greenlet or both which
# this seems to fix:
# https://github.com/python-greenlet/greenlet/issues/242
del ec
# assert outside the block so it works for AssertionError too !
assert success, "Callable did not raise an exception"
def expect_raises(except_cls, check_context=False):
return _expect_raises(except_cls, check_context=check_context)
def expect_raises_message(except_cls, msg, check_context=False):
return _expect_raises(except_cls, msg=msg, check_context=check_context)
def expect_raises_with_proper_context(except_cls, check_context=True):
return _expect_raises(except_cls, check_context=check_context)
def expect_raises_message_with_proper_context(
except_cls, msg, check_context=True
):
return _expect_raises(except_cls, msg=msg, check_context=check_context)

View file

@ -0,0 +1,17 @@
from dataclasses import dataclass
from pathlib import Path
from ._config import ReadsCfg
from .helpers import make_path
@dataclass
class Config(ReadsCfg):
module_base: Path
template_base: Path
section_header = "mako_testing"
converters = {Path: make_path}
config = Config.from_cfg_file("./setup.cfg")

View file

@ -0,0 +1,80 @@
import pytest
from mako.ext.beaker_cache import has_beaker
from mako.util import update_wrapper
try:
import babel.messages.extract as babel
except ImportError:
babel = None
try:
import lingua
except ImportError:
lingua = None
try:
import dogpile.cache # noqa
except ImportError:
has_dogpile_cache = False
else:
has_dogpile_cache = True
requires_beaker = pytest.mark.skipif(
not has_beaker, reason="Beaker is required for these tests."
)
requires_babel = pytest.mark.skipif(
babel is None, reason="babel not installed: skipping babelplugin test"
)
requires_lingua = pytest.mark.skipif(
lingua is None, reason="lingua not installed: skipping linguaplugin test"
)
requires_dogpile_cache = pytest.mark.skipif(
not has_dogpile_cache,
reason="dogpile.cache is required to run these tests",
)
def _pygments_version():
try:
import pygments
version = pygments.__version__
except:
version = "0"
return version
requires_pygments_14 = pytest.mark.skipif(
_pygments_version() < "1.4", reason="Requires pygments 1.4 or greater"
)
# def requires_pygments_14(fn):
# return skip_if(
# lambda: version < "1.4", "Requires pygments 1.4 or greater"
# )(fn)
def requires_no_pygments_exceptions(fn):
def go(*arg, **kw):
from mako import exceptions
exceptions._install_fallback()
try:
return fn(*arg, **kw)
finally:
exceptions._install_highlighting()
return update_wrapper(go, fn)

View file

@ -0,0 +1,109 @@
import os
from mako.cache import CacheImpl
from mako.cache import register_plugin
from mako.template import Template
from .assertions import eq_
from .config import config
class TemplateTest:
def _file_template(self, filename, **kw):
filepath = self._file_path(filename)
return Template(
uri=filename,
filename=filepath,
module_directory=config.module_base,
**kw,
)
def _file_path(self, filename):
name, ext = os.path.splitext(filename)
py3k_path = os.path.join(config.template_base, name + "_py3k" + ext)
if os.path.exists(py3k_path):
return py3k_path
return os.path.join(config.template_base, filename)
def _do_file_test(
self,
filename,
expected,
filters=None,
unicode_=True,
template_args=None,
**kw,
):
t1 = self._file_template(filename, **kw)
self._do_test(
t1,
expected,
filters=filters,
unicode_=unicode_,
template_args=template_args,
)
def _do_memory_test(
self,
source,
expected,
filters=None,
unicode_=True,
template_args=None,
**kw,
):
t1 = Template(text=source, **kw)
self._do_test(
t1,
expected,
filters=filters,
unicode_=unicode_,
template_args=template_args,
)
def _do_test(
self,
template,
expected,
filters=None,
template_args=None,
unicode_=True,
):
if template_args is None:
template_args = {}
if unicode_:
output = template.render_unicode(**template_args)
else:
output = template.render(**template_args)
if filters:
output = filters(output)
eq_(output, expected)
class PlainCacheImpl(CacheImpl):
"""Simple memory cache impl so that tests which
use caching can run without beaker."""
def __init__(self, cache):
self.cache = cache
self.data = {}
def get_or_create(self, key, creation_function, **kw):
if key in self.data:
return self.data[key]
else:
self.data[key] = data = creation_function(**kw)
return data
def put(self, key, value, **kw):
self.data[key] = value
def get(self, key, **kw):
return self.data[key]
def invalidate(self, key, **kw):
del self.data[key]
register_plugin("plain", __name__, "PlainCacheImpl")

View file

@ -0,0 +1,67 @@
import contextlib
import pathlib
from pathlib import Path
import re
import time
from typing import Union
from unittest import mock
def flatten_result(result):
return re.sub(r"[\s\r\n]+", " ", result).strip()
def result_lines(result):
return [
x.strip()
for x in re.split(r"\r?\n", re.sub(r" +", " ", result))
if x.strip() != ""
]
def make_path(
filespec: Union[Path, str],
make_absolute: bool = True,
check_exists: bool = False,
) -> Path:
path = Path(filespec)
if make_absolute:
path = path.resolve(strict=check_exists)
if check_exists and (not path.exists()):
raise FileNotFoundError(f"No file or directory at {filespec}")
return path
def _unlink_path(path, missing_ok=False):
# Replicate 3.8+ functionality in 3.7
cm = contextlib.nullcontext()
if missing_ok:
cm = contextlib.suppress(FileNotFoundError)
with cm:
path.unlink()
def replace_file_with_dir(pathspec):
path = pathlib.Path(pathspec)
_unlink_path(path, missing_ok=True)
path.mkdir(exist_ok=True)
return path
def file_with_template_code(filespec):
with open(filespec, "w") as f:
f.write(
"""
i am an artificial template just for you
"""
)
return filespec
@contextlib.contextmanager
def rewind_compile_time(hours=1):
rewound = time.time() - (hours * 3_600)
with mock.patch("mako.codegen.time") as codegen_time:
codegen_time.time.return_value = rewound
yield