mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-01 15:47:06 +00:00
fix: keep normalize_ctx_input's ctx annotation on Python 3.14
Python 3.14 (PEP 649/749) replaced "__annotations__" with "__annotate__" in functools.WRAPPER_ASSIGNMENTS. normalize_ctx_input excluded only "__annotations__" when wrapping, so functools.wraps copied the wrapped function's __annotate__ and the wrapper's permissive ctx annotation (_dict | Document | dict | str) was overwritten by the narrow ItemDetailsCtx | str. Now that Frappe casts whitelisted args via typing_validations, a dict ctx failed the isinstance-only frappe._dict check and raised FrappeTypeError. Exclude "__annotate__" too. Cleanup while here: - Merge the three identical frappe._dict aliases (ItemDetails, ItemDetailsCtx, ItemPriceCtx) into ItemDetailsCtx. - Drop the now-redundant "| str" from decorated signatures; the decorator's wrapper union is what typing_validations enforces. - Decorate get_batch_based_item_price with normalize_ctx_input instead of a manual parse_json, renaming its arg pctx -> ctx (JS caller updated) so a dict/string payload is normalized to frappe._dict. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -179,7 +179,9 @@ def normalize_ctx_input(T: type) -> callable:
|
||||
|
||||
def decorator(func: callable):
|
||||
# conserve annotations for frappe.utils.typing_validations
|
||||
@functools.wraps(func, assigned=(a for a in functools.WRAPPER_ASSIGNMENTS if a != "__annotations__"))
|
||||
@functools.wraps(
|
||||
func, assigned=(a for a in functools.WRAPPER_ASSIGNMENTS if a not in ("__annotations__", "__annotate__"))
|
||||
)
|
||||
def wrapper(ctx: T | Document | dict | str, *args, **kwargs):
|
||||
if isinstance(ctx, Document):
|
||||
ctx = T(**ctx.as_dict())
|
||||
|
||||
Reference in New Issue
Block a user