0

Let's say I have a function that has type annotations and then a variable (pointer) to that function:

def some_func(arg1: str, arg2: int = 0, arg3: str | None = None) -> List[Any]:
   # do something and return

another_func = some_func

Because py.typed packages should have all variables type-annotated than another_func should be as well, otherwise Pylance will complain and not provide autocomplete if the function is imported from an installed package.

How to deal with this? Is there an easy way to also keep the argument names? Or do I need to use Callable? And in that case, how do you handle default arguments? Because when I do something like this:

another_func: Callable[[str, int, str | None], List[Any]] = some_func
another_func("Hello")

Then I get more linting about positional arguments missing. How to deal with keyword arguments? Or to copy the function signature as type along with argument names?

geeshta
  • 31
  • 2
  • Python **doesn't have pointers**. That is not a "function pointer". That is a *function*. Python is a purely object-oriented langauge. *Everything* is an object, ints, strings, lists, tuples, functions and even classes themselves are just objects (instances of the `type` metaclass) – juanpa.arrivillaga Jan 16 '22 at 18:46
  • This should be closed probably as a duplicate of : https://stackoverflow.com/questions/61569324/type-annotation-for-callable-that-takes-kwargs – juanpa.arrivillaga Jan 16 '22 at 18:50
  • 1
    Anyway, the answer is to use a callable Protocol, and specify the exact signature in the Protocal's `__call__` method – juanpa.arrivillaga Jan 16 '22 at 18:50
  • @juanpa.arrivillaga I'm not talking pointers in C sense of the word. Of course I know Python doesn't have those. But each variable in Python is a reference (pointer) to an object in memory. When you define the first function (some_func) the annotations are inline in the func definition. But then create a new reference (another_func) to the same function that is already defined. My question was how to annotate that. So no, that is not a *function*. The object in memory is a function. some_func and another_func are references (pointers) to that object. – geeshta Jan 17 '22 at 13:43

1 Answers1

-1

I would use types.FunctionType to represent a function:

>>> import types
>>> types.FunctionType
<class 'function'>
>>>
>>> def func():
...     pass
...
>>> type(func)
<class 'function'>
>>> isinstance(func, types.FunctionType)
True
>>>

You could also use a string literal such as 'function', but it looks like you want an actual type object.

OctopuSS7
  • 465
  • 2
  • 9
  • 1
    No, this is not the correct way to annotate this. Usually, you should just use the `typing.Callable[[arg,types], return_type]`, in this case, the OP should use a callable protocol – juanpa.arrivillaga Jan 16 '22 at 18:48