Name | objectcrawler JSON |
Version |
0.0.2
JSON |
| download |
home_page | None |
Summary | simple object crawling debug tool |
upload_time | 2024-04-15 13:36:29 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.7 |
license | None |
keywords |
debug
inspect
inspection
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# objectcrawler
Basic and lightweight python tool for inspecting python objects.
Originally built for objects defining `__slots__`, however it also handles the `__dict__` attribute just fine.
## Installation
1) Create a fork of this repo
2) Clone the forked repo to your machine
3) Install with `pip install ObjectCrawler`
For development you can install using the pip `-e` editable flag.
Feel free to file a pull request if you make any changes!
## Usage
Inspecting an object is simple, import the `Crawler` class and feed it the object in question:
```python
from objectcrawler import Crawler
print(Crawler(...))
```
### Demo
Lets demonstrate this with a simple class:
```python
class Food:
__slots__ = ["name"]
def __init__(self, name: str):
self.name = name
def __repr__(self):
return f"Food({self.name})"
```
After creating an instance of this class, we can inspect it:
```python
from objectcrawler import Crawler
a = Food("Apple")
print(Crawler(a))
```
This will output the following table:
```
────────────┬──────────────┬────────────┬─────────
assignment │ value │ classname │ source
────────────┼──────────────┼────────────┼─────────
~ │ Food(Apple) │ Food │ self
└─ name │ Apple │ str │ Food
```
### Inheritance
The purpose of the `source` column is to display information about inheritance.
If we create a subclass, we can see this behaviour:
```python
class PreparedFood(Food):
__slots__ = ["prep_time"]
def __init__(self, name: str, prep_time: int):
super().__init__(name)
self.prep_time = prep_time
def __repr__(self):
return f"PreparedFood({self.name}, {self.prep_time})"
b = PreparedFood("Pasta", 10)
print(Crawler(b))
```
Giving the following table. Note the `source` column:
```
──────────────┬──────────────────────────┬───────────────┬───────────────
assignment │ value │ classname │ source
──────────────┼──────────────────────────┼───────────────┼───────────────
~ │ PreparedFood(Pasta, 10) │ PreparedFood │ None
├─ prep_time │ 10 │ int │ PreparedFood
└─ name │ Pasta │ str │ Food
```
### Iterators
Iterators are a special case, since they are implicit storage containers, an attempt is made to "unpack" them into the data tree.
lists, tuples, etc. wil have their `assignment` set to the index
dicts, OrderedDicts, etc. will have their `assignment` set to the key (the object must provide a `iter()` method for this functionality)
```python
class Meal:
__slots__ = ["name", "ingredients"]
def __init__(self, name: str, ingredients: list):
self.name = name
self.ingredients = ingredients
ingredients = [
Food("Cheese"),
PreparedFood("Beans", 10),
PreparedFood("Toast", 5)
]
c = Meal("Cheesy Beans on Toast", ingredients)
print(Crawler(c))
```
```
────────────────────┬───────────────────────────────────────────┬───────────────┬───────────────
assignment │ value │ classname │ source
────────────────────┼───────────────────────────────────────────┼───────────────┼───────────────
~ │ <__main__.Meal object at 0x762f4d65de10> │ Meal │ None
├─ name │ Cheesy Beans on Toast │ str │ Meal
└─ ingredients │ iterable: list │ list │ Meal
│ ├─ 0 │ Food(Cheese) │ Food │ Meal
│ │ └─ name │ Cheese │ str │ Food
│ ├─ 1 │ PreparedFood(Beans, 10) │ PreparedFood │ Meal
│ │ ├─ prep_time │ 10 │ int │ PreparedFood
│ │ └─ name │ Beans │ str │ Food
│ └─ 2 │ PreparedFood(Toast, 5) │ PreparedFood │ Meal
│ │ ├─ prep_time │ 5 │ int │ PreparedFood
│ │ └─ name │ Toast │ str │ Food
```
## Differences
If you're trying to debug a class and have one working example of it, you can quickly find the issues by differencing it with a broken version. To do this, you should create two Crawler instances (one working, and one not). You can then "subtract" these objects to reveal the differences.
```python
a = Object(...)
b = Object(...)
crawl_a = Crawler(a)
crawl_b = Crawler(b)
print(crawl_a - crawl_b)
```
This will print out two joined tables with the differences highlighted in red.
## Debug
If you don't trust the output there exists a debug mode for the print which can help you figure out what's going on.
To activate this we should create the actual `Crawler` object and store it in a variable:
```python
crawl = Crawler(c)
```
We can then print the info using the `print()` method. This can take extra args, including `debug`
```python
crawl.print(debug=True)
```
```
────────────────────┬───────────────────────────────────────────┬───────────────┬───────────────┬───────────────────┬───────────────────┬───────────
assignment │ value │ classname │ source │ entity │ parent │ nchildren
────────────────────┼───────────────────────────────────────────┼───────────────┼───────────────┼───────────────────┼───────────────────┼───────────
~ │ <__main__.Meal object at 0x762f4d65de10> │ Meal │ None │ Entity #47004730 │ None │ 2
├─ name │ Cheesy Beans on Toast │ str │ Meal │ Entity #91735648 │ Entity #47004730 │ 0
└─ ingredients │ iterable: list │ list │ Meal │ Entity #43691166 │ Entity #47004730 │ 3
│ ├─ 0 │ Food(Cheese) │ Food │ Meal │ Entity #27979510 │ Entity #43691166 │ 1
│ │ └─ name │ Cheese │ str │ Food │ Entity #27472819 │ Entity #27979510 │ 0
│ ├─ 1 │ PreparedFood(Beans, 10) │ PreparedFood │ Meal │ Entity #62084209 │ Entity #43691166 │ 2
│ │ ├─ prep_time │ 10 │ int │ PreparedFood │ Entity #04848920 │ Entity #62084209 │ 0
│ │ └─ name │ Beans │ str │ Food │ Entity #13535757 │ Entity #62084209 │ 0
│ └─ 2 │ PreparedFood(Toast, 5) │ PreparedFood │ Meal │ Entity #55272230 │ Entity #43691166 │ 2
│ │ ├─ prep_time │ 5 │ int │ PreparedFood │ Entity #32701778 │ Entity #55272230 │ 0
│ │ └─ name │ Toast │ str │ Food │ Entity #67167938 │ Entity #55272230 │ 0
```
### Debug output
To understand what we're seeing here it can be helpful to know what's going on inside this table.
Each row is represented by an `Entity` object. This stores some information about each attribute of the original object, but most importantly it stores the hierarchy of children.
The extra columns added expose this information.
The `entity` column contains part of the hash for the `Entity` in _that row_.
The `parent` column contains part of the hash for the `Entity` that _provided_ the `Entity` in that row.
The `nchildren` column is a counter of how many children that entity has, and is used for tree generation.
## Formatting
Similar to the debug, `print()` can also take some basic formatting arguments, `whitespace` and `branch_len`.
`whitespace` dictates the amount of padding added to the end of each column, whereas `branch_len` controls the length of each "branch" in the tree.
The best way to understand these args is to demonstrate them:
### whitespace
```python
crawl.print(whitespace=10)
```
```
────────────────────────────┬───────────────────────────────────────────────────┬───────────────────────┬───────────────────────
assignment │ value │ classname │ source
────────────────────────────┼───────────────────────────────────────────────────┼───────────────────────┼───────────────────────
~ │ <__main__.Meal object at 0x762f4d65de10> │ Meal │ None
├─ name │ Cheesy Beans on Toast │ str │ Meal
└─ ingredients │ iterable: list │ list │ Meal
│ ├─ 0 │ Food(Cheese) │ Food │ Meal
│ │ └─ name │ Cheese │ str │ Food
│ ├─ 1 │ PreparedFood(Beans, 10) │ PreparedFood │ Meal
│ │ ├─ prep_time │ 10 │ int │ PreparedFood
│ │ └─ name │ Beans │ str │ Food
│ └─ 2 │ PreparedFood(Toast, 5) │ PreparedFood │ Meal
│ │ ├─ prep_time │ 5 │ int │ PreparedFood
│ │ └─ name │ Toast │ str │ Food
```
### branch_len
```python
crawl.print(branch_len=4)
```
```
─────────────────────────────┬───────────────────────────────────────────┬───────────────┬───────────────
assignment │ value │ classname │ source
─────────────────────────────┼───────────────────────────────────────────┼───────────────┼───────────────
~ │ <__main__.Meal object at 0x762f4d65de10> │ Meal │ None
├──── name │ Cheesy Beans on Toast │ str │ Meal
└──── ingredients │ iterable: list │ list │ Meal
│ ├──── 0 │ Food(Cheese) │ Food │ Meal
│ │ └──── name │ Cheese │ str │ Food
│ ├──── 1 │ PreparedFood(Beans, 10) │ PreparedFood │ Meal
│ │ ├──── prep_time │ 10 │ int │ PreparedFood
│ │ └──── name │ Beans │ str │ Food
│ └──── 2 │ PreparedFood(Toast, 5) │ PreparedFood │ Meal
│ │ ├──── prep_time │ 5 │ int │ PreparedFood
│ │ └──── name │ Toast │ str │ Food
```
Raw data
{
"_id": null,
"home_page": null,
"name": "objectcrawler",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "debug, inspect, inspection",
"author": null,
"author_email": "Louis Beal <louis.j.beal@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/74/ea/ad13d4bf7bf00e97aa7bc7a5d1004af48b72122a44c772e5af620f221f12/objectcrawler-0.0.2.tar.gz",
"platform": null,
"description": "# objectcrawler\n\nBasic and lightweight python tool for inspecting python objects.\n\nOriginally built for objects defining `__slots__`, however it also handles the `__dict__` attribute just fine.\n\n## Installation\n\n1) Create a fork of this repo\n2) Clone the forked repo to your machine\n3) Install with `pip install ObjectCrawler`\n\nFor development you can install using the pip `-e` editable flag.\n\nFeel free to file a pull request if you make any changes!\n\n## Usage\n\nInspecting an object is simple, import the `Crawler` class and feed it the object in question:\n\n```python\nfrom objectcrawler import Crawler\nprint(Crawler(...))\n```\n\n### Demo\n\nLets demonstrate this with a simple class:\n\n```python\nclass Food:\n __slots__ = [\"name\"]\n def __init__(self, name: str):\n self.name = name\n\n def __repr__(self):\n return f\"Food({self.name})\"\n```\n\nAfter creating an instance of this class, we can inspect it:\n\n```python\nfrom objectcrawler import Crawler\na = Food(\"Apple\")\nprint(Crawler(a))\n```\n\nThis will output the following table:\n\n```\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nassignment \u2502 value \u2502 classname \u2502 source\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n~ \u2502 Food(Apple) \u2502 Food \u2502 self\n\u2514\u2500 name \u2502 Apple \u2502 str \u2502 Food\n```\n\n### Inheritance\n\nThe purpose of the `source` column is to display information about inheritance.\n\nIf we create a subclass, we can see this behaviour:\n\n```python\nclass PreparedFood(Food):\n __slots__ = [\"prep_time\"]\n def __init__(self, name: str, prep_time: int):\n super().__init__(name)\n\n self.prep_time = prep_time\n\n def __repr__(self):\n return f\"PreparedFood({self.name}, {self.prep_time})\"\n\nb = PreparedFood(\"Pasta\", 10)\nprint(Crawler(b))\n```\n\nGiving the following table. Note the `source` column:\n\n```\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nassignment \u2502 value \u2502 classname \u2502 source\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n~ \u2502 PreparedFood(Pasta, 10) \u2502 PreparedFood \u2502 None\n\u251c\u2500 prep_time \u2502 10 \u2502 int \u2502 PreparedFood\n\u2514\u2500 name \u2502 Pasta \u2502 str \u2502 Food\n```\n\n### Iterators\n\nIterators are a special case, since they are implicit storage containers, an attempt is made to \"unpack\" them into the data tree.\n\nlists, tuples, etc. wil have their `assignment` set to the index\n\ndicts, OrderedDicts, etc. will have their `assignment` set to the key (the object must provide a `iter()` method for this functionality)\n\n```python\nclass Meal:\n __slots__ = [\"name\", \"ingredients\"]\n def __init__(self, name: str, ingredients: list):\n self.name = name\n self.ingredients = ingredients\n\ningredients = [\n Food(\"Cheese\"),\n PreparedFood(\"Beans\", 10),\n PreparedFood(\"Toast\", 5)\n]\n\nc = Meal(\"Cheesy Beans on Toast\", ingredients)\nprint(Crawler(c))\n```\n\n```\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nassignment \u2502 value \u2502 classname \u2502 source\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n~ \u2502 <__main__.Meal object at 0x762f4d65de10> \u2502 Meal \u2502 None\n\u251c\u2500 name \u2502 Cheesy Beans on Toast \u2502 str \u2502 Meal\n\u2514\u2500 ingredients \u2502 iterable: list \u2502 list \u2502 Meal\n\u2502 \u251c\u2500 0 \u2502 Food(Cheese) \u2502 Food \u2502 Meal\n\u2502 \u2502 \u2514\u2500 name \u2502 Cheese \u2502 str \u2502 Food\n\u2502 \u251c\u2500 1 \u2502 PreparedFood(Beans, 10) \u2502 PreparedFood \u2502 Meal\n\u2502 \u2502 \u251c\u2500 prep_time \u2502 10 \u2502 int \u2502 PreparedFood\n\u2502 \u2502 \u2514\u2500 name \u2502 Beans \u2502 str \u2502 Food\n\u2502 \u2514\u2500 2 \u2502 PreparedFood(Toast, 5) \u2502 PreparedFood \u2502 Meal\n\u2502 \u2502 \u251c\u2500 prep_time \u2502 5 \u2502 int \u2502 PreparedFood\n\u2502 \u2502 \u2514\u2500 name \u2502 Toast \u2502 str \u2502 Food\n```\n\n## Differences\n\nIf you're trying to debug a class and have one working example of it, you can quickly find the issues by differencing it with a broken version. To do this, you should create two Crawler instances (one working, and one not). You can then \"subtract\" these objects to reveal the differences.\n\n```python\na = Object(...)\nb = Object(...)\n\ncrawl_a = Crawler(a)\ncrawl_b = Crawler(b)\n\nprint(crawl_a - crawl_b)\n```\n\nThis will print out two joined tables with the differences highlighted in red.\n\n## Debug\n\nIf you don't trust the output there exists a debug mode for the print which can help you figure out what's going on.\n\nTo activate this we should create the actual `Crawler` object and store it in a variable:\n\n```python\ncrawl = Crawler(c)\n```\nWe can then print the info using the `print()` method. This can take extra args, including `debug`\n\n```python\ncrawl.print(debug=True)\n```\n\n```\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nassignment \u2502 value \u2502 classname \u2502 source \u2502 entity \u2502 parent \u2502 nchildren\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n~ \u2502 <__main__.Meal object at 0x762f4d65de10> \u2502 Meal \u2502 None \u2502 Entity #47004730 \u2502 None \u2502 2\n\u251c\u2500 name \u2502 Cheesy Beans on Toast \u2502 str \u2502 Meal \u2502 Entity #91735648 \u2502 Entity #47004730 \u2502 0\n\u2514\u2500 ingredients \u2502 iterable: list \u2502 list \u2502 Meal \u2502 Entity #43691166 \u2502 Entity #47004730 \u2502 3\n\u2502 \u251c\u2500 0 \u2502 Food(Cheese) \u2502 Food \u2502 Meal \u2502 Entity #27979510 \u2502 Entity #43691166 \u2502 1\n\u2502 \u2502 \u2514\u2500 name \u2502 Cheese \u2502 str \u2502 Food \u2502 Entity #27472819 \u2502 Entity #27979510 \u2502 0\n\u2502 \u251c\u2500 1 \u2502 PreparedFood(Beans, 10) \u2502 PreparedFood \u2502 Meal \u2502 Entity #62084209 \u2502 Entity #43691166 \u2502 2\n\u2502 \u2502 \u251c\u2500 prep_time \u2502 10 \u2502 int \u2502 PreparedFood \u2502 Entity #04848920 \u2502 Entity #62084209 \u2502 0\n\u2502 \u2502 \u2514\u2500 name \u2502 Beans \u2502 str \u2502 Food \u2502 Entity #13535757 \u2502 Entity #62084209 \u2502 0\n\u2502 \u2514\u2500 2 \u2502 PreparedFood(Toast, 5) \u2502 PreparedFood \u2502 Meal \u2502 Entity #55272230 \u2502 Entity #43691166 \u2502 2\n\u2502 \u2502 \u251c\u2500 prep_time \u2502 5 \u2502 int \u2502 PreparedFood \u2502 Entity #32701778 \u2502 Entity #55272230 \u2502 0\n\u2502 \u2502 \u2514\u2500 name \u2502 Toast \u2502 str \u2502 Food \u2502 Entity #67167938 \u2502 Entity #55272230 \u2502 0\n```\n\n### Debug output\n\nTo understand what we're seeing here it can be helpful to know what's going on inside this table.\n\nEach row is represented by an `Entity` object. This stores some information about each attribute of the original object, but most importantly it stores the hierarchy of children.\n\nThe extra columns added expose this information.\n\nThe `entity` column contains part of the hash for the `Entity` in _that row_.\n\nThe `parent` column contains part of the hash for the `Entity` that _provided_ the `Entity` in that row.\n\nThe `nchildren` column is a counter of how many children that entity has, and is used for tree generation.\n\n## Formatting\n\nSimilar to the debug, `print()` can also take some basic formatting arguments, `whitespace` and `branch_len`.\n\n`whitespace` dictates the amount of padding added to the end of each column, whereas `branch_len` controls the length of each \"branch\" in the tree.\n\nThe best way to understand these args is to demonstrate them:\n\n### whitespace\n\n```python\ncrawl.print(whitespace=10)\n```\n\n```\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nassignment \u2502 value \u2502 classname \u2502 source\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n~ \u2502 <__main__.Meal object at 0x762f4d65de10> \u2502 Meal \u2502 None\n\u251c\u2500 name \u2502 Cheesy Beans on Toast \u2502 str \u2502 Meal\n\u2514\u2500 ingredients \u2502 iterable: list \u2502 list \u2502 Meal\n\u2502 \u251c\u2500 0 \u2502 Food(Cheese) \u2502 Food \u2502 Meal\n\u2502 \u2502 \u2514\u2500 name \u2502 Cheese \u2502 str \u2502 Food\n\u2502 \u251c\u2500 1 \u2502 PreparedFood(Beans, 10) \u2502 PreparedFood \u2502 Meal\n\u2502 \u2502 \u251c\u2500 prep_time \u2502 10 \u2502 int \u2502 PreparedFood\n\u2502 \u2502 \u2514\u2500 name \u2502 Beans \u2502 str \u2502 Food\n\u2502 \u2514\u2500 2 \u2502 PreparedFood(Toast, 5) \u2502 PreparedFood \u2502 Meal\n\u2502 \u2502 \u251c\u2500 prep_time \u2502 5 \u2502 int \u2502 PreparedFood\n\u2502 \u2502 \u2514\u2500 name \u2502 Toast \u2502 str \u2502 Food\n\n\n```\n\n### branch_len\n\n```python\ncrawl.print(branch_len=4)\n```\n\n```\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nassignment \u2502 value \u2502 classname \u2502 source\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n~ \u2502 <__main__.Meal object at 0x762f4d65de10> \u2502 Meal \u2502 None\n\u251c\u2500\u2500\u2500\u2500 name \u2502 Cheesy Beans on Toast \u2502 str \u2502 Meal\n\u2514\u2500\u2500\u2500\u2500 ingredients \u2502 iterable: list \u2502 list \u2502 Meal\n\u2502 \u251c\u2500\u2500\u2500\u2500 0 \u2502 Food(Cheese) \u2502 Food \u2502 Meal\n\u2502 \u2502 \u2514\u2500\u2500\u2500\u2500 name \u2502 Cheese \u2502 str \u2502 Food\n\u2502 \u251c\u2500\u2500\u2500\u2500 1 \u2502 PreparedFood(Beans, 10) \u2502 PreparedFood \u2502 Meal\n\u2502 \u2502 \u251c\u2500\u2500\u2500\u2500 prep_time \u2502 10 \u2502 int \u2502 PreparedFood\n\u2502 \u2502 \u2514\u2500\u2500\u2500\u2500 name \u2502 Beans \u2502 str \u2502 Food\n\u2502 \u2514\u2500\u2500\u2500\u2500 2 \u2502 PreparedFood(Toast, 5) \u2502 PreparedFood \u2502 Meal\n\u2502 \u2502 \u251c\u2500\u2500\u2500\u2500 prep_time \u2502 5 \u2502 int \u2502 PreparedFood\n\u2502 \u2502 \u2514\u2500\u2500\u2500\u2500 name \u2502 Toast \u2502 str \u2502 Food\n\n\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "simple object crawling debug tool",
"version": "0.0.2",
"project_urls": {
"Documentation": "https://github.com/ljbeal/ObjectCrawler",
"Homepage": "https://github.com/ljbeal/ObjectCrawler",
"Issues": "https://github.com/ljbeal/ObjectCrawler/issues",
"Repository": "https://github.com/ljbeal/ObjectCrawler"
},
"split_keywords": [
"debug",
" inspect",
" inspection"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bf3da199d767f7faa61ab73bd332bb358f663c647a45b89abf6ccf6a0166ffc6",
"md5": "5ba18163a4f081eb45ae18814699acc3",
"sha256": "ab2cdc7a86e976f3c95d227b8254eaf3277d963641671ee78425204bade609d3"
},
"downloads": -1,
"filename": "objectcrawler-0.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5ba18163a4f081eb45ae18814699acc3",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 10062,
"upload_time": "2024-04-15T13:36:28",
"upload_time_iso_8601": "2024-04-15T13:36:28.803712Z",
"url": "https://files.pythonhosted.org/packages/bf/3d/a199d767f7faa61ab73bd332bb358f663c647a45b89abf6ccf6a0166ffc6/objectcrawler-0.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "74eaad13d4bf7bf00e97aa7bc7a5d1004af48b72122a44c772e5af620f221f12",
"md5": "8e9c818a04aab82fd54199f266c65520",
"sha256": "c28b50ed3e13a029dfb0331d6541afc9bf1e7f8ea6eaf5f77a045c50ee0b6100"
},
"downloads": -1,
"filename": "objectcrawler-0.0.2.tar.gz",
"has_sig": false,
"md5_digest": "8e9c818a04aab82fd54199f266c65520",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 12469,
"upload_time": "2024-04-15T13:36:29",
"upload_time_iso_8601": "2024-04-15T13:36:29.942000Z",
"url": "https://files.pythonhosted.org/packages/74/ea/ad13d4bf7bf00e97aa7bc7a5d1004af48b72122a44c772e5af620f221f12/objectcrawler-0.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-15 13:36:29",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ljbeal",
"github_project": "ObjectCrawler",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "objectcrawler"
}