django-stubs icon indicating copy to clipboard operation
django-stubs copied to clipboard

Update edit.pyi

Open KalleDK opened this issue 2 years ago • 1 comments

get_form either returns a instance of the class's form_class if form_class is None else a instance of the form_class given to the method. I don't know how to make a test for it, and I don't know if overload is the answer, but this seems to make pylance happy

I have made things!

Related issues

  • Closes #920

KalleDK avatar Apr 12 '22 08:04 KalleDK

Maybe I'm misunderstanding something, but looks like using _FormT here was intentional. We use generic class to make sure that form is always of type _FormT. If some magic is done to get_form with instance of another class or get_form_class is overriden to return something different from _FormT, then assumptions in rest of code are invalid.

Suppose the following:

class MyForm(Form):
    important_attr: bool = True
    ...  # Fields are defined here

class AnotherForm(Form): ...

class MyView(FormView[MyForm]):
    def form_valid(self, form: MyForm) -> HttpResponse:
        assert form.important_attr  # No type error anyway
        return super().form_valid(form)
    def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
        return super().get_context_data(**kwargs) | {
            'form': self.get_form(AnotherForm)  # Now error is here
        }

It does typecheck but fails on runtime with AttributeError.

I think that the only way to remain type-safe here is to reject any code that uses get_form(AnotherForm) until AnotherForm is subclass of MyForm

sterliakov avatar Apr 17 '22 18:04 sterliakov