Find and expose cyclic imports in python projects.
Project description
byecycle 🚲
Find and expose cyclic imports in python projects.
Installation
byecycle
uses the built-in ast module
to parse code files. As a consequence, it can only handle python code within the same
major version (read: no support for python 1 and 2), and the same or lower minor version
of the python interpreter it was installed with. If byecycle
raises SyntaxError
s in
code that you know to be working, try using a byecycle
that is installed with the same
python version that can run the code in question.
From PyPI
Requirements:
- python 3.11 or higher
- pipx
pipx install byecycle
Development Setup
Requirements:
- python 3.11 or higher
- pdm
- git
git clone https://github.com/a-recknagel/byecycle.git
cd byecycle
pdm install -G:all
Usage
As a Command Line Tool
# with a path
byecycle /home/me/dev/byecycle/src/byecycle/
# or the name of an installed package
byecycle byecycle
The result will be a json string:
{
"byecycle.misc": {},
"byecycle.graph": {
"byecycle": {
"tags": [
"vanilla",
"parent"
],
"cycle": "complicated"
},
"byecycle.misc": {
"tags": [
"vanilla"
],
"cycle": null
}
},
[...]
"byecycle": {
"byecycle.graph": {
"tags": [
"vanilla",
"parent"
],
"cycle": "complicated"
}
}
}
By default, the result is printed with some rich formatting to highlight types and such.
If you need the output to be plain ascii, pass the --no-rich
flag.
For bigger projects, you might get much more complex output. The intent of returning
json
is to have something that can be easily piped into e.g. jq
for further
processing:
# filter out imports that don't have a cycle
byecycle byecycle | jq '.[] |= (.[] |= select(.cycle != null) | select(. != {}))'
{
"byecycle.graph": {
"byecycle": {
"tags": [
"parent",
"vanilla"
],
"cycle": "complicated"
}
},
"byecycle.cli": {
"byecycle": {
"tags": [
"parent",
"vanilla"
],
"cycle": "complicated"
}
},
"byecycle": {
"byecycle.graph": {
"tags": [
"parent",
"vanilla"
],
"cycle": "complicated"
},
"byecycle.cli": {
"tags": [
"parent",
"vanilla"
],
"cycle": "complicated"
}
}
}
Alternatively, you can also call the main entrypoint's core functionality as a regular python function. Among other things, it returns a dictionary equivalent to the CLI's json that you can work with:
from byecycle import run
cycles, *_ = run("byecycle")
# filter out imports that don't have a cycle
for outer_k, outer_v in cycles.items():
for inner_k, inner_v in outer_v.items():
if inner_v["cycle"]:
print(f"{outer_k} -> {inner_k}: {inner_v['cycle']}")
byecycle.graph -> byecycle -> complicated
byecycle.cli -> byecycle -> complicated
byecycle -> byecycle.graph -> complicated
byecycle -> byecycle.cli -> complicated
See the help text of byecycle
for an explanation of tags/ImportKind
s and
cycle/EdgeKind
s.
In short, if there is a cycle, the tags of all involved imports inform the cycle-severity, with the highest severity winning out if multiple apply. The defaults can be overriden in order to isolate, filter, or highlight cycles with specific severities.
To Visualize the Import Graph
If you pass the --draw
flag1 on your command-line-call, byecycle
will create an image of
the import graph instead:
byecycle byecycle --draw
[1] Requires installation of the draw
-extra, i.e. pipx install "byecycle[draw]"
.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file byecycle-0.1.5.tar.gz
.
File metadata
- Download URL: byecycle-0.1.5.tar.gz
- Upload date:
- Size: 18.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: pdm/2.15.4 CPython/3.10.12 Linux/6.5.0-1021-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | be2c907b090d27f9699daa7a8dec419d573b59b1ef9413302f013c822e0bdacb |
|
MD5 | e268dfa79cbcb03de1ff0c67a2ff13ea |
|
BLAKE2b-256 | 44b7053810b8f83772d72c8814168b1a010184a7b8146eb0368a33cbd768b63d |
File details
Details for the file byecycle-0.1.5-py3-none-any.whl
.
File metadata
- Download URL: byecycle-0.1.5-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: pdm/2.15.4 CPython/3.10.12 Linux/6.5.0-1021-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a75cf216b0e0ba6f061beb5c94ed1a9a9e080ea6ed93993c71790276da075a89 |
|
MD5 | ad6130096ba3ff4539eba587bc86ba93 |
|
BLAKE2b-256 | 1aa178de79b757bccae010a1eb90bab3998d099c4090f71849ccfccf00c5a71d |