Skip to content

Commit 87a04f9

Browse files
committed
Merging 'master' into 'wrap'
2 parents ce1c73e + 56bede0 commit 87a04f9

39 files changed

+820
-376
lines changed

wrap/.github/workflows/linux-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
fail-fast: false
1212
matrix:
13-
python-version: [3.6, 3.7, 3.8, 3.9]
13+
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
1414

1515
steps:
1616
- name: Checkout

wrap/.github/workflows/macos-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
fail-fast: false
1212
matrix:
13-
python-version: [3.6, 3.7, 3.8, 3.9]
13+
python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
1414

1515
steps:
1616
- name: Checkout

wrap/DOCS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ The python wrapper supports keyword arguments for functions/methods. Hence, the
100100
```
101101

102102
- Using classes defined in other modules
103-
- If you are using a class `OtherClass` not wrapped in an interface file, add `class OtherClass;` as a forward declaration to avoid a dependency error. `OtherClass` should be in the same project.
103+
- If you are using a class `OtherClass` not wrapped in an interface file, add `class OtherClass;` as a forward declaration to avoid a dependency error.
104+
- `OtherClass` may not be in the same project. If this is the case, include the header for the appropriate project `#include <other_project/OtherClass.h>`.
104105

105106
- Virtual inheritance
106107
- Specify fully-qualified base classes, i.e. `virtual class Derived : ns::Base {` where `ns` is the namespace.

wrap/gtwrap/interface_parser/classes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def __init__(self,
189189

190190
# Check to ensure arg and return type are the same.
191191
if len(args) == 1 and self.operator not in ("()", "[]"):
192-
assert args.args_list[0].ctype.typename.name == return_type.type1.typename.name, \
192+
assert args.list()[0].ctype.typename.name == return_type.type1.typename.name, \
193193
"Mixed type overloading not supported. Both arg and return type must be the same."
194194

195195
def __repr__(self) -> str:

wrap/gtwrap/interface_parser/declaration.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from .tokens import (CLASS, COLON, INCLUDE, LOPBRACK, ROPBRACK, SEMI_COLON,
1616
VIRTUAL)
1717
from .type import Typename
18+
from .utils import collect_namespaces
1819

1920

2021
class Include:
@@ -42,11 +43,12 @@ class ForwardDeclaration:
4243
t.name, t.parent_type, t.is_virtual))
4344

