loopsniff


Nameloopsniff JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryA static analysis tool for detecting inefficient SQLAlchemy loops
upload_time2025-02-22 21:58:24
maintainerNone
docs_urlNone
authorJiri Otoupal
requires_python>=3.10
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # LoopSniff

LoopSniff is a static analysis tool that scans your Python code for inefficient iterative processing patterns—especially those involving SQLAlchemy query results. If you’ve ever manually looped over query results to add rows one-by-one or used list comprehensions on query results, LoopSniff will help you identify and optimize these patterns for better performance.

## Features

- **Detects Inefficient Iteration:**  
  Finds for-loops iterating over SQLAlchemy query results where items are added individually using `.add()`, `.append()`, or via augmented assignment (`+=`).

- **List Comprehension Analysis:**  
  Flags list comprehensions that iterate over query results (e.g., `[a for a in session.query(MyModel).all()]`) to help you rethink bulk operations.

- **Extended Pattern Matching:**  
  Recognizes both direct query calls (e.g., `session.query(MyModel)`) and calls via partial functions (e.g., `query = session.query` then `items = query(MyModel).all()`).

- **Additional Inefficiency Warnings:**  
  Detects other performance bottlenecks in loops, such as calling `.commit()`, `.filter()`, `.update()`, etc., inside loops.

