Skip to content

Fix FunctionMaker.create() with return type annotation (#138) - #186

Merged
micheles merged 1 commit into
micheles:masterfrom
apoorvdarshan:fix-138-return-annotation
Jul 9, 2026
Merged

Fix FunctionMaker.create() with return type annotation (#138)#186
micheles merged 1 commit into
micheles:masterfrom
apoorvdarshan:fix-138-return-annotation

Conversation

@apoorvdarshan

Copy link
Copy Markdown
Contributor

Summary

FunctionMaker.create() raised a SyntaxError when the signature string contained a return annotation, e.g.:

FunctionMaker.create("add3(a: int, b: int) -> int", "return add(a, b)", evaldict={"add": add})

The parser assumed the signature always ended with ) and stripped the last character with rest[:-1], then unconditionally re-appended ) when emitting the def line. With a return annotation present, this produced invalid source such as:

def add3(a: int, b: int) -> in):
    return add(a, b)

which failed to compile. This matches the report in #138 (and the earlier acknowledgement in #114).

Fix

In FunctionMaker.create(), split the argument list from an optional -> ... return annotation using rest.rpartition(')'), and reattach the annotation after the closing paren when building the def line (via a %(return_annotation)s placeholder so it is substituted safely). Signatures without a return annotation are handled exactly as before (rpartition yields an empty tail), so behavior is unchanged for the existing case.

Tests / Verification

  • Added ExtraTestCase.test_return_annotation covering both a signature without an annotation and one with a -> int return annotation. It fails on master with SyntaxError: unmatched ')' and passes with this change.
  • Full suite green: python tests/test.py -v -> Ran 26 tests ... OK (including the doctest suite).
  • Lint/type checks clean: flake8 (CI config), codespell (CI config), python -m mypy.stubtest decorator, and python -m mypy src/decorator/__init__.py all pass.
  • Added a CHANGES.md entry under "Unreleased".

Disclosure: prepared with AI assistance; reviewed and verified locally.

FunctionMaker.create() raised a SyntaxError when the signature string
contained a return annotation, e.g. create('add(a: int) -> int', ...).
The parser assumed the signature always ended with ')' and stripped the
last character, then unconditionally re-appended ')' in the def line,
producing invalid source such as 'def add(a: int) -> in):'.

Split the argument list from an optional '-> ...' return annotation using
rpartition(')'), and reattach the annotation after the closing paren when
emitting the def line. Signatures without an annotation are unchanged.

Fixes micheles#138.
@micheles

micheles commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Thanks for your contribution, you must understand that the decorator module is old and predates annotations

@micheles
micheles merged commit 2322c7b into micheles:master Jul 9, 2026
8 checks passed
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.

2 participants