Skip to content

Commit

Permalink
Added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Masara committed Apr 11, 2024
1 parent d24ef1b commit d774b5c
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 16 deletions.
13 changes: 1 addition & 12 deletions src/safeds_stubgen/api_analyzer/_ast_walker.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,8 @@ def __walk(self, node: MypyFile | ClassDef | Decorator | FuncDef | AssignmentStm
child_nodes = [_def for _def in definitions if _def.__class__.__name__ == "AssignmentStmt"]

for child_node in child_nodes:
# Ignore global variables and function attributes if the function is an __init__
if isinstance(child_node, AssignmentStmt):
if isinstance(node, MypyFile):
continue
if isinstance(node, FuncDef) and node.name != "__init__":
continue

# The '__mypy-replace' name is a mypy placeholer which we don't want to parse.
if (isinstance(child_node, FuncDef) and isinstance(node, FuncDef)) or getattr(
child_node,
"name",
"",
) == "__mypy-replace":
if getattr(child_node, "name", "") == "__mypy-replace": # pragma: no cover
continue

self.__walk(child_node, visited_nodes)
Expand Down
4 changes: 2 additions & 2 deletions src/safeds_stubgen/docstring_parsing/_docstring_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,14 @@ def _griffe_annotation_to_api_type(
return sds_types.TupleType(types=types)
elif annotation.canonical_path == "set":
return sds_types.SetType(types=types)
elif annotation.canonical_path == "collections.abc.Callable":
elif annotation.canonical_path in {"collections.abc.Callable", "typing.Callable"}:
param_type = types[0] if len(types) >= 1 else [any_type]
if not isinstance(param_type, sds_types.AbstractType): # pragma: no cover
raise TypeError(f"Expected AbstractType object, received {type(param_type)}")
parameter_types = param_type.types if isinstance(param_type, sds_types.ListType) else [param_type]
return_type = types[1] if len(types) >= 2 else any_type
return sds_types.CallableType(parameter_types=parameter_types, return_type=return_type)
elif annotation.canonical_path in {"dict", "collections.abc.Mapping"}:
elif annotation.canonical_path in {"dict", "collections.abc.Mapping", "typing.Mapping"}:
key_type = types[0] if len(types) >= 1 else any_type
value_type = types[1] if len(types) >= 2 else any_type
return sds_types.DictType(key_type=key_type, value_type=value_type)
Expand Down
21 changes: 20 additions & 1 deletion tests/data/docstring_parser_package/googledoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A module for testing the various docstring types.
"""
from enum import Enum
from typing import Optional, Any
from typing import Optional, Any, Callable, Mapping
from tests.data.various_modules_package.another_path.another_module import AnotherClass


Expand Down Expand Up @@ -230,6 +230,10 @@ class ClassWithVariousAttributeTypes:
optional_type_2 (Optional[int]):
class_type (ClassWithAttributes):
imported_type (AnotherClass):
callable_type (Callable[[int], str]):
mapping_type (Mapping[int, str]):
bool_op_type (int or str or bool):
list_type_5 ([int]):
"""
no_type = ""
optional_type = ""
Expand All @@ -255,6 +259,21 @@ class ClassWithVariousAttributeTypes:
optional_type_2: Optional[int]
class_type: ClassWithAttributes
imported_type: AnotherClass
callable_type: Callable[[int], str]
mapping_type: Mapping[int, str]
bool_op_type: int | str | bool
list_type_5: list[int]


def uninferable_return_doc():
"""
uninferable_return_doc.
Dolor sit amet.
Returns:
'True' is something happens, else 'False'.
"""


def infer_types():
Expand Down
22 changes: 21 additions & 1 deletion tests/data/docstring_parser_package/numpydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A module for testing the various docstring types.
"""
from typing import Any, Optional
from typing import Any, Optional, Callable, Mapping
from enum import Enum
from tests.data.various_modules_package.another_path.another_module import AnotherClass

Expand Down Expand Up @@ -363,6 +363,10 @@ class ClassWithVariousAttributeTypes:
optional_type_2 : Optional[int]
class_type : ClassWithAttributes
imported_type : AnotherClass
callable_type : Callable[[int], str]
mapping_type : Mapping[int, str]
bool_op_type : int or str or bool
list_type_5 : [int]
"""
no_type = ""
optional_type = ""
Expand All @@ -388,6 +392,22 @@ class ClassWithVariousAttributeTypes:
optional_type_2: Optional[int]
class_type: ClassWithAttributes
imported_type: AnotherClass
callable_type: Callable[[int], str]
mapping_type: Mapping[int, str]
bool_op_type: int | str | bool
list_type_5: list[int]


def uninferable_return_doc():
"""
uninferable_return_doc.
Dolor sit amet.
Returns
-------
'True' is something happens, else 'False'.
"""


def infer_types():
Expand Down
23 changes: 23 additions & 0 deletions tests/data/docstring_parser_package/restdoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,17 @@ def infer_types2(a, b):
return True


def uninferable_return_doc():
"""
uninferable_return_doc.
Dolor sit amet.
:return: return value
:rtype: 'True' is something happens, else 'False'.
"""


# Todo Currently disabled, since Griffe can't analyze ReST (Sphinx) attributes (see issue #98)
# class ClassWithVariousAttributeTypes:
# """
Expand Down Expand Up @@ -295,6 +306,14 @@ def infer_types2(a, b):
# :type any_type: Any
# :var optional_type_2:
# :type optional_type_2: Optional[int]
# :var callable_type:
# :type callable_type: Callable[[int], str]
# :var mapping_type:
# :type mapping_type: Mapping[int, str]
# :var bool_op_type:
# :type bool_op_type: int or str or bool
# :var list_type_5:
# :type list_type_5: [int]
# """
# has_default = 1
# optional_int = None
Expand Down Expand Up @@ -324,3 +343,7 @@ def infer_types2(a, b):
# optional_type_2: Optional[int]
# class_type: ClassWithMethod
# imported_type: AnotherClass
# callable_type: Callable[[int], str]
# mapping_type: Mapping[int, str]
# bool_op_type: int | str | bool
# list_type_5: list[int]
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ fun functionWithMultipleResults() -> (result1: Int, result2: Boolean)
@PythonName("function_without_return_value")
fun functionWithoutReturnValue()

// TODO Result type information missing.
/**
* uninferable_return_doc.
*
* Dolor sit amet.
*
* @result result1 'True' is something happens, else 'False'.
*/
@Pure
@PythonName("uninferable_return_doc")
fun uninferableReturnDoc()

/**
* property_method_with_docstring.
*
Expand Down Expand Up @@ -288,6 +300,15 @@ class ClassWithVariousAttributeTypes() {
static attr classType: ClassWithAttributes
@PythonName("imported_type")
static attr importedType: AnotherClass
// TODO Attribute has no type information.
@PythonName("callable_type")
static attr callableType
@PythonName("mapping_type")
static attr mappingType: Map<Int, String>
@PythonName("bool_op_type")
static attr boolOpType: union<Boolean, Int, String>
@PythonName("list_type_5")
static attr listType5: List<Int>
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ fun functionWithMultipleResults() -> (firstResult: Int, secondResult: Boolean)
@PythonName("function_without_result_value")
fun functionWithoutResultValue()

// TODO Result type information missing.
/**
* uninferable_return_doc.
*
* Dolor sit amet.
*/
@Pure
@PythonName("uninferable_return_doc")
fun uninferableReturnDoc()

/**
* property_method_with_docstring.
*
Expand Down Expand Up @@ -385,6 +395,15 @@ class ClassWithVariousAttributeTypes() {
static attr classType: ClassWithAttributes
@PythonName("imported_type")
static attr importedType: AnotherClass
// TODO Attribute has no type information.
@PythonName("callable_type")
static attr callableType
@PythonName("mapping_type")
static attr mappingType: Map<Int, String>
@PythonName("bool_op_type")
static attr boolOpType: union<Boolean, Int, String>
@PythonName("list_type_5")
static attr listType5: List<Int>
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ fun inferTypes2(
b
) -> result1: union<Boolean, String>

// TODO Result type information missing.
/**
* uninferable_return_doc.
*
* Dolor sit amet.
*
* @result result1 return value
*/
@Pure
@PythonName("uninferable_return_doc")
fun uninferableReturnDoc()

/**
* ClassWithDocumentation. Code::
*
Expand Down

0 comments on commit d774b5c

Please sign in to comment.