我正在将 mypy 集成到现有的代码库上(使用 django、drf 框架)。
view.py 中的示例代码:
from rest_framework.permissions import IsAdminUser, IsAuthenticatedOrReadOnly
@api_view()
@permission_classes([IsAuthenticatedOrReadOnly | IsAdminUser])
def listAbc(request):
queryset = ...
serializer = ...
return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)
结果:
$ mypy
error: Unsupported left operand type for | ("Type[IsAuthenticatedOrReadOnly]")
Run Code Online (Sandbox Code Playgroud)
使用的插件:
$ pip list | grep stubs
django-stubs 1.2.0
djangorestframework-stubs 1.0.0
Run Code Online (Sandbox Code Playgroud)
mypy 配置文件(mypy.ini):
[mypy]
plugins =
mypy_django_plugin.main, mypy_drf_plugin.main
;ignore_missing_imports = True
files=**/*.py
[mypy-*.migrations.*]
ignore_errors = True
[mypy.plugins.django-stubs]
django_settings_module = project.settings
Run Code Online (Sandbox Code Playgroud)
使用 mypy(0.720 和 0.740)进行检查。
这里可能有什么问题?由于操作'|' mypy 无法识别,我怀疑在 mypy 评估期间未添加元类 BasePermissionMetaclass (包含操作) BasePermission。我认为只需安装 djangorestframework-stubs …
假设我有以下 Django 模型:
class Toolbox(models.Model):
name = models.CharField(max_length=255)
tools = models.ManyToManyField("Tool")
class Tool(models.Model):
class Size(models.TextChoices):
SMALL = "S"
MEDIUM = "M"
LARGE = "L"
name = models.CharField(max_length=255)
size = models.CharField(max_length=10, choices=Size.choices)
Run Code Online (Sandbox Code Playgroud)
我有一个功能可以获取每个工具箱的所有小工具。参数类型提示来自这个 SO 答案:
from django.db.models import QuerySet
def get_toolbox_to_small_tools_mappings(
toolboxes: QuerySet | list[Toolbox],
) -> dict[Toolbox, list[Tool]]:
return {toolbox: toolbox.small_tools for toolbox in toolboxes}
Run Code Online (Sandbox Code Playgroud)
这里的想法是要求该函数的用户预取该small_tools
字段,prefetch_related()
以减少数据库命中次数并加快代码速度:
toolboxes = Toolbox.objects.prefetch_related(
Prefetch(
"tools",
queryset=Tool.objects.filter(size=Tool.Size.SMALL),
to_attr="small_tools",
)
)
toolbox_to_small_tools_mappings = get_toolbox_to_small_tools_mappings(toolboxes)
Run Code Online (Sandbox Code Playgroud)
这一切都很好,但 mypy 抱怨以下错误:
错误:“工具箱”没有属性“small_tools”[属性定义]
有没有什么办法解决这一问题?
WithAnnotations[Model] …
我有一个带有多个模型的 Django 应用程序。这是我过滤对象时的自动完成
然后我为 MyPy 安装 django-stubs
pip install django-stubs
Run Code Online (Sandbox Code Playgroud)
现在我的自动完成看起来像这样
当我删除 django-stubs 时,自动完成效果很好,就像第一张图片一样
pip uninstall django-stubs
Run Code Online (Sandbox Code Playgroud)
那么,有没有办法将 django-stubs 与 Pycharm Django 自动完成功能结合使用?
我使用Pycharm Professional 2019.1和Python3.7
我尝试在提交之前配置 start mypy + django-stubs 检查。我使用预提交。当我尝试提交时,出现错误django.core.exceptions.ImproperlyConfigured:设置 POSTGRES_DB 环境变量。该变量位于 .env 文件中,我使用 django-environ 将变量从 .env 导出到 Django 配置。当然还有 .gitignore 中的 .env。所以,据我了解:预提交从它自己的虚拟环境开始,它不知道我的 .env 文件。
最重要的是,我是否正确理解了我的情况?如果我是对的,如何将变量从 .env 文件获取到预提交环境?
我的.pre-commit-config.yaml(部分)
- repo: https://github.com/pre-commit/mirrors-mypy
rev: ''
hooks:
- id: mypy
exclude: "[a-zA-Z]*/(migrations)/(.)*"
args: [--config=setup.cfg,
--no-strict-optional,
--ignore-missing-imports]
additional_dependencies: [django-stubs, django-environ]
Run Code Online (Sandbox Code Playgroud)
我的设置.cfg
[mypy]
python_version = 3.9
allow_redefinition = True
check_untyped_defs = True
ignore_missing_imports = True
incremental = True
strict_optional = True
show_traceback = True
warn_no_return = False
warn_unused_ignores = True
warn_redundant_casts = True …
Run Code Online (Sandbox Code Playgroud) 我有一个现有的 Django 项目,它使用User
扩展的自定义模型类AbstractUser
。由于各种重要原因,我们需要重新定义该email
字段,如下:
class User(AbstractUser):
...
email = models.EmailField(db_index=True, blank=True, null=True, unique=True)
...
Run Code Online (Sandbox Code Playgroud)
最近添加了通过 mypy 进行键入检查。但是,当我执行 mypy 检查时,出现以下错误:
错误:赋值中的类型不兼容(表达式的类型为“EmailField[str | int | Combinable | None, str | None]”,基类“AbstractUser”将类型定义为“EmailField[str | int | Combinable, str]”)[任务]
我怎样才能让 mypy 允许这种类型重新分配?我不想仅仅使用,# type: ignore
因为我希望使用它的类型保护。
对于上下文,如果我确实使用# type: ignore
,那么我会从我的代码库中得到数十个以下 mypy 错误的实例:
错误:无法确定“电子邮件”的类型 [has-type]
以下是我的设置的详细信息:
python version: 3.10.5
django version: 3.2.19
mypy version: 1.6.1
django-stubs[compatible-mypy] version: 4.2.6
django-stubs-ext version: 4.2.5
typing-extensions version: 4.8.0
Run Code Online (Sandbox Code Playgroud) 假设我们有以下模型:
class Site(models.Model):
# This is djangos build-in Site Model
pass
class Organization(models.Model):
site = models.OneToOneField(Site)
Run Code Online (Sandbox Code Playgroud)
如果我在其他班级的某个地方使用它:
organization = self.site.organization
Run Code Online (Sandbox Code Playgroud)
然后 mypy 抱怨道:
Site has no attribute "organization"
Run Code Online (Sandbox Code Playgroud)
我怎样才能让mypy在这里开心?
我最近开始使用 mypy,并遇到了一些奇怪的问题,我似乎一生都无法弄清楚。
我正在使用 mypy 0.950、django-stubs 1.11.0、django 4.0.5 和 python 3.10.2。
通过命令行运行 mypy 将返回以下内容:
project/suppliers/models.py:6: error: Name "Optional" is not defined
project/suppliers/models.py:6: note: Did you forget to import it from "typing"? (Suggestion: "from typing import Optional")
project/users/models.py:6: error: Name "Optional" is not defined
project/users/models.py:6: note: Did you forget to import it from "typing"? (Suggestion: "from typing import Optional")
project/products/models.py:6: error: Name "Optional" is not defined
project/products/models.py:6: note: Did you forget to import it from "typing"? (Suggestion: "from typing import Optional")(Suggestion: "from …
Run Code Online (Sandbox Code Playgroud)