azure-functions-python-worker icon indicating copy to clipboard operation
azure-functions-python-worker copied to clipboard

[Bug] Opportunistic code in `get_function_return_type`.

Open VRGhost opened this issue 6 months ago • 1 comments

Expected Behavior

There should be no error

Actual Behavior

There is an error (please see log output)

Steps to Reproduce

No response

Relevant code being tried

import json
from typing import Generic, Mapping, Optional, TypeVar, Union

import azure.functions as func

# Type for valid JSON-serializable values
JsonType = Union[list, tuple, dict, str, int, float, bool]
T = TypeVar("T", bound=JsonType)


class JsonResponse(func.HttpResponse, Generic[T]):
    def __init__(
        self,
        body: T,
        status_code: int = 200,
        headers: Optional[Mapping[str, str]] = None,
    ):
        headers = (headers or {}) | {"Content-Type": "application/json"}
        super().__init__(json.dumps(body), status_code=status_code, headers=headers, charset="utf-8")

    def json(self) -> T:
        """Get the original body that was passed to the response.

        Returns:
            The original body object, preserving its exact type.
        """
        return json.loads(self.get_body().decode("utf-8"))

@app.route(route="health")
def health(req: func.HttpRequest) -> site_monitor.func.JsonResponse:
    """Health check endpoint that returns initialization status."""
    return site_monitor.func.JsonResponse(
        {
            "status": "healthy",
            "initialized": init_event.is_set(),
            "healthy": True,
            "uptime_seconds": int(time.monotonic() - startup_time),
        },
    )

Relevant log output

[2025-06-01T13:52:36.579Z] Indexed function app and found 2 functions
[2025-06-01T13:52:36.589Z] Worker failed to index functions
[2025-06-01T13:52:36.590Z] Result: Failure
Exception: AttributeError: 'NoneType' object has no attribute '__name__'
Stack:   File "C:\Devel\bin\node-v22.15.0-win-x64\node_modules\azure-functions-core-tools\bin\workers\python\3.12\WINDOWS\X64\azure_functions_worker\dispatcher.py", line 480, in _handle__functions_metadata_request
    self.load_function_metadata(
  File "C:\Devel\bin\node-v22.15.0-win-x64\node_modules\azure-functions-core-tools\bin\workers\python\3.12\WINDOWS\X64\azure_functions_worker\dispatcher.py", line 460, in load_function_metadata
    self.index_functions(function_path, function_app_directory)) \
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Devel\bin\node-v22.15.0-win-x64\node_modules\azure-functions-core-tools\bin\workers\python\3.12\WINDOWS\X64\azure_functions_worker\dispatcher.py", line 846, in index_functions
    loader.process_indexed_function(
  File "C:\Devel\bin\node-v22.15.0-win-x64\node_modules\azure-functions-core-tools\bin\workers\python\3.12\WINDOWS\X64\azure_functions_worker\loader.py", line 145, in process_indexed_function
    function_info = functions_registry.add_indexed_function(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Devel\bin\node-v22.15.0-win-x64\node_modules\azure-functions-core-tools\bin\workers\python\3.12\WINDOWS\X64\azure_functions_worker\functions.py", line 457, in add_indexed_function
    self.get_function_return_type(annotations,
  File "C:\Devel\bin\node-v22.15.0-win-x64\node_modules\azure-functions-core-tools\bin\workers\python\3.12\WINDOWS\X64\azure_functions_worker\functions.py", line 275, in get_function_return_type
    return_anno).__name__ == 'Out':
                 ^^^^^^^^
.
[2025-06-01T13:52:36.595Z] 0 functions found (Worker)
[2025-06-01T13:52:36.602Z] 0 functions loaded

requirements.txt file


Where are you facing this problem?

Local - Core Tools

Function app name

No response

Additional Information

I would like to report opportunistic code function.py file.

The typing_inspect.get_origin() can return None link

VRGhost avatar Jun 01 '25 13:06 VRGhost

Hi @VRGhost, thanks for reporting this.

The intended flow for this code snippet is that, wherever get_origin returns None, is_generic_type would return False, so the 'NoneType' object has no attribute '__name__' error would never be hit.

if typing_inspect.is_generic_type(
                    return_anno) and typing_inspect.get_origin(
                    return_anno).__name__ == 'Out':

However, in your scenario, is_generic_type is returning True, and get_origin isn't returning the correct type. We have a PR out now to get this fixed.

hallvictoria avatar Jun 02 '25 18:06 hallvictoria