chevron icon indicating copy to clipboard operation
chevron copied to clipboard

False-like values are not rendered when iterating

Open jrcutler opened this issue 6 years ago • 9 comments

It appears that False-like values (e.g. False, 0, 0.0, '', and []) are not being rendered correctly when iterating.

Example:

import chevron
template = '{{#.}}({{.}}){{/.}}{{^.}}empty{{/.}}'
data = [ False, 0, 0.0, '', [] ]
output = chevron.render(template, data)
print(repr(output))

Expected result: '(False)(0)(0.0)()([])'

Actual result: ''

(The fact that the specification doesn't test False-like values in the "Implicit Iterators" block of sections.yml is probably an upstream bug.)

jrcutler avatar Jul 19 '19 00:07 jrcutler

Just took a few minutes testing it out, and yeah it looks like you found another hole in the spec.

dmorrison42 avatar Jul 19 '19 00:07 dmorrison42

I'm pretty sure the expected result should be (False)(0)(0.0)()() due to this test and it's what mustache.io outputs as well.

Am I wrong in thinking that? Or is the list printing as an empty list expected as well?

noahmorrison avatar Jul 19 '19 01:07 noahmorrison

Well simply telling it that it shouldn't do falsy handling when inside a list doesn't cut it.

        # If the current scope is falsy and not the only scope
        elif not current_scope and len(scopes) != 1 and not (
            isinstance(scopes[1], (Sequence, Iterator))
        ):

Then I get '(False)(0)(0.0)()([])empty'.

I think in general inverted scopes have a lot of issues that aren't tested for some reason. Not sure yet.

dmorrison42 avatar Jul 19 '19 01:07 dmorrison42

I've got a commit that works. basically it passes an is_seq value into the render function when it's doing a sequence. Then when we're inside of a section or an inverted section I set that to false.

It works, but as you said, there's probably edge cases we're just not getting

noahmorrison avatar Jul 19 '19 01:07 noahmorrison

Also I had to cleanup _get_key, as it was returning empty lists when they were referenced by {{.}}}, and not returning 0.0 when it was referenced by name (e.g. {{zerodotzero}} would output 0).

I could probably think of about 5 tests to add to ExpandedCoverage that this issue has unearthed. You found a good one @jrcutler :stuck_out_tongue:

noahmorrison avatar Jul 19 '19 01:07 noahmorrison

@noahmorrison is this behavior correct? I'm pretty sure it's not.

    def test_array(self):
        args = {
            'template': '{{.}}',
            'data': ['b'],
        }

        result = chevron.render(**args)
        expected = '''['b']'''

        self.assertEqual(result, expected)

dmorrison42 avatar Jul 19 '19 01:07 dmorrison42

Yeah again the spec is pretty vague. Mustache.io prints 'b' so I guess when in doubt we should side with that?

If there was any sane way to fuzz this I'd be all for that.

noahmorrison avatar Jul 19 '19 02:07 noahmorrison

@jrcutler there's definitely a fix coming! (Code is already done) But I'm gonna wait til the weekend to do anything as it's late and there's life stuff I have to go do.

noahmorrison avatar Jul 19 '19 02:07 noahmorrison

Will there be a fix?

jrcutler avatar Sep 18 '19 18:09 jrcutler