4445
def __init__(self,
45-
name: Typename,
46+
typename: Typename,
4647
parent_type: str,
4748
is_virtual: str,
4849
parent: str = ''):
49-
self.name = name
50+
self.name = typename.name
51+
self.typename = typename
5052
if parent_type:
5153
self.parent_type = parent_type
5254
else:
@@ -55,6 +57,9 @@ def __init__(self,
5557
self.is_virtual = is_virtual
5658
self.parent = parent
5759

60+
def namespaces(self) -> list:
61+
"""Get the namespaces which this class is nested under as a list."""
62+
return collect_namespaces(self)
63+
5864
def __repr__(self) -> str:
59-
return "ForwardDeclaration: {} {}({})".format(self.is_virtual,
60-
self.name, self.parent)
65+
return "ForwardDeclaration: {} {}".format(self.is_virtual, self.name)

wrap/gtwrap/interface_parser/function.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ class Argument:
2929
void sayHello(/*`s` is the method argument with type `const string&`*/ const string& s);
3030
```
3131
"""
32-
rule = ((Type.rule ^ TemplatedType.rule)("ctype") + IDENT("name") + \
33-
Optional(EQUAL + (DEFAULT_ARG ^ Type.rule ^ TemplatedType.rule) + \
34-
Optional(LPAREN + RPAREN) # Needed to parse the parens for default constructors
35-
)("default")
36-
).setParseAction(lambda t: Argument(t.ctype, t.name, t.default))
32+
rule = ((Type.rule ^ TemplatedType.rule)("ctype") #
33+
+ IDENT("name") #
34+
+ Optional(EQUAL + DEFAULT_ARG)("default")
35+
).setParseAction(lambda t: Argument(
36+
t.ctype, #
37+
t.name, #
38+
t.default[0] if isinstance(t.default, ParseResults) else None))
3739

3840
def __init__(self,
3941
ctype: Union[Type, TemplatedType],
@@ -44,18 +46,8 @@ def __init__(self,
4446
else:
4547
self.ctype = ctype
4648
self.name = name
47-
# If the length is 1, it's a regular type,
48-
if len(default) == 1:
49-
default = default[0]
50-
# This means a tuple has been passed so we convert accordingly
51-
elif len(default) > 1:
52-
default = tuple(default.asList())
53-
else:
54-
# set to None explicitly so we can support empty strings
55-
default = None
5649
self.default = default
57-
58-
self.parent: Union[ArgumentList, None] = None
50+
self.parent = None # type: Union[ArgumentList, None]
5951

6052
def __repr__(self) -> str:
6153
return self.to_cpp()
@@ -94,10 +86,14 @@ def __repr__(self) -> str:
9486
def __len__(self) -> int:
9587
return len(self.args_list)
9688

97-
def args_names(self) -> List[str]:
89+
def names(self) -> List[str]:
9890
"""Return a list of the names of all the arguments."""
9991
return [arg.name for arg in self.args_list]
10092

93+
def list(self) -> List[Argument]:
94+
"""Return a list of the names of all the arguments."""
95+
return self.args_list
96+
10197
def to_cpp(self, use_boost: bool) -> List[str]:
10298
"""Generate the C++ code for wrapping."""
10399
return [arg.ctype.to_cpp(use_boost) for arg in self.args_list]

wrap/gtwrap/interface_parser/namespace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def find_class_or_function(
102102
res = []
103103
for namespace in found_namespaces:
104104
classes_and_funcs = (c for c in namespace.content
105-
if isinstance(c, (Class, GlobalFunction)))
105+
if isinstance(c, (Class, GlobalFunction, ForwardDeclaration)))
106106
res += [c for c in classes_and_funcs if c.name == typename.name]
107107
if not res:
108108
raise ValueError("Cannot find class {} in module!".format(

wrap/gtwrap/interface_parser/tokens.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert
1111
"""
1212

13-
from pyparsing import (Keyword, Literal, Or, QuotedString, Suppress, Word,
14-
alphanums, alphas, delimitedList, nums,
15-
pyparsing_common)
13+
from pyparsing import (Keyword, Literal, OneOrMore, Or, QuotedString, Suppress,
14+
Word, alphanums, alphas, nestedExpr, nums,
15+
originalTextFor, printables)
1616

1717
# rule for identifiers (e.g. variable names)
1818
IDENT = Word(alphas + '_', alphanums + '_') ^ Word(nums)
@@ -22,16 +22,20 @@
2222
LPAREN, RPAREN, LBRACE, RBRACE, COLON, SEMI_COLON = map(Suppress, "(){}:;")
2323
LOPBRACK, ROPBRACK, COMMA, EQUAL = map(Suppress, "<>,=")
2424

25-
# Encapsulating type for numbers, and single and double quoted strings.
26-
# The pyparsing_common utilities ensure correct coversion to the corresponding type.
27-
# E.g. pyparsing_common.number will convert 3.1415 to a float type.
28-
NUMBER_OR_STRING = (pyparsing_common.number ^ QuotedString('"') ^ QuotedString("'"))
29-
30-
# A python tuple, e.g. (1, 9, "random", 3.1415)
31-
TUPLE = (LPAREN + delimitedList(NUMBER_OR_STRING) + RPAREN)
32-
3325
# Default argument passed to functions/methods.
34-
DEFAULT_ARG = (NUMBER_OR_STRING ^ pyparsing_common.identifier ^ TUPLE)
26+
# Allow anything up to ',' or ';' except when they
27+
# appear inside matched expressions such as
28+
# (a, b) {c, b} "hello, world", templates, initializer lists, etc.
29+
DEFAULT_ARG = originalTextFor(
30+
OneOrMore(
31+
QuotedString('"') ^ # parse double quoted strings
32+
QuotedString("'") ^ # parse single quoted strings
33+
Word(printables, excludeChars="(){}[]<>,;") ^ # parse arbitrary words
34+
nestedExpr(opener='(', closer=')') ^ # parse expression in parentheses
35+
nestedExpr(opener='[', closer=']') ^ # parse expression in brackets
36+
nestedExpr(opener='{', closer='}') ^ # parse expression in braces
37+
nestedExpr(opener='<', closer='>') # parse template expressions
38+
))
3539

3640
CONST, VIRTUAL, CLASS, STATIC, PAIR, TEMPLATE, TYPEDEF, INCLUDE = map(
3741
Keyword,

wrap/gtwrap/interface_parser/variable.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from pyparsing import Optional, ParseResults
1414

15-
from .tokens import DEFAULT_ARG, EQUAL, IDENT, SEMI_COLON, STATIC
15+
from .tokens import DEFAULT_ARG, EQUAL, IDENT, SEMI_COLON
1616
from .type import TemplatedType, Type
1717

1818

@@ -32,10 +32,12 @@ class Hello {
3232
"""
3333
rule = ((Type.rule ^ TemplatedType.rule)("ctype") #
3434
+ IDENT("name") #
35-
#TODO(Varun) Add support for non-basic types
36-
+ Optional(EQUAL + (DEFAULT_ARG))("default") #
35+
+ Optional(EQUAL + DEFAULT_ARG)("default") #
3736
+ SEMI_COLON #
38-
).setParseAction(lambda t: Variable(t.ctype, t.name, t.default))
37+
).setParseAction(lambda t: Variable(
38+
t.ctype, #
39+
t.name, #
40+
t.default[0] if isinstance(t.default, ParseResults) else None))
3941

4042
def __init__(self,
4143
ctype: Type,
@@ -44,11 +46,7 @@ def __init__(self,
4446
parent=''):
4547
self.ctype = ctype[0] # ParseResult is a list
4648
self.name = name
47-
if default:
48-
self.default = default[0]
49-
else:
50-
self.default = None
51-
49+
self.default = default
5250
self.parent = parent
5351

5452
def __repr__(self) -> str:

0 commit comments

Comments
 (0)