diff --git a/python/extractor/tests/parser/class_bases_new.expected b/python/extractor/tests/parser/class_bases_new.expected new file mode 100644 index 000000000000..9cd652a98a73 --- /dev/null +++ b/python/extractor/tests/parser/class_bases_new.expected @@ -0,0 +1 @@ +Module: [1, 0] - [20, 0] diff --git a/python/extractor/tests/parser/class_bases_new.py b/python/extractor/tests/parser/class_bases_new.py new file mode 100644 index 000000000000..3ae778b1f338 --- /dev/null +++ b/python/extractor/tests/parser/class_bases_new.py @@ -0,0 +1,19 @@ +class NoBase: pass + +class EmptyBase(): pass + +class PrimitiveBase(int): pass + +class ManyBases(list, object): pass + +class SubscriptBase(list[int]): pass + +class WalrusBase(foo:=object): pass + +class AttrBase(typing.List): pass + +class TypedBase[K, V](dict[K, V]): pass + +class EllipsisBase(tuple[int, ...]): pass + +class NestedBase[K, V](dict[tuple[K, ...], list[V]]): pass diff --git a/python/extractor/tsg-python/python.tsg b/python/extractor/tsg-python/python.tsg index c832f7e63219..ff5de34da594 100644 --- a/python/extractor/tsg-python/python.tsg +++ b/python/extractor/tsg-python/python.tsg @@ -1282,15 +1282,17 @@ attr (@class.inner_scope -> @stmt.node) body = (named-child-index @stmt) } -; Class.bases - using `(_ !value !name)` as a proxy for all non-keyword arguments. -; In particular, `keyword_argument` nodes have a `name` field, and `dictionary_splat` -; nodes have a `value` field. +; Class.bases (class_definition - superclasses: (argument_list element: (_ !value !name) @arg) + superclasses: (argument_list element: (_) @arg) ) @class { - edge @class.class_expr -> @arg.node - attr (@class.class_expr -> @arg.node) bases = (named-child-index @arg) + if (not (or + (instance-of @arg "keyword_argument") + (instance-of @arg "dictionary_splat"))) { + edge @class.class_expr -> @arg.node + attr (@class.class_expr -> @arg.node) bases = (named-child-index @arg) + } } ; Class.keywords of the form `foo=bar`