pyrilog


Namepyrilog JSON
Version 0.2.4 PyPI version JSON
download
home_pageNone
SummaryA Python-based SystemVerilog code generator using context managers
upload_time2025-09-09 18:02:31
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT
keywords code-generation hardware hdl systemverilog verilog
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Pyrilog

一个基于 Python 上下文管理器的 SystemVerilog 代码生成工具。使用简洁的 Python 语法生成结构化的硬件描述语言代码。

## 特性

- 🏗️ **层次化设计**: 基于上下文管理器的嵌套块结构
- 🎯 **简洁 API**: 使用 `v_` 前缀的短别名,代码更加简洁
- 🔄 **case 语句支持**: 支持单语句和多语句两种 case 语句写法
- 🧩 **模块化**: 支持参数化模块、实例化、多维数组等
- 🚀 **现代语法**: 生成 SystemVerilog `always_ff`、`always_comb` 语法

## 安装

```bash
pip install pyrilog
```

## 快速开始

### 基本模块定义

```python
from pyrilog import *

with v_gen() as gen:
    with v_module("counter"):
        # 参数定义
        v_param("WIDTH", "8")
        
        # 端口定义
        v_input("clk")
        v_input("rst_n") 
        v_input("data_in", "WIDTH")
        v_output("count", "WIDTH", None, "reg")

print(gen.generate())
```

生成的 SystemVerilog 代码:

```systemverilog
module counter #(
parameter WIDTH = 8
) (
input clk,
input rst_n,
input [WIDTH-1:0] data_in,
output reg [WIDTH-1:0] count
);
endmodule
```

### 时序逻辑 - 计数器

```python
from pyrilog import *

with v_gen() as gen:
    with v_module("counter"):
        v_param("WIDTH", "8")
        v_input("clk")
        v_input("rst_n")
        v_output("count", "WIDTH", None, "reg")
        
        # SystemVerilog always_ff 块  
        with v_always_ff("clk", "rst_n"):
            with v_if("!rst_n"):
                v_body("count <= '0;")
            with v_else():
                v_body("count <= count + 1'b1;")

with open("counter.sv", "w") as f:
    f.write(gen.generate())
```

### Case 语句 - ALU 设计

Pyrilog 支持两种 case 语句写法:

#### 1. 单语句模式

```python
from pyrilog import *

with v_gen() as gen:
    with v_module("simple_alu"):
        v_input("opcode", 3)
        v_input("a", 8)
        v_input("b", 8) 
        v_output("result", 8, None, "reg")
        
        with v_always_comb():
            with v_case("opcode"):
                v_case_item("3'b000", "result = a + b;")
                v_case_item("3'b001", "result = a - b;")
                v_case_item("3'b010", "result = a & b;")
                v_case_default("result = 8'h00;")

print(gen.generate())
```

#### 2. 多语句模式(使用上下文管理器)

```python
from pyrilog import *

with v_gen() as gen:
    with v_module("complex_alu"):
        v_input("clk")
        v_input("rst_n")
        v_input("opcode", 4)
        v_input("a", 16)
        v_input("b", 16)
        v_output("result", 16, None, "reg")
        v_output("valid", 1, None, "reg")
        v_output("overflow", 1, None, "reg")
        
        with v_always_ff("clk", "rst_n"):
            with v_if("!rst_n"):
                v_body("result <= 16'h0000;")
                v_body("valid <= 1'b0;")
                v_body("overflow <= 1'b0;")
            with v_else():
                with v_case("opcode"):
                    # 单语句 case
                    v_case_item("4'b0000", "result <= a + b;")
                    v_case_item("4'b0001", "result <= a - b;")
                    
                    # 多语句 case,使用 with 上下文管理器
                    with v_case_item("4'b0010"):  # 位与运算,带有效信号
                        v_body("result <= a & b;")
                        v_body("valid <= 1'b1;")
                        v_body("overflow <= 1'b0;")
                    
                    with v_case_item("4'b0011"):  # 位或运算,带溢出检测
                        v_body("result <= a | b;")
                        v_body("valid <= 1'b1;")
                        v_body("overflow <= (a[15] | b[15]) & !result[15];")
                    
                    # 默认情况
                    v_case_default("result <= 16'h0000;")
                
                v_body("valid <= 1'b1;")  # case 外的公共语句

print(gen.generate())
```

