# pyla-linter
A collection of Python linting tools designed to be used with flake8.
## Features
### Length Checker Plugin
A flake8 plugin that enforces configurable statement limits for classes and functions using AST-based analysis, excluding docstrings and comments from the count.
#### Installation
Install using Poetry:
```bash
poetry add pyla-linter
```
Or using pip:
```bash
pip install pyla-linter
```
#### Usage
The length checker integrates with flake8 as a plugin. Run it using:
```bash
# Check all Python files in current directory with our plugin
flake8 --select=EL
# Check specific files or directories
flake8 --select=EL src/
flake8 --select=EL myfile.py
# Use with all flake8 checks
flake8
# Use only our length checker plugin
flake8 --select=EL001,EL002
```
#### Configuration
Configure the length checker in your `pyproject.toml` file:
```toml
[tool.pyla-linters]
# Maximum statements for functions (default: 40)
max_function_length = 40
# Maximum statements for classes (default: 200)
max_class_length = 200
```
You can also configure via command line arguments using flake8's standard option system:
```bash
# Use with flake8 ignore/select options
flake8 --select=EL001 # Only check function length
flake8 --select=EL002 # Only check class length
flake8 --ignore=EL001 # Ignore function length violations
```
#### Error Codes
The length checker uses the following error codes:
- **EL001**: Function exceeds maximum statement limit (error at 2x threshold)
- **EL002**: Class exceeds maximum statement limit (error at 2x threshold)
- **WL001**: Function exceeds warning statement threshold
- **WL002**: Class exceeds warning statement threshold
#### Statement Counting Logic
The plugin uses AST-based analysis to count logical statements rather than physical lines, providing a more accurate measure of code complexity. It counts executable statements while excluding:
- Docstrings
- Comments
- Empty lines
- Pure whitespace
For nested structures:
- Nested functions/classes are excluded from their parent's statement count
- Each code element is evaluated independently
- Decorators are included in the decorated element's line span but don't count as statements
The plugin implements a two-tier threshold system:
- **Warning**: Issued when statement count exceeds the configured threshold
- **Error**: Issued when statement count exceeds 2x the configured threshold
#### Examples
**Function that would trigger EL001:**
```python
def long_function(): # Function definition
"""This is a docstring (not counted as a statement)."""
# This is a comment (not counted)
x = 1 # Statement 1
y = 2 # Statement 2
# ... more code statements
return x + y # Statement 41 (exceeds default limit of 40)
```
**Class that would trigger EL002:**
```python
class LargeClass: # Class definition
"""Class docstring (not counted as a statement)."""
def method1(self): # Method definitions don't count toward class statements
self.value = 1 # Statement 1 (counts toward method, not class)
return self.value # Statement 2 (counts toward method, not class)
def __init__(self): # Init method
self.data = [] # Statement 1 of class body
# ... many more statements in class body
# Class with 201 statements in its direct body (exceeds default limit of 200)
```
#### Integration with Existing Workflow
The length checker works seamlessly with other flake8 plugins:
```bash
# Run with multiple checks (flake8 automatically includes all installed plugins)
flake8
# Run only our length checker with other specific checks
flake8 --select=E,F,EL
# Include in existing CI/CD pipelines
poetry run flake8 src/
```
## Development
### Setup
```bash
# Clone the repository
git clone <repository-url>
cd pyla-linter
# Install dependencies
poetry install
# Run tests
poetry run pytest
# Run linting and formatting
poetry run poe autolint
```
### Quality Checks
Before submitting changes, ensure all quality checks pass:
```bash
# Format code
poetry run poe format
# Run linting
poetry run poe lint
# Type checking
poetry run pyright
# Run tests
poetry run pytest
```
## License
[License information would go here]
Raw data
{
"_id": null,
"home_page": null,
"name": "pyla-linter",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "linting, flake8, python, langadventure",
"author": "LangAdventure LLC",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/76/b5/2189a4135e6a682b8d32ed1bc01f0c643ac198fb1beae81a8b2e1eab3cc1/pyla_linter-1.3.1.tar.gz",
"platform": null,
"description": "# pyla-linter\n\nA collection of Python linting tools designed to be used with flake8.\n\n## Features\n\n### Length Checker Plugin\n\nA flake8 plugin that enforces configurable statement limits for classes and functions using AST-based analysis, excluding docstrings and comments from the count.\n\n#### Installation\n\nInstall using Poetry:\n\n```bash\npoetry add pyla-linter\n```\n\nOr using pip:\n\n```bash\npip install pyla-linter\n```\n\n#### Usage\n\nThe length checker integrates with flake8 as a plugin. Run it using:\n\n```bash\n# Check all Python files in current directory with our plugin\nflake8 --select=EL\n\n# Check specific files or directories\nflake8 --select=EL src/\nflake8 --select=EL myfile.py\n\n# Use with all flake8 checks\nflake8\n\n# Use only our length checker plugin\nflake8 --select=EL001,EL002\n```\n\n#### Configuration\n\nConfigure the length checker in your `pyproject.toml` file:\n\n```toml\n[tool.pyla-linters]\n# Maximum statements for functions (default: 40)\nmax_function_length = 40\n\n# Maximum statements for classes (default: 200)\nmax_class_length = 200\n```\n\nYou can also configure via command line arguments using flake8's standard option system:\n\n```bash\n# Use with flake8 ignore/select options\nflake8 --select=EL001 # Only check function length\nflake8 --select=EL002 # Only check class length\nflake8 --ignore=EL001 # Ignore function length violations\n```\n\n#### Error Codes\n\nThe length checker uses the following error codes:\n\n- **EL001**: Function exceeds maximum statement limit (error at 2x threshold)\n- **EL002**: Class exceeds maximum statement limit (error at 2x threshold)\n- **WL001**: Function exceeds warning statement threshold\n- **WL002**: Class exceeds warning statement threshold\n\n#### Statement Counting Logic\n\nThe plugin uses AST-based analysis to count logical statements rather than physical lines, providing a more accurate measure of code complexity. It counts executable statements while excluding:\n\n- Docstrings\n- Comments\n- Empty lines\n- Pure whitespace\n\nFor nested structures:\n- Nested functions/classes are excluded from their parent's statement count\n- Each code element is evaluated independently\n- Decorators are included in the decorated element's line span but don't count as statements\n\nThe plugin implements a two-tier threshold system:\n- **Warning**: Issued when statement count exceeds the configured threshold\n- **Error**: Issued when statement count exceeds 2x the configured threshold\n\n#### Examples\n\n**Function that would trigger EL001:**\n\n```python\ndef long_function(): # Function definition\n \"\"\"This is a docstring (not counted as a statement).\"\"\"\n \n # This is a comment (not counted)\n \n x = 1 # Statement 1\n y = 2 # Statement 2\n # ... more code statements\n return x + y # Statement 41 (exceeds default limit of 40)\n```\n\n**Class that would trigger EL002:**\n\n```python\nclass LargeClass: # Class definition\n \"\"\"Class docstring (not counted as a statement).\"\"\"\n \n def method1(self): # Method definitions don't count toward class statements\n self.value = 1 # Statement 1 (counts toward method, not class)\n return self.value # Statement 2 (counts toward method, not class)\n \n def __init__(self): # Init method\n self.data = [] # Statement 1 of class body\n # ... many more statements in class body\n \n # Class with 201 statements in its direct body (exceeds default limit of 200)\n```\n\n#### Integration with Existing Workflow\n\nThe length checker works seamlessly with other flake8 plugins:\n\n```bash\n# Run with multiple checks (flake8 automatically includes all installed plugins)\nflake8\n\n# Run only our length checker with other specific checks\nflake8 --select=E,F,EL\n\n# Include in existing CI/CD pipelines\npoetry run flake8 src/\n```\n\n## Development\n\n### Setup\n\n```bash\n# Clone the repository\ngit clone <repository-url>\ncd pyla-linter\n\n# Install dependencies\npoetry install\n\n# Run tests\npoetry run pytest\n\n# Run linting and formatting\npoetry run poe autolint\n```\n\n### Quality Checks\n\nBefore submitting changes, ensure all quality checks pass:\n\n```bash\n# Format code\npoetry run poe format\n\n# Run linting\npoetry run poe lint\n\n# Type checking\npoetry run pyright\n\n# Run tests\npoetry run pytest\n```\n\n## License\n\n[License information would go here]\n",
"bugtrack_url": null,
"license": "GPL-3.0",
"summary": "Flake8 linting plugins to handle common AI code agent issues",
"version": "1.3.1",
"project_urls": {
"Homepage": "https://github.com/langadventurellc/pyla-linter",
"Issues": "https://github.com/langadventurellc/pyla-linter/issues",
"Repository": "https://github.com/langadventurellc/pyla-linter"
},
"split_keywords": [
"linting",
" flake8",
" python",
" langadventure"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "64a73441e67f7c853da3df24e764f988399922c339864f105fd94c906c17db11",
"md5": "0dae979fb61d87e001bb2dfc7134ef00",
"sha256": "949ce00c0ddd7b7e6aa6cddc187fd5148f6aed9fcc8dc8f4ef1fcb5527237c15"
},
"downloads": -1,
"filename": "pyla_linter-1.3.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0dae979fb61d87e001bb2dfc7134ef00",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 15096,
"upload_time": "2025-08-07T20:23:58",
"upload_time_iso_8601": "2025-08-07T20:23:58.781017Z",
"url": "https://files.pythonhosted.org/packages/64/a7/3441e67f7c853da3df24e764f988399922c339864f105fd94c906c17db11/pyla_linter-1.3.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "76b52189a4135e6a682b8d32ed1bc01f0c643ac198fb1beae81a8b2e1eab3cc1",
"md5": "721f1345196412c3ae33e99331244686",
"sha256": "3e8fd5bc486bca8865caa56c1ed8a5ce8cfa3fb1f1a2a179f2ca7317f24f23d0"
},
"downloads": -1,
"filename": "pyla_linter-1.3.1.tar.gz",
"has_sig": false,
"md5_digest": "721f1345196412c3ae33e99331244686",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 83624,
"upload_time": "2025-08-07T20:24:00",
"upload_time_iso_8601": "2025-08-07T20:24:00.249891Z",
"url": "https://files.pythonhosted.org/packages/76/b5/2189a4135e6a682b8d32ed1bc01f0c643ac198fb1beae81a8b2e1eab3cc1/pyla_linter-1.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-07 20:24:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "langadventurellc",
"github_project": "pyla-linter",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pyla-linter"
}