def fix_anomalies()

in tasks/tools/typings_generator.py [0:0]


    def fix_anomalies(schema: Dict):
        """
        the original json schema gets generated as below, where inner model classes,
        that are referred from API request response classes, are generated with
        multiple references in definitions.

        schema:
            properties: {
                Car: {
                    $ref: #/definitions/<uuid>__Car
                }
            }
            definitions: {
                <uuid>__Car: {
                },
                ideadatamodel__Car: {
                },
                ListCars: {
                    listing: {
                        $ref: <uuid>__Car
                    }
                }
            }

        goal is to unify all these references to a single reference:
            #/definitions/Car

        one major caveat to this implementation is the Model class names must be unique.
        this issue can be eliminated as long as all model class names are unique across modules.
        """

        definitions = Utils.get_value_as_dict('definitions', schema)

        # find anomalies in schema properties
        properties = Utils.get_value_as_dict('properties', schema)
        if properties is not None:
            for name, value in properties.items():
                ref = Utils.get_value_as_string('$ref', value)
                if '__' not in ref:
                    continue
                definition_key = ref.replace('#/definitions/', '')
                definition = Utils.get_value_as_dict(definition_key, definitions)
                definitions[name] = definition
                updated_ref = f'#/definitions/{name}'
                value['$ref'] = updated_ref

        # traverse definitions and replace anomalies

        add_definitions = {}

        def get_update_ref(ref_value: Optional[str]) -> Optional[str]:
            if ref_value is None:
                return None
            if '__' not in ref:
                return ref
            ref_type_name = ref.split('__')[-1]
            return f'#/definitions/{ref_type_name}'

        if definitions is not None:
            for name, value in definitions.items():
                if '__' in name:
                    title = Utils.get_value_as_string('title', value)
                    add_definitions[title] = value
                current_properties = Utils.get_value_as_dict('properties', value)
                if current_properties is None:
                    continue
                for prop_name, prop_value in current_properties.items():
                    prop_type = Utils.get_value_as_string('type', prop_value)
                    if prop_type is not None and prop_type == 'array':
                        array_items = Utils.get_value_as_dict('items', prop_value)
                        any_of_types = Utils.get_value_as_list('anyOf', array_items)
                        if any_of_types is not None:
                            for any_of in any_of_types:
                                ref = Utils.get_value_as_string('$ref', any_of)
                                updated_ref = get_update_ref(ref)
                                if updated_ref is not None:
                                    any_of['$ref'] = updated_ref
                        else:
                            ref = Utils.get_value_as_string('$ref', array_items)
                            updated_ref = get_update_ref(ref)
                            if updated_ref is not None:
                                array_items['$ref'] = updated_ref
                    else:
                        ref = Utils.get_value_as_string('$ref', prop_value)
                        updated_ref = get_update_ref(ref)
                        if updated_ref is not None:
                            prop_value['$ref'] = updated_ref

            # clean-up definitions
            to_delete = []
            for name in definitions:
                if '__' in name:
                    to_delete.append(name)
            for name in to_delete:
                del definitions[name]

            # add updated refs
            for name in add_definitions:
                definitions[name] = add_definitions[name]