My question is: What is happening here between jupyter and functools.wraps that produces the strangest of effects described below? How should I write my decorator "correctly" (besides the solution I show at the end) to avoid such effects?
The double_up_as_factory decorator below is meant to transform other decorator functions so that they can be used both as parameter-less decorators (e.g. @decorator) or "factories" (e.g. @decorator(...)).
from functools import partial, wraps
def _double_up_as_factory(wrapped=None, *args, __decorator_func=None, **kwargs):
if wrapped is None: # then we want a factory
return partial(__decorator_func, **kwargs)
else:
return __decorator_func(wrapped, *args, **kwargs)
def double_up_as_factory(decorator_func):
return wraps(decorator_func)(
partial(_double_up_as_factory, __decorator_func=decorator_func)
)
The above is a stripped down version of my actual function, but it works.
Below is the minimum to produce the error, but not representative of an actual use (I can post that, but don't think it's necessary).
from i2.deco import double_up_as_factory
def foo(f=None, *, x=1):
return f(x)
# This creates no problem (as long as the block below is commented out)
bar = double_up_as_factory(foo)
# Using double_up_as_factory with @ creates the problem
@double_up_as_factory
def same_foo(f=None, *, x):
return f(x)
To test, in a notebook, do:
from PACKAGE import MODULE_WHERE_YOU_PUT_THE_ABOVE_CODE as m
m.[TRY_TAB_COMPLETING]
The first time I (after a kernel restart) I get the expected auto-suggestions, but the second time I try, I get nothing.
This problem
only happens in notebooks (browser-based jupyter access with Mac Chrome); not in VSCode or PyCharm,
and only if double_up_as_factory is used the @-way,
and only on the second tab-completion.
And the plot thickens: If I copy the code for wraps from functools within the module I'm defining double_up_as_factory in:
Note: Posted on this stackoverflow question
My question is: What is happening here between jupyter and
functools.wraps
that produces the strangest of effects described below? How should I write my decorator "correctly" (besides the solution I show at the end) to avoid such effects?The
double_up_as_factory
decorator below is meant to transform other decorator functions so that they can be used both as parameter-less decorators (e.g.@decorator
) or "factories" (e.g.@decorator(...)
).The above is a stripped down version of my actual function, but it works. Below is the minimum to produce the error, but not representative of an actual use (I can post that, but don't think it's necessary).
To test, in a notebook, do:
The first time I (after a kernel restart) I get the expected auto-suggestions, but the second time I try, I get nothing.
This problem
double_up_as_factory
is used the@
-way,And the plot thickens: If I copy the code for
wraps
fromfunctools
within the module I'm definingdouble_up_as_factory
in:the problem disappears.
I'm stumped as to why such minor differences would affect jupyter's tab-completion abilities!