diff --git a/package-parser/package_parser/commands/generate_annotations/_generate_annotations.py b/package-parser/package_parser/commands/generate_annotations/_generate_annotations.py index 187742482..ed4fc51c5 100644 --- a/package-parser/package_parser/commands/generate_annotations/_generate_annotations.py +++ b/package-parser/package_parser/commands/generate_annotations/_generate_annotations.py @@ -192,9 +192,16 @@ def __get_default_type_from_value(default_value: str) -> tuple[str, str]: def __get_required_annotations(usages: UsageStore, api: API) -> dict[str, dict[str, dict[str, str]]]: + """ + Returns all required annotations + + :param usages: Usage store + :param api: Description of the API + """ result = {} parameters = (api.parameters()) + # Takes all parameters with default value optional_parameter = [(it, parameters[it]) for it in parameters if parameters[it].default_value is not None] for qname, parameter in optional_parameter: @@ -208,6 +215,11 @@ def __get_required_annotations(usages: UsageStore, api: API) -> dict[str, dict[s def __get_parameter_type(values: list[tuple[str, int]]) -> (ParameterType, str): + """ + Returns a tuple of the parameter Typ and parameter value + + :param values: list of tuples where the first value represents the parameter name and the second represents the count of occurrences + """ if len(values) == 0: return ParameterType.Unused, None elif len(values) == 1: @@ -216,9 +228,9 @@ def __get_parameter_type(values: list[tuple[str, int]]) -> (ParameterType, str): n = len(values) m = sum([count for value, count in values]) - most_used_value, seconds_most_used_value = sorted(values, key=lambda tup: tup[1])[:2] + seconds_most_used_value, most_used_value = sorted(values, key=lambda tup: tup[1])[-2:] - if most_used_value[1] - seconds_most_used_value[1] <= n/m: + if most_used_value[1] - seconds_most_used_value[1] <= m/n: return ParameterType.Required, None else: return ParameterType.Optional, most_used_value[0] diff --git a/package-parser/tests/commands/generate_annotations/test_generate_annotations.py b/package-parser/tests/commands/generate_annotations/test_generate_annotations.py new file mode 100644 index 000000000..c7133544d --- /dev/null +++ b/package-parser/tests/commands/generate_annotations/test_generate_annotations.py @@ -0,0 +1,25 @@ +import json +import os +import pytest + +from package_parser.commands.find_usages import UsageStore +from package_parser.commands.generate_annotations.generate_annotations import ( + generate_annotations, __get_unused_annotations, __get_constant_annotations, ____qname_to_target_name, + _preprocess_usages) +from package_parser.commands.get_api import API + +REQUIRED_EXPECTED = {"constant": { + 'test/test/commonly_used_global_required_and_optional_function/optional_that_should_be_required': + {'target': 'test/test/commonly_used_global_required_and_optional_function/optional_that_should_be_required'}, + 'test/test/commonly_used_global_required_and_optional_function/required_that_should_be_required': + {'target': 'test/test/commonly_used_global_required_and_optional_function/required_that_should_be_required'}, + 'test/test/commonly_used_global_required_and_optional_function/commonly_used_barely_required': + {'target': 'test/test/commonly_used_global_required_and_optional_function/commonly_used_barely_required'}} + } + + +# Reihenfolge ist wichtig, siehe Reihenfolge von annotation_functions in generate_annotations.py +FULL_EXPECTED = {**UNUSED_EXPECTED, **CONSTANT_EXPECTED, **REQUIRED_EXPECTED} + +def test_required_annotation(): + pass diff --git a/package-parser/tests/data/requried/usage_data.json b/package-parser/tests/data/requried/usage_data.json deleted file mode 100644 index 875c7df31..000000000 --- a/package-parser/tests/data/requried/usage_data.json +++ /dev/null @@ -1,209 +0,0 @@ -{ - "class_usages": {}, - "function_usages": { - "test.unused_global_function": [], - "test.commonly_used_global_function": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 2, - "column": 2 - } - ] - }, - "parameter_usages": { - "test.unused_global_function.unused_required_parameter": [], - "test.unused_global_function.unused_optional_parameter": [], - "test.commonly_used_global_function.useless_required_parameter": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - } - ], - "test.commonly_used_global_function.useful_required_parameter": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - } - ], - "test.commonly_used_global_function.unused_optional_parameter": [], - "test.commonly_used_global_function.useless_optional_parameter": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - } - ], - "test.commonly_used_global_function.useful_optional_parameter": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - } - ] - }, - "value_usages": { - "test.unused_global_function.unused_required_parameter": {}, - "test.unused_global_function.unused_optional_parameter": {}, - "test.commonly_used_global_function.useless_required_parameter": { - "'blup'": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - } - ] - }, - "test.commonly_used_global_function.useful_required_parameter": { - "'bla'": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - } - ], - "'blup'": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - } - ] - }, - "test.commonly_used_global_function.unused_optional_parameter": {}, - "test.commonly_used_global_function.useless_optional_parameter": { - "'bla'": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - } - ] - }, - "test.commonly_used_global_function.useful_optional_parameter": { - "'blup'": [ - { - "file": "test.py", - "line": 1, - "column": 1 - }, - { - "file": "test.py", - "line": 1, - "column": 1 - } - ] - } - } -} diff --git a/package-parser/tests/data/requried/api_data.json b/package-parser/tests/data/requried_and_optional/api_data.json similarity index 68% rename from package-parser/tests/data/requried/api_data.json rename to package-parser/tests/data/requried_and_optional/api_data.json index d4bca8ec1..c58a745e6 100644 --- a/package-parser/tests/data/requried/api_data.json +++ b/package-parser/tests/data/requried_and_optional/api_data.json @@ -10,7 +10,7 @@ "classes": [], "functions": [ "test.unused_global_function", - "test.commonly_used_global_function" + "test.commonly_used_global_required_and_optional_function" ] } ], @@ -24,7 +24,7 @@ "decorators": [], "parameters": [ { - "name": "unused_required_parameter", + "name": "unused_parameter", "default_value": null, "is_public": true, "assigned_by": "POSITION_OR_NAME", @@ -32,16 +32,6 @@ "type": "str", "description": "" } - }, - { - "name": "unused_optional_parameter", - "default_value": "'bla'", - "is_public": true, - "assigned_by": "POSITION_OR_NAME", - "docstring": { - "type": "str", - "description": "" - } } ], "results": [], @@ -51,14 +41,24 @@ "source_code": "" }, { - "name": "commonly_used_global_function", - "unique_name": "commonly_used_global_function", - "qname": "test.commonly_used_global_function", - "unique_qname": "test.commonly_used_global_function", + "name": "commonly_used_global_required_and_optional_function", + "unique_name": "commonly_used_global_required_and_optional_function", + "qname": "test.commonly_used_global_required_and_optional_function", + "unique_qname": "test.commonly_used_global_required_and_optional_function", "decorators": [], "parameters": [ { - "name": "useless_required_parameter", + "name": "optional_that_should_be_required", + "default_value": "'test'", + "is_public": true, + "assigned_by": "POSITION_OR_NAME", + "docstring": { + "type": "str", + "description": "" + } + }, + { + "name": "required_that_should_be_required", "default_value": null, "is_public": true, "assigned_by": "POSITION_OR_NAME", @@ -68,7 +68,7 @@ } }, { - "name": "useful_required_parameter", + "name": "required_that_should_be_optional", "default_value": null, "is_public": true, "assigned_by": "POSITION_OR_NAME", @@ -78,8 +78,18 @@ } }, { - "name": "unused_optional_parameter", - "default_value": "'bla'", + "name": "optional_that_should_be_optional", + "default_value": "'captain_morgan'", + "is_public": true, + "assigned_by": "POSITION_OR_NAME", + "docstring": { + "type": "str", + "description": "" + } + }, + { + "name": "commonly_used_almost_required", + "default_value": "'marvel'", "is_public": true, "assigned_by": "POSITION_OR_NAME", "docstring": { @@ -88,8 +98,8 @@ } }, { - "name": "useless_optional_parameter", - "default_value": "'bla'", + "name": "commonly_used_barely_required", + "default_value": "'otto'", "is_public": true, "assigned_by": "POSITION_OR_NAME", "docstring": { @@ -98,8 +108,8 @@ } }, { - "name": "useful_optional_parameter", - "default_value": "'bla'", + "name": "constant_parameter", + "default_value": null, "is_public": true, "assigned_by": "POSITION_OR_NAME", "docstring": { diff --git a/package-parser/tests/data/requried_and_optional/usage_data.json b/package-parser/tests/data/requried_and_optional/usage_data.json new file mode 100644 index 000000000..69a8a7738 --- /dev/null +++ b/package-parser/tests/data/requried_and_optional/usage_data.json @@ -0,0 +1,428 @@ +{ + "class_usages": {}, + "function_usages": { + "test.unused_global_function": [], + "test.commonly_used_global_required_and_optional_function": [ + { + "file": "test.py", + "line": 1, + "column": 1 + }, + { + "file": "test.py", + "line":2, + "column": 2 + }, + { + "file": "test.py", + "line": 3, + "column": 3 + }, + { + "file": "test.py", + "line": 4, + "column": 4 + }, + { + "file": "test.py", + "line": 5, + "column": 5 + }, + { + "file": "test.py", + "line": 6, + "column": 6 + }, + { + "file": "test.py", + "line": 7, + "column": 7 + }, + { + "file": "test.py", + "line": 8, + "column": 8 + }, + { + "file": "test.py", + "line": 9, + "column": 9 + }, + { + "file": "test.py", + "line": 10, + "column": 10 + }, + { + "file": "test.py", + "line": 11, + "column": 11 + }, + { + "file": "test.py", + "line": 12, + "column": 12 + }, + { + "file": "test.py", + "line": 13, + "column": 13 + }, + { + "file": "test.py", + "line": 14, + "column": 14 + }, + { + "file": "test.py", + "line": 15, + "column": 15 + }, + { + "file": "test.py", + "line": 16, + "column": 16 + }, + { + "file": "test.py", + "line": 17, + "column": 17 + }, + { + "file": "test.py", + "line": 18, + "column": 18 + }, + { + "file": "test.py", + "line": 19, + "column": 19 + }, + { + "file": "test.py", + "line": 20, + "column": 20 + }, + { + "file": "test.py", + "line": 21, + "column": 21 + }, + { + "file": "test.py", + "line": 22, + "column": 22 + }, + { + "file": "test.py", + "line": 23, + "column": 23 + }, + { + "file": "test.py", + "line": 24, + "column": 24 + } + ] + }, + "parameter_usages": { + "test.unused_global_function.unused_parameter": [], + "test.commonly_used_global_required_and_optional_function.optional_that_should_be_required": [ + { + "file": "test.py", + "line": 1, + "column": 1 + }, + { + "file": "test.py", + "line":2, + "column": 2 + } + ], + "test.commonly_used_global_required_and_optional_function.required_that_should_be_required": [ + { + "file": "test.py", + "line": 3, + "column": 3 + }, + { + "file": "test.py", + "line": 4, + "column": 4 + } + ], + "test.commonly_used_global_required_and_optional_function.required_that_should_be_optional": [ + { + "file": "test.py", + "line": 5, + "column": 5 + }, + { + "file": "test.py", + "line": 6, + "column": 6 + }, + { + "file": "test.py", + "line": 7, + "column": 7 + }, + { + "file": "test.py", + "line": 8, + "column": 8 + }, + { + "file": "test.py", + "line": 9, + "column": 9 + } + ], + "test.commonly_used_global_required_and_optional_function.optional_that_should_be_optional": [ + { + "file": "test.py", + "line": 10, + "column": 10 + }, + { + "file": "test.py", + "line": 11, + "column": 11 + }, + { + "file": "test.py", + "line": 12, + "column": 12 + }, + { + "file": "test.py", + "line": 13, + "column": 13 + }, + { + "file": "test.py", + "line": 14, + "column": 14 + } + ], + "test.commonly_used_global_required_and_optional_function.commonly_used_almost_required": [ + { + "file": "test.py", + "line": 15, + "column": 15 + }, + { + "file": "test.py", + "line": 16, + "column": 16 + }, + { + "file": "test.py", + "line": 17, + "column": 17 + }, + { + "file": "test.py", + "line": 18, + "column": 18 + }, + { + "file": "test.py", + "line": 19, + "column": 19 + } + ], + "test.commonly_used_global_required_and_optional_function.commonly_used_barely_required": [ + { + "file": "test.py", + "line": 20, + "column": 20 + }, + { + "file": "test.py", + "line": 21, + "column": 21 + }, + { + "file": "test.py", + "line": 22, + "column": 22 + }, + { + "file": "test.py", + "line": 23, + "column": 23 + } + ], + "test.commonly_used_global_required_and_optional_function.constant_parameter": [ + { + "file": "test.py", + "line": 24, + "column": 24 + } + ] + }, + "value_usages": { + "test.unused_global_function.unused_parameter": {}, + "test.commonly_used_global_required_and_optional_function.optional_that_should_be_required": { + "'test'": [ + { + "file": "test.py", + "line": 1, + "column": 1 + } + ], + "'irgendwas_anderes'": [ + { + "file": "test.py", + "line": 2, + "column": 2 + } + ] + }, + "test.commonly_used_global_required_and_optional_function.required_that_should_be_required": { + "'hallo'": [ + { + "file": "test.py", + "line": 3, + "column": 3 + } + ], + "'irgendwas_anderes'": [ + { + "file": "test.py", + "line": 4, + "column": 4 + } + ] + }, + "test.commonly_used_global_required_and_optional_function.required_that_should_be_optional": { + "'miau'": [ + { + "file": "test.py", + "line": 5, + "column": 5 + }, + { + "file": "test.py", + "line": 6, + "column": 6 + }, + { + "file": "test.py", + "line": 7, + "column": 7 + }, + { + "file": "test.py", + "line": 8, + "column": 8 + } + ], + "'irgendwas_anderes'": [ + { + "file": "test.py", + "line": 9, + "column": 9 + } + ] + }, + "test.commonly_used_global_required_and_optional_function.optional_that_should_be_optional": { + "'captain_morgan'": [ + { + "file": "test.py", + "line": 10, + "column": 10 + }, + { + "file": "test.py", + "line": 11, + "column": 11 + }, + { + "file": "test.py", + "line": 12, + "column": 12 + }, + { + "file": "test.py", + "line": 13, + "column": 13 + } + ], + "'irgendwas_anderes'": [ + { + "file": "test.py", + "line": 14, + "column": 14 + } + ] + }, + "test.commonly_used_global_required_and_optional_function.commonly_used_almost_required": { + "'marvel'": [ + { + "file": "test.py", + "line": 15, + "column": 15 + }, + { + "file": "test.py", + "line": 16, + "column": 16 + }, + { + "file": "test.py", + "line": 17, + "column": 17 + }, + { + "file": "test.py", + "line": 18, + "column": 18 + } + ], + "'irgendwas_anderes'": [ + { + "file": "test.py", + "line": 19, + "column": 19 + } + ] + }, + "test.commonly_used_global_required_and_optional_function.commonly_used_barely_required": { + "'otto'": [ + { + "file": "test.py", + "line": 20, + "column": 20 + }, + { + "file": "test.py", + "line": 21, + "column": 21 + }, + { + "file": "test.py", + "line": 22, + "column": 22 + } + ], + "'irgendwas_anderes'": [ + { + "file": "test.py", + "line": 23, + "column": 23 + } + ] + }, + "test.commonly_used_global_required_and_optional_function.constant_parameter": { + "'bockwurst'": [ + { + "file": "test.py", + "line": 24, + "column": 24 + } + ] + } + } +}