From 567b5cc66dd2530ddf170b7eb0096d391311a197 Mon Sep 17 00:00:00 2001 From: Brad Cowie Date: Thu, 9 Jan 2025 15:37:05 +1300 Subject: [PATCH] Import ruamel.yaml 0.18.10 source --- .hgtags | 4 + CHANGES | 17 ++++ LICENSE | 2 +- README.md | 142 +++++++++++--------------- __init__.py | 17 +--- _doc/README.ryd | 81 ++++++++++++--- _doc/_static/pypi.svg | 2 +- _doc/api.ryd | 2 +- _doc/basicuse.ryd | 12 ++- _doc/contributing.ryd | 2 +- _doc/detail.ryd | 121 ++++++++++++---------- _doc/dumpcls.ryd | 18 ++-- _doc/example.ryd | 30 +++--- _doc/install.ryd | 4 +- _doc/links.rydinc | 12 +-- _doc/overview.ryd | 10 +- _doc/pyyaml.ryd | 18 ++-- compat.py | 4 +- composer.py | 2 +- constructor.py | 24 +++-- setup.py | 227 ++++++++++++++++++------------------------ tox.ini | 4 +- util.py | 3 +- 23 files changed, 401 insertions(+), 357 deletions(-) diff --git a/.hgtags b/.hgtags index 5836cb7..6dc6618 100644 --- a/.hgtags +++ b/.hgtags @@ -232,3 +232,7 @@ a35908655d678b8463ee6198869a0708b3446e06 0.18.2 e32fbfcda1a48d808542670d91f1e84d14f69956 0.18.3 08d87cada1f6e5fedde079b55536061e4fe246a0 0.18.4 eb3ecf31085135283908fc8449befebbc1fff4b3 0.18.5 +6f41eb6001661917fceb0e88ed0693ae1a7c50f4 0.18.6 +2ccda40f4274005ca52b7976e2d9666a66f9e5f9 0.18.7 +6d77c3b64d97a2c94729fa48e3236657a0352a47 0.18.8 +68accd7d13b00de1917a8e1604f1fbf76d3b7bfe 0.18.9 diff --git a/CHANGES b/CHANGES index de0d020..f8c3d98 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,20 @@ +[0.18.10, 2025-01-06]: +- implemented changes to the setup.py for Python 3.14 as suggested by [Miro Hrončok](https://sourceforge.net/u/hroncok/profile/) + in merge requests (MR not merged as those files are copied in from `develop` config) + +[0.18.9, 2025-01-05]: +- fix issue with roundtripping 0 in YAML 1.1 reported by [Peter Law](https://sourceforge.net/u/peterjclaw/profile/) + +[0.18.8, 2025-01-02]: +- added warning to README.md that PyPI might block updates due to breaking changes + +[0.18.7, 2024-12-30]: +- fixes for README (reported by [Kees Bakker](https://sourceforge.net/u/keesb/profile/)) +- fixes preserving anchor on scalar integer `0` (issue reported by (Mor Peled)[https://sourceforge.net/u/morp/profile/] + and also in a question by [Ravi](https://stackoverflow.com/users/6550398/ravi) on + [Stackoverflow](https://stackoverflow.com/a/79306830/1307905)) +- fix for formatting of README suggested by [Michael R. Crusoe](https://sourceforge.net/u/crusoe/profile/) + [0.18.6, 2024-02-07]: - fixed an issue with dataclass loading when the fields were collections (bug found as a result of a question by [FibroMyAlgebra](https://stackoverflow.com/users/6855070/fibromyalgebra) diff --git a/LICENSE b/LICENSE index 8777c9c..008000f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) - Copyright (c) 2014-2024 Anthon van der Neut, Ruamel bvba + Copyright (c) 2014-2025 Anthon van der Neut, Ruamel bvba Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 8e24a45..3c2d4f5 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,37 @@ - # ruamel.yaml `ruamel.yaml` is a YAML 1.2 loader/dumper package for Python. - - - - - - - - - - - - - - - - -
version0.18.6
updated2024-02-07
documentationhttps://yaml.readthedocs.io
repositoryhttps://sourceforge.net/projects/ruamel-yaml
pypihttps://pypi.org/project/ruamel.yaml
+ +| | | +| - | - | +| version |0.18.9 | +| updated |2025-01-05 | +| documentation |https://yaml.dev/doc/ruamel.yaml | +| repository |https://sourceforge.net/projects/ruamel-yaml | +| pypi |https://pypi.org/project/ruamel.yaml | + + +## breaking changes, that may make future uploads to PyPI impossible + +*If you are interested in future upgrades of `ruamel.yaml` +please check the [documentation on installing](https://yaml.dev/doc/ruamel.yaml/install/), +since at some point I might not be able to upload a new version to PyPI with updated information.* + +`ruamel.yaml` was intentionally named as `yaml` in a namespace `ruamel`. The namespace allows the installation +name to correspond unchanged to how the package is imported, reduces the number of links I have to create +in site-packages of a Python install during development, as well as providing a recognisable set of packages +my company releases to the public. + +However, after uploading version 0.18.7, I got an email from PyPI, about having to change the project name +to `ruamel_yaml` to comply with PEP 625, sometime in the future. The email doesn't say if namespace packages are +no longer allowed, or how to deal with the very real clash with the pre-existing package `ruamel_yaml`. + +I might not be able to adapt `ruamel.yaml`, in +a way that does not negatively affect the 0.5 million daily downloads (and my own usage of the package) in time. +My experience with other such service downgrades (Bitbucket, Readthedocs), has not been entirely positive. + +----- + As announced, in 0.18.0, the old PyYAML functions have been deprecated. @@ -26,7 +39,7 @@ As announced, in 0.18.0, the old PyYAML functions have been deprecated. (`_all`, `safe_`, `round_trip_`, etc)). If you only read this after your program has stopped working: I am sorry to hear that, but that also means you, or the person developing your program, has not tested with warnings on (which is the recommendation -in PEP 565, and e.g. defaultin when using `pytest`). If you have troubles, explicitly use +in PEP 565, and e.g. defaulting when using `pytest`). If you have troubles, explicitly use ``` pip install "ruamel.yaml<0.18.0" ``` @@ -44,15 +57,16 @@ but I do consider adding a `ruamel.yaml.unsafe` package that will re-add the `ty There seems to be a CVE on `ruamel.yaml`, stating that the `load()` function could be abused because of unchecked input. `load()` was never the default function (that was `round_trip_load()` -before the new API came into existence`. So the creator of that CVE was ill informed and +before the new API came into existence. So the creator of that CVE was ill informed and probably lazily assumed that since `ruamel.yaml` is a derivative of PyYAML (for which a similar CVE exists), the same problem would still exist, without checking. -So the CVE was always inappriate, now just more so, as the call +So the CVE was always inappropriate, now just more so, as the call to the function `load()` with any input will terminate your program with an error message. If you (have to) care about such things as this CVE, my recommendation is to stop using Python completely, as `pickle.load()` can be abused in the same way as `load()` (and like unlike `load()` is only documented to be unsafe, without development-time warning. +Version 0.18.9 was the last one tested to be working with Python 3.7 Version 0.17.21 was the last one tested to be working on Python 3.5 and 3.6
The 0.16.13 release was the last that was tested to be working on Python 2.7. @@ -67,69 +81,29 @@ email, preferably with some information on how you use the package (or a link to the repository) and I'll keep you informed when the status of the API is stable enough to make the transition. -
-    Overview
-
-    Installing
-      Optional requirements
-
-    Basic Usage
-      Load and dump  
-      More examples
-
-    Working with Python classes
-      Dumping Python classes
-      Dataclass
-
-    Details
-      Indentation of block sequences
-        Inconsistently indented YAML
-        Indenting using `typ="safe"`
-      Positioning ':' in top level mappings, prefixing ':'
-        Document version support
-        Round trip including comments
-    Config file formats
-    Extending
-    Smartening
-
-    Examples
-      Output of `dump()` as a string
-
-    Departure from previous API
-      Loading
-        Duplicate keys
-      Dumping a multi-document YAML stream
-      Dumping
-        Controls
-      Transparent usage of new and old API
-      Reason for API change
-
-    Differences with PyYAML
-      Defaulting to YAML 1.2 support
-      PY2/PY3 reintegration
-      Fixes
-      Testing
-      API
-
-    Contributing
-      Documentation
-      Code
-        Flake
-        Tox/pytest
-        Typing/mypy
-      Generated files
-      Vulnerabilities
-
- - - -[![image](https://readthedocs.org/projects/yaml/badge/?version=latest)](https://yaml.readthedocs.org/en/latest?badge=latest)[![image](https://bestpractices.coreinfrastructure.org/projects/1128/badge)](https://bestpractices.coreinfrastructure.org/projects/1128) -[![image](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/_doc/_static/license.svg?format=raw)](https://opensource.org/licenses/MIT) -[![image](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/_doc/_static/pypi.svg?format=raw)](https://pypi.org/project/ruamel.yaml/) -[![image](https://sourceforge.net/p/oitnb/code/ci/default/tree/_doc/_static/oitnb.svg?format=raw)](https://pypi.org/project/oitnb/) -[![image](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) - -# ChangeLog + + + + + + + +NEXT:
+- implemented changes to the setup.py for Python 3.14 as suggested by [Miro Hrončok](https://sourceforge.net/u/hroncok/profile/) in merge requests (MR not merged as those files are copied in from `develop` config) + +0.18.9 (2025-01-05): + +- fix issue with roundtripping 0 in YAML 1.1 reported by [Peter Law](https://sourceforge.net/u/peterjclaw/profile/) + +0.18.8 (2025-01-02): + +- added warning to README.md that PyPI might block updates due to breaking changes + +0.18.7 (2024-12-30): + +- fixes for README (reported by [Kees Bakker](https://sourceforge.net/u/keesb/profile/)) +- fixes preserving anchor on scalar integer `0` (issue reported by (Mor Peled)[https://sourceforge.net/u/morp/profile/] and also in a question by [Ravi](https://stackoverflow.com/users/6550398/ravi) on [Stackoverflow](https://stackoverflow.com/a/79306830/1307905)) +- fix for formatting of README suggested by [Michael R. Crusoe](https://sourceforge.net/u/crusoe/profile/) 0.18.6 (2024-02-07): diff --git a/__init__.py b/__init__.py index cf9a01d..892c79b 100644 --- a/__init__.py +++ b/__init__.py @@ -6,9 +6,9 @@ _package_data = dict( full_package_name='ruamel.yaml', - version_info=(0, 18, 6), - __version__='0.18.6', - version_timestamp='2024-02-07 07:43:33', + version_info=(0, 18, 10), + __version__='0.18.10', + version_timestamp='2025-01-06 15:02:34', author='Anthon van der Neut', author_email='a.van.der.neut@ruamel.eu', description='ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order', # NOQA @@ -20,21 +20,14 @@ 'docs': ['ryd', 'mercurial>5.7'], }, classifiers=[ - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: Implementation :: CPython', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Text Processing :: Markup', 'Typing :: Typed', ], keywords='yaml 1.2 parser round-trip preserve quotes order config', - read_the_docs='yaml', - supported=[(3, 7)], # minimum + url_doc='https://yaml.dev/doc/{full_package_name}', + supported=[(3, 8)], # minimum tox=dict( env='*', fl8excl='_test/lib,branch_default', diff --git a/_doc/README.ryd b/_doc/README.ryd index f728607..2b5e976 100644 --- a/_doc/README.ryd +++ b/_doc/README.ryd @@ -1,5 +1,5 @@ version: 0.2 -text: md +text: smd pdf: false order: - overview.ryd @@ -46,9 +46,41 @@ mkdocs: --- !table version: !Env version updated: !Env date -documentation: https://yaml.readthedocs.io +documentation: https://yaml.dev/doc/ruamel.yaml repository: https://sourceforge.net/projects/ruamel-yaml pypi: https://pypi.org/project/ruamel.yaml +--- !python-hidden | + +import os +from textwrap import dedent + +if os.environ.get('GEN_README_MD'): + print(dedent("""\ + ## breaking changes, that may make future uploads to PyPI impossible + + *If you are interested in future upgrades of `ruamel.yaml` + please check the [documentation on installing](https://yaml.dev/doc/ruamel.yaml/install/), + since at some point I might not be able to upload a new version to PyPI with updated information.* + + `ruamel.yaml` was intentionally named as `yaml` in a namespace `ruamel`. The namespace allows the installation + name to correspond unchanged to how the package is imported, reduces the number of links I have to create + in site-packages of a Python install during development, as well as providing a recognisable set of packages + my company releases to the public. + + However, after uploading version 0.18.7, I got an email from PyPI, about having to change the project name + to `ruamel_yaml` to comply with PEP 625, sometime in the future. The email doesn't say if namespace packages are + no longer allowed, or how to deal with the very real clash with the pre-existing package `ruamel_yaml`. + + I might not be able to adapt `ruamel.yaml`, in + a way that does not negatively affect the 0.5 million daily downloads (and my own usage of the package) in time. + My experience with other such service downgrades (Bitbucket, Readthedocs), has not been entirely positive. + + ----- + + """)) + +--- !stdout-raw | + --- | As announced, in 0.18.0, the old PyYAML functions have been deprecated. @@ -56,7 +88,7 @@ As announced, in 0.18.0, the old PyYAML functions have been deprecated. (`_all`, `safe_`, `round_trip_`, etc)). If you only read this after your program has stopped working: I am sorry to hear that, but that also means you, or the person developing your program, has not tested with warnings on (which is the recommendation -in PEP 565, and e.g. defaultin when using `pytest`). If you have troubles, explicitly use +in PEP 565, and e.g. defaulting when using `pytest`). If you have troubles, explicitly use ``` pip install "ruamel.yaml<0.18.0" ``` @@ -74,15 +106,16 @@ but I do consider adding a `ruamel.yaml.unsafe` package that will re-add the `ty There seems to be a CVE on `ruamel.yaml`, stating that the `load()` function could be abused because of unchecked input. `load()` was never the default function (that was `round_trip_load()` -before the new API came into existence`. So the creator of that CVE was ill informed and +before the new API came into existence. So the creator of that CVE was ill informed and probably lazily assumed that since `ruamel.yaml` is a derivative of PyYAML (for which a similar CVE exists), the same problem would still exist, without checking. -So the CVE was always inappriate, now just more so, as the call +So the CVE was always inappropriate, now just more so, as the call to the function `load()` with any input will terminate your program with an error message. If you (have to) care about such things as this CVE, my recommendation is to stop using Python completely, as `pickle.load()` can be abused in the same way as `load()` (and like unlike `load()` is only documented to be unsafe, without development-time warning. +Version 0.18.9 was the last one tested to be working with Python 3.7 Version 0.17.21 was the last one tested to be working on Python 3.5 and 3.6
The 0.16.13 release was the last that was tested to be working on Python 2.7. @@ -97,16 +130,38 @@ email, preferably with some information on how you use the package (or a link to the repository) and I'll keep you informed when the status of the API is stable enough to make the transition. ---- !toc -level: 3 -# prefix: http://yaml.readthedocs.io/en/latest/ +--- !comment | +# # ToDo 2024-12 +# --- !toc +# level: 3 +# # prefix: http://yaml.readthedocs.io/en/latest/ --- | -[![image](https://readthedocs.org/projects/yaml/badge/?version=latest)](https://yaml.readthedocs.org/en/latest?badge=latest)[![image](https://bestpractices.coreinfrastructure.org/projects/1128/badge)](https://bestpractices.coreinfrastructure.org/projects/1128) -[![image](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/_doc/_static/license.svg?format=raw)](https://opensource.org/licenses/MIT) -[![image](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/_doc/_static/pypi.svg?format=raw)](https://pypi.org/project/ruamel.yaml/) -[![image](https://sourceforge.net/p/oitnb/code/ci/default/tree/_doc/_static/oitnb.svg?format=raw)](https://pypi.org/project/oitnb/) -[![image](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) +```=html + + + + + + +``` + + +--- !comment | +[]($image.url('https://sourceforge.net/p/oitnb/code/ci/default/tree/_doc/_static/oitnb.svg?format=raw')) + +[bla]($link.url("https://pypi.org/project/oitnb/")) + +[[]($image.url('https://sourceforge.net/p/oitnb/code/ci/default/tree/_doc/_static/oitnb.svg?format=raw'))]($link.url("https://pypi.org/project/oitnb/")) +[($image.url('https://sourceforge.net/p/oitnb/code/ci/default/tree/_doc/_static/oitnb.svg?format=raw').linked(true))] +[($image.url('https://sourceforge.net/p/oitnb/code/ci/default/tree/_doc/_static/oitnb.svg?format=raw'))](https://pypi.org/project/oitnb/) +# [![image](https://readthedocs.org/projects/yaml/badge/?version=latest)](https://yaml.readthedocs.org/en/latest?badge=latest) +# [![image](https://bestpractices.coreinfrastructure.org/projects/1128/badge)](https://bestpractices.coreinfrastructure.org/projects/1128) +# [![image](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/_doc/_static/license.svg?format=raw)](https://opensource.org/licenses/MIT) +# [![image](https://sourceforge.net/p/ruamel-yaml/code/ci/default/tree/_doc/_static/pypi.svg?format=raw)](https://pypi.org/project/ruamel.yaml/) +# [![image](https://sourceforge.net/p/oitnb/code/ci/default/tree/_doc/_static/oitnb.svg?format=raw)](https://pypi.org/project/oitnb/) +# [![image](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/) +# [![image](https://img.shields.io/pepy/dt/ruamel.yaml.svg)](https://www.pepy.tech/projects/ruamel.yaml) # ChangeLog diff --git a/_doc/_static/pypi.svg b/_doc/_static/pypi.svg index 28c535d..f46c13a 100644 --- a/_doc/_static/pypi.svg +++ b/_doc/_static/pypi.svg @@ -1 +1 @@ - pypipypi0.18.60.18.6 + pypipypi0.18.100.18.10 diff --git a/_doc/api.ryd b/_doc/api.ryd index c0e1a7d..8d30a6c 100644 --- a/_doc/api.ryd +++ b/_doc/api.ryd @@ -1,5 +1,5 @@ version: 0.2 -text: md +text: smd pdf: false --- !python-pre | import sys diff --git a/_doc/basicuse.ryd b/_doc/basicuse.ryd index cce50d8..040e309 100644 --- a/_doc/basicuse.ryd +++ b/_doc/basicuse.ryd @@ -1,6 +1,8 @@ version: 0.2 -text: md +text: smd pdf: false +frontmatter: + title: Basic Usage --- !python-pre | import sys from io import StringIO @@ -11,7 +13,7 @@ doc = "a: 1" data = dict(a=1) --- | # Basic Usage -## Load and dump +## Load and dump You load a YAML document using: --- !python | @@ -21,8 +23,8 @@ yaml=YAML(typ='safe') # default, if not specfied, is 'rt' (round-trip) yaml.load(doc) --- | -in this `doc` can be a file pointer (i.e. an object that has the -`.read()` method, a string or a `pathlib.Path()`. `typ='safe'` +in this, `doc` can be a file pointer (i.e. an object that has the +`.read()` method, a string, or a `pathlib.Path()` instance. `typ='safe'` accomplishes the same as what `safe_load()` did before: loading of a document without resolving unknown tags. Provide `pure=True` to enforce using the pure Python implementation, otherwise the faster C libraries @@ -30,7 +32,7 @@ will be used when possible/available but these behave slightly different (and sometimes more like a YAML 1.1 loader). Dumping works in the same way: ---- !code | +--- !python-code | from ruamel.yaml import YAML yaml=YAML() diff --git a/_doc/contributing.ryd b/_doc/contributing.ryd index 24e351b..37d674a 100644 --- a/_doc/contributing.ryd +++ b/_doc/contributing.ryd @@ -1,5 +1,5 @@ version: 0.2 -text: md +text: smd pdf: false --- | # Contributing diff --git a/_doc/detail.ryd b/_doc/detail.ryd index 26ce7f0..296228e 100644 --- a/_doc/detail.ryd +++ b/_doc/detail.ryd @@ -1,5 +1,5 @@ version: 0.2 -text: md +text: smd pdf: false --- | # Details @@ -32,27 +32,33 @@ pdf: false - preservation of whitelines after block scalars. Contributed by Sam Thursfield. -*In the following examples it is assumed you have done something like:*: +*In the following examples it is assumed you have done something like:* - from ruamel.yaml import YAML - yaml = YAML() +```python +from ruamel.yaml import YAML +yaml = YAML() +``` *if not explicitly specified.* ## Indentation of block sequences Although ruamel.yaml doesn\'t preserve individual indentations of block -sequence items, it does properly dump: +sequence items, it does dump: - x: - - b: 1 - - 2 +```yaml +x: +- b: 1 +- 2 +``` back to: - x: - - b: 1 - - 2 +```yaml +x: +- b: 1 +- 2 +``` if you specify `yaml.indent(sequence=4)` (indentation is counted to the beginning of the sequence element). @@ -60,9 +66,11 @@ beginning of the sequence element). PyYAML (and older versions of ruamel.yaml) gives you non-indented scalars (when specifying default_flow_style=False): - x: - - b: 1 - - 2 +```yaml +x: +- b: 1 +- 2 +``` You can use `mapping=4` to also have the mappings values indented. The dump also observes an additional `offset=2` setting that can be used to @@ -71,10 +79,12 @@ push the dash inwards, *within the space defined by* `sequence`. The above example with the often seen `yaml.indent(mapping=2, sequence=4, offset=2)` indentation: - x: - y: - - b: 1 - - 2 +```yaml +x: + y: + - b: 1 + - 2 +``` The defaults are as if you specified `yaml.indent(mapping=2, sequence=2, offset=0)`. @@ -99,16 +109,20 @@ Here are some inconsistently indented YAML examples. `b` indented 3, `c` indented 4 positions: - a: - b: - c: 1 +```yaml +a: + b: + c: 1 +``` Top level sequence is indented 2 without offset, the other sequence 4 (with offset 2): - - key: - - foo - - bar +```yaml +- key: + - foo + - bar +``` ### Indenting using `typ="safe"` @@ -121,9 +135,11 @@ of the dumper if you want to have that sort of control. If you want your toplevel mappings to look like: - library version: 1 - comment : | - this is just a first try +```yaml +library version: 1 +comment : | + this is just a first try +``` then set `yaml.top_level_colon_align = True` (and `yaml.indent = 4`). `True` causes calculation based on the longest key, but you can also @@ -132,9 +148,11 @@ explicitly set a number. If you want an extra space between a mapping key and the colon specify `yaml.prefix_colon = ' '`: - - https://myurl/abc.tar.xz : 23445 - # ^ extra space here - - https://myurl/def.tar.xz : 944 +```yaml +- https://myurl/abc.tar.xz : 23445 +# extra space here --^ +- https://myurl/def.tar.xz : 944 +``` If you combine `prefix_colon` with `top_level_colon_align`, the top level mapping doesn\'t get the extra prefix. If you want that anyway, @@ -157,8 +175,8 @@ The 1.2 version does **not** support: - sexagesimals like `12:34:56` - octals that start with 0 only: like `012` for number 10 (`0o12` **is** supported by YAML 1.2) -- Unquoted Yes and On as alternatives for True and No and Off for - False. +- Unquoted `Yes` and `On` as alternatives for `True`, resp. `No` and `Off` for + `False`. If you cannot change your YAML files and you need them to load as 1.1 you can load with `yaml.version = (1, 1)`, or the equivalent (version @@ -209,8 +227,8 @@ for for this is: data['xyz'].yaml_add_eol_comment('comment 7\n\n# that\'s all folks', 'd', column=20) yaml.dump(data, sys.stdout) ---- !stdout | -Resulting in:: +--- !stdout-yaml | +Resulting in: --- !comment | abc: - a # comment 1 @@ -234,7 +252,7 @@ Make sure that the added comment is correct, in the sense that when it contains newlines, the following is either an empty line or a line with only spaces, or the first non-space is a `#`. -# Config file formats +## Config file formats There are only a few configuration file formats that are easily readable and editable: JSON, INI/ConfigParser, YAML (XML is to cluttered to be @@ -262,7 +280,7 @@ comments, it makes YAML a very good choice for configuration files that are human readable and editable while at the same time interpretable and modifiable by a program. -# Extending +## Extending There are normally six files involved when extending the roundtrip capabilities: the reader, parser, composer and constructor to go from @@ -275,24 +293,25 @@ alternative), that should behave like the original, but on the way from Python to YAML generates the original (or at least something much closer). -# Smartening +## Smartening When you use round-tripping, then the complex data you get are already subclasses of the built-in types. So you can patch in extra methods or override existing ones. Some methods are already included and you can do: - yaml_str = """\ - a: - - b: - c: 42 - - d: - f: 196 - e: - g: 3.14 - """ - - - data = yaml.load(yaml_str) - - assert data.mlget(['a', 1, 'd', 'f'], list_ok=True) == 196 +```python +yaml_str = """\ +a: +- b: + c: 42 +- d: + f: 196 + e: + g: 3.14 +""" + +data = yaml.load(yaml_str) + +assert data.mlget(['a', 1, 'd', 'f'], list_ok=True) == 196 +``` diff --git a/_doc/dumpcls.ryd b/_doc/dumpcls.ryd index 048cdeb..e0f74b2 100644 --- a/_doc/dumpcls.ryd +++ b/_doc/dumpcls.ryd @@ -1,5 +1,5 @@ version: 0.2 -text: md +text: smd pdf: false # code_directory: ../_example --- | @@ -32,8 +32,8 @@ class User: yaml = ruamel.yaml.YAML() yaml.register_class(User) yaml.dump([User('Anthon', 18)], sys.stdout) ---- !stdout | -which gives as output:: +--- !stdout-yaml | +which gives as output: --- | The tag `!User` originates from the name of the class. @@ -65,8 +65,8 @@ class User: yaml = ruamel.yaml.YAML() yaml.register_class(User) yaml.dump([User('Anthon', 18)], sys.stdout) ---- !stdout | -which gives as output:: +--- !stdout-yaml | +which gives as output: --- | When using the decorator, which takes the `YAML()` instance as a @@ -130,7 +130,7 @@ class User: yaml.dump([User('Anthon', 18)], sys.stdout) ---- !stdout | +--- !stdout-yaml | This also gives: @@ -170,7 +170,7 @@ path = Path('/tmp/arya.yaml') yaml.dump(arya, path) print(path.read_text()) ---- !stdout | +--- !stdout-yaml | dumping as: @@ -203,7 +203,7 @@ print(data) giving: --- | -But if you provide a (to) simple loader: +But if you provide a (too) simple loader: --- !python | @@ -238,7 +238,7 @@ giving: --- | As you can see, Sansa has no normal siblings after this load. -What you need to do is yield the empty Person instance and fill it in +What you need to do is yield the empty `Person` instance, and fill it in afterwards: --- !python | diff --git a/_doc/example.ryd b/_doc/example.ryd index 4b431cd..231410e 100644 --- a/_doc/example.ryd +++ b/_doc/example.ryd @@ -1,5 +1,5 @@ version: 0.2 -text: md +text: smd pdf: false --- | # Examples @@ -24,8 +24,8 @@ generating YAML: yaml.dump(code, sys.stdout) ---- !stdout | -Resulting in:: +--- !stdout-yaml | +Resulting in: --- | ------------------------------------------------------------------------ @@ -81,8 +81,8 @@ position, while optionally adding a comment: data.insert(1, 'last name', 'Vandelay', comment="new key") yaml.dump(data, sys.stdout) ---- !stdout | -gives:: +--- !stdout-yaml | +gives: --- | Please note that the comment is aligned with that of its neighbour (if available). @@ -107,16 +107,16 @@ from ruamel.yaml import YAML d = dict(a=dict(b=2),c=[3, 4]) yaml = YAML() yaml.dump(d, sys.stdout) -print('0123456789') +print('#123456789') yaml = YAML() yaml.indent(mapping=4, sequence=6, offset=3) yaml.dump(d, sys.stdout) -print('0123456789') +print('#123456789') ---- !stdout | +--- !stdout-yaml | -giving:: +giving: --- | @@ -142,9 +142,9 @@ yaml.compact(seq_seq=False, seq_map=False) yaml.dump(d, sys.stdout) ---- !stdout | +--- !stdout-yaml | -giving:: +giving: --- | @@ -191,8 +191,8 @@ yaml = YAML() yaml.explicit_start = True yaml.dump(data, sys.stdout, transform=sequence_indent_four) ---- !stdout | -gives as output:: +--- !stdout-yaml | +gives as output: --- | The transform example, in the last document, was inspired by a [question @@ -246,10 +246,10 @@ yaml = MyYAML() # or typ='safe'/'unsafe' etc --- | with about one tenth of the lines needed for the old interface, you can once more do: ---- !code | +--- !python-code | print(yaml.dump(dict(a=1, b=2))) --- | instead of: ---- !code | +--- !python-code | yaml.dump((dict(a=1, b=2)), sys.stdout) print() # or sys.stdout.write('\n') diff --git a/_doc/install.ryd b/_doc/install.ryd index 9edfc70..3f2f8cd 100644 --- a/_doc/install.ryd +++ b/_doc/install.ryd @@ -1,5 +1,5 @@ version: 0.2 -text: md +text: smd pdf: false --- | # Installing @@ -14,7 +14,7 @@ probably best to do: in your environment (`virtualenv`, (Docker) container, etc) before installing `ruamel.yaml`. -`ruamel.yaml` itself should be installed from [PyPI]() using: +`ruamel.yaml` itself should be installed from [PyPI] using: pip install ruamel.yaml diff --git a/_doc/links.rydinc b/_doc/links.rydinc index 7e840c7..51eb362 100644 --- a/_doc/links.rydinc +++ b/_doc/links.rydinc @@ -1,7 +1,7 @@ -.. _tox: https://pypi.python.org/pypi/tox -.. _py.test: http://pytest.org/latest/ -.. _YAML 1.1: http://www.yaml.org/spec/1.1/spec.html -.. _YAML 1.2: http://www.yaml.org/spec/1.2/spec.html -.. _PyPI: https://pypi.python.org/pypi -.. _ruamel.yaml: https://pypi.python.org/pypi/ruamel.yaml +[tox]: https://pypi.python.org/pypi/tox +[py.test]: http://pytest.org/latest/ +[YAML 1.1]: http://www.yaml.org/spec/1.1/spec.html +[YAML 1.2]: http://www.yaml.org/spec/1.2/spec.html +[PyPI]: https://pypi.python.org/pypi +[ruamel.yaml]: https://pypi.python.org/pypi/ruamel.yaml diff --git a/_doc/overview.ryd b/_doc/overview.ryd index b10dc78..97777c9 100644 --- a/_doc/overview.ryd +++ b/_doc/overview.ryd @@ -1,5 +1,5 @@ version: 0.2 -text: md +text: smd pdf: false --- | # Overview @@ -8,7 +8,7 @@ pdf: false derivative of Kirill Simonov\'s [PyYAML 3.11](https://bitbucket.org/xi/pyyaml). -`ruamel.yaml` supports [YAML 1.2]() and has round-trip loaders and +`ruamel.yaml` supports [YAML 1.2] and has round-trip loaders and dumpers. A round-trip is a YAML load-modify-save sequence and ruamel.yaml tries to preserve, among others: @@ -45,3 +45,9 @@ Many of the bugs filed against PyYAML, but that were never acted upon, have been fixed in `ruamel.yaml` --- !inc-raw | links.rydinc + +--- | + +---------- + +This documentation was generate using [ryd](https://pypi.org/project/ryd/) and [zine](https://zine-ssg.io/). diff --git a/_doc/pyyaml.ryd b/_doc/pyyaml.ryd index f670237..730f8bc 100644 --- a/_doc/pyyaml.ryd +++ b/_doc/pyyaml.ryd @@ -1,15 +1,15 @@ version: 0.2 -text: md +text: smd pdf: false --- | # Differences with PyYAML -::: parsed-literal -*If I have seen further, it is by standing on the shoulders of giants*. +``` + If I have seen further, it is by standing on the shoulders of giants. -: Isaac Newton (1676) -::: + Isaac Newton (1676) +``` `ruamel.yaml` is a derivative of Kirill Simonov\'s [PyYAML 3.11](https://bitbucket.org/xi/pyyaml) and would not exist without that @@ -19,8 +19,8 @@ The following a summary of the major differences with PyYAML 3.11 ## Defaulting to YAML 1.2 support -PyYAML supports the [YAML 1.1]() standard, `ruamel.yaml` supports [YAML -1.2]() as released in 2009. +PyYAML supports the [YAML 1.1] standard, `ruamel.yaml` supports [YAML +1.2] as released in 2009. - YAML 1.2 dropped support for several features unquoted `Yes`, `No`, `On`, `Off` @@ -34,7 +34,7 @@ PyYAML supports the [YAML 1.1]() standard, `ruamel.yaml` supports [YAML - `\/` escape for JSON compatibility - correct parsing of floating point scalars with exponentials -unless the YAML document is loaded with an explicit `version==1.1` or +*unless* the YAML document is loaded with an explicit `version==1.1` or the document starts with: % YAML 1.1 @@ -57,7 +57,7 @@ miniscule part of the code is Python version specific. ## Testing -`ruamel.yaml` is tested using [tox]() and [py.test](). In addition to +`ruamel.yaml` is tested using [tox] and [py.test]. In addition to new tests, the original PyYAML test framework is called from within `tox` runs. diff --git a/compat.py b/compat.py index 46d0c3b..c049552 100644 --- a/compat.py +++ b/compat.py @@ -116,10 +116,10 @@ def __init__(self, file_name: Any = None) -> None: self._file_name = file_name def __call__(self, *args: Any, **kw: Any) -> None: - import traceback - if not bool(_debug): return + import traceback + out = sys.stdout if self._file_name is None else open(self._file_name, 'a') dbgprint = print # to fool checking for print statements by dv utility kw1 = kw.copy() diff --git a/composer.py b/composer.py index ca4031a..69f0d8e 100644 --- a/composer.py +++ b/composer.py @@ -87,6 +87,7 @@ def get_single_node(self) -> Any: return document def compose_document(self: Any) -> Any: + self.anchors = {} # Drop the DOCUMENT-START event. self.parser.get_event() @@ -96,7 +97,6 @@ def compose_document(self: Any) -> Any: # Drop the DOCUMENT-END event. self.parser.get_event() - self.anchors = {} return node def return_alias(self, a: Any) -> Any: diff --git a/constructor.py b/constructor.py index a25ef20..450c780 100644 --- a/constructor.py +++ b/constructor.py @@ -1019,13 +1019,11 @@ def construct_yaml_int(self, node: Any) -> Any: underscore = None value_s = value_su.replace('_', "") sign = +1 - if value_s[0] == '-': - sign = -1 if value_s[0] in '+-': + if value_s[0] == '-': + sign = -1 value_s = value_s[1:] - if value_s == '0': - return 0 - elif value_s.startswith('0b'): + if value_s.startswith('0b'): if self.resolver.processing_version > (1, 1) and value_s[2] == '0': width = len(value_s[2:]) if underscore is not None: @@ -1069,7 +1067,11 @@ def construct_yaml_int(self, node: Any) -> Any: underscore=underscore, anchor=node.anchor, ) - elif self.resolver.processing_version != (1, 2) and value_s[0] == '0': + elif ( + self.resolver.processing_version != (1, 2) + and len(value_s) > 1 + and value_s[0] == '0' + ): return OctalInt( sign * int(value_s, 8), width=width, underscore=underscore, anchor=node.anchor, ) @@ -1087,7 +1089,12 @@ def construct_yaml_int(self, node: Any) -> Any: if underscore is not None: # cannot have a leading underscore underscore[2] = len(value_su) > 1 and value_su[-1] == '_' - return ScalarInt(sign * int(value_s), width=len(value_s), underscore=underscore) + return ScalarInt( + sign * int(value_s), + width=len(value_s), + underscore=underscore, + anchor=node.anchor, + ) elif underscore: # cannot have a leading underscore underscore[2] = len(value_su) > 1 and value_su[-1] == '_' @@ -1223,8 +1230,7 @@ def construct_rt_sequence(self, node: Any, seqtyp: Any, deep: bool = False) -> A def flatten_mapping(self, node: Any) -> Any: """ This implements the merge key feature http://yaml.org/type/merge.html - by inserting keys from the merge dict/list of dicts if not yet - available in this node + by referencing the merge dict/list of dicts """ def constructed(value_node: Any) -> Any: diff --git a/setup.py b/setup.py index 3154575..05cb68a 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ # # header # coding: utf-8 -# dd: 20230418 +# dd: 20241207 # # __init__.py parser @@ -11,20 +11,13 @@ sys.path = [path for path in sys.path if path not in [os.getcwd(), ""]] import platform # NOQA -from _ast import * # NOQA +import _ast as Ast # NOQA from ast import parse # NOQA from setuptools import setup, Extension, Distribution # NOQA from setuptools.command import install_lib # NOQA from setuptools.command.sdist import sdist as _sdist # NOQA -# try: -# from setuptools.namespaces import Installer as NameSpaceInstaller # NOQA -# except ImportError: -# msg = ('You should use the latest setuptools. The namespaces.py file that this setup.py' -# ' uses was added in setuptools 28.7.0 (Oct 2016)') -# print(msg) -# sys.exit() if __name__ != '__main__': raise NotImplementedError('should never include setup.py') @@ -33,39 +26,13 @@ full_package_name = None -if sys.version_info < (3,): - string_type = basestring -else: - string_type = str - - -if sys.version_info < (3, 4): - - class Bytes: - pass - - class NameConstant: - pass - - -if sys.version_info < (3,): - open_kw = {} -else: - open_kw = dict(encoding='utf-8') # NOQA: C408 - - -if sys.version_info < (2, 7) or platform.python_implementation() == 'Jython': - - class Set: - pass - +open_kw = dict(encoding='utf-8') # NOQA: C408 if os.environ.get('DVDEBUG', "") == "": def debug(*args, **kw): pass - else: def debug(*args, **kw): @@ -75,8 +42,12 @@ def debug(*args, **kw): print('{:%Y-%d-%mT%H:%M:%S}'.format(datetime.datetime.now()), file=fp, end=' ') print(*args, **kw1) -if sys.version_info >= (3, 8): - from ast import Str, Num, Bytes, NameConstant # NOQA + +# # default data + +_setup_data = dict( + supported=[(3, 9)], # minimum non-EOL python +) def literal_eval(node_or_string): @@ -89,59 +60,47 @@ def literal_eval(node_or_string): Even when passing in Unicode, the resulting Str types parsed are 'str' in Python 2. I don't now how to set 'unicode_literals' on parse -> Str is explicitly converted. """ - _safe_names = {'None': None, 'True': True, 'False': False} - if isinstance(node_or_string, string_type): + if isinstance(node_or_string, str): node_or_string = parse(node_or_string, mode='eval') - if isinstance(node_or_string, Expression): + if isinstance(node_or_string, Ast.Expression): node_or_string = node_or_string.body else: raise TypeError('only string or AST nodes supported') def _convert(node): - if isinstance(node, Str): - if sys.version_info < (3,) and not isinstance(node.s, unicode): - return node.s.decode('utf-8') - return node.s - elif isinstance(node, Bytes): - return node.s - elif isinstance(node, Num): - return node.n - elif isinstance(node, Tuple): + if isinstance(node, Ast.Constant): + return node.value + elif isinstance(node, Ast.Tuple): return tuple(map(_convert, node.elts)) - elif isinstance(node, List): + elif isinstance(node, Ast.List): return list(map(_convert, node.elts)) - elif isinstance(node, Set): + elif isinstance(node, Ast.Set): return set(map(_convert, node.elts)) - elif isinstance(node, Dict): + elif isinstance(node, Ast.Dict): return {_convert(k): _convert(v) for k, v in zip(node.keys, node.values)} - elif isinstance(node, NameConstant): - return node.value - elif sys.version_info < (3, 4) and isinstance(node, Name): - if node.id in _safe_names: - return _safe_names[node.id] elif ( - isinstance(node, UnaryOp) - and isinstance(node.op, (UAdd, USub)) - and isinstance(node.operand, (Num, UnaryOp, BinOp)) + isinstance(node, Ast.UnaryOp) + and isinstance(node.op, (Ast.UAdd, Ast.USub)) + and isinstance(node.operand, (Ast.Num, Ast.UnaryOp, Ast.BinOp)) ): # NOQA operand = _convert(node.operand) - if isinstance(node.op, UAdd): + if isinstance(node.op, Ast.UAdd): return +operand else: return -operand elif ( - isinstance(node, BinOp) - and isinstance(node.op, (Add, Sub)) - and isinstance(node.right, (Num, UnaryOp, BinOp)) - and isinstance(node.left, (Num, UnaryOp, BinOp)) + isinstance(node, Ast.BinOp) + and isinstance(node.op, (Ast.Add, Ast.Sub)) + and isinstance(node.right, (Ast.Num, Ast.UnaryOp, Ast.BinOp)) + and isinstance(node.left, (Ast.Num, Ast.UnaryOp, Ast.BinOp)) ): # NOQA left = _convert(node.left) right = _convert(node.right) - if isinstance(node.op, Add): + if isinstance(node.op, Ast.Add): return left + right else: return left - right - elif isinstance(node, Call): + elif isinstance(node, Ast.Call): func_id = getattr(node.func, 'id', None) if func_id == 'dict': return {k.arg: _convert(k.value) for k in node.keywords} @@ -169,8 +128,6 @@ def _package_data(fn): parsing = False lines = [] for line in fp.readlines(): - if sys.version_info < (3,): - line = line.decode('utf-8') if line.startswith('_package_data'): if 'dict(' in line: parsing = 'python' @@ -278,7 +235,7 @@ def initialize_options(self): _sdist.initialize_options(self) # failed expiriment, see pep 527, new uploads should be tar.gz or .zip # because of unicode_literals - # self.formats = fmt if fmt else [b'bztar'] if sys.version_info < (3, ) else ['bztar'] + # self.formats = fmt if fmt else ['bztar'] dist_base = os.environ.get('PYDISTBASE') fpn = getattr(getattr(self, 'nsp', self), 'full_package_name', None) if fpn and dist_base: @@ -310,8 +267,9 @@ class NameSpacePackager(object): def __init__(self, pkg_data): assert isinstance(pkg_data, dict) self._pkg_data = pkg_data - self.full_package_name = self.pn(self._pkg_data['full_package_name']) + self.full_package_name = self._pkg_data['full_package_name'] self._split = None + self._extra_packages = [] self.depth = self.full_package_name.count('.') self.nested = self._pkg_data.get('nested', False) # if self.nested: @@ -343,17 +301,12 @@ def __init__(self, pkg_data): self.command = x break - def pn(self, s): - if sys.version_info < (3,) and isinstance(s, unicode): - return s.encode('utf-8') - return s - @property def split(self): """split the full package name in list of compontents traditionally done by setuptools.find_packages. This routine skips any directories - with __init__.py, for which the name starts with "_" or ".", or contain a - setup.py/tox.ini (indicating a subpackage) + with __init__.py, for which the name starts with "_" or ".", or the + __init__.py contains package data (indicating a subpackage) """ skip = [] if self._split is None: @@ -372,11 +325,9 @@ def split(self): if pd.get('nested', False): skip.append(d) continue - self._split.append(self.full_package_name + '.' + d) - if sys.version_info < (3,): - self._split = [ - (y.encode('utf-8') if isinstance(y, unicode) else y) for y in self._split - ] + ep = self.full_package_name + '.' + d + self._split.append(ep) + self._extra_packages.append(ep) if skip: # this interferes with output checking # print('skipping sub-packages:', ', '.join(skip)) @@ -516,16 +467,6 @@ def pckg_entry_point(name): ], } - @property - def url(self): - url = self._pkg_data.get('url') - if url: - return url - sp = self.full_package_name - for ch in '_.': - sp = sp.replace(ch, '-') - return 'https://sourceforge.net/p/{0}/code/ci/default/tree'.format(sp) - @property def project_urls(self): ret_val = {} @@ -539,9 +480,10 @@ def project_urls(self): if 'sourceforge.net' in base_url: ret_val['Source'] = base_url + 'code/ci/default/tree/' ret_val['Tracker'] = base_url + 'tickets/' - rtfd = self._pkg_data.get('read_the_docs') - if rtfd: - ret_val['Documentation'] = 'https://{0}.readthedocs.io/'.format(rtfd) + assert self._pkg_data.get('read_the_docs') is None, "update pon data read_the_docs -> url_doc='https://domain/path/{pkgname}/'" + url_doc = self._pkg_data.get('url_doc') + if url_doc: + ret_val['Documentation'] = url_doc.format(full_package_name=sp) return ret_val @property @@ -585,7 +527,7 @@ def status(self): def classifiers(self): """this needs more intelligence, probably splitting the classifiers from _pkg_data and only adding defaults when no explicit entries were provided. - Add explicit Python versions in sync with tox.env generation based on python_requires? + Add explicit Python versions in sync with tox.env generation based on python_requires? See comment develop """ attr = '_' + sys._getframe().f_code.co_name if not hasattr(self, attr): @@ -593,24 +535,53 @@ def classifiers(self): return getattr(self, attr) def _setup_classifiers(self): - return sorted( - set( - [ - 'Development Status :: {0} - {1}'.format(*self.status), - 'Intended Audience :: Developers', - 'License :: ' - + ('OSI Approved :: MIT' if self.has_mit_lic() else 'Other/Proprietary') - + ' License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - ] - + [self.pn(x) for x in self._pkg_data.get('classifiers', [])], - ), + c = set( + [ + ('Development Status', '{0} - {1}'.format(*self.status), ), + ('Intended Audience', 'Developers'), + ('License', 'OSI Approved', 'MIT' if self.has_mit_lic() else 'Other/Proprietary' + ' License'), + ('Operating System', 'OS Independent', ), + ('Programming Language', 'Python'), + ] ) + for cl in self._pkg_data.get('classifiers', []): + print('cltype', type(cl), repr(cl)) + if isinstance(cl, str): + c.add((cl,)) + else: + c.add(tuple(c)) + supported = self._pkg_data.get('supported', _setup_data['supported'])[0] + assert supported[0] == 3 + minor = supported[1] + while minor <= 13: + version = (supported[0], minor) + c.add(tuple(['Programming Language', 'Python',] + list(version))) + minor += 1 + ret_val = [] + for x in c: + print('x', repr(x)) + prev = str + for cl in sorted(c): + if isinstance(cl, str): + ret_val.append(cl) + continue + assert isinstance(cl, (tuple, list)) + line = "" + for elem in cl: # append the elements with appropriate separator + next = type(elem) + if line: + if prev is int and next is int: + line += '.' + else: + line += ' :: ' + line += str(elem) + prev = next + ret_val.append(line) + return ret_val @property def keywords(self): - return self.pn(self._pkg_data.get('keywords', [])) + return self._pkg_data.get('keywords', []) @property def install_requires(self): @@ -643,7 +614,7 @@ def _analyse_packages(self): return self._pkg # 'any' for all builds, 'py27' etc for specifics versions packages = ir.get('any', []) - if isinstance(packages, string_type): + if isinstance(packages, str): packages = packages.split() # assume white space separated string if self.nested: # parent dir is also a package, make sure it is installed (need its .pth file) @@ -706,24 +677,21 @@ def package_data(self): pd = self._pkg_data.get('package_data', {}) if df: pd[self.full_package_name] = df - if sys.version_info < (3,): - # python2 doesn't seem to like unicode package names as keys - # maybe only when the packages themselves are non-unicode - for k in pd: - if isinstance(k, unicode): - pd[str(k)] = pd.pop(k) - # for k in pd: - # pd[k] = [e.encode('utf-8') for e in pd[k]] # de-unicode return pd @property def packages(self): # s = self.split s = [self._pkg_data['full_package_name']] - # fixed this in package_data, the keys there must be non-unicode for py27 - # if sys.version_info < (3, 0): - # s = [x.encode('utf-8') for x in self.split] - return s + self._pkg_data.get('extra_packages', []) + return s + self.extra_packages + + @property + def extra_packages(self): + try: + return self._pkg_data['extra_packages'] + except KeyError: + _ = self.split + return self._extra_packages @property def python_requires(self): @@ -763,9 +731,9 @@ def ext_modules(self): if no_test_compile: for target in self._pkg_data.get('ext_modules', []): ext = Extension( - self.pn(target['name']), - sources=[self.pn(x) for x in target['src']], - libraries=[self.pn(x) for x in target.get('lib')], + target['name'], + sources=[x for x in target['src']], + libraries=[x for x in target.get('lib')], ) self._ext_modules.append(ext) return self._ext_modules @@ -830,7 +798,7 @@ def py_project(self): with open(file_name, 'w') as fp: fp.write(dedent("""\ [build-system] - requires = ["setuptools", "wheel"] + requires = ["setuptools"] # test build-backend = "setuptools.build_meta" """)) @@ -871,7 +839,6 @@ def main(): version=version_str, packages=nsp.packages, python_requires=nsp.python_requires, - # url=nsp.url, project_urls=nsp.project_urls, author=nsp.author, author_email=nsp.author_email, diff --git a/tox.ini b/tox.ini index 0c4a722..e51468d 100755 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] # toxworkdir = /data1/DATA/tox/ruamel.yaml -envlist = cs,py311,py310,py39,py38,py37,py312 +envlist = cs,py313,py312,py311,py310,py39,py38 [testenv] allowlist_externals = /bin/bash @@ -41,7 +41,7 @@ commands = show-source = True max-line-length = 95 ignore = W503,F405,E203,C408 -exclude = _test/lib,branch_default,.hg,.git,.tox,dist,.cache,__pycache__,ruamel.zip2tar.egg-info +exclude = _test/lib,branch_default,split,jabsy,cmd,bytes,jinja2,clib,pytypes,string,data,base,convert,.hg,.git,.tox,dist,.cache,__pycache__,ruamel.zip2tar.egg-info [pytest] filterwarnings = diff --git a/util.py b/util.py index 17cb2d6..fb74b4c 100644 --- a/util.py +++ b/util.py @@ -1,10 +1,11 @@ -from __future__ import annotations """ some helper functions that might be generally useful """ +from __future__ import annotations + import datetime from functools import partial import re