| Name | yamello JSON |
| Version |
0.0.2
JSON |
| download |
| home_page | https://gitlab.com/berlinade/yamello |
| Summary | serialize & de-serialize yamello files (which are a true subset of actual yaml>=1.1) |
| upload_time | 2022-12-22 13:43:40 |
| maintainer | |
| docs_url | None |
| author | codima |
| requires_python | >=3.10 |
| license | GPLv3 |
| keywords |
|
| VCS |
|
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# yamello
## author information
[codima](https://www.youtube.com/channel/UCwnthITQqkWgaHnz82U7WsA) (coding-mathmatics) on youtube
## Usage
this package can serialize as well as deserialize python
data (`int`, `float`, `bool`, `str`, `math.inf`, `None`)
and data structures (`list` _or_ `tuple` & `dict`) into
text-based files with suffix `.yamello` or `.yaml` or `.yml`.
As the last 2 suffixes indicate: **Yes, any** _yamello_
**file is supposed to satisfy the** _YAML_ **spec, too!**
Sometimes they can be valid _JSON_, too.
In comparision to the _Yaml_ file format, _yamello_
is way less capable to express exotic data and does purposefully
not allow binary data dumps.
The scope of _yamello_ is simply different and has 3 main goals:
1. it essentially tries to feel like _JSON_ to users, but
mixed in with a bit of syntactic sugar
2. the deserialization will respect or keep the ordering of
dictionary keys within _yamello_ files
(whatever ordering they may have in the first place)
3. the serialization process of _yamello_ will order
dictionary keys alphabetically
Due to main goals 2 & 3 there is no canonicalization necessary
when hashing serialized _yamello_ files; which (aside from
coding exploration) was the major reason to implement
_yamello_ in the first place!
```python
from yamello import serialize, deserialize
''' deserialization '''
with open('demo_resources/demo.in.yaml', mode ='r') as in_stream:
in_str = in_stream.read()
in_data = deserialize(in_str, vec_constructor = tuple)
print(in_data)
''' operations on the data '''
out_data = in_data
''' serialization '''
out_str: str = serialize(out_data)
with open('demo_resources/demo.out.yaml', mode ='w') as out_stream:
out_stream.write(out_str)
```
Please note: _yamello_ is written purely in _python_ and
hence it was not developed with execution speed in mind.
## data
### int
`int` are composed of digits `0` to `9` (e.g. `1217`)
and may include a leading minus `-` to indicate negative
numbers (e.g. `-13`).
**Caution:** numbers in scientific notation, e.g. `12e7`, will
be interpreted as `float`!
**Note:** one can write `inf` or `-inf` for infinity or
negative infinity.
**Note:** It is allowed to place underscores `_` in between digits for
readability (e.g. `1_000_000` which is equivalent to
`1_0_0000_0` as well as to `1000000`).
### float
`float` or floating point numbers. They are composed of
digits `0` to `9`, including a point `.` as decimal seperator
(e.g. `1.0` or `0.045` or `13.076`).
They may include a leading minus `-` to indicate negative
numbers (e.g. `-70.09` or `-0.0007`).
**Note:** `float` can be written in scientific notation,
i.e. in exponent notation including `e` (e.g. `1.4e-8` or
`12e2` or `-0.3e2`)
**Note:** a decimal seperator is necessary, unless scientific
notion is in use.
**Note:** one can write `inf` or `-inf` for infinity or
negative infinity.
**Note:** It is allowed to place underscores `_` in between
digits for readability (e.g. `1_000_000.0_0` or `1_0e2_0`).
**Caution:** decimal seperators `.` need to be
surrounded by digits (e.g. `1.0` is valid as well as `0.01`
whereas `1.` or `.01` are not)!
### bool
`bool` can be written as `True` or `False` (regardless of
upper and lower case, i.e. `true` is as much `True` as `tRuE`)
### str
`str` or strings always have to be enclosed by a pair of
double-quotes `"`, unless they are dictionary keys
(see dictionaries) where they are optional.
Any composition of UTF-8 may appear in between a pair of
double-quotes.
**Note:** double quotes can be escaped using backslash `\"`
to include double-quotes into strings.
**Caution:** single-quotes `'` are simply ignored during the
deserialization process to decide whether something is a
string or not.
### None
`None` can be denoted by `null` (regardless of
upper and lower case, e.g. `NULL` or `Null`
or `nuLL` are valid as well)
### infinity
`inf` or `-inf` represent infinity or negative infinity
(again regardless of lower and upper case).
**Note:** The serialization will convert `math.inf` (from the
math library) or `numpy.inf` (from the numpy library) into
`inf`.
**Note:** The deserialization will convert `inf` into
`math.inf` (from the math library).
## data structures
### inline dict
Inline `dict` or dictionaries are enclosed by a pair of
curly-braces `{` and `}`. They are an **ordered** list of
`key: value` pairs, seperated by commas `,`. Hence, the
general structure follows:
```yaml
{ key1: value1, key2: value2, ... }
```
or
```yaml
{
key1:
value1,
key2: value2 }
```
as linebreaks do not matter.
- `key` is either a string enclosed by a pair of double-quotes `"`
or a (not enclosed) string containing characters `a` to `z`,
`A` to `Z`, underscore `_` and digits `0` to `9`
(provided the character is not a digit).
- `value` is any _data_ discussed above or another inline `dict`
or an inline `list`.
```yaml
{
valid_not_enclosed_key: 99,
"quotes enclosed key due to white spaces": -17.02,
_anotehr_valid_key: "message"
}
```
**Caution:** repeated `keys` within the same dictionary will
overwrite each other (last one counts)!
### (regular) dict
Regular aka "not inline" `dicts` are essentially equivalent to
inline `dicts` (-> see inline `dicts`). The only two differences
are the syntax and the fact that `values`
(from the `key:value` pairs) can be another
regular `dict` or a regular `list`, too.
Regarding the syntax: A regular `dict` is not surrounded
by curly-braces.
Instead, a line break followed by a consistent increase
of indentation (in front of `keys`) mark the beginning,
as well as a decrease (by the same amount of characters)
of indentation mark the end of a regular `dict`.
The indentation of `values` (for those `values` that are
put on one of the next lines) have to be consistent among `values`
and larger than that of their `keys`.
Furthermore, line breaks replace commas to
separate `key:value` pairs from one another.
```yaml
upper_level_key1: # regular structs (dict and list) require line break ...
key1: value1 # ... hence a new (regular) dict starts here
key2: value2
key3: # empty lines and ...
value3 # ... linebreaks between keys and values are allowed
key4: # also empty lines between keys and ...
value4 # ... values are allowed
upper_level_key2: upper_level_value2
```
### inline list
Inline `list` or lists are enclosed by a pair of
brackets `[` and `]`. They are an **ordered** collection of
`entries`, seperated by commas `,`. Hence, the
general structure follows:
```yaml
[ value1, value2, ... ]
```
or
```yaml
[
value1,
value2 ]
```
as linebreaks again do not matter.
- `entry` is any _data_ discussed above or another inline `dict`
or an inline `list`.
### (regular) list
Regular aka "not inline" `lists` are essentially equivalent to
inline `lists` (-> see inline `list`). The only two differences
are the syntax and the
fact that `entries` can be another regular `dict` or a regular `list`, too.
Regarding the syntax: A regular `list` is not surrounded
by brackets.
Instead, a line break followed by a consistent increase
of indentation mark the beginning,
as well as a decrease (by the same amount of characters)
of indentation mark the end of a regular `list`.
Every entry has to be introduced by a dash `-` followed by at least one
space. The indentation of `entries` (for those `entries` that are
put on one of the next lines) have to be consistent among such `entries`
and larger than that compared to the indentation of their dashes `-`.
Furthermore, line breaks replace commas to
separate `entries` from one another.
```yaml
upper_level_key1: # following struct is equivalent to [value1, value2, value3, value4]
- value1
- value2
- value3
- # line breaks are valid, but require either a comment or your IDE not to delete trailing whitespaces
value4
upper_level_key2: # following struct is equivalent to [[value5, value6], [value7], value8]
- - value5
- value6
- - value7
- value9
upper_level_key3: upper_level_value3
```
## additional features
### comments
everything after `#` on any line is considered as a comment
and ignored by the parser during deserialization.
### alias
Any data as well as inline data struct can be aliased for re-use.
The definition of a new alias is introduced by `&` and the use of an
alias is introduced by `*`. Using an alias requires it definition to take
place further up the same document. The same alias can be defined only once.
```yaml
upper_level_key1:
&key1 "content" # defines alias of name: "key1" with value: "content"
upper_level_key2:
*key1 # substitutes the value: "content" stored under the alias with name: "key1"
&key2 upper_level_key3: &other_key [99, inf, null] # defines to alias
upper_level_key4:
- *key2 # substitutes the (string) value: "upper_level_key3"
- *other_key # substitutes the (inline list) value: [99, inf, null]
```
**Note:** rules for alias names are the same as for not (by double quotes)
enclosed dictionary keys, i.e. upper, lower case letters, underscore.
Except for the first character also digits may be used within
## docs
... *under construction*
[//]: # ([https://berlinade.gitlab.io/tomarkdown/](https://berlinade.gitlab.io/tomarkdown/))
## TODOs
- write MkDocs documentation
- (maybe) write an actual spec
- exchange all
```python
raise Assertion('palceholder')
```
for proper Exceptions within the code!
#### informal info on license (english)
This repository is licensed under GPL-V3 (see LICENSE). You can refer to the author of this package as codima & ... .
Raw data
{
"_id": null,
"home_page": "https://gitlab.com/berlinade/yamello",
"name": "yamello",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "",
"keywords": "",
"author": "codima",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/c2/19/7b3a327d3669ad4167641c5e122039d657036046ef3266f3c360001b9cb5/yamello-0.0.2.tar.gz",
"platform": "unix",
"description": "# yamello\n\n## author information\n[codima](https://www.youtube.com/channel/UCwnthITQqkWgaHnz82U7WsA) (coding-mathmatics) on youtube\n\n## Usage\n\nthis package can serialize as well as deserialize python \ndata (`int`, `float`, `bool`, `str`, `math.inf`, `None`)\nand data structures (`list` _or_ `tuple` & `dict`) into \ntext-based files with suffix `.yamello` or `.yaml` or `.yml`.\n\nAs the last 2 suffixes indicate: **Yes, any** _yamello_ \n**file is supposed to satisfy the** _YAML_ **spec, too!**\nSometimes they can be valid _JSON_, too.\n\nIn comparision to the _Yaml_ file format, _yamello_ \nis way less capable to express exotic data and does purposefully \nnot allow binary data dumps. \nThe scope of _yamello_ is simply different and has 3 main goals:\n 1. it essentially tries to feel like _JSON_ to users, but \n mixed in with a bit of syntactic sugar\n 2. the deserialization will respect or keep the ordering of \n dictionary keys within _yamello_ files \n (whatever ordering they may have in the first place)\n 3. the serialization process of _yamello_ will order \n dictionary keys alphabetically\n\nDue to main goals 2 & 3 there is no canonicalization necessary \nwhen hashing serialized _yamello_ files; which (aside from\ncoding exploration) was the major reason to implement \n_yamello_ in the first place!\n\n```python\nfrom yamello import serialize, deserialize\n\n\n''' deserialization '''\nwith open('demo_resources/demo.in.yaml', mode ='r') as in_stream:\n in_str = in_stream.read()\nin_data = deserialize(in_str, vec_constructor = tuple)\nprint(in_data)\n\n''' operations on the data '''\nout_data = in_data\n\n''' serialization '''\nout_str: str = serialize(out_data)\nwith open('demo_resources/demo.out.yaml', mode ='w') as out_stream: \n out_stream.write(out_str)\n```\n\nPlease note: _yamello_ is written purely in _python_ and \nhence it was not developed with execution speed in mind.\n\n## data\n\n### int\n`int` are composed of digits `0` to `9` (e.g. `1217`) \nand may include a leading minus `-` to indicate negative \nnumbers (e.g. `-13`). \n\n**Caution:** numbers in scientific notation, e.g. `12e7`, will\nbe interpreted as `float`!\n\n**Note:** one can write `inf` or `-inf` for infinity or \nnegative infinity. \n\n**Note:** It is allowed to place underscores `_` in between digits for \nreadability (e.g. `1_000_000` which is equivalent to \n`1_0_0000_0` as well as to `1000000`).\n\n### float\n`float` or floating point numbers. They are composed of \ndigits `0` to `9`, including a point `.` as decimal seperator \n(e.g. `1.0` or `0.045` or `13.076`).\nThey may include a leading minus `-` to indicate negative \nnumbers (e.g. `-70.09` or `-0.0007`).\n\n**Note:** `float` can be written in scientific notation, \ni.e. in exponent notation including `e` (e.g. `1.4e-8` or \n`12e2` or `-0.3e2`)\n\n**Note:** a decimal seperator is necessary, unless scientific\nnotion is in use.\n\n**Note:** one can write `inf` or `-inf` for infinity or \nnegative infinity. \n\n**Note:** It is allowed to place underscores `_` in between \ndigits for readability (e.g. `1_000_000.0_0` or `1_0e2_0`).\n\n**Caution:** decimal seperators `.` need to be \nsurrounded by digits (e.g. `1.0` is valid as well as `0.01` \nwhereas `1.` or `.01` are not)!\n\n### bool\n`bool` can be written as `True` or `False` (regardless of\nupper and lower case, i.e. `true` is as much `True` as `tRuE`)\n\n### str\n`str` or strings always have to be enclosed by a pair of\ndouble-quotes `\"`, unless they are dictionary keys \n(see dictionaries) where they are optional.\nAny composition of UTF-8 may appear in between a pair of \ndouble-quotes. \n\n**Note:** double quotes can be escaped using backslash `\\\"` \nto include double-quotes into strings.\n\n**Caution:** single-quotes `'` are simply ignored during the \ndeserialization process to decide whether something is a \nstring or not. \n\n### None\n`None` can be denoted by `null` (regardless of\nupper and lower case, e.g. `NULL` or `Null` \nor `nuLL` are valid as well)\n\n### infinity \n`inf` or `-inf` represent infinity or negative infinity \n(again regardless of lower and upper case).\n\n**Note:** The serialization will convert `math.inf` (from the \nmath library) or `numpy.inf` (from the numpy library) into\n`inf`. \n\n**Note:** The deserialization will convert `inf` into \n`math.inf` (from the math library).\n\n## data structures\n\n### inline dict\nInline `dict` or dictionaries are enclosed by a pair of\ncurly-braces `{` and `}`. They are an **ordered** list of \n`key: value` pairs, seperated by commas `,`. Hence, the \ngeneral structure follows:\n\n```yaml\n{ key1: value1, key2: value2, ... }\n```\nor\n```yaml\n{\n key1:\n value1,\n \n key2: value2 }\n```\nas linebreaks do not matter.\n\n- `key` is either a string enclosed by a pair of double-quotes `\"`\n or a (not enclosed) string containing characters `a` to `z`, \n `A` to `Z`, underscore `_` and digits `0` to `9` \n (provided the character is not a digit).\n- `value` is any _data_ discussed above or another inline `dict` \n or an inline `list`. \n\n```yaml\n{\n valid_not_enclosed_key: 99,\n \"quotes enclosed key due to white spaces\": -17.02,\n _anotehr_valid_key: \"message\"\n}\n```\n\n**Caution:** repeated `keys` within the same dictionary will \noverwrite each other (last one counts)! \n\n### (regular) dict\nRegular aka \"not inline\" `dicts` are essentially equivalent to \ninline `dicts` (-> see inline `dicts`). The only two differences \nare the syntax and the fact that `values` \n(from the `key:value` pairs) can be another \nregular `dict` or a regular `list`, too.\n\nRegarding the syntax: A regular `dict` is not surrounded \nby curly-braces. \nInstead, a line break followed by a consistent increase \nof indentation (in front of `keys`) mark the beginning, \nas well as a decrease (by the same amount of characters) \nof indentation mark the end of a regular `dict`.\nThe indentation of `values` (for those `values` that are \nput on one of the next lines) have to be consistent among `values`\nand larger than that of their `keys`. \nFurthermore, line breaks replace commas to \nseparate `key:value` pairs from one another. \n\n```yaml\nupper_level_key1: # regular structs (dict and list) require line break ...\n key1: value1 # ... hence a new (regular) dict starts here\n key2: value2\n\n key3: # empty lines and ... \n value3 # ... linebreaks between keys and values are allowed\n \n key4: # also empty lines between keys and ...\n \n value4 # ... values are allowed\nupper_level_key2: upper_level_value2\n```\n\n### inline list\nInline `list` or lists are enclosed by a pair of\nbrackets `[` and `]`. They are an **ordered** collection of \n`entries`, seperated by commas `,`. Hence, the \ngeneral structure follows:\n\n```yaml\n[ value1, value2, ... ]\n```\nor\n```yaml\n[\n value1,\n \n value2 ]\n```\nas linebreaks again do not matter.\n\n- `entry` is any _data_ discussed above or another inline `dict` \n or an inline `list`.\n\n### (regular) list\nRegular aka \"not inline\" `lists` are essentially equivalent to \ninline `lists` (-> see inline `list`). The only two differences \nare the syntax and the\nfact that `entries` can be another regular `dict` or a regular `list`, too.\n\nRegarding the syntax: A regular `list` is not surrounded \nby brackets. \nInstead, a line break followed by a consistent increase \nof indentation mark the beginning, \nas well as a decrease (by the same amount of characters) \nof indentation mark the end of a regular `list`.\nEvery entry has to be introduced by a dash `-` followed by at least one \nspace. The indentation of `entries` (for those `entries` that are \nput on one of the next lines) have to be consistent among such `entries`\nand larger than that compared to the indentation of their dashes `-`. \nFurthermore, line breaks replace commas to \nseparate `entries` from one another.\n\n```yaml\nupper_level_key1: # following struct is equivalent to [value1, value2, value3, value4]\n - value1\n - value2\n\n - value3\n \n - # line breaks are valid, but require either a comment or your IDE not to delete trailing whitespaces\n value4\nupper_level_key2: # following struct is equivalent to [[value5, value6], [value7], value8]\n - - value5\n - value6\n - - value7\n - value9\nupper_level_key3: upper_level_value3\n```\n\n## additional features\n\n### comments\neverything after `#` on any line is considered as a comment\nand ignored by the parser during deserialization.\n\n### alias\nAny data as well as inline data struct can be aliased for re-use.\nThe definition of a new alias is introduced by `&` and the use of an \nalias is introduced by `*`. Using an alias requires it definition to take \nplace further up the same document. The same alias can be defined only once. \n\n```yaml\nupper_level_key1:\n &key1 \"content\" # defines alias of name: \"key1\" with value: \"content\"\nupper_level_key2:\n *key1 # substitutes the value: \"content\" stored under the alias with name: \"key1\"\n&key2 upper_level_key3: &other_key [99, inf, null] # defines to alias\nupper_level_key4:\n - *key2 # substitutes the (string) value: \"upper_level_key3\"\n - *other_key # substitutes the (inline list) value: [99, inf, null]\n```\n\n**Note:** rules for alias names are the same as for not (by double quotes) \nenclosed dictionary keys, i.e. upper, lower case letters, underscore.\nExcept for the first character also digits may be used within\n\n## docs\n\n... *under construction*\n\n[//]: # ([https://berlinade.gitlab.io/tomarkdown/](https://berlinade.gitlab.io/tomarkdown/))\n\n## TODOs\n \n - write MkDocs documentation\n - (maybe) write an actual spec\n - exchange all\n ```python \n raise Assertion('palceholder')\n ```\n for proper Exceptions within the code!\n\n#### informal info on license (english)\nThis repository is licensed under GPL-V3 (see LICENSE). You can refer to the author of this package as codima & ... .\n",
"bugtrack_url": null,
"license": "GPLv3",
"summary": "serialize & de-serialize yamello files (which are a true subset of actual yaml>=1.1)",
"version": "0.0.2",
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"md5": "5bb5f6c8bf73b12f7ab0a213065200e1",
"sha256": "2ef04bde5dca0a2b4e909c26e1258be2139bb8b962384bb720b457fa54725806"
},
"downloads": -1,
"filename": "yamello-0.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5bb5f6c8bf73b12f7ab0a213065200e1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 24628,
"upload_time": "2022-12-22T13:43:38",
"upload_time_iso_8601": "2022-12-22T13:43:38.461566Z",
"url": "https://files.pythonhosted.org/packages/35/b7/77fa0f601dbdade116ce642101fc1536d79eeee0319a63e165c6a3eb43eb/yamello-0.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"md5": "a263ee1dcbee06ce8c607d8c726e66f7",
"sha256": "5c3156a3aeb5079b2e96b28b0e94957c7b1c644732859aca7a83c7d7ee8d8027"
},
"downloads": -1,
"filename": "yamello-0.0.2.tar.gz",
"has_sig": false,
"md5_digest": "a263ee1dcbee06ce8c607d8c726e66f7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 28131,
"upload_time": "2022-12-22T13:43:40",
"upload_time_iso_8601": "2022-12-22T13:43:40.385575Z",
"url": "https://files.pythonhosted.org/packages/c2/19/7b3a327d3669ad4167641c5e122039d657036046ef3266f3c360001b9cb5/yamello-0.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-12-22 13:43:40",
"github": false,
"gitlab": true,
"bitbucket": false,
"gitlab_user": "berlinade",
"gitlab_project": "yamello",
"lcname": "yamello"
}