Fix TypeError in os.fork() for garbage-collected processors - #5453
Fix TypeError in os.fork() for garbage-collected processors#5453pranaysb wants to merge 13 commits into
Conversation
Assisted-by: Claude Opus 4.6
Assisted-by: Google Antigravity
Assisted-by: Google Antigravity
Assisted-by: Google Antigravity
Assisted-by: Google Antigravity
There was a problem hiding this comment.
Pull request overview
This PR fixes a TypeError: 'NoneType' object is not callable that can occur during os.fork() when at-fork callbacks are registered via os.register_at_fork using weakref.WeakMethod, and the underlying processor/reader instance has been garbage collected. The change updates the at-fork callback implementations to safely no-op when the weak reference has expired, aligning behavior with existing fork-handling patterns in the SDK.
Changes:
- Guard
os.register_at_fork(after_in_child=...)callbacks so weakly-referenced bound methods are only invoked when still alive. - Add fork-focused regression tests for
BatchProcessorandPeriodicExportingMetricReaderto ensure no unraisable exception is emitted tostderrafter GC. - Add a targeted pylint suppression in a log export test; add changelog entry.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/init.py | Makes BatchProcessor’s at-fork callback safe when the weak method has expired. |
| opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/init.py | Makes PeriodicExportingMetricReader’s at-fork callback safe when the weak method has expired. |
| opentelemetry-sdk/tests/shared_internal/test_batch_processor.py | Adds a regression test that forks after GC and asserts no TypeError is printed to stderr. |
| opentelemetry-sdk/tests/metrics/test_periodic_exporting_metric_reader.py | Adds a regression test that forks after GC and asserts no TypeError is printed to stderr. |
| opentelemetry-sdk/tests/logs/test_export.py | Adds an inline pylint suppression for an intentional “too few args” logging call in a test. |
| .changelog/5453.fixed | Documents the bugfix in the changelog system. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…t__.py Co-authored-by: Lukas Hering <40302054+herin049@users.noreply.github.com>
…rt/__init__.py Co-authored-by: Lukas Hering <40302054+herin049@users.noreply.github.com>
Assisted-by: Google Antigravity
Assisted-by: Google Antigravity
Assisted-by: Google Antigravity
|
Please resolve comments if you feel they're addressed, and we can take another review pass |
…ter_at_fork Matches the equivalent metrics reader test and addresses Copilot review feedback on PR open-telemetry#5453.
addressed the review feedback and pushed a fix for the skip-condition gap. all threads resolved |
Description
Fixes
TypeError: 'NoneType' object is not callableinos.fork()when aBatchProcessororPeriodicExportingMetricReaderhas been garbage collected.The
after_in_childcallbacks registered viaos.register_at_forkduring initialization stored weak references toreinitmethods, but unconditionally invoked them without checking if the reference had resolved toNone. This PR adds a safe_after_in_childmethod that checks forNonebefore invoking the callback, matching the existing behavior ofConcurrentMultiSpanProcessor.Fixes #5452
Type of change
How Has This Been Tested?
Verified via the existing test suite and added specific unit tests verifying that garbage-collected processors do not crash the child process upon fork.
test_garbage_collected_processor_does_not_crash_on_forkintests/shared_internal/test_batch_processor.pytest_garbage_collected_processor_does_not_crash_on_forkintests/metrics/test_periodic_exporting_metric_reader.pyDoes This PR Require a Contrib Repo Change?
Checklist: