Name | dirlay JSON |
Version |
0.3.0
JSON |
| download |
home_page | None |
Summary | Directory layout object for testing and documentation |
upload_time | 2025-03-03 14:33:03 |
maintainer | None |
docs_url | None |
author | None |
requires_python | !=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7 |
license | MIT |
keywords |
directory
layout
structure
tree
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# dirlay
<!-- docsub: begin -->
<!-- docsub: exec yq '"> " + .project.description' pyproject.toml -->
> Directory layout object for testing and documentation
<!-- docsub: end -->
<!-- docsub: begin -->
<!-- docsub: include docs/badges.md -->
[](https://github.com/makukha/dirlay/blob/main/LICENSE)
[](https://pypi.org/project/dirlay)
[](https://pypi.org/project/dirlay)
[](https://github.com/makukha/dirlay)
[](https://github.com/makukha/dirlay)
[](https://github.com/makukha/multipython)
[](https://github.com/makukha/docsub)
[](http://mypy.readthedocs.io)
[](https://github.com/astral-sh/ruff)
[](https://github.com/astral-sh/ruff)
<!-- docsub: end -->
<!-- docsub: begin -->
<!-- docsub: include docs/features.md -->
# Features
- Create directory tree and files from Python `dict`
- Chdir to tree subdirectories
- Display as rich tree for documentation
- Developer friendly syntax:
- reference nodes by paths: `tree['a/b/c.md']`
- add, update, delete nodes: `tree |= {'d': {}}`, `del tree['a']`
- create tree under given or temporary directory
- `contextmanager` interface to unlink tree on exit
- Fully typed
- Python 2 support (using [pathlib2](https://github.com/jazzband/pathlib2))
<!-- docsub: end -->
# Installation
```shell
$ pip install dirlay[rich]
```
# Usage
<!-- docsub: begin #usage.md -->
<!-- docsub: include docs/usage.md -->
<!-- docsub: begin -->
<!-- docsub: x toc tests/test_usage.py 'Usage.*' -->
* [Create directory layout tree](#create-directory-layout-tree)
* [Chdir to subdirectory](#chdir-to-subdirectory)
* [Print as tree](#print-as-tree)
<!-- docsub: end -->
```pycon
>>> from dirlay import Dir
```
<!-- docsub: begin -->
<!-- docsub: x cases --no-title tests/test_usage.py 'QuickStart' -->
Define directory structure and files content:
```pycon
>>> layout = Dir({'a': {'b/c.txt': 'ccc', 'd.txt': 'ddd'}})
>>> layout.data == {'a': {'b': {'c.txt': 'ccc'}, 'd.txt': 'ddd'}}
True
>>> layout['a/b/c.txt']
<Node 'a/b/c.txt': 'ccc'>
>>> 'z.txt' in layout
False
```
Content of files and directories can be updated:
```pycon
>>> layout |= {'a/d.txt': {'e.txt': 'eee'}}
>>> layout['a/b/c.txt'].data *= 2
>>> layout.root()
<Node '.': {'a': {...}}>
>>> layout.data == {'a': {'b': {'c.txt': 'cccccc'}, 'd.txt': {'e.txt': 'eee'}}}
True
```
Instantiate on the file system (in temporary directory by default) and remove when
exiting the context.
```pycon
>>> with layout.mktree():
... assert getcwd() != layout.basedir # cwd not changed
... str(layout['a/b/c.txt'].path.read_text())
'cccccc'
```
Optionally, change current working directory to a layout subdir, and change back
after context manager is exited.
```pycon
>>> with layout.mktree(chdir='a/b'):
... assert getcwd() == layout.basedir / 'a/b'
... str(Path('c.txt').read_text())
'cccccc'
```
<!-- docsub: end -->
<!-- docsub: begin -->
<!-- docsub: x cases tests/test_usage.py 'Usage.*' -->
## Create directory layout tree
Directory layout can be constructed from dict:
```pycon
>>> layout = Dir({'a': {'b/c.txt': 'ccc', 'd.txt': 'ddd'}})
>>> layout.basedir is None
True
>>> layout.mktree()
<Dir '/tmp/...': {'a': ...}>
>>> layout.basedir
PosixPath('/tmp/...')
```
And remove when not needed anymore:
```pycon
>>> layout.rmtree()
```
## Chdir to subdirectory
```pycon
>>> import os
>>> os.chdir('/tmp')
```
When layout is instantiated, current directory remains unchanged:
```pycon
>>> layout = Dir({'a/b/c.txt': 'ccc'})
>>> layout.mktree()
<Dir '/tmp/...': {'a': {'b': {'c.txt': 'ccc'}}}>
>>> getcwd()
PosixPath('/tmp')
```
On first `chdir`, initial working directory is stored internally, and will be
restored on `destroy`. Without argument, `chdir` sets current directory to
`layout.basedir`.
```pycon
>>> layout.basedir
PosixPath('/tmp/...')
>>> layout.chdir()
>>> getcwd()
PosixPath('/tmp/...')
```
If `chdir` has argument, it must be a path relative to `basedir`.
```pycon
>>> layout.chdir('a/b')
>>> getcwd()
PosixPath('/tmp/.../a/b')
```
When directory is removed, current directory is restored:
```pycon
>>> layout.rmtree()
>>> getcwd()
PosixPath('/tmp')
```
## Print as tree
```pycon
>>> layout = Dir({'a': {'b/c.txt': 'ccc', 'd.txt': 'ddd'}})
>>> layout.print_rich()
📂 .
└── 📂 a
├── 📂 b
│ └── 📄 c.txt
└── 📄 d.txt
```
Display `basedir` path and file content:
```pycon
>>> layout.mktree()
<Dir '/tmp/...': ...>
>>> layout.print_rich(real_basedir=True, show_data=True)
📂 /tmp/...
└── 📂 a
├── 📂 b
│ └── 📄 c.txt
│ â•─────╮
│ │ ccc │
│ ╰─────╯
└── 📄 d.txt
â•─────╮
│ ddd │
╰─────╯
```
Extra keyword arguments will be passed through to `rich.tree.Tree`:
```pycon
>>> layout.print_rich(show_data=True, hide_root=True)
📂 a
├── 📂 b
│ └── 📄 c.txt
│ â•─────╮
│ │ ccc │
│ ╰─────╯
└── 📄 d.txt
â•─────╮
│ ddd │
╰─────╯
>>> layout.rmtree()
```
<!-- docsub: end -->
<!-- docsub: end #usage.md -->
# See also
* [Documentation](https://dirlay.readthedocs.io)
* [Changelog](https://github.com/makukha/dirlay/tree/main/CHANGELOG.md)
* [Issues](https://github.com/makukha/dirlay/issues)
* [License](https://github.com/makukha/dirlay/tree/main/LICENSE)
Raw data
{
"_id": null,
"home_page": null,
"name": "dirlay",
"maintainer": null,
"docs_url": null,
"requires_python": "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7",
"maintainer_email": null,
"keywords": "directory, layout, structure, tree",
"author": null,
"author_email": "Michael Makukha <m.makukha@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/67/64/ff7a028c9d8468338002f26cc3e807f0717d0c209594c0a979a66a863aba/dirlay-0.3.0.tar.gz",
"platform": null,
"description": "# dirlay\n<!-- docsub: begin -->\n<!-- docsub: exec yq '\"> \" + .project.description' pyproject.toml -->\n> Directory layout object for testing and documentation\n<!-- docsub: end -->\n\n<!-- docsub: begin -->\n<!-- docsub: include docs/badges.md -->\n[](https://github.com/makukha/dirlay/blob/main/LICENSE)\n[](https://pypi.org/project/dirlay)\n[](https://pypi.org/project/dirlay)\n[](https://github.com/makukha/dirlay)\n[](https://github.com/makukha/dirlay)\n[](https://github.com/makukha/multipython)\n[](https://github.com/makukha/docsub)\n[](http://mypy.readthedocs.io)\n[](https://github.com/astral-sh/ruff)\n[](https://github.com/astral-sh/ruff)\n<!-- docsub: end -->\n\n\n<!-- docsub: begin -->\n<!-- docsub: include docs/features.md -->\n# Features\n\n- Create directory tree and files from Python `dict`\n- Chdir to tree subdirectories\n- Display as rich tree for documentation\n- Developer friendly syntax:\n - reference nodes by paths: `tree['a/b/c.md']`\n - add, update, delete nodes: `tree |= {'d': {}}`, `del tree['a']`\n - create tree under given or temporary directory\n - `contextmanager` interface to unlink tree on exit\n- Fully typed\n- Python 2 support (using [pathlib2](https://github.com/jazzband/pathlib2))\n<!-- docsub: end -->\n\n\n# Installation\n\n```shell\n$ pip install dirlay[rich]\n```\n\n\n# Usage\n\n<!-- docsub: begin #usage.md -->\n<!-- docsub: include docs/usage.md -->\n<!-- docsub: begin -->\n<!-- docsub: x toc tests/test_usage.py 'Usage.*' -->\n* [Create directory layout tree](#create-directory-layout-tree)\n* [Chdir to subdirectory](#chdir-to-subdirectory)\n* [Print as tree](#print-as-tree)\n<!-- docsub: end -->\n\n```pycon\n>>> from dirlay import Dir\n```\n\n<!-- docsub: begin -->\n<!-- docsub: x cases --no-title tests/test_usage.py 'QuickStart' -->\nDefine directory structure and files content:\n\n```pycon\n>>> layout = Dir({'a': {'b/c.txt': 'ccc', 'd.txt': 'ddd'}})\n>>> layout.data == {'a': {'b': {'c.txt': 'ccc'}, 'd.txt': 'ddd'}}\nTrue\n>>> layout['a/b/c.txt']\n<Node 'a/b/c.txt': 'ccc'>\n>>> 'z.txt' in layout\nFalse\n```\n\nContent of files and directories can be updated:\n\n```pycon\n>>> layout |= {'a/d.txt': {'e.txt': 'eee'}}\n>>> layout['a/b/c.txt'].data *= 2\n>>> layout.root()\n<Node '.': {'a': {...}}>\n>>> layout.data == {'a': {'b': {'c.txt': 'cccccc'}, 'd.txt': {'e.txt': 'eee'}}}\nTrue\n```\n\nInstantiate on the file system (in temporary directory by default) and remove when\nexiting the context.\n\n```pycon\n>>> with layout.mktree():\n... assert getcwd() != layout.basedir # cwd not changed\n... str(layout['a/b/c.txt'].path.read_text())\n'cccccc'\n```\n\nOptionally, change current working directory to a layout subdir, and change back\nafter context manager is exited.\n\n```pycon\n>>> with layout.mktree(chdir='a/b'):\n... assert getcwd() == layout.basedir / 'a/b'\n... str(Path('c.txt').read_text())\n'cccccc'\n```\n\n<!-- docsub: end -->\n\n<!-- docsub: begin -->\n<!-- docsub: x cases tests/test_usage.py 'Usage.*' -->\n## Create directory layout tree\n\nDirectory layout can be constructed from dict:\n\n```pycon\n>>> layout = Dir({'a': {'b/c.txt': 'ccc', 'd.txt': 'ddd'}})\n>>> layout.basedir is None\nTrue\n>>> layout.mktree()\n<Dir '/tmp/...': {'a': ...}>\n>>> layout.basedir\nPosixPath('/tmp/...')\n```\n\nAnd remove when not needed anymore:\n\n```pycon\n>>> layout.rmtree()\n```\n\n## Chdir to subdirectory\n\n```pycon\n>>> import os\n>>> os.chdir('/tmp')\n```\n\nWhen layout is instantiated, current directory remains unchanged:\n\n```pycon\n>>> layout = Dir({'a/b/c.txt': 'ccc'})\n>>> layout.mktree()\n<Dir '/tmp/...': {'a': {'b': {'c.txt': 'ccc'}}}>\n>>> getcwd()\nPosixPath('/tmp')\n```\n\nOn first `chdir`, initial working directory is stored internally, and will be\nrestored on `destroy`. Without argument, `chdir` sets current directory to\n`layout.basedir`.\n\n```pycon\n>>> layout.basedir\nPosixPath('/tmp/...')\n>>> layout.chdir()\n>>> getcwd()\nPosixPath('/tmp/...')\n```\n\nIf `chdir` has argument, it must be a path relative to `basedir`.\n\n```pycon\n>>> layout.chdir('a/b')\n>>> getcwd()\nPosixPath('/tmp/.../a/b')\n```\n\nWhen directory is removed, current directory is restored:\n\n```pycon\n>>> layout.rmtree()\n>>> getcwd()\nPosixPath('/tmp')\n```\n\n## Print as tree\n\n```pycon\n>>> layout = Dir({'a': {'b/c.txt': 'ccc', 'd.txt': 'ddd'}})\n>>> layout.print_rich()\n\ud83d\udcc2 .\n\u2514\u2500\u2500 \ud83d\udcc2 a\n \u251c\u2500\u2500 \ud83d\udcc2 b\n \u2502 \u2514\u2500\u2500 \ud83d\udcc4 c.txt\n \u2514\u2500\u2500 \ud83d\udcc4 d.txt\n```\n\nDisplay `basedir` path and file content:\n\n```pycon\n>>> layout.mktree()\n<Dir '/tmp/...': ...>\n>>> layout.print_rich(real_basedir=True, show_data=True)\n\ud83d\udcc2 /tmp/...\n\u2514\u2500\u2500 \ud83d\udcc2 a\n \u251c\u2500\u2500 \ud83d\udcc2 b\n \u2502 \u2514\u2500\u2500 \ud83d\udcc4 c.txt\n \u2502 \u256d\u2500\u2500\u2500\u2500\u2500\u256e\n \u2502 \u2502 ccc \u2502\n \u2502 \u2570\u2500\u2500\u2500\u2500\u2500\u256f\n \u2514\u2500\u2500 \ud83d\udcc4 d.txt\n \u256d\u2500\u2500\u2500\u2500\u2500\u256e\n \u2502 ddd \u2502\n \u2570\u2500\u2500\u2500\u2500\u2500\u256f\n```\n\nExtra keyword arguments will be passed through to `rich.tree.Tree`:\n\n```pycon\n>>> layout.print_rich(show_data=True, hide_root=True)\n\ud83d\udcc2 a\n\u251c\u2500\u2500 \ud83d\udcc2 b\n\u2502 \u2514\u2500\u2500 \ud83d\udcc4 c.txt\n\u2502 \u256d\u2500\u2500\u2500\u2500\u2500\u256e\n\u2502 \u2502 ccc \u2502\n\u2502 \u2570\u2500\u2500\u2500\u2500\u2500\u256f\n\u2514\u2500\u2500 \ud83d\udcc4 d.txt\n \u256d\u2500\u2500\u2500\u2500\u2500\u256e\n \u2502 ddd \u2502\n \u2570\u2500\u2500\u2500\u2500\u2500\u256f\n\n>>> layout.rmtree()\n```\n\n<!-- docsub: end -->\n<!-- docsub: end #usage.md -->\n\n\n# See also\n\n* [Documentation](https://dirlay.readthedocs.io)\n* [Changelog](https://github.com/makukha/dirlay/tree/main/CHANGELOG.md)\n* [Issues](https://github.com/makukha/dirlay/issues)\n* [License](https://github.com/makukha/dirlay/tree/main/LICENSE)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Directory layout object for testing and documentation",
"version": "0.3.0",
"project_urls": {
"Changelog": "https://github.com/makukha/dirlay/blob/main/CHANGELOG.md",
"Documentation": "https://dirlay.readthedocs.io",
"Homepage": "https://github.com/makukha/dirlay",
"Issues": "https://github.com/makukha/dirlay/issues",
"Repository": "https://github.com/makukha/dirlay"
},
"split_keywords": [
"directory",
" layout",
" structure",
" tree"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "81699bff27bea41789fc0fa668c5ac5ca6881a541ac8cce54c89df7df2862045",
"md5": "363abb27cda30bd0b30c35e99939a394",
"sha256": "f7a6086986dd6e6bf169ac252cd795c84b0cb86162f7ec7ff797c0c7f293f03a"
},
"downloads": -1,
"filename": "dirlay-0.3.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "363abb27cda30bd0b30c35e99939a394",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7",
"size": 13452,
"upload_time": "2025-03-03T14:33:02",
"upload_time_iso_8601": "2025-03-03T14:33:02.121940Z",
"url": "https://files.pythonhosted.org/packages/81/69/9bff27bea41789fc0fa668c5ac5ca6881a541ac8cce54c89df7df2862045/dirlay-0.3.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "6764ff7a028c9d8468338002f26cc3e807f0717d0c209594c0a979a66a863aba",
"md5": "0f045b01a9c752cd81bc47c7ad57649c",
"sha256": "93c231a2c143dc202fc7a2354b2a194f63cd35bf88605efabbc355efe8171367"
},
"downloads": -1,
"filename": "dirlay-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "0f045b01a9c752cd81bc47c7ad57649c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7",
"size": 121672,
"upload_time": "2025-03-03T14:33:03",
"upload_time_iso_8601": "2025-03-03T14:33:03.609440Z",
"url": "https://files.pythonhosted.org/packages/67/64/ff7a028c9d8468338002f26cc3e807f0717d0c209594c0a979a66a863aba/dirlay-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-03-03 14:33:03",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "makukha",
"github_project": "dirlay",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"tox": true,
"lcname": "dirlay"
}