From 2ee20d37a277e6fa1c2ad49f68fe8fad4dc32319 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Mon, 10 Aug 2020 11:57:15 +0200
Subject: [PATCH 2/2] pep8: put 2 lines between function definitions (#45780)

---
 combo/public/templatetags/combo.py | 42 ++++++++++++++++++++++++++++++
 tests/test_public_templatetags.py  |  5 ++++
 2 files changed, 47 insertions(+)

diff --git a/combo/public/templatetags/combo.py b/combo/public/templatetags/combo.py
index b350e69f..51cb57d2 100644
--- a/combo/public/templatetags/combo.py
+++ b/combo/public/templatetags/combo.py
@@ -48,20 +48,22 @@ from combo.data.models import Page, Placeholder
 from combo.public.menu import get_menu_context
 from combo.utils import NothingInCacheException, flatten_context
 from combo.utils.date import make_date, make_datetime
 from combo.apps.dashboard.models import DashboardCell, Tile
 
 
 register = template.Library()
 
+
 def skeleton_text(context, placeholder_name, content=''):
     return '{%% block placeholder-%s %%}{%% block %s %%}%s{%% endblock %%}{%% endblock %%}' % (
         placeholder_name, placeholder_name, content)
 
+
 @register.inclusion_tag('combo/placeholder.html', takes_context=True)
 def placeholder(context, placeholder_name, **options):
     placeholder = Placeholder(key=placeholder_name, cell=context.get('cell'), **options)
     # make sure render_skeleton is available in context
     context['render_skeleton'] = context.get('render_skeleton')
     if context.get('placeholder_search_mode'):
         if placeholder.name:
             # only include placeholders with a name
@@ -92,16 +94,17 @@ def placeholder(context, placeholder_name, **options):
         (context.get('render_skeleton') or x.is_relevant(context) and
          x.is_visible(user=context['request'].user, check_validity_info=False))]
     if context.get('render_skeleton'):
         context['skeleton'] = skeleton_text(context, placeholder_name)
     else:
         context['skeleton'] = ''
     return context
 
+
 @register.simple_tag(takes_context=True)
 def render_cell(context, cell):
     if context.get('render_skeleton') and cell.is_user_dependant(context):
         context = flatten_context(context)
         return template.loader.get_template('combo/deferred-cell.html').render(context)
 
     in_dashboard = False
     if DashboardCell.is_enabled():
@@ -123,16 +126,17 @@ def render_cell(context, cell):
         return cell.render(context)
     except NothingInCacheException:
         return template.loader.get_template('combo/deferred-cell.html').render(context)
     except:
         if context.get('placeholder_search_mode'):
             return ''
         raise
 
+
 @register.tag
 def skeleton_extra_placeholder(parser, token):
     try:
         tag_name, placeholder_name = token.split_contents()
     except ValueError:
         raise template.TemplateSyntaxError(
             "%r tag requires exactly one argument" % token.contents.split()[0]
         )
@@ -169,131 +173,145 @@ class ExtraPlaceholderNode(template.Node):
         self.placeholder_name = placeholder_name
         self.content = content
 
     def render(self, context):
         if not context.get('render_skeleton'):
             return self.nodelist.render(context)
         return skeleton_text(context, self.placeholder_name, content=self.content)
 
+
 @register.inclusion_tag('combo/menu.html', takes_context=True)
 def show_menu(context, level=0, current_page=None, depth=1, ignore_visibility=True, reduce_depth=False):
     if reduce_depth:
         depth -= 1
     new_context = {
         'page': context['page'],
         'render_skeleton': context.get('render_skeleton'),
         'request': context['request']}
     return get_menu_context(new_context, level=level, current_page=current_page,
             depth=depth, ignore_visibility=ignore_visibility)
 
+
 @register.simple_tag(takes_context=True)
 def page_absolute_url(context, page):
     return context['request'].build_absolute_uri(page.get_online_url())
 
+
 @register.filter(name='strptime')
 @stringfilter
 def strptime(date_string, date_format):
     try:
         return datetime.datetime.strptime(date_string, date_format)
     except ValueError:
         return None
 
+
 @register.filter
 def parse_date(date_string):
     try:
         return make_date(date_string)
     except ValueError:
         pass
     # fallback to Django function
     try:
         return dateparse.parse_date(date_string)
     except (ValueError, TypeError):
         return None
 
