# printree
[![Python CI](https://github.com/chrizzFTD/printree/actions/workflows/python-package.yml/badge.svg)](https://github.com/chrizzFTD/printree/actions/workflows/python-package.yml)
[![Coverage Status](https://coveralls.io/repos/github/chrizzFTD/printree/badge.svg?branch=master)](https://coveralls.io/github/chrizzFTD/printree?branch=master)
[![Documentation Status](https://readthedocs.org/projects/printree/badge/?version=latest)](https://printree.readthedocs.io/en/latest/?badge=latest)
[![PyPI version](https://badge.fury.io/py/printree.svg)](https://badge.fury.io/py/printree)
[![PyPI](https://img.shields.io/pypi/pyversions/printree.svg)](https://pypi.python.org/pypi/printree)
Tree-like formatting for arbitrary python data structures.
## Instalation
```bash
pip install printree
```
## Usage
`printree` aims to be similar to pretty print ([pprint](https://docs.python.org/3/library/pprint.html)) with a format inspired by the [tree command](https://en.wikipedia.org/wiki/Tree_%28command%29):
```python
>>> from printree import ptree, ftree
>>> ptree({"x", len, 42}) # will print to the output console
┐
├── 0: x
├── 1: <built-in function len>
└── 2: 42
>>> ftree({"x", len, 42}) # will return a string representation
'┐\n├── 0: x\n├── 1: <built-in function len>\n└── 2: 42'
```
Instances of [abc.Iterable](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable) (with the exception of [str](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str) & [bytes](https://docs.python.org/3/library/stdtypes.html#bytes-objects)) will be represented as branches.
All other objects will be considered leaf nodes:
```python
>>> from printree import ptree
>>> dct = {
... "foo": [],
... True: {
... "uno": {"ABC", "XYZ"},
... "dos": r"B:\newline\tab\like.ext",
... "tres": {
... "leaf": b"bytes",
... "numbers": (42, -17, 0.01)
... },
... },
... ("tuple", "as", "key"):
... {"multi\nlined\n\ttabbed key": "multi\nline\n\ttabbed value"}
... }
>>> dct["recursion"] = [1, dct, 2]
>>> ptree(dct)
┐
├── foo
├── True
│ ├── uno
│ │ ├── 0: XYZ
│ │ └── 1: ABC
│ ├── dos: B:\newline\tab\like.ext
│ └── tres
│ ├── leaf: b'bytes'
│ └── numbers
│ ├── 0: 42
│ ├── 1: -17
│ └── 2: 0.01
├── ('tuple', 'as', 'key')
│ └── multi
│ lined
│ tabbed key: multi
│ line
│ tabbed value
└── recursion
├── 0: 1
├── 1: <Recursion on dict with id=2414949505984>
└── 2: 2
```
The `annotated` and `depth` arguments modify verbosity of the output when creating the tree representation:
```python
>>> ptree(dct, depth=2, annotated=True)
┐ → dict[items=4]
├── foo → list[empty]
├── True → dict[items=3]
│ ├── uno → set[items=2] [...]
│ ├── dos: B:\newline\tab\like.ext
│ └── tres → dict[items=2] [...]
├── ('tuple', 'as', 'key') → dict[items=1]
│ └── multi
│ lined
│ tabbed key: multi
│ line
│ tabbed value
└── recursion → list[items=3]
├── 0: 1
├── 1: <Recursion on dict with id=2414949505984>
└── 2: 2
```
## Customizing formatting
`TreePrinter` subclasses can change each of the string representations of the tree. The subclass `AsciiPrinter` is provided as an example:
```python
>>> from printree import AsciiPrinter
>>> obj = [42, {"foo": (True, False)}]
>>> AsciiPrinter(annotated=True).ptree(obj)
. -> list[items=2]
|-- 0: 42
`-- 1 -> dict[items=1]
`-- foo -> tuple[items=2]
|-- 0: True
`-- 1: False
```
The main members to override are:
- `ROOT`
- `EDGE`
- `BRANCH_NEXT`
- `BRANCH_LAST`
- `ARROW`
The `level` attribute will be automatically set on the printer instance to indicate the current depth in the traversal of the tree.
To print each branch level with a different color, something like the following could be implemented:
```python
from printree import TreePrinter
class ColoredTree(TreePrinter):
colors = {
0: '\033[31m', # red
1: '\033[32m', # green
2: '\033[33m', # yellow
3: '\033[36m', # cyan
4: '\033[35m', # magenta
}
_RESET = '\033[0m'
def __getattribute__(self, item):
if item in ("EDGE", "BRANCH_NEXT", "BRANCH_LAST"):
return f"{self.color}{getattr(super(), item)}{self._RESET}"
return super().__getattribute__(item)
@property
def color(self):
return self.colors[self.level % len(self.colors)]
@property
def ROOT(self): # for root (level 0), prefer the color of the children (level 1)
return f'{self.colors[1]}{super().ROOT}{self._RESET}'
multiline = {"foo": {False: {"AB\nCD": "xy", 42:len}, True: []}, ("bar",): []}
dct = {"A": multiline, "B": (multiline,), "C\nD": "x\ny", "F": (1, "2")}
import os
os.system("") # required on windows only
ColoredTree().ptree(dct)
```
Which outputs:
![](https://raw.githubusercontent.com/chrizzFTD/printree/master/colored_example.svg)
Raw data
{
"_id": null,
"home_page": "https://github.com/chrizzFTD/printree",
"name": "printree",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "pprint pformat ptree pretty print tree format formatting",
"author": "Christian L\u00f3pez Barr\u00f3n",
"author_email": "chris.gfz@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/4a/c9/40e508c5539ae7b0e846f20d2b9de88496ed4845b5e27f19c22dcb8c4cf3/printree-0.2.1.tar.gz",
"platform": null,
"description": "# printree\r\n\r\n[![Python CI](https://github.com/chrizzFTD/printree/actions/workflows/python-package.yml/badge.svg)](https://github.com/chrizzFTD/printree/actions/workflows/python-package.yml)\r\n[![Coverage Status](https://coveralls.io/repos/github/chrizzFTD/printree/badge.svg?branch=master)](https://coveralls.io/github/chrizzFTD/printree?branch=master)\r\n[![Documentation Status](https://readthedocs.org/projects/printree/badge/?version=latest)](https://printree.readthedocs.io/en/latest/?badge=latest)\r\n[![PyPI version](https://badge.fury.io/py/printree.svg)](https://badge.fury.io/py/printree)\r\n[![PyPI](https://img.shields.io/pypi/pyversions/printree.svg)](https://pypi.python.org/pypi/printree)\r\n\r\nTree-like formatting for arbitrary python data structures.\r\n\r\n## Instalation\r\n```bash\r\npip install printree\r\n```\r\n\r\n## Usage\r\n`printree` aims to be similar to pretty print ([pprint](https://docs.python.org/3/library/pprint.html)) with a format inspired by the [tree command](https://en.wikipedia.org/wiki/Tree_%28command%29):\r\n\r\n```python\r\n>>> from printree import ptree, ftree\r\n>>> ptree({\"x\", len, 42}) # will print to the output console\r\n\u2510\r\n\u251c\u2500\u2500 0: x\r\n\u251c\u2500\u2500 1: <built-in function len>\r\n\u2514\u2500\u2500 2: 42\r\n>>> ftree({\"x\", len, 42}) # will return a string representation\r\n'\u2510\\n\u251c\u2500\u2500 0: x\\n\u251c\u2500\u2500 1: <built-in function len>\\n\u2514\u2500\u2500 2: 42'\r\n```\r\n\r\nInstances of [abc.Iterable](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable) (with the exception of [str](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str) & [bytes](https://docs.python.org/3/library/stdtypes.html#bytes-objects)) will be represented as branches.\r\nAll other objects will be considered leaf nodes:\r\n```python\r\n>>> from printree import ptree\r\n>>> dct = {\r\n... \"foo\": [],\r\n... True: {\r\n... \"uno\": {\"ABC\", \"XYZ\"},\r\n... \"dos\": r\"B:\\newline\\tab\\like.ext\",\r\n... \"tres\": {\r\n... \"leaf\": b\"bytes\",\r\n... \"numbers\": (42, -17, 0.01)\r\n... },\r\n... },\r\n... (\"tuple\", \"as\", \"key\"):\r\n... {\"multi\\nlined\\n\\ttabbed key\": \"multi\\nline\\n\\ttabbed value\"}\r\n... }\r\n>>> dct[\"recursion\"] = [1, dct, 2]\r\n>>> ptree(dct)\r\n\u2510\r\n\u251c\u2500\u2500 foo\r\n\u251c\u2500\u2500 True\r\n\u2502 \u251c\u2500\u2500 uno\r\n\u2502 \u2502 \u251c\u2500\u2500 0: XYZ\r\n\u2502 \u2502 \u2514\u2500\u2500 1: ABC\r\n\u2502 \u251c\u2500\u2500 dos: B:\\newline\\tab\\like.ext\r\n\u2502 \u2514\u2500\u2500 tres\r\n\u2502 \u251c\u2500\u2500 leaf: b'bytes'\r\n\u2502 \u2514\u2500\u2500 numbers\r\n\u2502 \u251c\u2500\u2500 0: 42\r\n\u2502 \u251c\u2500\u2500 1: -17\r\n\u2502 \u2514\u2500\u2500 2: 0.01\r\n\u251c\u2500\u2500 ('tuple', 'as', 'key')\r\n\u2502 \u2514\u2500\u2500 multi\r\n\u2502 lined\r\n\u2502 tabbed key: multi\r\n\u2502 line\r\n\u2502 tabbed value\r\n\u2514\u2500\u2500 recursion\r\n \u251c\u2500\u2500 0: 1\r\n \u251c\u2500\u2500 1: <Recursion on dict with id=2414949505984>\r\n \u2514\u2500\u2500 2: 2\r\n```\r\nThe `annotated` and `depth` arguments modify verbosity of the output when creating the tree representation:\r\n```python\r\n>>> ptree(dct, depth=2, annotated=True)\r\n\u2510 \u2192 dict[items=4]\r\n\u251c\u2500\u2500 foo \u2192 list[empty]\r\n\u251c\u2500\u2500 True \u2192 dict[items=3]\r\n\u2502 \u251c\u2500\u2500 uno \u2192 set[items=2] [...]\r\n\u2502 \u251c\u2500\u2500 dos: B:\\newline\\tab\\like.ext\r\n\u2502 \u2514\u2500\u2500 tres \u2192 dict[items=2] [...]\r\n\u251c\u2500\u2500 ('tuple', 'as', 'key') \u2192 dict[items=1]\r\n\u2502 \u2514\u2500\u2500 multi\r\n\u2502 lined\r\n\u2502 tabbed key: multi\r\n\u2502 line\r\n\u2502 tabbed value\r\n\u2514\u2500\u2500 recursion \u2192 list[items=3]\r\n \u251c\u2500\u2500 0: 1\r\n \u251c\u2500\u2500 1: <Recursion on dict with id=2414949505984>\r\n \u2514\u2500\u2500 2: 2\r\n``` \r\n\r\n## Customizing formatting\r\n`TreePrinter` subclasses can change each of the string representations of the tree. The subclass `AsciiPrinter` is provided as an example:\r\n```python\r\n>>> from printree import AsciiPrinter\r\n>>> obj = [42, {\"foo\": (True, False)}]\r\n>>> AsciiPrinter(annotated=True).ptree(obj)\r\n. -> list[items=2]\r\n|-- 0: 42\r\n`-- 1 -> dict[items=1]\r\n `-- foo -> tuple[items=2]\r\n |-- 0: True\r\n `-- 1: False\r\n```\r\nThe main members to override are:\r\n- `ROOT`\r\n- `EDGE`\r\n- `BRANCH_NEXT`\r\n- `BRANCH_LAST`\r\n- `ARROW`\r\n\r\nThe `level` attribute will be automatically set on the printer instance to indicate the current depth in the traversal of the tree.\r\n\r\nTo print each branch level with a different color, something like the following could be implemented:\r\n```python\r\nfrom printree import TreePrinter\r\n\r\nclass ColoredTree(TreePrinter):\r\n colors = {\r\n 0: '\\033[31m', # red\r\n 1: '\\033[32m', # green\r\n 2: '\\033[33m', # yellow\r\n 3: '\\033[36m', # cyan\r\n 4: '\\033[35m', # magenta\r\n }\r\n _RESET = '\\033[0m'\r\n\r\n def __getattribute__(self, item):\r\n if item in (\"EDGE\", \"BRANCH_NEXT\", \"BRANCH_LAST\"):\r\n return f\"{self.color}{getattr(super(), item)}{self._RESET}\"\r\n return super().__getattribute__(item)\r\n\r\n @property\r\n def color(self):\r\n return self.colors[self.level % len(self.colors)]\r\n\r\n @property\r\n def ROOT(self): # for root (level 0), prefer the color of the children (level 1) \r\n return f'{self.colors[1]}{super().ROOT}{self._RESET}'\r\n\r\n\r\nmultiline = {\"foo\": {False: {\"AB\\nCD\": \"xy\", 42:len}, True: []}, (\"bar\",): []}\r\ndct = {\"A\": multiline, \"B\": (multiline,), \"C\\nD\": \"x\\ny\", \"F\": (1, \"2\")}\r\n\r\nimport os\r\nos.system(\"\") # required on windows only\r\n\r\nColoredTree().ptree(dct)\r\n```\r\nWhich outputs:\r\n\r\n![](https://raw.githubusercontent.com/chrizzFTD/printree/master/colored_example.svg)\r\n",
"bugtrack_url": null,
"license": null,
"summary": "Pretty print python objects in a tree format.",
"version": "0.2.1",
"project_urls": {
"Homepage": "https://github.com/chrizzFTD/printree"
},
"split_keywords": [
"pprint",
"pformat",
"ptree",
"pretty",
"print",
"tree",
"format",
"formatting"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bd0eba9a2b70c199b7f0cf374fbe003c4bc36ab8f59f29d89c0559b0bac63f2f",
"md5": "fb1e0f06c584276eec14aa2f3affe6a1",
"sha256": "fa86f76a6df9cf43fb9b8e6b7ca588d808ab106f082dc8dc5afe7676eeb52811"
},
"downloads": -1,
"filename": "printree-0.2.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "fb1e0f06c584276eec14aa2f3affe6a1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 9298,
"upload_time": "2025-01-02T11:15:45",
"upload_time_iso_8601": "2025-01-02T11:15:45.714470Z",
"url": "https://files.pythonhosted.org/packages/bd/0e/ba9a2b70c199b7f0cf374fbe003c4bc36ab8f59f29d89c0559b0bac63f2f/printree-0.2.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "4ac940e508c5539ae7b0e846f20d2b9de88496ed4845b5e27f19c22dcb8c4cf3",
"md5": "80f4e9c6632bfb43ce9bf7d6d5ec89b7",
"sha256": "6c74980256211b9f94abeb77be050d4e5992b5b1e1b147e92d10882ea16947f1"
},
"downloads": -1,
"filename": "printree-0.2.1.tar.gz",
"has_sig": false,
"md5_digest": "80f4e9c6632bfb43ce9bf7d6d5ec89b7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 8389,
"upload_time": "2025-01-02T11:15:48",
"upload_time_iso_8601": "2025-01-02T11:15:48.076609Z",
"url": "https://files.pythonhosted.org/packages/4a/c9/40e508c5539ae7b0e846f20d2b9de88496ed4845b5e27f19c22dcb8c4cf3/printree-0.2.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-01-02 11:15:48",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "chrizzFTD",
"github_project": "printree",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "printree"
}