cxxheaderparser 1.7.0__tar.gz → 1.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/PKG-INFO +1 -1
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/gentest.py +3 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/parser.py +246 -45
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/parserstate.py +14 -3
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/types.py +60 -1
- cxxheaderparser-1.7.2/cxxheaderparser/version.py +24 -0
- cxxheaderparser-1.7.0/cxxheaderparser/version.py +0 -34
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/.gitignore +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/LICENSE.txt +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/README.md +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/__init__.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/__main__.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/_ply/__init__.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/_ply/lex.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/dump.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/errors.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/lexer.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/options.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/preprocessor.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/py.typed +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/simple.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/tokfmt.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/cxxheaderparser/visitor.py +0 -0
- {cxxheaderparser-1.7.0 → cxxheaderparser-1.7.2}/pyproject.toml +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import dataclasses
|
|
3
|
+
import enum
|
|
3
4
|
import inspect
|
|
4
5
|
import subprocess
|
|
5
6
|
import textwrap
|
|
@@ -44,6 +45,8 @@ def nondefault_repr(data: typing.Any) -> str:
|
|
|
44
45
|
for k, v in o.items():
|
|
45
46
|
vals.append(f'"{k}": {_inner_repr(v)}')
|
|
46
47
|
return "{" + ",".join(vals) + "}"
|
|
48
|
+
elif isinstance(o, enum.Enum):
|
|
49
|
+
return f"{o.__class__.__qualname__}.{o.name}"
|
|
47
50
|
else:
|
|
48
51
|
return repr(o)
|
|
49
52
|
|
|
@@ -19,6 +19,8 @@ from .parserstate import (
|
|
|
19
19
|
from .types import (
|
|
20
20
|
AnonymousName,
|
|
21
21
|
Array,
|
|
22
|
+
Attribute,
|
|
23
|
+
AttributeStyle,
|
|
22
24
|
AutoSpecifier,
|
|
23
25
|
BaseClass,
|
|
24
26
|
ClassDecl,
|
|
@@ -104,6 +106,7 @@ class CxxParser:
|
|
|
104
106
|
None, self.lex.current_location(), global_ns
|
|
105
107
|
)
|
|
106
108
|
self.anon_id = 0
|
|
109
|
+
self._pending_attributes: typing.List[Attribute] = []
|
|
107
110
|
|
|
108
111
|
self.verbose = self.options.verbose
|
|
109
112
|
if self.verbose:
|
|
@@ -907,38 +910,116 @@ class CxxParser:
|
|
|
907
910
|
}
|
|
908
911
|
_attribute_start_tokens |= _attribute_specifier_seq_start_types
|
|
909
912
|
|
|
910
|
-
def
|
|
913
|
+
def _record_attributes(self, attrs: typing.Iterable[Attribute]) -> None:
|
|
914
|
+
self._pending_attributes.extend(attrs)
|
|
915
|
+
|
|
916
|
+
def _take_pending_attributes(self) -> typing.List[Attribute]:
|
|
917
|
+
attrs = self._pending_attributes
|
|
918
|
+
self._pending_attributes = []
|
|
919
|
+
return attrs
|
|
920
|
+
|
|
921
|
+
def _parse_attribute_list_tokens(
|
|
922
|
+
self, kind: AttributeStyle, *init_tokens: LexToken
|
|
923
|
+
) -> typing.List[Attribute]:
|
|
924
|
+
|
|
925
|
+
match_stack = [self._balanced_token_map[tok.type] for tok in init_tokens]
|
|
926
|
+
get_token = self.lex.token
|
|
927
|
+
|
|
928
|
+
attrs = []
|
|
929
|
+
name_tokens: typing.List[LexToken] = []
|
|
930
|
+
|
|
931
|
+
def _commit(value: typing.Optional[Value]) -> None:
|
|
932
|
+
name = "".join(tok.value for tok in name_tokens).strip()
|
|
933
|
+
name_tokens.clear()
|
|
934
|
+
if name:
|
|
935
|
+
attrs.append(Attribute(style=kind, name=name, value=value))
|
|
936
|
+
elif value is not None:
|
|
937
|
+
raise self._parse_error(None, expected="missing attribute name")
|
|
938
|
+
|
|
939
|
+
while True:
|
|
940
|
+
tok = get_token()
|
|
941
|
+
if tok.type in self._end_balanced_tokens:
|
|
942
|
+
expected = match_stack[-1]
|
|
943
|
+
if tok.type != expected:
|
|
944
|
+
raise self._parse_error(tok, expected)
|
|
945
|
+
|
|
946
|
+
if name_tokens:
|
|
947
|
+
_commit(None)
|
|
948
|
+
|
|
949
|
+
if len(match_stack) == 2:
|
|
950
|
+
self._next_token_must_be(match_stack[0])
|
|
951
|
+
|
|
952
|
+
break
|
|
953
|
+
|
|
954
|
+
elif tok.type in self._balanced_token_map:
|
|
955
|
+
_commit(self._create_value(self._consume_balanced_tokens(tok)[1:-1]))
|
|
956
|
+
elif tok.type == ",":
|
|
957
|
+
_commit(None)
|
|
958
|
+
else:
|
|
959
|
+
name_tokens.append(tok)
|
|
960
|
+
|
|
961
|
+
return attrs
|
|
962
|
+
|
|
963
|
+
def _consume_attribute(
|
|
964
|
+
self,
|
|
965
|
+
tok: LexToken,
|
|
966
|
+
doxygen: typing.Optional[str] = None,
|
|
967
|
+
*,
|
|
968
|
+
record: bool = True,
|
|
969
|
+
) -> typing.List[Attribute]:
|
|
911
970
|
if tok.type == "__attribute__":
|
|
912
|
-
self._consume_gcc_attribute(tok)
|
|
971
|
+
attrs = self._consume_gcc_attribute(tok, doxygen, record=record)
|
|
913
972
|
elif tok.type == "__declspec":
|
|
914
|
-
self._consume_declspec(tok)
|
|
973
|
+
attrs = self._consume_declspec(tok, doxygen, record=record)
|
|
915
974
|
elif tok.type in self._attribute_specifier_seq_start_types:
|
|
916
|
-
self._consume_attribute_specifier_seq(tok)
|
|
975
|
+
attrs = self._consume_attribute_specifier_seq(tok, doxygen, record=record)
|
|
917
976
|
else:
|
|
918
977
|
raise CxxParseError("internal error")
|
|
978
|
+
return attrs
|
|
919
979
|
|
|
920
980
|
def _consume_gcc_attribute(
|
|
921
|
-
self,
|
|
922
|
-
|
|
981
|
+
self,
|
|
982
|
+
tok: typing.Optional[LexToken],
|
|
983
|
+
doxygen: typing.Optional[str] = None,
|
|
984
|
+
*,
|
|
985
|
+
record: bool = True,
|
|
986
|
+
) -> typing.List[Attribute]:
|
|
987
|
+
attrs: typing.List[Attribute] = []
|
|
923
988
|
while True:
|
|
924
989
|
tok1 = self._next_token_must_be("(")
|
|
925
990
|
tok2 = self._next_token_must_be("(")
|
|
926
|
-
|
|
991
|
+
attrs.extend(
|
|
992
|
+
self._parse_attribute_list_tokens(AttributeStyle.GCC, tok1, tok2)
|
|
993
|
+
)
|
|
927
994
|
|
|
928
995
|
# Apparently you can have multiple attributes chained together?
|
|
929
996
|
tok = self.lex.token_if("__attribute__")
|
|
930
997
|
if tok is None:
|
|
931
998
|
break
|
|
999
|
+
if record:
|
|
1000
|
+
self._record_attributes(attrs)
|
|
1001
|
+
return attrs
|
|
932
1002
|
|
|
933
1003
|
def _consume_declspec(
|
|
934
|
-
self,
|
|
935
|
-
|
|
1004
|
+
self,
|
|
1005
|
+
tok: LexToken,
|
|
1006
|
+
doxygen: typing.Optional[str] = None,
|
|
1007
|
+
*,
|
|
1008
|
+
record: bool = True,
|
|
1009
|
+
) -> typing.List[Attribute]:
|
|
936
1010
|
tok = self._next_token_must_be("(")
|
|
937
|
-
self.
|
|
1011
|
+
attrs = self._parse_attribute_list_tokens(AttributeStyle.MSVC, tok)
|
|
1012
|
+
if record:
|
|
1013
|
+
self._record_attributes(attrs)
|
|
1014
|
+
return attrs
|
|
938
1015
|
|
|
939
1016
|
def _consume_attribute_specifier_seq(
|
|
940
|
-
self,
|
|
941
|
-
|
|
1017
|
+
self,
|
|
1018
|
+
tok: LexToken,
|
|
1019
|
+
doxygen: typing.Optional[str] = None,
|
|
1020
|
+
*,
|
|
1021
|
+
record: bool = True,
|
|
1022
|
+
) -> typing.List[Attribute]:
|
|
942
1023
|
"""
|
|
943
1024
|
attribute_specifier_seq: attribute_specifier
|
|
944
1025
|
| attribute_specifier_seq attribute_specifier
|
|
@@ -974,17 +1055,20 @@ class CxxParser:
|
|
|
974
1055
|
| token
|
|
975
1056
|
"""
|
|
976
1057
|
|
|
977
|
-
|
|
978
|
-
# attrs = []
|
|
979
|
-
|
|
1058
|
+
attrs: typing.List[Attribute] = []
|
|
980
1059
|
while True:
|
|
981
1060
|
if tok.type == "DBL_LBRACKET":
|
|
982
|
-
|
|
983
|
-
# attrs.append(Attribute(tokens))
|
|
1061
|
+
attrs.extend(self._parse_attribute_list_tokens(AttributeStyle.CXX, tok))
|
|
984
1062
|
elif tok.type == "alignas":
|
|
985
1063
|
next_tok = self._next_token_must_be("(")
|
|
986
1064
|
tokens = self._consume_balanced_tokens(next_tok)
|
|
987
|
-
|
|
1065
|
+
attrs.append(
|
|
1066
|
+
Attribute(
|
|
1067
|
+
style=AttributeStyle.CXX,
|
|
1068
|
+
name="alignas",
|
|
1069
|
+
value=self._create_value(tokens[1:-1]),
|
|
1070
|
+
)
|
|
1071
|
+
)
|
|
988
1072
|
else:
|
|
989
1073
|
self.lex.return_token(tok)
|
|
990
1074
|
break
|
|
@@ -996,7 +1080,18 @@ class CxxParser:
|
|
|
996
1080
|
|
|
997
1081
|
tok = maybe_tok
|
|
998
1082
|
|
|
999
|
-
|
|
1083
|
+
if record:
|
|
1084
|
+
self._record_attributes(attrs)
|
|
1085
|
+
return attrs
|
|
1086
|
+
|
|
1087
|
+
def _consume_decl_attributes(self) -> typing.List[Attribute]:
|
|
1088
|
+
attrs: typing.List[Attribute] = []
|
|
1089
|
+
while True:
|
|
1090
|
+
tok = self.lex.token_if_in_set(self._attribute_start_tokens)
|
|
1091
|
+
if not tok:
|
|
1092
|
+
break
|
|
1093
|
+
attrs.extend(self._consume_attribute(tok, record=False))
|
|
1094
|
+
return attrs
|
|
1000
1095
|
|
|
1001
1096
|
#
|
|
1002
1097
|
# Using directive/declaration/typealias
|
|
@@ -1109,6 +1204,7 @@ class CxxParser:
|
|
|
1109
1204
|
is_typedef: bool,
|
|
1110
1205
|
location: Location,
|
|
1111
1206
|
mods: ParsedTypeModifiers,
|
|
1207
|
+
attributes: typing.List[Attribute],
|
|
1112
1208
|
) -> None:
|
|
1113
1209
|
"""
|
|
1114
1210
|
opaque_enum_declaration: enum_key [attribute_specifier_seq] IDENTIFIER [enum_base] ";"
|
|
@@ -1148,18 +1244,29 @@ class CxxParser:
|
|
|
1148
1244
|
|
|
1149
1245
|
# enum forward declaration with base
|
|
1150
1246
|
fdecl = ForwardDecl(
|
|
1151
|
-
typename,
|
|
1247
|
+
typename,
|
|
1248
|
+
None,
|
|
1249
|
+
doxygen,
|
|
1250
|
+
attributes=attributes,
|
|
1251
|
+
enum_base=base,
|
|
1252
|
+
access=self._current_access,
|
|
1152
1253
|
)
|
|
1153
1254
|
self.visitor.on_forward_decl(self.state, fdecl)
|
|
1154
1255
|
return
|
|
1155
1256
|
|
|
1156
1257
|
values = self._parse_enumerator_list()
|
|
1157
1258
|
|
|
1158
|
-
enum = EnumDecl(
|
|
1259
|
+
enum = EnumDecl(
|
|
1260
|
+
typename, values, base, doxygen, attributes, self._current_access
|
|
1261
|
+
)
|
|
1159
1262
|
self.visitor.on_enum(self.state, enum)
|
|
1160
1263
|
|
|
1161
1264
|
# Finish it up
|
|
1162
|
-
self._finish_class_or_enum(
|
|
1265
|
+
attrs_after = self._finish_class_or_enum(
|
|
1266
|
+
enum.typename, is_typedef, mods, "enum"
|
|
1267
|
+
)
|
|
1268
|
+
if attrs_after:
|
|
1269
|
+
enum.attributes.extend(attrs_after)
|
|
1163
1270
|
|
|
1164
1271
|
def _parse_enumerator_list(self) -> typing.List[Enumerator]:
|
|
1165
1272
|
"""
|
|
@@ -1186,17 +1293,18 @@ class CxxParser:
|
|
|
1186
1293
|
|
|
1187
1294
|
name = name_tok.value
|
|
1188
1295
|
value = None
|
|
1296
|
+
attributes = []
|
|
1189
1297
|
|
|
1190
1298
|
tok = self._next_token_must_be("}", ",", "=", "DBL_LBRACKET")
|
|
1191
1299
|
if tok.type == "DBL_LBRACKET":
|
|
1192
|
-
self._consume_attribute_specifier_seq(tok)
|
|
1300
|
+
attributes = self._consume_attribute_specifier_seq(tok, record=False)
|
|
1193
1301
|
tok = self._next_token_must_be("}", ",", "=")
|
|
1194
1302
|
|
|
1195
1303
|
if tok.type == "=":
|
|
1196
1304
|
value = self._create_value(self._consume_value_until([], ",", "}"))
|
|
1197
1305
|
tok = self._next_token_must_be("}", ",")
|
|
1198
1306
|
|
|
1199
|
-
values.append(Enumerator(name, value, doxygen))
|
|
1307
|
+
values.append(Enumerator(name, value, doxygen, attributes))
|
|
1200
1308
|
|
|
1201
1309
|
if tok.type == "}":
|
|
1202
1310
|
break
|
|
@@ -1235,8 +1343,9 @@ class CxxParser:
|
|
|
1235
1343
|
tok_type = tok.type
|
|
1236
1344
|
|
|
1237
1345
|
# might start with attributes
|
|
1346
|
+
attributes = []
|
|
1238
1347
|
if tok.type in self._attribute_specifier_seq_start_types:
|
|
1239
|
-
self._consume_attribute_specifier_seq(tok)
|
|
1348
|
+
attributes = self._consume_attribute_specifier_seq(tok, record=False)
|
|
1240
1349
|
tok = self.lex.token()
|
|
1241
1350
|
tok_type = tok.type
|
|
1242
1351
|
|
|
@@ -1261,7 +1370,9 @@ class CxxParser:
|
|
|
1261
1370
|
if self.lex.token_if("ELLIPSIS"):
|
|
1262
1371
|
parameter_pack = True
|
|
1263
1372
|
|
|
1264
|
-
bases.append(
|
|
1373
|
+
bases.append(
|
|
1374
|
+
BaseClass(access, typename, virtual, parameter_pack, attributes)
|
|
1375
|
+
)
|
|
1265
1376
|
|
|
1266
1377
|
if not self.lex.token_if(","):
|
|
1267
1378
|
break
|
|
@@ -1277,6 +1388,7 @@ class CxxParser:
|
|
|
1277
1388
|
typedef: bool,
|
|
1278
1389
|
location: Location,
|
|
1279
1390
|
mods: ParsedTypeModifiers,
|
|
1391
|
+
attributes: typing.List[Attribute],
|
|
1280
1392
|
) -> None:
|
|
1281
1393
|
"""
|
|
1282
1394
|
class_specifier: class_head "{" [member_specification] "}"
|
|
@@ -1329,7 +1441,14 @@ class CxxParser:
|
|
|
1329
1441
|
raise self._parse_error(tok, "{")
|
|
1330
1442
|
|
|
1331
1443
|
clsdecl = ClassDecl(
|
|
1332
|
-
typename,
|
|
1444
|
+
typename,
|
|
1445
|
+
bases,
|
|
1446
|
+
template,
|
|
1447
|
+
explicit,
|
|
1448
|
+
final,
|
|
1449
|
+
doxygen,
|
|
1450
|
+
attributes,
|
|
1451
|
+
self._current_access,
|
|
1333
1452
|
)
|
|
1334
1453
|
state: ClassBlockState = ClassBlockState(
|
|
1335
1454
|
self.state, location, clsdecl, default_access, typedef, mods
|
|
@@ -1340,12 +1459,14 @@ class CxxParser:
|
|
|
1340
1459
|
self.visitor = null_visitor
|
|
1341
1460
|
|
|
1342
1461
|
def _finish_class_decl(self, state: ClassBlockState) -> None:
|
|
1343
|
-
self._finish_class_or_enum(
|
|
1462
|
+
attrs_after = self._finish_class_or_enum(
|
|
1344
1463
|
state.class_decl.typename,
|
|
1345
1464
|
state.typedef,
|
|
1346
1465
|
state.mods,
|
|
1347
1466
|
state.class_decl.classkey,
|
|
1348
1467
|
)
|
|
1468
|
+
if attrs_after:
|
|
1469
|
+
state.class_decl.attributes.extend(attrs_after)
|
|
1349
1470
|
|
|
1350
1471
|
def _process_access_specifier(
|
|
1351
1472
|
self, tok: LexToken, doxygen: typing.Optional[str]
|
|
@@ -1433,6 +1554,7 @@ class CxxParser:
|
|
|
1433
1554
|
doxygen: typing.Optional[str],
|
|
1434
1555
|
location: Location,
|
|
1435
1556
|
is_typedef: bool,
|
|
1557
|
+
attributes: typing.List[Attribute],
|
|
1436
1558
|
) -> None:
|
|
1437
1559
|
state = self.state
|
|
1438
1560
|
state.location = location
|
|
@@ -1498,7 +1620,7 @@ class CxxParser:
|
|
|
1498
1620
|
if is_typedef:
|
|
1499
1621
|
if not name:
|
|
1500
1622
|
raise self._parse_error(None)
|
|
1501
|
-
typedef = Typedef(dtype, name, self._current_access)
|
|
1623
|
+
typedef = Typedef(dtype, name, self._current_access, attributes)
|
|
1502
1624
|
self.visitor.on_typedef(state, typedef)
|
|
1503
1625
|
else:
|
|
1504
1626
|
props = dict.fromkeys(mods.both.keys(), True)
|
|
@@ -1515,13 +1637,20 @@ class CxxParser:
|
|
|
1515
1637
|
value=default,
|
|
1516
1638
|
bits=bits,
|
|
1517
1639
|
doxygen=doxygen,
|
|
1640
|
+
attributes=attributes,
|
|
1518
1641
|
**props,
|
|
1519
1642
|
)
|
|
1520
1643
|
self.visitor.on_class_field(class_state, f)
|
|
1521
1644
|
else:
|
|
1522
1645
|
assert pqname is not None
|
|
1523
1646
|
v = Variable(
|
|
1524
|
-
pqname,
|
|
1647
|
+
pqname,
|
|
1648
|
+
dtype,
|
|
1649
|
+
default,
|
|
1650
|
+
doxygen=doxygen,
|
|
1651
|
+
template=template,
|
|
1652
|
+
attributes=attributes,
|
|
1653
|
+
**props,
|
|
1525
1654
|
)
|
|
1526
1655
|
self.visitor.on_variable(state, v)
|
|
1527
1656
|
|
|
@@ -2000,6 +2129,10 @@ class CxxParser:
|
|
|
2000
2129
|
fn.has_trailing_return = True
|
|
2001
2130
|
fn.return_type = return_type
|
|
2002
2131
|
|
|
2132
|
+
extra_attrs = self._consume_decl_attributes()
|
|
2133
|
+
if extra_attrs:
|
|
2134
|
+
fn.attributes.extend(extra_attrs)
|
|
2135
|
+
|
|
2003
2136
|
if self.lex.token_if("{"):
|
|
2004
2137
|
self._discard_contents("{", "}")
|
|
2005
2138
|
fn.has_body = True
|
|
@@ -2073,6 +2206,11 @@ class CxxParser:
|
|
|
2073
2206
|
self.lex.return_token(tok)
|
|
2074
2207
|
break
|
|
2075
2208
|
|
|
2209
|
+
if not method.has_body:
|
|
2210
|
+
extra_attrs = self._consume_decl_attributes()
|
|
2211
|
+
if extra_attrs:
|
|
2212
|
+
method.attributes.extend(extra_attrs)
|
|
2213
|
+
|
|
2076
2214
|
def _parse_function(
|
|
2077
2215
|
self,
|
|
2078
2216
|
mods: ParsedTypeModifiers,
|
|
@@ -2088,6 +2226,7 @@ class CxxParser:
|
|
|
2088
2226
|
is_typedef: bool,
|
|
2089
2227
|
msvc_convention: typing.Optional[LexToken],
|
|
2090
2228
|
is_guide: bool = False,
|
|
2229
|
+
attributes: typing.Optional[typing.List[Attribute]] = None,
|
|
2091
2230
|
) -> bool:
|
|
2092
2231
|
"""
|
|
2093
2232
|
Assumes the caller has already consumed the return type and name, this consumes the
|
|
@@ -2129,6 +2268,11 @@ class CxxParser:
|
|
|
2129
2268
|
|
|
2130
2269
|
if (is_class_block or multiple_name_segments) and not is_typedef:
|
|
2131
2270
|
props.update(dict.fromkeys(mods.meths.keys(), True))
|
|
2271
|
+
if mods.explicit_value is not None:
|
|
2272
|
+
props["explicit"] = mods.explicit_value
|
|
2273
|
+
|
|
2274
|
+
if attributes is None:
|
|
2275
|
+
attributes = []
|
|
2132
2276
|
|
|
2133
2277
|
method = Method(
|
|
2134
2278
|
return_type,
|
|
@@ -2136,6 +2280,7 @@ class CxxParser:
|
|
|
2136
2280
|
params,
|
|
2137
2281
|
vararg,
|
|
2138
2282
|
doxygen=doxygen,
|
|
2283
|
+
attributes=attributes,
|
|
2139
2284
|
constructor=constructor,
|
|
2140
2285
|
destructor=destructor,
|
|
2141
2286
|
template=template,
|
|
@@ -2183,12 +2328,15 @@ class CxxParser:
|
|
|
2183
2328
|
return False
|
|
2184
2329
|
else:
|
|
2185
2330
|
assert return_type is not None
|
|
2331
|
+
if attributes is None:
|
|
2332
|
+
attributes = []
|
|
2186
2333
|
fn = Function(
|
|
2187
2334
|
return_type,
|
|
2188
2335
|
pqname,
|
|
2189
2336
|
params,
|
|
2190
2337
|
vararg,
|
|
2191
2338
|
doxygen=doxygen,
|
|
2339
|
+
attributes=attributes,
|
|
2192
2340
|
template=template,
|
|
2193
2341
|
operator=op,
|
|
2194
2342
|
**props,
|
|
@@ -2230,7 +2378,7 @@ class CxxParser:
|
|
|
2230
2378
|
msvc_convention=fn.msvc_convention,
|
|
2231
2379
|
)
|
|
2232
2380
|
|
|
2233
|
-
typedef = Typedef(fntype, name, self._current_access)
|
|
2381
|
+
typedef = Typedef(fntype, name, self._current_access, attributes or [])
|
|
2234
2382
|
self.visitor.on_typedef(state, typedef)
|
|
2235
2383
|
return False
|
|
2236
2384
|
else:
|
|
@@ -2416,6 +2564,7 @@ class CxxParser:
|
|
|
2416
2564
|
vars: typing.Dict[str, LexToken] = {} # only found on variables
|
|
2417
2565
|
both: typing.Dict[str, LexToken] = {} # found on either
|
|
2418
2566
|
meths: typing.Dict[str, LexToken] = {} # only found on methods
|
|
2567
|
+
explicit_value: typing.Optional[Value] = None
|
|
2419
2568
|
|
|
2420
2569
|
get_token = self.lex.token
|
|
2421
2570
|
|
|
@@ -2424,6 +2573,7 @@ class CxxParser:
|
|
|
2424
2573
|
|
|
2425
2574
|
pqname: typing.Optional[PQName] = None
|
|
2426
2575
|
pqname_optional = False
|
|
2576
|
+
friend_tok: typing.Optional[LexToken] = None
|
|
2427
2577
|
|
|
2428
2578
|
_pqname_start_tokens = self._pqname_start_tokens
|
|
2429
2579
|
_attribute_start = self._attribute_start_tokens
|
|
@@ -2448,6 +2598,8 @@ class CxxParser:
|
|
|
2448
2598
|
break
|
|
2449
2599
|
elif tok_type == "const":
|
|
2450
2600
|
const = True
|
|
2601
|
+
elif tok_type == "friend" and pqname is None:
|
|
2602
|
+
friend_tok = tok
|
|
2451
2603
|
elif tok_type in self._type_kwd_both:
|
|
2452
2604
|
if tok_type == "extern":
|
|
2453
2605
|
# TODO: store linkage
|
|
@@ -2455,6 +2607,13 @@ class CxxParser:
|
|
|
2455
2607
|
both[tok_type] = tok
|
|
2456
2608
|
elif tok_type in self._type_kwd_meth:
|
|
2457
2609
|
meths[tok_type] = tok
|
|
2610
|
+
if tok_type == "explicit":
|
|
2611
|
+
# C++20: explicit(<bool-constant-expression>)
|
|
2612
|
+
otok = self.lex.token_if("(")
|
|
2613
|
+
if otok:
|
|
2614
|
+
explicit_value = self._create_value(
|
|
2615
|
+
self._consume_balanced_tokens(otok)[1:-1]
|
|
2616
|
+
)
|
|
2458
2617
|
elif tok_type == "mutable":
|
|
2459
2618
|
vars["mutable"] = tok
|
|
2460
2619
|
elif tok_type == "volatile":
|
|
@@ -2479,7 +2638,7 @@ class CxxParser:
|
|
|
2479
2638
|
self.lex.return_token(tok)
|
|
2480
2639
|
|
|
2481
2640
|
# Always return the modifiers
|
|
2482
|
-
mods = ParsedTypeModifiers(vars, both, meths)
|
|
2641
|
+
mods = ParsedTypeModifiers(vars, both, meths, explicit_value, friend_tok)
|
|
2483
2642
|
return parsed_type, mods
|
|
2484
2643
|
|
|
2485
2644
|
def _parse_decl(
|
|
@@ -2491,6 +2650,7 @@ class CxxParser:
|
|
|
2491
2650
|
template: TemplateDeclTypeVar,
|
|
2492
2651
|
is_typedef: bool,
|
|
2493
2652
|
is_friend: bool,
|
|
2653
|
+
attributes: typing.List[Attribute],
|
|
2494
2654
|
) -> bool:
|
|
2495
2655
|
toks = []
|
|
2496
2656
|
|
|
@@ -2596,6 +2756,7 @@ class CxxParser:
|
|
|
2596
2756
|
is_typedef,
|
|
2597
2757
|
msvc_convention,
|
|
2598
2758
|
is_guide,
|
|
2759
|
+
attributes,
|
|
2599
2760
|
)
|
|
2600
2761
|
elif msvc_convention:
|
|
2601
2762
|
raise self._parse_error(msvc_convention)
|
|
@@ -2612,6 +2773,7 @@ class CxxParser:
|
|
|
2612
2773
|
parsed_type.typename,
|
|
2613
2774
|
template,
|
|
2614
2775
|
doxygen,
|
|
2776
|
+
attributes=attributes,
|
|
2615
2777
|
access=self._current_access,
|
|
2616
2778
|
)
|
|
2617
2779
|
friend = FriendDecl(cls=fwd)
|
|
@@ -2627,7 +2789,9 @@ class CxxParser:
|
|
|
2627
2789
|
if isinstance(template, list):
|
|
2628
2790
|
raise CxxParseError("multiple template declarations on a field")
|
|
2629
2791
|
|
|
2630
|
-
self._parse_field(
|
|
2792
|
+
self._parse_field(
|
|
2793
|
+
mods, dtype, pqname, template, doxygen, location, is_typedef, attributes
|
|
2794
|
+
)
|
|
2631
2795
|
return False
|
|
2632
2796
|
|
|
2633
2797
|
def _parse_operator_conversion(
|
|
@@ -2638,6 +2802,7 @@ class CxxParser:
|
|
|
2638
2802
|
template: TemplateDeclTypeVar,
|
|
2639
2803
|
is_typedef: bool,
|
|
2640
2804
|
is_friend: bool,
|
|
2805
|
+
attributes: typing.List[Attribute],
|
|
2641
2806
|
) -> None:
|
|
2642
2807
|
tok = self._next_token_must_be("operator")
|
|
2643
2808
|
|
|
@@ -2675,6 +2840,8 @@ class CxxParser:
|
|
|
2675
2840
|
is_friend,
|
|
2676
2841
|
False,
|
|
2677
2842
|
None,
|
|
2843
|
+
False,
|
|
2844
|
+
attributes,
|
|
2678
2845
|
):
|
|
2679
2846
|
# has function body and handled it
|
|
2680
2847
|
return
|
|
@@ -2701,15 +2868,31 @@ class CxxParser:
|
|
|
2701
2868
|
|
|
2702
2869
|
location = tok.location
|
|
2703
2870
|
|
|
2871
|
+
attributes = self._take_pending_attributes()
|
|
2872
|
+
|
|
2704
2873
|
# Almost always starts out with some kind of type name or a modifier
|
|
2705
2874
|
parsed_type, mods = self._parse_type(tok, operator_ok=True)
|
|
2875
|
+
attributes.extend(self._take_pending_attributes())
|
|
2876
|
+
|
|
2877
|
+
if mods.friend is not None:
|
|
2878
|
+
if is_friend or is_typedef or not isinstance(self.state, ClassBlockState):
|
|
2879
|
+
raise self._parse_error(mods.friend)
|
|
2880
|
+
is_friend = True
|
|
2881
|
+
mods = mods._replace(friend=None)
|
|
2706
2882
|
|
|
2707
2883
|
# Check to see if this might be a class/enum declaration
|
|
2708
2884
|
if (
|
|
2709
2885
|
parsed_type is not None
|
|
2710
2886
|
and parsed_type.typename.classkey
|
|
2711
2887
|
and self._maybe_parse_class_enum_decl(
|
|
2712
|
-
parsed_type,
|
|
2888
|
+
parsed_type,
|
|
2889
|
+
mods,
|
|
2890
|
+
doxygen,
|
|
2891
|
+
template,
|
|
2892
|
+
is_typedef,
|
|
2893
|
+
is_friend,
|
|
2894
|
+
location,
|
|
2895
|
+
attributes,
|
|
2713
2896
|
)
|
|
2714
2897
|
):
|
|
2715
2898
|
return
|
|
@@ -2742,14 +2925,21 @@ class CxxParser:
|
|
|
2742
2925
|
if parsed_type is None:
|
|
2743
2926
|
# this means an operator was encountered, deal with the special case
|
|
2744
2927
|
self._parse_operator_conversion(
|
|
2745
|
-
mods, location, doxygen, template, is_typedef, is_friend
|
|
2928
|
+
mods, location, doxygen, template, is_typedef, is_friend, attributes
|
|
2746
2929
|
)
|
|
2747
2930
|
return
|
|
2748
2931
|
|
|
2749
2932
|
# Ok, dealing with a variable or function/method
|
|
2750
2933
|
while True:
|
|
2751
2934
|
if self._parse_decl(
|
|
2752
|
-
parsed_type,
|
|
2935
|
+
parsed_type,
|
|
2936
|
+
mods,
|
|
2937
|
+
location,
|
|
2938
|
+
doxygen,
|
|
2939
|
+
template,
|
|
2940
|
+
is_typedef,
|
|
2941
|
+
is_friend,
|
|
2942
|
+
attributes,
|
|
2753
2943
|
):
|
|
2754
2944
|
# if it returns True then it handled the end of the statement
|
|
2755
2945
|
break
|
|
@@ -2777,6 +2967,7 @@ class CxxParser:
|
|
|
2777
2967
|
is_typedef: bool,
|
|
2778
2968
|
is_friend: bool,
|
|
2779
2969
|
location: Location,
|
|
2970
|
+
attributes: typing.List[Attribute],
|
|
2780
2971
|
) -> bool:
|
|
2781
2972
|
# check for forward declaration or friend declaration
|
|
2782
2973
|
if self.lex.token_if(";"):
|
|
@@ -2801,7 +2992,11 @@ class CxxParser:
|
|
|
2801
2992
|
raise self._parse_error(None)
|
|
2802
2993
|
|
|
2803
2994
|
fdecl = ForwardDecl(
|
|
2804
|
-
parsed_type.typename,
|
|
2995
|
+
parsed_type.typename,
|
|
2996
|
+
template,
|
|
2997
|
+
doxygen,
|
|
2998
|
+
attributes=attributes,
|
|
2999
|
+
access=self._current_access,
|
|
2805
3000
|
)
|
|
2806
3001
|
state = self.state
|
|
2807
3002
|
state.location = location
|
|
@@ -2830,14 +3025,21 @@ class CxxParser:
|
|
|
2830
3025
|
|
|
2831
3026
|
if typename.classkey in ("class", "struct", "union"):
|
|
2832
3027
|
self._parse_class_decl(
|
|
2833
|
-
typename,
|
|
3028
|
+
typename,
|
|
3029
|
+
tok,
|
|
3030
|
+
doxygen,
|
|
3031
|
+
template,
|
|
3032
|
+
is_typedef,
|
|
3033
|
+
location,
|
|
3034
|
+
mods,
|
|
3035
|
+
attributes,
|
|
2834
3036
|
)
|
|
2835
3037
|
else:
|
|
2836
3038
|
if template:
|
|
2837
3039
|
# enum cannot have a template
|
|
2838
3040
|
raise self._parse_error(tok)
|
|
2839
3041
|
self._parse_enum_decl(
|
|
2840
|
-
typename, tok, doxygen, is_typedef, location, mods
|
|
3042
|
+
typename, tok, doxygen, is_typedef, location, mods, attributes
|
|
2841
3043
|
)
|
|
2842
3044
|
|
|
2843
3045
|
return True
|
|
@@ -2851,12 +3053,10 @@ class CxxParser:
|
|
|
2851
3053
|
is_typedef: bool,
|
|
2852
3054
|
mods: ParsedTypeModifiers,
|
|
2853
3055
|
classkey: typing.Optional[str],
|
|
2854
|
-
) ->
|
|
3056
|
+
) -> typing.Optional[typing.List[Attribute]]:
|
|
2855
3057
|
parsed_type = Type(name)
|
|
2856
3058
|
|
|
2857
|
-
|
|
2858
|
-
if tok:
|
|
2859
|
-
self._consume_gcc_attribute(tok)
|
|
3059
|
+
attrs_after = self._consume_decl_attributes()
|
|
2860
3060
|
|
|
2861
3061
|
if not is_typedef and self.lex.token_if(";"):
|
|
2862
3062
|
# if parent scope is a class, add the anonymous
|
|
@@ -2876,12 +3076,12 @@ class CxxParser:
|
|
|
2876
3076
|
access=access,
|
|
2877
3077
|
)
|
|
2878
3078
|
self.visitor.on_class_field(class_state, f)
|
|
2879
|
-
return
|
|
3079
|
+
return attrs_after
|
|
2880
3080
|
|
|
2881
3081
|
while True:
|
|
2882
3082
|
location = self.lex.current_location()
|
|
2883
3083
|
if self._parse_decl(
|
|
2884
|
-
parsed_type, mods, location, None, None, is_typedef, False
|
|
3084
|
+
parsed_type, mods, location, None, None, is_typedef, False, attrs_after
|
|
2885
3085
|
):
|
|
2886
3086
|
# if it returns True then it handled the end of the statement
|
|
2887
3087
|
break
|
|
@@ -2890,3 +3090,4 @@ class CxxParser:
|
|
|
2890
3090
|
tok = self._next_token_must_be(",", ";")
|
|
2891
3091
|
if tok.type == ";":
|
|
2892
3092
|
break
|
|
3093
|
+
return None
|
|
@@ -5,15 +5,23 @@ if typing.TYPE_CHECKING:
|
|
|
5
5
|
|
|
6
6
|
from .errors import CxxParseError
|
|
7
7
|
from .lexer import LexToken, Location
|
|
8
|
-
from .types import ClassDecl, NamespaceDecl
|
|
8
|
+
from .types import ClassDecl, NamespaceDecl, Value
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class ParsedTypeModifiers(typing.NamedTuple):
|
|
12
12
|
vars: typing.Dict[str, LexToken] # only found on variables
|
|
13
13
|
both: typing.Dict[str, LexToken] # found on either variables or functions
|
|
14
14
|
meths: typing.Dict[str, LexToken] # only found on methods
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
#: For C++20 ``explicit(<expr>)``: the constant expression inside the
|
|
16
|
+
#: parens (omitting the parens themselves). ``None`` if absent or if
|
|
17
|
+
#: ``explicit`` was used as a bare keyword.
|
|
18
|
+
explicit_value: typing.Optional[Value] = None
|
|
19
|
+
#: ``friend`` if encountered while parsing declaration specifiers.
|
|
20
|
+
friend: typing.Optional[LexToken] = None
|
|
21
|
+
|
|
22
|
+
def validate(
|
|
23
|
+
self, *, var_ok: bool, meth_ok: bool, msg: str, friend_ok: bool = False
|
|
24
|
+
) -> None:
|
|
17
25
|
# Almost there! Do any checks the caller asked for
|
|
18
26
|
if not var_ok and self.vars:
|
|
19
27
|
for tok in self.vars.values():
|
|
@@ -27,6 +35,9 @@ class ParsedTypeModifiers(typing.NamedTuple):
|
|
|
27
35
|
for tok in self.both.values():
|
|
28
36
|
raise CxxParseError(f"{msg}: unexpected '{tok.value}'")
|
|
29
37
|
|
|
38
|
+
if not friend_ok and self.friend is not None:
|
|
39
|
+
raise CxxParseError(f"{msg}: unexpected '{self.friend.value}'")
|
|
40
|
+
|
|
30
41
|
|
|
31
42
|
#: custom user data for this state type
|
|
32
43
|
T = typing.TypeVar("T")
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import typing
|
|
2
|
+
from enum import Enum
|
|
2
3
|
from dataclasses import dataclass, field
|
|
3
4
|
|
|
4
5
|
from .tokfmt import tokfmt, Token
|
|
@@ -22,6 +23,41 @@ class Value:
|
|
|
22
23
|
return tokfmt(self.tokens)
|
|
23
24
|
|
|
24
25
|
|
|
26
|
+
class AttributeStyle(Enum):
|
|
27
|
+
"""
|
|
28
|
+
Indicates what style of attribute was found
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
#: ``[[deprecated]]``
|
|
32
|
+
CXX = "cxx"
|
|
33
|
+
|
|
34
|
+
#: ``__attribute__((deprecated))``
|
|
35
|
+
GCC = "gcc"
|
|
36
|
+
|
|
37
|
+
#: ``__declspec(deprecated)``
|
|
38
|
+
MSVC = "msvc"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class Attribute:
|
|
43
|
+
"""
|
|
44
|
+
An attribute
|
|
45
|
+
|
|
46
|
+
.. code-block:: c++
|
|
47
|
+
|
|
48
|
+
[[deprecated("message")]]
|
|
49
|
+
~~~~~~~~~ ~~~~~~~~~~~
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
#: Indicates what style of attribute this is
|
|
53
|
+
style: AttributeStyle
|
|
54
|
+
|
|
55
|
+
name: str
|
|
56
|
+
|
|
57
|
+
#: Portion of the attribute inside the parens
|
|
58
|
+
value: typing.Optional[Value] = None
|
|
59
|
+
|
|
60
|
+
|
|
25
61
|
@dataclass
|
|
26
62
|
class NamespaceAlias:
|
|
27
63
|
"""
|
|
@@ -427,6 +463,9 @@ class Enumerator:
|
|
|
427
463
|
#: Documentation if present
|
|
428
464
|
doxygen: typing.Optional[str] = None
|
|
429
465
|
|
|
466
|
+
#: Any attributes attached to this enumerator
|
|
467
|
+
attributes: typing.List[Attribute] = field(default_factory=list)
|
|
468
|
+
|
|
430
469
|
|
|
431
470
|
@dataclass
|
|
432
471
|
class EnumDecl:
|
|
@@ -442,6 +481,8 @@ class EnumDecl:
|
|
|
442
481
|
|
|
443
482
|
#: Documentation if present
|
|
444
483
|
doxygen: typing.Optional[str] = None
|
|
484
|
+
#: Any attributes attached to this enum declaration
|
|
485
|
+
attributes: typing.List[Attribute] = field(default_factory=list)
|
|
445
486
|
|
|
446
487
|
#: If within a class, the access level for this decl
|
|
447
488
|
access: typing.Optional[str] = None
|
|
@@ -610,6 +651,8 @@ class ForwardDecl:
|
|
|
610
651
|
typename: PQName
|
|
611
652
|
template: TemplateDeclTypeVar = None
|
|
612
653
|
doxygen: typing.Optional[str] = None
|
|
654
|
+
#: Any attributes attached to this forward declaration
|
|
655
|
+
attributes: typing.List[Attribute] = field(default_factory=list)
|
|
613
656
|
|
|
614
657
|
#: Set if this is a forward declaration of an enum and it has a base
|
|
615
658
|
enum_base: typing.Optional[PQName] = None
|
|
@@ -635,6 +678,8 @@ class BaseClass:
|
|
|
635
678
|
|
|
636
679
|
#: Contains a ``...``
|
|
637
680
|
param_pack: bool = False
|
|
681
|
+
#: Any attributes attached to this base specifier
|
|
682
|
+
attributes: typing.List[Attribute] = field(default_factory=list)
|
|
638
683
|
|
|
639
684
|
|
|
640
685
|
@dataclass
|
|
@@ -652,6 +697,8 @@ class ClassDecl:
|
|
|
652
697
|
final: bool = False
|
|
653
698
|
|
|
654
699
|
doxygen: typing.Optional[str] = None
|
|
700
|
+
#: Any attributes attached to this class declaration
|
|
701
|
+
attributes: typing.List[Attribute] = field(default_factory=list)
|
|
655
702
|
|
|
656
703
|
#: If within a class, the access level for this decl
|
|
657
704
|
access: typing.Optional[str] = None
|
|
@@ -701,6 +748,8 @@ class Function:
|
|
|
701
748
|
vararg: bool = False
|
|
702
749
|
|
|
703
750
|
doxygen: typing.Optional[str] = None
|
|
751
|
+
#: Any attributes attached to this function declaration
|
|
752
|
+
attributes: typing.List[Attribute] = field(default_factory=list)
|
|
704
753
|
|
|
705
754
|
constexpr: bool = False
|
|
706
755
|
extern: typing.Union[bool, str] = False
|
|
@@ -773,7 +822,11 @@ class Method(Function):
|
|
|
773
822
|
ref_qualifier: typing.Optional[str] = None
|
|
774
823
|
|
|
775
824
|
constructor: bool = False
|
|
776
|
-
|
|
825
|
+
|
|
826
|
+
#: True if the method was declared ``explicit``. For C++20
|
|
827
|
+
#: ``explicit(<expr>)``, this holds the expression as a Value (omitting
|
|
828
|
+
#: the outer parentheses).
|
|
829
|
+
explicit: typing.Union[bool, Value] = False
|
|
777
830
|
default: bool = False
|
|
778
831
|
|
|
779
832
|
destructor: bool = False
|
|
@@ -825,6 +878,8 @@ class Typedef:
|
|
|
825
878
|
|
|
826
879
|
#: If within a class, the access level for this decl
|
|
827
880
|
access: typing.Optional[str] = None
|
|
881
|
+
#: Any attributes attached to this typedef
|
|
882
|
+
attributes: typing.List[Attribute] = field(default_factory=list)
|
|
828
883
|
|
|
829
884
|
|
|
830
885
|
@dataclass
|
|
@@ -847,6 +902,8 @@ class Variable:
|
|
|
847
902
|
template: typing.Optional[TemplateDecl] = None
|
|
848
903
|
|
|
849
904
|
doxygen: typing.Optional[str] = None
|
|
905
|
+
#: Any attributes attached to this variable
|
|
906
|
+
attributes: typing.List[Attribute] = field(default_factory=list)
|
|
850
907
|
|
|
851
908
|
|
|
852
909
|
@dataclass
|
|
@@ -870,6 +927,8 @@ class Field:
|
|
|
870
927
|
inline: bool = False
|
|
871
928
|
|
|
872
929
|
doxygen: typing.Optional[str] = None
|
|
930
|
+
#: Any attributes attached to this field
|
|
931
|
+
attributes: typing.List[Attribute] = field(default_factory=list)
|
|
873
932
|
|
|
874
933
|
|
|
875
934
|
@dataclass
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '1.7.2'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 7, 2)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = None
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# file generated by setuptools-scm
|
|
2
|
-
# don't change, don't track in version control
|
|
3
|
-
|
|
4
|
-
__all__ = [
|
|
5
|
-
"__version__",
|
|
6
|
-
"__version_tuple__",
|
|
7
|
-
"version",
|
|
8
|
-
"version_tuple",
|
|
9
|
-
"__commit_id__",
|
|
10
|
-
"commit_id",
|
|
11
|
-
]
|
|
12
|
-
|
|
13
|
-
TYPE_CHECKING = False
|
|
14
|
-
if TYPE_CHECKING:
|
|
15
|
-
from typing import Tuple
|
|
16
|
-
from typing import Union
|
|
17
|
-
|
|
18
|
-
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
-
COMMIT_ID = Union[str, None]
|
|
20
|
-
else:
|
|
21
|
-
VERSION_TUPLE = object
|
|
22
|
-
COMMIT_ID = object
|
|
23
|
-
|
|
24
|
-
version: str
|
|
25
|
-
__version__: str
|
|
26
|
-
__version_tuple__: VERSION_TUPLE
|
|
27
|
-
version_tuple: VERSION_TUPLE
|
|
28
|
-
commit_id: COMMIT_ID
|
|
29
|
-
__commit_id__: COMMIT_ID
|
|
30
|
-
|
|
31
|
-
__version__ = version = '1.7.0'
|
|
32
|
-
__version_tuple__ = version_tuple = (1, 7, 0)
|
|
33
|
-
|
|
34
|
-
__commit_id__ = commit_id = None
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|