def test_spans(self):
        # test the string sections our fields come from
        string = 'hello world'
        r = parse.parse('hello {}', string)
        self.assertEqual(r.spans, {0: (6, 11)})
        start, end = r.spans[0]
        self.assertEqual(string[start:end], r.fixed[0])

        string = 'hello     world'
        r = parse.parse('hello {:>}', string)
        self.assertEqual(r.spans, {0: (10, 15)})
        start, end = r.spans[0]
        self.assertEqual(string[start:end], r.fixed[0])

        string = 'hello 0x12 world'
        r = parse.parse('hello {val:x} world', string)
        self.assertEqual(r.spans, {'val': (6, 10)})
        start, end = r.spans['val']
        self.assertEqual(string[start:end], '0x%x' % r.named['val'])

        string = 'hello world and other beings'
        r = parse.parse('hello {} {name} {} {spam}', string)
        self.assertEqual(r.spans, {
            0: (6, 11),
            'name': (12, 15),
            1: (16, 21),
            'spam': (22, 28)
        })
 def test_dotted_type_conversion_pull_8(self):
     # test pull request 8 which fixes type conversion related to dotted
     # names being applied correctly
     r = parse.parse('{a.b:d}', '1')
     self.assertEqual(r['a.b'], 1)
     r = parse.parse('{a_b:w} {a.b:d}', '1 2')
     self.assertEqual(r['a_b'], '1')
     self.assertEqual(r['a.b'], 2)
 def test_dotted_type_conversion_pull_8(self):
     # test pull request 8 which fixes type conversion related to dotted
     # names being applied correctly
     r = parse.parse('{a.b:d}', '1')
     self.assertEqual(r['a.b'], 1)
     r = parse.parse('{a_b:w} {a.b:d}', '1 2')
     self.assertEqual(r['a_b'], '1')
     self.assertEqual(r['a.b'], 2)
 def test_regular_expression(self):
     # match an actual regular expression
     s = r'^(hello\s[wW]{}!+.*)$'
     e = s.replace('{}', 'orld')
     r = parse.parse(s, e)
     self.assertEqual(r.fixed, ('orld',))
     e = s.replace('{}', '.*?')
     r = parse.parse(s, e)
     self.assertEqual(r.fixed, ('.*?',))
 def test_named_aligned_typed(self):
     # pull a named, typed values out of string
     r = parse.parse('hello {number:<d} {things}', 'hello 12      people')
     self.assertEqual(r.named, dict(number=12, things='people'))
     r = parse.parse('hello {number:>d} {things}', 'hello      12 people')
     self.assertEqual(r.named, dict(number=12, things='people'))
     r = parse.parse('hello {number:^d} {things}',
         'hello      12      people')
     self.assertEqual(r.named, dict(number=12, things='people'))
 def test_regular_expression(self):
     # match an actual regular expression
     s = r'^(hello\s[wW]{}!+.*)$'
     e = s.replace('{}', 'orld')
     r = parse.parse(s, e)
     self.assertEqual(r.fixed, ('orld', ))
     e = s.replace('{}', '.*?')
     r = parse.parse(s, e)
     self.assertEqual(r.fixed, ('.*?', ))
 def test_named_aligned_typed(self):
     # pull a named, typed values out of string
     r = parse.parse('hello {number:<d} {things}', 'hello 12      people')
     self.assertEqual(r.named, dict(number=12, things='people'))
     r = parse.parse('hello {number:>d} {things}', 'hello      12 people')
     self.assertEqual(r.named, dict(number=12, things='people'))
     r = parse.parse('hello {number:^d} {things}',
                     'hello      12      people')
     self.assertEqual(r.named, dict(number=12, things='people'))
 def test_custom_type(self):
     # use a custom type
     r = parse.parse('{:shouty} {:spam}', 'hello world',
         dict(shouty=lambda s: s.upper(),
             spam=lambda s: ''.join(reversed(s))))
     self.assertEqual(r.fixed, ('HELLO', 'dlrow'))
     r = parse.parse('{:d}', '12', dict(d=lambda s: int(s) * 2))
     self.assertEqual(r.fixed, (24,))
     r = parse.parse('{:d}', '12')
     self.assertEqual(r.fixed, (12,))
 def test_custom_type(self):
     # use a custom type
     r = parse.parse(
         '{:shouty} {:spam}', 'hello world',
         dict(shouty=lambda s: s.upper(),
              spam=lambda s: ''.join(reversed(s))))
     self.assertEqual(r.fixed, ('HELLO', 'dlrow'))
     r = parse.parse('{:d}', '12', dict(d=lambda s: int(s) * 2))
     self.assertEqual(r.fixed, (24, ))
     r = parse.parse('{:d}', '12')
     self.assertEqual(r.fixed, (12, ))
    def test_named_date_issue7(self):
        r = parse.parse('on {date:ti}', 'on 2012-09-17')
        self.assertEqual(r['date'], datetime(2012, 9, 17, 0, 0, 0))

        # fix introduced regressions
        r = parse.parse('a {:ti} b', 'a 1997-07-16T19:20 b')
        self.assertEqual(r[0], datetime(1997, 7, 16, 19, 20, 0))
        r = parse.parse('a {:ti} b', 'a 1997-07-16T19:20Z b')
        utc = parse.FixedTzOffset(0, 'UTC')
        self.assertEqual(r[0], datetime(1997, 7, 16, 19, 20, tzinfo=utc))
        r = parse.parse('a {date:ti} b', 'a 1997-07-16T19:20Z b')
        self.assertEqual(r['date'], datetime(1997, 7, 16, 19, 20, tzinfo=utc))
    def test_named_date_issue7(self):
        r = parse.parse('on {date:ti}', 'on 2012-09-17')
        self.assertEqual(r['date'], datetime(2012, 9, 17, 0, 0, 0))

        # fix introduced regressions
        r = parse.parse('a {:ti} b', 'a 1997-07-16T19:20 b')
        self.assertEqual(r[0], datetime(1997, 7, 16, 19, 20, 0))
        r = parse.parse('a {:ti} b', 'a 1997-07-16T19:20Z b')
        utc = parse.FixedTzOffset(0, 'UTC')
        self.assertEqual(r[0], datetime(1997, 7, 16, 19, 20, tzinfo=utc))
        r = parse.parse('a {date:ti} b', 'a 1997-07-16T19:20Z b')
        self.assertEqual(r['date'], datetime(1997, 7, 16, 19, 20, tzinfo=utc))
 def test_dot_separated_fields_name_collisions(self):
     # this should just work and provide the named value
     res = parse.parse('{a_.b}_{a__b}_{a._b}_{a___b}', 'a_b_c_d')
     assert res.named['a_.b'] == 'a'
     assert res.named['a__b'] == 'b'
     assert res.named['a._b'] == 'c'
     assert res.named['a___b'] == 'd'
 def test_dot_separated_fields_name_collisions(self):
     # this should just work and provide the named value
     res = parse.parse('{a_.b}_{a__b}_{a._b}_{a___b}', 'a_b_c_d')
     assert res.named['a_.b'] == 'a'
     assert res.named['a__b'] == 'b'
     assert res.named['a._b'] == 'c'
     assert res.named['a___b'] == 'd'
 def test_mixed_types(self):
     # stress-test: pull one of everything out of a string
     r = parse.parse(
         '''
         letters: {:w}
         non-letters: {:W}
         whitespace: "{:s}"
         non-whitespace: \t{:S}\n
         digits: {:d} {:d}
         non-digits: {:D}
         numbers with thousands: {:n}
         fixed-point: {:f}
         floating-point: {:e}
         general numbers: {:g} {:g}
         binary: {:b}
         octal: {:o}
         hex: {:x}
         ISO 8601 e.g. {:ti}
         RFC2822 e.g. {:te}
         Global e.g. {:tg}
         US e.g. {:ta}
         ctime() e.g. {:tc}
         HTTP e.g. {:th}
         time: {:tt}
         final value: {}
     ''', '''
         letters: abcdef_GHIJLK
         non-letters: !@#%$ *^%
         whitespace: "   \t\n"
         non-whitespace: \tabc\n
         digits: 12345 0b1011011
         non-digits: abcdef
         numbers with thousands: 1,000
         fixed-point: 100.2345
         floating-point: 1.1e-10
         general numbers: 1 1.1
         binary: 0b1000
         octal: 0o1000
         hex: 0x1000
         ISO 8601 e.g. 1972-01-20T10:21:36Z
         RFC2822 e.g. Mon, 20 Jan 1972 10:21:36 +1000
         Global e.g. 20/1/1972 10:21:36 AM +1:00
         US e.g. 1/20/1972 10:21:36 PM +10:30
         ctime() e.g. Sun Sep 16 01:03:52 1973
         HTTP e.g. 21/Nov/2011:00:07:11 +0000
         time: 10:21:36 PM -5:30
         final value: spam
     ''')
     self.assertNotEqual(r, None)
     self.assertEqual(r.fixed[22], 'spam')
 def test_mixed_types(self):
     # stress-test: pull one of everything out of a string
     r = parse.parse('''
         letters: {:w}
         non-letters: {:W}
         whitespace: "{:s}"
         non-whitespace: \t{:S}\n
         digits: {:d} {:d}
         non-digits: {:D}
         numbers with thousands: {:n}
         fixed-point: {:f}
         floating-point: {:e}
         general numbers: {:g} {:g}
         binary: {:b}
         octal: {:o}
         hex: {:x}
         ISO 8601 e.g. {:ti}
         RFC2822 e.g. {:te}
         Global e.g. {:tg}
         US e.g. {:ta}
         ctime() e.g. {:tc}
         HTTP e.g. {:th}
         time: {:tt}
         final value: {}
     ''',
     '''
         letters: abcdef_GHIJLK
         non-letters: !@#%$ *^%
         whitespace: "   \t\n"
         non-whitespace: \tabc\n
         digits: 12345 0b1011011
         non-digits: abcdef
         numbers with thousands: 1,000
         fixed-point: 100.2345
         floating-point: 1.1e-10
         general numbers: 1 1.1
         binary: 0b1000
         octal: 0o1000
         hex: 0x1000
         ISO 8601 e.g. 1972-01-20T10:21:36Z
         RFC2822 e.g. Mon, 20 Jan 1972 10:21:36 +1000
         Global e.g. 20/1/1972 10:21:36 AM +1:00
         US e.g. 1/20/1972 10:21:36 PM +10:30
         ctime() e.g. Sun Sep 16 01:03:52 1973
         HTTP e.g. 21/Nov/2011:00:07:11 +0000
         time: 10:21:36 PM -5:30
         final value: spam
     ''')
     self.assertNotEqual(r, None)
     self.assertEqual(r.fixed[22], 'spam')
 def test_mixed_type_variant(self):
     r = parse.parse(
         '''
         letters: {:w}
         non-letters: {:W}
         whitespace: "{:s}"
         non-whitespace: \t{:S}\n
         digits: {:d}
         non-digits: {:D}
         numbers with thousands: {:n}
         fixed-point: {:f}
         floating-point: {:e}
         general numbers: {:g} {:g}
         binary: {:b}
         octal: {:o}
         hex: {:x}
         ISO 8601 e.g. {:ti}
         RFC2822 e.g. {:te}
         Global e.g. {:tg}
         US e.g. {:ta}
         ctime() e.g. {:tc}
         HTTP e.g. {:th}
         time: {:tt}
         final value: {}
     ''', '''
         letters: abcdef_GHIJLK
         non-letters: !@#%$ *^%
         whitespace: "   \t\n"
         non-whitespace: \tabc\n
         digits: 0xabcdef
         non-digits: abcdef
         numbers with thousands: 1.000.000
         fixed-point: 0.00001
         floating-point: NAN
         general numbers: 1.1e10 nan
         binary: 0B1000
         octal: 0O1000
         hex: 0X1000
         ISO 8601 e.g. 1972-01-20T10:21:36Z
         RFC2822 e.g. Mon, 20 Jan 1972 10:21:36 +1000
         Global e.g. 20/1/1972 10:21:36 AM +1:00
         US e.g. 1/20/1972 10:21:36 PM +10:30
         ctime() e.g. Sun Sep 16 01:03:52 1973
         HTTP e.g. 21/Nov/2011:00:07:11 +0000
         time: 10:21:36 PM -5:30
         final value: spam
     ''')
     self.assertNotEqual(r, None)
     self.assertEqual(r.fixed[21], 'spam')
 def test_mixed_type_variant(self):
     r = parse.parse('''
         letters: {:w}
         non-letters: {:W}
         whitespace: "{:s}"
         non-whitespace: \t{:S}\n
         digits: {:d}
         non-digits: {:D}
         numbers with thousands: {:n}
         fixed-point: {:f}
         floating-point: {:e}
         general numbers: {:g} {:g}
         binary: {:b}
         octal: {:o}
         hex: {:x}
         ISO 8601 e.g. {:ti}
         RFC2822 e.g. {:te}
         Global e.g. {:tg}
         US e.g. {:ta}
         ctime() e.g. {:tc}
         HTTP e.g. {:th}
         time: {:tt}
         final value: {}
     ''',
     '''
         letters: abcdef_GHIJLK
         non-letters: !@#%$ *^%
         whitespace: "   \t\n"
         non-whitespace: \tabc\n
         digits: 0xabcdef
         non-digits: abcdef
         numbers with thousands: 1.000.000
         fixed-point: 0.00001
         floating-point: NAN
         general numbers: 1.1e10 nan
         binary: 0B1000
         octal: 0O1000
         hex: 0X1000
         ISO 8601 e.g. 1972-01-20T10:21:36Z
         RFC2822 e.g. Mon, 20 Jan 1972 10:21:36 +1000
         Global e.g. 20/1/1972 10:21:36 AM +1:00
         US e.g. 1/20/1972 10:21:36 PM +10:30
         ctime() e.g. Sun Sep 16 01:03:52 1973
         HTTP e.g. 21/Nov/2011:00:07:11 +0000
         time: 10:21:36 PM -5:30
         final value: spam
     ''')
     self.assertNotEqual(r, None)
     self.assertEqual(r.fixed[21], 'spam')
    def test_spans(self):
        # test the string sections our fields come from
        string = 'hello world'
        r = parse.parse('hello {}', string)
        self.assertEqual(r.spans, {0: (6, 11)})
        start, end = r.spans[0]
        self.assertEqual(string[start:end], r.fixed[0])

        string = 'hello     world'
        r = parse.parse('hello {:>}', string)
        self.assertEqual(r.spans, {0: (10, 15)})
        start, end = r.spans[0]
        self.assertEqual(string[start:end], r.fixed[0])

        string = 'hello 0x12 world'
        r = parse.parse('hello {val:x} world', string)
        self.assertEqual(r.spans, {'val': (6, 10)})
        start, end = r.spans['val']
        self.assertEqual(string[start:end], '0x%x' % r.named['val'])

        string = 'hello world and other beings'
        r = parse.parse('hello {} {name} {} {spam}', string)
        self.assertEqual(r.spans, {0: (6, 11), 'name': (12, 15),
            1: (16, 21), 'spam': (22, 28)})
 def test_datetime_group_count(self):
     # test we increment the group count correctly for datetimes
     r = parse.parse('{:ti} {}', '1972-01-01 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:tg} {}', '1-1-1972 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:ta} {}', '1-1-1972 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:th} {}', '21/Nov/2011:10:21:36 +1000 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:te} {}', '21 Nov 2011 10:21:36 +1000 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:tc} {}', 'Mon Nov 21 10:21:36 2011 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:tt} {}', '10:21 spam')
     self.assertEqual(r.fixed[1], 'spam')
 def test_datetime_group_count(self):
     # test we increment the group count correctly for datetimes
     r = parse.parse('{:ti} {}', '1972-01-01 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:tg} {}', '1-1-1972 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:ta} {}', '1-1-1972 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:th} {}', '21/Nov/2011:10:21:36 +1000 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:te} {}', '21 Nov 2011 10:21:36 +1000 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:tc} {}', 'Mon Nov 21 10:21:36 2011 spam')
     self.assertEqual(r.fixed[1], 'spam')
     r = parse.parse('{:tt} {}', '10:21 spam')
     self.assertEqual(r.fixed[1], 'spam')
 def test_multiline(self):
     r = parse.parse('hello\n{}\nworld', 'hello\nthere\nworld')
     self.assertEqual(r.fixed[0], 'there')
 def test_mixed(self):
     # pull a fixed and named values out of string
     r = parse.parse('hello {} {name} {} {spam}',
         'hello world and other beings')
     self.assertEqual(r.fixed, ('world', 'other'))
     self.assertEqual(r.named, dict(name='and', spam='beings'))
 def test_named_repeated_fail_value(self):
     # test repeated name fails if value mismatches
     r = parse.parse('{n} {n}', 'x y')
     self.assertEqual(r, None)
 def test_named_repeated(self):
     # test a name may be repeated
     r = parse.parse('{n} {n}', 'x x')
     self.assertEqual(r.named, {'n': 'x'})
 def test_typed_fail(self):
     # pull a named, typed values out of string
     self.assertEqual(parse.parse('hello {:d} {:w}', 'hello people 12'),
         None)
 def test_typed(self):
     # pull a named, typed values out of string
     r = parse.parse('hello {:d} {:w}', 'hello 12 people')
     self.assertEqual(r.fixed, (12, 'people'))
     r = parse.parse('hello {:w} {:w}', 'hello 12 people')
     self.assertEqual(r.fixed, ('12', 'people'))
 def test_right(self):
     # pull right-aligned text out of string
     r = parse.parse('hello {:>}', 'hello       world')
     self.assertEqual(r.fixed, ('world', ))
 def test_typed(self):
     # pull a named, typed values out of string
     r = parse.parse('hello {:d} {:w}', 'hello 12 people')
     self.assertEqual(r.fixed, (12, 'people'))
     r = parse.parse('hello {:w} {:w}', 'hello 12 people')
     self.assertEqual(r.fixed, ('12', 'people'))
 def test_typed_fail(self):
     # pull a named, typed values out of string
     self.assertEqual(parse.parse('hello {:d} {:w}', 'hello people 12'),
                      None)
 def test_mixed(self):
     # pull a fixed and named values out of string
     r = parse.parse('hello {} {name} {} {spam}',
                     'hello world and other beings')
     self.assertEqual(r.fixed, ('world', 'other'))
     self.assertEqual(r.named, dict(name='and', spam='beings'))
 def test_named_repeated(self):
     # test a name may be repeated
     r = parse.parse('{n} {n}', 'x x')
     self.assertEqual(r.named, {'n': 'x'})
 def n(fmt, s, e):
     if parse.parse(fmt, s) is not None:
         self.fail('%r matched %r' % (fmt, s))
 def test_two_datetimes(self):
     r = parse.parse('a {:ti} {:ti} b', 'a 1997-07-16 2012-08-01 b')
     self.assertEqual(len(r.fixed), 2)
     self.assertEqual(r[0], datetime(1997, 7, 16))
     self.assertEqual(r[1], datetime(2012, 8, 1))
 def test_named(self):
     # pull a named value out of string
     r = parse.parse('hello {name}', 'hello world')
     self.assertEqual(r.named, {'name': 'world'})
 def test_named_repeated_fail_value(self):
     # test repeated name fails if value mismatches
     r = parse.parse('{n} {n}', 'x y')
     self.assertEqual(r, None)
 def test_pm_overflow_issue16(self):
     r = parse.parse('Meet at {:tg}', 'Meet at 1/2/2011 12:45 PM')
     self.assertEqual(r[0], datetime(2011, 2, 2, 0, 45))
 def test_center(self):
     # pull center-aligned text out of string
     r = parse.parse('hello {:^} world', 'hello  there     world')
     self.assertEqual(r.fixed, ('there', ))
 def test_dot_separated_fields(self):
     # this should just work and provide the named value
     res = parse.parse('{hello.world}_{jojo.foo.baz}_{simple}', 'a_b_c')
     assert res.named['hello.world'] == 'a'
     assert res.named['jojo.foo.baz'] == 'b'
     assert res.named['simple'] == 'c'
 def test_right(self):
     # pull right-aligned text out of string
     r = parse.parse('hello {:>}', 'hello       world')
     self.assertEqual(r.fixed, ('world', ))
 def test_dot_separated_fields(self):
     # this should just work and provide the named value
     res = parse.parse('{hello.world}_{jojo.foo.baz}_{simple}', 'a_b_c')
     assert res.named['hello.world'] == 'a'
     assert res.named['jojo.foo.baz'] == 'b'
     assert res.named['simple'] == 'c'
 def test_named(self):
     # pull a named value out of string
     r = parse.parse('hello {name}', 'hello world')
     self.assertEqual(r.named, {'name': 'world'})
 def test_nothing(self):
     # do no actual parsing
     r = parse.parse('{{hello}}', '{hello}')
     self.assertEqual(r.fixed, ())
     self.assertEqual(r.named, {})
 def test_named_repeated_type(self):
     # test a name may be repeated with type conversion
     r = parse.parse('{n:d} {n:d}', '1 1')
     self.assertEqual(r.named, {'n': 1})
 def test_two_datetimes(self):
     r = parse.parse('a {:ti} {:ti} b', 'a 1997-07-16 2012-08-01 b')
     self.assertEqual(len(r.fixed), 2)
     self.assertEqual(r[0], datetime(1997, 7, 16))
     self.assertEqual(r[1], datetime(2012, 8, 1))
 def test_named_repeated_type_fail_value(self):
     # test repeated name with type conversion fails if value mismatches
     r = parse.parse('{n:d} {n:d}', '1 2')
     self.assertEqual(r, None)
 def test_named_repeated_type_fail_value(self):
     # test repeated name with type conversion fails if value mismatches
     r = parse.parse('{n:d} {n:d}', '1 2')
     self.assertEqual(r, None)
 def test_left(self):
     # pull left-aligned text out of string
     r = parse.parse('{:<} world', 'hello       world')
     self.assertEqual(r.fixed, ('hello', ))
 def test_question_mark(self):
     # issue9: make sure a ? in the parse string is handled correctly
     r = parse.parse('"{}"?', '"teststr"?')
     self.assertEqual(r[0], 'teststr')
 def test_center(self):
     # pull center-aligned text out of string
     r = parse.parse('hello {:^} world', 'hello  there     world')
     self.assertEqual(r.fixed, ('there', ))
 def test_multiline(self):
     r = parse.parse('hello\n{}\nworld', 'hello\nthere\nworld')
     self.assertEqual(r.fixed[0], 'there')
 def n(fmt, s, e):
     if parse.parse(fmt, s) is not None:
         self.fail('%r matched %r' % (fmt, s))
 def test_question_mark(self):
     # issue9: make sure a ? in the parse string is handled correctly
     r = parse.parse('"{}"?', '"teststr"?')
     self.assertEqual(r[0], 'teststr')
 def test_pipe(self):
     # issue22: make sure a | in the parse string is handled correctly
     r = parse.parse('| {}', '| teststr')
     self.assertEqual(r[0], 'teststr')
 def test_fixed(self):
     # pull a fixed value out of string
     r = parse.parse('hello {}', 'hello world')
     self.assertEqual(r.fixed, ('world', ))
 def test_fixed(self):
     # pull a fixed value out of string
     r = parse.parse('hello {}', 'hello world')
     self.assertEqual(r.fixed, ('world', ))
 def test_left(self):
     # pull left-aligned text out of string
     r = parse.parse('{:<} world', 'hello       world')
     self.assertEqual(r.fixed, ('hello', ))
 def test_pm_overflow_issue16(self):
     r = parse.parse('Meet at {:tg}', 'Meet at 1/2/2011 12:45 PM')
     self.assertEqual(r[0], datetime(2011, 2, 2, 0, 45))
 def test_named_repeated_type(self):
     # test a name may be repeated with type conversion
     r = parse.parse('{n:d} {n:d}', '1 1')
     self.assertEqual(r.named, {'n': 1})
 def test_nothing(self):
     # do no actual parsing
     r = parse.parse('{{hello}}', '{hello}')
     self.assertEqual(r.fixed, ())
     self.assertEqual(r.named, {})
 def test_no_match(self):
     # string does not match format
     self.assertEqual(parse.parse('{{hello}}', 'hello'), None)