Can I add specificity to a kwarg in a subclass’ constructor?

I am trying to get PyCharm to understand that the subclass of my base controller class only takes a specific type of widget.

Minimal example:

import tkinter as tk


class BaseWidgetController:
    def __init__(self, parent: 'tk.Widget'): # Parent is always __some__ kind of widget
        self._parent = parent


class EntryWidgetController(BaseWidgetController):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._parent: 'tk.Entry' # On this class, I want Pycharm to understand _parent is only ever an Entry (a subclass of tk.Widget), but even adding this line doesn't change its mind.

    def say_type(self) -> None:
        print(type(self._parent)) # PyCharm still thinks _parent is a tk.Widget


ew = EntryWidgetController(parent=tk.Frame())
ew.say_type()  # Obviously this works fine at runtime.

Answer

If you want to constrain the EntryWidgetController so that it only accepts tk.Entry or subclasses, the fix is rather simple – just do

class EntryWidgetController(BaseWidgetController):
    def __init__(self, parent: 'tk.Entry', **kwargs):
        super().__init__(parent=parent, **kwargs)

That way

ew = EntryWidgetController(parent=tk.Frame())

will make PyCharm complain that Expected type 'Entry', got 'Frame' instead.

Source: stackoverflow
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .