>>> pydiffx: Building testing/pydiffx 1.1-r0 (using abuild 3.10.0-r0) started Tue, 14 Mar 2023 11:51:39 +0000 >>> pydiffx: Checking sanity of /home/buildozer/aports/testing/pydiffx/APKBUILD... >>> pydiffx: Analyzing dependencies... >>> pydiffx: Installing for build: build-base python3 py3-six py3-gpep517 py3-setuptools py3-wheel py3-kgb py3-pytest (1/23) Installing libbz2 (1.0.8-r4) (2/23) Installing libffi (3.4.4-r0) (3/23) Installing gdbm (1.23-r0) (4/23) Installing xz-libs (5.4.1-r0) (5/23) Installing mpdecimal (2.5.1-r1) (6/23) Installing libpanelw (6.4_p20230311-r0) (7/23) Installing readline (8.2.1-r0) (8/23) Installing sqlite-libs (3.41.1-r0) (9/23) Installing python3 (3.11.2-r0) (10/23) Installing py3-six (1.16.0-r5) (11/23) Installing py3-installer (0.6.0-r0) (12/23) Installing py3-gpep517 (13-r0) (13/23) Installing py3-parsing (3.0.9-r1) (14/23) Installing py3-packaging (23.0-r1) (15/23) Installing py3-setuptools (67.6.0-r0) (16/23) Installing py3-wheel (0.38.4-r1) (17/23) Installing py3-kgb (7.1.1-r0) (18/23) Installing py3-attrs (22.2.0-r0) (19/23) Installing py3-iniconfig (1.1.1-r5) (20/23) Installing py3-pluggy (1.0.0-r2) (21/23) Installing py3-py (1.11.0-r1) (22/23) Installing py3-pytest (7.2.2-r0) (23/23) Installing .makedepends-pydiffx (20230314.115140) Executing busybox-1.36.0-r5.trigger OK: 449 MiB in 121 packages >>> pydiffx: Cleaning up srcdir >>> pydiffx: Cleaning up pkgdir >>> pydiffx: Fetching https://distfiles.alpinelinux.org/distfiles/edge//pydiffx-1.1.tar.gz >>> pydiffx: Fetching https://distfiles.alpinelinux.org/distfiles/edge//pydiffx-1.1.tar.gz >>> pydiffx: Checking sha512sums... pydiffx-1.1.tar.gz: OK >>> pydiffx: Unpacking /var/cache/distfiles/edge/pydiffx-1.1.tar.gz... 2023-03-14 11:51:40,761 gpep517 INFO Building wheel via backend setuptools.build_meta:__legacy__ 2023-03-14 11:51:40,810 root INFO running bdist_wheel 2023-03-14 11:51:40,817 root INFO running build 2023-03-14 11:51:40,817 root INFO running build_py 2023-03-14 11:51:40,818 root INFO creating build 2023-03-14 11:51:40,818 root INFO creating build/lib 2023-03-14 11:51:40,818 root INFO creating build/lib/pydiffx 2023-03-14 11:51:40,818 root INFO copying pydiffx/_version.py -> build/lib/pydiffx 2023-03-14 11:51:40,819 root INFO copying pydiffx/__init__.py -> build/lib/pydiffx 2023-03-14 11:51:40,819 root INFO copying pydiffx/writer.py -> build/lib/pydiffx 2023-03-14 11:51:40,819 root INFO copying pydiffx/errors.py -> build/lib/pydiffx 2023-03-14 11:51:40,819 root INFO copying pydiffx/sections.py -> build/lib/pydiffx 2023-03-14 11:51:40,819 root INFO copying pydiffx/reader.py -> build/lib/pydiffx 2023-03-14 11:51:40,819 root INFO copying pydiffx/options.py -> build/lib/pydiffx 2023-03-14 11:51:40,820 root INFO creating build/lib/pydiffx/dom 2023-03-14 11:51:40,820 root INFO copying pydiffx/dom/__init__.py -> build/lib/pydiffx/dom 2023-03-14 11:51:40,820 root INFO copying pydiffx/dom/writer.py -> build/lib/pydiffx/dom 2023-03-14 11:51:40,820 root INFO copying pydiffx/dom/objects.py -> build/lib/pydiffx/dom 2023-03-14 11:51:40,820 root INFO copying pydiffx/dom/reader.py -> build/lib/pydiffx/dom 2023-03-14 11:51:40,820 root INFO copying pydiffx/dom/properties.py -> build/lib/pydiffx/dom 2023-03-14 11:51:40,821 root INFO creating build/lib/pydiffx/integrations 2023-03-14 11:51:40,821 root INFO copying pydiffx/integrations/__init__.py -> build/lib/pydiffx/integrations 2023-03-14 11:51:40,821 root INFO copying pydiffx/integrations/pygments_lexer.py -> build/lib/pydiffx/integrations 2023-03-14 11:51:40,821 root INFO creating build/lib/pydiffx/tests 2023-03-14 11:51:40,821 root INFO copying pydiffx/tests/test_utils_unified_diffs.py -> build/lib/pydiffx/tests 2023-03-14 11:51:40,821 root INFO copying pydiffx/tests/__init__.py -> build/lib/pydiffx/tests 2023-03-14 11:51:40,821 root INFO copying pydiffx/tests/test_utils_text.py -> build/lib/pydiffx/tests 2023-03-14 11:51:40,821 root INFO copying pydiffx/tests/test_writer.py -> build/lib/pydiffx/tests 2023-03-14 11:51:40,822 root INFO copying pydiffx/tests/testcases.py -> build/lib/pydiffx/tests 2023-03-14 11:51:40,822 root INFO copying pydiffx/tests/test_reader.py -> build/lib/pydiffx/tests 2023-03-14 11:51:40,822 root INFO copying pydiffx/tests/test_dom_objects.py -> build/lib/pydiffx/tests 2023-03-14 11:51:40,822 root INFO creating build/lib/pydiffx/utils 2023-03-14 11:51:40,822 root INFO copying pydiffx/utils/__init__.py -> build/lib/pydiffx/utils 2023-03-14 11:51:40,823 root INFO copying pydiffx/utils/text.py -> build/lib/pydiffx/utils 2023-03-14 11:51:40,823 root INFO copying pydiffx/utils/unified_diffs.py -> build/lib/pydiffx/utils 2023-03-14 11:51:40,826 wheel INFO installing to build/bdist.linux-s390x/wheel 2023-03-14 11:51:40,826 root INFO running install 2023-03-14 11:51:40,831 root INFO running install_lib 2023-03-14 11:51:40,832 root INFO creating build/bdist.linux-s390x 2023-03-14 11:51:40,833 root INFO creating build/bdist.linux-s390x/wheel 2023-03-14 11:51:40,833 root INFO creating build/bdist.linux-s390x/wheel/pydiffx 2023-03-14 11:51:40,833 root INFO copying build/lib/pydiffx/_version.py -> build/bdist.linux-s390x/wheel/pydiffx 2023-03-14 11:51:40,833 root INFO copying build/lib/pydiffx/__init__.py -> build/bdist.linux-s390x/wheel/pydiffx 2023-03-14 11:51:40,833 root INFO creating build/bdist.linux-s390x/wheel/pydiffx/dom 2023-03-14 11:51:40,833 root INFO copying build/lib/pydiffx/dom/__init__.py -> build/bdist.linux-s390x/wheel/pydiffx/dom 2023-03-14 11:51:40,833 root INFO copying build/lib/pydiffx/dom/writer.py -> build/bdist.linux-s390x/wheel/pydiffx/dom 2023-03-14 11:51:40,833 root INFO copying build/lib/pydiffx/dom/objects.py -> build/bdist.linux-s390x/wheel/pydiffx/dom 2023-03-14 11:51:40,833 root INFO copying build/lib/pydiffx/dom/reader.py -> build/bdist.linux-s390x/wheel/pydiffx/dom 2023-03-14 11:51:40,834 root INFO copying build/lib/pydiffx/dom/properties.py -> build/bdist.linux-s390x/wheel/pydiffx/dom 2023-03-14 11:51:40,834 root INFO copying build/lib/pydiffx/writer.py -> build/bdist.linux-s390x/wheel/pydiffx 2023-03-14 11:51:40,834 root INFO copying build/lib/pydiffx/errors.py -> build/bdist.linux-s390x/wheel/pydiffx 2023-03-14 11:51:40,834 root INFO creating build/bdist.linux-s390x/wheel/pydiffx/integrations 2023-03-14 11:51:40,834 root INFO copying build/lib/pydiffx/integrations/__init__.py -> build/bdist.linux-s390x/wheel/pydiffx/integrations 2023-03-14 11:51:40,834 root INFO copying build/lib/pydiffx/integrations/pygments_lexer.py -> build/bdist.linux-s390x/wheel/pydiffx/integrations 2023-03-14 11:51:40,834 root INFO copying build/lib/pydiffx/sections.py -> build/bdist.linux-s390x/wheel/pydiffx 2023-03-14 11:51:40,835 root INFO creating build/bdist.linux-s390x/wheel/pydiffx/tests 2023-03-14 11:51:40,835 root INFO copying build/lib/pydiffx/tests/test_utils_unified_diffs.py -> build/bdist.linux-s390x/wheel/pydiffx/tests 2023-03-14 11:51:40,835 root INFO copying build/lib/pydiffx/tests/__init__.py -> build/bdist.linux-s390x/wheel/pydiffx/tests 2023-03-14 11:51:40,835 root INFO copying build/lib/pydiffx/tests/test_utils_text.py -> build/bdist.linux-s390x/wheel/pydiffx/tests 2023-03-14 11:51:40,835 root INFO copying build/lib/pydiffx/tests/test_writer.py -> build/bdist.linux-s390x/wheel/pydiffx/tests 2023-03-14 11:51:40,835 root INFO copying build/lib/pydiffx/tests/testcases.py -> build/bdist.linux-s390x/wheel/pydiffx/tests 2023-03-14 11:51:40,835 root INFO copying build/lib/pydiffx/tests/test_reader.py -> build/bdist.linux-s390x/wheel/pydiffx/tests 2023-03-14 11:51:40,836 root INFO copying build/lib/pydiffx/tests/test_dom_objects.py -> build/bdist.linux-s390x/wheel/pydiffx/tests 2023-03-14 11:51:40,836 root INFO copying build/lib/pydiffx/reader.py -> build/bdist.linux-s390x/wheel/pydiffx 2023-03-14 11:51:40,836 root INFO copying build/lib/pydiffx/options.py -> build/bdist.linux-s390x/wheel/pydiffx 2023-03-14 11:51:40,836 root INFO creating build/bdist.linux-s390x/wheel/pydiffx/utils 2023-03-14 11:51:40,836 root INFO copying build/lib/pydiffx/utils/__init__.py -> build/bdist.linux-s390x/wheel/pydiffx/utils 2023-03-14 11:51:40,836 root INFO copying build/lib/pydiffx/utils/text.py -> build/bdist.linux-s390x/wheel/pydiffx/utils 2023-03-14 11:51:40,836 root INFO copying build/lib/pydiffx/utils/unified_diffs.py -> build/bdist.linux-s390x/wheel/pydiffx/utils 2023-03-14 11:51:40,836 root INFO running install_egg_info 2023-03-14 11:51:40,842 root INFO running egg_info 2023-03-14 11:51:40,843 root INFO writing pydiffx.egg-info/PKG-INFO 2023-03-14 11:51:40,843 root INFO writing dependency_links to pydiffx.egg-info/dependency_links.txt 2023-03-14 11:51:40,843 root INFO writing entry points to pydiffx.egg-info/entry_points.txt 2023-03-14 11:51:40,843 root INFO writing requirements to pydiffx.egg-info/requires.txt 2023-03-14 11:51:40,843 root INFO writing top-level names to pydiffx.egg-info/top_level.txt 2023-03-14 11:51:40,844 root INFO reading manifest file 'pydiffx.egg-info/SOURCES.txt' 2023-03-14 11:51:40,845 root INFO adding license file 'LICENSE' 2023-03-14 11:51:40,845 root INFO adding license file 'AUTHORS' 2023-03-14 11:51:40,845 root INFO writing manifest file 'pydiffx.egg-info/SOURCES.txt' 2023-03-14 11:51:40,845 root INFO Copying pydiffx.egg-info to build/bdist.linux-s390x/wheel/pydiffx-1.1-py3.11.egg-info 2023-03-14 11:51:40,846 root INFO running install_scripts 2023-03-14 11:51:40,847 wheel INFO creating build/bdist.linux-s390x/wheel/pydiffx-1.1.dist-info/WHEEL 2023-03-14 11:51:40,847 wheel INFO creating '/home/buildozer/aports/testing/pydiffx/src/pydiffx-1.1/dist/.tmp-vbp2gy3w/pydiffx-1.1-py2.py3-none-any.whl' and adding 'build/bdist.linux-s390x/wheel' to it 2023-03-14 11:51:40,847 wheel INFO adding 'pydiffx/__init__.py' 2023-03-14 11:51:40,847 wheel INFO adding 'pydiffx/_version.py' 2023-03-14 11:51:40,847 wheel INFO adding 'pydiffx/errors.py' 2023-03-14 11:51:40,847 wheel INFO adding 'pydiffx/options.py' 2023-03-14 11:51:40,847 wheel INFO adding 'pydiffx/reader.py' 2023-03-14 11:51:40,847 wheel INFO adding 'pydiffx/sections.py' 2023-03-14 11:51:40,848 wheel INFO adding 'pydiffx/writer.py' 2023-03-14 11:51:40,848 wheel INFO adding 'pydiffx/dom/__init__.py' 2023-03-14 11:51:40,848 wheel INFO adding 'pydiffx/dom/objects.py' 2023-03-14 11:51:40,848 wheel INFO adding 'pydiffx/dom/properties.py' 2023-03-14 11:51:40,848 wheel INFO adding 'pydiffx/dom/reader.py' 2023-03-14 11:51:40,848 wheel INFO adding 'pydiffx/dom/writer.py' 2023-03-14 11:51:40,848 wheel INFO adding 'pydiffx/integrations/__init__.py' 2023-03-14 11:51:40,848 wheel INFO adding 'pydiffx/integrations/pygments_lexer.py' 2023-03-14 11:51:40,849 wheel INFO adding 'pydiffx/tests/__init__.py' 2023-03-14 11:51:40,849 wheel INFO adding 'pydiffx/tests/test_dom_objects.py' 2023-03-14 11:51:40,849 wheel INFO adding 'pydiffx/tests/test_reader.py' 2023-03-14 11:51:40,849 wheel INFO adding 'pydiffx/tests/test_utils_text.py' 2023-03-14 11:51:40,849 wheel INFO adding 'pydiffx/tests/test_utils_unified_diffs.py' 2023-03-14 11:51:40,849 wheel INFO adding 'pydiffx/tests/test_writer.py' 2023-03-14 11:51:40,849 wheel INFO adding 'pydiffx/tests/testcases.py' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx/utils/__init__.py' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx/utils/text.py' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx/utils/unified_diffs.py' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx-1.1.dist-info/AUTHORS' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx-1.1.dist-info/LICENSE' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx-1.1.dist-info/METADATA' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx-1.1.dist-info/WHEEL' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx-1.1.dist-info/entry_points.txt' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx-1.1.dist-info/top_level.txt' 2023-03-14 11:51:40,850 wheel INFO adding 'pydiffx-1.1.dist-info/RECORD' 2023-03-14 11:51:40,851 wheel INFO removing build/bdist.linux-s390x/wheel 2023-03-14 11:51:40,851 gpep517 INFO The backend produced dist/pydiffx-1.1-py2.py3-none-any.whl pydiffx-1.1-py2.py3-none-any.whl ============================= test session starts ============================== platform linux -- Python 3.11.2, pytest-7.2.2, pluggy-1.0.0 rootdir: /home/buildozer/aports/testing/pydiffx/src/pydiffx-1.1 plugins: kgb-7.1.1 collected 176 items pydiffx/tests/test_dom_objects.py .FF...........F....................... [ 21%] .............................................. [ 47%] pydiffx/tests/test_reader.py ......FF............. [ 59%] pydiffx/tests/test_utils_text.py .F... [ 62%] pydiffx/tests/test_utils_unified_diffs.py ....................... [ 75%] pydiffx/tests/test_writer.py .......FF..........F....................... [100%] =================================== FAILURES =================================== ____________ DiffXTests.test_from_bytes_to_bytes_preserves_content _____________ self = def test_from_bytes_to_bytes_preserves_content(self): """Testing DiffX.from_bytes followed by to_bytes results in byte-for-byte reproduction """ diff_content = ( b'#diffx: version=1.0\n' b'#.preamble: encoding=ascii, indent=2, length=36,' b' line_endings=dos, mimetype=text/plain\n' b' This is the file-level preamble.\r\n' b'#.meta: encoding=utf-32, format=json, length=96\n' b'\xff\xfe\x00\x00{\x00\x00\x00\n\x00\x00\x00' b' \x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00"' b'\x00\x00\x00k\x00\x00\x00e\x00\x00\x00y\x00\x00\x00"' b'\x00\x00\x00:\x00\x00\x00 \x00\x00\x00"\x00\x00\x00v' b'\x00\x00\x00a\x00\x00\x00l\x00\x00\x00u\x00\x00\x00e' b'\x00\x00\x00"\x00\x00\x00\n\x00\x00\x00}\x00\x00\x00' b'\n\x00\x00\x00' b'#.change: encoding=utf-16\n' b'#..preamble: indent=2, length=14, line_endings=unix, ' b'mimetype=text/markdown\n' b' \xff\xfet\x00e\x00s\x00t\x00\n\x00' b'#..meta: encoding=utf-8, format=json, length=244\n' b'{\n' b' "author": "Test User ",\n' b' "committer": "Test User ",\n' b' "committer date": "2021-06-02T13:12:06-07:00",\n' b' "date": "2021-06-01T19:26:31-07:00",\n' b' "id": "a25e7b28af5e3184946068f432122c68c1a30b23"\n' b'}\n' b'#..file:\n' b'#...meta: encoding=latin1, format=json, length=166\n' b'{\n' b' "path": "file1",\n' b' "revision": {\n' b' "new": "eed8df7f1400a95cdf5a87ddb947e7d9c5a19cef",\n' b' "old": "c8839177d1a5605aa60abe69db95c84183f0eebe"\n' b' }\n' b'}\n' b'#...diff: length=60, line_endings=unix\n' b'--- /file1\n' b'+++ /file1\n' b'@@ -498,7 +498,7 @@\n' b' ... diff content\n' b'#.change: encoding=utf-32\n' b'#..preamble: encoding=utf-8, indent=4, length=56, ' b'line_endings=unix\n' b' Summary of commit #2\n' b' \n' b' Here\'s a description.\n' b'#..meta: encoding=utf-8, format=json, length=244\n' b'{\n' b' "author": "Test User ",\n' b' "committer": "Test User ",\n' b' "committer date": "2021-06-02T19:46:25-07:00",\n' b' "date": "2021-06-01T19:46:22-07:00",\n' b' "id": "91127b687f583184144161f432222748c1a30b23"\n' b'}\n' b'#..file:\n' b'#...meta: encoding=utf-32, format=json, length=96\n' b'\xff\xfe\x00\x00' b'{\x00\x00\x00\n' b'\x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00' b' \x00\x00\x00"\x00\x00\x00k\x00\x00\x00e\x00\x00\x00' b'y\x00\x00\x00"\x00\x00\x00:\x00\x00\x00 \x00\x00\x00' b'"\x00\x00\x00v\x00\x00\x00a\x00\x00\x00l\x00\x00\x00' b'u\x00\x00\x00e\x00\x00\x00"\x00\x00\x00\n' b'\x00\x00\x00}\x00\x00\x00\n\x00\x00\x00' b'#...diff: encoding=utf-16, length=22, line_endings=unix\n' b'\xff\xfe \x00.\x00.\x00.\x00 \x00d\x00i\x00f\x00f\x00\n\x00' b'#..file:\n' b'#...meta: encoding=utf-8, format=json, length=166\n' b'{\n' b' "path": "file3",\n' b' "revision": {\n' b' "new": "0d4a0fb8d62b762a26e13591d06d93d79d61102f",\n' b' "old": "be089b7197974703c83682088a068bef3422c6c2"\n' b' }\n' b'}\n' b'#...diff: length=86, line_endings=dos\n' b'--- a/file3\r\n' b'+++ b/file3\r\n' b'@@ -258,7 +258,8 @@\r\n' b' ... diff content for commit 2, file3\r\n' ) > diffx = DiffX.from_bytes(diff_content) pydiffx/tests/test_dom_objects.py:803: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pydiffx/dom/objects.py:394: in from_bytes return cls.from_stream(io.BytesIO(data)) pydiffx/dom/objects.py:415: in from_stream return DiffXDOMReader(cls).parse(stream) pydiffx/dom/reader.py:82: in parse for section_info in reader: pydiffx/reader.py:234: in iter_sections section['diff'] = self._read_content( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , length = 22 encoding = 'utf-16', indent = None, line_endings = 'unix' preserve_trailing_newline = True, keep_bytes = True def _read_content(self, length, encoding=None, indent=None, line_endings=None, preserve_trailing_newline=False, keep_bytes=False): """Read content for a section, with the given length. The content will be read, any specified indentation stripped, and the resulting bytes decoded to a Unicode string (if an encoding is specified). The content will be validated to ensure that it ended in a newline (helping ensure that the length covered the entirety of the section's content). Args: length (int): The length of the content to read. encoding (unicode, optional): The encoding used to decode the content to a Unicode string. If ``None``, the result will be a byte string. indent (int, optional): The amount of indentation to strip from the beginning of each byte string. line_endings (unicode, optional): The specified line ending format (``dos`` or ``unix``). If provided, this will be used to split lines. If not provided, the line endings will be inferred. keep_bytes (bool, optional): Whether to keep the result as bytes, even if an encoding is provided. Returns: bytes or unicode: The processed string. The type is dependent on the ``encoding`` value. Raises: pydiffx.errors.DiffXParseError: The content did not end in the newline, or an option did not validate. """ fp = self._fp content = fp.read(length) # First, determine the line endings that we're going to be working # with. if line_endings: # An explicit line ending type was specified. Validate it and # get the newline characters, encoding it for the byte string. try: newline = get_newline_for_type(line_endings, encoding=encoding) except ValueError as e: raise DiffXParseError(six.text_type(e), linenum=self._linenum) else: # An explicit line ending type was not specified. Try to determine # the appropriate line ending based on the first line of content. line_endings, newline = guess_line_endings(content, encoding=encoding) lines = split_lines(data=content, newline=newline, keep_ends=True) if indent: # It's important that we don't assume each line is actually # indented correctly. There could be nothing but a newline, # or due to some error the indentation on some line may be # wrong. Be careful to strip only the spaces, up to the specified # indentation level. indent_re = re.compile(br'^ {1,%d}' % indent) content = b''.join( indent_re.sub(b'', _line) for _line in lines ) if encoding and not keep_bytes: # We know what this content was encoded with. We can now decode # it. content = content.decode(encoding) newline = newline.decode(encoding) # Validate that the content ends in a newline. This is to ensure that # the file was written according to spec. if not content.endswith(newline): > raise DiffXParseError( 'Expected a newline after content', linenum=self._linenum) E pydiffx.errors.DiffXParseError: Error on line 55: Expected a newline after content pydiffx/reader.py:509: DiffXParseError _________________ DiffXTests.test_from_bytes_with_complex_diff _________________ self = def test_from_bytes_with_complex_diff(self): """Testing DiffX.from_bytes with a complex diff""" > diffx = DiffX.from_bytes( b'#diffx: encoding=utf-16, version=1.0\n' b'#.preamble: encoding=ascii, indent=2, length=36,' b' line_endings=dos, mimetype=text/plain\n' b' This is the file-level preamble.\r\n' b'#.meta: encoding=utf-32, format=json, length=96\n' b'\xff\xfe\x00\x00{\x00\x00\x00\n\x00\x00\x00' b' \x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00"' b'\x00\x00\x00k\x00\x00\x00e\x00\x00\x00y\x00\x00\x00"' b'\x00\x00\x00:\x00\x00\x00 \x00\x00\x00"\x00\x00\x00v' b'\x00\x00\x00a\x00\x00\x00l\x00\x00\x00u\x00\x00\x00e' b'\x00\x00\x00"\x00\x00\x00\n\x00\x00\x00}\x00\x00\x00' b'\n\x00\x00\x00' b'#.change:\n' b'#..preamble: indent=2, length=14, line_endings=unix, ' b'mimetype=text/markdown\n' b' \xff\xfet\x00e\x00s\x00t\x00\n\x00' b'#..meta: encoding=utf-8, format=json, length=244\n' b'{\n' b' "author": "Test User ",\n' b' "committer": "Test User ",\n' b' "committer date": "2021-06-02T13:12:06-07:00",\n' b' "date": "2021-06-01T19:26:31-07:00",\n' b' "id": "a25e7b28af5e3184946068f432122c68c1a30b23"\n' b'}\n' b'#..file:\n' b'#...meta: encoding=latin1, format=json, length=166\n' b'{\n' b' "path": "file1",\n' b' "revision": {\n' b' "new": "eed8df7f1400a95cdf5a87ddb947e7d9c5a19cef",\n' b' "old": "c8839177d1a5605aa60abe69db95c84183f0eebe"\n' b' }\n' b'}\n' b'#...diff: length=60, line_endings=unix\n' b'--- /file1\n' b'+++ /file1\n' b'@@ -498,7 +498,7 @@\n' b' ... diff content\n' b'#.change: encoding=utf-32\n' b'#..preamble: encoding=utf-8, indent=4, length=56, ' b'line_endings=unix\n' b' Summary of commit #2\n' b' \n' b' Here\'s a description.\n' b'#..meta: encoding=utf-8, format=json, length=244\n' b'{\n' b' "author": "Test User ",\n' b' "committer": "Test User ",\n' b' "committer date": "2021-06-02T19:46:25-07:00",\n' b' "date": "2021-06-01T19:46:22-07:00",\n' b' "id": "91127b687f583184144161f432222748c1a30b23"\n' b'}\n' b'#..file:\n' b'#...meta: encoding=utf-32, format=json, length=96\n' b'\xff\xfe\x00\x00' b'{\x00\x00\x00\n' b'\x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00' b' \x00\x00\x00"\x00\x00\x00k\x00\x00\x00e\x00\x00\x00' b'y\x00\x00\x00"\x00\x00\x00:\x00\x00\x00 \x00\x00\x00' b'"\x00\x00\x00v\x00\x00\x00a\x00\x00\x00l\x00\x00\x00' b'u\x00\x00\x00e\x00\x00\x00"\x00\x00\x00\n' b'\x00\x00\x00}\x00\x00\x00\n\x00\x00\x00' b'#...diff: encoding=utf-16, length=22, line_endings=unix\n' b'\xff\xfe \x00.\x00.\x00.\x00 \x00d\x00i\x00f\x00f\x00\n\x00' b'#..file:\n' b'#...meta: encoding=utf-8, format=json, length=166\n' b'{\n' b' "path": "file3",\n' b' "revision": {\n' b' "new": "0d4a0fb8d62b762a26e13591d06d93d79d61102f",\n' b' "old": "be089b7197974703c83682088a068bef3422c6c2"\n' b' }\n' b'}\n' b'#...diff: length=86, line_endings=dos\n' b'--- a/file3\r\n' b'+++ b/file3\r\n' b'@@ -258,7 +258,8 @@\r\n' b' ... diff content for commit 2, file3\r\n' ) pydiffx/tests/test_dom_objects.py:443: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pydiffx/dom/objects.py:394: in from_bytes return cls.from_stream(io.BytesIO(data)) pydiffx/dom/objects.py:415: in from_stream return DiffXDOMReader(cls).parse(stream) pydiffx/dom/reader.py:82: in parse for section_info in reader: pydiffx/reader.py:234: in iter_sections section['diff'] = self._read_content( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , length = 22 encoding = 'utf-16', indent = None, line_endings = 'unix' preserve_trailing_newline = True, keep_bytes = True def _read_content(self, length, encoding=None, indent=None, line_endings=None, preserve_trailing_newline=False, keep_bytes=False): """Read content for a section, with the given length. The content will be read, any specified indentation stripped, and the resulting bytes decoded to a Unicode string (if an encoding is specified). The content will be validated to ensure that it ended in a newline (helping ensure that the length covered the entirety of the section's content). Args: length (int): The length of the content to read. encoding (unicode, optional): The encoding used to decode the content to a Unicode string. If ``None``, the result will be a byte string. indent (int, optional): The amount of indentation to strip from the beginning of each byte string. line_endings (unicode, optional): The specified line ending format (``dos`` or ``unix``). If provided, this will be used to split lines. If not provided, the line endings will be inferred. keep_bytes (bool, optional): Whether to keep the result as bytes, even if an encoding is provided. Returns: bytes or unicode: The processed string. The type is dependent on the ``encoding`` value. Raises: pydiffx.errors.DiffXParseError: The content did not end in the newline, or an option did not validate. """ fp = self._fp content = fp.read(length) # First, determine the line endings that we're going to be working # with. if line_endings: # An explicit line ending type was specified. Validate it and # get the newline characters, encoding it for the byte string. try: newline = get_newline_for_type(line_endings, encoding=encoding) except ValueError as e: raise DiffXParseError(six.text_type(e), linenum=self._linenum) else: # An explicit line ending type was not specified. Try to determine # the appropriate line ending based on the first line of content. line_endings, newline = guess_line_endings(content, encoding=encoding) lines = split_lines(data=content, newline=newline, keep_ends=True) if indent: # It's important that we don't assume each line is actually # indented correctly. There could be nothing but a newline, # or due to some error the indentation on some line may be # wrong. Be careful to strip only the spaces, up to the specified # indentation level. indent_re = re.compile(br'^ {1,%d}' % indent) content = b''.join( indent_re.sub(b'', _line) for _line in lines ) if encoding and not keep_bytes: # We know what this content was encoded with. We can now decode # it. content = content.decode(encoding) newline = newline.decode(encoding) # Validate that the content ends in a newline. This is to ensure that # the file was written according to spec. if not content.endswith(newline): > raise DiffXParseError( 'Expected a newline after content', linenum=self._linenum) E pydiffx.errors.DiffXParseError: Error on line 55: Expected a newline after content pydiffx/reader.py:509: DiffXParseError __________________ DiffXTests.test_to_bytes_with_complex_diff __________________ self = def test_to_bytes_with_complex_diff(self): """Testing DiffX.to_bytes with a complex diff""" diffx_file = DiffX( encoding='utf-16', preamble='This is the file-level preamble.', preamble_encoding='ascii', preamble_indent=2, preamble_line_endings=LineEndings.DOS, preamble_mimetype=PreambleMimeType.PLAIN, meta={ 'key': 'value', }, meta_encoding='utf-32', version='1.0') change = diffx_file.add_change( preamble='test', preamble_indent=2, preamble_line_endings=LineEndings.UNIX, preamble_mimetype=PreambleMimeType.MARKDOWN, meta={ 'author': 'Test User ', 'committer': 'Test User ', 'committer date': '2021-06-02T13:12:06-07:00', 'date': '2021-06-01T19:26:31-07:00', 'id': 'a25e7b28af5e3184946068f432122c68c1a30b23', }, meta_encoding='utf-8') change.add_file( meta={ 'path': 'file1', 'revision': { 'old': 'c8839177d1a5605aa60abe69db95c84183f0eebe', 'new': 'eed8df7f1400a95cdf5a87ddb947e7d9c5a19cef', }, }, meta_encoding='latin1', diff=( b'--- /file1\n' b'+++ /file1\n' b'@@ -498,7 +498,7 @@\n' b' ... diff content\n' )) change = diffx_file.add_change( preamble=( "Summary of commit #2\n" "\n" "Here's a description.\n" ), preamble_encoding='utf-8', meta={ 'author': 'Test User ', 'committer': 'Test User ', 'committer date': '2021-06-02T19:46:25-07:00', 'date': '2021-06-01T19:46:22-07:00', 'id': '91127b687f583184144161f432222748c1a30b23', }, meta_encoding='utf-8') change.add_file( meta={ 'key': 'value', }, meta_encoding='utf-32', diff=' ... diff'.encode('utf-16'), diff_encoding='utf-16') change.add_file( meta={ 'path': 'file3', 'revision': { 'old': 'be089b7197974703c83682088a068bef3422c6c2', 'new': '0d4a0fb8d62b762a26e13591d06d93d79d61102f', }, }, meta_encoding='utf-8', diff=( b'--- a/file3\r\n' b'+++ b/file3\r\n' b'@@ -258,7 +258,8 @@\r\n' b' ... diff content for commit 2, file3\r\n' ), diff_line_endings=LineEndings.DOS) > self._check_result( diffx_file, b'#diffx: encoding=utf-16, version=1.0\n' b'#.preamble: encoding=ascii, indent=2, length=36,' b' line_endings=dos, mimetype=text/plain\n' b' This is the file-level preamble.\r\n' b'#.meta: encoding=utf-32, format=json, length=96\n' b'\xff\xfe\x00\x00{\x00\x00\x00\n\x00\x00\x00' b' \x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00"' b'\x00\x00\x00k\x00\x00\x00e\x00\x00\x00y\x00\x00\x00"' b'\x00\x00\x00:\x00\x00\x00 \x00\x00\x00"\x00\x00\x00v' b'\x00\x00\x00a\x00\x00\x00l\x00\x00\x00u\x00\x00\x00e' b'\x00\x00\x00"\x00\x00\x00\n\x00\x00\x00}\x00\x00\x00' b'\n\x00\x00\x00' b'#.change:\n' b'#..preamble: indent=2, length=14, line_endings=unix, ' b'mimetype=text/markdown\n' b' \xff\xfet\x00e\x00s\x00t\x00\n\x00' b'#..meta: encoding=utf-8, format=json, length=244\n' b'{\n' b' "author": "Test User ",\n' b' "committer": "Test User ",\n' b' "committer date": "2021-06-02T13:12:06-07:00",\n' b' "date": "2021-06-01T19:26:31-07:00",\n' b' "id": "a25e7b28af5e3184946068f432122c68c1a30b23"\n' b'}\n' b'#..file:\n' b'#...meta: encoding=latin1, format=json, length=166\n' b'{\n' b' "path": "file1",\n' b' "revision": {\n' b' "new": "eed8df7f1400a95cdf5a87ddb947e7d9c5a19cef",\n' b' "old": "c8839177d1a5605aa60abe69db95c84183f0eebe"\n' b' }\n' b'}\n' b'#...diff: length=60, line_endings=unix\n' b'--- /file1\n' b'+++ /file1\n' b'@@ -498,7 +498,7 @@\n' b' ... diff content\n' b'#.change:\n' b'#..preamble: encoding=utf-8, indent=4, length=56, ' b'line_endings=unix\n' b' Summary of commit #2\n' b' \n' b' Here\'s a description.\n' b'#..meta: encoding=utf-8, format=json, length=244\n' b'{\n' b' "author": "Test User ",\n' b' "committer": "Test User ",\n' b' "committer date": "2021-06-02T19:46:25-07:00",\n' b' "date": "2021-06-01T19:46:22-07:00",\n' b' "id": "91127b687f583184144161f432222748c1a30b23"\n' b'}\n' b'#..file:\n' b'#...meta: encoding=utf-32, format=json, length=96\n' b'\xff\xfe\x00\x00' b'{\x00\x00\x00\n' b'\x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00' b' \x00\x00\x00"\x00\x00\x00k\x00\x00\x00e\x00\x00\x00' b'y\x00\x00\x00"\x00\x00\x00:\x00\x00\x00 \x00\x00\x00' b'"\x00\x00\x00v\x00\x00\x00a\x00\x00\x00l\x00\x00\x00' b'u\x00\x00\x00e\x00\x00\x00"\x00\x00\x00\n' b'\x00\x00\x00}\x00\x00\x00\n\x00\x00\x00' b'#...diff: encoding=utf-16, length=22, line_endings=unix\n' b'\xff\xfe \x00.\x00.\x00.\x00 \x00d\x00i\x00f\x00f\x00\n\x00' b'#..file:\n' b'#...meta: encoding=utf-8, format=json, length=166\n' b'{\n' b' "path": "file3",\n' b' "revision": {\n' b' "new": "0d4a0fb8d62b762a26e13591d06d93d79d61102f",\n' b' "old": "be089b7197974703c83682088a068bef3422c6c2"\n' b' }\n' b'}\n' b'#...diff: length=86, line_endings=dos\n' b'--- a/file3\r\n' b'+++ b/file3\r\n' b'@@ -258,7 +258,8 @@\r\n' b' ... diff content for commit 2, file3\r\n' ) pydiffx/tests/test_dom_objects.py:241: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pydiffx/tests/test_dom_objects.py:1179: in _check_result self.assertMultiLineBytesEqual(data, expected_result, pydiffx/tests/testcases.py:58: in assertMultiLineBytesEqual self.assertEqual( E AssertionError: Lists differ: [b'#d[228 chars] b'\x00\x00\xfe\xff\x00\x00\x00{\x00\x00\x00\n[2643 chars]r\n'] != [b'#d[228 chars] b'\xff\xfe\x00\x00{\x00\x00\x00\n', b'\x00\x0[2643 chars]r\n'] E E First differing element 4: E b'\x00\x00\xfe\xff\x00\x00\x00{\x00\x00\x00\n' E b'\xff\xfe\x00\x00{\x00\x00\x00\n' E E [b'#diffx: encoding=utf-16, version=1.0\n', E b'#.preamble: encoding=ascii, indent=2, length=36, line_endings=dos, mimetype=' E b'text/plain\n', E b' This is the file-level preamble.\r\n', E b'#.meta: encoding=utf-32, format=json, length=96\n', E - b'\x00\x00\xfe\xff\x00\x00\x00{\x00\x00\x00\n', E ? ------------ ^^ E E + b'\xff\xfe\x00\x00{\x00\x00\x00\n', E ? ^^ E E b'\x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00"' E b'\x00\x00\x00k\x00\x00\x00e\x00\x00\x00y\x00\x00\x00"\x00\x00\x00:' E b'\x00\x00\x00 \x00\x00\x00"\x00\x00\x00v\x00\x00\x00a\x00\x00\x00l' E b'\x00\x00\x00u\x00\x00\x00e\x00\x00\x00"\x00\x00\x00\n', E b'\x00\x00\x00}\x00\x00\x00\n', E - b'#.change:\n', E + b'\x00\x00\x00#.change:\n', E b'#..preamble: indent=2, length=14, line_endings=unix, mimetype=text/markd' E b'own\n', E - b' \xfe\xff\x00t\x00e\x00s\x00t\x00\n', E ? ---- ^^ E E + b' \xff\xfet\x00e\x00s\x00t\x00\n', E ? ^^ E E - b'#..meta: encoding=utf-8, format=json, length=244\n', E + b'\x00#..meta: encoding=utf-8, format=json, length=244\n', E ? ++++ E E b'{\n', E b' "author": "Test User ",\n', E b' "committer": "Test User ",\n', E b' "committer date": "2021-06-02T13:12:06-07:00",\n', E b' "date": "2021-06-01T19:26:31-07:00",\n', E b' "id": "a25e7b28af5e3184946068f432122c68c1a30b23"\n', E b'}\n', E b'#..file:\n', E b'#...meta: encoding=latin1, format=json, length=166\n', E b'{\n', E b' "path": "file1",\n', E b' "revision": {\n', E b' "new": "eed8df7f1400a95cdf5a87ddb947e7d9c5a19cef",\n', E b' "old": "c8839177d1a5605aa60abe69db95c84183f0eebe"\n', E b' }\n', E b'}\n', E b'#...diff: length=60, line_endings=unix\n', E b'--- /file1\n', E b'+++ /file1\n', E b'@@ -498,7 +498,7 @@\n', E b' ... diff content\n', E b'#.change:\n', E b'#..preamble: encoding=utf-8, indent=4, length=56, line_endings=unix\n', E b' Summary of commit #2\n', E b' \n', E b" Here's a description.\n", E b'#..meta: encoding=utf-8, format=json, length=244\n', E b'{\n', E b' "author": "Test User ",\n', E b' "committer": "Test User ",\n', E b' "committer date": "2021-06-02T19:46:25-07:00",\n', E b' "date": "2021-06-01T19:46:22-07:00",\n', E b' "id": "91127b687f583184144161f432222748c1a30b23"\n', E b'}\n', E b'#..file:\n', E b'#...meta: encoding=utf-32, format=json, length=96\n', E - b'\x00\x00\xfe\xff\x00\x00\x00{\x00\x00\x00\n', E ? ------------ ^^ E E + b'\xff\xfe\x00\x00{\x00\x00\x00\n', E ? ^^ E E b'\x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00"' E b'\x00\x00\x00k\x00\x00\x00e\x00\x00\x00y\x00\x00\x00"\x00\x00\x00:' E b'\x00\x00\x00 \x00\x00\x00"\x00\x00\x00v\x00\x00\x00a\x00\x00\x00l' E b'\x00\x00\x00u\x00\x00\x00e\x00\x00\x00"\x00\x00\x00\n', E b'\x00\x00\x00}\x00\x00\x00\n', E - b'#...diff: encoding=utf-16, length=22, line_endings=unix\n', E + b'\x00\x00\x00#...diff: encoding=utf-16, length=22, line_endings=unix\n', E ? ++++++++++++ E E - b'\xfe\xff\x00 \x00.\x00.\x00.\x00 \x00d\x00i\x00f\x00f\x00\n', E ? ---- ^^ E E + b'\xff\xfe \x00.\x00.\x00.\x00 \x00d\x00i\x00f\x00f\x00\n', E ? ^^ E E - b'#..file:\n', E + b'\x00#..file:\n', E ? ++++ E E b'#...meta: encoding=utf-8, format=json, length=166\n', E b'{\n', E b' "path": "file3",\n', E b' "revision": {\n', E b' "new": "0d4a0fb8d62b762a26e13591d06d93d79d61102f",\n', E b' "old": "be089b7197974703c83682088a068bef3422c6c2"\n', E b' }\n', E b'}\n', E b'#...diff: length=86, line_endings=dos\n', E b'--- a/file3\r\n', E b'+++ b/file3\r\n', E b'@@ -258,7 +258,8 @@\r\n', E b' ... diff content for commit 2, file3\r\n'] ___________________ DiffXReaderTests.test_with_content_utf16 ___________________ self = def test_with_content_utf16(self): """Testing DiffXReader with content in UTF-16 encoding""" reader = DiffXReader(io.BytesIO( b'#diffx: encoding=utf-16, version=1.0\n' b'#.preamble: indent=4, length=36\n' b' \xff\xfet\x00h\x00i\x00s\x00 \x00i\x00s\x00 \x00a\x00 ' b'\x00t\x00e\x00s\x00t\x00\n\x00' b'#.change:\n' b'#..file:\n' b'#...meta: format=json, length=48\n' b'\xff\xfe{\x00\n\x00 \x00 \x00 \x00 \x00"\x00k\x00e\x00y\x00' b'"\x00:\x00 \x00"\x00v\x00a\x00l\x00u\x00e\x00"\x00\n\x00}\x00' b'\n\x00' b'#...diff: encoding=utf-16, length=24, line_endings=dos\n' b'\xff\xfe \x00.\x00.\x00.\x00 \x00d\x00i\x00f\x00f\x00' b'\r\x00\n\x00' b'#.change:\n' )) > self.assertEqual(list(reader), [ { 'level': 0, 'line': 0, 'options': { 'encoding': 'utf-16', 'version': '1.0', }, 'section': Section.MAIN, 'type': 'diffx', }, { 'level': 1, 'line': 1, 'options': { 'indent': 4, 'length': 36, }, 'section': Section.MAIN_PREAMBLE, 'text': 'this is a test\n', 'type': 'preamble', }, { 'level': 1, 'line': 3, 'options': {}, 'section': Section.CHANGE, 'type': 'change', }, { 'level': 2, 'line': 4, 'options': {}, 'section': Section.FILE, 'type': 'file', }, { 'level': 3, 'line': 5, 'metadata': { 'key': 'value', }, 'options': { 'format': 'json', 'length': 48, }, 'section': Section.FILE_META, 'type': 'meta', }, { 'level': 3, 'line': 9, 'options': { 'encoding': 'utf-16', 'length': 24, 'line_endings': 'dos', }, 'section': Section.FILE_DIFF, 'diff': ' ... diff\r\n'.encode('utf-16'), 'type': 'diff', }, { 'level': 1, 'line': 11, 'options': {}, 'section': Section.CHANGE, 'type': 'change', }, ]) pydiffx/tests/test_reader.py:831: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pydiffx/reader.py:234: in iter_sections section['diff'] = self._read_content( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , length = 24 encoding = 'utf-16', indent = None, line_endings = 'dos' preserve_trailing_newline = True, keep_bytes = True def _read_content(self, length, encoding=None, indent=None, line_endings=None, preserve_trailing_newline=False, keep_bytes=False): """Read content for a section, with the given length. The content will be read, any specified indentation stripped, and the resulting bytes decoded to a Unicode string (if an encoding is specified). The content will be validated to ensure that it ended in a newline (helping ensure that the length covered the entirety of the section's content). Args: length (int): The length of the content to read. encoding (unicode, optional): The encoding used to decode the content to a Unicode string. If ``None``, the result will be a byte string. indent (int, optional): The amount of indentation to strip from the beginning of each byte string. line_endings (unicode, optional): The specified line ending format (``dos`` or ``unix``). If provided, this will be used to split lines. If not provided, the line endings will be inferred. keep_bytes (bool, optional): Whether to keep the result as bytes, even if an encoding is provided. Returns: bytes or unicode: The processed string. The type is dependent on the ``encoding`` value. Raises: pydiffx.errors.DiffXParseError: The content did not end in the newline, or an option did not validate. """ fp = self._fp content = fp.read(length) # First, determine the line endings that we're going to be working # with. if line_endings: # An explicit line ending type was specified. Validate it and # get the newline characters, encoding it for the byte string. try: newline = get_newline_for_type(line_endings, encoding=encoding) except ValueError as e: raise DiffXParseError(six.text_type(e), linenum=self._linenum) else: # An explicit line ending type was not specified. Try to determine # the appropriate line ending based on the first line of content. line_endings, newline = guess_line_endings(content, encoding=encoding) lines = split_lines(data=content, newline=newline, keep_ends=True) if indent: # It's important that we don't assume each line is actually # indented correctly. There could be nothing but a newline, # or due to some error the indentation on some line may be # wrong. Be careful to strip only the spaces, up to the specified # indentation level. indent_re = re.compile(br'^ {1,%d}' % indent) content = b''.join( indent_re.sub(b'', _line) for _line in lines ) if encoding and not keep_bytes: # We know what this content was encoded with. We can now decode # it. content = content.decode(encoding) newline = newline.decode(encoding) # Validate that the content ends in a newline. This is to ensure that # the file was written according to spec. if not content.endswith(newline): > raise DiffXParseError( 'Expected a newline after content', linenum=self._linenum) E pydiffx.errors.DiffXParseError: Error on line 13: Expected a newline after content pydiffx/reader.py:509: DiffXParseError ___________________ DiffXReaderTests.test_with_content_utf32 ___________________ self = def test_with_content_utf32(self): """Testing DiffXReader with content in UTF-32 encoding""" reader = DiffXReader(io.BytesIO( b'#diffx: encoding=utf-32, version=1.0\n' b'#.preamble: indent=4, length=68\n' b' \xff\xfe\x00\x00' b't\x00\x00\x00h\x00\x00\x00i\x00\x00\x00s\x00\x00\x00' b' \x00\x00\x00i\x00\x00\x00s\x00\x00\x00 \x00\x00\x00' b'a\x00\x00\x00 \x00\x00\x00t\x00\x00\x00e\x00\x00\x00' b's\x00\x00\x00t\x00\x00\x00\n\x00\x00\x00' b'#.change:\n' b'#..file:\n' b'#...meta: format=json, length=96\n' b'\xff\xfe\x00\x00' b'{\x00\x00\x00\n\x00\x00\x00' b' \x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00' b'"\x00\x00\x00k\x00\x00\x00e\x00\x00\x00y\x00\x00\x00' b'"\x00\x00\x00:\x00\x00\x00 \x00\x00\x00"\x00\x00\x00' b'v\x00\x00\x00a\x00\x00\x00l\x00\x00\x00u\x00\x00\x00' b'e\x00\x00\x00"\x00\x00\x00\n\x00\x00\x00' b'}\x00\x00\x00\n\x00\x00\x00' b'#...diff: encoding=utf-32, length=48, line_endings=dos\n' b'\xff\xfe\x00\x00 \x00\x00\x00.\x00\x00\x00.\x00\x00\x00' b'.\x00\x00\x00 \x00\x00\x00d\x00\x00\x00i\x00\x00\x00' b'f\x00\x00\x00f\x00\x00\x00\r\x00\x00\x00\n\x00\x00\x00' b'#.change:\n' )) > self.assertEqual(list(reader), [ { 'level': 0, 'line': 0, 'options': { 'encoding': 'utf-32', 'version': '1.0', }, 'section': Section.MAIN, 'type': 'diffx', }, { 'level': 1, 'line': 1, 'options': { 'indent': 4, 'length': 68, }, 'section': Section.MAIN_PREAMBLE, 'text': 'this is a test\n', 'type': 'preamble', }, { 'level': 1, 'line': 3, 'options': {}, 'section': Section.CHANGE, 'type': 'change', }, { 'level': 2, 'line': 4, 'options': {}, 'section': Section.FILE, 'type': 'file', }, { 'level': 3, 'line': 5, 'metadata': { 'key': 'value', }, 'options': { 'format': 'json', 'length': 96, }, 'section': Section.FILE_META, 'type': 'meta', }, { 'level': 3, 'line': 9, 'options': { 'encoding': 'utf-32', 'length': 48, 'line_endings': 'dos', }, 'section': Section.FILE_DIFF, 'diff': ' ... diff\r\n'.encode('utf-32'), 'type': 'diff', }, { 'level': 1, 'line': 11, 'options': {}, 'section': Section.CHANGE, 'type': 'change', }, ]) pydiffx/tests/test_reader.py:929: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pydiffx/reader.py:234: in iter_sections section['diff'] = self._read_content( _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , length = 48 encoding = 'utf-32', indent = None, line_endings = 'dos' preserve_trailing_newline = True, keep_bytes = True def _read_content(self, length, encoding=None, indent=None, line_endings=None, preserve_trailing_newline=False, keep_bytes=False): """Read content for a section, with the given length. The content will be read, any specified indentation stripped, and the resulting bytes decoded to a Unicode string (if an encoding is specified). The content will be validated to ensure that it ended in a newline (helping ensure that the length covered the entirety of the section's content). Args: length (int): The length of the content to read. encoding (unicode, optional): The encoding used to decode the content to a Unicode string. If ``None``, the result will be a byte string. indent (int, optional): The amount of indentation to strip from the beginning of each byte string. line_endings (unicode, optional): The specified line ending format (``dos`` or ``unix``). If provided, this will be used to split lines. If not provided, the line endings will be inferred. keep_bytes (bool, optional): Whether to keep the result as bytes, even if an encoding is provided. Returns: bytes or unicode: The processed string. The type is dependent on the ``encoding`` value. Raises: pydiffx.errors.DiffXParseError: The content did not end in the newline, or an option did not validate. """ fp = self._fp content = fp.read(length) # First, determine the line endings that we're going to be working # with. if line_endings: # An explicit line ending type was specified. Validate it and # get the newline characters, encoding it for the byte string. try: newline = get_newline_for_type(line_endings, encoding=encoding) except ValueError as e: raise DiffXParseError(six.text_type(e), linenum=self._linenum) else: # An explicit line ending type was not specified. Try to determine # the appropriate line ending based on the first line of content. line_endings, newline = guess_line_endings(content, encoding=encoding) lines = split_lines(data=content, newline=newline, keep_ends=True) if indent: # It's important that we don't assume each line is actually # indented correctly. There could be nothing but a newline, # or due to some error the indentation on some line may be # wrong. Be careful to strip only the spaces, up to the specified # indentation level. indent_re = re.compile(br'^ {1,%d}' % indent) content = b''.join( indent_re.sub(b'', _line) for _line in lines ) if encoding and not keep_bytes: # We know what this content was encoded with. We can now decode # it. content = content.decode(encoding) newline = newline.decode(encoding) # Validate that the content ends in a newline. This is to ensure that # the file was written according to spec. if not content.endswith(newline): > raise DiffXParseError( 'Expected a newline after content', linenum=self._linenum) E pydiffx.errors.DiffXParseError: Error on line 13: Expected a newline after content pydiffx/reader.py:509: DiffXParseError __________________ GetNewlineForTypeTests.test_with_encoding ___________________ self = def test_with_encoding(self): """Testing get_newline_for_type with encoding""" > self.assertEqual(get_newline_for_type(LineEndings.DOS, encoding='utf-32'), b'\r\x00\x00\x00\n\x00\x00\x00') E AssertionError: b'\x00\x00\x00\r\x00\x00\x00\n' != b'\r\x00\x00\x00\n\x00\x00\x00' pydiffx/tests/test_utils_text.py:35: AssertionError ___________________ DiffXWriterTests.test_with_content_utf16 ___________________ self = def test_with_content_utf16(self): """Testing DiffXWriter with content in UTF-16 encoding""" stream, writer = self._create_writer(encoding='utf-16') writer.write_preamble('this is a test\n') writer.new_change() writer.new_file() writer.write_meta({ 'key': 'value', }) writer.write_diff( ' ... diff\r\n'.encode('utf-16'), encoding='utf-16') > self._check_result( stream, b'#diffx: encoding=utf-16, version=1.0\n' b'#.preamble: indent=4, length=36, line_endings=unix\n' b' \xff\xfet\x00h\x00i\x00s\x00 \x00i\x00s\x00 \x00a\x00 ' b'\x00t\x00e\x00s\x00t\x00\n\x00' b'#.change:\n' b'#..file:\n' b'#...meta: format=json, length=48\n' b'\xff\xfe{\x00\n\x00 \x00 \x00 \x00 \x00"\x00k\x00e\x00y\x00' b'"\x00:\x00 \x00"\x00v\x00a\x00l\x00u\x00e\x00"\x00\n\x00}\x00' b'\n\x00' b'#...diff: encoding=utf-16, length=24, line_endings=dos\n' b'\xff\xfe \x00.\x00.\x00.\x00 \x00d\x00i\x00f\x00f\x00' b'\r\x00\n\x00' ) pydiffx/tests/test_writer.py:419: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pydiffx/tests/test_writer.py:1050: in _check_result self.assertMultiLineBytesEqual(data, expected_result, pydiffx/tests/testcases.py:58: in assertMultiLineBytesEqual self.assertEqual( E AssertionError: Lists differ: [b'#d[100 chars] \xfe\xff\x00t\x00h\x00i\x00s\x00 \x00i\x00s\[379 chars]0\n'] != [b'#d[100 chars] \xff\xfet\x00h\x00i\x00s\x00 \x00i\x00s\x00 [384 chars]x00'] E E First differing element 2: E b' \xfe\xff\x00t\x00h\x00i\x00s\x00 \x00i\x00s\[36 chars]00\n' E b' \xff\xfet\x00h\x00i\x00s\x00 \x00i\x00s\x00 [32 chars]00\n' E E Second list contains 1 additional elements. E First extra element 11: E b'\x00' E E [b'#diffx: encoding=utf-16, version=1.0\n', E b'#.preamble: indent=4, length=36, line_endings=unix\n', E - b' \xfe\xff\x00t\x00h\x00i\x00s\x00 \x00i\x00s\x00 \x00a\x00 \x00t' E ? ---- ^^ E E + b' \xff\xfet\x00h\x00i\x00s\x00 \x00i\x00s\x00 \x00a\x00 \x00t\x00' E ? ^^ ++++ E E - b'\x00e\x00s\x00t\x00\n', E ? ---- E E + b'e\x00s\x00t\x00\n', E - b'#.change:\n', E + b'\x00#.change:\n', E ? ++++ E E b'#..file:\n', E b'#...meta: format=json, length=48\n', E - b'\xfe\xff\x00{\x00\n', E ? ---- ^^ E E + b'\xff\xfe{\x00\n', E ? ^^ E E b'\x00 \x00 \x00 \x00 \x00"\x00k\x00e\x00y\x00"\x00:\x00 \x00"\x00v\x00a' E b'\x00l\x00u\x00e\x00"\x00\n', E b'\x00}\x00\n', E - b'#...diff: encoding=utf-16, length=24, line_endings=dos\n', E + b'\x00#...diff: encoding=utf-16, length=24, line_endings=dos\n', E ? ++++ E E - b'\xfe\xff\x00 \x00.\x00.\x00.\x00 \x00d\x00i\x00f\x00f\x00\r\x00\n'] E ? ---- ^^ ^ E E + b'\xff\xfe \x00.\x00.\x00.\x00 \x00d\x00i\x00f\x00f\x00\r\x00\n', E ? ^^ ^ E E + b'\x00'] ___________________ DiffXWriterTests.test_with_content_utf32 ___________________ self = def test_with_content_utf32(self): """Testing DiffXWriter with content in UTF-32 encoding""" stream, writer = self._create_writer(encoding='utf-32') writer.write_preamble('this is a test\n') writer.new_change() writer.new_file() writer.write_meta({ 'key': 'value', }) writer.write_diff( ' ... diff\r\n'.encode('utf-32'), encoding='utf-32') > self._check_result( stream, b'#diffx: encoding=utf-32, version=1.0\n' b'#.preamble: indent=4, length=68, line_endings=unix\n' b' \xff\xfe\x00\x00' b't\x00\x00\x00h\x00\x00\x00i\x00\x00\x00s\x00\x00\x00' b' \x00\x00\x00i\x00\x00\x00s\x00\x00\x00 \x00\x00\x00' b'a\x00\x00\x00 \x00\x00\x00t\x00\x00\x00e\x00\x00\x00' b's\x00\x00\x00t\x00\x00\x00\n\x00\x00\x00' b'#.change:\n' b'#..file:\n' b'#...meta: format=json, length=96\n' b'\xff\xfe\x00\x00' b'{\x00\x00\x00\n\x00\x00\x00' b' \x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00' b'"\x00\x00\x00k\x00\x00\x00e\x00\x00\x00y\x00\x00\x00' b'"\x00\x00\x00:\x00\x00\x00 \x00\x00\x00"\x00\x00\x00' b'v\x00\x00\x00a\x00\x00\x00l\x00\x00\x00u\x00\x00\x00' b'e\x00\x00\x00"\x00\x00\x00\n\x00\x00\x00' b'}\x00\x00\x00\n\x00\x00\x00' b'#...diff: encoding=utf-32, length=48, line_endings=dos\n' b'\xff\xfe\x00\x00 \x00\x00\x00.\x00\x00\x00.\x00\x00\x00' b'.\x00\x00\x00 \x00\x00\x00d\x00\x00\x00i\x00\x00\x00' b'f\x00\x00\x00f\x00\x00\x00\r\x00\x00\x00\n\x00\x00\x00' ) pydiffx/tests/test_writer.py:451: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pydiffx/tests/test_writer.py:1050: in _check_result self.assertMultiLineBytesEqual(data, expected_result, pydiffx/tests/testcases.py:58: in assertMultiLineBytesEqual self.assertEqual( E AssertionError: Lists differ: [b'#d[99 chars] \x00\x00\xfe\xff\x00\x00\x00t\x00\x00\x00h\[796 chars]0\n'] != [b'#d[99 chars] \xff\xfe\x00\x00t\x00\x00\x00h\x00\x00\x00i[801 chars]x00'] E E First differing element 2: E b' \x00\x00\xfe\xff\x00\x00\x00t\x00\x00\x00h\[165 chars]00\n' E b' \xff\xfe\x00\x00t\x00\x00\x00h\x00\x00\x00i[153 chars]00\n' E E Second list contains 1 additional elements. E First extra element 11: E b'\x00\x00\x00' E E [b'#diffx: encoding=utf-32, version=1.0\n', E b'#.preamble: indent=4, length=68, line_endings=unix\n', E - b' \x00\x00\xfe\xff\x00\x00\x00t\x00\x00\x00h\x00\x00\x00i\x00\x00\x00s' E ? ------------ ^^ E E + b' \xff\xfe\x00\x00t\x00\x00\x00h\x00\x00\x00i\x00\x00\x00s\x00\x00\x00' E ? ^^ ++++++++++++ E E + b' \x00\x00\x00i\x00\x00\x00s\x00\x00\x00 \x00\x00\x00a\x00\x00\x00' E - b'\x00\x00\x00 \x00\x00\x00i\x00\x00\x00s\x00\x00\x00 \x00\x00\x00a' E ? ^ ^ ^ ^ E E + b' \x00\x00\x00t\x00\x00\x00e\x00\x00\x00s\x00\x00\x00t\x00\x00\x00\n', E ? + ^ ^ ^ ^^ + E E - b'\x00\x00\x00 \x00\x00\x00t\x00\x00\x00e\x00\x00\x00s\x00\x00\x00t' E - b'\x00\x00\x00\n', E + b'\x00\x00\x00#.change:\n', E ? +++++++++ E E - b'#.change:\n', E b'#..file:\n', E b'#...meta: format=json, length=96\n', E - b'\x00\x00\xfe\xff\x00\x00\x00{\x00\x00\x00\n', E ? ------------ ^^ E E + b'\xff\xfe\x00\x00{\x00\x00\x00\n', E ? ^^ E E b'\x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00 \x00\x00\x00"' E b'\x00\x00\x00k\x00\x00\x00e\x00\x00\x00y\x00\x00\x00"\x00\x00\x00:' E b'\x00\x00\x00 \x00\x00\x00"\x00\x00\x00v\x00\x00\x00a\x00\x00\x00l' E b'\x00\x00\x00u\x00\x00\x00e\x00\x00\x00"\x00\x00\x00\n', E b'\x00\x00\x00}\x00\x00\x00\n', E - b'#...diff: encoding=utf-32, length=48, line_endings=dos\n', E + b'\x00\x00\x00#...diff: encoding=utf-32, length=48, line_endings=dos\n', E ? ++++++++++++ E E - b'\x00\x00\xfe\xff\x00\x00\x00 \x00\x00\x00.\x00\x00\x00.\x00\x00\x00.' E + b'\xff\xfe\x00\x00 \x00\x00\x00.\x00\x00\x00.\x00\x00\x00.\x00\x00\x00' E - b'\x00\x00\x00 \x00\x00\x00d\x00\x00\x00i\x00\x00\x00f\x00\x00\x00f' E ? ------------ E E + b' \x00\x00\x00d\x00\x00\x00i\x00\x00\x00f\x00\x00\x00f\x00\x00\x00' E ? ++++++++++++ E E - b'\x00\x00\x00\r\x00\x00\x00\n'] E + b'\r\x00\x00\x00\n', E + b'\x00\x00\x00'] ____ DiffXWriterTests.test_write_diff_with_encoding_no_newline_line_endings ____ self = def test_write_diff_with_encoding_no_newline_line_endings(self): """Testing DiffXWriter.write_diff with multi-byte encoding, no trailing newline, and specific line endings """ stream, writer = self._create_writer() writer.new_change() writer.new_file() writer.write_meta({ 'key': 'value', }) writer.write_diff('...'.encode('utf-16'), diff_type=DiffType.TEXT, line_endings=LineEndings.UNIX, encoding='utf-16') > self._check_result( stream, b'#diffx: encoding=utf-8, version=1.0\n' b'#.change:\n' b'#..file:\n' b'#...meta: format=json, length=23\n' b'{\n' b' "key": "value"\n' b'}\n' b'#...diff: encoding=utf-16, length=10, line_endings=unix,' b' type=text\n' b'\xff\xfe.\x00.\x00.\x00\n\x00' ) pydiffx/tests/test_writer.py:624: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pydiffx/tests/test_writer.py:1050: in _check_result self.assertMultiLineBytesEqual(data, expected_result, pydiffx/tests/testcases.py:58: in assertMultiLineBytesEqual self.assertEqual( E AssertionError: Lists differ: [b'#d[197 chars]ings=unix, type=text\n', b'\xfe\xff\x00.\x00.\x00.\x00\n'] != [b'#d[197 chars]ings=unix, type=text\n', b'\xff\xfe.\x00.\x00.\x00\n', b'\x00'] E E First differing element 8: E b'\xfe\xff\x00.\x00.\x00.\x00\n' E b'\xff\xfe.\x00.\x00.\x00\n' E E Second list contains 1 additional elements. E First extra element 9: E b'\x00' E E [b'#diffx: encoding=utf-8, version=1.0\n', E b'#.change:\n', E b'#..file:\n', E b'#...meta: format=json, length=23\n', E b'{\n', E b' "key": "value"\n', E b'}\n', E b'#...diff: encoding=utf-16, length=10, line_endings=unix, type=text\n', E - b'\xfe\xff\x00.\x00.\x00.\x00\n'] E ? ---- ^^ ^ E E + b'\xff\xfe.\x00.\x00.\x00\n', E ? ^^ ^ E E + b'\x00'] =============================== warnings summary =============================== pydiffx/tests/test_dom_objects.py: 22 warnings pydiffx/tests/test_reader.py: 10 warnings pydiffx/tests/test_utils_text.py: 2 warnings pydiffx/tests/test_utils_unified_diffs.py: 7 warnings pydiffx/tests/test_writer.py: 27 warnings /home/buildozer/aports/testing/pydiffx/src/pydiffx-1.1/pydiffx/tests/testcases.py:68: DeprecationWarning: Please use assertRaisesRegex instead. with self.assertRaisesRegexp(exception, re.escape(message)): -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================== short test summary info ============================ FAILED pydiffx/tests/test_dom_objects.py::DiffXTests::test_from_bytes_to_bytes_preserves_content FAILED pydiffx/tests/test_dom_objects.py::DiffXTests::test_from_bytes_with_complex_diff FAILED pydiffx/tests/test_dom_objects.py::DiffXTests::test_to_bytes_with_complex_diff FAILED pydiffx/tests/test_reader.py::DiffXReaderTests::test_with_content_utf16 FAILED pydiffx/tests/test_reader.py::DiffXReaderTests::test_with_content_utf32 FAILED pydiffx/tests/test_utils_text.py::GetNewlineForTypeTests::test_with_encoding FAILED pydiffx/tests/test_writer.py::DiffXWriterTests::test_with_content_utf16 FAILED pydiffx/tests/test_writer.py::DiffXWriterTests::test_with_content_utf32 FAILED pydiffx/tests/test_writer.py::DiffXWriterTests::test_write_diff_with_encoding_no_newline_line_endings ================== 9 failed, 167 passed, 68 warnings in 0.36s ================== >>> ERROR: pydiffx: check failed >>> pydiffx: Uninstalling dependencies... (1/23) Purging .makedepends-pydiffx (20230314.115140) (2/23) Purging py3-six (1.16.0-r5) (3/23) Purging py3-gpep517 (13-r0) (4/23) Purging py3-installer (0.6.0-r0) (5/23) Purging py3-setuptools (67.6.0-r0) (6/23) Purging py3-wheel (0.38.4-r1) (7/23) Purging py3-kgb (7.1.1-r0) (8/23) Purging py3-pytest (7.2.2-r0) (9/23) Purging py3-attrs (22.2.0-r0) (10/23) Purging py3-iniconfig (1.1.1-r5) (11/23) Purging py3-packaging (23.0-r1) (12/23) Purging py3-parsing (3.0.9-r1) (13/23) Purging py3-pluggy (1.0.0-r2) (14/23) Purging py3-py (1.11.0-r1) (15/23) Purging python3 (3.11.2-r0) (16/23) Purging libbz2 (1.0.8-r4) (17/23) Purging libffi (3.4.4-r0) (18/23) Purging gdbm (1.23-r0) (19/23) Purging xz-libs (5.4.1-r0) (20/23) Purging mpdecimal (2.5.1-r1) (21/23) Purging libpanelw (6.4_p20230311-r0) (22/23) Purging readline (8.2.1-r0) (23/23) Purging sqlite-libs (3.41.1-r0) Executing busybox-1.36.0-r5.trigger OK: 369 MiB in 98 packages