# everything until the colon and discard the rest. It can however be a
# part of a rogue C++ type name, so pick the < only if directly at the
# start or after a space or bracket, and the > only if at the end
- # again.
- if c == '<' and (i == 0 or string[i - 1] in [' ', '(', '[']):
- name_end = string.find(':', i)
- if name_end == -1:
- raise SyntaxError("Enum expected to have a value: `{}`".format(string))
+ # again. Also ignore stuff like <FooBar object at 0x1234> -- a : has to
+ # be before a >. Ugh maybe I should just use a regex here.
+ if c == '<' and (i == 0 or string[i - 1] in [' ', '(', '[']) and -1 < string.find(':', i + 1) < string.find('>', i + 1):
+ name_end = string.index(':', i + 1)
default += string[i + 1:name_end]
- i = string.find('>', name_end + 1) + 1
+ i = string.index('>', name_end + 1) + 1
- if i == -1 or (i < len(string) and string[i] not in [',', ')', ']']):
+ if i < len(string) and string[i] not in [',', ')', ']']:
raise SyntaxError("Unexpected content after enum value: `{}`".format(string[i:]))
continue
('a', 'Enum', 'Enum', 'Enum_MISSING_DOT')
], None, None))
+ # This is how pybind prints various objects, should be passed as-is.
+ # It should not corrupt any parameters after.
+ self.assertEqual(parse_pybind_signature(self.state, [],
+ 'foo(a: FooBar = <FooBar object at 0xabcd>, b: int = 3)'),
+ ('foo', '', [
+ ('a', 'FooBar', 'FooBar', '<FooBar object at 0xabcd>'),
+ ('b', 'int', 'int', '3')
+ ], None, None))
+
+ # This is weird and so will be passed as-is.
+ self.assertEqual(parse_pybind_signature(self.state, [],
+ 'foo(a: Enum = <Enum_MISSING_GT: -1)'),
+ ('foo', '', [
+ ('a', 'Enum', 'Enum', '<Enum_MISSING_GT: -1')
+ ], None, None))
+
# This will fail
bad_signature = ('foo', '', [('…', None, None, None)], None, None)
- self.assertEqual(parse_pybind_signature(self.state, [], 'foo(a: Enum = <Enum.MISSING_COLON>)'), bad_signature)
- self.assertEqual(parse_pybind_signature(self.state, [], 'foo(a: Enum = <Enum.MISSING_GT)'), bad_signature)
- self.assertEqual(parse_pybind_signature(self.state, [], 'foo(a: Enum = <Enum.CHARACTERS_AFTER>a)'), bad_signature)
- self.assertEqual(parse_pybind_signature(self.state, [], 'foo(a: Enum = <Enum.CHARACTERS_AFTER><)'), bad_signature)
+ self.assertEqual(parse_pybind_signature(self.state, [], 'foo(a: Enum = <Enum.CHARACTERS_AFTER: 17>a)'), bad_signature)
+ self.assertEqual(parse_pybind_signature(self.state, [], 'foo(a: Enum = <Enum.CHARACTERS_AFTER: 89><)'), bad_signature)
def test_bad_return_type(self):
bad_signature = ('foo', '', [('…', None, None, None)], None, None)