最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

visual studio code - How do I get VSCode Intellisense to work with my python class factory method? - Stack Overflow

programmeradmin6浏览0评论

I have a python class factory method that I use to create a commonly implemented derived class of django.tests.TestCase and django.tests.TransactionTestCase:

from typing import Type

from django.test import TestCase, TransactionTestCase

def test_case_class_factory(base_class) -> Type[TestCase]:

    class MyDerivedTestCase(base_class):
        ...

    return MyDerivedTestCase

TracebaseTestCase: TestCase = test_case_class_factory(TestCase)
TracebaseTransactionTestCase: TransactionTestCase = test_case_class_factory(TransactionTestCase)

These classes work well. I've used them for years now, but when I inherit from either of those classes, VSCode's Intellisense and syntax highlighting has never worked, e.g.:

from DataRepo.tests.tracebase_test_case import TracebaseTestCase

class MyTests(TracebaseTestCase):

    def test_multiply(self):
        self.assertEqual(6.2, multiply(2.0, 3.1))

E.g. assertEqual is white:

I've tried a few things today in terms of type hinting, but I can't seem to figure out how to make it work. How can I make inheriting from these factory-created classes be compatible with VSCode's intellisense and syntax highlighting?

I have a python class factory method that I use to create a commonly implemented derived class of django.tests.TestCase and django.tests.TransactionTestCase:

from typing import Type

from django.test import TestCase, TransactionTestCase

def test_case_class_factory(base_class) -> Type[TestCase]:

    class MyDerivedTestCase(base_class):
        ...

    return MyDerivedTestCase

TracebaseTestCase: TestCase = test_case_class_factory(TestCase)
TracebaseTransactionTestCase: TransactionTestCase = test_case_class_factory(TransactionTestCase)

These classes work well. I've used them for years now, but when I inherit from either of those classes, VSCode's Intellisense and syntax highlighting has never worked, e.g.:

from DataRepo.tests.tracebase_test_case import TracebaseTestCase

class MyTests(TracebaseTestCase):

    def test_multiply(self):
        self.assertEqual(6.2, multiply(2.0, 3.1))

E.g. assertEqual is white:

I've tried a few things today in terms of type hinting, but I can't seem to figure out how to make it work. How can I make inheriting from these factory-created classes be compatible with VSCode's intellisense and syntax highlighting?

Share Improve this question asked Mar 16 at 19:13 hepcat72hepcat72 1,1467 silver badges29 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Ah! I did it!

Here's how I got it to work:

from typing import Type, TypeVar
from django.test import TestCase, TransactionTestCase

T = TypeVar("TBTC", TestCase, TransactionTestCase)

def test_case_class_factory(base_class: Type[T]) -> Type[T]:

    class MyDerivedTestCase(base_class):
        ...

    return MyDerivedTestCase

TracebaseTestCase = test_case_class_factory(TestCase)
TracebaseTransactionTestCase = test_case_class_factory(TransactionTestCase)

As soon as I removed the type hints from the declared variables (TracebaseTestCase and TracebaseTransactionTestCase), they went from blue to green, and the syntax highlighting started working in subsequent derived classes!

I realized that setting the factory method to output -> Type[TestCase], was static, and that I could use a TypeVar to make it dynamic. I'm not sure I totally understand all of this. For example, I don't know what the significance of the first argument to TypeVar is, but I think I learned one thing:

"TracebaseTestCase: TestCase = ..." was wrong. It was type-hinting TracebaseTestCase as an instance of TestCase, not a type/class. That's why it was highlighted blue.

And I'm not sure I understand if VSCode could know what type TracebaseTestCase is if I don't type-hint it: TracebaseTransactionTestCase = test_case_class_factory(TransactionTestCase). Can it? I.e. Can it differentiate between the presence of assertQuerySetEqual as a method of the class?

EDIT

OK. Based on this answer to a related question, I realized that mypy doesn't support dynamic typing. There might be another way for me to create these base classes in a DRY fashion, but I also realized that outside of ignoring the dynamic class definition with # type: ignore, I could define static types with type hints when I create the class variables:

from typing import Type, TypeVar
from django.test import TestCase, TransactionTestCase

T = TypeVar("TBTC", TestCase, TransactionTestCase)

def test_case_class_factory(base_class: Type[T]) -> Type[T]:

    class MyDerivedTestCase(base_class):  # type: ignore
        ...

    return MyDerivedTestCase

TracebaseTestCase: Type[TestCase] = test_case_class_factory(TestCase)
TracebaseTransactionTestCase: Type[TransactionTestCase] = test_case_class_factory(TransactionTestCase)

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论