# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['config_file', 'tests']

package_data = \
{'': ['*'],
 'tests': ['templates/ini/*',
           'templates/json/*',
           'templates/toml/*',
           'templates/yaml/*']}

extras_require = \
{'toml': ['tomlkit>=0.6.0,<0.7.0'], 'yaml': ['ruamel.yaml>=0.16.10,<0.17.0']}

setup_kwargs = {
    'name': 'config-file',
    'version': '0.11.0',
    'description': 'Modify configuration files of various formats with the same simple API.',
    'long_description': '# Config File\n\n> Modify configuration files of various formats with the same simple API\n\n![Python Version](https://img.shields.io/pypi/pyversions/config-file.svg)\n[![Version](https://img.shields.io/pypi/v/config-file)](https://pypi.org/project/config-file/)\n[![Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://pypi.org/project/black/)\n[![Documentation Status](https://readthedocs.org/projects/config-file/badge/?version=latest)](https://config-file.readthedocs.io/en/latest/?badge=latest)\n[![Build Status](https://github.com/eugenetriguba/config-file/workflows/python%20package%20CI/badge.svg?branch=master)](https://github.com/eugenetriguba/config-file/actions/)\n[![Codecov](https://codecov.io/gh/eugenetriguba/config-file/graph/badge.svg)](https://codecov.io/gh/eugenetriguba/config-file)\n\n## About Config File\n\nThe Config File project is designed to allow you to easily manipulate your\nconfiguration files with the same simple API whether they are in INI, JSON,\nYAML, or TOML.\n\n## Installation\n\nConfig File is available to download through PyPI.\n\n```bash\n$ pip install config-file\n```\n\n### Installing Extras\n\nIf you want to manipulate YAML and TOML, you\'ll want to download the extras as well.\n\n```bash\n$ pip install config-file[yaml, toml]\n```\n\nYou can also use [Poetry](https://python-poetry.org).\n\n```bash\n$ poetry install config-file -E yaml -E toml\n```\n\n## Usage\n\nFor this overview, let\'s say you have the following `ini` file\nyou want to manipulate.\n\nDo note, however, that the `ini` format is the oddest format that\n`ConfigFile` supports in that it has no formal specification and is\nnot type aware. When retrieving items from the file, it will return\nthem as strings by default. Others are more type aware and do not\nrequire as much type coercion.\n\n```ini\n[section]\nnum_key = 5\nstr_key = blah\nbool_key = true\nlist_key = [1, 2]\n\n[second_section]\ndict_key = { "another_num": 5 }\n```\n\nIt must have a `.ini` extension in order\nfor the package to recognize it and use the correct parser for it.\n\n### Setting up ConfigFile\n\nTo use the package, we import in the `ConfigFile` object. This object\nis the only thing considered to be part of the public API.\n\nWe can set it up by giving it a string or `pathlib.Path` as the argument.\nAny home tildes `~` in the string or `Path` are recognized and converted\nto the full path for us.\n\n```python\nfrom config_file import ConfigFile\n\nconfig = ConfigFile("~/some-project/config.ini")\n```\n\n### Using `get()`\n\nA recurring pattern you\'ll see here is that all methods that\nneed to specify something inside your configuration file will\ndo so using a dot syntax.\n\n#### Retrieving keys and sections\n\nSo to retrieve our `num_key`, we\'d specify the heading and the\nkey separated by a dot. All values will then be retrieved as\nstrings.\n\n```python\nconfig.get(\'section.num_key\')\n>>> \'5\'\n```\n\nWhile we can retrieves keys, we can also retrieve the entire\nsection, which will be returned back to us as a dictionary.\n\n```python\nconfig.get(\'section\')\n>>> {\'num_key\': \'5\', \'str_key\': \'blah\', \'bool_key\': \'true\', \'list_key\': \'[1, 2]\'}\n```\n\nFurthermore, you can also index into the `ConfigFile` object\nto retrieve keys if that is preferred.\n\n```python\nconfig[\'section\'][\'num_key\']\n>>> \'5\'\n```\n\n#### Coercing the return types\n\nHowever, some of these keys are obviously not strings natively.\nIf we are retrieving a particular value of a key, we may want to\ncoerce it right away without doing clunky type conversions after\neach time we retrieve a value. To do this, we can utilize the\n`return_type` keyword argument.\n\n```python\nconfig.get(\'section.num_key\', return_type=int)\n>>> 5\n```\n\nSometimes we don\'t have structures quite that simple though. What\nif we wanted all the values in `section` coerced? For that, we can\nutilize a `parse_types` keyword argument.\n\n```python\nconfig.get(\'section\', parse_types=True)\n>>> {\'num_key\': 5, \'str_key\': \'blah\', \'bool_key\': True, \'list_key\': [1, 2]}\n```\n\nIt also works for regular keys.\n\n```python\nconfig.get(\'section.num_key\', parse_types=True)\n>>> 5\n```\n\n#### Handling non-existent keys\n\nSometimes we want to retrieve a key but are unsure of if it will exist.\nThere are two ways we could handle that.\n\nThe first is the one we\'re used to seeing: catch the error.\n\n```python\ntry:\n    important_value = config.get(\'section.i_do_not_exist\')\nexcept KeyError:\n    important_value = 42\n```\n\nHowever, the `get` method comes with a `default` keyword argument that we\ncan utilze for this purpose.\n\n```python\nconfig.get(\'section.i_do_not_exist\', default=42)\n>>> 42\n```\n\nThis can be handy if you have a default for a particular configuration value.\n\n### Using `set()`\n\nWe can use `set()` to set a existing key\'s value.\n\n```python\nconfig.set(\'section.num_key\', 6)\n```\n\nThe method does not return anything, since there is nothing\nuseful to return. If something goes wrong where it is unable to set\nthe value, an exception will be raised instead. This is the case\nfor most methods on `ConfigFile`, such as `delete()` or `save()`,\nwhere there would be no useful return value to utilize.\n\nWith `set()`, we can also create and set keys that don\'t exist yet.\n\n```python\nconfig.set(\'new_section.new_key\', \'New key value!\')\n```\n\nWould then result in the following section being added to our original file:\n\n```ini\n[new_section]\nnew_key = New key value!\n```\n\nThe exact behavior of how these new keys or sections are added are a bit\ndependent on the file format we\'re using, since every format is a little\ndifferent in it\'s structure and in what it supports. Mostly though, `ini`\nis just the odd one.\n\nIf we try the following in `ini`, which does not support subsections or\nnested keys, we simply get a single section.\n\n```python\nconfig.set("section.sub_section.sub_sub_section.key", 5)\n```\n\n```ini\n[section.sub_section.sub_sub_section]\nkey = 5\n```\n\nLastly, we can set values using an array notation as well. The underlying\ncontent is all manipulated as a dictionary for every file type. If we wanted\nto create a new section, we\'d simply set it to be an empty dictionary.\n\n```python\nconfig[\'new_section\'] = {}\n```\n\nWhich would result to be an empty section:\n\n```ini\n[new_section]\n```\n\n### Using `delete()`\n\n`delete()` allows us to delete entire sections or specific keys.\n\n```python\nconfig.delete(\'section\')\n```\n\nWould result in the entire section being removed from our configuration file.\nHowever, we can also just delete a single key.\n\n```python\nconfig.delete(\'section.num_key\')\n```\n\nWe can also use the array notation here as well.\n\n```python\ndel config[\'section\'][\'num_key\']\n```\n\n### Using `has()`\n\n`has()` allows us to check whether a given key exists in our file. There\nare two ways to use `has()`.\n\nThe first is using the dot syntax.\n\n```python\nconfig.has(\'section.str_key\')\n>>> True\nconfig.has(\'does_not_exist\')\n>>> False\n```\n\nThis will check if our specific key or section exists. However, we can\nalso check in general if a given key or sections exists anywhere in our\nfile with the `wild` keyword argument.\n\n```python\nconfig.has(\'str_key\', wild=True)\n>>> True\n```\n\n### Using `save()`\n\nFor any changes we make to our configuration file, they are not written out\nto the filesystem until we call `save()`. This is to avoid unnecessary write\ncalls after each operation until we actually need to save.\n\n```python\nconfig.delete(\'section.list_key\')\nconfig.save()\n```\n\n### Using `stringify()`\n\n`stringify()` shows us our configuration file, with any changes we\'ve made,\nas a string. `stringify()` will always show us our latest changes since it\nis stringify-ing our internal representation of the configuration file, not\njust the file we\'ve read in.\n\n```python\nconfig.stringify()\n>>> \'[section]\\nnum_key = 5\\nstr_key = blah\\nbool_key = true\\nlist_key = [1, 2]\\n\\n[second_section]\\ndict_key = { "another_num": 5 }\\n\\n\'\n```\n\n\n### Using `restore_original()`\n\nIf we have a initial configuration file state, we could keep a copy of that\ninitial file and restore back to it whenever needed using `restore_original()`.\n\nBy default, if we created our `ConfigFile` object with the path of `~/some-project/config.ini`,\n`restore_original()` will look for our original file at `~/some-project/config.original.ini`.\n\n```python\nconfig.restore_original()\n```\n\nHowever, if we have a specific path elsewhere that this original configuration file is or it\nis named differently than what the default expects, we can utilize the `original_path`\nkeyword argument.\n\n```python\nconfig.restore_original(original_path="~/some-project/original-configs/config.ini")\n```\n\n\n## Format Versions Supported\n\n| Format  | Specification version supported |\n| ------------- | ------------- |\n| INI  | No official specification. |\n| JSON  | [RFC 7159](https://tools.ietf.org/html/rfc7159.html)  |\n| YAML  | [v1.2](https://yaml.org/spec/1.2/spec.html)  |\n| TOML  | [v1.0.0-rc.1](https://github.com/toml-lang/toml/releases/tag/v1.0.0-rc.1)  |\n\nFor `ini` and `json`, Python\'s standard library modules are used.\nRegarding `ini`, there is no formal specification so the syntax that configparser\nsupports is what is supported here.\n\n## License\n\nThe [MIT](https://github.com/eugenetriguba/config-file/blob/master/LICENSE) License.\n',
    'author': 'Eugene Triguba',
    'author_email': 'eugenetriguba@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/eugenetriguba/config_file',
    'packages': packages,
    'package_data': package_data,
    'extras_require': extras_require,
    'python_requires': '>=3.6,<4.0',
}


setup(**setup_kwargs)
