summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2019-08-08 08:21:57 +0200
committerAnthon van der Neut <anthon@mnt.org>2019-08-08 08:21:57 +0200
commit679917903a98206aa3566594c89b2ce20705b2c6 (patch)
tree35c057be6cc83ba8aa417c748a3e52a04b5b7688
parentdcf61a365571b2ace182232252db6122382e9ace (diff)
downloadruamel.yaml-679917903a98206aa3566594c89b2ce20705b2c6.tar.gz
allow '#' in tag URI, force use of new clib0.16.1
fixes issue #300 *When this change indeed resolves your problem, please **Close** this issue*. *(You can do so using the WorkFlow pull-down (close to the top right of this page))*
-rw-r--r--CHANGES7
-rw-r--r--README.rst11
-rw-r--r--__init__.py6
-rw-r--r--_doc/_static/pypi.svg2
-rw-r--r--_test/test_issues.py26
-rw-r--r--scanner.py1
-rw-r--r--setup.py149
7 files changed, 60 insertions, 142 deletions
diff --git a/CHANGES b/CHANGES
index d776e0c..e2d3e83 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+[0, 16, 1]: 2019-08-08
+ - Force the use of new version of ruamel.yaml.clib (reported by `Alex Joz
+ <https://bitbucket.org/%7B9af55900-2534-4212-976c-61339b6ffe14%7D/>`__)
+ - Allow '#' in tag URI as these are allowed in YAML 1.2 (reported by
+ `Thomas Smith
+ <https://bitbucket.org/%7Bd4c57a72-f041-4843-8217-b4d48b6ece2f%7D/>`__)
+
[0, 16, 0]: 2019-07-25
- split of C source that generates .so file to ruamel.yaml.clib
- duplicate keys are now an error when working with the old API as well
diff --git a/README.rst b/README.rst
index aa29e61..10da491 100644
--- a/README.rst
+++ b/README.rst
@@ -4,8 +4,8 @@ ruamel.yaml
``ruamel.yaml`` is a YAML 1.2 loader/dumper package for Python.
-:version: 0.16.0
-:updated: 2019-07-25
+:version: 0.16.1
+:updated: 2019-08-08
:documentation: http://yaml.readthedocs.io
:repository: https://bitbucket.org/ruamel/yaml
:pypi: https://pypi.org/project/ruamel.yaml/
@@ -54,6 +54,13 @@ ChangeLog
.. should insert NEXT: at the beginning of line for next key (with empty line)
+0.16.1 (2019-08-08):
+ - Force the use of new version of ruamel.yaml.clib (reported by `Alex Joz
+ <https://bitbucket.org/%7B9af55900-2534-4212-976c-61339b6ffe14%7D/>`__)
+ - Allow '#' in tag URI as these are allowed in YAML 1.2 (reported by
+ `Thomas Smith
+ <https://bitbucket.org/%7Bd4c57a72-f041-4843-8217-b4d48b6ece2f%7D/>`__)
+
0.16.0 (2019-07-25):
- split of C source that generates .so file to ruamel.yaml.clib
- duplicate keys are now an error when working with the old API as well
diff --git a/__init__.py b/__init__.py
index 33e1d63..995bca9 100644
--- a/__init__.py
+++ b/__init__.py
@@ -7,8 +7,8 @@ if False: # MYPY
_package_data = dict(
full_package_name='ruamel.yaml',
- version_info=(0, 16, 0),
- __version__='0.16.0',
+ version_info=(0, 16, 1),
+ __version__='0.16.1',
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
@@ -17,7 +17,7 @@ _package_data = dict(
extras_require={':platform_python_implementation=="CPython" and python_version<="2.7"': [
'ruamel.ordereddict',
], ':platform_python_implementation=="CPython" and python_version<"3.8"': [
- 'ruamel.yaml.clib',
+ 'ruamel.yaml.clib>=0.1.2',
], 'jinja2': ['ruamel.yaml.jinja2>=0.2'], 'docs': ['ryd']},
# NOQA
# test='#include "ext/yaml.h"\n\nint main(int argc, char* argv[])\n{\nyaml_parser_t parser;\nparser = parser; /* prevent warning */\nreturn 0;\n}\n', # NOQA
diff --git a/_doc/_static/pypi.svg b/_doc/_static/pypi.svg
index 025942d..aa448d9 100644
--- a/_doc/_static/pypi.svg
+++ b/_doc/_static/pypi.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="86" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#007ec6" d="M33 0h53v20H33z"/><path fill="url(#b)" d="M0 0h86v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">pypi</text><text x="175" y="140" transform="scale(.1)" textLength="230">pypi</text><text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">0.16.0</text><text x="585" y="140" transform="scale(.1)" textLength="430">0.16.0</text></g> </svg>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="86" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#007ec6" d="M33 0h53v20H33z"/><path fill="url(#b)" d="M0 0h86v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">pypi</text><text x="175" y="140" transform="scale(.1)" textLength="230">pypi</text><text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">0.16.1</text><text x="585" y="140" transform="scale(.1)" textLength="430">0.16.1</text></g> </svg>
diff --git a/_test/test_issues.py b/_test/test_issues.py
index 90128dd..3692f61 100644
--- a/_test/test_issues.py
+++ b/_test/test_issues.py
@@ -824,6 +824,32 @@ class TestIssues:
dc = copy.deepcopy(data)
assert round_trip_dump(dc) == inp
+ def test_issue_300(self):
+ from ruamel.yaml import YAML
+
+ inp = dedent("""
+ %YAML 1.2
+ %TAG ! tag:example.com,2019/path#fragment
+ ---
+ null
+ """)
+ YAML().load(inp)
+
+ def test_issue_300a(self):
+ import ruamel.yaml
+
+ inp = dedent("""
+ %YAML 1.1
+ %TAG ! tag:example.com,2019/path#fragment
+ ---
+ null
+ """)
+ yaml = YAML()
+ yaml.version = (1, 1) # This should not be necessary -> issue 301
+ with pytest.raises(ruamel.yaml.scanner.ScannerError,
+ match='while scanning a directive'):
+ yaml.load(inp)
+
# @pytest.mark.xfail(strict=True, reason='bla bla', raises=AssertionError)
# def test_issue_ xxx(self):
# inp = """
diff --git a/scanner.py b/scanner.py
index 46cd9d7..7267cea 100644
--- a/scanner.py
+++ b/scanner.py
@@ -1675,6 +1675,7 @@ class Scanner(object):
or 'A' <= ch <= 'Z'
or 'a' <= ch <= 'z'
or ch in "-;/?:@&=+$,_.!~*'()[]%"
+ or ((self.scanner_processing_version > (1, 1)) and ch == "#")
):
if ch == '%':
chunks.append(self.reader.prefix(length))
diff --git a/setup.py b/setup.py
index 644f916..7c5ccb3 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,6 @@
# # header
# coding: utf-8
+# dd: 20190807
from __future__ import print_function, absolute_import, division, unicode_literals
@@ -19,6 +20,8 @@ from setuptools import setup, Extension, Distribution # NOQA
from setuptools.command import install_lib # NOQA
from setuptools.command.sdist import sdist as _sdist # NOQA
+from setuptools.namespaces import Installer as NameSpaceInstaller # NOQA
+
if __name__ != '__main__':
raise NotImplementedError('should never include setup.py')
@@ -306,100 +309,6 @@ except ImportError:
_bdist_wheel_available = False
-class InMemoryZipFile(object):
- def __init__(self, file_name=None):
- try:
- from cStringIO import StringIO
- except ImportError:
- from io import BytesIO as StringIO
- import zipfile
-
- self.zip_file = zipfile
- # Create the in-memory file-like object
- self._file_name = file_name
- self._removed_names = []
- self.in_memory_data = StringIO()
- # Create the in-memory zipfile
- self.in_memory_zip = self.zip_file.ZipFile(
- self.in_memory_data, 'w', self.zip_file.ZIP_DEFLATED, False
- )
- self.in_memory_zip.debug = 3
-
- def append(self, filename_in_zip, file_contents):
- """Appends a file with name filename_in_zip and contents of
- file_contents to the in-memory zip.
- """
- if filename_in_zip.endswith('.dist-info/RECORD') and self._removed_names:
- # this is normally the last file
- # remove any names filtered, to placate auditwheel
- convert = not isinstance(file_contents, string_type)
- if convert:
- file_contents = file_contents.decode('utf-8')
- outlines = []
- for line in file_contents.splitlines(True):
- for fn in self._removed_names:
- fn = fn + ',' # comma is the record seperator in RECORD
- if line.startswith(fn):
- break
- else:
- outlines.append(line)
- file_contents = ''.join(outlines)
- self.in_memory_zip.writestr(filename_in_zip, file_contents)
- return self # so you can daisy-chain
-
- def write_to_file(self, filename):
- """Writes the in-memory zip to a file."""
- # Mark the files as having been created on Windows so that
- # Unix permissions are not inferred as 0000
- for zfile in self.in_memory_zip.filelist:
- zfile.create_system = 0
- self.in_memory_zip.close()
- with open(filename, 'wb') as f:
- f.write(self.in_memory_data.getvalue())
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_value, traceback):
- if self._file_name is None:
- return
- self.write_to_file(self._file_name)
-
- def delete_from_zip_file(self, pattern=None, file_names=None):
- """
- zip_file can be a string or a zipfile.ZipFile object, the latter will be closed
- any name in file_names is deleted from the list of files to write to the new zip
- (using .append)
- all file_names provided have to be in the ZIP archive or else an IOError is raised
- """
- if pattern and isinstance(pattern, string_type):
- import re
-
- pattern = re.compile(pattern)
- if file_names:
- if not isinstance(file_names, list):
- file_names = [file_names]
- else:
- file_names = []
- with self.zip_file.ZipFile(self._file_name) as zf:
- for l in zf.infolist():
- if l.filename in file_names:
- file_names.remove(l.filename)
- self._removed_names.append(l.filename)
- continue
- if pattern and pattern.match(l.filename):
- self._removed_names.append(l.filename)
- continue
- self.append(l.filename, zf.read(l))
- if file_names:
- raise IOError(
- '[Errno 2] No such file{}: {}'.format(
- "" if len(file_names) == 1 else 's',
- ', '.join([repr(f) for f in file_names]),
- )
- )
-
-
class NameSpacePackager(object):
def __init__(self, pkg_data):
assert isinstance(pkg_data, dict)
@@ -408,6 +317,8 @@ class NameSpacePackager(object):
self._split = None
self.depth = self.full_package_name.count('.')
self.nested = self._pkg_data.get('nested', False)
+ if self.nested:
+ NameSpaceInstaller.install_namespaces = lambda x: None
self.command = None
self.python_version()
self._pkg = [None, None] # required and pre-installable packages
@@ -769,14 +680,14 @@ class NameSpacePackager(object):
ep = self._pkg_data.get('extras_require')
return ep
- @property
- def data_files(self):
- df = self._pkg_data.get('data_files', [])
- if self.has_mit_lic():
- df.append('LICENSE')
- if not df:
- return None
- return [('.', df)]
+ # @property
+ # def data_files(self):
+ # df = self._pkg_data.get('data_files', [])
+ # if self.has_mit_lic():
+ # df.append('LICENSE')
+ # if not df:
+ # return None
+ # return [('.', df)]
@property
def package_data(self):
@@ -1018,30 +929,6 @@ def main():
pass
if nsp.wheel(kw, setup):
- if nsp.nested and 'bdist_wheel' in sys.argv:
- try:
- d = sys.argv[sys.argv.index('-d') + 1]
- except ValueError:
- dist_base = os.environ.get('PYDISTBASE')
- if dist_base:
- d = os.path.join(dist_base, nsp.full_package_name)
- else:
- d = 'dist'
- dashed_vs = '-' + version_str + '-'
- latest_mtime = -1
- full_name = None
- for x in os.listdir(d):
- if x.endswith('.whl') and dashed_vs in x:
- # remove .pth file from the wheel
- fn = os.path.join(d, x)
- if os.path.getmtime(fn) > latest_mtime:
- full_name = fn
- if full_name is None:
- print('no wheel file found in', d)
- else:
- print('patching .pth from {}'.format(full_name))
- with InMemoryZipFile(full_name) as imz:
- imz.delete_from_zip_file(nsp.full_package_name + '.*.pth')
return
for x in ['-c', 'egg_info', '--egg-base', 'pip-egg-info']:
if x not in sys.argv:
@@ -1066,16 +953,6 @@ def main():
break
try_dir = os.path.dirname(try_dir)
setup(**kw)
- if nsp.nested and sys.argv[:2] == ['-c', 'bdist_wheel']:
- d = sys.argv[sys.argv.index('-d') + 1]
- for x in os.listdir(d):
- if x.endswith('.whl'):
- # remove .pth file from the wheel
- full_name = os.path.join(d, x)
- print('patching .pth from', full_name)
- with InMemoryZipFile(full_name) as imz:
- imz.delete_from_zip_file(nsp.full_package_name + '.*.pth')
- break
main()