- **User-Friendly Output:**  
  Uses the [Rich](https://github.com/Textualize/rich) library for colorful, engaging console output with explanations and code snippets for each issue found.

- **Easy-to-Use CLI:**  
  Built with [Click](https://click.palletsprojects.com/) for a dynamic command-line interface that lets you scan directories with ease.

- **Tested & Reliable:**  
  Comes with comprehensive tests using [pytest](https://docs.pytest.org/), ensuring robust detection across a variety of edge cases.

## Installation

Clone the repository and install the dependencies using pip:

```bash
git clone https://github.com/yourusername/loopsniff.git
cd loopsniff
pip install -r requirements.txt
```

*Note: Make sure your `requirements.txt` includes dependencies such as `click`, `rich`, and `pytest`.*

## Usage

To scan your code for inefficient SQLAlchemy patterns, run:

```bash
loopsniff /path/to/your/project
```

This command recursively scans all `.py` files in the specified directory and prints out a concise, color-coded summary of any detected patterns, along with code snippets and recommendations for improvement.

### Example Output

```
myfile.py | For-loop at line 10 (.add()/.append() at line 11): Iteratively processing 'item' from query 'items' is slow. Consider bulk operations for better performance. | Code: for item in items:
myfile.py | At line 15 (listcomp): List comprehension over query results is suboptimal. Rethink your approach. | Code: [a for a in session.query(MyModel).all()]
```

## Testing

LoopSniff is tested with pytest. To run the tests, simply execute:

```bash
pytest
```

This runs a suite of tests covering various edge cases—from standard for-loops with `.add()`/`.append()` and `+=` to inefficient list comprehensions.

## Contributing

Contributions are welcome! Feel free to open issues or submit pull requests for enhancements, bug fixes, or new features. Please follow standard GitHub contribution guidelines.

## License

This project is licensed under the [MIT License](LICENSE).

## Acknowledgments

- Thanks to the [Rich](https://github.com/Textualize/rich) and [Click](https://click.palletsprojects.com/) communities for their fantastic libraries.
- Inspired by real-world performance challenges in SQLAlchemy-based applications.

---

Happy scanning and optimizing!

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "loopsniff",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": null,
    "author": "Jiri Otoupal",
    "author_email": "jiri-otoupal@ips-database.eu",
    "download_url": "https://files.pythonhosted.org/packages/18/d9/26a9742f789b51f4be954356fa8e23270c20824609b0b8b0d6b25f2bd550/loopsniff-0.1.0.tar.gz",
    "platform": null,
    "description": "# LoopSniff\n\nLoopSniff is a static analysis tool that scans your Python code for inefficient iterative processing patterns\u2014especially those involving SQLAlchemy query results. If you\u2019ve ever manually looped over query results to add rows one-by-one or used list comprehensions on query results, LoopSniff will help you identify and optimize these patterns for better performance.\n\n## Features\n\n- **Detects Inefficient Iteration:**  \n  Finds for-loops iterating over SQLAlchemy query results where items are added individually using `.add()`, `.append()`, or via augmented assignment (`+=`).\n\n- **List Comprehension Analysis:**  \n  Flags list comprehensions that iterate over query results (e.g., `[a for a in session.query(MyModel).all()]`) to help you rethink bulk operations.\n\n- **Extended Pattern Matching:**  \n  Recognizes both direct query calls (e.g., `session.query(MyModel)`) and calls via partial functions (e.g., `query = session.query` then `items = query(MyModel).all()`).\n\n- **Additional Inefficiency Warnings:**  \n  Detects other performance bottlenecks in loops, such as calling `.commit()`, `.filter()`, `.update()`, etc., inside loops.\n\n- **User-Friendly Output:**  \n  Uses the [Rich](https://github.com/Textualize/rich) library for colorful, engaging console output with explanations and code snippets for each issue found.\n\n- **Easy-to-Use CLI:**  \n  Built with [Click](https://click.palletsprojects.com/) for a dynamic command-line interface that lets you scan directories with ease.\n\n- **Tested & Reliable:**  \n  Comes with comprehensive tests using [pytest](https://docs.pytest.org/), ensuring robust detection across a variety of edge cases.\n\n## Installation\n\nClone the repository and install the dependencies using pip:\n\n```bash\ngit clone https://github.com/yourusername/loopsniff.git\ncd loopsniff\npip install -r requirements.txt\n```\n\n*Note: Make sure your `requirements.txt` includes dependencies such as `click`, `rich`, and `pytest`.*\n\n## Usage\n\nTo scan your code for inefficient SQLAlchemy patterns, run:\n\n```bash\nloopsniff /path/to/your/project\n```\n\nThis command recursively scans all `.py` files in the specified directory and prints out a concise, color-coded summary of any detected patterns, along with code snippets and recommendations for improvement.\n\n### Example Output\n\n```\nmyfile.py | For-loop at line 10 (.add()/.append() at line 11): Iteratively processing 'item' from query 'items' is slow. Consider bulk operations for better performance. | Code: for item in items:\nmyfile.py | At line 15 (listcomp): List comprehension over query results is suboptimal. Rethink your approach. | Code: [a for a in session.query(MyModel).all()]\n```\n\n## Testing\n\nLoopSniff is tested with pytest. To run the tests, simply execute:\n\n```bash\npytest\n```\n\nThis runs a suite of tests covering various edge cases\u2014from standard for-loops with `.add()`/`.append()` and `+=` to inefficient list comprehensions.\n\n## Contributing\n\nContributions are welcome! Feel free to open issues or submit pull requests for enhancements, bug fixes, or new features. Please follow standard GitHub contribution guidelines.\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n\n## Acknowledgments\n\n- Thanks to the [Rich](https://github.com/Textualize/rich) and [Click](https://click.palletsprojects.com/) communities for their fantastic libraries.\n- Inspired by real-world performance challenges in SQLAlchemy-based applications.\n\n---\n\nHappy scanning and optimizing!\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A static analysis tool for detecting inefficient SQLAlchemy loops",
    "version": "0.1.0",
    "project_urls": null,
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7fd569c316971bd3f1aadef31e2a3909a07f84da0f98c2eba48e3fd080b6304c",
                "md5": "8bc0ea705295b52056467271526e0239",
                "sha256": "e2a139f83178bff700b40413c9bd58ef00ac1f192d326eac051e8aedbace2f1d"
            },
            "downloads": -1,
            "filename": "loopsniff-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8bc0ea705295b52056467271526e0239",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 7340,
            "upload_time": "2025-02-22T21:58:22",
            "upload_time_iso_8601": "2025-02-22T21:58:22.759227Z",
            "url": "https://files.pythonhosted.org/packages/7f/d5/69c316971bd3f1aadef31e2a3909a07f84da0f98c2eba48e3fd080b6304c/loopsniff-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "18d926a9742f789b51f4be954356fa8e23270c20824609b0b8b0d6b25f2bd550",
                "md5": "b6a6927555797ef22529e98071dfee84",
                "sha256": "54b8d893822bf4e3f6a092866b8aa4d56897e1dfedc1864d950155a4f19093b9"
            },
            "downloads": -1,
            "filename": "loopsniff-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "b6a6927555797ef22529e98071dfee84",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 6470,
            "upload_time": "2025-02-22T21:58:24",
            "upload_time_iso_8601": "2025-02-22T21:58:24.637437Z",
            "url": "https://files.pythonhosted.org/packages/18/d9/26a9742f789b51f4be954356fa8e23270c20824609b0b8b0d6b25f2bd550/loopsniff-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-22 21:58:24",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "loopsniff"
}
        
Elapsed time: 1.29744s