Я посмотрел на это из любопытства, и я думаю, что большая часть "магии" на самом деле приходит за pytest-django .
В исходном коде Django, например для CharField
нет ничего, что могло бы дать типу подсказку, что это строка. А поскольку класс наследует только от Field
, который также является родителем других нестроковых полей, знания должны быть закодированы в другом месте.
С другой стороны, копаясь в исходном коде pylint-django, я обнаружил, где это, скорее всего, происходит:
в pylint_django.transforms.fields
, несколько полей жестко закодированы аналогичным образом:
_STR_FIELDS = ('CharField', 'SlugField', 'URLField', 'TextField', 'EmailField',
'CommaSeparatedIntegerField', 'FilePathField', 'GenericIPAddressField',
'IPAddressField', 'RegexField', 'SlugField')
Далее, функция с подозрительным именем apply_type_shim
добавляет информацию в класс в зависимости от типа поля, в котором она находится (str, int, dict, list). и т. д.)
Эта дополнительная информация передается в inference_tip
, который согласно астрологическим документам , используется для добавления информации о логическом выводе (выделено мной):
Astroid можно использовать как библиотеку AST, он также предлагает некоторые
Основная поддержка логического вывода, это может сделать вывод, что имена могут означать в
учитывая контекст, это может быть использовано для решения атрибутов в очень сложных
иерархия классов и т. д. Мы называем этот механизм в целом выводом
на протяжении всего проекта.
astroid - базовая библиотека, используемая Pylint для представления кода Python, поэтому я уверен, что именно так информация передается в Pylint. Если вы следите за тем, что происходит при импорте плагина, вы найдете этот интересный бит в pylint_django / .plugin , где он фактически импортирует transforms
, эффективно добавляя подсказку вывода в узел AST.
Я думаю, что если вы хотите добиться того же с вашими собственными классами, вы можете либо:
- Непосредственно производный от другого класса модели Django, который уже имеет связанный тип, который вы ищете.
- Создайте и зарегистрируйте эквивалентный плагин Pylint, который также будет использовать Astroid для добавления информации в класс, чтобы Pylint знал, что с ним делать.