Skip to content

Fix UnboundLocalError in _get_version() when package metadata is missing - #342

Open
yashbudhia wants to merge 1 commit into
razorpay:masterfrom
yashbudhia:fix-version-fallback
Open

Fix UnboundLocalError in _get_version() when package metadata is missing#342
yashbudhia wants to merge 1 commit into
razorpay:masterfrom
yashbudhia:fix-version-fallback

Conversation

@yashbudhia

Copy link
Copy Markdown

Client._get_version() has a fallback for when the package metadata cannot be found, but the fallback never runs. Instead every request raises UnboundLocalError.

Reproduce (any environment where razorpay is importable but not installed, e.g. a source checkout or a vendored copy):

>>> import importlib.metadata, razorpay
>>> importlib.metadata.version = lambda name: (_ for _ in ()).throw(importlib.metadata.PackageNotFoundError(name))
>>> razorpay.Client(auth=("k", "s"))._get_version()
UnboundLocalError: cannot access local variable 'DistributionNotFound' where it is not associated with a value

Cause

DistributionNotFound is imported only inside the pkg_resources branch, but it is named in the except (PackageNotFoundError, DistributionNotFound, NameError) clause that also guards the importlib.metadata path. When importlib.metadata.version() raises PackageNotFoundError, Python evaluates that tuple, hits the unbound local, and the new UnboundLocalError replaces the original exception. It is raised while evaluating the except expression, so the clause itself cannot catch it, and it propagates out of _update_user_agent_header() and therefore out of every API call.

Fix

Resolve the "not found" exception class before doing the lookup, then look up the version in its own try. Behaviour when the package is installed is unchanged; when the metadata is missing the documented fallback version is returned with the existing UserWarning. The fallback value itself is left as it was.

Tests

tests/test_client_version.py covers the installed path, the fallback with its warning, and that a request's User-Agent header can still be built without metadata. Full suite: 160 passed, 1 skipped.

_get_version() imported DistributionNotFound only inside the pkg_resources
fallback branch, but named it in the except clause that also guards the
importlib.metadata path. When importlib.metadata.version() raised
PackageNotFoundError, evaluating that except tuple hit the unbound name
and the original exception was replaced by UnboundLocalError, which
propagated out of _update_user_agent_header() and so out of every request.

That is exactly the situation the fallback was written for, e.g. running
the SDK from a source checkout or a vendored copy that was never
pip-installed. The exception class is now resolved before the lookup, so
the fallback version and its warning are actually used.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ZJQzxtgWvkWobxsDcuLoW
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.

1 participant