././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1575692709.0231464 pyaml-19.12.0/0000755000175000017500000000000000000000000014053 5ustar00fraggodfraggod00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1478060463.0 pyaml-19.12.0/COPYING0000644000175000017500000000075300000000000015113 0ustar00fraggodfraggod00000000000000 DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 Copyright (C) 2012 Mike Kazantsev Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. You just DO WHAT THE FUCK YOU WANT TO. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1432061116.0 pyaml-19.12.0/MANIFEST.in0000644000175000017500000000003300000000000015605 0ustar00fraggodfraggod00000000000000include COPYING README.rst ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1575692709.0231464 pyaml-19.12.0/PKG-INFO0000644000175000017500000003061500000000000015155 0ustar00fraggodfraggod00000000000000Metadata-Version: 1.1 Name: pyaml Version: 19.12.0 Summary: PyYAML-based module to produce pretty and readable YAML-serialized data Home-page: https://github.com/mk-fg/pretty-yaml Author: Mike Kazantsev Author-email: mk.fraggod@gmail.com License: WTFPL Description: pretty-yaml (or pyaml) ====================== PyYAML-based python module to produce pretty and readable YAML-serialized data. This module is for serialization only, see `ruamel.yaml`_ module for literate YAML parsing (keeping track of comments, spacing, line/column numbers of values, etc). .. contents:: :backlinks: none Warning ------- Prime goal of this module is to produce human-readable output that can be easily manipulated and re-used, but maybe with some occasional caveats. One good example of such "caveat" is that e.g. ``{'foo': '123'}`` will serialize to ``foo: 123``, which for PyYAML would be a bug, as 123 will then be read back as an integer from that, but here it's a feature. So please do not rely on the thing to produce output that can always be deserialized exactly to what was exported, at least - use PyYAML (e.g. with options from the next section) for that. What this module does and why ----------------------------- YAML is generally nice and easy format to read *if* it was written by humans. PyYAML can a do fairly decent job of making stuff readable, and the best combination of parameters for such output that I've seen so far is probably this one:: >>> m = [123, 45.67, {1: None, 2: False}, u'some text'] >>> data = dict(a=u'asldnsa\nasldpáknsa\n', b=u'whatever text', ma=m, mb=m) >>> yaml.safe_dump(data, sys.stdout, allow_unicode=True, default_flow_style=False) a: 'asldnsa asldpáknsa ' b: whatever text ma: &id001 - 123 - 45.67 - 1: null 2: false - some text mb: *id001 pyaml tries to improve on that a bit, with the following tweaks: * Most human-friendly representation options in PyYAML (that I know of) get picked as defaults. * Does not dump "null" values, if possible, replacing these with just empty strings, which have the same meaning but reduce visual clutter and are easier to edit. * Dicts, sets, OrderedDicts, defaultdicts, namedtuples, etc are representable and get sorted on output (OrderedDicts and namedtuples keep their ordering), so that output would be as diff-friendly as possible, and not arbitrarily depend on python internals. It appears that at least recent PyYAML versions also do such sorting for python dicts. * List items get indented, as they should be. * bytestrings that can't be auto-converted to unicode raise error, as yaml has no "binary bytes" (i.e. unix strings) type. * Attempt is made to pick more readable string representation styles, depending on the value, e.g.:: >>> yaml.safe_dump(cert, sys.stdout) cert: '-----BEGIN CERTIFICATE----- MIIH3jCCBcagAwIBAgIJAJi7AjQ4Z87OMA0GCSqGSIb3DQEBCwUAMIHBMRcwFQYD VQQKFA52YWxlcm9uLm5vX2lzcDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0aG9y ... >>> pyaml.p(cert): cert: | -----BEGIN CERTIFICATE----- MIIH3jCCBcagAwIBAgIJAJi7AjQ4Z87OMA0GCSqGSIb3DQEBCwUAMIHBMRcwFQYD VQQKFA52YWxlcm9uLm5vX2lzcDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0aG9y ... * "force_embed" option to avoid having &id stuff scattered all over the output (which might be beneficial in some cases, hence the option). * "&id" anchors, if used, get labels from the keys they get attached to, not just use meaningless enumerators. * "string_val_style" option to only apply to strings that are values, not keys, i.e:: >>> pyaml.p(data, string_val_style='"') key: "value\nasldpáknsa\n" >>> yaml.safe_dump(data, sys.stdout, allow_unicode=True, default_style='"') "key": "value\nasldpáknsa\n" * "sort_dicts=False" option to leave dict item ordering to python, and not force-sort them in yaml output, which can be important for python 3.6+ where they retain ordering info. * Has an option to add vertical spacing (empty lines) between keys on different depths, to make output much more seekable. Result for the (rather meaningless) example above (without any additional tweaks):: >>> pyaml.p(data) a: | asldnsa asldpáknsa b: 'whatever text' ma: &ma - 123 - 45.67 - 1: 2: false - 'some text' mb: *ma ---------- Extended example:: >>> pyaml.dump(conf, sys.stdout, vspacing=[2, 1]): destination: encoding: xz: enabled: true min_size: 5120 options: path_filter: - \.(gz|bz2|t[gb]z2?|xz|lzma|7z|zip|rar)$ - \.(rpm|deb|iso)$ - \.(jpe?g|gif|png|mov|avi|ogg|mkv|webm|mp[34g]|flv|flac|ape|pdf|djvu)$ - \.(sqlite3?|fossil|fsl)$ - \.git/objects/[0-9a-f]+/[0-9a-f]+$ result: append_to_file: append_to_lafs_dir: print_to_stdout: true url: http://localhost:3456/uri filter: - /(CVS|RCS|SCCS|_darcs|\{arch\})/$ - /\.(git|hg|bzr|svn|cvs)(/|ignore|attributes|tags)?$ - /=(RELEASE-ID|meta-update|update)$ http: ca_certs_files: /etc/ssl/certs/ca-certificates.crt debug_requests: false request_pool_options: cachedConnectionTimeout: 600 maxPersistentPerHost: 10 retryAutomatically: true logging: formatters: basic: datefmt: '%Y-%m-%d %H:%M:%S' format: '%(asctime)s :: %(name)s :: %(levelname)s: %(message)s' handlers: console: class: logging.StreamHandler formatter: basic level: custom stream: ext://sys.stderr loggers: twisted: handlers: - console level: 0 root: handlers: - console level: custom Note that unless there are many moderately wide and deep trees of data, which are expected to be read and edited by people, it might be preferrable to directly use PyYAML regardless, as it won't introduce another (rather pointless in that case) dependency and a point of failure. Some Tricks ----------- * Pretty-print any yaml or json (yaml subset) file from the shell:: % python -m pyaml /path/to/some/file.yaml % curl -s https://status.github.com/api.json | python -m pyaml * Process and replace json/yaml file in-place:: % python -m pyaml -r file-with-json.data * Easier "debug printf" for more complex data (all funcs below are aliases to same thing):: pyaml.p(stuff) pyaml.pprint(my_data) pyaml.pprint('----- HOW DOES THAT BREAKS!?!?', input_data, some_var, more_stuff) pyaml.print(data, file=sys.stderr) # needs "from __future__ import print_function" * Force all string values to a certain style (see info on these in `PyYAML docs`_):: pyaml.dump(many_weird_strings, string_val_style='|') pyaml.dump(multiline_words, string_val_style='>') pyaml.dump(no_want_quotes, string_val_style='plain') Using ``pyaml.add_representer()`` (note \*p\*yaml) as suggested in `this SO thread`_ (or `github-issue-7`_) should also work. * Control indent and width of the results:: pyaml.dump(wide_and_deep, indent=4, width=120) These are actually keywords for PyYAML Emitter (passed to it from Dumper), see more info on these in `PyYAML docs`_. * Dump multiple yaml documents into a file: ``pyaml.dump_all([data1, data2, data3], dst_file)`` explicit_start=True is implied, unless explicit_start=False is passed. .. _PyYAML docs: http://pyyaml.org/wiki/PyYAMLDocumentation#Scalars .. _this SO thread: http://stackoverflow.com/a/7445560 .. _github-issue-7: https://github.com/mk-fg/pretty-yaml/issues/7 Installation ------------ It's a regular package for Python (3.x or 2.x). Module uses PyYAML_ for processing of the actual YAML files and should pull it in as a dependency. Dependency on unidecode_ module is optional and should only be necessary if same-id objects or recursion is used within serialized data. Be sure to use python3/python2, pip3/pip2, easy_install-... binaries below, based on which python version you want to install the module for, if you have several on the system (as is norm these days for py2-py3 transition). Using pip_ is the best way:: % pip install pyaml (add --user option to install into $HOME for current user only) Or, if you don't have "pip" command:: % python -m ensurepip % python -m pip install --upgrade pip % python -m pip install pyaml (same suggestion wrt "install --user" as above) On a very old systems, one of these might work:: % curl https://bootstrap.pypa.io/get-pip.py | python % pip install pyaml % easy_install pyaml % git clone --depth=1 https://github.com/mk-fg/pretty-yaml % cd pretty-yaml % python setup.py install (all of install-commands here also have --user option, see also `pip docs "installing" section`_) Current-git version can be installed like this:: % pip install 'git+https://github.com/mk-fg/pretty-yaml#egg=pyaml' Note that to install stuff to system-wide PATH and site-packages (without --user), elevated privileges (i.e. root and su/sudo) are often required. Use "...install --user", `~/.pydistutils.cfg`_ or virtualenv_ to do unprivileged installs into custom paths. More info on python packaging can be found at `packaging.python.org`_. .. _ruamel.yaml: https://bitbucket.org/ruamel/yaml/ .. _PyYAML: http://pyyaml.org/ .. _unidecode: http://pypi.python.org/pypi/Unidecode .. _pip: http://pip-installer.org/ .. _pip docs "installing" section: http://www.pip-installer.org/en/latest/installing.html .. _~/.pydistutils.cfg: http://docs.python.org/install/index.html#distutils-configuration-files .. _virtualenv: http://pypi.python.org/pypi/virtualenv .. _packaging.python.org: https://packaging.python.org/installing/ Keywords: yaml serialization pretty print format human readable readability Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.5 Classifier: Topic :: Software Development Classifier: Topic :: Software Development :: Libraries :: Python Modules ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1575692653.0 pyaml-19.12.0/README0000644000175000017500000002237300000000000014742 0ustar00fraggodfraggod00000000000000pretty-yaml (or pyaml) ====================== PyYAML-based python module to produce pretty and readable YAML-serialized data. This module is for serialization only, see `ruamel.yaml`_ module for literate YAML parsing (keeping track of comments, spacing, line/column numbers of values, etc). .. contents:: :backlinks: none Warning ------- Prime goal of this module is to produce human-readable output that can be easily manipulated and re-used, but maybe with some occasional caveats. One good example of such "caveat" is that e.g. ``{'foo': '123'}`` will serialize to ``foo: 123``, which for PyYAML would be a bug, as 123 will then be read back as an integer from that, but here it's a feature. So please do not rely on the thing to produce output that can always be deserialized exactly to what was exported, at least - use PyYAML (e.g. with options from the next section) for that. What this module does and why ----------------------------- YAML is generally nice and easy format to read *if* it was written by humans. PyYAML can a do fairly decent job of making stuff readable, and the best combination of parameters for such output that I've seen so far is probably this one:: >>> m = [123, 45.67, {1: None, 2: False}, u'some text'] >>> data = dict(a=u'asldnsa\nasldpáknsa\n', b=u'whatever text', ma=m, mb=m) >>> yaml.safe_dump(data, sys.stdout, allow_unicode=True, default_flow_style=False) a: 'asldnsa asldpáknsa ' b: whatever text ma: &id001 - 123 - 45.67 - 1: null 2: false - some text mb: *id001 pyaml tries to improve on that a bit, with the following tweaks: * Most human-friendly representation options in PyYAML (that I know of) get picked as defaults. * Does not dump "null" values, if possible, replacing these with just empty strings, which have the same meaning but reduce visual clutter and are easier to edit. * Dicts, sets, OrderedDicts, defaultdicts, namedtuples, etc are representable and get sorted on output (OrderedDicts and namedtuples keep their ordering), so that output would be as diff-friendly as possible, and not arbitrarily depend on python internals. It appears that at least recent PyYAML versions also do such sorting for python dicts. * List items get indented, as they should be. * bytestrings that can't be auto-converted to unicode raise error, as yaml has no "binary bytes" (i.e. unix strings) type. * Attempt is made to pick more readable string representation styles, depending on the value, e.g.:: >>> yaml.safe_dump(cert, sys.stdout) cert: '-----BEGIN CERTIFICATE----- MIIH3jCCBcagAwIBAgIJAJi7AjQ4Z87OMA0GCSqGSIb3DQEBCwUAMIHBMRcwFQYD VQQKFA52YWxlcm9uLm5vX2lzcDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0aG9y ... >>> pyaml.p(cert): cert: | -----BEGIN CERTIFICATE----- MIIH3jCCBcagAwIBAgIJAJi7AjQ4Z87OMA0GCSqGSIb3DQEBCwUAMIHBMRcwFQYD VQQKFA52YWxlcm9uLm5vX2lzcDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0aG9y ... * "force_embed" option to avoid having &id stuff scattered all over the output (which might be beneficial in some cases, hence the option). * "&id" anchors, if used, get labels from the keys they get attached to, not just use meaningless enumerators. * "string_val_style" option to only apply to strings that are values, not keys, i.e:: >>> pyaml.p(data, string_val_style='"') key: "value\nasldpáknsa\n" >>> yaml.safe_dump(data, sys.stdout, allow_unicode=True, default_style='"') "key": "value\nasldpáknsa\n" * "sort_dicts=False" option to leave dict item ordering to python, and not force-sort them in yaml output, which can be important for python 3.6+ where they retain ordering info. * Has an option to add vertical spacing (empty lines) between keys on different depths, to make output much more seekable. Result for the (rather meaningless) example above (without any additional tweaks):: >>> pyaml.p(data) a: | asldnsa asldpáknsa b: 'whatever text' ma: &ma - 123 - 45.67 - 1: 2: false - 'some text' mb: *ma ---------- Extended example:: >>> pyaml.dump(conf, sys.stdout, vspacing=[2, 1]): destination: encoding: xz: enabled: true min_size: 5120 options: path_filter: - \.(gz|bz2|t[gb]z2?|xz|lzma|7z|zip|rar)$ - \.(rpm|deb|iso)$ - \.(jpe?g|gif|png|mov|avi|ogg|mkv|webm|mp[34g]|flv|flac|ape|pdf|djvu)$ - \.(sqlite3?|fossil|fsl)$ - \.git/objects/[0-9a-f]+/[0-9a-f]+$ result: append_to_file: append_to_lafs_dir: print_to_stdout: true url: http://localhost:3456/uri filter: - /(CVS|RCS|SCCS|_darcs|\{arch\})/$ - /\.(git|hg|bzr|svn|cvs)(/|ignore|attributes|tags)?$ - /=(RELEASE-ID|meta-update|update)$ http: ca_certs_files: /etc/ssl/certs/ca-certificates.crt debug_requests: false request_pool_options: cachedConnectionTimeout: 600 maxPersistentPerHost: 10 retryAutomatically: true logging: formatters: basic: datefmt: '%Y-%m-%d %H:%M:%S' format: '%(asctime)s :: %(name)s :: %(levelname)s: %(message)s' handlers: console: class: logging.StreamHandler formatter: basic level: custom stream: ext://sys.stderr loggers: twisted: handlers: - console level: 0 root: handlers: - console level: custom Note that unless there are many moderately wide and deep trees of data, which are expected to be read and edited by people, it might be preferrable to directly use PyYAML regardless, as it won't introduce another (rather pointless in that case) dependency and a point of failure. Some Tricks ----------- * Pretty-print any yaml or json (yaml subset) file from the shell:: % python -m pyaml /path/to/some/file.yaml % curl -s https://status.github.com/api.json | python -m pyaml * Process and replace json/yaml file in-place:: % python -m pyaml -r file-with-json.data * Easier "debug printf" for more complex data (all funcs below are aliases to same thing):: pyaml.p(stuff) pyaml.pprint(my_data) pyaml.pprint('----- HOW DOES THAT BREAKS!?!?', input_data, some_var, more_stuff) pyaml.print(data, file=sys.stderr) # needs "from __future__ import print_function" * Force all string values to a certain style (see info on these in `PyYAML docs`_):: pyaml.dump(many_weird_strings, string_val_style='|') pyaml.dump(multiline_words, string_val_style='>') pyaml.dump(no_want_quotes, string_val_style='plain') Using ``pyaml.add_representer()`` (note \*p\*yaml) as suggested in `this SO thread`_ (or `github-issue-7`_) should also work. * Control indent and width of the results:: pyaml.dump(wide_and_deep, indent=4, width=120) These are actually keywords for PyYAML Emitter (passed to it from Dumper), see more info on these in `PyYAML docs`_. * Dump multiple yaml documents into a file: ``pyaml.dump_all([data1, data2, data3], dst_file)`` explicit_start=True is implied, unless explicit_start=False is passed. .. _PyYAML docs: http://pyyaml.org/wiki/PyYAMLDocumentation#Scalars .. _this SO thread: http://stackoverflow.com/a/7445560 .. _github-issue-7: https://github.com/mk-fg/pretty-yaml/issues/7 Installation ------------ It's a regular package for Python (3.x or 2.x). Module uses PyYAML_ for processing of the actual YAML files and should pull it in as a dependency. Dependency on unidecode_ module is optional and should only be necessary if same-id objects or recursion is used within serialized data. Be sure to use python3/python2, pip3/pip2, easy_install-... binaries below, based on which python version you want to install the module for, if you have several on the system (as is norm these days for py2-py3 transition). Using pip_ is the best way:: % pip install pyaml (add --user option to install into $HOME for current user only) Or, if you don't have "pip" command:: % python -m ensurepip % python -m pip install --upgrade pip % python -m pip install pyaml (same suggestion wrt "install --user" as above) On a very old systems, one of these might work:: % curl https://bootstrap.pypa.io/get-pip.py | python % pip install pyaml % easy_install pyaml % git clone --depth=1 https://github.com/mk-fg/pretty-yaml % cd pretty-yaml % python setup.py install (all of install-commands here also have --user option, see also `pip docs "installing" section`_) Current-git version can be installed like this:: % pip install 'git+https://github.com/mk-fg/pretty-yaml#egg=pyaml' Note that to install stuff to system-wide PATH and site-packages (without --user), elevated privileges (i.e. root and su/sudo) are often required. Use "...install --user", `~/.pydistutils.cfg`_ or virtualenv_ to do unprivileged installs into custom paths. More info on python packaging can be found at `packaging.python.org`_. .. _ruamel.yaml: https://bitbucket.org/ruamel/yaml/ .. _PyYAML: http://pyyaml.org/ .. _unidecode: http://pypi.python.org/pypi/Unidecode .. _pip: http://pip-installer.org/ .. _pip docs "installing" section: http://www.pip-installer.org/en/latest/installing.html .. _~/.pydistutils.cfg: http://docs.python.org/install/index.html#distutils-configuration-files .. _virtualenv: http://pypi.python.org/pypi/virtualenv .. _packaging.python.org: https://packaging.python.org/installing/ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1575692653.0 pyaml-19.12.0/README.rst0000644000175000017500000002237300000000000015551 0ustar00fraggodfraggod00000000000000pretty-yaml (or pyaml) ====================== PyYAML-based python module to produce pretty and readable YAML-serialized data. This module is for serialization only, see `ruamel.yaml`_ module for literate YAML parsing (keeping track of comments, spacing, line/column numbers of values, etc). .. contents:: :backlinks: none Warning ------- Prime goal of this module is to produce human-readable output that can be easily manipulated and re-used, but maybe with some occasional caveats. One good example of such "caveat" is that e.g. ``{'foo': '123'}`` will serialize to ``foo: 123``, which for PyYAML would be a bug, as 123 will then be read back as an integer from that, but here it's a feature. So please do not rely on the thing to produce output that can always be deserialized exactly to what was exported, at least - use PyYAML (e.g. with options from the next section) for that. What this module does and why ----------------------------- YAML is generally nice and easy format to read *if* it was written by humans. PyYAML can a do fairly decent job of making stuff readable, and the best combination of parameters for such output that I've seen so far is probably this one:: >>> m = [123, 45.67, {1: None, 2: False}, u'some text'] >>> data = dict(a=u'asldnsa\nasldpáknsa\n', b=u'whatever text', ma=m, mb=m) >>> yaml.safe_dump(data, sys.stdout, allow_unicode=True, default_flow_style=False) a: 'asldnsa asldpáknsa ' b: whatever text ma: &id001 - 123 - 45.67 - 1: null 2: false - some text mb: *id001 pyaml tries to improve on that a bit, with the following tweaks: * Most human-friendly representation options in PyYAML (that I know of) get picked as defaults. * Does not dump "null" values, if possible, replacing these with just empty strings, which have the same meaning but reduce visual clutter and are easier to edit. * Dicts, sets, OrderedDicts, defaultdicts, namedtuples, etc are representable and get sorted on output (OrderedDicts and namedtuples keep their ordering), so that output would be as diff-friendly as possible, and not arbitrarily depend on python internals. It appears that at least recent PyYAML versions also do such sorting for python dicts. * List items get indented, as they should be. * bytestrings that can't be auto-converted to unicode raise error, as yaml has no "binary bytes" (i.e. unix strings) type. * Attempt is made to pick more readable string representation styles, depending on the value, e.g.:: >>> yaml.safe_dump(cert, sys.stdout) cert: '-----BEGIN CERTIFICATE----- MIIH3jCCBcagAwIBAgIJAJi7AjQ4Z87OMA0GCSqGSIb3DQEBCwUAMIHBMRcwFQYD VQQKFA52YWxlcm9uLm5vX2lzcDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0aG9y ... >>> pyaml.p(cert): cert: | -----BEGIN CERTIFICATE----- MIIH3jCCBcagAwIBAgIJAJi7AjQ4Z87OMA0GCSqGSIb3DQEBCwUAMIHBMRcwFQYD VQQKFA52YWxlcm9uLm5vX2lzcDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0aG9y ... * "force_embed" option to avoid having &id stuff scattered all over the output (which might be beneficial in some cases, hence the option). * "&id" anchors, if used, get labels from the keys they get attached to, not just use meaningless enumerators. * "string_val_style" option to only apply to strings that are values, not keys, i.e:: >>> pyaml.p(data, string_val_style='"') key: "value\nasldpáknsa\n" >>> yaml.safe_dump(data, sys.stdout, allow_unicode=True, default_style='"') "key": "value\nasldpáknsa\n" * "sort_dicts=False" option to leave dict item ordering to python, and not force-sort them in yaml output, which can be important for python 3.6+ where they retain ordering info. * Has an option to add vertical spacing (empty lines) between keys on different depths, to make output much more seekable. Result for the (rather meaningless) example above (without any additional tweaks):: >>> pyaml.p(data) a: | asldnsa asldpáknsa b: 'whatever text' ma: &ma - 123 - 45.67 - 1: 2: false - 'some text' mb: *ma ---------- Extended example:: >>> pyaml.dump(conf, sys.stdout, vspacing=[2, 1]): destination: encoding: xz: enabled: true min_size: 5120 options: path_filter: - \.(gz|bz2|t[gb]z2?|xz|lzma|7z|zip|rar)$ - \.(rpm|deb|iso)$ - \.(jpe?g|gif|png|mov|avi|ogg|mkv|webm|mp[34g]|flv|flac|ape|pdf|djvu)$ - \.(sqlite3?|fossil|fsl)$ - \.git/objects/[0-9a-f]+/[0-9a-f]+$ result: append_to_file: append_to_lafs_dir: print_to_stdout: true url: http://localhost:3456/uri filter: - /(CVS|RCS|SCCS|_darcs|\{arch\})/$ - /\.(git|hg|bzr|svn|cvs)(/|ignore|attributes|tags)?$ - /=(RELEASE-ID|meta-update|update)$ http: ca_certs_files: /etc/ssl/certs/ca-certificates.crt debug_requests: false request_pool_options: cachedConnectionTimeout: 600 maxPersistentPerHost: 10 retryAutomatically: true logging: formatters: basic: datefmt: '%Y-%m-%d %H:%M:%S' format: '%(asctime)s :: %(name)s :: %(levelname)s: %(message)s' handlers: console: class: logging.StreamHandler formatter: basic level: custom stream: ext://sys.stderr loggers: twisted: handlers: - console level: 0 root: handlers: - console level: custom Note that unless there are many moderately wide and deep trees of data, which are expected to be read and edited by people, it might be preferrable to directly use PyYAML regardless, as it won't introduce another (rather pointless in that case) dependency and a point of failure. Some Tricks ----------- * Pretty-print any yaml or json (yaml subset) file from the shell:: % python -m pyaml /path/to/some/file.yaml % curl -s https://status.github.com/api.json | python -m pyaml * Process and replace json/yaml file in-place:: % python -m pyaml -r file-with-json.data * Easier "debug printf" for more complex data (all funcs below are aliases to same thing):: pyaml.p(stuff) pyaml.pprint(my_data) pyaml.pprint('----- HOW DOES THAT BREAKS!?!?', input_data, some_var, more_stuff) pyaml.print(data, file=sys.stderr) # needs "from __future__ import print_function" * Force all string values to a certain style (see info on these in `PyYAML docs`_):: pyaml.dump(many_weird_strings, string_val_style='|') pyaml.dump(multiline_words, string_val_style='>') pyaml.dump(no_want_quotes, string_val_style='plain') Using ``pyaml.add_representer()`` (note \*p\*yaml) as suggested in `this SO thread`_ (or `github-issue-7`_) should also work. * Control indent and width of the results:: pyaml.dump(wide_and_deep, indent=4, width=120) These are actually keywords for PyYAML Emitter (passed to it from Dumper), see more info on these in `PyYAML docs`_. * Dump multiple yaml documents into a file: ``pyaml.dump_all([data1, data2, data3], dst_file)`` explicit_start=True is implied, unless explicit_start=False is passed. .. _PyYAML docs: http://pyyaml.org/wiki/PyYAMLDocumentation#Scalars .. _this SO thread: http://stackoverflow.com/a/7445560 .. _github-issue-7: https://github.com/mk-fg/pretty-yaml/issues/7 Installation ------------ It's a regular package for Python (3.x or 2.x). Module uses PyYAML_ for processing of the actual YAML files and should pull it in as a dependency. Dependency on unidecode_ module is optional and should only be necessary if same-id objects or recursion is used within serialized data. Be sure to use python3/python2, pip3/pip2, easy_install-... binaries below, based on which python version you want to install the module for, if you have several on the system (as is norm these days for py2-py3 transition). Using pip_ is the best way:: % pip install pyaml (add --user option to install into $HOME for current user only) Or, if you don't have "pip" command:: % python -m ensurepip % python -m pip install --upgrade pip % python -m pip install pyaml (same suggestion wrt "install --user" as above) On a very old systems, one of these might work:: % curl https://bootstrap.pypa.io/get-pip.py | python % pip install pyaml % easy_install pyaml % git clone --depth=1 https://github.com/mk-fg/pretty-yaml % cd pretty-yaml % python setup.py install (all of install-commands here also have --user option, see also `pip docs "installing" section`_) Current-git version can be installed like this:: % pip install 'git+https://github.com/mk-fg/pretty-yaml#egg=pyaml' Note that to install stuff to system-wide PATH and site-packages (without --user), elevated privileges (i.e. root and su/sudo) are often required. Use "...install --user", `~/.pydistutils.cfg`_ or virtualenv_ to do unprivileged installs into custom paths. More info on python packaging can be found at `packaging.python.org`_. .. _ruamel.yaml: https://bitbucket.org/ruamel/yaml/ .. _PyYAML: http://pyyaml.org/ .. _unidecode: http://pypi.python.org/pypi/Unidecode .. _pip: http://pip-installer.org/ .. _pip docs "installing" section: http://www.pip-installer.org/en/latest/installing.html .. _~/.pydistutils.cfg: http://docs.python.org/install/index.html#distutils-configuration-files .. _virtualenv: http://pypi.python.org/pypi/virtualenv .. _packaging.python.org: https://packaging.python.org/installing/ ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1575692709.0221465 pyaml-19.12.0/pyaml/0000755000175000017500000000000000000000000015175 5ustar00fraggodfraggod00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1555467892.0 pyaml-19.12.0/pyaml/__init__.py0000644000175000017500000001761100000000000017314 0ustar00fraggodfraggod00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import itertools as it, operator as op, functools as ft from collections import defaultdict, OrderedDict, namedtuple import os, sys, io, re import yaml if sys.version_info.major > 2: unicode = str class PrettyYAMLDumper(yaml.dumper.SafeDumper): def __init__(self, *args, **kws): self.pyaml_force_embed = kws.pop('force_embed', False) self.pyaml_string_val_style = kws.pop('string_val_style', None) self.pyaml_sort_dicts = kws.pop('sort_dicts', True) return super(PrettyYAMLDumper, self).__init__(*args, **kws) def represent_odict(dumper, data): value = list() node = yaml.nodes.MappingNode( 'tag:yaml.org,2002:map', value, flow_style=None ) if dumper.alias_key is not None: dumper.represented_objects[dumper.alias_key] = node for item_key, item_value in data.items(): node_key = dumper.represent_data(item_key) node_value = dumper.represent_data(item_value) value.append((node_key, node_value)) node.flow_style = False return node def represent_undefined(dumper, data): if isinstance(data, tuple) and hasattr(data, '_make') and hasattr(data, '_asdict'): return dumper.represent_odict(data._asdict()) # assuming namedtuple elif isinstance(data, OrderedDict): return dumper.represent_odict(data) elif isinstance(data, dict): return dumper.represent_dict(data) elif callable(getattr(data, 'tolist', None)): return dumper.represent_data(data.tolist()) return super(PrettyYAMLDumper, dumper).represent_undefined(data) def represent_dict(dumper, data): if not dumper.pyaml_sort_dicts: return dumper.represent_odict(data) return super(PrettyYAMLDumper, dumper).represent_dict(data) def serialize_node(self, node, parent, index): if self.pyaml_force_embed: self.serialized_nodes.clear() return super(PrettyYAMLDumper, self).serialize_node(node, parent, index) @staticmethod def pyaml_transliterate(string): if not all(ord(c) < 128 for c in string): from unidecode import unidecode string = unidecode(string) string_new = '' for ch in string: if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' or ch in '-_': string_new += ch else: string_new += '_' return string_new.lower() def anchor_node(self, node, hint=list()): if node in self.anchors: if self.anchors[node] is None and not self.pyaml_force_embed: self.anchors[node] = self.generate_anchor(node)\ if not hint else '{}'.format( self.pyaml_transliterate( '_-_'.join(map(op.attrgetter('value'), hint)) ) ) else: self.anchors[node] = None if isinstance(node, yaml.nodes.SequenceNode): for item in node.value: self.anchor_node(item) elif isinstance(node, yaml.nodes.MappingNode): for key, value in node.value: self.anchor_node(key) self.anchor_node(value, hint=hint+[key]) PrettyYAMLDumper.add_representer(dict, PrettyYAMLDumper.represent_dict) PrettyYAMLDumper.add_representer(defaultdict, PrettyYAMLDumper.represent_dict) PrettyYAMLDumper.add_representer(OrderedDict, PrettyYAMLDumper.represent_odict) PrettyYAMLDumper.add_representer(set, PrettyYAMLDumper.represent_list) PrettyYAMLDumper.add_representer(None, PrettyYAMLDumper.represent_undefined) if sys.version_info.major >= 3: try: import pathlib except ImportError: pass else: PrettyYAMLDumper.add_representer( type(pathlib.Path('')), lambda cls,o: cls.represent_data(str(o)) ) class UnsafePrettyYAMLDumper(PrettyYAMLDumper): def expect_block_sequence(self): self.increase_indent(flow=False, indentless=False) self.state = self.expect_first_block_sequence_item def expect_block_sequence_item(self, first=False): if not first and isinstance(self.event, yaml.events.SequenceEndEvent): self.indent = self.indents.pop() self.state = self.states.pop() else: self.write_indent() self.write_indicator('-', True, indention=True) self.states.append(self.expect_block_sequence_item) self.expect_node(sequence=True) def choose_scalar_style(self): is_dict_key = self.states[-1] == self.expect_block_mapping_simple_value if is_dict_key: # Don't mess-up (replace) styles for dict keys, if possible if self.pyaml_string_val_style: self.event.style = 'plain' else: # Make sure we don't create "key: null" mapping accidentally if self.event.value.endswith(':'): self.event.style = "'" return super(UnsafePrettyYAMLDumper, self).choose_scalar_style()\ if self.event.style != 'plain' else ("'" if ' ' in self.event.value else None) def represent_stringish(dumper, data): # Will crash on bytestrings with weird chars in them, # because we can't tell if it's supposed to be e.g. utf-8 readable string # or an arbitrary binary buffer, and former one *must* be pretty-printed # PyYAML's Representer.represent_str does the guesswork and !!binary or !!python/str # Explicit crash on any bytes object might be more sane, but also annoying # Use something like base64 to encode such buffer values instead # Having such binary stuff pretty much everywhere on unix (e.g. paths) kinda sucks data = unicode(data) # read the comment above # Try to use '|' style for multiline data, # quoting it with 'literal' if lines are too long anyway, # not sure if Emitter.analyze_scalar can also provide useful info here style = dumper.pyaml_string_val_style if not style: style = 'plain' if '\n' in data or not data or data == '-' or data[0] in '!&*[': style = 'literal' if '\n' in data[:-1]: for line in data.splitlines(): if len(line) > dumper.best_width: break else: style = '|' return yaml.representer.ScalarNode('tag:yaml.org,2002:str', data, style=style) for str_type in {bytes, unicode}: UnsafePrettyYAMLDumper.add_representer( str_type, UnsafePrettyYAMLDumper.represent_stringish ) UnsafePrettyYAMLDumper.add_representer( type(None), lambda s,o: s.represent_scalar('tag:yaml.org,2002:null', '') ) def add_representer(*args, **kws): PrettyYAMLDumper.add_representer(*args, **kws) UnsafePrettyYAMLDumper.add_representer(*args, **kws) def dump_add_vspacing(buff, vspacing): 'Post-processing to add some nice-ish spacing for deeper map/list levels.' if isinstance(vspacing, int): vspacing = ['\n']*(vspacing+1) buff.seek(0) result = list() for line in buff: level = 0 line = line.decode('utf-8') result.append(line) if ':' in line or re.search(r'---(\s*$|\s)', line): while line.startswith(' '): level, line = level + 1, line[2:] if len(vspacing) > level and len(result) != 1: vspace = vspacing[level] result.insert( -1, vspace if not isinstance(vspace, int) else '\n'*vspace ) buff.seek(0), buff.truncate() buff.write(''.join(result).encode('utf-8')) def dump_all(data, *dump_args, **dump_kws): return dump(data, *dump_args, multiple_docs=True, **dump_kws) def dump( data, dst=unicode, safe=False, force_embed=False, vspacing=None, string_val_style=None, sort_dicts=True, multiple_docs=False, **pyyaml_kws ): buff = io.BytesIO() Dumper = PrettyYAMLDumper if safe else UnsafePrettyYAMLDumper Dumper = ft.partial( Dumper, force_embed=force_embed, string_val_style=string_val_style, sort_dicts=sort_dicts ) if not multiple_docs: data = [data] else: pyyaml_kws.setdefault('explicit_start', True) yaml.dump_all( data, buff, Dumper=Dumper, default_flow_style=False, allow_unicode=True, encoding='utf-8', **pyyaml_kws ) if vspacing is not None: dump_add_vspacing(buff, vspacing) buff = buff.getvalue() if dst is bytes: return buff elif dst is unicode: return buff.decode('utf-8') else: try: dst.write(b'') # tests if dst is unicode- or bytestream except: dst.write(buff.decode('utf-8')) else: dst.write(buff) def dumps(data, **dump_kws): return dump(data, dst=bytes, **dump_kws) def pprint(*data, **dump_kws): dst = dump_kws.pop('file', dump_kws.pop('dst', sys.stdout)) if len(data) == 1: data, = data dump(data, dst=dst, **dump_kws) p, _p = pprint, print print = pprint # pyaml.print() won't work without "from __future__ import print_function" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1575692161.0 pyaml-19.12.0/pyaml/__main__.py0000644000175000017500000000315700000000000017275 0ustar00fraggodfraggod00000000000000# -*- coding: utf-8 -*- import os, sys, stat, tempfile, contextlib, yaml, pyaml @contextlib.contextmanager def safe_replacement(path, *open_args, **open_kws): path = str(path) try: mode = stat.S_IMODE(os.stat(path).st_mode) except (OSError, IOError): mode = None open_kws.update( delete=False, dir=os.path.dirname(path), prefix=os.path.basename(path)+'.' ) with tempfile.NamedTemporaryFile(*open_args, **open_kws) as tmp: try: if mode is not None: os.fchmod(tmp.fileno(), mode) yield tmp if not tmp.closed: tmp.flush() os.rename(tmp.name, path) finally: try: os.unlink(tmp.name) except (OSError, IOError): pass def main(argv=None): import argparse parser = argparse.ArgumentParser( description='Process and dump prettified YAML to stdout.') parser.add_argument('path', nargs='?', metavar='path', help='Path to YAML to read (default: use stdin).') parser.add_argument('-r', '--replace', action='store_true', help='Replace specified path with prettified version in-place.') parser.add_argument('-w', '--width', type=int, metavar='chars', help='Max line width hint to pass to pyyaml for the dump.' ' Only used to format scalars and collections (e.g. lists).') opts = parser.parse_args(argv or sys.argv[1:]) src = open(opts.path) if opts.path else sys.stdin try: data = yaml.safe_load(src) finally: src.close() pyaml_kwargs = dict() if opts.width: pyaml_kwargs['width'] = opts.width if opts.replace and opts.path: with safe_replacement(opts.path) as tmp: pyaml.pprint(data, file=tmp, **pyaml_kwargs) else: pyaml.pprint(data, **pyaml_kwargs) if __name__ == '__main__': sys.exit(main()) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1575692709.0221465 pyaml-19.12.0/pyaml/tests/0000755000175000017500000000000000000000000016337 5ustar00fraggodfraggod00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1554927782.0 pyaml-19.12.0/pyaml/tests/__init__.py0000644000175000017500000000000000000000000020436 0ustar00fraggodfraggod00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1555468102.0 pyaml-19.12.0/pyaml/tests/dump.py0000644000175000017500000004144300000000000017664 0ustar00fraggodfraggod00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import itertools as it, operator as op, functools as ft from collections import Mapping, OrderedDict, namedtuple import os, sys, io, yaml, unittest if sys.version_info.major > 2: unicode = str try: import pyaml except ImportError: sys.path.insert(1, os.path.join(__file__, *['..']*3)) import pyaml large_yaml = b''' ### Default (baseline) configuration parameters. ### DO NOT ever change this config, use -c commandline option instead! # Note that this file is YAML, so YAML types can be used here, see http://yaml.org/type/ # For instance, large number can be specified as "10_000_000" or "!!float 10e6". source: # Path or glob pattern (to match path) to backup, required path: # example: /srv/backups/weekly.* queue: # Path to intermediate backup queue-file (list of paths to upload), required path: # example: /srv/backups/queue.txt # Don't rebuild queue-file if it's newer than source.path check_mtime: true entry_cache: # Path to persistent db (sqlite) of remote directory nodes, required path: # example: /srv/backups/dentries.sqlite # How to pick a path among those matched by "path" glob pick_policy: alphasort_last # only one supported destination: # URL of Tahoe-LAFS node webapi url: http://localhost:3456/uri result: # what to do with a cap (URI) of a resulting tree (with full backup) print_to_stdout: true # Append the entry to the specified file (creating it, if doesn't exists) # Example entry: "2012-10-10T23:12:43.904543 /srv/backups/weekly.2012-10-10 URI:DIR2-CHK:..." append_to_file: # example: /srv/backups/lafs_caps # Append the entry to specified tahoe-lafs directory (i.e. put it into that dir) append_to_lafs_dir: # example: URI:DIR2:... encoding: xz: enabled: true options: # see lzma.LZMAOptions, empty = module defaults min_size: 5120 # don't compress files smaller than 5 KiB (unless overidden in "path_filter") path_filter: # List of include/exclude regexp path-rules, similar to "filter" section below. # Same as with "filter", rules can be tuples with '+' or '-' (implied for strings) as first element. # '+' will indicate that file is compressible, if it's size >= "min_size" option. # Unlike "filter", first element of rule-tuple can also be a number, # overriding "min_size" parameter for matched (by that rule) paths. # If none of the patterns match path, file is handled as if it was matched by '+' rule. - '\.(gz|bz2|t[gb]z2?|xz|lzma|7z|zip|rar)$' - '\.(rpm|deb|iso)$' - '\.(jpe?g|gif|png|mov|avi|ogg|mkv|webm|mp[34g]|flv|flac|ape|pdf|djvu)$' - '\.(sqlite3?|fossil|fsl)$' - '\.git/objects/[0-9a-f]+/[0-9a-f]+$' # - [500, '\.(txt|csv|log|md|rst|cat|(ba|z|k|c|fi)?sh|env)$'] # - [500, '\.(cgi|py|p[lm]|php|c|h|[ce]l|lisp|hs|patch|diff|xml|xsl|css|x?html[45]?|js)$'] # - [500, '\.(co?nf|cfg?|li?st|ini|ya?ml|jso?n|vg|tab)(\.(sample|default|\w+-new))?$'] # - [500, '\.(unit|service|taget|mount|desktop|rules|rc|menu)$'] # - [2000, '^/etc/'] http: request_pool_options: maxPersistentPerHost: 10 cachedConnectionTimeout: 600 retryAutomatically: true ca_certs_files: /etc/ssl/certs/ca-certificates.crt # can be a list debug_requests: false # insecure! logs will contain tahoe caps filter: # Either tuples like "[action ('+' or '-'), regexp]" or just exclude-patterns (python # regexps) to match relative (to source.path, starting with "/") paths to backup. # Patterns are matched against each path in order they're listed here. # Leaf directories are matched with the trailing slash # (as with rsync) to be distinguishable from files with the same name. # If path doesn't match any regexp on the list, it will be included. # # Examples: # - ['+', '/\.git/config$'] # backup git repository config files # - '/\.git/' # *don't* backup any repository objects # - ['-', '/\.git/'] # exactly same thing as above (redundant) # - '/(?i)\.?svn(/.*|ignore)$' # exclude (case-insensitive) svn (or .svn) paths and ignore-lists - '/(CVS|RCS|SCCS|_darcs|\{arch\})/$' - '/\.(git|hg|bzr|svn|cvs)(/|ignore|attributes|tags)?$' - '/=(RELEASE-ID|meta-update|update)$' operation: queue_only: false # only generate upload queue file, don't upload anything reuse_queue: false # don't generate upload queue file, use existing one as-is disable_deduplication: false # make no effort to de-duplicate data (should still work on tahoe-level for files) # Rate limiting might be useful to avoid excessive cpu/net usage on nodes, # and especially when uploading to rate-limited api's (like free cloud storages). # Only used when uploading objects to the grid, not when building queue file. # Format of each value is "interval[:burst]", where "interval" can be specified as rate (e.g. "1/3e5"). # Simple token bucket algorithm is used. Empty values mean "no limit". # Examples: # "objects: 1/10:50" - 10 objects per second, up to 50 at once (if rate was lower before). # "objects: 0.1:50" - same as above. # "objects: 10:20" - 1 object in 10 seconds, up to 20 at once. # "objects: 5" - make interval between object uploads equal 5 seconds. # "bytes: 1/3e6:50e6" - 3 MB/s max, up to 50 MB/s if connection was underutilized before. rate_limit: bytes: # limit on rate of *file* bytes upload, example: 1/3e5:20e6 objects: # limit on rate of uploaded objects, example: 10:50 logging: # see http://docs.python.org/library/logging.config.html # "custom" level means WARNING/DEBUG/NOISE, depending on CLI options warnings: true # capture python warnings sql_queries: false # log executed sqlite queries (very noisy, caps will be there) version: 1 formatters: basic: format: '%(asctime)s :: %(name)s :: %(levelname)s: %(message)s' datefmt: '%Y-%m-%d %H:%M:%S' handlers: console: class: logging.StreamHandler stream: ext://sys.stderr formatter: basic level: custom debug_logfile: class: logging.handlers.RotatingFileHandler filename: /srv/backups/debug.log formatter: basic encoding: utf-8 maxBytes: 5242880 # 5 MiB backupCount: 2 level: NOISE loggers: twisted: handlers: [console] level: 0 root: level: custom handlers: [console] ''' data = dict( path='/some/path', query_dump=OrderedDict([ ('key1', 'тест1'), ('key2', 'тест2'), ('key3', 'тест3'), ('последний', None) ]), ids=OrderedDict(), a=[1,None,'asd', 'не-ascii'], b=3.5, c=None, asd=OrderedDict([('b', 1), ('a', 2)]) ) data['query_dump_clone'] = data['query_dump'] data['ids']['id в уникоде'] = [4, 5, 6] data['ids']['id2 в уникоде'] = data['ids']['id в уникоде'] # data["'asd'\n!\0\1"] =OrderedDict([('b', 1), ('a', 2)]) <-- fails in many ways data_str_multiline = dict(cert=( '-----BEGIN CERTIFICATE-----\n' 'MIIDUjCCAjoCCQD0/aLLkLY/QDANBgkqhkiG9w0BAQUFADBqMRAwDgYDVQQKFAdm\n' 'Z19jb3JlMRYwFAYDVQQHEw1ZZWthdGVyaW5idXJnMR0wGwYDVQQIExRTdmVyZGxv\n' 'dnNrYXlhIG9ibGFzdDELMAkGA1UEBhMCUlUxEjAQBgNVBAMTCWxvY2FsaG9zdDAg\n' 'Fw0xMzA0MjQwODUxMTRaGA8yMDUzMDQxNDA4NTExNFowajEQMA4GA1UEChQHZmdf\n' 'Y29yZTEWMBQGA1UEBxMNWWVrYXRlcmluYnVyZzEdMBsGA1UECBMUU3ZlcmRsb3Zz\n' 'a2F5YSBvYmxhc3QxCzAJBgNVBAYTAlJVMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEi\n' 'MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnZr3jbhfb5bUhORhmXOXOml8N\n' 'fAli/ak6Yv+LRBtmOjke2gFybPZFuXYr0lYGQ4KgarN904vEg7WUbSlwwJuszJxQ\n' 'Lz3xSDqQDqF74m1XeBYywZQIywKIbA/rfop3qiMeDWo3WavYp2kaxW28Xd/ZcsTd\n' 'bN/eRo+Ft1bor1VPiQbkQKaOOi6K8M9a/2TK1ei2MceNbw6YrlCZe09l61RajCiz\n' 'y5eZc96/1j436wynmqJn46hzc1gC3APjrkuYrvUNKORp8y//ye+6TX1mVbYW+M5n\n' 'CZsIjjm9URUXf4wsacNlCHln1nwBxUe6D4e2Hxh2Oc0cocrAipxuNAa8Afn5AgMB\n' 'AAEwDQYJKoZIhvcNAQEFBQADggEBADUHf1UXsiKCOYam9u3c0GRjg4V0TKkIeZWc\n' 'uN59JWnpa/6RBJbykiZh8AMwdTonu02g95+13g44kjlUnK3WG5vGeUTrGv+6cnAf\n' '4B4XwnWTHADQxbdRLja/YXqTkZrXkd7W3Ipxdi0bDCOSi/BXSmiblyWdbNU4cHF/\n' 'Ex4dTWeGFiTWY2upX8sa+1PuZjk/Ry+RPMLzuamvzP20mVXmKtEIfQTzz4b8+Pom\n' 'T1gqPkNEbe2j1DciRNUOH1iuY+cL/b7JqZvvdQK34w3t9Cz7GtMWKo+g+ZRdh3+q\n' '2sn5m3EkrUb1hSKQbMWTbnaG4C/F3i4KVkH+8AZmR9OvOmZ+7Lo=\n' '-----END CERTIFICATE-----' )) data_str_long = dict(cert=( 'MIIDUjCCAjoCCQD0/aLLkLY/QDANBgkqhkiG9w0BAQUFADBqMRAwDgYDVQQKFAdm' 'Z19jb3JlMRYwFAYDVQQHEw1ZZWthdGVyaW5idXJnMR0wGwYDVQQIExRTdmVyZGxv' 'dnNrYXlhIG9ibGFzdDELMAkGA1UEBhMCUlUxEjAQBgNVBAMTCWxvY2FsaG9zdDAg' 'Fw0xMzA0MjQwODUxMTRaGA8yMDUzMDQxNDA4NTExNFowajEQMA4GA1UEChQHZmdf' 'Y29yZTEWMBQGA1UEBxMNWWVrYXRlcmluYnVyZzEdMBsGA1UECBMUU3ZlcmRsb3Zz' 'a2F5YSBvYmxhc3QxCzAJBgNVBAYTAlJVMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEi' 'MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnZr3jbhfb5bUhORhmXOXOml8N' 'fAli/ak6Yv+LRBtmOjke2gFybPZFuXYr0lYGQ4KgarN904vEg7WUbSlwwJuszJxQ' 'Lz3xSDqQDqF74m1XeBYywZQIywKIbA/rfop3qiMeDWo3WavYp2kaxW28Xd/ZcsTd' 'bN/eRo+Ft1bor1VPiQbkQKaOOi6K8M9a/2TK1ei2MceNbw6YrlCZe09l61RajCiz' 'y5eZc96/1j436wynmqJn46hzc1gC3APjrkuYrvUNKORp8y//ye+6TX1mVbYW+M5n' 'CZsIjjm9URUXf4wsacNlCHln1nwBxUe6D4e2Hxh2Oc0cocrAipxuNAa8Afn5AgMB' 'AAEwDQYJKoZIhvcNAQEFBQADggEBADUHf1UXsiKCOYam9u3c0GRjg4V0TKkIeZWc' 'uN59JWnpa/6RBJbykiZh8AMwdTonu02g95+13g44kjlUnK3WG5vGeUTrGv+6cnAf' '4B4XwnWTHADQxbdRLja/YXqTkZrXkd7W3Ipxdi0bDCOSi/BXSmiblyWdbNU4cHF/' 'Ex4dTWeGFiTWY2upX8sa+1PuZjk/Ry+RPMLzuamvzP20mVXmKtEIfQTzz4b8+Pom' 'T1gqPkNEbe2j1DciRNUOH1iuY+cL/b7JqZvvdQK34w3t9Cz7GtMWKo+g+ZRdh3+q' '2sn5m3EkrUb1hSKQbMWTbnaG4C/F3i4KVkH+8AZmR9OvOmZ+7Lo=' )) # Restore Python2-like heterogeneous list sorting functionality in Python3 # Based on https://gist.github.com/pR0Ps/1e1a1e892aad5b691448 def compare(x, y): if x == y: return 0 try: if x < y: return -1 else: return 1 except TypeError as e: # The case where both are None is taken care of by the equality test if x is None: return -1 elif y is None: return 1 if type(x) != type(y): return compare(*map(lambda t: type(t).__name__, [x, y])) # Types are the same but a native compare didn't work. # x and y might be indexable, recursively compare elements for a, b in zip(x, y): c = compare(a, b) if c != 0: return c return compare(len(x), len(y)) class DumpTests(unittest.TestCase): def flatten(self, data, path=tuple()): dst = list() if isinstance(data, (tuple, list)): for v in data: dst.extend(self.flatten(v, path + (list,))) elif isinstance(data, Mapping): for k,v in data.items(): dst.extend(self.flatten(v, path + (k,))) else: dst.append((path, data)) return tuple(sorted(dst, key=ft.cmp_to_key(compare))) def test_dst(self): buff = io.BytesIO() self.assertIs(pyaml.dump(data, buff), None) self.assertIsInstance(pyaml.dump(data, str), str) self.assertIsInstance(pyaml.dump(data, unicode), unicode) def test_simple(self): a = self.flatten(data) b = pyaml.dump(data, unicode) self.assertEqual(a, self.flatten(yaml.safe_load(b))) def test_vspacing(self): data = yaml.safe_load(large_yaml) a = self.flatten(data) b = pyaml.dump(data, unicode, vspacing=[2, 1]) self.assertEqual(a, self.flatten(yaml.safe_load(b))) pos, pos_list = 0, list() while True: pos = b.find(u'\n', pos+1) if pos < 0: break pos_list.append(pos) self.assertEqual( pos_list, [ 12, 13, 25, 33, 53, 74, 89, 108, 158, 185, 265, 300, 345, 346, 356, 376, 400, 426, 427, 460, 461, 462, 470, 508, 564, 603, 604, 605, 611, 612, 665, 666, 690, 691, 715, 748, 777, 806, 807, 808, 817, 818, 832, 843, 878, 948, 949, 961, 974, 1009, 1032, 1052, 1083, 1102, 1123, 1173, 1195, 1234, 1257, 1276, 1300, 1301, 1312, 1325, 1341, 1359, 1374, 1375, 1383, 1397, 1413, 1431, 1432, 1453, 1454, 1467, 1468, 1485, 1486, 1487, 1498, 1499, 1530, 1531, 1551, 1552, 1566, 1577, 1590, 1591, 1612, 1613, 1614, 1622, 1623, 1638, 1648, 1649, 1657, 1658, 1688, 1689, 1698, 1720, 1730 ] ) b = pyaml.dump(data, unicode) self.assertNotIn('\n\n', b) def test_ids(self): b = pyaml.dump(data, unicode) self.assertNotIn('&id00', b) self.assertIn('query_dump_clone: *query_dump_clone', b) self.assertIn("'id в уникоде': &ids_-_id2_v_unikode", b) # kinda bug - should be just "id" def test_force_embed(self): b = pyaml.dump(data, unicode, force_embed=True) c = pyaml.dump(data, unicode, safe=True, force_embed=True) for char, dump in it.product('*&', [b, c]): self.assertNotIn(char, dump) def test_encoding(self): b = pyaml.dump(data, unicode, force_embed=True) b_lines = list(map(unicode.strip, b.splitlines())) chk = ['query_dump:', 'key1: тест1', 'key2: тест2', 'key3: тест3', 'последний:'] pos = b_lines.index('query_dump:') self.assertEqual(b_lines[pos:pos + len(chk)], chk) def test_str_long(self): b = pyaml.dump(data_str_long, unicode) self.assertNotIn('"', b) self.assertNotIn("'", b) self.assertEqual(len(b.splitlines()), 1) def test_str_multiline(self): b = pyaml.dump(data_str_multiline, unicode) b_lines = b.splitlines() self.assertGreater(len(b_lines), len(data_str_multiline['cert'].splitlines())) for line in b_lines: self.assertLess(len(line), 100) def test_dumps(self): b = pyaml.dumps(data_str_multiline) self.assertIsInstance(b, bytes) def test_print(self): self.assertIs(pyaml.print, pyaml.pprint) self.assertIs(pyaml.print, pyaml.p) buff = io.BytesIO() b = pyaml.dump(data_str_multiline, dst=bytes) pyaml.print(data_str_multiline, file=buff) self.assertEqual(b, buff.getvalue()) def test_print_args(self): buff = io.BytesIO() args = 1, 2, 3 b = pyaml.dump(args, dst=bytes) pyaml.print(*args, file=buff) self.assertEqual(b, buff.getvalue()) def test_str_style_pick(self): a = pyaml.dump(data_str_multiline) b = pyaml.dump(data_str_multiline, string_val_style='|') self.assertEqual(a, b) b = pyaml.dump(data_str_multiline, string_val_style='plain') self.assertNotEqual(a, b) self.assertTrue(pyaml.dump('waka waka', string_val_style='|').startswith('|-\n')) self.assertEqual(pyaml.dump(dict(a=1), string_val_style='|'), 'a: 1\n') def test_colons_in_strings(self): val1 = {'foo': ['bar:', 'baz', 'bar:bazzo', 'a: b'], 'foo:': 'yak:'} val1_str = pyaml.dump(val1) val2 = yaml.safe_load(val1_str) val2_str = pyaml.dump(val2) val3 = yaml.safe_load(val2_str) self.assertEqual(val1, val2) self.assertEqual(val1_str, val2_str) self.assertEqual(val2, val3) def test_empty_strings(self): val1 = {'key': ['', 'stuff', '', 'more'], '': 'value', 'k3': ''} val1_str = pyaml.dump(val1) val2 = yaml.safe_load(val1_str) val2_str = pyaml.dump(val2) val3 = yaml.safe_load(val2_str) self.assertEqual(val1, val2) self.assertEqual(val1_str, val2_str) self.assertEqual(val2, val3) def test_single_dash_strings(self): strip_seq_dash = lambda line: line.lstrip().lstrip('-').lstrip() val1 = {'key': ['-', '-stuff', '- -', '- more-', 'more-', '--']} val1_str = pyaml.dump(val1) val2 = yaml.safe_load(val1_str) val2_str = pyaml.dump(val2) val3 = yaml.safe_load(val2_str) self.assertEqual(val1, val2) self.assertEqual(val1_str, val2_str) self.assertEqual(val2, val3) val1_str_lines = val1_str.splitlines() self.assertEqual(strip_seq_dash(val1_str_lines[2]), '-stuff') self.assertEqual(strip_seq_dash(val1_str_lines[5]), 'more-') self.assertEqual(strip_seq_dash(val1_str_lines[6]), '--') val1 = {'key': '-'} val1_str = pyaml.dump(val1) val2 = yaml.safe_load(val1_str) val2_str = pyaml.dump(val2) val3 = yaml.safe_load(val2_str) def test_namedtuple(self): TestTuple = namedtuple('TestTuple', 'y x z') val = TestTuple(1, 2, 3) val_str = pyaml.dump(val) self.assertEqual(val_str, u'y: 1\nx: 2\nz: 3\n') # namedtuple order was preserved def test_ordereddict(self): d = OrderedDict((i, '') for i in reversed(range(10))) lines = pyaml.dump(d).splitlines() self.assertEqual(lines, list(reversed(sorted(lines)))) def test_pyyaml_params(self): d = {'foo': 'lorem ipsum ' * 30} # 300+ chars for w in 40, 80, 200: lines = pyaml.dump(d, width=w, indent=10).splitlines() for n, line in enumerate(lines, 1): self.assertLess(len(line), w*1.2) if n != len(lines): self.assertGreater(len(line), w*0.8) def test_multiple_docs(self): docs = [yaml.safe_load(large_yaml), dict(a=1, b=2, c=3)] docs_str = pyaml.dump_all(docs, vspacing=[3, 2]) self.assertTrue(docs_str.startswith('---')) self.assertIn('---\n\n\n\na: 1\n\n\n\nb: 2\n\n\n\nc: 3\n', docs_str) docs_str2 = pyaml.dump(docs, vspacing=[3, 2], multiple_docs=True) self.assertEqual(docs_str, docs_str2) docs_str2 = pyaml.dump(docs, vspacing=[3, 2]) self.assertNotEqual(docs_str, docs_str2) docs_str2 = pyaml.dump_all(docs, explicit_start=False) self.assertFalse(docs_str2.startswith('---')) self.assertNotEqual(docs_str, docs_str2) docs_str = pyaml.dump(docs, multiple_docs=True, explicit_start=False) self.assertEqual(docs_str, docs_str2) if __name__ == '__main__': unittest.main() # print('-'*80) # pyaml.dump(yaml.safe_load(large_yaml), sys.stdout) # print('-'*80) # pyaml.dump(data, sys.stdout) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1575692709.0221465 pyaml-19.12.0/pyaml.egg-info/0000755000175000017500000000000000000000000016667 5ustar00fraggodfraggod00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1575692708.0 pyaml-19.12.0/pyaml.egg-info/PKG-INFO0000644000175000017500000003061500000000000017771 0ustar00fraggodfraggod00000000000000Metadata-Version: 1.1 Name: pyaml Version: 19.12.0 Summary: PyYAML-based module to produce pretty and readable YAML-serialized data Home-page: https://github.com/mk-fg/pretty-yaml Author: Mike Kazantsev Author-email: mk.fraggod@gmail.com License: WTFPL Description: pretty-yaml (or pyaml) ====================== PyYAML-based python module to produce pretty and readable YAML-serialized data. This module is for serialization only, see `ruamel.yaml`_ module for literate YAML parsing (keeping track of comments, spacing, line/column numbers of values, etc). .. contents:: :backlinks: none Warning ------- Prime goal of this module is to produce human-readable output that can be easily manipulated and re-used, but maybe with some occasional caveats. One good example of such "caveat" is that e.g. ``{'foo': '123'}`` will serialize to ``foo: 123``, which for PyYAML would be a bug, as 123 will then be read back as an integer from that, but here it's a feature. So please do not rely on the thing to produce output that can always be deserialized exactly to what was exported, at least - use PyYAML (e.g. with options from the next section) for that. What this module does and why ----------------------------- YAML is generally nice and easy format to read *if* it was written by humans. PyYAML can a do fairly decent job of making stuff readable, and the best combination of parameters for such output that I've seen so far is probably this one:: >>> m = [123, 45.67, {1: None, 2: False}, u'some text'] >>> data = dict(a=u'asldnsa\nasldpáknsa\n', b=u'whatever text', ma=m, mb=m) >>> yaml.safe_dump(data, sys.stdout, allow_unicode=True, default_flow_style=False) a: 'asldnsa asldpáknsa ' b: whatever text ma: &id001 - 123 - 45.67 - 1: null 2: false - some text mb: *id001 pyaml tries to improve on that a bit, with the following tweaks: * Most human-friendly representation options in PyYAML (that I know of) get picked as defaults. * Does not dump "null" values, if possible, replacing these with just empty strings, which have the same meaning but reduce visual clutter and are easier to edit. * Dicts, sets, OrderedDicts, defaultdicts, namedtuples, etc are representable and get sorted on output (OrderedDicts and namedtuples keep their ordering), so that output would be as diff-friendly as possible, and not arbitrarily depend on python internals. It appears that at least recent PyYAML versions also do such sorting for python dicts. * List items get indented, as they should be. * bytestrings that can't be auto-converted to unicode raise error, as yaml has no "binary bytes" (i.e. unix strings) type. * Attempt is made to pick more readable string representation styles, depending on the value, e.g.:: >>> yaml.safe_dump(cert, sys.stdout) cert: '-----BEGIN CERTIFICATE----- MIIH3jCCBcagAwIBAgIJAJi7AjQ4Z87OMA0GCSqGSIb3DQEBCwUAMIHBMRcwFQYD VQQKFA52YWxlcm9uLm5vX2lzcDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0aG9y ... >>> pyaml.p(cert): cert: | -----BEGIN CERTIFICATE----- MIIH3jCCBcagAwIBAgIJAJi7AjQ4Z87OMA0GCSqGSIb3DQEBCwUAMIHBMRcwFQYD VQQKFA52YWxlcm9uLm5vX2lzcDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0aG9y ... * "force_embed" option to avoid having &id stuff scattered all over the output (which might be beneficial in some cases, hence the option). * "&id" anchors, if used, get labels from the keys they get attached to, not just use meaningless enumerators. * "string_val_style" option to only apply to strings that are values, not keys, i.e:: >>> pyaml.p(data, string_val_style='"') key: "value\nasldpáknsa\n" >>> yaml.safe_dump(data, sys.stdout, allow_unicode=True, default_style='"') "key": "value\nasldpáknsa\n" * "sort_dicts=False" option to leave dict item ordering to python, and not force-sort them in yaml output, which can be important for python 3.6+ where they retain ordering info. * Has an option to add vertical spacing (empty lines) between keys on different depths, to make output much more seekable. Result for the (rather meaningless) example above (without any additional tweaks):: >>> pyaml.p(data) a: | asldnsa asldpáknsa b: 'whatever text' ma: &ma - 123 - 45.67 - 1: 2: false - 'some text' mb: *ma ---------- Extended example:: >>> pyaml.dump(conf, sys.stdout, vspacing=[2, 1]): destination: encoding: xz: enabled: true min_size: 5120 options: path_filter: - \.(gz|bz2|t[gb]z2?|xz|lzma|7z|zip|rar)$ - \.(rpm|deb|iso)$ - \.(jpe?g|gif|png|mov|avi|ogg|mkv|webm|mp[34g]|flv|flac|ape|pdf|djvu)$ - \.(sqlite3?|fossil|fsl)$ - \.git/objects/[0-9a-f]+/[0-9a-f]+$ result: append_to_file: append_to_lafs_dir: print_to_stdout: true url: http://localhost:3456/uri filter: - /(CVS|RCS|SCCS|_darcs|\{arch\})/$ - /\.(git|hg|bzr|svn|cvs)(/|ignore|attributes|tags)?$ - /=(RELEASE-ID|meta-update|update)$ http: ca_certs_files: /etc/ssl/certs/ca-certificates.crt debug_requests: false request_pool_options: cachedConnectionTimeout: 600 maxPersistentPerHost: 10 retryAutomatically: true logging: formatters: basic: datefmt: '%Y-%m-%d %H:%M:%S' format: '%(asctime)s :: %(name)s :: %(levelname)s: %(message)s' handlers: console: class: logging.StreamHandler formatter: basic level: custom stream: ext://sys.stderr loggers: twisted: handlers: - console level: 0 root: handlers: - console level: custom Note that unless there are many moderately wide and deep trees of data, which are expected to be read and edited by people, it might be preferrable to directly use PyYAML regardless, as it won't introduce another (rather pointless in that case) dependency and a point of failure. Some Tricks ----------- * Pretty-print any yaml or json (yaml subset) file from the shell:: % python -m pyaml /path/to/some/file.yaml % curl -s https://status.github.com/api.json | python -m pyaml * Process and replace json/yaml file in-place:: % python -m pyaml -r file-with-json.data * Easier "debug printf" for more complex data (all funcs below are aliases to same thing):: pyaml.p(stuff) pyaml.pprint(my_data) pyaml.pprint('----- HOW DOES THAT BREAKS!?!?', input_data, some_var, more_stuff) pyaml.print(data, file=sys.stderr) # needs "from __future__ import print_function" * Force all string values to a certain style (see info on these in `PyYAML docs`_):: pyaml.dump(many_weird_strings, string_val_style='|') pyaml.dump(multiline_words, string_val_style='>') pyaml.dump(no_want_quotes, string_val_style='plain') Using ``pyaml.add_representer()`` (note \*p\*yaml) as suggested in `this SO thread`_ (or `github-issue-7`_) should also work. * Control indent and width of the results:: pyaml.dump(wide_and_deep, indent=4, width=120) These are actually keywords for PyYAML Emitter (passed to it from Dumper), see more info on these in `PyYAML docs`_. * Dump multiple yaml documents into a file: ``pyaml.dump_all([data1, data2, data3], dst_file)`` explicit_start=True is implied, unless explicit_start=False is passed. .. _PyYAML docs: http://pyyaml.org/wiki/PyYAMLDocumentation#Scalars .. _this SO thread: http://stackoverflow.com/a/7445560 .. _github-issue-7: https://github.com/mk-fg/pretty-yaml/issues/7 Installation ------------ It's a regular package for Python (3.x or 2.x). Module uses PyYAML_ for processing of the actual YAML files and should pull it in as a dependency. Dependency on unidecode_ module is optional and should only be necessary if same-id objects or recursion is used within serialized data. Be sure to use python3/python2, pip3/pip2, easy_install-... binaries below, based on which python version you want to install the module for, if you have several on the system (as is norm these days for py2-py3 transition). Using pip_ is the best way:: % pip install pyaml (add --user option to install into $HOME for current user only) Or, if you don't have "pip" command:: % python -m ensurepip % python -m pip install --upgrade pip % python -m pip install pyaml (same suggestion wrt "install --user" as above) On a very old systems, one of these might work:: % curl https://bootstrap.pypa.io/get-pip.py | python % pip install pyaml % easy_install pyaml % git clone --depth=1 https://github.com/mk-fg/pretty-yaml % cd pretty-yaml % python setup.py install (all of install-commands here also have --user option, see also `pip docs "installing" section`_) Current-git version can be installed like this:: % pip install 'git+https://github.com/mk-fg/pretty-yaml#egg=pyaml' Note that to install stuff to system-wide PATH and site-packages (without --user), elevated privileges (i.e. root and su/sudo) are often required. Use "...install --user", `~/.pydistutils.cfg`_ or virtualenv_ to do unprivileged installs into custom paths. More info on python packaging can be found at `packaging.python.org`_. .. _ruamel.yaml: https://bitbucket.org/ruamel/yaml/ .. _PyYAML: http://pyyaml.org/ .. _unidecode: http://pypi.python.org/pypi/Unidecode .. _pip: http://pip-installer.org/ .. _pip docs "installing" section: http://www.pip-installer.org/en/latest/installing.html .. _~/.pydistutils.cfg: http://docs.python.org/install/index.html#distutils-configuration-files .. _virtualenv: http://pypi.python.org/pypi/virtualenv .. _packaging.python.org: https://packaging.python.org/installing/ Keywords: yaml serialization pretty print format human readable readability Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.5 Classifier: Topic :: Software Development Classifier: Topic :: Software Development :: Libraries :: Python Modules ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1575692708.0 pyaml-19.12.0/pyaml.egg-info/SOURCES.txt0000644000175000017500000000043000000000000020550 0ustar00fraggodfraggod00000000000000COPYING MANIFEST.in README README.rst setup.cfg setup.py pyaml/__init__.py pyaml/__main__.py pyaml.egg-info/PKG-INFO pyaml.egg-info/SOURCES.txt pyaml.egg-info/dependency_links.txt pyaml.egg-info/requires.txt pyaml.egg-info/top_level.txt pyaml/tests/__init__.py pyaml/tests/dump.py././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1575692708.0 pyaml-19.12.0/pyaml.egg-info/dependency_links.txt0000644000175000017500000000000100000000000022735 0ustar00fraggodfraggod00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1575692708.0 pyaml-19.12.0/pyaml.egg-info/requires.txt0000644000175000017500000000000700000000000021264 0ustar00fraggodfraggod00000000000000PyYAML ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1575692708.0 pyaml-19.12.0/pyaml.egg-info/top_level.txt0000644000175000017500000000000600000000000021415 0ustar00fraggodfraggod00000000000000pyaml ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1575692709.0241463 pyaml-19.12.0/setup.cfg0000644000175000017500000000010300000000000015666 0ustar00fraggodfraggod00000000000000[bdist_wheel] universal = 1 [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1575692678.0 pyaml-19.12.0/setup.py0000600000175000017500000000220400000000000015553 0ustar00fraggodfraggod00000000000000#!/usr/bin/env python from setuptools import setup, find_packages import os, io pkg_root = os.path.dirname(__file__) # Error-handling here is to allow package to be built w/o README included try: readme = io.open(os.path.join(pkg_root, 'README.rst'), encoding='utf-8').read() except IOError: readme = '' setup( name = 'pyaml', version = '19.12.0', author = 'Mike Kazantsev', author_email = 'mk.fraggod@gmail.com', license = 'WTFPL', keywords = 'yaml serialization pretty print format human readable readability', url = 'https://github.com/mk-fg/pretty-yaml', description = 'PyYAML-based module to' ' produce pretty and readable YAML-serialized data', long_description = readme, classifiers = [ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'Programming Language :: Python', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.5', 'Topic :: Software Development', 'Topic :: Software Development :: Libraries :: Python Modules' ], install_requires = ['PyYAML'], packages = find_packages(), package_data = {'': ['README.txt']}, exclude_package_data = {'': ['README.*']} )