<p align="center">
<img src="https://raw.githubusercontent.com/guilatrova/tryceratops/main/img/logo.png">
</p>
<h2 align="center">Prevent Exception Handling AntiPatterns in Python</h2>
<p align="center">
<a href="https://github.com/guilatrova/tryceratops/actions"><img alt="Actions Status" src="https://github.com/guilatrova/tryceratops/workflows/CI/badge.svg"></a>
<a href="https://pypi.org/project/tryceratops/"><img alt="PyPI" src="https://img.shields.io/pypi/v/tryceratops"/></a>
<img src="https://badgen.net/pypi/python/tryceratops" />
<a href="https://github.com/relekang/python-semantic-release"><img alt="Semantic Release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg"></a>
<a href="https://github.com/guilatrova/tryceratops/blob/main/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/guilatrova/tryceratops"/></a>
<a href="https://pepy.tech/project/tryceratops/"><img alt="Downloads" src="https://static.pepy.tech/personalized-badge/tryceratops?period=total&units=international_system&left_color=grey&right_color=blue&left_text=%F0%9F%A6%96%20Downloads"/></a>
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"/></a>
<a href="https://github.com/guilatrova/tryceratops"><img alt="try/except style: tryceratops" src="https://img.shields.io/badge/try%2Fexcept%20style-tryceratops%20%F0%9F%A6%96%E2%9C%A8-black" /></a>
<a href="https://twitter.com/intent/user?screen_name=guilatrova"><img alt="Follow guilatrova" src="https://img.shields.io/twitter/follow/guilatrova?style=social"/></a>
</p>
Inspired by [this blog post](https://blog.guilatrova.dev/handling-exceptions-in-python-like-a-pro/). I described [the building process of this tool here](https://blog.guilatrova.dev/project-tryceratops/).
> βFor those who like dinosaurs π¦ and clean try/except β¨ blocks.β
**Summary**
- [Installation and usage](#installation-and-usage)
- [Installation](#installation)
- [Usage](#usage)
- [`flake8` Plugin](#flake8-plugin)
- [Violations](#violations)
- [Autofix support](#autofix-support)
- [Ignoring violations](#ignoring-violations)
- [Configuration](#configuration)
- [Pre-commit](#pre-commit)
- [Show your style](#show-your-style)
- [Extra Resources](#extra-resources)
- [Contributing](#contributing)
- [Change log](#change-log)
- [License](#license)
- [Credits](#credits)
---
## Installation and usage
### Installation
```
pip install tryceratops
```
OR
```
poetry add -D tryceratops
```
### Usage
```
tryceratops [filename or dir...]
```
You can enable experimental analyzers by running:
```
tryceratops --experimental [filename or dir...]
```
You can ignore specific violations by using: `--ignore TRYXXX` repeatedly:
```
tryceratops --ignore TRY201 --ignore TRY202 [filename or dir...]
```
You can exclude dirs by using: `--exclude dir/path` repeatedly:
```
tryceratops --exclude tests --exclude .venv [filename or dir...]
```
You can also autofix some violations:
```
tryceratops --autofix [filename or dir...]
```
![example](https://raw.githubusercontent.com/guilatrova/tryceratops/main/img/tryceratops-example3.gif)
### [`flake8`](https://github.com/PyCQA/flake8) Plugin
π¦ Tryceratops is also a plugin for `flake8`, so you can:
```
β― flake8 --select TRY src/tests/samples/violations/call_raise_vanilla.py
src/tests/samples/violations/call_raise_vanilla.py:13:9: TRY002 Create your own exception
src/tests/samples/violations/call_raise_vanilla.py:13:9: TRY003 Avoid specifying long messages outside the exception class
src/tests/samples/violations/call_raise_vanilla.py:21:9: TRY201 Simply use 'raise' without specifying exception object again
```
## Violations
All violations and its descriptions can be found in [docs](https://github.com/guilatrova/tryceratops/tree/main/docs/violations).
### Autofix support
So far, autofix only supports violations: [TRY200](docs/violations/TRY200.md), [TRY201](docs/violations/TRY201.md), and [TRY400](docs/violations/TRY400.md).
### Ignoring violations
If you want to ignore a violation in a specific file, you can either:
- Add a comment with `noqa` to the top of the file you want to ignore
- Add a comment with `noqa` to the line you want to ignore
- Add a comment with `noqa: CODE` to the line you want to ignore a specific violation
Example:
```py
def verbose_reraise_1():
try:
a = 1
except Exception as ex:
raise ex # noqa: TRY202
```
### Configuration
You can set up a `pyproject.toml` file to set rules.
This is useful to avoid reusing the same CLI flags over and over again and helps to define the structure of your project.
Example:
```toml
[tool.tryceratops]
exclude = ["samples"]
ignore = ["TRY002", "TRY200", "TRY300"]
experimental = false
check_pickable = false
allowed_base_exceptions = ["MyAppBase"]
```
CLI flags always overwrite the config file.
## Pre-commit
If you wish to use pre-commit, add this:
```yaml
- repo: https://github.com/guilatrova/tryceratops
rev: v2.4.1
hooks:
- id: tryceratops
```
## Show your style
[![try/except style: tryceratops](https://img.shields.io/badge/try%2Fexcept%20style-tryceratops%20%F0%9F%A6%96%E2%9C%A8-black)](https://github.com/guilatrova/tryceratops)
Add this fancy badge to your project's `README.md`:
```md
[![try/except style: tryceratops](https://img.shields.io/badge/try%2Fexcept%20style-tryceratops%20%F0%9F%A6%96%E2%9C%A8-black)](https://github.com/guilatrova/tryceratops)
```
## Extra Resources
If you want to read more about:
- [How to structure exceptions in Python π ποΈ π£](https://blog.guilatrova.dev/how-to-structure-exception-in-python-like-a-pro/)
- [How to log in Python ππ΄](https://blog.guilatrova.dev/how-to-log-in-python-like-a-pro/)
- [Book: Effective Python](https://amzn.to/3bEVHpG)
## Contributing
Thank you for considering making Tryceratops better for everyone!
Refer to [Contributing docs](docs/CONTRIBUTING.md).
## Change log
See [CHANGELOG](CHANGELOG.md).
## License
MIT
## Credits
Thanks to God for the inspiration π βοΈ βοΈ
The [black](https://github.com/psf/black) project for insights.
Raw data
{
"_id": null,
"home_page": "https://github.com/guilatrova/tryceratops",
"name": "tryceratops",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8.1",
"maintainer_email": null,
"keywords": "lint, try, except",
"author": "Guilherme Latrova",
"author_email": "hello@guilatrova.dev",
"download_url": "https://files.pythonhosted.org/packages/2a/d3/43c2c190bb6b01decc92d87538b451d7fe8070aaaf18aa1e166bf432754e/tryceratops-2.4.1.tar.gz",
"platform": null,
"description": "<p align=\"center\">\n <img src=\"https://raw.githubusercontent.com/guilatrova/tryceratops/main/img/logo.png\">\n</p>\n\n<h2 align=\"center\">Prevent Exception Handling AntiPatterns in Python</h2>\n\n<p align=\"center\">\n <a href=\"https://github.com/guilatrova/tryceratops/actions\"><img alt=\"Actions Status\" src=\"https://github.com/guilatrova/tryceratops/workflows/CI/badge.svg\"></a>\n <a href=\"https://pypi.org/project/tryceratops/\"><img alt=\"PyPI\" src=\"https://img.shields.io/pypi/v/tryceratops\"/></a>\n <img src=\"https://badgen.net/pypi/python/tryceratops\" />\n <a href=\"https://github.com/relekang/python-semantic-release\"><img alt=\"Semantic Release\" src=\"https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg\"></a>\n <a href=\"https://github.com/guilatrova/tryceratops/blob/main/LICENSE\"><img alt=\"GitHub\" src=\"https://img.shields.io/github/license/guilatrova/tryceratops\"/></a>\n <a href=\"https://pepy.tech/project/tryceratops/\"><img alt=\"Downloads\" src=\"https://static.pepy.tech/personalized-badge/tryceratops?period=total&units=international_system&left_color=grey&right_color=blue&left_text=%F0%9F%A6%96%20Downloads\"/></a>\n <a href=\"https://github.com/psf/black\"><img alt=\"Code style: black\" src=\"https://img.shields.io/badge/code%20style-black-000000.svg\"/></a>\n <a href=\"https://github.com/guilatrova/tryceratops\"><img alt=\"try/except style: tryceratops\" src=\"https://img.shields.io/badge/try%2Fexcept%20style-tryceratops%20%F0%9F%A6%96%E2%9C%A8-black\" /></a>\n <a href=\"https://twitter.com/intent/user?screen_name=guilatrova\"><img alt=\"Follow guilatrova\" src=\"https://img.shields.io/twitter/follow/guilatrova?style=social\"/></a>\n</p>\n\nInspired by [this blog post](https://blog.guilatrova.dev/handling-exceptions-in-python-like-a-pro/). I described [the building process of this tool here](https://blog.guilatrova.dev/project-tryceratops/).\n\n> \u201cFor those who like dinosaurs \ud83e\udd96 and clean try/except \u2728 blocks.\u201d\n\n**Summary**\n- [Installation and usage](#installation-and-usage)\n - [Installation](#installation)\n - [Usage](#usage)\n - [`flake8` Plugin](#flake8-plugin)\n- [Violations](#violations)\n - [Autofix support](#autofix-support)\n - [Ignoring violations](#ignoring-violations)\n - [Configuration](#configuration)\n- [Pre-commit](#pre-commit)\n- [Show your style](#show-your-style)\n- [Extra Resources](#extra-resources)\n- [Contributing](#contributing)\n- [Change log](#change-log)\n- [License](#license)\n- [Credits](#credits)\n\n---\n\n## Installation and usage\n\n### Installation\n\n```\npip install tryceratops\n```\n\nOR\n\n```\npoetry add -D tryceratops\n```\n\n### Usage\n\n```\ntryceratops [filename or dir...]\n```\n\nYou can enable experimental analyzers by running:\n\n```\ntryceratops --experimental [filename or dir...]\n```\n\nYou can ignore specific violations by using: `--ignore TRYXXX` repeatedly:\n\n```\ntryceratops --ignore TRY201 --ignore TRY202 [filename or dir...]\n```\n\nYou can exclude dirs by using: `--exclude dir/path` repeatedly:\n\n```\ntryceratops --exclude tests --exclude .venv [filename or dir...]\n```\n\nYou can also autofix some violations:\n\n```\ntryceratops --autofix [filename or dir...]\n```\n\n![example](https://raw.githubusercontent.com/guilatrova/tryceratops/main/img/tryceratops-example3.gif)\n\n### [`flake8`](https://github.com/PyCQA/flake8) Plugin\n\n\ud83e\udd96 Tryceratops is also a plugin for `flake8`, so you can:\n\n```\n\u276f flake8 --select TRY src/tests/samples/violations/call_raise_vanilla.py\nsrc/tests/samples/violations/call_raise_vanilla.py:13:9: TRY002 Create your own exception\nsrc/tests/samples/violations/call_raise_vanilla.py:13:9: TRY003 Avoid specifying long messages outside the exception class\nsrc/tests/samples/violations/call_raise_vanilla.py:21:9: TRY201 Simply use 'raise' without specifying exception object again\n```\n\n## Violations\n\nAll violations and its descriptions can be found in [docs](https://github.com/guilatrova/tryceratops/tree/main/docs/violations).\n\n### Autofix support\n\nSo far, autofix only supports violations: [TRY200](docs/violations/TRY200.md), [TRY201](docs/violations/TRY201.md), and [TRY400](docs/violations/TRY400.md).\n\n### Ignoring violations\n\nIf you want to ignore a violation in a specific file, you can either:\n\n- Add a comment with `noqa` to the top of the file you want to ignore\n- Add a comment with `noqa` to the line you want to ignore\n- Add a comment with `noqa: CODE` to the line you want to ignore a specific violation\n\nExample:\n\n```py\ndef verbose_reraise_1():\n try:\n a = 1\n except Exception as ex:\n raise ex # noqa: TRY202\n```\n\n### Configuration\n\nYou can set up a `pyproject.toml` file to set rules.\nThis is useful to avoid reusing the same CLI flags over and over again and helps to define the structure of your project.\n\nExample:\n\n```toml\n[tool.tryceratops]\nexclude = [\"samples\"]\nignore = [\"TRY002\", \"TRY200\", \"TRY300\"]\nexperimental = false\ncheck_pickable = false\nallowed_base_exceptions = [\"MyAppBase\"]\n```\n\nCLI flags always overwrite the config file.\n\n## Pre-commit\n\nIf you wish to use pre-commit, add this:\n\n```yaml\n - repo: https://github.com/guilatrova/tryceratops\n rev: v2.4.1\n hooks:\n - id: tryceratops\n```\n\n## Show your style\n\n[![try/except style: tryceratops](https://img.shields.io/badge/try%2Fexcept%20style-tryceratops%20%F0%9F%A6%96%E2%9C%A8-black)](https://github.com/guilatrova/tryceratops)\n\nAdd this fancy badge to your project's `README.md`:\n\n```md\n[![try/except style: tryceratops](https://img.shields.io/badge/try%2Fexcept%20style-tryceratops%20%F0%9F%A6%96%E2%9C%A8-black)](https://github.com/guilatrova/tryceratops)\n```\n\n## Extra Resources\n\nIf you want to read more about:\n\n- [How to structure exceptions in Python \ud83d\udc0d \ud83c\udfd7\ufe0f \ud83d\udca3](https://blog.guilatrova.dev/how-to-structure-exception-in-python-like-a-pro/)\n- [How to log in Python \ud83d\udc0d\ud83c\udf34](https://blog.guilatrova.dev/how-to-log-in-python-like-a-pro/)\n- [Book: Effective Python](https://amzn.to/3bEVHpG)\n\n## Contributing\n\nThank you for considering making Tryceratops better for everyone!\n\nRefer to [Contributing docs](docs/CONTRIBUTING.md).\n\n## Change log\n\nSee [CHANGELOG](CHANGELOG.md).\n\n## License\n\nMIT\n\n## Credits\n\nThanks to God for the inspiration \ud83d\ude4c \u2601\ufe0f \u2600\ufe0f\n\nThe [black](https://github.com/psf/black) project for insights.\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Prevent Exception Handling AntiPatterns",
"version": "2.4.1",
"project_urls": {
"Changelog": "https://github.com/guilatrova/tryceratops/blob/main/CHANGELOG.md",
"Homepage": "https://github.com/guilatrova/tryceratops",
"Repository": "https://github.com/guilatrova/tryceratops"
},
"split_keywords": [
"lint",
" try",
" except"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "27b588caeba349f17b7fd37b61bc88f81c138b3b5149b4e2a9deec66eaad1bdb",
"md5": "f732887eadbf71f6552763bfe17cb919",
"sha256": "271b92367be89b243918a56361618607d2a9aa4aa4ba766ecfabd5f98c00480c"
},
"downloads": -1,
"filename": "tryceratops-2.4.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f732887eadbf71f6552763bfe17cb919",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8.1",
"size": 27378,
"upload_time": "2024-10-30T16:42:38",
"upload_time_iso_8601": "2024-10-30T16:42:38.914132Z",
"url": "https://files.pythonhosted.org/packages/27/b5/88caeba349f17b7fd37b61bc88f81c138b3b5149b4e2a9deec66eaad1bdb/tryceratops-2.4.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2ad343c2c190bb6b01decc92d87538b451d7fe8070aaaf18aa1e166bf432754e",
"md5": "79aa0f3f446a75ee7ffbde2285efc88d",
"sha256": "fbfc14650004e27cd1e55ebb7c76b43ced04a4d3b4cbe42aac9d71e4623ed84d"
},
"downloads": -1,
"filename": "tryceratops-2.4.1.tar.gz",
"has_sig": false,
"md5_digest": "79aa0f3f446a75ee7ffbde2285efc88d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8.1",
"size": 20595,
"upload_time": "2024-10-30T16:42:40",
"upload_time_iso_8601": "2024-10-30T16:42:40.970713Z",
"url": "https://files.pythonhosted.org/packages/2a/d3/43c2c190bb6b01decc92d87538b451d7fe8070aaaf18aa1e166bf432754e/tryceratops-2.4.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-30 16:42:40",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "guilatrova",
"github_project": "tryceratops",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "tryceratops"
}