生成的 SystemVerilog 代码:

```systemverilog
module complex_alu (
input clk,
input rst_n,
input [3:0] opcode,
input [15:0] a,
input [15:0] b,
output reg [15:0] result,
output reg valid,
output reg overflow
);
always_ff @(posedge clk, negedge rst_n) begin
if (!rst_n) begin
result <= 16'h0000;
valid <= 1'b0;
overflow <= 1'b0;
end
else begin
case (opcode)
4'b0000: result <= a + b;
4'b0001: result <= a - b;
4'b0010: begin
result <= a & b;
valid <= 1'b1;
overflow <= 1'b0;
end
4'b0011: begin
result <= a | b;
valid <= 1'b1;
overflow <= (a[15] | b[15]) & !result[15];
end
default: result <= 16'h0000;
endcase
valid <= 1'b1;
end
end
endmodule
```

### 多维数组支持

```python
from pyrilog import *

with v_gen() as gen:
    with v_module("memory_array"):
        v_input("clk")
        v_input("addr", 8)
        v_input("wr_data", 32)
        v_output("rd_data", 32, None, "reg")
        
        # 创建二维内存数组:32位宽,256x4 的数组
        v_reg("memory", 32, [256, 4])
        
        # 一维数组:32位宽,16个元素
        v_wire("buffer", 32, 16)

print(gen.generate())
```

### 模块实例化

```python
from pyrilog import *

with v_gen() as gen:
    with v_module("cpu_top"):
        v_input("clk")
        v_input("rst_n")
        v_input("instruction", 32)
        v_output("result", 32, None, "wire")
        
        # 实例化 ALU 模块(完整参数)
        v_inst("complex_alu", "alu_inst", 
               {"WIDTH": "32"},  # 参数
               {                 # 端口连接
                   "clk": "clk",
                   "rst_n": "rst_n", 
                   "opcode": "instruction[3:0]",
                   "a": "instruction[31:16]",
                   "b": "instruction[15:4]",
                   "result": "result"
               })
        
        # 简化实例化(利用默认参数)
        v_inst("simple_counter", "cnt_inst")  # 无参数、无端口连接
        
        # 部分参数实例化
        v_inst("timer", "timer_inst", ports={"clk": "clk", "rst_n": "rst_n"})

print(gen.generate())
```

## API 参考

### 核心块结构
- `v_gen()`: 顶层生成器
- `v_module(name)`: 模块定义
- `v_always_ff(clk, rst=None)`: always_ff 时序逻辑块  
- `v_always_comb()`: always_comb 组合逻辑块
- `v_if(condition)`: 条件语句
- `v_else()`: else 语句
- `v_case(expression)`: case 语句

### Case 语句
- `v_case_item(value, statement=None)`: case 项
  - 单语句:`v_case_item("3'b001", "result = a + b;")`
  - 多语句:`with v_case_item("3'b001"): ...`
- `v_case_default(statement=None)`: 默认 case

### 端口和变量
- `v_input(name, width=1, dimensions=None, var_type="")`: 输入端口
- `v_output(name, width=1, dimensions=None, var_type="")`: 输出端口  
- `v_inout(name, width=1, dimensions=None, var_type="")`: 双向端口
- `v_wire(name, width=1, dimensions=None)`: wire 信号
- `v_reg(name, width=1, dimensions=None)`: reg 信号

### 其他功能
- `v_param(name, value)`: 参数定义
- `v_assign(lhs, rhs)`: assign 语句
- `v_inst(module_name, inst_name, params, ports)`: 模块实例化
- `v_body(code)`: 添加原始代码行

## 维度格式

支持多种维度表示方法:

```python
# 位宽
v_reg("data", 8)        # [7:0] data
v_reg("data", "WIDTH")  # [WIDTH-1:0] data

# 一维数组
v_reg("mem", 8, 16)     # [7:0] mem[15:0] 
v_reg("mem", 8, [16])   # [7:0] mem[15:0]

# 多维数组  
v_reg("mem", 8, [16, 4]) # [7:0] mem[15:0][3:0]
```

## 许可证

本项目采用 MIT 许可证。详情请见 [LICENSE](LICENSE) 文件。
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pyrilog",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "code-generation, hardware, hdl, systemverilog, verilog",
    "author": null,
    "author_email": "NightWatcher <hitszzzf@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/f5/25/f16df8da7c4970bb55848b35c691b923a7cfa67aadade591007cd4044435/pyrilog-0.2.4.tar.gz",
    "platform": null,
    "description": "# Pyrilog\n\n\u4e00\u4e2a\u57fa\u4e8e Python \u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\u7684 SystemVerilog \u4ee3\u7801\u751f\u6210\u5de5\u5177\u3002\u4f7f\u7528\u7b80\u6d01\u7684 Python \u8bed\u6cd5\u751f\u6210\u7ed3\u6784\u5316\u7684\u786c\u4ef6\u63cf\u8ff0\u8bed\u8a00\u4ee3\u7801\u3002\n\n## \u7279\u6027\n\n- \ud83c\udfd7\ufe0f **\u5c42\u6b21\u5316\u8bbe\u8ba1**: \u57fa\u4e8e\u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\u7684\u5d4c\u5957\u5757\u7ed3\u6784\n- \ud83c\udfaf **\u7b80\u6d01 API**: \u4f7f\u7528 `v_` \u524d\u7f00\u7684\u77ed\u522b\u540d\uff0c\u4ee3\u7801\u66f4\u52a0\u7b80\u6d01\n- \ud83d\udd04 **case \u8bed\u53e5\u652f\u6301**: \u652f\u6301\u5355\u8bed\u53e5\u548c\u591a\u8bed\u53e5\u4e24\u79cd case \u8bed\u53e5\u5199\u6cd5\n- \ud83e\udde9 **\u6a21\u5757\u5316**: \u652f\u6301\u53c2\u6570\u5316\u6a21\u5757\u3001\u5b9e\u4f8b\u5316\u3001\u591a\u7ef4\u6570\u7ec4\u7b49\n- \ud83d\ude80 **\u73b0\u4ee3\u8bed\u6cd5**: \u751f\u6210 SystemVerilog `always_ff`\u3001`always_comb` \u8bed\u6cd5\n\n## \u5b89\u88c5\n\n```bash\npip install pyrilog\n```\n\n## \u5feb\u901f\u5f00\u59cb\n\n### \u57fa\u672c\u6a21\u5757\u5b9a\u4e49\n\n```python\nfrom pyrilog import *\n\nwith v_gen() as gen:\n    with v_module(\"counter\"):\n        # \u53c2\u6570\u5b9a\u4e49\n        v_param(\"WIDTH\", \"8\")\n        \n        # \u7aef\u53e3\u5b9a\u4e49\n        v_input(\"clk\")\n        v_input(\"rst_n\") \n        v_input(\"data_in\", \"WIDTH\")\n        v_output(\"count\", \"WIDTH\", None, \"reg\")\n\nprint(gen.generate())\n```\n\n\u751f\u6210\u7684 SystemVerilog \u4ee3\u7801\uff1a\n\n```systemverilog\nmodule counter #(\nparameter WIDTH = 8\n) (\ninput clk,\ninput rst_n,\ninput [WIDTH-1:0] data_in,\noutput reg [WIDTH-1:0] count\n);\nendmodule\n```\n\n### \u65f6\u5e8f\u903b\u8f91 - \u8ba1\u6570\u5668\n\n```python\nfrom pyrilog import *\n\nwith v_gen() as gen:\n    with v_module(\"counter\"):\n        v_param(\"WIDTH\", \"8\")\n        v_input(\"clk\")\n        v_input(\"rst_n\")\n        v_output(\"count\", \"WIDTH\", None, \"reg\")\n        \n        # SystemVerilog always_ff \u5757  \n        with v_always_ff(\"clk\", \"rst_n\"):\n            with v_if(\"!rst_n\"):\n                v_body(\"count <= '0;\")\n            with v_else():\n                v_body(\"count <= count + 1'b1;\")\n\nwith open(\"counter.sv\", \"w\") as f:\n    f.write(gen.generate())\n```\n\n### Case \u8bed\u53e5 - ALU \u8bbe\u8ba1\n\nPyrilog \u652f\u6301\u4e24\u79cd case \u8bed\u53e5\u5199\u6cd5\uff1a\n\n#### 1. \u5355\u8bed\u53e5\u6a21\u5f0f\n\n```python\nfrom pyrilog import *\n\nwith v_gen() as gen:\n    with v_module(\"simple_alu\"):\n        v_input(\"opcode\", 3)\n        v_input(\"a\", 8)\n        v_input(\"b\", 8) \n        v_output(\"result\", 8, None, \"reg\")\n        \n        with v_always_comb():\n            with v_case(\"opcode\"):\n                v_case_item(\"3'b000\", \"result = a + b;\")\n                v_case_item(\"3'b001\", \"result = a - b;\")\n                v_case_item(\"3'b010\", \"result = a & b;\")\n                v_case_default(\"result = 8'h00;\")\n\nprint(gen.generate())\n```\n\n#### 2. \u591a\u8bed\u53e5\u6a21\u5f0f\uff08\u4f7f\u7528\u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\uff09\n\n```python\nfrom pyrilog import *\n\nwith v_gen() as gen:\n    with v_module(\"complex_alu\"):\n        v_input(\"clk\")\n        v_input(\"rst_n\")\n        v_input(\"opcode\", 4)\n        v_input(\"a\", 16)\n        v_input(\"b\", 16)\n        v_output(\"result\", 16, None, \"reg\")\n        v_output(\"valid\", 1, None, \"reg\")\n        v_output(\"overflow\", 1, None, \"reg\")\n        \n        with v_always_ff(\"clk\", \"rst_n\"):\n            with v_if(\"!rst_n\"):\n                v_body(\"result <= 16'h0000;\")\n                v_body(\"valid <= 1'b0;\")\n                v_body(\"overflow <= 1'b0;\")\n            with v_else():\n                with v_case(\"opcode\"):\n                    # \u5355\u8bed\u53e5 case\n                    v_case_item(\"4'b0000\", \"result <= a + b;\")\n                    v_case_item(\"4'b0001\", \"result <= a - b;\")\n                    \n                    # \u591a\u8bed\u53e5 case\uff0c\u4f7f\u7528 with \u4e0a\u4e0b\u6587\u7ba1\u7406\u5668\n                    with v_case_item(\"4'b0010\"):  # \u4f4d\u4e0e\u8fd0\u7b97\uff0c\u5e26\u6709\u6548\u4fe1\u53f7\n                        v_body(\"result <= a & b;\")\n                        v_body(\"valid <= 1'b1;\")\n                        v_body(\"overflow <= 1'b0;\")\n                    \n                    with v_case_item(\"4'b0011\"):  # \u4f4d\u6216\u8fd0\u7b97\uff0c\u5e26\u6ea2\u51fa\u68c0\u6d4b\n                        v_body(\"result <= a | b;\")\n                        v_body(\"valid <= 1'b1;\")\n                        v_body(\"overflow <= (a[15] | b[15]) & !result[15];\")\n                    \n                    # \u9ed8\u8ba4\u60c5\u51b5\n                    v_case_default(\"result <= 16'h0000;\")\n                \n                v_body(\"valid <= 1'b1;\")  # case \u5916\u7684\u516c\u5171\u8bed\u53e5\n\nprint(gen.generate())\n```\n\n\u751f\u6210\u7684 SystemVerilog \u4ee3\u7801\uff1a\n\n```systemverilog\nmodule complex_alu (\ninput clk,\ninput rst_n,\ninput [3:0] opcode,\ninput [15:0] a,\ninput [15:0] b,\noutput reg [15:0] result,\noutput reg valid,\noutput reg overflow\n);\nalways_ff @(posedge clk, negedge rst_n) begin\nif (!rst_n) begin\nresult <= 16'h0000;\nvalid <= 1'b0;\noverflow <= 1'b0;\nend\nelse begin\ncase (opcode)\n4'b0000: result <= a + b;\n4'b0001: result <= a - b;\n4'b0010: begin\nresult <= a & b;\nvalid <= 1'b1;\noverflow <= 1'b0;\nend\n4'b0011: begin\nresult <= a | b;\nvalid <= 1'b1;\noverflow <= (a[15] | b[15]) & !result[15];\nend\ndefault: result <= 16'h0000;\nendcase\nvalid <= 1'b1;\nend\nend\nendmodule\n```\n\n### \u591a\u7ef4\u6570\u7ec4\u652f\u6301\n\n```python\nfrom pyrilog import *\n\nwith v_gen() as gen:\n    with v_module(\"memory_array\"):\n        v_input(\"clk\")\n        v_input(\"addr\", 8)\n        v_input(\"wr_data\", 32)\n        v_output(\"rd_data\", 32, None, \"reg\")\n        \n        # \u521b\u5efa\u4e8c\u7ef4\u5185\u5b58\u6570\u7ec4\uff1a32\u4f4d\u5bbd\uff0c256x4 \u7684\u6570\u7ec4\n        v_reg(\"memory\", 32, [256, 4])\n        \n        # \u4e00\u7ef4\u6570\u7ec4\uff1a32\u4f4d\u5bbd\uff0c16\u4e2a\u5143\u7d20\n        v_wire(\"buffer\", 32, 16)\n\nprint(gen.generate())\n```\n\n### \u6a21\u5757\u5b9e\u4f8b\u5316\n\n```python\nfrom pyrilog import *\n\nwith v_gen() as gen:\n    with v_module(\"cpu_top\"):\n        v_input(\"clk\")\n        v_input(\"rst_n\")\n        v_input(\"instruction\", 32)\n        v_output(\"result\", 32, None, \"wire\")\n        \n        # \u5b9e\u4f8b\u5316 ALU \u6a21\u5757\uff08\u5b8c\u6574\u53c2\u6570\uff09\n        v_inst(\"complex_alu\", \"alu_inst\", \n               {\"WIDTH\": \"32\"},  # \u53c2\u6570\n               {                 # \u7aef\u53e3\u8fde\u63a5\n                   \"clk\": \"clk\",\n                   \"rst_n\": \"rst_n\", \n                   \"opcode\": \"instruction[3:0]\",\n                   \"a\": \"instruction[31:16]\",\n                   \"b\": \"instruction[15:4]\",\n                   \"result\": \"result\"\n               })\n        \n        # \u7b80\u5316\u5b9e\u4f8b\u5316\uff08\u5229\u7528\u9ed8\u8ba4\u53c2\u6570\uff09\n        v_inst(\"simple_counter\", \"cnt_inst\")  # \u65e0\u53c2\u6570\u3001\u65e0\u7aef\u53e3\u8fde\u63a5\n        \n        # \u90e8\u5206\u53c2\u6570\u5b9e\u4f8b\u5316\n        v_inst(\"timer\", \"timer_inst\", ports={\"clk\": \"clk\", \"rst_n\": \"rst_n\"})\n\nprint(gen.generate())\n```\n\n## API \u53c2\u8003\n\n### \u6838\u5fc3\u5757\u7ed3\u6784\n- `v_gen()`: \u9876\u5c42\u751f\u6210\u5668\n- `v_module(name)`: \u6a21\u5757\u5b9a\u4e49\n- `v_always_ff(clk, rst=None)`: always_ff \u65f6\u5e8f\u903b\u8f91\u5757  \n- `v_always_comb()`: always_comb \u7ec4\u5408\u903b\u8f91\u5757\n- `v_if(condition)`: \u6761\u4ef6\u8bed\u53e5\n- `v_else()`: else \u8bed\u53e5\n- `v_case(expression)`: case \u8bed\u53e5\n\n### Case \u8bed\u53e5\n- `v_case_item(value, statement=None)`: case \u9879\n  - \u5355\u8bed\u53e5\uff1a`v_case_item(\"3'b001\", \"result = a + b;\")`\n  - \u591a\u8bed\u53e5\uff1a`with v_case_item(\"3'b001\"): ...`\n- `v_case_default(statement=None)`: \u9ed8\u8ba4 case\n\n### \u7aef\u53e3\u548c\u53d8\u91cf\n- `v_input(name, width=1, dimensions=None, var_type=\"\")`: \u8f93\u5165\u7aef\u53e3\n- `v_output(name, width=1, dimensions=None, var_type=\"\")`: \u8f93\u51fa\u7aef\u53e3  \n- `v_inout(name, width=1, dimensions=None, var_type=\"\")`: \u53cc\u5411\u7aef\u53e3\n- `v_wire(name, width=1, dimensions=None)`: wire \u4fe1\u53f7\n- `v_reg(name, width=1, dimensions=None)`: reg \u4fe1\u53f7\n\n### \u5176\u4ed6\u529f\u80fd\n- `v_param(name, value)`: \u53c2\u6570\u5b9a\u4e49\n- `v_assign(lhs, rhs)`: assign \u8bed\u53e5\n- `v_inst(module_name, inst_name, params, ports)`: \u6a21\u5757\u5b9e\u4f8b\u5316\n- `v_body(code)`: \u6dfb\u52a0\u539f\u59cb\u4ee3\u7801\u884c\n\n## \u7ef4\u5ea6\u683c\u5f0f\n\n\u652f\u6301\u591a\u79cd\u7ef4\u5ea6\u8868\u793a\u65b9\u6cd5\uff1a\n\n```python\n# \u4f4d\u5bbd\nv_reg(\"data\", 8)        # [7:0] data\nv_reg(\"data\", \"WIDTH\")  # [WIDTH-1:0] data\n\n# \u4e00\u7ef4\u6570\u7ec4\nv_reg(\"mem\", 8, 16)     # [7:0] mem[15:0] \nv_reg(\"mem\", 8, [16])   # [7:0] mem[15:0]\n\n# \u591a\u7ef4\u6570\u7ec4  \nv_reg(\"mem\", 8, [16, 4]) # [7:0] mem[15:0][3:0]\n```\n\n## \u8bb8\u53ef\u8bc1\n\n\u672c\u9879\u76ee\u91c7\u7528 MIT \u8bb8\u53ef\u8bc1\u3002\u8be6\u60c5\u8bf7\u89c1 [LICENSE](LICENSE) \u6587\u4ef6\u3002",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Python-based SystemVerilog code generator using context managers",
    "version": "0.2.4",
    "project_urls": {
        "Homepage": "https://github.com/nightwatcher/pyrilog",
        "Issues": "https://github.com/nightwatcher/pyrilog/issues",
        "Repository": "https://github.com/nightwatcher/pyrilog.git"
    },
    "split_keywords": [
        "code-generation",
        " hardware",
        " hdl",
        " systemverilog",
        " verilog"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "81842b152ddc74efaaddfb4d0a587e735d34d6aadf86b5ec9cceb0e42489eb98",
                "md5": "802fc558a911606124e0a3d3a0ff8e2b",
                "sha256": "82cdb3554b9ba917dfcde191bfd3f19ecceb969a24b70a2d0d8481c79b7105f8"
            },
            "downloads": -1,
            "filename": "pyrilog-0.2.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "802fc558a911606124e0a3d3a0ff8e2b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 6917,
            "upload_time": "2025-09-09T18:02:30",
            "upload_time_iso_8601": "2025-09-09T18:02:30.347918Z",
            "url": "https://files.pythonhosted.org/packages/81/84/2b152ddc74efaaddfb4d0a587e735d34d6aadf86b5ec9cceb0e42489eb98/pyrilog-0.2.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f525f16df8da7c4970bb55848b35c691b923a7cfa67aadade591007cd4044435",
                "md5": "1d04f39bc5d0b4584474a6b778990614",
                "sha256": "37f8588865cbcf31fc478be2c9270f3729a9b8cf78245b38c9e1f735de140f70"
            },
            "downloads": -1,
            "filename": "pyrilog-0.2.4.tar.gz",
            "has_sig": false,
            "md5_digest": "1d04f39bc5d0b4584474a6b778990614",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 25394,
            "upload_time": "2025-09-09T18:02:31",
            "upload_time_iso_8601": "2025-09-09T18:02:31.957204Z",
            "url": "https://files.pythonhosted.org/packages/f5/25/f16df8da7c4970bb55848b35c691b923a7cfa67aadade591007cd4044435/pyrilog-0.2.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-09 18:02:31",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "nightwatcher",
    "github_project": "pyrilog",
    "github_not_found": true,
    "lcname": "pyrilog"
}
        
Elapsed time: 3.41663s