diff --git a/jinja2/filters.py b/jinja2/filters.py index e5c7a1ab4..eb8f54ba9 100644 --- a/jinja2/filters.py +++ b/jinja2/filters.py @@ -10,8 +10,8 @@ """ import re import math +import random -from random import choice from operator import itemgetter from itertools import groupby from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode, \ @@ -360,13 +360,13 @@ def do_last(environment, seq): return environment.undefined('No last item, sequence was empty.') -@environmentfilter -def do_random(environment, seq): +@contextfilter +def do_random(context, seq): """Return a random item from the sequence.""" try: - return choice(seq) + return random.choice(seq) except IndexError: - return environment.undefined('No random item, sequence was empty.') + return context.environment.undefined('No random item, sequence was empty.') def do_filesizeformat(value, binary=False): diff --git a/tests/test_filters.py b/tests/test_filters.py index 741ef341b..ceaba509a 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -8,6 +8,7 @@ :copyright: (c) 2010 by the Jinja Team. :license: BSD, see LICENSE for more details. """ +import random import pytest from jinja2 import Markup, Environment from jinja2._compat import text_type, implements_to_string @@ -177,12 +178,18 @@ def test_pprint(self, env): data = list(range(1000)) assert tmpl.render(data=data) == pformat(data) - def test_random(self, env): + def test_random1(self, env): tmpl = env.from_string('''{{ seq|random }}''') seq = list(range(100)) for _ in range(10): assert int(tmpl.render(seq=seq)) in seq + def test_random2(self, env, monkeypatch): + monkeypatch.setattr(random, 'choice', lambda seq: seq[0]) + tmpl = env.from_string('''{{ range(100)|random }}''') + monkeypatch.setattr(random, 'choice', lambda seq: seq[2]) + assert tmpl.render() == '2' + def test_reverse(self, env): tmpl = env.from_string('{{ "foobar"|reverse|join }}|' '{{ [1, 2, 3]|reverse|list }}')