{ "info": { "author": "Valentin Lab", "author_email": "valentin.lab@kalysto.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Version Control" ], "description": "=========================\nkids.file\n=========================\n\n.. image:: http://img.shields.io/pypi/v/kids.file.svg?style=flat\n :target: https://pypi.python.org/pypi/kids.file/\n :alt: Latest PyPI version\n\n.. image:: http://img.shields.io/pypi/dm/kids.file.svg?style=flat\n :target: https://pypi.python.org/pypi/kids.file/\n :alt: Number of PyPI downloads\n\n.. image:: http://img.shields.io/travis/0k/kids.file/master.svg?style=flat\n :target: https://travis-ci.org/0k/kids.file/\n :alt: Travis CI build status\n\n.. image:: http://img.shields.io/coveralls/0k/kids.file/master.svg?style=flat\n :target: https://coveralls.io/r/0k/kids.file\n :alt: Test coverage\n\n\nThis very small module is part of KIDS (Keep It Dead Simple), and proposes some\npython coding shortcuts on very common tasks. Original tasks I've shortcuted\noften requires to know 2 to 10 lines of python or special cases or different\nmodules location.\n\nIt is, for now, a very humble package.\n\n\nMaturity\n========\n\nThis code is in alpha stage. It wasn't tested on Windows. API may change.\nThis is more a draft for an ongoing reflection.\n\n\nDocumentation\n=============\n\n\ntmp, get_contents, put_contents\n-------------------------------\n\nLet's create a new temporary file containing the string 'bonjour'::\n\n >>> import kids.file as kf\n >>> filepath = kf.mk_tmp_file(content='bonjour')\n\n``filepath`` holds the file path of the temporary file. Let's check what is the file\ncontent with ``get_contents``::\n\n >>> kf.get_contents(filepath)\n 'bonjour'\n\nLet's now put some new content in this file, thanks to ``put_contents``::\n\n >>> kf.put_contents(filepath, 'hello\\nfriend')\n >>> kf.get_contents(filepath)\n 'hello\\nfriend'\n\nThis is it.\n\n\nremove files\n------------\n\nTo remove files, you can use ``rm`` (or ``rm`` which is an alias).\n\nThis version works as python ``rm`` with some added usefull behaviors::\n\n >>> kf.rm(filepath)\n\nThe file was removed. But notice if we try it again::\n\n >>> kf.rm(filepath) ## doctest: +ELLIPSIS\n Traceback (most recent call last):\n ...\n FileNotFoundError: [Errno 2] No such file or directory: '...'\n\nTo mimick the behavior of ``rm`` and the usage of its ``-f``, you have also\na ``force`` keyword argument, that will not cast an exception on non-existent\nfile::\n\n >>> kf.rm(filepath, force=True)\n\nWhile it will continue to cast an exception whenever it is NOT a ``file not\nfound`` error::\n\n >>> kf.rm('/', force=True)\n Traceback (most recent call last):\n ...\n IsADirectoryError: [Errno 21] Is a directory: '/'\n\nAnd of course, there's a ``recursive`` argument which remove directories with all\nfiles and subdirectories (as would shell ``rm`` on a Unix like system shell)::\n\n >>> tmp_dirpath = kf.mk_tmp_dir()\n >>> kf.rm(tmp_dirpath, recursive=True)\n >>> kf.rm(tmp_dirpath, recursive=True) ## doctest: +ELLIPSIS\n Traceback (most recent call last):\n ...\n FileNotFoundError: [Errno 2] No such file or directory: '...'\n >>> kf.rm(tmp_dirpath, recursive=True, force=True)\n\nIt supports also multiple files::\n\n >>> filepath1 = kf.mk_tmp_file()\n >>> filepath2 = kf.mk_tmp_file()\n >>> kf.rm([filepath1, filepath2])\n\nAnd of course still catches bad usage, and tries to be clear about it::\n\n >>> kf.rm(filepath1, foo=True)\n Traceback (most recent call last):\n ...\n TypeError: 'rm' got unexpecteds keywords argument foo\n\n\nchown, mkdir, touch\n-------------------\n\nA ``chown`` function is provided, with an optional ``recursive`` keyword argument.\n\nLet's now create a small tree directory (using ``mk_tmp_dir``, ``mkdir``,\n``touch``)::\n\n >>> from os.path import join\n\n >>> tmp_dirpath = kf.mk_tmp_dir()\n >>> base = join(tmp_dirpath, 'base')\n\n >>> kf.mkdir(join(base, 'foo'), recursive=True)\n >>> kf.mkdir([join(base, 'foo', 'bar1'),\n ... join(base, 'foo', 'bar2')])\n >>> kf.touch(join(base, 'plop'))\n >>> kf.touch([join(base, 'foo', 'bar1', 'README'), ])\n\nNotice that both ``mkdir`` and ``touch`` support multiple files at once.\n\n\nWe will mock the legacy ``os.chown`` to see what happens under the hood::\n\n >>> import os\n >>> import minimock\n >>> m = minimock.mock('os.chown')\n\nAnd call ``kids``'s ``chown`` on user 'root'::\n\n >>> kf.chown(base, user='root', recursive=True) ## doctest: +ELLIPSIS\n Called os.chown('.../base/foo', 0, -1)\n Called os.chown('.../base/foo/bar1', 0, -1)\n Called os.chown('.../base/foo/bar1/README', 0, -1)\n Called os.chown('.../base/foo/bar2', 0, -1)\n Called os.chown('.../base/plop', 0, -1)\n\nIt support numerical ids if necessary::\n\n >>> kf.chown(base, gid=0) ## doctest: +ELLIPSIS\n Called os.chown('.../base', -1, 0)\n\nIs equivalent to::\n\n >>> kf.chown(base, group='root') ## doctest: +ELLIPSIS\n Called os.chown('.../base', -1, 0)\n\nYou should of course avoid setting uid and user at the same time::\n\n >>> kf.chown(base, uid=0, user='root') ## doctest: +ELLIPSIS\n Traceback (most recent call last):\n ...\n SyntaxError: uid and user keyword arguments are exclusive.\n\nSame for group and gid::\n\n >>> kf.chown(base, group='root', gid=0) ## doctest: +ELLIPSIS\n Traceback (most recent call last):\n ...\n SyntaxError: gid and group keyword arguments are exclusive.\n\nAnd you must set at least a group or user (numerically or not)::\n\n >>> kf.chown(base) ## doctest: +ELLIPSIS\n Traceback (most recent call last):\n ...\n SyntaxError: No user nor group provided.\n\nLet's clean up our mess::\n\n >>> minimock.restore()\n\n >>> kf.rm(tmp_dirpath, recursive=True)\n\n\nBasename\n--------\n\nThere's a full basename implementation::\n\n >>> kf.basename(\"/path/foo.bar\", \".bar\")\n 'foo'\n >>> kf.basename(\"/path/foo.bar\")\n 'foo.bar'\n\nNote that you can provide multiple suffixes::\n\n >>> kf.basename(\"/path/foo.bar\", (\".foo\", \".bar\"))\n 'foo'\n\nOnly the first matching the end will be removed.\n\n\nnormpath\n--------\n\nGiven a path, it'll return the absolute path::\n\n >>> kf.normpath('../tata' , cwd='/tmp/toto')\n '/tmp/tata'\n\nif you don't give the ``cwd`` argument, it'll default to current\nworking directory.\n\n\nis_empty, exists\n----------------\n\nGiven a file path, it'll return a boolean, and usage is quite\nstraightforward::\n\n >>> tmpdir = kf.mk_tmp_dir()\n\n >>> foo = os.path.join(tmpdir, \"foo\")\n >>> kf.chk.exists(foo)\n False\n >>> try:\n ... kf.chk.is_empty(foo)\n ... except Exception as e:\n ... print(str(e))\n [Errno 2] No such file or directory: '...foo'\n\n >>> kf.touch(foo)\n >>> kf.chk.exists(foo)\n True\n >>> kf.chk.is_empty(foo)\n True\n\n >>> kf.put_contents(foo, \"hello\")\n >>> kf.chk.is_empty(foo)\n False\n\n >>> kf.rm(tmpdir, recursive=True)\n\n\nFile\n----\n\nFile objects in python only offers to read line by line which are for\nsome reason, delimited by ``\\n`` (or equivalent). This is quite\narbitrary, and so ``File`` is an adaptor on any file object to offer\nthe ability to read based on any delimiter.\n\nTo show how it work we'll use ``filify`` which takes a string and\nreturns a file object containing the string. (Yes, this is StringIO,\nbut with additional PY3 love)::\n\n >>> from kids.file import File, filify\n\nTo use ``File``, you should use it as an adaptor, this means you give\nhim a file object, and it'll return his object that will make the\nbridge between his new API and the old API::\n\n >>> f = File(filify(\"a-b-c-d\"))\n\nAs read provides an iterator, here a convenient function to get the\ncontents::\n\n >>> def show(l):\n ... print(\", \".join(l))\n\nSo this is quite straightforward::\n\n >>> show(f.read(delimiter=\"-\"))\n a, b, c, d\n\nThis should work with very large file or records and is very handy for instance\nto parse file (like stdout) that use ``NUL`` separated fields.\n\n\nAdditional Shortcuts\n====================\n\nI'm not sure to keep these shortcuts. I'll see if these are really used often.\n\n\nCompressed file\n---------------\n\nYou should now read this easily::\n\n >>> filepath = kf.mk_tmp_file(content=\"foo\")\n\nLet's zip this file::\n\n >>> zip_filepath = kf.zip(filepath)\n\nThis created a new file along the previvous file. Let's check its contents::\n\n >>> kf.get_contents(zip_filepath, uncompress=\"zlib\")\n 'foo'\n\nAnd now, we can clean up our mess::\n\n >>> kf.rm(filepath, zip_filepath)\n\n\nTests\n=====\n\nWell, this package is really small, and you've just read the tests.\n\nTo execute them, install ``nosetest``, and run::\n\n nosetests\n\n\nContributing\n============\n\nAny suggestion or issue is welcome. Push request are very welcome,\nplease check out the guidelines.\n\n\nPush Request Guidelines\n-----------------------\n\nYou can send any code. I'll look at it and will integrate it myself in\nthe code base and leave you as the author. This process can take time and\nit'll take less time if you follow the following guidelines:\n\n- check your code with PEP8 or pylint. Try to stick to 80 columns wide.\n- separate your commits per smallest concern.\n- each commit should pass the tests (to allow easy bisect)\n- each functionality/bugfix commit should contain the code, tests,\n and doc.\n- prior minor commit with typographic or code cosmetic changes are\n very welcome. These should be tagged in their commit summary with\n ``!minor``.\n- the commit message should follow gitchangelog rules (check the git\n log to get examples)\n- if the commit fixes an issue or finished the implementation of a\n feature, please mention it in the summary.\n\nIf you have some questions about guidelines which is not answered here,\nplease check the current ``git log``, you might find previous commit that\nwould show you how to deal with your issue.\n\n\nLicense\n=======\n\nCopyright (c) 2019 Valentin Lab.\n\nLicensed under the `BSD License`_.\n\n.. _BSD License: http://raw.github.com/0k/kids.file/master/LICENSE\n\nChangelog\n=========\n\n\n0.0.6 (2015-03-11)\n------------------\n\nNew\n~~~\n- Added ``is_empty()`` and ``exists()`` shortcuts. [Valentin Lab]\n\n\n0.0.4 (2015-03-04)\n------------------\n\nNew\n~~~\n- Nearly all commands now support list of filenames. [Valentin Lab]\n\n\n0.0.3 (2015-02-06)\n------------------\n\nNew\n~~~\n- Added ``File`` to read files by chunk delimited by any char. [Valentin\n Lab]\n\n Standard file object's method ``.read()`` return line by line content,\n but there is no way to parse with having a delimiter other than ``\\n``\n or equivalent. This is what ``File`` does.\n\n- Added ``normpath`` that support a ``cwd`` argument. [Valentin Lab]\n- ``basename`` now supports multiple suffixes. [Valentin Lab]\n- [chk] added shortcut ``is_dir`` ``is_file`` ``exists``. [Valentin Lab]\n\n These are only a way to gather them in ``chk`` and rename names\n to follow pep8 conventions.\n\n\n\n0.0.2 (2015-01-20)\n------------------\n\nNew\n~~~\n- [basename] added a full basename support (with suffix removal).\n [Valentin Lab]\n- [chown] walk in alphabetical order and support setting only user or\n group, and support of numerical ids. [Valentin Lab]\n- Big changes to the API, ``rmtree`` now in ``rm``, ``zip_file`` return\n filename. [Valentin Lab]\n\n\n0.0.1 (2013-02-12)\n------------------\n- First import. [Valentin Lab]\n\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/0k/kids.file", "keywords": "", "license": "BSD 3-Clause License", "maintainer": "", "maintainer_email": "", "name": "kids.file", "package_url": "https://pypi.org/project/kids.file/", "platform": "", "project_url": "https://pypi.org/project/kids.file/", "project_urls": { "Homepage": "http://github.com/0k/kids.file" }, "release_url": "https://pypi.org/project/kids.file/0.0.7/", "requires_dist": [ "minimock; extra == 'test'", "nose; extra == 'test'" ], "requires_python": "", "summary": "Kids file management library.", "version": "0.0.7" }, "last_serial": 5049680, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "804eee4c7a38deb8f2a0b389e65a1e14", "sha256": "62d27eddbffe997b30fb490e4ea86b271c4dfcc0b76a626adf4e357af7dece4e" }, "downloads": -1, "filename": "kids.file-0.0.1.tar.gz", "has_sig": false, "md5_digest": "804eee4c7a38deb8f2a0b389e65a1e14", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5903, "upload_time": "2014-05-14T10:00:27", "url": "https://files.pythonhosted.org/packages/c7/0a/0c8cf4d7d8a2506df27e874419198de82145fc2335b351437ba3b05ec53a/kids.file-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "7075f8e2fd236b101f1168d45f4c24d6", "sha256": "1ece14a9f23718f91346c985558675beb700f33531ce768e79f3c2b535e29043" }, "downloads": -1, "filename": "kids.file-0.0.2.tar.gz", "has_sig": false, "md5_digest": "7075f8e2fd236b101f1168d45f4c24d6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8355, "upload_time": "2015-01-20T03:55:35", "url": "https://files.pythonhosted.org/packages/84/8f/d27fcd67ecf9882ed2e288c6bd772e1d0b0716d5651bbad0cdcb4d8bdb2d/kids.file-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "7b569bfcc4aba74360e61e2c3ab1fdbf", "sha256": "cccff8482805a70736b5ec0e7a2d2fa2224fd1c7673d9b5e4339e7ced25eda20" }, "downloads": -1, "filename": "kids.file-0.0.3.tar.gz", "has_sig": false, "md5_digest": "7b569bfcc4aba74360e61e2c3ab1fdbf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11736, "upload_time": "2015-02-06T08:03:37", "url": "https://files.pythonhosted.org/packages/55/e0/b7464796468bbec7620a29440c6016bad43180f514158793a99bc754ed51/kids.file-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "622c85138a5853c3eed24753722e1d7f", "sha256": "73705d668368756158f512d9fe5c664f63f98af938aec53c3cb35f5d683657f0" }, "downloads": -1, "filename": "kids.file-0.0.4.tar.gz", "has_sig": false, "md5_digest": "622c85138a5853c3eed24753722e1d7f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13215, "upload_time": "2015-03-04T10:27:32", "url": "https://files.pythonhosted.org/packages/d4/9f/d5f75926a4d4fbe598f7e0ceb2ff21b21b2c5cc0fa7171143cfb526c17a4/kids.file-0.0.4.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "14de567a47135fa6650cb770abd9faba", "sha256": "9cfc0139293e077e27c4cedf6af64a0566cc8fde8ce572129962093b2276f629" }, "downloads": -1, "filename": "kids.file-0.0.6.tar.gz", "has_sig": false, "md5_digest": "14de567a47135fa6650cb770abd9faba", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13598, "upload_time": "2015-03-11T11:27:27", "url": "https://files.pythonhosted.org/packages/28/c9/ddcd61e4b0b3f8fe0cbe31b492c6df2050edf7a54030b892e46bcc11781c/kids.file-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "95431bb3392915798c25280fa138d64c", "sha256": "7fe42275e1b45820d5abf1638739750c7e8a4b5742a87bedd73e6a123c88f914" }, "downloads": -1, "filename": "kids.file-0.0.7-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "95431bb3392915798c25280fa138d64c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 16825, "upload_time": "2019-04-02T13:20:55", "url": "https://files.pythonhosted.org/packages/c9/61/a4cc3777715954c96e9acebe1dfa9daf9da6dd9801258b9863d1aed32874/kids.file-0.0.7-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "71acd740554bc9c2510afaaac4697e96", "sha256": "7acee1f39c5260d7cd1bffd6785bbb60287e213c7ce68c98728f469636b92c69" }, "downloads": -1, "filename": "kids.file-0.0.7.tar.gz", "has_sig": false, "md5_digest": "71acd740554bc9c2510afaaac4697e96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12616, "upload_time": "2019-04-02T13:20:57", "url": "https://files.pythonhosted.org/packages/38/57/8c00a79bf8bc8ce4fdd3b8eda11992f9bd29f413e643054c062c086737d4/kids.file-0.0.7.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "95431bb3392915798c25280fa138d64c", "sha256": "7fe42275e1b45820d5abf1638739750c7e8a4b5742a87bedd73e6a123c88f914" }, "downloads": -1, "filename": "kids.file-0.0.7-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "95431bb3392915798c25280fa138d64c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 16825, "upload_time": "2019-04-02T13:20:55", "url": "https://files.pythonhosted.org/packages/c9/61/a4cc3777715954c96e9acebe1dfa9daf9da6dd9801258b9863d1aed32874/kids.file-0.0.7-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "71acd740554bc9c2510afaaac4697e96", "sha256": "7acee1f39c5260d7cd1bffd6785bbb60287e213c7ce68c98728f469636b92c69" }, "downloads": -1, "filename": "kids.file-0.0.7.tar.gz", "has_sig": false, "md5_digest": "71acd740554bc9c2510afaaac4697e96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12616, "upload_time": "2019-04-02T13:20:57", "url": "https://files.pythonhosted.org/packages/38/57/8c00a79bf8bc8ce4fdd3b8eda11992f9bd29f413e643054c062c086737d4/kids.file-0.0.7.tar.gz" } ] }