open-telemetry / open-telemetry/opentelemetry-python-contrib

AttributeError in unpatch_handler_class when child class inherits from instrumented parent handler in opentelemetry-instrumentation-tornado

Open
#3,072 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
1.1k
Forks
1.1k
Avg merge
4d 15h
Merged PRs (30d)
16

Description

Describe your environment

Python version: Python 3.12
Package version:

  • opentelemetry-instrumentation-tornado: 0.49b2
  • tornado: 6.4.2
What happened?

OpenTelemetry Tornado instrumentation throws AttributeError when unpatch_handler_class is called on a child class after its parent class has been instrumented. This occurs due to inconsistent behavior between getattr and delattr when handling class variables in inheritance.

Steps to Reproduce
  1. Install dependencies:
python>=3.12
opentelemetry-instrumentation-tornado>=0.49b2
tornado>=6.4.2
  1. Create the following test code:
import tornado.web
import tornado.httputil
import unittest.mock
import opentelemetry.instrumentation.tornado


class Handler1(tornado.web.RequestHandler):
    pass


class Handler2(Handler1):
    def initialize(self):
        opentelemetry.instrumentation.tornado.unpatch_handler_class(type(self))


def main():
    opentelemetry.instrumentation.tornado.TornadoInstrumentor().instrument()
    app = tornado.web.Application()
    req = tornado.httputil.HTTPServerRequest(
        connection=tornado.http1connection.HTTP1Connection(
            unittest.mock.MagicMock(), False
        )
    )
    Handler1(app, req)  # Parent handler instantiation
    Handler2(app, req)  # Child handler instantiation
  1. Run the code
Expected Result

The code should execute without errors, properly handling the unpatching of the child handler class.

Actual Result

An AttributeError is raised:

AttributeError: type object 'Handler2' has no attribute '_otel_patched_key'
Additional context

The issue stems from inconsistent behavior in Python's attribute handling:

  1. getattr(cls, '_otel_patched_key') traverses the inheritance chain
  2. delattr(cls, '_otel_patched_key') only operates on the immediate class

The sequence causing the error:

  1. Parent class (Handler1) gets instrumented with _otel_patched_key
  2. Child class (Handler2) calls unpatch_handler_class
  3. getattr check passes (finds attribute in parent)
  4. delattr fails (can't find attribute in child)
Would you like to implement a fix?

None

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating unpatch_handler_class in the Tornado instrumentation and run the provided Handler1/Handler2 reproduction with Python 3.12, Tornado 6.4.2, and instrumentation 0.49b2. Done means the child handler can be unpatched without AttributeError and a regression test covers the inherited _otel_patched_key case.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, observability-sre
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.