Skip to content

[WIP] On the way to solving hopefully #90 #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

### x.y.z - in progress

- Fixed a `KeyError` happening when `wraps` is provided with a string `new_sig`. Fixes
[#90](https://github.com/smarie/python-makefun/issues/90)

### 1.15.1 - bugfixes

- Fixed `ValueError: Invalid co_name` happening on python 2 when the name of a function to create starts or ends with
Expand Down
17 changes: 11 additions & 6 deletions src/makefun/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ def create_function(func_signature, # type: Union[str, Signature]
user_provided_name = False

# co_name default
# TODO this section should happen later, after and/or at the same time than
# the if isinstance(func_signature, X)
user_provided_co_name = co_name is not None
if not user_provided_co_name:
if func_name is None:
Expand Down Expand Up @@ -265,6 +267,9 @@ def create_function(func_signature, # type: Union[str, Signature]
# fix the signature if needed
elif func_name_from_str is None:
func_signature_str = co_name + func_signature_str
elif user_provided_co_name:
raise ValueError("Providing both a name in the signature string and a non-none `co_name` is unsupported at"
" the moment")

elif isinstance(func_signature, Signature):
# create the signature string
Expand Down Expand Up @@ -816,7 +821,7 @@ def wraps(wrapped_fun,
**attrs)`

In other words, as opposed to `@with_signature`, the metadata (doc, module name, etc.) is provided by the wrapped
`wrapped_fun`, so that the created function seems to be identical (except possiblyfor the signature).
`wrapped_fun`, so that the created function seems to be identical (except possibly for the signature).
Note that all options in `with_signature` can still be overrided using parameters of `@wraps`.

The additional `__wrapped__` attribute is set on the created function, to stay consistent
Expand Down Expand Up @@ -955,10 +960,10 @@ def _get_args_for_wrapping(wrapped, new_sig, remove_args, prepend_args, append_a
qualname = getattr_partial_aware(wrapped, '__qualname__', None)
if module_name is None:
module_name = getattr_partial_aware(wrapped, '__module__', None)
if co_name is None:
code = getattr_partial_aware(wrapped, '__code__', None)
if code is not None:
co_name = code.co_name
# if co_name is None:
# code = getattr_partial_aware(wrapped, '__code__', None)
# if code is not None:
# co_name = code.co_name

# attributes: start from the wrapped dict, add '__wrapped__' if needed, and override with all attrs.
all_attrs = copy(getattr_partial_aware(wrapped, '__dict__'))
Expand Down Expand Up @@ -1012,7 +1017,7 @@ def impl(...):
`inspect.signature` or from the `funcsigs.signature` backport. Note that these objects can be created manually
too. If the signature is provided as a string and contains a non-empty name, this name will be used instead
of the one of the decorated function. Finally `None` can be provided to indicate that user wants to only change
the medatadata (func_name, doc, module_name, attrs) of the decorated function, without generating a new
the metadata (func_name, doc, module_name, attrs) of the decorated function, without generating a new
function.
:param inject_as_first_arg: if `True`, the created function will be injected as the first positional argument of
the decorated function. This can be handy in case the implementation is shared between several facades and needs
Expand Down
16 changes: 16 additions & 0 deletions tests/test_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,19 @@ def test_issue_91():
"""This test should work also in python 2 ! """
assert is_identifier("_results_bag")
assert is_identifier("hello__bag")


def test_issue_90():
"""Test that passing a string to @wraps as new_sig works"""

def f(a):
return 2 * a

@wraps(f, new_sig="_results_bag()")
def g():
return f(2)

assert g() == 4
assert g.__name__ == "_results_bag"
assert g.__code__.co_name == "_results_bag"
assert str(signature(g)) == "()"