+
 @register.filter(expects_localtime=True, is_safe=False)
 def date(value, arg=None):
     if arg is None:
         return parse_date(value) or ''
     if not isinstance(value, (datetime.datetime, datetime.date, datetime.time)):
         value = parse_datetime(value) or parse_date(value)
     return defaultfilters.date(value, arg=arg)
 
+
 @register.filter
 def parse_datetime(datetime_string):
     try:
         return make_datetime(datetime_string)
     except ValueError:
         pass
     # fallback to Django function
     try:
         return dateparse.parse_datetime(datetime_string)
     except (ValueError, TypeError):
         return None
 
+
 @register.filter(name='datetime', expects_localtime=True, is_safe=False)
 def datetime_(value, arg=None):
     if arg is None:
         return parse_datetime(value) or ''
     if not isinstance(value, (datetime.datetime, datetime.date, datetime.time)):
         value = parse_datetime(value)
     return defaultfilters.date(value, arg=arg)
 
+
 @register.filter
 def parse_time(time_string):
     # if input is a datetime, extract its time
     try:
         dt = parse_datetime(time_string)
         if dt:
             return dt.time()
     except (ValueError, TypeError):
         pass
     # fallback to Django function
     try:
         return dateparse.parse_time(time_string)
     except (ValueError, TypeError):
         return None
 
+
 @register.filter(expects_localtime=True, is_safe=False)
 def time(value, arg=None):
     if arg is None:
         parsed = parse_time(value)
         return parsed if parsed is not None else ''  # because bool(midnight) == False
     if not isinstance(value, (datetime.datetime, datetime.date, datetime.time)):
         value = parse_time(value)
     return defaultfilters.date(value, arg=arg)
 
+
 @register.filter
 def shown_because_admin(cell, request):
     if not (request.user and request.user.is_superuser):
         return False
     if cell.public:
         return False
     cell_groups = cell.groups.all()
     if not cell_groups:
         return False
     return not(set(cell_groups).intersection(request.user.groups.all()))
 
+
 @register.filter(name='has_role')
 def has_role(user, groupname):
     if not user or user.is_anonymous:
         return False
     return user.groups.filter(name=groupname).exists()
 
+
 @register.filter(name='get')
 def get(obj, key):
     try:
         return obj.get(key)
     except AttributeError:
         return None
 
+
 @register.filter
 def split(string, separator=' '):
     return (string or '').split(separator)
 
+
 @register.filter
 def strip(string, chars=None):
     if not string:
         return ''
     if chars:
         return force_text(string).strip(force_text(chars))
     else:
         return force_text(string).strip()
@@ -327,46 +345,53 @@ def get_group(group_list, group_name):
     for group in group_list:
         if getattr(group, 'grouper', Ellipsis) == group_name:
             # Django >= 1.11, namedtuple
             ret.extend(group.list)
         elif not hasattr(group, 'grouper') and group['grouper'] == group_name:
             ret.extend(group['list'])
     return ret
 
+
 @register.filter(name='is_empty_placeholder')
 def is_empty_placeholder(page, placeholder_name):
     return len([x for x in page.get_cells() if x.placeholder == placeholder_name]) == 0
 
+
 @register.filter(name='list')
 def as_list(obj):
     return list(obj)
 
+
 @register.filter(name='as_json')
 def as_json(obj):
     return json.dumps(obj)
 
+
 @register.filter
 def signed(obj):
     return signing.dumps(obj)
 
+
 @register.filter
 def name_id(user):
     if user and user.is_authenticated:
         user_name_id = user.get_name_id()
         if user_name_id:
             return user_name_id
     # it is important to raise this so get_templated_url is aborted and no call
     # is tried with a missing user argument.
     raise VariableDoesNotExist('name_id')
 
+
 @register.simple_tag
 def get_page(page_slug):
     return Page.objects.get(slug=page_slug)
 
+
 @register.filter
 def startswith(string, substring):
     return string and force_text(string).startswith(force_text(substring))
 
 
 @register.filter
 def endswith(string, substring):
     return string and force_text(string).endswith(force_text(substring))
@@ -376,72 +401,78 @@ def parse_float(value):
     if isinstance(value, six.string_types):
         # replace , by . for French users comfort
         value = value.replace(',', '.')
     try:
         return float(value)
     except (ValueError, TypeError):
         return ''
 
