标签: python-typing

指定模型中Django字段的类型(用于Pylint)

我已经创建了基于CharField的自定义Django模型域子类,但是它使用to_python来确保返回的模型对象具有更复杂的对象(有些是列表,有些是具有特定格式的字典,等等)-我正在使用MySQL因此某些PostGreSql字段类型不可用。

一切都很好,但是Pylint相信这些字段中的所有值都是字符串,因此在使用这些模型的代码上我收到很多“ unsupported-membership-test”和“ unsubscriptable-object”警告。我可以单独禁用它们,但我想让Pylint知道这些模型返回某些对象类型。类型提示无济于事,例如:

class MealPrefs(models.Model):
    user = ...foreign key...
    prefs: dict = custom_fields.DictOfListsExtendsCharField(
            default={'breakfast': ['cereal', 'toast'], 'lunch': []},
            )
Run Code Online (Sandbox Code Playgroud)

我知道某些内置的Django字段会为Pylint返回正确的类型(CharField,IntegerField),某些其他扩展已经找到了指定其类型的方法,因此Pylint很高兴(MultiSelectField),但深入研究其代码,我不知道指定返回类型的“魔术”所在的位置。

(注意:此问题与Django表单字段的INPUT:type不相关)

谢谢!

django pylint django-models python-3.x python-typing

9
推荐指数
1
解决办法
268
查看次数

os.getenv 的 Python typehint 导致下游不兼容类型错误

当用于os.getenv检索环境变量时,默认行为返回Optional[str]. 这是有问题的,因为使用这些变量的任何下游方法/函数都可能被定义为str显式接受类型。是否有可接受的用法来解决此问题或强制执行str返回类型?

getenv在in typeshed的存根文件定义中,您可以发现它的getenv返回类型可以为Optional[str]或 ,Union[str, T_]具体取决于 kwarg 的使用default

目前我能看到的四个选项是:

  1. 定义任何下游操作以接受Optional[str]类型作为参数。这感觉不太正确,因为函数/方法的结构可能不符合类型的Optional意义。即该操作没有理由将特定参数设为None
  2. 使用defaultkwarg forgetenv并提供str默认值。这似乎更正确,但要求为每次使用设置一个默认值getenv。我能看到的唯一问题是这样做可能会混淆不同环境中的测试或使用。
  3. 定义某种变量检查函数。这可能是一个函数,它接受要加载的环境变量的名称,显式返回一个字符串,并在环境变量不存在时引发错误。
  4. 显式设置返回值的类型为getenvstr。我真的不喜欢这个,因为它期望环境始终被正确配置,根据我的经验,这不是一个好的假设。

下面是一个引发 mypy 错误的示例。

import os

SOME_VAR = os.getenv("SOME_VAR")


def some_func(val: str) -> None:
    print(f"Loaded env var: {val}")


some_func(SOME_VAR)
Run Code Online (Sandbox Code Playgroud)

上面引发了 mypy 错误:

错误:“some_func”的参数 1 具有不兼容的类型“Optional[str]”;预期“str”

python mypy python-typing

9
推荐指数
1
解决办法
3859
查看次数

如何在python的类型提示系统中使用通用(高级)类型变量?

假设我想使用 mypy 编写一个泛型类,但是该类的类型参数本身就是一个泛型类型。例如:

from typing import TypeVar, Generic, Callable

A = TypeVar("A")
B = TypeVar("B")
T = TypeVar("T")


class FunctorInstance(Generic[T]):
    def __init__(self, map: Callable[[Callable[[A], B], T[A]], T[B]]):
        self._map = map

    def map(self, x: T[A], f: Callable[[A], B]) -> T[B]:
        return self._map(f, x)
Run Code Online (Sandbox Code Playgroud)

当我尝试在上面的定义中调用 mypy 时,出现错误:

$ mypy typeclasses.py 
typeclasses.py:9: error: Type variable "T" used with arguments
typeclasses.py:12: error: Type variable "T" used with arguments 
Run Code Online (Sandbox Code Playgroud)

我尝试在T TypeVar's 定义中添加约束,但未能完成这项工作。是否有可能做到这一点?

python type-hinting higher-kinded-types mypy python-typing

8
推荐指数
2
解决办法
779
查看次数

返回类实例的抽象类方法的键入提示

我在以下代码中遇到类型检查器错误,我很想了解如何解决该错误。

下面的基类有一个抽象类方法,我希望从它继承的每个子类都将实现一个decode返回子类实例的函数。

from abc import ABC, abstractmethod
from typing import TypeVar


TMetricBase = TypeVar("TMetricBase", bound="MetricBase")


class MetricBase(ABC):
    @abstractmethod
    def add(self, element: str) -> None:
        pass  # pragma: no cover

    @classmethod
    @abstractmethod
    def decode(cls, json_str: str) -> TMetricBase:
        pass  # pragma: no cover


Run Code Online (Sandbox Code Playgroud)

子类如下所示

import json
from typing import Any, Callable, List, Mapping, Optional
from something import MetricBase, TMetricBase


class DiscreteHistogramMetric(MetricBase):
    def __init__(self, histogram: Optional[Mapping[str, int]]) -> None:
        super().__init__()
        self._histogram = dict(histogram) if histogram else {}

    def add(self, element: …
Run Code Online (Sandbox Code Playgroud)

python type-hinting python-3.x python-typing

8
推荐指数
2
解决办法
4299
查看次数

具有可变数量的 str/相同类型参数的 Callable 的 Python 类型提示?

如何为所有这些可调用对象指定一种类型:

a(str)
b(str, str)
c(str, str, str)
d(str, str, str, str
Run Code Online (Sandbox Code Playgroud)

我发现我可以Callable[..., None]用一般方式指定,但如何详细指定所有参数都将是 str 而不使用丑陋的语法Union[Callable[[str], None], Callable[[str, str], None, __more_like_this__]。有其他方法可以做到吗?我可以通过使用打字来做到吗?

python python-3.x python-typing

8
推荐指数
2
解决办法
4029
查看次数

Pyright 报告的“导入无法解决”

在此处输入图片说明

我刚刚开始使用Pyright。在运行良好的文件上运行它我得到了很多错误。

这个问题类似,但指的是自己的模块。

例如Import "numpy" could not be resolved。这是什么意思,我该如何解决?

python python-typing pyright

8
推荐指数
3
解决办法
2万
查看次数

如何使用 *args 和 **kwargs 注释可调用对象?

我有一个返回函数的函数。我想找到一个合适的类型注释。但是,返回的函数具有*args*kwargs。里面是怎么注释的Callable[[Parameters???], ReturnType]

例子:

from typing import Callable
import io
import pandas as pd

def get_conversion_function(file_type: str) -> Callable[[io.BytesIO, TODO], pd.DataFrame]:
    def to_csv(bytes_, *args, **kwargs):
        return pd.read_csv(bytes_, **kwargs)
    if file_type == "csv":
        return to_csv
Run Code Online (Sandbox Code Playgroud)

python python-typing

8
推荐指数
2
解决办法
1157
查看次数

os.PathLike[Any] 与 os.PathLike[str]

我在 typeshed 中看到过这样的行:

https://github.com/python/typeshed/blob/994b69ef8f18e76689daca3947879c3d7f76173e/stdlib/_typeshed/__init__.pyi#L77

os.PathLike似乎并不通用。它不允许传递字符串。

import os
import pathlib

def test(f: os.PathLike[str]):
    print(pathlib.Path(f))


test(r"C:\Program Files")
Run Code Online (Sandbox Code Playgroud)

上面的代码片段失败了 Mypy

python type-hinting mypy python-typing python-3.9

8
推荐指数
1
解决办法
5567
查看次数

用于具有多种类型的通用可变元组/固定长度序列的 Python 类型提示

我目前正在努力向项目添加类型提示,但不知道如何做到这一点。我有一个列表列表,其中嵌套列表包含两个 int 和 float 类型的元素。嵌套列表的第一个元素始终是 int,第二个元素始终是 float。

my_list = [[1000, 5.5], [1432, 2.2], [1234, 0.3]]
Run Code Online (Sandbox Code Playgroud)

我想对它进行类型注释,以便在 for 循环或循环理解中解包内部列表以保留类型信息。我可以将内部列表更改为元组,并得到我正在寻找的内容:

def some_function(list_arg: list[tuple[int, float]]): pass

Run Code Online (Sandbox Code Playgroud)

但是,我需要内部列表是可变的。有没有一种好的方法可以对列表执行此操作?我知道像 Sequence 和 Collection 这样的抽象类不支持多种类型。

python type-hinting data-structures python-typing

8
推荐指数
1
解决办法
1136
查看次数

当它们按原样传递给另一个函数时,如何输入提示 kwargs?

假设我有一个完全类型提示的方法,仅包含关键字参数:

class A:
    def func(a: int, b: str, c: SomeIntricateTypeHint) -> OutputClass:
        ...
Run Code Online (Sandbox Code Playgroud)

现在假设我有一个函数,它接受可变关键字参数,并将它们完全传递给该方法:

def outer_func(n_repeat: int, **kwargs: ???) -> OtherOutputClass:
    a = A()
    for _ in range(n_repeat):
        a.func(**kwargs)
Run Code Online (Sandbox Code Playgroud)

这样做,我失去了 类型提示的好处func。我如何输入提示kwargs才能outer_func恢复这些好处?

对于额外的细节,就我而言,我个人不定义func. 它实际上是来自客户端对象的方法boto3。因此,我正在寻找一种动态创建类型提示的解决方案,而不必手动创建 TypedDict。

python python-typing

8
推荐指数
1
解决办法
1785
查看次数