open-telemetry / opentelemetry-python-contrib

OpenTelemetry instrumentation for Python modules
https://opentelemetry.io
Apache License 2.0
739 stars 613 forks source link

AttributeError: 'functools.partial' object has no attribute '__name__' in `AsyncioInstrumentor.trace_to_thread` #2910

Closed ecarrara closed 1 month ago

ecarrara commented 1 month ago

Describe your environment

OS: ubuntu:22.04 Python version: 3.12 Package version: 0.48b0

What happened?

An AttributeError in AsyncioInstrumentor.trace_to_thread when func is a functools.partial instance.

File "example.py", line 58, in invoke_sales_agent_graph
    answer = await graph.ainvoke(input_message, config)
  File "/usr/local/lib/python3.12/site-packages/langgraph/pregel/__init__.py", line 1604, in ainvoke
    async for chunk in self.astream(
  File "/usr/local/lib/python3.12/site-packages/langgraph/pregel/__init__.py", line 1493, in astream
    async for _ in runner.atick(
  File "/usr/local/lib/python3.12/site-packages/langgraph/pregel/runner.py", line 130, in atick
    await arun_with_retry(t, retry_policy, stream=self.use_astream)
  File "/usr/local/lib/python3.12/site-packages/langgraph/pregel/retry.py", line 102, in arun_with_retry
    await task.proc.ainvoke(task.input, config)
  File "/usr/local/lib/python3.12/site-packages/langgraph/utils/runnable.py", line 428, in ainvoke
    input = await asyncio.create_task(coro, context=context)
  File "/usr/local/lib/python3.12/site-packages/opentelemetry/instrumentation/asyncio/__init__.py", line 279, in trace_coroutine
    return await coro
  File "/usr/local/lib/python3.12/site-packages/langgraph/utils/runnable.py", line 211, in ainvoke
    ret = await asyncio.create_task(coro, context=context)
  File "/usr/local/lib/python3.12/site-packages/opentelemetry/instrumentation/asyncio/__init__.py", line 279, in trace_coroutine
    return await coro
  File "/usr/local/lib/python3.12/site-packages/langgraph/graph/graph.py", line 107, in _aroute
    value = await asyncio.to_thread(reader, config)
  File "/usr/local/lib/python3.12/site-packages/opentelemetry/instrumentation/asyncio/__init__.py", line 204, in wrap_to_thread
    wrapped_first_arg = self.trace_to_thread(first_arg)
  File "/usr/local/lib/python3.12/site-packages/opentelemetry/instrumentation/asyncio/__init__.py", line 238, in trace_to_thread
    if func.__name__ in self._to_thread_name_to_trace

I found this issue while using the LangGraph library. But this issue isn't just with LangGraph; it can happen with any code that uses functools.partial.

Steps to Reproduce

Here is a minimal reproducible example:

import functools
import asyncio

def multiply(x, y):
    return x * y

double = functools.partial(multiply, 2)

async def example():
    result = await asyncio.to_thread(double, 3)
    assert result == 6

asyncio.run(example())

Expected Result

The function should run without error.

Actual Result

Raises an AttributeError 🥲

Additional context

No response

Would you like to implement a fix?

Yes