fix(helpers): fix type annotation bug: np.array → np.ndarray in helpers.py (TypeError on Python 3.11+) - #95
fix(helpers): fix type annotation bug: np.array → np.ndarray in helpers.py (TypeError on Python 3.11+)#95nervgh wants to merge 3 commits into
np.array → np.ndarray in helpers.py (TypeError on Python 3.11+)#95Conversation
`helpers.py` (TypeError on Python 3.11+)
|
I came from okama-mcp with the error. # python --version # Python 3.12.3
# uvx okama-mcp stdio # <-- my command
Installed 91 packages in 84ms
Traceback (most recent call last):
File "/tmp/.tmpshlVOC/archive-v0/dgrAM591ZcXkBhCg/bin/okama-mcp", line 12, in <module>
sys.exit(main())
^^^^^^
File "/tmp/.tmpshlVOC/archive-v0/dgrAM591ZcXkBhCg/lib/python3.12/site-packages/okama_mcp/transport.py", line 57, in main
from okama_mcp.server import mcp
File "/tmp/.tmpshlVOC/archive-v0/dgrAM591ZcXkBhCg/lib/python3.12/site-packages/okama_mcp/server.py", line 37, in <module>
register_all(mcp)
File "/tmp/.tmpshlVOC/archive-v0/dgrAM591ZcXkBhCg/lib/python3.12/site-packages/okama_mcp/tools/__init__.py", line 14, in register_all
from okama_mcp.tools import (
File "/tmp/.tmpshlVOC/archive-v0/dgrAM591ZcXkBhCg/lib/python3.12/site-packages/okama_mcp/tools/asset.py", line 13, in <module>
import okama as ok
File "/tmp/.tmpshlVOC/archive-v0/dgrAM591ZcXkBhCg/lib/python3.12/site-packages/okama/__init__.py", line 27, in <module>
from okama.asset_list import AssetList # noqa: F401
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/tmp/.tmpshlVOC/archive-v0/dgrAM591ZcXkBhCg/lib/python3.12/site-packages/okama/asset_list.py", line 7, in <module>
from okama.common.helpers.helpers import check_rolling_window
File "/tmp/.tmpshlVOC/archive-v0/dgrAM591ZcXkBhCg/lib/python3.12/site-packages/okama/common/helpers/helpers.py", line 225, in <module>
class Frame:
File "/tmp/.tmpshlVOC/archive-v0/dgrAM591ZcXkBhCg/lib/python3.12/site-packages/okama/common/helpers/helpers.py", line 258, in Frame
def get_portfolio_mean_return(cls, weights: list | np.array, ror: pd.DataFrame) -> float:
~~~~~^~~~~~~~~~
TypeError: unsupported operand type(s) for |: 'type' and 'builtin_function_or_method'A quick reproduction command with Docker: docker run --rm astral/uv:python3.12-bookworm-slim bash -c 'uvx okama-mcp stdio' |
chilango74
left a comment
There was a problem hiding this comment.
The code fix is correct: I reproduced the import-time TypeError on the current master with Python 3.11, verified that this branch imports successfully and resolves both weight annotations as list | np.ndarray, and ran the full suite (405 passed, 3 skipped) plus Ruff (All checks passed!).
One blocking item remains: CONTRIBUTING.md requires every contribution to be accompanied by unit tests, but this PR changes production code without a regression test. Please add a focused test, preferably in tests/test_helpers.py, that evaluates the weight annotations of both Frame.get_portfolio_mean_return and Frame.get_portfolio_risk (for example via typing.get_type_hints) and verifies list | np.ndarray. Such a test fails on the current master even under Python 3.14, where annotation evaluation is deferred, and protects this exact regression.
|
@nervgh, thank you for tracing this back to I reproduced the failure on the current Before merging, please add a focused regression test as required by Once the test is pushed, please ping me here and I will re-review and merge the PR. |
GH #95: ensure `weights` parameter annotations in `Frame.get_portfolio_mean_return` and `Frame.get_portfolio_risk` resolve to `list | np.ndarray` instead of the non-type `np.array`.
|
@chilango74 thank you for your feedback. I've made requested changes. |
Fix type annotation bug:
np.array→np.ndarrayinhelpers.py(TypeError on Python 3.11+)Description
Two methods in
okama/common/helpers/helpers.pyusenp.array(a function) in PEP 604 union type hints instead ofnp.ndarray(the actual type). On Python 3.11+ these annotations are evaluated eagerly at import time and crash withTypeError.Background
In
okama/common/helpers/helpers.py, classFramehas two methods annotated withlist | np.array:np.arrayis abuiltin_function_or_method, not atype. PEP 604's|operator requires both operands to be types. When Python evaluateslist | np.arrayit callslist.__or__(np.array), which receives a non-type and raises:The bug was introduced in v1.3.0 (May 2023) during a refactoring into
common/helpers/. At that time the code usedtyping.Union[list, np.array]—Unionaccepts any object and does not validate that it's a type, so the bug remained latent. When the codebase migrated to PEP 604 syntax in v1.5.0 (Python 3.10+) and then v2.0.0 (Python 3.11+), the bug became fatal —list | np.arrayis evaluated eagerly and crashes.The bug has persisted unreleased through 11 releases up to the current v2.3.0. It went unnoticed because no other module in okama directly triggers import of these
Framemethods. It manifests when external code (e.g.okama-mcpserver) callsget_portfolio_mean_returnorget_portfolio_risk.Scope
okama/common/helpers/helpers.py, replacingnp.arraywithnp.ndarray:get_portfolio_mean_return(line 258)get_portfolio_risk(line 386)np.array()calls inside the body are valid runtime invocations and must not be changed.Related
np.array— factory function →<class 'builtin_function_or_method'>np.ndarray— actual type →<class 'type'>Patch applied
File:
okama/okama/common/helpers/helpers.pyget_portfolio_mean_returnweights: list | np.arrayweights: list | np.ndarrayget_portfolio_riskweights: list | np.arrayweights: list | np.ndarrayValidation:
All checks passed!Summary by Sourcery
Enhancements: