跳转到主要内容

带有标准Python迭代器接口的迭代JSON解析器

项目描述

https://github.com/ICRAR/ijson/actions/workflows/deploy-to-pypi.yml/badge.svg https://github.com/ICRAR/ijson/actions/workflows/fast-built-and-test.yml/badge.svg https://coveralls.io/repos/github/ICRAR/ijson/badge.svg?branch=master https://badge.fury.io/py/ijson.svg https://img.shields.io/pypi/pyversions/ijson.svg https://img.shields.io/pypi/dd/ijson.svg https://img.shields.io/pypi/dw/ijson.svg https://img.shields.io/pypi/dm/ijson.svg

ijson

Ijson 是一个带有标准Python迭代器接口的迭代JSON解析器。

安装

Ijson 在 PyPI 上托管,因此您应该可以通过 pip 安装它。

pip install ijson

提供了主流平台和python版本的二进制轮。这些是通过 GitHub Actions 使用 cibuildwheel 自动构建和发布的。

使用

所有的使用示例将使用描述地理对象的JSON文档。

{
  "earth": {
    "europe": [
      {"name": "Paris", "type": "city", "info": { ... }},
      {"name": "Thames", "type": "river", "info": { ... }},
      // ...
    ],
    "america": [
      {"name": "Texas", "type": "state", "info": { ... }},
      // ...
    ]
  }
}

高级接口

最常见的用法是让 ijson 从位于前缀下的JSON流中产生原生Python对象。这是使用 items 函数完成的。以下是如何处理所有欧洲城市的方法

import ijson

f = urlopen('http://.../')
objects = ijson.items(f, 'earth.europe.item')
cities = (o for o in objects if o['type'] == 'city')
for city in cities:
    do_something_with(city)

有关如何构建前缀的信息,请参阅下面的 前缀 部分。

有时,如果要迭代对象的成员而不是对象本身(例如,当对象太大时),则可能很有用。在这种情况下,可以使用 kvitems 函数。

import ijson

f = urlopen('http://.../')
european_places = ijson.kvitems(f, 'earth.europe.item')
names = (v for k, v in european_places if k == 'name')
for name in names:
    do_something_with(name)

低级接口

有时,在处理特别大的JSON有效负载时,甚至可以不构建单个Python对象,而是立即对单个事件做出反应,并产生某些结果。这是使用 parse 函数实现的。

import ijson

parser = ijson.parse(urlopen('http://.../'))
stream.write('<geo>')
for prefix, event, value in parser:
    if (prefix, event) == ('earth', 'map_key'):
        stream.write('<%s>' % value)
        continent = value
    elif prefix.endswith('.name'):
        stream.write('<object name="%s"/>' % value)
    elif (prefix, event) == ('earth.%s' % continent, 'end_map'):
        stream.write('</%s>' % continent)
stream.write('</geo>')

更基础的特性是,无需使用 basic_parse 函数计算前缀即可对单个事件做出反应。

import ijson

events = ijson.basic_parse(urlopen('http://.../'))
num_names = sum(1 for event, value in events
                if event == 'map_key' and value == 'name')

命令行

ijson 包含一个命令行工具,用于可视化上述每个例程的输出。它从标准输入读取 JSON,并将用户选择的解析方法的输出打印到标准输出。

可以通过运行 ijson.dump 模块来获取此工具。例如

$> echo '{"A": 0, "B": [1, 2, 3, 4]}' | python -m ijson.dump -m parse
#: path, name, value
--------------------
0: , start_map, None
1: , map_key, A
2: A, number, 0
3: , map_key, B
4: B, start_array, None
5: B.item, number, 1
6: B.item, number, 2
7: B.item, number, 3
8: B.item, number, 4
9: B, end_array, None
10: , end_map, None

使用 -h/--help 将显示所有可用选项。

基准测试

ijson 包含一个命令行工具,用于对包提供的不同方法进行基准测试。它提供了一些内置示例输入,试图模拟不同的场景,但更重要的是,它还支持用户提供的输入。您还可以指定要计时哪些后端、迭代次数等。

可以通过运行 ijson.benchmark 模块来获取此工具。例如

$> python -m ijson.benchmark my/json/file.json -m items -p values.item

使用 -h/--help 将显示所有可用选项。

bytes/str 支持

尽管通常不是这样运行的,但上述所有函数也直接接受 bytesstr 对象作为输入。然后它们被内部包装成文件对象,并进一步处理。这对于测试和原型设计很有用,但在实际场景中可能不是非常有用。

asyncio 支持

上述所有方法也适用于文件类似异步对象,因此可以异步迭代。换句话说,类似这样的

import asyncio
import ijson

async def run():
   f = await async_urlopen('http://..../')
   async for object in ijson.items(f, 'earth.europe.item'):
      if object['type'] == 'city':
         do_something_with(city)
asyncio.run(run())

还存在一组显式的 *_async 函数,它们提供相同的功能,但如果不传递文件类似异步对象,它们将失败。(因此,上述示例也可以使用 ijson.items_async 来编写)。事实上,在 ijson 3.0 版本中,这是访问 asyncio 支持的唯一方式。

截获事件

上面显示的四个例程在内部相互连锁:由 basic_parse 生成的元组是 parse 的输入,而 parse 的结果则是 kvitemsitems 的输入。

通常用户看不到这种交互,因为他们只关心他们调用的函数的最终输出,但有时利用这个调用链可能很有用。这可以通过将一个函数的输出(即事件的可迭代对象,通常是生成器)作为另一个函数的输入来实现,从而为用户的事件过滤或注入打开大门。

例如,如果想在完整项目解析之前跳过某些内容

import io
import ijson

parse_events = ijson.parse(io.BytesIO(b'["skip", {"a": 1}, {"b": 2}, {"c": 3}]'))
while True:
    prefix, event, value = next(parse_events)
    if value == "skip":
        break
for obj in ijson.items(parse_events, 'item'):
    print(obj)

请注意,这种拦截只适用于 basic_parse -> parseparse -> itemsparse -> kvitems 交互。

请注意,当前异步函数不支持事件拦截。

推送接口

上述所有示例都使用文件类似对象作为数据输入(无论是正常情况,还是用于 asyncio 支持),因此是“拉”接口,库根据需要读取数据。如果出于任何原因无法使用此方法,您仍然可以通过另一个接口 推送 数据:通过生成器(而不是 asyncio 协程)的协程(PEP 342)。协程有效地允许用户在任何时候向它们发送数据,一个最终的类似协程的对象接收结果。

在以下示例中,用户负责读取,而不是让库来做

import ijson

@ijson.coroutine
def print_cities():
   while True:
      obj = (yield)
      if obj['type'] != 'city':
         continue
      print(obj)

coro = ijson.items_coro(print_cities(), 'earth.europe.item')
f = urlopen('http://.../')
for chunk in iter(functools.partial(f.read, buf_size)):
   coro.send(chunk)
coro.close()

所有四个ijson迭代器都有一个工作方式是通过将数据推入的*_coro对应物。它们不是接收文件对象和选项缓冲区大小作为参数,而是接收一个单个的target参数,该参数应为一个类似协程的对象(任何实现了send方法的对象),通过该对象将结果发布。

提供协程的另一种方法是使用ijson.sendable_list来累积结果,前提是在每次解析迭代后清空列表,如下所示

import ijson

events = ijson.sendable_list()
coro = ijson.items_coro(events, 'earth.europe.item')
f = urlopen('http://.../')
for chunk in iter(functools.partial(f.read, buf_size)):
   coro.send(chunk)
   process_accumulated_events(events)
   del events[:]
coro.close()
process_accumulated_events(events)

选项

所有 ijson函数都支持额外的选项,以便用户对某些操作有更细致的控制

  • use_float选项(默认为False)控制如何将非整数值返回给用户。如果设置为True,用户将收到float()值;否则将构造Decimal值。请注意,构建float值通常更快,但另一方面,可能会有精度损失(大多数应用程序不会关心这一点),并在溢出时引发异常(例如,如果遇到1e400)。此选项还有副作用,即大于2^64(但有时为2^32,见后端)的整数数字也会由于类似的原因引发溢出错误。ijson的未来版本可能会将此选项的默认值更改为True

  • multiple_values选项(默认为False)控制是否支持多个顶级值。JSON内容应包含单个顶级值(参见JSON语法)。然而,在野外有许多包含多个顶级值的JSON文件,通常由换行符分隔。默认情况下,除非指定multiple_values=True,否则ijson将无法处理这些文件,并会引发parse error: trailing garbage错误。

  • 类似地,allow_comments选项(默认为False)控制是否允许在内容中包含C样式注释(例如,/* a comment */),这些注释不被JSON标准支持。

  • 对于接收文件对象的函数,一个额外的buf_size选项(默认为65536或64KB)指定库每次尝试读取的字节数。

  • itemskvitems函数,以及它们的所有变体,都有一个可选的map_type参数(默认为dict),用于从JSON流构建对象。这应该是一个支持项赋值的类似字典的类型。

事件

当使用较低级别的ijson.parse函数时,会生成包含前缀、事件名称和值的三个元素的元组。事件将是以下之一

  • start_mapend_map分别表示JSON对象的开始和结束。它们携带一个None作为其值。

  • start_arrayend_array分别表示JSON数组的开始和结束。它们也携带一个None作为其值。

  • map_key表示JSON对象中的一个字段的名称。其关联的值是名称本身。

  • “null”、“布尔型”、“整型”、“双精度浮点型”、“数值”和“字符串”都表示实际内容,这些内容存储在相关的值中。

前缀

前缀表示事件在JSON文档中产生的上下文。其工作方式如下:

  • 它从空字符串开始。

  • 当解析器开始解析名为“name”的JSON对象成员的内容时,将添加一个<name>部分,并在内容结束时移除。

  • 当解析器解析JSON数组的元素时,将添加一个item部分,并在数组结束时移除。

  • 部分之间由.分隔。

当使用ijson.items函数时,前缀作为选择,以确定哪些对象应该由ijson自动构建和返回。

后端

ijson通过位于ijson/backends中的后端提供实际解析的几种实现。

  • yajl2_c:使用YAJL 2.x的C扩展。这是最快的,但可能需要编译器以及安装此软件包时需要YAJL开发文件。主要平台/架构存在二进制轮分布,以便用户无需编译软件包。

  • yajl2_cffi:使用CFFI包装YAJL 2.x。

  • yajl2:使用ctypes包装YAJL 2.x,在无法使用CFFI的情况下使用。

  • yajl:废弃的YAJL 1.x + ctypes包装,用于更旧的系统。

  • python:纯Python解析器,与PyPy配合使用时很好。

您可以将特定后端导入并像使用顶级库一样使用它。

import ijson.backends.yajl2_cffi as ijson

for item in ijson.items(...):
    # ...

将顶级库作为import ijson导入使用时,将使用列表中顺序相同的第一个可用的后端,并且其名称记录在ijson.backend下。如果设置了IJSON_BACKEND环境变量,则其值优先,并用于选择默认后端。

您还可以使用ijson.get_backend函数根据名称获取特定后端。

backend = ijson.get_backend('yajl2_c')
for item in backend.items(...):
    # ...

性能技巧

按照或多或少递减的顺序,以下是您可以采取的常见操作,以确保您从ijson中获得大多数性能。

  • 确保您使用可用的最快后端。有关详细信息,请参阅后端

  • 如果您知道您的JSON数据仅包含“表现良好”的数值,请考虑启用use_float选项。有关详细信息,请参阅选项

  • 确保您以二进制数据而不是文本数据提供ijson。有关详细信息,请参阅常见问题解答 #1。

  • 尝试调整buf_size选项,因为根据您的数据源和系统,不同的值可能与默认值表现更好。有关详细信息,请参阅选项

基准测试工具应有助于尝试这些选项并观察它们对输入文件的影响。