+
 def get_as_datetime(s):
     result = parse_datetime(s)
     if not result:
         result = parse_date(s)
         if result:
             result = datetime.datetime(year=result.year, month=result.month, day=result.day)
     return result
 
+
 @register.filter(expects_localtime=True, is_safe=False)
 def add_days(value, arg):
     value = parse_date(value)  # consider only date, not hours
     if not value:
         return ''
     arg = parse_float(arg)
     if not arg:
         return value
     result = value + datetime.timedelta(days=float(arg))
     return result
 
+
 @register.filter(expects_localtime=True, is_safe=False)
 def add_hours(value, arg):
     value = parse_datetime(value)
     if not value:
         return ''
     arg = parse_float(arg)
     if not arg:
         return value
     return value + datetime.timedelta(hours=float(arg))
 
+
 @register.filter(expects_localtime=True, is_safe=False)
 def age_in_days(value, today=None):
     value = parse_date(value)
     if not value:
         return ''
     if today is not None:
         today = parse_date(today)
         if not today:
             return ''
     else:
         today = datetime.date.today()
     return (today - value).days
 
+
 @register.filter(expects_localtime=True, is_safe=False)
 def age_in_hours(value, now=None):
     # consider value and now as datetimes (and not dates)
     value = parse_datetime(value)
     if not value:
         return ''
     if now is not None:
         now = parse_datetime(now)
         if not now:
             return ''
     else:
         now = datetime.datetime.now()
     return int((now - value).total_seconds() / 3600)
 
+
 def age_in_years_and_months(born, today=None):
     '''Compute age since today as the number of years and months elapsed'''
     born = make_date(born)
     if not born:
         return ''
     if today is not None:
         today = make_date(today)
         if not today:
@@ -453,23 +484,25 @@ def age_in_years_and_months(born, today=None):
     months = today.month - born.month
     if before:
         years -= 1
         months += 12
     if today.day < born.day:
         months -= 1
     return years, months
 
+
 @register.filter(expects_localtime=True, is_safe=False)
 def age_in_years(value, today=None):
     try:
         return age_in_years_and_months(value, today)[0]
     except ValueError:
         return ''
 
+
 @register.filter(expects_localtime=True, is_safe=False)
 def age_in_months(value, today=None):
     try:
         years, months = age_in_years_and_months(value, today)
     except ValueError:
         return ''
     return years * 12 + months
 
@@ -490,24 +523,26 @@ def parse_decimal(value, default=Decimal(0)):
     if isinstance(value, six.string_types):
         # replace , by . for French users comfort
         value = value.replace(',', '.')
     try:
         return Decimal(value).quantize(Decimal('1.0000')).normalize()
     except (ArithmeticError, TypeError):
         return default
 
+
 @register.filter(is_safe=False)
 def decimal(value, arg=None):
     if not isinstance(value, Decimal):
         value = parse_decimal(value)
     if arg is None:
         return value
     return defaultfilters.floatformat(value, arg=arg)
 
+
 @register.filter
 def add(term1, term2):
     '''replace the "add" native django filter'''
 
     if term1 is None:
         term1 = ''
     if term2 is None:
         term2 = ''
@@ -517,46 +552,53 @@ def add(term1, term2):
     if term1_decimal is not None and term2_decimal is not None:
         return term1_decimal + term2_decimal
     if term1 == '' and term2_decimal is not None:
         return term2_decimal
     if term2 == '' and term1_decimal is not None:
         return term1_decimal
     return defaultfilters.add(term1, term2)
 
+
 @register.filter
 def subtract(term1, term2):
     return parse_decimal(term1) - parse_decimal(term2)
 
+
 @register.filter
 def multiply(term1, term2):
     return parse_decimal(term1) * parse_decimal(term2)
 
+
 @register.filter
 def divide(term1, term2):
     try:
         return parse_decimal(term1) / parse_decimal(term2)
     except DecimalInvalidOperation:
         return ''
     except DecimalDivisionByZero:
         return ''
 
+
 @register.filter
 def ceil(value):
     '''the smallest integer value greater than or equal to value'''
     return decimal(math.ceil(parse_decimal(value)))
 
+
 @register.filter
 def floor(value):
     return decimal(math.floor(parse_decimal(value)))
 
+
 @register.filter(name='abs')
 def abs_(value):
     return decimal(abs(parse_decimal(value)))
 
