Skip to content

fix(logfire-api): support bare @logfire.instrument decorator#2047

Open
syf2211 wants to merge 1 commit into
pydantic:mainfrom
syf2211:fix/1877-logfire-api-instrument-decorator
Open

fix(logfire-api): support bare @logfire.instrument decorator#2047
syf2211 wants to merge 1 commit into
pydantic:mainfrom
syf2211:fix/1877-logfire-api-instrument-decorator

Conversation

@syf2211

@syf2211 syf2211 commented Jul 1, 2026

Copy link
Copy Markdown

Summary

Fix the logfire-api no-op shim so @logfire.instrument (without parentheses) returns the original function instead of the inner decorator.

Motivation

When logfire is not installed, logfire-api provides a lightweight stub. Its instrument() always returned the inner decorator function. With bare @logfire.instrument, Python passes the target function as the first positional argument, but the shim never applied the decorator — the decorated name became decorator itself.

This matches the behavior described in #1877 and mirrors the real SDK dispatch (if callable(msg_template): return self.instrument()(msg_template)).

Changes

  • Detect callable first arguments in Logfire.instrument shim and apply the no-op decorator immediately
  • Add regression coverage in test_logfire_api.py for the no-logfire code path

Tests

  • uv run pytest tests/test_logfire_api.py -v — 3 passed, 1 skipped
  • uv run ruff check logfire-api/logfire_api/__init__.py tests/test_logfire_api.py — pass

Notes

  • Only affects the logfire-api stub used when the full logfire package is not installed
  • @logfire.instrument() and @logfire.instrument('template') behavior unchanged

Fixes #1877

Review in cubic

When logfire is not installed, logfire-api's instrument() shim always
returned the inner decorator function. Using @logfire.instrument without
parentheses passed the target function as the first argument but never
applied the decorator, replacing the function with decorator itself.

Detect callable first arguments the same way the real Logfire.instrument
does and apply the no-op decorator immediately.

Fixes pydantic#1877

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 2 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

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 the logfire-api no-op shim so @logfire.instrument (without parentheses) behaves correctly when the real logfire package is not installed, and adds a regression test to prevent the decorator from replacing the target function.

Changes:

  • Update the logfire-api shim Logfire.instrument to immediately apply the no-op decorator when invoked as a bare decorator.
  • Add a regression test validating bare @logfire_api.instrument preserves call behavior and function identity metadata.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
tests/test_logfire_api.py Adds a regression assertion for bare @logfire_api.instrument in the no-logfire (shim) import path.
logfire-api/logfire_api/init.py Adjusts the shim instrument implementation to handle the bare-decorator invocation pattern.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +134 to 140
def instrument(self, msg_template=None, **kwargs):
def decorator(func):
return func

if callable(msg_template):
return decorator(msg_template)
return decorator

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The real instrument only accepts a single positional arg (msg_template) — everything after it is keyword-only — so instrument('tpl', extra_positional) already raises TypeError when logfire is installed. Dropping *args makes the shim match that contract instead of silently accepting calls that would fail for real. And the callable() check mirrors the real SDK's own dispatch (if callable(msg_template): return self.instrument()(msg_template)), which is the whole point of the shim.

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

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@hramezani hramezani requested a review from alexmojaki July 2, 2026 09:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

logfire-api instrument decorator behaves wrong

3 participants