Skip to content

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

Open
@f-kanari

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions