# PyRustor
[](https://pypi.org/project/pyrustor/)
[](https://pypi.org/project/pyrustor/)
[](https://pypi.org/project/pyrustor/)
[](LICENSE)
[](https://www.rust-lang.org)
[](https://github.com/loonghao/PyRustor/actions)
English | [δΈζ](README_zh.md)
A **blazingly fast** Python code parsing and refactoring tool written in Rust with Python bindings.
## π Features
### π **Core Advantages**
- **β‘ Superior Performance**: Built on Ruff's blazing-fast Python parser - 10-100x faster than traditional Python tools
- **π Python AST Parsing**: Parse Python code into AST for analysis using Ruff's proven parsing engine
- **π οΈ Code Refactoring**: Rename functions, classes, modernize syntax
- **π§΅ Safe Concurrency**: Built with Rust's fearless concurrency
- **π Python Bindings**: Easy-to-use Python API
### ποΈ **Refactoring Operations**
- **Function Renaming**: Rename functions throughout codebase
- **Class Renaming**: Rename classes and update references
- **Import Modernization**: Update deprecated imports to modern alternatives
- **Syntax Modernization**: Convert old Python syntax to modern patterns
- **Custom Transformations**: Apply custom AST transformations
## π Quick Start
```bash
pip install pyrustor
```
```python
import pyrustor
# Parse Python code
parser = pyrustor.Parser()
ast = parser.parse_string("def hello(): pass")
# Create refactor instance
refactor = pyrustor.Refactor(ast)
refactor.rename_function("hello", "greet")
# Get the modified code
result = refactor.get_code()
print(result) # def greet(): pass
```
### β¨ Key Features Demonstration
```python
import pyrustor
# 1. Function and Class Renaming
code = '''
def old_function(x, y):
return x + y
class OldClass:
def method(self):
return old_function(1, 2)
'''
parser = pyrustor.Parser()
ast = parser.parse_string(code)
refactor = pyrustor.Refactor(ast)
# Rename function and class
refactor.rename_function("old_function", "new_function")
refactor.rename_class("OldClass", "NewClass")
print("Refactored code:")
print(refactor.get_code())
# 2. Import Modernization
legacy_code = '''
import ConfigParser
import imp
from urllib2 import urlopen
'''
ast2 = parser.parse_string(legacy_code)
refactor2 = pyrustor.Refactor(ast2)
# Modernize imports
refactor2.replace_import("ConfigParser", "configparser")
refactor2.replace_import("imp", "importlib")
refactor2.replace_import("urllib2", "urllib.request")
print("Modernized imports:")
print(refactor2.get_code())
# 3. Get detailed change information
print("Changes made:")
for change in refactor2.change_summary():
print(f" - {change}")
```
## π¦ Installation
### From PyPI (Recommended)
```bash
# Standard installation (Python version-specific wheels)
pip install pyrustor
# ABI3 installation (compatible with Python 3.8+)
pip install pyrustor --prefer-binary
```
### Prerequisites (Building from Source)
- Rust 1.87+ (for building from source)
- Python 3.8+
- maturin (for building Python bindings)
### Build from Source
```bash
# Clone the repository
git clone https://github.com/loonghao/PyRustor.git
cd PyRustor
# Install dependencies
just install
# Build the extension
just build
```
## π§ Usage Examples
### Basic Operations
```python
import pyrustor
# Parse Python code
parser = pyrustor.Parser()
ast = parser.parse_string("""
def old_function():
return "Hello, World!"
class OldClass:
pass
""")
# Create refactor instance
refactor = pyrustor.Refactor(ast)
# Rename function
refactor.rename_function("old_function", "new_function")
# Rename class
refactor.rename_class("OldClass", "NewClass")
# Get refactored code
print(refactor.get_code())
```
### File Operations
```python
import pyrustor
# Parse from file
parser = pyrustor.Parser()
ast = parser.parse_file("example.py")
# Apply refactoring
refactor = pyrustor.Refactor(ast)
refactor.modernize_syntax()
# Save to file
refactor.save_to_file("refactored_example.py")
# Get change summary
print(refactor.change_summary())
```
### Complete Refactoring Workflow
```python
import pyrustor
def modernize_legacy_code(source_code: str) -> str:
"""Complete workflow for modernizing legacy Python code."""
parser = pyrustor.Parser()
ast = parser.parse_string(source_code)
refactor = pyrustor.Refactor(ast)
# Step 1: Modernize imports
refactor.replace_import("ConfigParser", "configparser")
refactor.replace_import("urllib2", "urllib.request")
refactor.replace_import("imp", "importlib")
# Step 2: Rename outdated functions/classes
refactor.rename_function("old_function", "new_function")
refactor.rename_class("LegacyClass", "ModernClass")
# Step 3: Apply syntax modernization
refactor.modernize_syntax()
# Step 4: Get the final result
return refactor.get_code()
# Example usage
legacy_code = '''
import ConfigParser
import urllib2
def old_function():
config = ConfigParser.ConfigParser()
response = urllib2.urlopen("http://example.com")
return response.read()
class LegacyClass:
def __init__(self):
self.data = old_function()
'''
modernized = modernize_legacy_code(legacy_code)
print("Modernized code:")
print(modernized)
# Get detailed change information
parser = pyrustor.Parser()
ast = parser.parse_string(legacy_code)
refactor = pyrustor.Refactor(ast)
refactor.replace_import("ConfigParser", "configparser")
refactor.rename_function("old_function", "new_function")
print("\nChanges made:")
for change in refactor.change_summary():
print(f" - {change}")
```
### Error Handling and Validation
```python
import pyrustor
def safe_refactor(code: str, old_name: str, new_name: str) -> tuple[str, bool]:
"""Safely refactor code with error handling."""
try:
parser = pyrustor.Parser()
ast = parser.parse_string(code)
refactor = pyrustor.Refactor(ast)
# Attempt to rename function
refactor.rename_function(old_name, new_name)
return refactor.get_code(), True
except Exception as e:
print(f"Refactoring failed: {e}")
return code, False # Return original code if refactoring fails
# Example usage
code = "def hello(): pass"
result, success = safe_refactor(code, "hello", "greet")
if success:
print("Refactoring successful:")
print(result)
else:
print("Refactoring failed, original code preserved")
```
### Advanced Refactoring
```python
import pyrustor
parser = pyrustor.Parser()
ast = parser.parse_string("""
import ConfigParser
from imp import reload
def format_string(name, age):
return "Name: %s, Age: %d" % (name, age)
""")
refactor = pyrustor.Refactor(ast)
# Modernize imports
refactor.replace_import("ConfigParser", "configparser")
refactor.replace_import("imp", "importlib")
# Modernize syntax
refactor.modernize_syntax()
print(refactor.to_string())
print("Changes made:")
print(refactor.change_summary())
```
### Ruff Formatter Integration
```python
import pyrustor
# Messy code that needs refactoring and formatting
messy_code = '''def old_function( x,y ):
return x+y
class OldClass:
def __init__(self,name):
self.name=name'''
parser = pyrustor.Parser()
ast = parser.parse_string(messy_code)
refactor = pyrustor.Refactor(ast)
# Refactor with automatic formatting
refactor.rename_function_with_format("old_function", "new_function", apply_formatting=True)
refactor.rename_class_with_format("OldClass", "NewClass", apply_formatting=True)
# Or apply formatting at the end
refactor.modernize_syntax()
formatted_result = refactor.refactor_and_format()
print("Beautifully formatted result:")
print(formatted_result)
```
### Building pyupgrade-style Tools
```python
import pyrustor
def modernize_python_code(source_code: str) -> str:
"""Build a pyupgrade-style modernization tool."""
parser = pyrustor.Parser()
ast = parser.parse_string(source_code)
refactor = pyrustor.Refactor(ast)
# Apply common modernizations
refactor.replace_import("ConfigParser", "configparser")
refactor.replace_import("urllib2", "urllib.request")
refactor.modernize_syntax() # % formatting -> f-strings, etc.
# Return beautifully formatted result
return refactor.refactor_and_format()
# Example usage
legacy_code = '''import ConfigParser
def greet(name):
return "Hello, %s!" % name'''
modernized = modernize_python_code(legacy_code)
print(modernized)
# Output: Clean, modern Python code with f-strings and updated imports
```
## π API Reference
### Parser Class
```python
parser = pyrustor.Parser()
# Parse from string
ast = parser.parse_string(source_code)
# Parse from file
ast = parser.parse_file("path/to/file.py")
# Parse directory
results = parser.parse_directory("path/to/dir", recursive=True)
```
### PythonAst Class
```python
# Check if AST is empty
if ast.is_empty():
print("No code found")
# Get statistics
print(f"Statements: {ast.statement_count()}")
print(f"Functions: {ast.function_names()}")
print(f"Classes: {ast.class_names()}")
print(f"Imports: {ast.imports()}")
# Convert back to string
source_code = ast.to_string()
```
### Refactor Class
```python
refactor = pyrustor.Refactor(ast)
# Basic refactoring
refactor.rename_function("old_name", "new_name")
refactor.rename_class("OldClass", "NewClass")
refactor.replace_import("old_module", "new_module")
# Refactoring with automatic formatting
refactor.rename_function_with_format("old_name", "new_name", apply_formatting=True)
refactor.rename_class_with_format("OldClass", "NewClass", apply_formatting=True)
refactor.modernize_syntax_with_format(apply_formatting=True)
# Advanced refactoring
refactor.modernize_syntax()
refactor.modernize_imports()
# Formatting options
refactor.format_code() # Apply Ruff formatting
formatted_result = refactor.refactor_and_format() # Refactor + format in one step
conditional_format = refactor.to_string_with_format(apply_formatting=True)
# Get results
refactored_code = refactor.to_string()
changes = refactor.change_summary()
# Save to file
refactor.save_to_file("output.py")
```
## π§ͺ Development
### Setup Development Environment
```bash
# Install just (command runner)
cargo install just
# Setup development environment
just dev
# Run tests
just test
# Format code
just format
# Run linting
just lint
# Build release
just release
```
### Testing
PyRustor has comprehensive test coverage with 257+ tests across Rust and Python components.
```bash
# Run all tests (Rust + Python)
just test
# Run specific test categories
just test-rust # 91 Rust tests
just test-python # 166 Python tests
# Run with coverage reporting
just coverage-all # Generate coverage reports for both languages
just coverage-python # Python coverage only
just coverage-rust # Rust coverage only
# Run specific test types
pytest tests/ -m "unit" # Unit tests only
pytest tests/ -m "integration" # Integration tests only
pytest tests/ -m "benchmark" # Performance benchmarks
pytest tests/ -m "not slow" # Skip slow tests
```
#### Test Categories
- **Unit Tests**: Core functionality testing
- **Integration Tests**: End-to-end workflow testing
- **Edge Case Tests**: Boundary conditions and error handling
- **Performance Tests**: Benchmarking and regression detection
- **Unicode Tests**: International character support
- **Error Handling Tests**: Robust error recovery
#### Coverage Reports
After running coverage tests, view detailed reports:
- **Python**: `htmlcov/index.html`
- **Rust**: `target/tarpaulin/tarpaulin-report.html`
### Quality Assurance
```bash
# Run all quality checks
just check-all
# Individual quality checks
just quality # Code quality analysis
just security # Security vulnerability scanning
just performance # Performance benchmarking
just docs-check # Documentation validation
# CI-specific checks
just ci-check-all # All checks optimized for CI
```
### Available Commands
```bash
just --list # Show all available commands
```
## π€ Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request
## π License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## π Acknowledgments
- [**Ruff**](https://github.com/astral-sh/ruff) - PyRustor is built on Ruff's high-performance Python AST parsing engine (`ruff_python_ast`). Ruff is an extremely fast Python linter and code formatter written in Rust, developed by [Astral](https://astral.sh). We leverage Ruff's proven parsing technology to deliver blazing-fast Python code analysis and refactoring capabilities.
- [PyO3](https://github.com/PyO3/pyo3) for excellent Python-Rust bindings
- [maturin](https://github.com/PyO3/maturin) for seamless Python package building
Raw data
{
"_id": null,
"home_page": "https://github.com/loonghao/PyRustor",
"name": "pyrustor",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "python, parser, refactoring, ast, code-analysis, rust",
"author": null,
"author_email": "Hal <hal.long@outlook.com>",
"download_url": "https://files.pythonhosted.org/packages/e7/77/1f6debd673c0906dd1c4fccdb5f5a47186ff87417396d7b233e6afa63133/pyrustor-0.1.19.tar.gz",
"platform": null,
"description": "# PyRustor\n\n[](https://pypi.org/project/pyrustor/)\n[](https://pypi.org/project/pyrustor/)\n[](https://pypi.org/project/pyrustor/)\n[](LICENSE)\n[](https://www.rust-lang.org)\n[](https://github.com/loonghao/PyRustor/actions)\n\nEnglish | [\u4e2d\u6587](README_zh.md)\n\nA **blazingly fast** Python code parsing and refactoring tool written in Rust with Python bindings.\n\n## \ud83d\ude80 Features\n\n### \ud83c\udf1f **Core Advantages**\n\n- **\u26a1 Superior Performance**: Built on Ruff's blazing-fast Python parser - 10-100x faster than traditional Python tools\n- **\ud83d\udd04 Python AST Parsing**: Parse Python code into AST for analysis using Ruff's proven parsing engine\n- **\ud83d\udee0\ufe0f Code Refactoring**: Rename functions, classes, modernize syntax\n- **\ud83e\uddf5 Safe Concurrency**: Built with Rust's fearless concurrency\n- **\ud83d\udc0d Python Bindings**: Easy-to-use Python API\n\n### \ud83c\udf9b\ufe0f **Refactoring Operations**\n\n- **Function Renaming**: Rename functions throughout codebase\n- **Class Renaming**: Rename classes and update references\n- **Import Modernization**: Update deprecated imports to modern alternatives\n- **Syntax Modernization**: Convert old Python syntax to modern patterns\n- **Custom Transformations**: Apply custom AST transformations\n\n## \ud83d\ude80 Quick Start\n\n```bash\npip install pyrustor\n```\n\n```python\nimport pyrustor\n\n# Parse Python code\nparser = pyrustor.Parser()\nast = parser.parse_string(\"def hello(): pass\")\n\n# Create refactor instance\nrefactor = pyrustor.Refactor(ast)\nrefactor.rename_function(\"hello\", \"greet\")\n\n# Get the modified code\nresult = refactor.get_code()\nprint(result) # def greet(): pass\n```\n\n### \u2728 Key Features Demonstration\n\n```python\nimport pyrustor\n\n# 1. Function and Class Renaming\ncode = '''\ndef old_function(x, y):\n return x + y\n\nclass OldClass:\n def method(self):\n return old_function(1, 2)\n'''\n\nparser = pyrustor.Parser()\nast = parser.parse_string(code)\nrefactor = pyrustor.Refactor(ast)\n\n# Rename function and class\nrefactor.rename_function(\"old_function\", \"new_function\")\nrefactor.rename_class(\"OldClass\", \"NewClass\")\n\nprint(\"Refactored code:\")\nprint(refactor.get_code())\n\n# 2. Import Modernization\nlegacy_code = '''\nimport ConfigParser\nimport imp\nfrom urllib2 import urlopen\n'''\n\nast2 = parser.parse_string(legacy_code)\nrefactor2 = pyrustor.Refactor(ast2)\n\n# Modernize imports\nrefactor2.replace_import(\"ConfigParser\", \"configparser\")\nrefactor2.replace_import(\"imp\", \"importlib\")\nrefactor2.replace_import(\"urllib2\", \"urllib.request\")\n\nprint(\"Modernized imports:\")\nprint(refactor2.get_code())\n\n# 3. Get detailed change information\nprint(\"Changes made:\")\nfor change in refactor2.change_summary():\n print(f\" - {change}\")\n```\n\n## \ud83d\udce6 Installation\n\n### From PyPI (Recommended)\n\n```bash\n# Standard installation (Python version-specific wheels)\npip install pyrustor\n\n# ABI3 installation (compatible with Python 3.8+)\npip install pyrustor --prefer-binary\n```\n\n### Prerequisites (Building from Source)\n\n- Rust 1.87+ (for building from source)\n- Python 3.8+\n- maturin (for building Python bindings)\n\n### Build from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/loonghao/PyRustor.git\ncd PyRustor\n\n# Install dependencies\njust install\n\n# Build the extension\njust build\n```\n\n## \ud83d\udd27 Usage Examples\n\n### Basic Operations\n\n```python\nimport pyrustor\n\n# Parse Python code\nparser = pyrustor.Parser()\nast = parser.parse_string(\"\"\"\ndef old_function():\n return \"Hello, World!\"\n\nclass OldClass:\n pass\n\"\"\")\n\n# Create refactor instance\nrefactor = pyrustor.Refactor(ast)\n\n# Rename function\nrefactor.rename_function(\"old_function\", \"new_function\")\n\n# Rename class\nrefactor.rename_class(\"OldClass\", \"NewClass\")\n\n# Get refactored code\nprint(refactor.get_code())\n```\n\n### File Operations\n\n```python\nimport pyrustor\n\n# Parse from file\nparser = pyrustor.Parser()\nast = parser.parse_file(\"example.py\")\n\n# Apply refactoring\nrefactor = pyrustor.Refactor(ast)\nrefactor.modernize_syntax()\n\n# Save to file\nrefactor.save_to_file(\"refactored_example.py\")\n\n# Get change summary\nprint(refactor.change_summary())\n```\n\n### Complete Refactoring Workflow\n\n```python\nimport pyrustor\n\ndef modernize_legacy_code(source_code: str) -> str:\n \"\"\"Complete workflow for modernizing legacy Python code.\"\"\"\n parser = pyrustor.Parser()\n ast = parser.parse_string(source_code)\n refactor = pyrustor.Refactor(ast)\n\n # Step 1: Modernize imports\n refactor.replace_import(\"ConfigParser\", \"configparser\")\n refactor.replace_import(\"urllib2\", \"urllib.request\")\n refactor.replace_import(\"imp\", \"importlib\")\n\n # Step 2: Rename outdated functions/classes\n refactor.rename_function(\"old_function\", \"new_function\")\n refactor.rename_class(\"LegacyClass\", \"ModernClass\")\n\n # Step 3: Apply syntax modernization\n refactor.modernize_syntax()\n\n # Step 4: Get the final result\n return refactor.get_code()\n\n# Example usage\nlegacy_code = '''\nimport ConfigParser\nimport urllib2\n\ndef old_function():\n config = ConfigParser.ConfigParser()\n response = urllib2.urlopen(\"http://example.com\")\n return response.read()\n\nclass LegacyClass:\n def __init__(self):\n self.data = old_function()\n'''\n\nmodernized = modernize_legacy_code(legacy_code)\nprint(\"Modernized code:\")\nprint(modernized)\n\n# Get detailed change information\nparser = pyrustor.Parser()\nast = parser.parse_string(legacy_code)\nrefactor = pyrustor.Refactor(ast)\nrefactor.replace_import(\"ConfigParser\", \"configparser\")\nrefactor.rename_function(\"old_function\", \"new_function\")\n\nprint(\"\\nChanges made:\")\nfor change in refactor.change_summary():\n print(f\" - {change}\")\n```\n\n### Error Handling and Validation\n\n```python\nimport pyrustor\n\ndef safe_refactor(code: str, old_name: str, new_name: str) -> tuple[str, bool]:\n \"\"\"Safely refactor code with error handling.\"\"\"\n try:\n parser = pyrustor.Parser()\n ast = parser.parse_string(code)\n refactor = pyrustor.Refactor(ast)\n\n # Attempt to rename function\n refactor.rename_function(old_name, new_name)\n\n return refactor.get_code(), True\n\n except Exception as e:\n print(f\"Refactoring failed: {e}\")\n return code, False # Return original code if refactoring fails\n\n# Example usage\ncode = \"def hello(): pass\"\nresult, success = safe_refactor(code, \"hello\", \"greet\")\n\nif success:\n print(\"Refactoring successful:\")\n print(result)\nelse:\n print(\"Refactoring failed, original code preserved\")\n```\n\n### Advanced Refactoring\n\n```python\nimport pyrustor\n\nparser = pyrustor.Parser()\nast = parser.parse_string(\"\"\"\nimport ConfigParser\nfrom imp import reload\n\ndef format_string(name, age):\n return \"Name: %s, Age: %d\" % (name, age)\n\"\"\")\n\nrefactor = pyrustor.Refactor(ast)\n\n# Modernize imports\nrefactor.replace_import(\"ConfigParser\", \"configparser\")\nrefactor.replace_import(\"imp\", \"importlib\")\n\n# Modernize syntax\nrefactor.modernize_syntax()\n\nprint(refactor.to_string())\nprint(\"Changes made:\")\nprint(refactor.change_summary())\n```\n\n### Ruff Formatter Integration\n\n```python\nimport pyrustor\n\n# Messy code that needs refactoring and formatting\nmessy_code = '''def old_function( x,y ):\n return x+y\n\nclass OldClass:\n def __init__(self,name):\n self.name=name'''\n\nparser = pyrustor.Parser()\nast = parser.parse_string(messy_code)\nrefactor = pyrustor.Refactor(ast)\n\n# Refactor with automatic formatting\nrefactor.rename_function_with_format(\"old_function\", \"new_function\", apply_formatting=True)\nrefactor.rename_class_with_format(\"OldClass\", \"NewClass\", apply_formatting=True)\n\n# Or apply formatting at the end\nrefactor.modernize_syntax()\nformatted_result = refactor.refactor_and_format()\n\nprint(\"Beautifully formatted result:\")\nprint(formatted_result)\n```\n\n### Building pyupgrade-style Tools\n\n```python\nimport pyrustor\n\ndef modernize_python_code(source_code: str) -> str:\n \"\"\"Build a pyupgrade-style modernization tool.\"\"\"\n parser = pyrustor.Parser()\n ast = parser.parse_string(source_code)\n refactor = pyrustor.Refactor(ast)\n\n # Apply common modernizations\n refactor.replace_import(\"ConfigParser\", \"configparser\")\n refactor.replace_import(\"urllib2\", \"urllib.request\")\n refactor.modernize_syntax() # % formatting -> f-strings, etc.\n\n # Return beautifully formatted result\n return refactor.refactor_and_format()\n\n# Example usage\nlegacy_code = '''import ConfigParser\ndef greet(name):\n return \"Hello, %s!\" % name'''\n\nmodernized = modernize_python_code(legacy_code)\nprint(modernized)\n# Output: Clean, modern Python code with f-strings and updated imports\n```\n\n## \ud83d\udcda API Reference\n\n### Parser Class\n\n```python\nparser = pyrustor.Parser()\n\n# Parse from string\nast = parser.parse_string(source_code)\n\n# Parse from file\nast = parser.parse_file(\"path/to/file.py\")\n\n# Parse directory\nresults = parser.parse_directory(\"path/to/dir\", recursive=True)\n```\n\n### PythonAst Class\n\n```python\n# Check if AST is empty\nif ast.is_empty():\n print(\"No code found\")\n\n# Get statistics\nprint(f\"Statements: {ast.statement_count()}\")\nprint(f\"Functions: {ast.function_names()}\")\nprint(f\"Classes: {ast.class_names()}\")\nprint(f\"Imports: {ast.imports()}\")\n\n# Convert back to string\nsource_code = ast.to_string()\n```\n\n### Refactor Class\n\n```python\nrefactor = pyrustor.Refactor(ast)\n\n# Basic refactoring\nrefactor.rename_function(\"old_name\", \"new_name\")\nrefactor.rename_class(\"OldClass\", \"NewClass\")\nrefactor.replace_import(\"old_module\", \"new_module\")\n\n# Refactoring with automatic formatting\nrefactor.rename_function_with_format(\"old_name\", \"new_name\", apply_formatting=True)\nrefactor.rename_class_with_format(\"OldClass\", \"NewClass\", apply_formatting=True)\nrefactor.modernize_syntax_with_format(apply_formatting=True)\n\n# Advanced refactoring\nrefactor.modernize_syntax()\nrefactor.modernize_imports()\n\n# Formatting options\nrefactor.format_code() # Apply Ruff formatting\nformatted_result = refactor.refactor_and_format() # Refactor + format in one step\nconditional_format = refactor.to_string_with_format(apply_formatting=True)\n\n# Get results\nrefactored_code = refactor.to_string()\nchanges = refactor.change_summary()\n\n# Save to file\nrefactor.save_to_file(\"output.py\")\n```\n\n## \ud83e\uddea Development\n\n### Setup Development Environment\n\n```bash\n# Install just (command runner)\ncargo install just\n\n# Setup development environment\njust dev\n\n# Run tests\njust test\n\n# Format code\njust format\n\n# Run linting\njust lint\n\n# Build release\njust release\n```\n\n### Testing\n\nPyRustor has comprehensive test coverage with 257+ tests across Rust and Python components.\n\n```bash\n# Run all tests (Rust + Python)\njust test\n\n# Run specific test categories\njust test-rust # 91 Rust tests\njust test-python # 166 Python tests\n\n# Run with coverage reporting\njust coverage-all # Generate coverage reports for both languages\njust coverage-python # Python coverage only\njust coverage-rust # Rust coverage only\n\n# Run specific test types\npytest tests/ -m \"unit\" # Unit tests only\npytest tests/ -m \"integration\" # Integration tests only\npytest tests/ -m \"benchmark\" # Performance benchmarks\npytest tests/ -m \"not slow\" # Skip slow tests\n```\n\n#### Test Categories\n\n- **Unit Tests**: Core functionality testing\n- **Integration Tests**: End-to-end workflow testing\n- **Edge Case Tests**: Boundary conditions and error handling\n- **Performance Tests**: Benchmarking and regression detection\n- **Unicode Tests**: International character support\n- **Error Handling Tests**: Robust error recovery\n\n#### Coverage Reports\n\nAfter running coverage tests, view detailed reports:\n- **Python**: `htmlcov/index.html`\n- **Rust**: `target/tarpaulin/tarpaulin-report.html`\n\n### Quality Assurance\n\n```bash\n# Run all quality checks\njust check-all\n\n# Individual quality checks\njust quality # Code quality analysis\njust security # Security vulnerability scanning\njust performance # Performance benchmarking\njust docs-check # Documentation validation\n\n# CI-specific checks\njust ci-check-all # All checks optimized for CI\n```\n\n### Available Commands\n\n```bash\njust --list # Show all available commands\n```\n\n## \ud83e\udd1d Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests\n5. Submit a pull request\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\ude4f Acknowledgments\n\n- [**Ruff**](https://github.com/astral-sh/ruff) - PyRustor is built on Ruff's high-performance Python AST parsing engine (`ruff_python_ast`). Ruff is an extremely fast Python linter and code formatter written in Rust, developed by [Astral](https://astral.sh). We leverage Ruff's proven parsing technology to deliver blazing-fast Python code analysis and refactoring capabilities.\n- [PyO3](https://github.com/PyO3/pyo3) for excellent Python-Rust bindings\n- [maturin](https://github.com/PyO3/maturin) for seamless Python package building\n\n",
"bugtrack_url": null,
"license": null,
"summary": "A high-performance Python code parsing and refactoring tool written in Rust",
"version": "0.1.19",
"project_urls": {
"Bug Tracker": "https://github.com/loonghao/PyRustor/issues",
"Documentation": "https://github.com/loonghao/PyRustor",
"Homepage": "https://github.com/loonghao/PyRustor",
"Repository": "https://github.com/loonghao/PyRustor"
},
"split_keywords": [
"python",
" parser",
" refactoring",
" ast",
" code-analysis",
" rust"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5cb798afcbc58b384e4f425d11de7c16ee167e5a9ca1a002e704c972c3f17419",
"md5": "b2572da8d351ba76e593cde544584860",
"sha256": "b99da2efa2e47de7fea51abf75aab707ef74ffcb6b007a876ec80e71fe2a4c53"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "b2572da8d351ba76e593cde544584860",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 952215,
"upload_time": "2025-08-10T05:32:00",
"upload_time_iso_8601": "2025-08-10T05:32:00.799355Z",
"url": "https://files.pythonhosted.org/packages/5c/b7/98afcbc58b384e4f425d11de7c16ee167e5a9ca1a002e704c972c3f17419/pyrustor-0.1.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e5ccbf548c0e970361f0e160abf46e24f03c93caea0048cdd117f9699fa92ae4",
"md5": "4ee36ff2e6f61230eef9b86b7b156491",
"sha256": "7b2c4f9a830e58ac3856734fa10fc4d13764c601034ee26f6e96426862fb8130"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "4ee36ff2e6f61230eef9b86b7b156491",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 972195,
"upload_time": "2025-08-10T05:32:02",
"upload_time_iso_8601": "2025-08-10T05:32:02.223751Z",
"url": "https://files.pythonhosted.org/packages/e5/cc/bf548c0e970361f0e160abf46e24f03c93caea0048cdd117f9699fa92ae4/pyrustor-0.1.19-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "59e9284c24578255273b0636ba2ead7974be836be119c8d318ac64cbbec5f9c9",
"md5": "43b183ce81e8580beea5661daf8d7d88",
"sha256": "2c03c421ef9500cc227835fc421144e1e6d14d003a8bf8b6b21555e6fa512d00"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp310-cp310-win32.whl",
"has_sig": false,
"md5_digest": "43b183ce81e8580beea5661daf8d7d88",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 842911,
"upload_time": "2025-08-10T05:32:03",
"upload_time_iso_8601": "2025-08-10T05:32:03.943931Z",
"url": "https://files.pythonhosted.org/packages/59/e9/284c24578255273b0636ba2ead7974be836be119c8d318ac64cbbec5f9c9/pyrustor-0.1.19-cp310-cp310-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "0c8d11eec49c96707f0bf701c82b06991a7b43a60f61279eb2c3121b7759544e",
"md5": "5b68b4bb3fb4048af4eb73428534935f",
"sha256": "c8687e20a751882b0cbb419e9edd799741aa73a319faaec7cf81915edafc4bf3"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp310-cp310-win_amd64.whl",
"has_sig": false,
"md5_digest": "5b68b4bb3fb4048af4eb73428534935f",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 847068,
"upload_time": "2025-08-10T05:32:05",
"upload_time_iso_8601": "2025-08-10T05:32:05.658605Z",
"url": "https://files.pythonhosted.org/packages/0c/8d/11eec49c96707f0bf701c82b06991a7b43a60f61279eb2c3121b7759544e/pyrustor-0.1.19-cp310-cp310-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "dc9b087f0888e0745ac32462636707f8ddf15b4ba1722a50900e0ed034c3ab44",
"md5": "23ac5f464b6517f77b6ebff260ff8d0d",
"sha256": "41138c2da657ff7d4d3720541ff99b18c4b3d1c28d8f7df0f927cd6f648180eb"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
"has_sig": false,
"md5_digest": "23ac5f464b6517f77b6ebff260ff8d0d",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 1810361,
"upload_time": "2025-08-10T05:32:07",
"upload_time_iso_8601": "2025-08-10T05:32:07.417850Z",
"url": "https://files.pythonhosted.org/packages/dc/9b/087f0888e0745ac32462636707f8ddf15b4ba1722a50900e0ed034c3ab44/pyrustor-0.1.19-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8d28d5f5eb84c4ab351cab8afe9a73c9dcf539f73ebef4655f3e0d05b4efad86",
"md5": "550434398c5019b1c340fbf1fe41ba9b",
"sha256": "a03bdd7068687f598e049a928d130f6c4a29512cf6c7e18147a552c2f852c7e8"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp311-cp311-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "550434398c5019b1c340fbf1fe41ba9b",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 929051,
"upload_time": "2025-08-10T05:32:08",
"upload_time_iso_8601": "2025-08-10T05:32:08.819966Z",
"url": "https://files.pythonhosted.org/packages/8d/28/d5f5eb84c4ab351cab8afe9a73c9dcf539f73ebef4655f3e0d05b4efad86/pyrustor-0.1.19-cp311-cp311-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c5b5354a345fb94f7c9ae6b1bfe4e0abe8a50e889993d2e18c52fcc28bc02af0",
"md5": "28a90c746c1d96d8548b9eaef738d448",
"sha256": "71f1d024a233be0921c429e81ae2715300d8a3367dff60a8a15934cd1cd84572"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "28a90c746c1d96d8548b9eaef738d448",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 951990,
"upload_time": "2025-08-10T05:32:10",
"upload_time_iso_8601": "2025-08-10T05:32:10.493301Z",
"url": "https://files.pythonhosted.org/packages/c5/b5/354a345fb94f7c9ae6b1bfe4e0abe8a50e889993d2e18c52fcc28bc02af0/pyrustor-0.1.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "a5709e54f9855a8c682fbf88738c49c1ef4a0ac12aa58732c52b75ed373de9fd",
"md5": "b540f96f4c62965614e670c1d0effea0",
"sha256": "9032237f973d18209c9d759daa4840b3d49e7ff74dccf653d3810d2b848472dc"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "b540f96f4c62965614e670c1d0effea0",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 971908,
"upload_time": "2025-08-10T05:32:12",
"upload_time_iso_8601": "2025-08-10T05:32:12.161643Z",
"url": "https://files.pythonhosted.org/packages/a5/70/9e54f9855a8c682fbf88738c49c1ef4a0ac12aa58732c52b75ed373de9fd/pyrustor-0.1.19-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8d4d360ab599ee522eb9dc10118b367d4ba43c09d96dc1f1caea1cba972d9856",
"md5": "80e94fa489a16c4cdb1a5eba5bd86cd5",
"sha256": "047e0da2484c8f486b1774d2ac97622004489aee5bd564791ceb6c77e14ceb5b"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp311-cp311-win32.whl",
"has_sig": false,
"md5_digest": "80e94fa489a16c4cdb1a5eba5bd86cd5",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 842793,
"upload_time": "2025-08-10T05:32:13",
"upload_time_iso_8601": "2025-08-10T05:32:13.858006Z",
"url": "https://files.pythonhosted.org/packages/8d/4d/360ab599ee522eb9dc10118b367d4ba43c09d96dc1f1caea1cba972d9856/pyrustor-0.1.19-cp311-cp311-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "23eafb38decfb2c774e5de3720181aa1aa7e926337d5591d7d7dbf3754abd95c",
"md5": "672ff252ab5506d717a4bc6e3746fa54",
"sha256": "75145bc97113de0d08379c5363a57410cd8a044a2b5e6a1e46f323b48fc04c49"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp311-cp311-win_amd64.whl",
"has_sig": false,
"md5_digest": "672ff252ab5506d717a4bc6e3746fa54",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 846928,
"upload_time": "2025-08-10T05:32:15",
"upload_time_iso_8601": "2025-08-10T05:32:15.544943Z",
"url": "https://files.pythonhosted.org/packages/23/ea/fb38decfb2c774e5de3720181aa1aa7e926337d5591d7d7dbf3754abd95c/pyrustor-0.1.19-cp311-cp311-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "649d956af45a4bbc7a34e20972b2e08580844c5bd2a39be6cbe813e3ceaa1fd6",
"md5": "e568a193b9325271d9adb7688b16cdb7",
"sha256": "ff030f78530d77579d42568003ead8af4006bc6f8f106bcbf5b0b521c6191db3"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
"has_sig": false,
"md5_digest": "e568a193b9325271d9adb7688b16cdb7",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.8",
"size": 1803128,
"upload_time": "2025-08-10T05:32:16",
"upload_time_iso_8601": "2025-08-10T05:32:16.929342Z",
"url": "https://files.pythonhosted.org/packages/64/9d/956af45a4bbc7a34e20972b2e08580844c5bd2a39be6cbe813e3ceaa1fd6/pyrustor-0.1.19-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "9ef38a5af0e295f5a17b60197cb16a2c16d52116cdfbbb748c26586b716a3758",
"md5": "602725ebdc0f05f89dd95b2837d9f9e1",
"sha256": "48fd2d51024fec76bfafe04fe258d967072fbf667a672c77900d30a410fa0cbd"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp312-cp312-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "602725ebdc0f05f89dd95b2837d9f9e1",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.8",
"size": 922163,
"upload_time": "2025-08-10T05:32:18",
"upload_time_iso_8601": "2025-08-10T05:32:18.505211Z",
"url": "https://files.pythonhosted.org/packages/9e/f3/8a5af0e295f5a17b60197cb16a2c16d52116cdfbbb748c26586b716a3758/pyrustor-0.1.19-cp312-cp312-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "3544203a42da69e0184d139253ab47a29a27144f598b93c88e60c4783440f216",
"md5": "312b5da9f3bd768e7e8f4356323f489f",
"sha256": "0fcece71c613b79d75c4f64588affc10d125c6ae1f5eb28805b98d2c5e43c3e2"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "312b5da9f3bd768e7e8f4356323f489f",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.8",
"size": 949526,
"upload_time": "2025-08-10T05:32:20",
"upload_time_iso_8601": "2025-08-10T05:32:20.345969Z",
"url": "https://files.pythonhosted.org/packages/35/44/203a42da69e0184d139253ab47a29a27144f598b93c88e60c4783440f216/pyrustor-0.1.19-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "59a3a1f1796f4fbe0323b3e12a46b0e3a200d41de93d78ad3eb44d91e7667ccf",
"md5": "1ca505c4ddb0c65537593f5ae5c5e995",
"sha256": "6557a8d794cee6d37ef0a73e482bfdb5b17633b0d52d23ce100d4765392871d7"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "1ca505c4ddb0c65537593f5ae5c5e995",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.8",
"size": 976134,
"upload_time": "2025-08-10T05:32:21",
"upload_time_iso_8601": "2025-08-10T05:32:21.969312Z",
"url": "https://files.pythonhosted.org/packages/59/a3/a1f1796f4fbe0323b3e12a46b0e3a200d41de93d78ad3eb44d91e7667ccf/pyrustor-0.1.19-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "59c2265adc10ed3002a052b80dfc1601b75ebb04502ca1ff43e03dee29b38a3d",
"md5": "3d36e54428405bee872edb65567b9aeb",
"sha256": "82747f3d781ab8f7d242d93e50e807acae748d6c8c6617ccf14092580a6fd4da"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp312-cp312-win32.whl",
"has_sig": false,
"md5_digest": "3d36e54428405bee872edb65567b9aeb",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.8",
"size": 838849,
"upload_time": "2025-08-10T05:32:23",
"upload_time_iso_8601": "2025-08-10T05:32:23.852618Z",
"url": "https://files.pythonhosted.org/packages/59/c2/265adc10ed3002a052b80dfc1601b75ebb04502ca1ff43e03dee29b38a3d/pyrustor-0.1.19-cp312-cp312-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f59f951644d0727b9c41528b792b7eb480a883558be7aa2dcbefbdecb9bbe1b2",
"md5": "d36da037fa1cc96402ab5305850bf0bf",
"sha256": "e0cff7fedf3eaa06671485979418c01b150047a82e280e8906545663bdb47b05"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp312-cp312-win_amd64.whl",
"has_sig": false,
"md5_digest": "d36da037fa1cc96402ab5305850bf0bf",
"packagetype": "bdist_wheel",
"python_version": "cp312",
"requires_python": ">=3.8",
"size": 845085,
"upload_time": "2025-08-10T05:32:25",
"upload_time_iso_8601": "2025-08-10T05:32:25.323034Z",
"url": "https://files.pythonhosted.org/packages/f5/9f/951644d0727b9c41528b792b7eb480a883558be7aa2dcbefbdecb9bbe1b2/pyrustor-0.1.19-cp312-cp312-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c7ede04a67c2fc4caab2f7fa4f764565a32196794deb3bfce59ee8abf0ce200d",
"md5": "440e2d27d456f0abd62b463dee6960fa",
"sha256": "c6845fbab9ffec43d44911833b6885117fcb6ad936b39b985a5374c932a58037"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
"has_sig": false,
"md5_digest": "440e2d27d456f0abd62b463dee6960fa",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.8",
"size": 1802781,
"upload_time": "2025-08-10T05:32:27",
"upload_time_iso_8601": "2025-08-10T05:32:27.024705Z",
"url": "https://files.pythonhosted.org/packages/c7/ed/e04a67c2fc4caab2f7fa4f764565a32196794deb3bfce59ee8abf0ce200d/pyrustor-0.1.19-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "421e5edcf442843c3911e97e4aea1bd9fcf3490e0dd8bd82276523573a8ac89d",
"md5": "25f1fe57040a4e2ee3e7ed692c48e274",
"sha256": "612e568e36afbc1514d1dd931be665e7a7197cc4b0aee17545f700381f72c71a"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp313-cp313-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "25f1fe57040a4e2ee3e7ed692c48e274",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.8",
"size": 921869,
"upload_time": "2025-08-10T05:32:28",
"upload_time_iso_8601": "2025-08-10T05:32:28.301840Z",
"url": "https://files.pythonhosted.org/packages/42/1e/5edcf442843c3911e97e4aea1bd9fcf3490e0dd8bd82276523573a8ac89d/pyrustor-0.1.19-cp313-cp313-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "355ba02b0a9068609d2106c26d0f7bef44f9995d7c3569e7c74c49992a956c4b",
"md5": "dbaa8d0a54c8f03d7d61bc25528ef547",
"sha256": "6091b38eb4ced0b3095063bfce432ef9f34673f5e3de43e132fa146bb14beb2a"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "dbaa8d0a54c8f03d7d61bc25528ef547",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.8",
"size": 949171,
"upload_time": "2025-08-10T05:32:29",
"upload_time_iso_8601": "2025-08-10T05:32:29.628462Z",
"url": "https://files.pythonhosted.org/packages/35/5b/a02b0a9068609d2106c26d0f7bef44f9995d7c3569e7c74c49992a956c4b/pyrustor-0.1.19-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "442201d2a84b4d239ea74d6ada0d515bd5e9f53ef4277c5a92cc83a6e2725ba3",
"md5": "d960cedc24e83343b2a5fc3d90642985",
"sha256": "0706382a4a6271b75758a529752983d5e073bdb7dc9f82d12a3d5aba3158c27d"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "d960cedc24e83343b2a5fc3d90642985",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.8",
"size": 975968,
"upload_time": "2025-08-10T05:32:30",
"upload_time_iso_8601": "2025-08-10T05:32:30.947871Z",
"url": "https://files.pythonhosted.org/packages/44/22/01d2a84b4d239ea74d6ada0d515bd5e9f53ef4277c5a92cc83a6e2725ba3/pyrustor-0.1.19-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4790f81e6d70f8cf7f2408e0b2e2040f6451c489470cfbe2fbfb2376ec4876b2",
"md5": "3ee35a7b965b0c52f52fd71df7d9297f",
"sha256": "56e6badd9099a2212315d2d8d1160c2926fe740ee143016e0cb0c3801a19ce6d"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp313-cp313-win32.whl",
"has_sig": false,
"md5_digest": "3ee35a7b965b0c52f52fd71df7d9297f",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.8",
"size": 838692,
"upload_time": "2025-08-10T05:32:32",
"upload_time_iso_8601": "2025-08-10T05:32:32.325122Z",
"url": "https://files.pythonhosted.org/packages/47/90/f81e6d70f8cf7f2408e0b2e2040f6451c489470cfbe2fbfb2376ec4876b2/pyrustor-0.1.19-cp313-cp313-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e726ac976b58265e6184969ba6acb68c766f29b9615e7dde742ba0ac9e3c3f96",
"md5": "0a3be4e3872fd5dd3adffb2c0a0925d7",
"sha256": "5e96f420621b239ac1b52fb89f3da4eae5a117fdf657c77b5adc18ffb7b6e19f"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp313-cp313-win_amd64.whl",
"has_sig": false,
"md5_digest": "0a3be4e3872fd5dd3adffb2c0a0925d7",
"packagetype": "bdist_wheel",
"python_version": "cp313",
"requires_python": ">=3.8",
"size": 844819,
"upload_time": "2025-08-10T05:32:33",
"upload_time_iso_8601": "2025-08-10T05:32:33.917291Z",
"url": "https://files.pythonhosted.org/packages/e7/26/ac976b58265e6184969ba6acb68c766f29b9615e7dde742ba0ac9e3c3f96/pyrustor-0.1.19-cp313-cp313-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "0cd268a5fb8149f0bbf3eed1511c7b377fb2bf634f6d392dabdaccb5a62a8980",
"md5": "e99ebcb7398572657d339b413213f547",
"sha256": "a6fe4180c5fadce9802cc1e57bdf801f11909f9e8c86b22f7c28eb860439aed9"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "e99ebcb7398572657d339b413213f547",
"packagetype": "bdist_wheel",
"python_version": "cp314",
"requires_python": ">=3.8",
"size": 948487,
"upload_time": "2025-08-10T05:32:35",
"upload_time_iso_8601": "2025-08-10T05:32:35.227287Z",
"url": "https://files.pythonhosted.org/packages/0c/d2/68a5fb8149f0bbf3eed1511c7b377fb2bf634f6d392dabdaccb5a62a8980/pyrustor-0.1.19-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "aed9d52bd7d609eb5f1d7fea0ac817bcc4f86017599aaffeb2350e17fc920d88",
"md5": "e2bb152ceb7011d60d42be1ea056f34e",
"sha256": "45a06678b60ab0b797a4d8ab8dc129e2c2e94f5800700954726bd6a67e3ff2a3"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "e2bb152ceb7011d60d42be1ea056f34e",
"packagetype": "bdist_wheel",
"python_version": "cp314",
"requires_python": ">=3.8",
"size": 974392,
"upload_time": "2025-08-10T05:32:36",
"upload_time_iso_8601": "2025-08-10T05:32:36.674812Z",
"url": "https://files.pythonhosted.org/packages/ae/d9/d52bd7d609eb5f1d7fea0ac817bcc4f86017599aaffeb2350e17fc920d88/pyrustor-0.1.19-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4c18ad316c93df673071ed9c55ebf31d6a1129ee061d7891dd01ac74897a3e4c",
"md5": "fe7581c81744bf552b800770e4578878",
"sha256": "1c7b841ed4331f7d1b5dada42650f013ee03691b90f95c780ff70ff1ff42d5c1"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp38-abi3-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "fe7581c81744bf552b800770e4578878",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 929864,
"upload_time": "2025-08-10T05:32:38",
"upload_time_iso_8601": "2025-08-10T05:32:38.003844Z",
"url": "https://files.pythonhosted.org/packages/4c/18/ad316c93df673071ed9c55ebf31d6a1129ee061d7891dd01ac74897a3e4c/pyrustor-0.1.19-cp38-abi3-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "6b7a23cb7d422148d48ba086b524846e9960686b6e0f3c14125024b58c61ad1d",
"md5": "5eb4285ec82baf1fa763cca101e28c7a",
"sha256": "0cb8d2e6940bcdff8bc13ab063295208c152f47af49d0d31f7d376aa75885ab3"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp38-abi3-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "5eb4285ec82baf1fa763cca101e28c7a",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 896237,
"upload_time": "2025-08-10T05:32:39",
"upload_time_iso_8601": "2025-08-10T05:32:39.741057Z",
"url": "https://files.pythonhosted.org/packages/6b/7a/23cb7d422148d48ba086b524846e9960686b6e0f3c14125024b58c61ad1d/pyrustor-0.1.19-cp38-abi3-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "547c452cfae51c3c21aa02c7ffbdae4f6890c084f0cc185a3282d69e692d674a",
"md5": "ef034a3132a81534360176db946cb302",
"sha256": "bcdb4956296ab7b8c4ef6bc31d9459515073a6a50e407d500735f8c068dee12b"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "ef034a3132a81534360176db946cb302",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 953212,
"upload_time": "2025-08-10T05:32:41",
"upload_time_iso_8601": "2025-08-10T05:32:41.077727Z",
"url": "https://files.pythonhosted.org/packages/54/7c/452cfae51c3c21aa02c7ffbdae4f6890c084f0cc185a3282d69e692d674a/pyrustor-0.1.19-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "98f03e3720e88315b36f595d0628129ad3d6288e6864bd61f77f90fa6384455b",
"md5": "d4815b2aa34a154343ba4f5b56daf6ca",
"sha256": "bfc43713000ad2d7503bb992bb1d5ae51855a427f8f5cd05235802a8ff77ad49"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "d4815b2aa34a154343ba4f5b56daf6ca",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 979591,
"upload_time": "2025-08-10T05:32:42",
"upload_time_iso_8601": "2025-08-10T05:32:42.872988Z",
"url": "https://files.pythonhosted.org/packages/98/f0/3e3720e88315b36f595d0628129ad3d6288e6864bd61f77f90fa6384455b/pyrustor-0.1.19-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4f3f8b2349a2acf9e1983eaf708bcf17188a263ae2eb98c9a100f5502a2d6917",
"md5": "e3f196f0336343ec42613aeb94994240",
"sha256": "9e10acaab36ff6e9674ebcac71b3a3bbcfeefa6a57ec29b4bf154a3c21a72a9e"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp38-abi3-win32.whl",
"has_sig": false,
"md5_digest": "e3f196f0336343ec42613aeb94994240",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 838802,
"upload_time": "2025-08-10T05:32:44",
"upload_time_iso_8601": "2025-08-10T05:32:44.386279Z",
"url": "https://files.pythonhosted.org/packages/4f/3f/8b2349a2acf9e1983eaf708bcf17188a263ae2eb98c9a100f5502a2d6917/pyrustor-0.1.19-cp38-abi3-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b885c81451f22d91a24e5e4490af2ff5cb4e51532fe4b30f312c08b70f034fb9",
"md5": "63fd6bb95501ef74896f2c2dabb02c52",
"sha256": "74611faf97001049dd0b41ddfe818243f1a4274b241f23520aafa40909616d0f"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp38-abi3-win_amd64.whl",
"has_sig": false,
"md5_digest": "63fd6bb95501ef74896f2c2dabb02c52",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 850046,
"upload_time": "2025-08-10T05:32:46",
"upload_time_iso_8601": "2025-08-10T05:32:46.098250Z",
"url": "https://files.pythonhosted.org/packages/b8/85/c81451f22d91a24e5e4490af2ff5cb4e51532fe4b30f312c08b70f034fb9/pyrustor-0.1.19-cp38-abi3-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "edf83ad063a57c5267d6f317da8b53609a8bfd879ea9df7307cc29253e9e37f5",
"md5": "82ecc8750aa9077020e5408cdcf72a83",
"sha256": "a1785a0bb32d3cef95983d53a2013fe7149455151018b5a8fc0a32478052cc2f"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "82ecc8750aa9077020e5408cdcf72a83",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 952434,
"upload_time": "2025-08-10T05:32:47",
"upload_time_iso_8601": "2025-08-10T05:32:47.588484Z",
"url": "https://files.pythonhosted.org/packages/ed/f8/3ad063a57c5267d6f317da8b53609a8bfd879ea9df7307cc29253e9e37f5/pyrustor-0.1.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ab1597c66838b57d633c54902a98159f169abae097dd4d95e27246fc25440aec",
"md5": "30a3908f928707774dd7141a9833426b",
"sha256": "7112e6b94cafd61569e64be79f3865b9e268f1b61c6ea4acb001f4e4d4638d50"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "30a3908f928707774dd7141a9833426b",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 972421,
"upload_time": "2025-08-10T05:32:49",
"upload_time_iso_8601": "2025-08-10T05:32:49.204019Z",
"url": "https://files.pythonhosted.org/packages/ab/15/97c66838b57d633c54902a98159f169abae097dd4d95e27246fc25440aec/pyrustor-0.1.19-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "509a472e56e8fa11415bad1e7bf3c10d1cf8e70ca0cbe8a6add7ba9a072729a9",
"md5": "97a6dd4c185e18a44b15c20638147c28",
"sha256": "999f03ffbe8432be5dd1f80d2fffc16683db84d0bdcbfb6d9e02df2eacc4b918"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "97a6dd4c185e18a44b15c20638147c28",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.8",
"size": 952428,
"upload_time": "2025-08-10T05:32:50",
"upload_time_iso_8601": "2025-08-10T05:32:50.974279Z",
"url": "https://files.pythonhosted.org/packages/50/9a/472e56e8fa11415bad1e7bf3c10d1cf8e70ca0cbe8a6add7ba9a072729a9/pyrustor-0.1.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "dffb1cb1dcf31209ce18c71febf621999695f14b3fea1e534e4ff0bcf98e1f49",
"md5": "5f4f452964e7474675f37f2bd0d15bf2",
"sha256": "0113bcfb083bf271a2c8f34a6cc86d0246e210b8cb9a0310361e29c2146239b6"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "5f4f452964e7474675f37f2bd0d15bf2",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.8",
"size": 972488,
"upload_time": "2025-08-10T05:32:52",
"upload_time_iso_8601": "2025-08-10T05:32:52.453892Z",
"url": "https://files.pythonhosted.org/packages/df/fb/1cb1dcf31209ce18c71febf621999695f14b3fea1e534e4ff0bcf98e1f49/pyrustor-0.1.19-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "7eaaaa2b8d15a25eff08ca7c811dfcf21732c42dc543af4bd1292f9f1e478438",
"md5": "91594e7b8cf03ff24cbbd864fa336a25",
"sha256": "c0bbbab4cedb2fee347d3f57dd3d6f3541eb568fc62844473c2c9010398e3032"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp39-cp39-win32.whl",
"has_sig": false,
"md5_digest": "91594e7b8cf03ff24cbbd864fa336a25",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.8",
"size": 842957,
"upload_time": "2025-08-10T05:32:54",
"upload_time_iso_8601": "2025-08-10T05:32:54.331480Z",
"url": "https://files.pythonhosted.org/packages/7e/aa/aa2b8d15a25eff08ca7c811dfcf21732c42dc543af4bd1292f9f1e478438/pyrustor-0.1.19-cp39-cp39-win32.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "98edfd8a34a602abca63a6e5cf9f3781965a83fcbb95f4f2d5f05dc75ff5b91a",
"md5": "1751cdb1720b64da3db1d1b25b6f84a0",
"sha256": "d0c518bf11b24c3769e39b791bca695a1831be35971e0eb1296af3537b310a9f"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-cp39-cp39-win_amd64.whl",
"has_sig": false,
"md5_digest": "1751cdb1720b64da3db1d1b25b6f84a0",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.8",
"size": 847149,
"upload_time": "2025-08-10T05:32:56",
"upload_time_iso_8601": "2025-08-10T05:32:56.021145Z",
"url": "https://files.pythonhosted.org/packages/98/ed/fd8a34a602abca63a6e5cf9f3781965a83fcbb95f4f2d5f05dc75ff5b91a/pyrustor-0.1.19-cp39-cp39-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "5a6fdde252b62fa0439b18a3d91f845ee5d23b156dbc2387b88f374e6f55cbb2",
"md5": "4ba817e61043cb6358cb3af644bb34b7",
"sha256": "5f3bd994d0946b4b88858537cb0c68e548464950dfa2bb3e03b293aba111b6c3"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "4ba817e61043cb6358cb3af644bb34b7",
"packagetype": "bdist_wheel",
"python_version": "pp310",
"requires_python": ">=3.8",
"size": 952213,
"upload_time": "2025-08-10T05:32:57",
"upload_time_iso_8601": "2025-08-10T05:32:57.798242Z",
"url": "https://files.pythonhosted.org/packages/5a/6f/dde252b62fa0439b18a3d91f845ee5d23b156dbc2387b88f374e6f55cbb2/pyrustor-0.1.19-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c6522ac9c27c1f96d31bc600b4bec6d53e4297fd6d4e4223af4027590595c6a6",
"md5": "2ca6e28db0b6233a8631b9ea20200a8e",
"sha256": "024c6692608ada04949e87e9f322df1961098aa2f0a6ee9900059a4785900dd4"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "2ca6e28db0b6233a8631b9ea20200a8e",
"packagetype": "bdist_wheel",
"python_version": "pp310",
"requires_python": ">=3.8",
"size": 972228,
"upload_time": "2025-08-10T05:32:59",
"upload_time_iso_8601": "2025-08-10T05:32:59.282712Z",
"url": "https://files.pythonhosted.org/packages/c6/52/2ac9c27c1f96d31bc600b4bec6d53e4297fd6d4e4223af4027590595c6a6/pyrustor-0.1.19-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "768f14461f584c3a10f96df6d742e3477b43f248ad9e6920706397c6c44dd38d",
"md5": "0025e31b0b2791ec9567d25ae491b8f2",
"sha256": "76e335fa5d50c9659329a21e5e948f3122d805a7b823f5c07de5b96455f8ff55"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "0025e31b0b2791ec9567d25ae491b8f2",
"packagetype": "bdist_wheel",
"python_version": "pp311",
"requires_python": ">=3.8",
"size": 951859,
"upload_time": "2025-08-10T05:33:00",
"upload_time_iso_8601": "2025-08-10T05:33:00.954093Z",
"url": "https://files.pythonhosted.org/packages/76/8f/14461f584c3a10f96df6d742e3477b43f248ad9e6920706397c6c44dd38d/pyrustor-0.1.19-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c4c79ac5b8fc4c6d34d72beab534aa69b247c72e7bd8c8396956c3cd4bb66055",
"md5": "b2b267873853fb4e5f5523cf3f7511b6",
"sha256": "8d7e7b291828f5a22f3db57e1783f50d4df1609495a55c95902df93bdf9c6b7a"
},
"downloads": -1,
"filename": "pyrustor-0.1.19-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl",
"has_sig": false,
"md5_digest": "b2b267873853fb4e5f5523cf3f7511b6",
"packagetype": "bdist_wheel",
"python_version": "pp311",
"requires_python": ">=3.8",
"size": 971711,
"upload_time": "2025-08-10T05:33:02",
"upload_time_iso_8601": "2025-08-10T05:33:02.276241Z",
"url": "https://files.pythonhosted.org/packages/c4/c7/9ac5b8fc4c6d34d72beab534aa69b247c72e7bd8c8396956c3cd4bb66055/pyrustor-0.1.19-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e7771f6debd673c0906dd1c4fccdb5f5a47186ff87417396d7b233e6afa63133",
"md5": "5411e0c399e52d4ee6cb69cb75eaba4b",
"sha256": "b89a9ff5e84466121544b41d684524b35f0ca1d3bbdc169c4b2e64921aff1aab"
},
"downloads": -1,
"filename": "pyrustor-0.1.19.tar.gz",
"has_sig": false,
"md5_digest": "5411e0c399e52d4ee6cb69cb75eaba4b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 54070,
"upload_time": "2025-08-10T05:33:03",
"upload_time_iso_8601": "2025-08-10T05:33:03.481538Z",
"url": "https://files.pythonhosted.org/packages/e7/77/1f6debd673c0906dd1c4fccdb5f5a47186ff87417396d7b233e6afa63133/pyrustor-0.1.19.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-10 05:33:03",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "loonghao",
"github_project": "PyRustor",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "pyrustor"
}