+
 _json_script_escapes = {
     ord('>'): '\\u003E',
     ord('<'): '\\u003C',
     ord('&'): '\\u0026',
 }
 
 
 @register.filter(is_safe=True)
diff --git a/tests/test_public_templatetags.py b/tests/test_public_templatetags.py
index c3d8bd6f..d771d01b 100644
--- a/tests/test_public_templatetags.py
+++ b/tests/test_public_templatetags.py
@@ -23,16 +23,17 @@ pytestmark = pytest.mark.django_db
 def test_strptime():
     t = Template('{{ someday|strptime:"%Y-%m-%d"|date:"Y" }}')
     assert t.render(Context({'someday': '2015-04-15'})) == '2015'
     assert t.render(Context({'someday': 'foobar'})) == ''
     assert t.render(Context({'someday': None})) == ''
     assert t.render(Context({'someday': {'foo': 'bar'}})) == ''
     assert t.render(Context({'someday': ['foo', 'bar']})) == ''
 
+
 def test_parse_datetime():
     t = Template('{{ someday|parse_datetime|date:"Y m d H i s T" }}')
     expected = '2015 04 15 13 11 12 UTC'
     assert t.render(Context({'someday': '2015-04-15T13:11:12'})) == expected
     assert t.render(Context({'someday': '2015-04-15 13:11:12'})) == expected
     assert t.render(Context({'someday': '2015-04-15T13:11:12Z'})) == expected
     assert t.render(Context({'someday': '2015-04-15T13:11:12+00:00'})) == expected
     assert t.render(Context({'someday': '2015-04-15T13:11:12.12345'})) == expected
@@ -69,16 +70,17 @@ def test_parse_datetime():
     assert t.render(Context({'someday': '13:99'})) == ''
     assert t.render(Context({'someday': '13'})) == ''
     assert t.render(Context({'someday': 'foobar'})) == ''
     assert t.render(Context({'someday': ''})) == ''
     assert t.render(Context({'someday': None})) == ''
     assert t.render(Context({'someday': {'foo': 'bar'}})) == ''
     assert t.render(Context({'someday': ['foo', 'bar']})) == ''
 
+
 def test_has_role():
     t = Template('{{ request.user|has_role:"Role1" }}')
 
     request = RequestFactory().get('/')
     user = User(username='foo', email='foo@example.net')
     user.save()
     request.user = user
     context = Context({'request': request})
@@ -102,16 +104,17 @@ def test_has_role():
     context = Context()
     assert t.render(context) == 'False'
     request = RequestFactory().get('/')
     context = Context({'request': request})
     assert t.render(context) == 'False'
     request.user = AnonymousUser()
     assert t.render(context) == 'False'
 
+
 def test_get():
     t = Template('{{ foo|get:"foo-bar" }}')
     context = Context({'foo': {'foo-bar': 'hello'}})
     assert t.render(context) == 'hello'
     context = Context({'foo': {'bar-foo': 'hello'}})
     assert t.render(context) == 'None'
     context = Context({'foo': None})
     assert t.render(context) == 'None'
@@ -119,22 +122,24 @@ def test_get():
     t = Template('{{ foo|get:"foo-bar"|default:"" }}')
     context = Context({'foo': {'rab': 'hello'}})
     assert t.render(context) == ''
 
     t = Template('{{ foo|get:key }}')
     context = Context({'foo': {'foo-bar': 'hello'}, 'key': 'foo-bar'})
     assert t.render(context) == 'hello'
 
+
 def test_split():
     t = Template('{% for x in plop|split %}{{x}}<br>{% endfor %}')
     assert t.render(Context({'plop': 'ab cd ef'})) == 'ab<br>cd<br>ef<br>'
     t = Template('{% for x in plop|split:"|" %}{{x}} {% endfor %}')
     assert t.render(Context({'plop': 'ab|cd|ef'})) == 'ab cd ef '
 
+
 def test_strip_templatetag():
     tmpl = Template('{{ foo|strip }}')
     assert tmpl.render(Context()) == ''
     assert tmpl.render(Context({'foo': None})) == ''
     assert tmpl.render(Context({'foo': ' foo bar '})) == 'foo bar'
     assert tmpl.render(Context({'foo': ' foo bar\t'})) == 'foo bar'
     assert tmpl.render(Context({'foo': ' félé  '})) == 'félé'
     tmpl = Template('{{ foo|strip:"XY" }}')
-- 
2.28.0

