Skip to content

Fix TypeError in os.fork() for garbage-collected processors - #5453

Open
pranaysb wants to merge 13 commits into
open-telemetry:mainfrom
pranaysb:fix/os-fork-gc-bug
Open

Fix TypeError in os.fork() for garbage-collected processors#5453
pranaysb wants to merge 13 commits into
open-telemetry:mainfrom
pranaysb:fix/os-fork-gc-bug

Conversation

@pranaysb

Copy link
Copy Markdown
Contributor

Description

Fixes TypeError: 'NoneType' object is not callable in os.fork() when a BatchProcessor or PeriodicExportingMetricReader has been garbage collected.

The after_in_child callbacks registered via os.register_at_fork during initialization stored weak references to reinit methods, but unconditionally invoked them without checking if the reference had resolved to None. This PR adds a safe _after_in_child method that checks for None before invoking the callback, matching the existing behavior of ConcurrentMultiSpanProcessor.

Fixes #5452

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

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_fork in tests/shared_internal/test_batch_processor.py
  • test_garbage_collected_processor_does_not_crash_on_fork in tests/metrics/test_periodic_exporting_metric_reader.py

Does This PR Require a Contrib Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@pranaysb
pranaysb requested a review from a team as a code owner July 23, 2026 01:42
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/_shared_internal/__init__.py Outdated
Comment thread opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py Outdated
Comment thread opentelemetry-sdk/tests/logs/test_export.py Outdated
@github-project-automation github-project-automation Bot moved this to Reviewed PRs that need fixes in Python PR digest Jul 23, 2026
@herin049
herin049 requested a review from Copilot July 23, 2026 04:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 BatchProcessor and PeriodicExportingMetricReader to ensure no unraisable exception is emitted to stderr after 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.

Comment thread opentelemetry-sdk/tests/shared_internal/test_batch_processor.py
Comment thread opentelemetry-sdk/tests/shared_internal/test_batch_processor.py
Comment thread opentelemetry-sdk/tests/shared_internal/test_batch_processor.py Outdated
Comment thread opentelemetry-sdk/tests/metrics/test_periodic_exporting_metric_reader.py Outdated
Comment thread opentelemetry-sdk/tests/metrics/test_periodic_exporting_metric_reader.py Outdated
pranaysb and others added 5 commits July 23, 2026 13:12
…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
@aabmass

aabmass commented Jul 31, 2026

Copy link
Copy Markdown
Member

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.
@pranaysb

pranaysb commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

Please resolve comments if you feel they're addressed, and we can take another review pass

addressed the review feedback and pushed a fix for the skip-condition gap. all threads resolved

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

Labels

None yet

Projects

Status: Reviewed PRs that need fixes

Development

Successfully merging this pull request may close these issues.

BatchProcessor and PeriodicExportingMetricReader cause TypeError: 'NoneType' object is not callable on os.fork() after being garbage collected

4 participants