It's because you didn't properly copy the function. If you take a look at the signature of types.FunctionType you'll see that it accepts 5 arguments:
class function(object)
| function(code, globals, name=None, argdefs=None, closure=None)
|
| Create a function object.
|
| code
| a code object
| globals
| the globals dictionary
| name
| a string that overrides the name from the code object
| argdefs
| a tuple that specifies the default argument values
| closure
| a tuple that supplies the bindings for free variables
You didn't pass any argdefs, so the function has no optional arguments any more. The correct way to copy the function is
types.FunctionType(f.__code__,
{},
f.__name__,
f.__defaults__,
f.__closure__
)
However, this leads to another problem: Cutting off access to globals also cuts off access to builtins. If you try to use print or open or dict or something similar in myFunction, you'll get a NameError. So the really correct way to write your decorator is this:
import builtins
import types
def noglobal(f):
return types.FunctionType(f.__code__,
{'__builtins__': builtins},
f.__name__,
f.__defaults__,
f.__closure__
)