常见问题解答

  1. :ijson是否与bytesstr值一起工作?

    :简而言之:两者都接受作为输入,输出仅为str

    所有期望文件对象(file-like object)的ijson函数应该理想情况下使用二进制模式打开的文件对象(即,其read函数返回bytes对象,而不是str对象)。然而,如果提供了文本模式的文件对象,则库会自动将字符串编码为UTF-8字节。目前,会发出一个警告(但默认情况下不可见),提醒用户关于这种自动转换。

    另一方面,ijson始终以str对象返回文本数据(JSON字符串值、对象成员名称、事件名称等),这模仿了系统json模块的行为。

  2. 问:数字是如何处理的?

    答:ijson对于整数返回int值,对于浮点数返回decimal.Decimal值。这主要是因为历史原因。从3.1版开始,有一个新的use_float选项(默认为False),可以返回float值。有关详细信息,请参阅选项部分。

  3. 问:我遇到了一个UnicodeDecodeError,或者没有消息的IncompleteJSONError

    答:此错误是由在UTF-8中无效的字节序列引起的。换句话说,给ijson的数据实际上并不是真正的UTF-8编码,或者至少编码不正确。

    根据数据来源的不同,您有多种选择

    • 如果您可以控制数据源,请修复它。

    • 如果您有拦截数据流的方式,请执行此操作,并通过“字节纠正器”传递它。例如,如果您有一个通过stdin将数据喂入您的过程的shell管道,您可以在其中添加类似... | iconv -f utf8 -t utf8 -c | ...的内容来纠正无效的字节序列。

    • 如果您完全在Python中工作,您可以使用codecs的incrementaldecoder创建一个UTF-8解码器,以宽容地将字节解码为字符串,并将这些字符串(使用类似文件类的类)馈入ijson(参见我们string_reader_async内部类以获得一些灵感)。

    将来,ijson可能会提供一些现成的方法来处理无效的UTF-8字节序列。

  4. 问:我遇到了parse error: trailing garbageAdditional data found错误。

    答:此错误表示输入包含比其要包含的顶层JSON值更多的数据。这通常是由包含多个值的JSON数据源引起的,通常通过将multiple_values=True传递给使用的ijson函数来解决。有关详细信息,请参阅选项部分。

  5. 问:后端之间有什么不同吗?

    答:除了性能外,所有后端都旨在支持相同的功能。然而,确实存在一些小的已知差异

    • yajl后端不支持multiple_values=True。它也不会对在顶层JSON对象之后找到的额外数据进行抱怨。当使用use_float=True时,它也没有正确地支持32位平台或Windows上的2^32以上的值。带前导零的数字不会报告为无效(尽管它们是无效的JSON数字)。在完整文档的末尾的不完整JSON令牌(例如,{"a": fals)不会被报告为IncompleteJSONError

    • Python后端不支持allow_comments=True。它还内部使用str对象,而不是bytes,但这是内部细节,用户不需要担心,未来可能会改变。

致谢

ijson最初由Ivan Sagalaev开发和维护,直到2016年。2019年,他移交了项目的维护和PyPI所有权。

由于Douglas Crockford发明了一种严格且易于解析的语法,ijson中的Python解析器相对简单。

YAJL库由Lloyd Hilaiel编写,是迭代解析JSON最流行和高效的方法。

ijson受到了Hatem Nassrat编写的yajl-py包装器的启发。虽然ijson几乎从yajl-py代码中借用了很少的东西,但它被用作使用ctypes与yajl集成的示例。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪一个,请了解有关安装包的更多信息。

源代码分发

ijson-3.3.0.tar.gz (60.1 kB 查看哈希值)

上传时间

构建分发

ijson-3.3.0-pp310-pypy310_pp73-win_amd64.whl (51.1 kB 查看哈希值)

上传时间 PyPy Windows x86-64

ijson-3.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (64.2 kB 查看哈希值)

上传于 PyPy manylinux: glibc 2.17+ x86-64

ijson-3.3.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl (66.8 kB 查看哈希值)

上传于 PyPy manylinux: glibc 2.17+ i686

ijson-3.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (66.0 kB 查看哈希值)

上传于 PyPy manylinux: glibc 2.17+ ARM64

ijson-3.3.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl (54.3 kB 查看哈希值)

上传于 PyPy macOS 10.9+ x86-64

ijson-3.3.0-pp39-pypy39_pp73-win_amd64.whl (51.1 kB 查看哈希值)

上传于 PyPy Windows x86-64

ijson-3.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (64.2 kB 查看哈希值)

上传于 PyPy manylinux: glibc 2.17+ x86-64

ijson-3.3.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl (66.8 kB 查看哈希值)

上传于 PyPy manylinux: glibc 2.17+ i686

ijson-3.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (66.0 kB 查看哈希值)

上传于 PyPy manylinux: glibc 2.17+ ARM64

ijson-3.3.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl (54.3 kB 查看哈希值)

上传于 PyPy macOS 10.9+ x86-64

ijson-3.3.0-pp38-pypy38_pp73-win_amd64.whl (51.2 kB 查看哈希值)

上传于 PyPy Windows x86-64

ijson-3.3.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (64.3 kB 查看哈希值)

上传于 PyPy manylinux: glibc 2.17+ x86-64

ijson-3.3.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl (66.7 kB 查看哈希值)

上传时间: PyPy manylinux: glibc 2.17+ i686

ijson-3.3.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (66.0 kB 查看哈希值)

上传时间: PyPy manylinux: glibc 2.17+ ARM64

ijson-3.3.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl (54.3 kB 查看哈希值)

上传时间: PyPy macOS 10.9+ x86-64

ijson-3.3.0-pp37-pypy37_pp73-win_amd64.whl (51.2 kB 查看哈希值)

上传时间: PyPy Windows x86-64

ijson-3.3.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (64.3 kB 查看哈希值)

上传时间: PyPy manylinux: glibc 2.17+ x86-64

ijson-3.3.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl (66.9 kB 查看哈希值)

上传时间: PyPy manylinux: glibc 2.17+ i686

ijson-3.3.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (66.0 kB 查看哈希值)

上传时间: PyPy manylinux: glibc 2.17+ ARM64

ijson-3.3.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl (54.3 kB 查看哈希值)

上传时间: PyPy macOS 10.9+ x86-64

ijson-3.3.0-cp312-cp312-win_amd64.whl (51.3 kB 查看哈希值)

上传时间: CPython 3.12 Windows x86-64

ijson-3.3.0-cp312-cp312-win32.whl (49.3 kB 查看哈希值)

上传时间: CPython 3.12 Windows x86

ijson-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl (127.9 kB 查看哈希值)

上传于 CPython 3.12 musllinux: musl 1.2+ x86-64

ijson-3.3.0-cp312-cp312-musllinux_1_2_i686.whl (121.5 kB 查看哈希值)

上传于 CPython 3.12 musllinux: musl 1.2+ i686

ijson-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl (129.6 kB 查看哈希值)

上传于 CPython 3.12 musllinux: musl 1.2+ ARM64

ijson-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (126.3 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ x86-64

ijson-3.3.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl (118.8 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ i686

ijson-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (127.4 kB 查看哈希值)

上传于 CPython 3.12 manylinux: glibc 2.17+ ARM64

ijson-3.3.0-cp312-cp312-macosx_11_0_arm64.whl (56.9 kB 查看哈希值)

上传于 CPython 3.12 macOS 11.0+ ARM64

ijson-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl (57.6 kB 查看哈希值)

上传于 CPython 3.12 macOS 10.9+ x86-64

ijson-3.3.0-cp312-cp312-macosx_10_9_universal2.whl (84.5 kB 查看哈希值)

上传于 CPython 3.12 macOS 10.9+ universal2 (ARM64, x86-64)

ijson-3.3.0-cp311-cp311-win_amd64.whl (51.0 kB 查看哈希值)

上传于 CPython 3.11 Windows x86-64

ijson-3.3.0-cp311-cp311-win32.whl (48.9 kB 查看哈希值)

上传于 CPython 3.11 Windows x86

ijson-3.3.0-cp311-cp311-musllinux_1_2_x86_64.whl (118.2 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.2+ x86-64

ijson-3.3.0-cp311-cp311-musllinux_1_2_i686.whl (116.7 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.2+ i686

ijson-3.3.0-cp311-cp311-musllinux_1_2_aarch64.whl (121.1 kB 查看哈希值)

上传于 CPython 3.11 musllinux: musl 1.2+ ARM64

ijson-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (119.2 kB 查看哈希值)

上传于 CPython 3.11 manylinux: glibc 2.17+ x86-64

ijson-3.3.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl (115.6 kB 查看哈希值)

上传于 CPython 3.11 manylinux: glibc 2.17+ i686

ijson-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (121.9 kB 查看哈希值)

上传于 CPython 3.11 manylinux: glibc 2.17+ ARM64

ijson-3.3.0-cp311-cp311-macosx_11_0_arm64.whl (57.2 kB 查看哈希值)

上传于 CPython 3.11 macOS 11.0+ ARM64

ijson-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl (57.8 kB 查看哈希值)

上传于 CPython 3.11 macOS 10.9+ x86-64

ijson-3.3.0-cp311-cp311-macosx_10_9_universal2.whl (85.0 kB 查看哈希值)

上传于 CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64)

ijson-3.3.0-cp310-cp310-win_amd64.whl (51.0 kB 查看哈希值)

上传于 CPython 3.10 Windows x86-64

ijson-3.3.0-cp310-cp310-win32.whl (48.9 kB 查看哈希值)

上传于 CPython 3.10 Windows x86

ijson-3.3.0-cp310-cp310-musllinux_1_2_x86_64.whl (114.2 kB 查看哈希值)

上传于 CPython 3.10 musllinux: musl 1.2+ x86-64

ijson-3.3.0-cp310-cp310-musllinux_1_2_i686.whl (112.6 kB 查看哈希值)

上传于 CPython 3.10 musllinux: musl 1.2+ i686

ijson-3.3.0-cp310-cp310-musllinux_1_2_aarch64.whl (116.8 kB 查看哈希值)

上传于 CPython 3.10 musllinux: musl 1.2+ ARM64

ijson-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (114.5 kB 查看哈希值)

上传于 CPython 3.10 manylinux: glibc 2.17+ x86-64

ijson-3.3.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl (110.8 kB 查看哈希值)

上传于 CPython 3.10 manylinux: glibc 2.17+ i686

ijson-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (117.2 kB 查看哈希值)

上传于 CPython 3.10 manylinux: glibc 2.17+ ARM64

ijson-3.3.0-cp310-cp310-macosx_11_0_arm64.whl (57.2 kB 查看哈希值)

上传于 CPython 3.10 macOS 11.0+ ARM64

ijson-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl (57.8 kB 查看哈希值)

上传于 CPython 3.10 macOS 10.9+ x86-64

ijson-3.3.0-cp310-cp310-macosx_10_9_universal2.whl (85.0 kB 查看哈希值)

上传于 CPython 3.10 macOS 10.9+ universal2 (ARM64, x86-64)

ijson-3.3.0-cp39-cp39-win_amd64.whl (51.0 kB 查看哈希)

上传于 CPython 3.9 Windows x86-64

ijson-3.3.0-cp39-cp39-win32.whl (49.0 kB 查看哈希)

上传于 CPython 3.9 Windows x86

ijson-3.3.0-cp39-cp39-musllinux_1_2_x86_64.whl (113.3 kB 查看哈希)

上传于 CPython 3.9 musllinux: musl 1.2+ x86-64

ijson-3.3.0-cp39-cp39-musllinux_1_2_i686.whl (111.9 kB 查看哈希)

上传于 CPython 3.9 musllinux: musl 1.2+ i686

ijson-3.3.0-cp39-cp39-musllinux_1_2_aarch64.whl (115.9 kB 查看哈希)

上传于 CPython 3.9 musllinux: musl 1.2+ ARM64

ijson-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (113.7 kB 查看哈希)

上传于 CPython 3.9 manylinux: glibc 2.17+ x86-64

ijson-3.3.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl (110.0 kB 查看哈希)

上传于 CPython 3.9 manylinux: glibc 2.17+ i686

ijson-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (116.4 kB 查看哈希)

上传于 CPython 3.9 manylinux: glibc 2.17+ ARM64

ijson-3.3.0-cp39-cp39-macosx_11_0_arm64.whl (57.2 kB 查看哈希)

上传于 CPython 3.9 macOS 11.0+ ARM64

ijson-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl (57.8 kB 查看哈希)

上传于 CPython 3.9 macOS 10.9+ x86-64

ijson-3.3.0-cp39-cp39-macosx_10_9_universal2.whl (85.1 kB 查看哈希)

上传于 CPython 3.9 macOS 10.9+ universal2 (ARM64, x86-64)

ijson-3.3.0-cp38-cp38-win_amd64.whl (51.0 kB 查看哈希)

上传于 CPython 3.8 Windows x86-64

ijson-3.3.0-cp38-cp38-win32.whl (49.0 kB 查看哈希)

上传于 CPython 3.8 Windows x86

ijson-3.3.0-cp38-cp38-musllinux_1_2_x86_64.whl (114.9 kB 查看哈希)

上传于 CPython 3.8 musllinux: musl 1.2+ x86-64

ijson-3.3.0-cp38-cp38-musllinux_1_2_i686.whl (113.6 kB 查看哈希)

上传于 CPython 3.8 musllinux: musl 1.2+ i686

ijson-3.3.0-cp38-cp38-musllinux_1_2_aarch64.whl (117.7 kB 查看哈希)

上传于 CPython 3.8 musllinux: musl 1.2+ ARM64

ijson-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (116.0 kB 查看哈希)

上传于 CPython 3.8 manylinux: glibc 2.17+ x86-64

ijson-3.3.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl (112.2 kB 查看哈希)

上传于 CPython 3.8 manylinux: glibc 2.17+ i686

ijson-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (118.3 kB 查看哈希)

上传于 CPython 3.8 manylinux: glibc 2.17+ ARM64

ijson-3.3.0-cp38-cp38-macosx_11_0_arm64.whl (57.2 kB 查看哈希)

上传于 CPython 3.8 macOS 11.0+ ARM64

ijson-3.3.0-cp38-cp38-macosx_10_9_x86_64.whl (57.8 kB 查看哈希值)

上传时间 CPython 3.8 macOS 10.9+ x86-64

ijson-3.3.0-cp38-cp38-macosx_10_9_universal2.whl (85.1 kB 查看哈希值)

上传时间 CPython 3.8 macOS 10.9+ universal2 (ARM64, x86-64)

ijson-3.3.0-cp37-cp37m-win_amd64.whl (50.9 kB 查看哈希值)

上传时间 CPython 3.7m Windows x86-64

ijson-3.3.0-cp37-cp37m-win32.whl (48.9 kB 查看哈希值)

上传时间 CPython 3.7m Windows x86

ijson-3.3.0-cp37-cp37m-musllinux_1_2_x86_64.whl (108.8 kB 查看哈希值)

上传时间 CPython 3.7m musllinux: musl 1.2+ x86-64

ijson-3.3.0-cp37-cp37m-musllinux_1_2_i686.whl (106.9 kB 查看哈希值)

上传时间 CPython 3.7m musllinux: musl 1.2+ i686

ijson-3.3.0-cp37-cp37m-musllinux_1_2_aarch64.whl (111.2 kB 查看哈希值)

上传时间 CPython 3.7m musllinux: musl 1.2+ ARM64

ijson-3.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (107.2 kB 查看哈希值)

上传时间 CPython 3.7m manylinux: glibc 2.17+ x86-64

ijson-3.3.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl (102.8 kB 查看哈希值)

上传时间 CPython 3.7m manylinux: glibc 2.17+ i686

ijson-3.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (109.2 kB 查看哈希值)

上传时间 CPython 3.7m manylinux: glibc 2.17+ ARM64

ijson-3.3.0-cp37-cp37m-macosx_10_9_x86_64.whl (57.5 kB 查看哈希值)

上传于 CPython 3.7m macOS 10.9+ x86-64

ijson-3.3.0-cp36-cp36m-win_amd64.whl (53.0 kB 查看哈希值)

上传于 CPython 3.6m Windows x86-64

ijson-3.3.0-cp36-cp36m-win32.whl (50.5 kB 查看哈希值)

上传于 CPython 3.6m Windows x86

ijson-3.3.0-cp36-cp36m-musllinux_1_2_x86_64.whl (108.8 kB 查看哈希值)

上传于 CPython 3.6m musllinux: musl 1.2+ x86-64

ijson-3.3.0-cp36-cp36m-musllinux_1_2_i686.whl (106.9 kB 查看哈希值)

上传于 CPython 3.6m musllinux: musl 1.2+ i686

ijson-3.3.0-cp36-cp36m-musllinux_1_2_aarch64.whl (111.3 kB 查看哈希值)

上传于 CPython 3.6m musllinux: musl 1.2+ ARM64

ijson-3.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (107.2 kB 查看哈希值)

上传于 CPython 3.6m manylinux: glibc 2.17+ x86-64

ijson-3.3.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl (102.8 kB 查看哈希值)

上传于 CPython 3.6m manylinux: glibc 2.17+ i686

ijson-3.3.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (109.3 kB 查看哈希值)

上传于 CPython 3.6m manylinux: glibc 2.17+ ARM64

ijson-3.3.0-cp36-cp36m-macosx_10_9_x86_64.whl (57.2 kB 查看哈希值)

上传于 CPython 3.6m macOS 10.9+ x86-64

由以下支持