Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python type hinting to return class in function

I have a function similar to below. I want the type hinting to return Bar but this seems to be invalid. Is there a way to do this or do i have to move the class outside the function to reference it as a return type?

def foo(i: int) -> Bar:
    class Bar:
        def __init__(i: int):
            self.i = i
    return Bar(i)
like image 478
Ajurna Avatar asked Oct 20 '16 08:10

Ajurna


1 Answers

The annotation is meaningless, because your function returns instances of a new, distinct Bar class each time it is called.

In other words, there is no one Bar class against which you can check the type. The result of type(foo(1)) is type(foo(2)) is always going to be false, so a type check against type(foo(1)) is always going to fail when you pass in foo(2) too.

If you want type checking to apply here, you'll need to declare a base class:

class BaseBar: pass

def foo(i: int) -> BaseBar:
    class Bar(BaseBar):
        def __init__(i: int):
            self.i = i
    return Bar(i)

To make this a bit more readable, the base class could just be named Bar and the function could produce a BarImpl or ConcreteBar or similar. That way you can keep using Bar in type annotations everywhere to reduce confusion.

You don't actually seem to need to create a new class each time; nothing in the class is parameterised or uses closures; if this is true for your actual code, then you could just define it outside the function:

class Bar:
    def __init__(i: int):
        self.i = i

def foo(i: int) -> Bar:
    return Bar(i)
like image 190
Martijn Pieters Avatar answered Oct 03 '22 01:10

Martijn Pieters