Adding upstream version 0.2.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
d372080b5f
commit
fb81c4a897
13 changed files with 159 additions and 116 deletions
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
open_collective: courtbouillon
|
29
.github/workflows/doconfly.yml
vendored
Normal file
29
.github/workflows/doconfly.yml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
name: doconfly
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
tags:
|
||||||
|
- "*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
doconfly:
|
||||||
|
name: doconfly job
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
PORT: ${{ secrets.PORT }}
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
TAKOYAKI: ${{ secrets.TAKOYAKI }}
|
||||||
|
USER: ${{ secrets.USER }}
|
||||||
|
DOCUMENTATION_PATH: ${{ secrets.DOCUMENTATION_PATH }}
|
||||||
|
DOCUMENTATION_URL: ${{ secrets.DOCUMENTATION_URL }}
|
||||||
|
steps:
|
||||||
|
- run: |
|
||||||
|
which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )
|
||||||
|
eval $(ssh-agent -s)
|
||||||
|
echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
chmod 700 ~/.ssh
|
||||||
|
ssh-keyscan -p $PORT $TAKOYAKI >> ~/.ssh/known_hosts
|
||||||
|
chmod 644 ~/.ssh/known_hosts
|
||||||
|
ssh $USER@$TAKOYAKI -p $PORT "doconfly/doconfly.sh $GITHUB_REPOSITORY $GITHUB_REF $DOCUMENTATION_PATH $DOCUMENTATION_URL"
|
35
.github/workflows/tests.yml
vendored
Normal file
35
.github/workflows/tests.yml
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
name: pydyf's tests
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
tests:
|
||||||
|
name: ${{ matrix.os }} - ${{ matrix.python-version }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
python-version: ['3.7', '3.8', '3.9', '3.10', 'pypy-3.8']
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
- name: Install Ghostscript (Ubuntu)
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
run: sudo apt-get update -y && sudo apt-get install ghostscript -y
|
||||||
|
- name: Install Ghostscript (macOS)
|
||||||
|
if: matrix.os == 'macos-latest'
|
||||||
|
run: brew install ghostscript
|
||||||
|
- name: Install Ghostscript (Windows)
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
run: |
|
||||||
|
C:\msys64\usr\bin\bash -lc 'pacman -S mingw-w64-x86_64-ghostscript --noconfirm'
|
||||||
|
echo "C:\msys64\mingw64\bin" | Out-File -FilePath $env:GITHUB_PATH
|
||||||
|
rm C:\msys64\mingw64\bin\python.exe
|
||||||
|
- name: Upgrade pip and setuptools
|
||||||
|
run: python -m pip install --upgrade pip setuptools
|
||||||
|
- name: Install tests’ requirements
|
||||||
|
run: python -m pip install .[test]
|
||||||
|
- name: Launch tests
|
||||||
|
run: python -m pytest
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/docs/_build
|
||||||
|
/tests/results
|
||||||
|
__pycache__
|
||||||
|
.coverage
|
57
PKG-INFO
57
PKG-INFO
|
@ -1,57 +0,0 @@
|
||||||
Metadata-Version: 2.1
|
|
||||||
Name: pydyf
|
|
||||||
Version: 0.1.2
|
|
||||||
Summary: A low-level PDF generator.
|
|
||||||
Keywords: pdf,generator
|
|
||||||
Author-email: CourtBouillon <contact@courtbouillon.org>
|
|
||||||
Maintainer-email: CourtBouillon <contact@courtbouillon.org>
|
|
||||||
Requires-Python: >=3.6
|
|
||||||
Description-Content-Type: text/x-rst
|
|
||||||
Classifier: Development Status :: 4 - Beta
|
|
||||||
Classifier: Intended Audience :: Developers
|
|
||||||
Classifier: License :: OSI Approved :: BSD License
|
|
||||||
Classifier: Operating System :: OS Independent
|
|
||||||
Classifier: Programming Language :: Python
|
|
||||||
Classifier: Programming Language :: Python :: 3
|
|
||||||
Classifier: Programming Language :: Python :: 3 :: Only
|
|
||||||
Classifier: Programming Language :: Python :: 3.6
|
|
||||||
Classifier: Programming Language :: Python :: 3.7
|
|
||||||
Classifier: Programming Language :: Python :: 3.8
|
|
||||||
Classifier: Programming Language :: Python :: 3.9
|
|
||||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
||||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
||||||
Requires-Dist: sphinx ; extra == "doc"
|
|
||||||
Requires-Dist: sphinx_rtd_theme ; extra == "doc"
|
|
||||||
Requires-Dist: pytest ; extra == "test"
|
|
||||||
Requires-Dist: pytest-cov ; extra == "test"
|
|
||||||
Requires-Dist: pytest-flake8 ; extra == "test"
|
|
||||||
Requires-Dist: pytest-isort ; extra == "test"
|
|
||||||
Requires-Dist: coverage[toml] ; extra == "test"
|
|
||||||
Requires-Dist: pillow ; extra == "test"
|
|
||||||
Project-URL: Changelog, https://github.com/CourtBouillon/pydyf/releases
|
|
||||||
Project-URL: Code, https://github.com/CourtBouillon/pydyf
|
|
||||||
Project-URL: Documentation, https://doc.courtbouillon.org/pydyf/
|
|
||||||
Project-URL: Donation, https://opencollective.com/courtbouillon
|
|
||||||
Project-URL: Homepage, https://www.courtbouillon.org/pydyf
|
|
||||||
Project-URL: Issues, https://github.com/CourtBouillon/pydyf/issues
|
|
||||||
Provides-Extra: doc
|
|
||||||
Provides-Extra: test
|
|
||||||
|
|
||||||
pydyf is a low-level PDF generator written in Python and based on PDF
|
|
||||||
specification 1.7.
|
|
||||||
|
|
||||||
* Free software: BSD license
|
|
||||||
* For Python 3.6+, tested on CPython and PyPy
|
|
||||||
* Documentation: https://doc.courtbouillon.org/pydyf
|
|
||||||
* Changelog: https://github.com/CourtBouillon/pydyf/releases
|
|
||||||
* Code, issues, tests: https://github.com/CourtBouillon/pydyf
|
|
||||||
* Code of conduct: https://www.courtbouillon.org/code-of-conduct
|
|
||||||
* Professional support: https://www.courtbouillon.org
|
|
||||||
* Donation: https://opencollective.com/courtbouillon
|
|
||||||
|
|
||||||
Copyrights are retained by their contributors, no copyright assignment is
|
|
||||||
required to contribute to pydyf. Unless explicitly stated otherwise, any
|
|
||||||
contribution intentionally submitted for inclusion is licensed under the BSD
|
|
||||||
3-clause license, without any additional terms or conditions. For full
|
|
||||||
authorship information, see the version control history.
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ pydyf is a low-level PDF generator written in Python and based on PDF
|
||||||
specification 1.7.
|
specification 1.7.
|
||||||
|
|
||||||
* Free software: BSD license
|
* Free software: BSD license
|
||||||
* For Python 3.6+, tested on CPython and PyPy
|
* For Python 3.7+, tested on CPython and PyPy
|
||||||
* Documentation: https://doc.courtbouillon.org/pydyf
|
* Documentation: https://doc.courtbouillon.org/pydyf
|
||||||
* Changelog: https://github.com/CourtBouillon/pydyf/releases
|
* Changelog: https://github.com/CourtBouillon/pydyf/releases
|
||||||
* Code, issues, tests: https://github.com/CourtBouillon/pydyf
|
* Code, issues, tests: https://github.com/CourtBouillon/pydyf
|
||||||
|
|
|
@ -2,6 +2,49 @@ Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.2.0
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Released on 2022-05-23.
|
||||||
|
|
||||||
|
Dependencies:
|
||||||
|
|
||||||
|
* Python 3.7+ is now needed, Python 3.6 is not supported anymore
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
* `d0be36b <https://github.com/CourtBouillon/pydyf/commit/d0be36b>`_:
|
||||||
|
Allow to set PDF version
|
||||||
|
* `879261c <https://github.com/CourtBouillon/pydyf/commit/879261c>`_:
|
||||||
|
Allow to set PDF identifier
|
||||||
|
|
||||||
|
Contributors:
|
||||||
|
|
||||||
|
* Guillaume Ayoub
|
||||||
|
|
||||||
|
Backers and sponsors:
|
||||||
|
|
||||||
|
* Grip Angebotssoftware
|
||||||
|
* Manuel Barkhau
|
||||||
|
* Crisp BV
|
||||||
|
* SimonSoft
|
||||||
|
* Menutech
|
||||||
|
* Spacinov
|
||||||
|
* KontextWork
|
||||||
|
* René Fritz
|
||||||
|
* Kobalt
|
||||||
|
* NCC Group
|
||||||
|
* Des images et des mots
|
||||||
|
* Nathalie Gutton
|
||||||
|
* Andreas Zettl
|
||||||
|
* Tom Pohl
|
||||||
|
* Moritz Mahringer
|
||||||
|
* Florian Demmer
|
||||||
|
* Yanal-Yvez Fargialla
|
||||||
|
* Gábor
|
||||||
|
* Piotr Horzycki
|
||||||
|
|
||||||
|
|
||||||
Version 0.1.2
|
Version 0.1.2
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
# pydyf documentation build configuration file.
|
# pydyf documentation build configuration file.
|
||||||
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import pydyf
|
import pydyf
|
||||||
|
|
||||||
# Add current path for css_diagram_role
|
|
||||||
sys.path.append(str(Path(__file__).parent))
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
extensions = [
|
extensions = [
|
||||||
|
|
|
@ -5,12 +5,11 @@ Going Further
|
||||||
Why pydyf?
|
Why pydyf?
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
pydyf has been created to replace Cairo PDF generation in WeasyPrint_.
|
pydyf has been created to replace Cairo_ PDF generation in WeasyPrint_.
|
||||||
|
|
||||||
Indeed, there are some bugs in WeasyPrint caused by Cairo_ and Cairo has some
|
Indeed, there were some bugs in WeasyPrint caused by Cairo, and new versions of
|
||||||
difficulties to make releases.
|
Cairo can take a long time to be released. There are also many features that
|
||||||
Also there are features which will be easier to implement while having more
|
are easier to implement with more control on the PDF generation.
|
||||||
control on the PDF generation.
|
|
||||||
|
|
||||||
So we created pydyf.
|
So we created pydyf.
|
||||||
|
|
||||||
|
@ -20,13 +19,13 @@ So we created pydyf.
|
||||||
Why Python?
|
Why Python?
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
Python is a really good language to design a small, OS-agnostic parser. As it
|
Python is a really good language to design a small, OS-agnostic library. As it
|
||||||
is object-oriented, it gives the possibility to follow the specification with
|
is object-oriented, it gives the possibility to follow the PDF specification
|
||||||
high-level classes and a small amount of very simple code.
|
with high-level classes and a small amount of very simple code.
|
||||||
|
|
||||||
And of course, WeasyPrint is written in Python too, giving an obvious reason
|
And of course, WeasyPrint is written in Python too, giving an obvious reason
|
||||||
for this choice.
|
for this choice.
|
||||||
|
|
||||||
Speed is not pydyf’s main goal. Code simplicity, maintainability and
|
Speed is not pydyf’s main goal. Code simplicity, maintainability and
|
||||||
flexibility are more important goals for this library, as they give the
|
flexibility are more important goals for this library, as they give the ability
|
||||||
ability to stay really close to the specification and to fix bugs easily.
|
to stay really close to the specification and to fix bugs easily.
|
||||||
|
|
|
@ -6,8 +6,9 @@ A low-level PDF generator.
|
||||||
import re
|
import re
|
||||||
import zlib
|
import zlib
|
||||||
from codecs import BOM_UTF16_BE
|
from codecs import BOM_UTF16_BE
|
||||||
|
from hashlib import md5
|
||||||
|
|
||||||
VERSION = __version__ = '0.1.2'
|
VERSION = __version__ = '0.2.0'
|
||||||
|
|
||||||
|
|
||||||
def _to_bytes(item):
|
def _to_bytes(item):
|
||||||
|
@ -425,7 +426,7 @@ class PDF:
|
||||||
})
|
})
|
||||||
self.add_object(self.pages)
|
self.add_object(self.pages)
|
||||||
|
|
||||||
#: PDF :class:`Dictionary` containing the PDF’s metadata.
|
#: PDF :class:`Dictionary` containing the PDF’s metadata.
|
||||||
self.info = Dictionary({})
|
self.info = Dictionary({})
|
||||||
self.add_object(self.info)
|
self.add_object(self.info)
|
||||||
|
|
||||||
|
@ -469,15 +470,17 @@ class PDF:
|
||||||
self.current_position += len(content) + 1
|
self.current_position += len(content) + 1
|
||||||
output.write(content + b'\n')
|
output.write(content + b'\n')
|
||||||
|
|
||||||
def write(self, output):
|
def write(self, output, version=b'1.7', identifier=None):
|
||||||
"""Write PDF to output.
|
"""Write PDF to output.
|
||||||
|
|
||||||
:param output: Output stream.
|
:param output: Output stream.
|
||||||
:type output: binary :term:`file object`
|
:type output: binary :term:`file object`
|
||||||
|
:param bytes version: PDF version.
|
||||||
|
:param bytes identifier: PDF file identifier.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Write header
|
# Write header
|
||||||
self.write_line(b'%PDF-1.7', output)
|
self.write_line(b'%PDF-' + version, output)
|
||||||
self.write_line(b'%\xf0\x9f\x96\xa4', output)
|
self.write_line(b'%\xf0\x9f\x96\xa4', output)
|
||||||
|
|
||||||
# Write all non-free PDF objects
|
# Write all non-free PDF objects
|
||||||
|
@ -502,6 +505,13 @@ class PDF:
|
||||||
self.write_line(f'/Size {len(self.objects)}'.encode(), output)
|
self.write_line(f'/Size {len(self.objects)}'.encode(), output)
|
||||||
self.write_line(b'/Root ' + self.catalog.reference, output)
|
self.write_line(b'/Root ' + self.catalog.reference, output)
|
||||||
self.write_line(b'/Info ' + self.info.reference, output)
|
self.write_line(b'/Info ' + self.info.reference, output)
|
||||||
|
if identifier is not None:
|
||||||
|
data = b''.join(
|
||||||
|
obj.data for obj in self.objects if obj.free != 'f')
|
||||||
|
data_hash = md5(data).hexdigest().encode()
|
||||||
|
self.write_line(
|
||||||
|
b'/ID [' + String(identifier).data + b' ' +
|
||||||
|
String(data_hash).data + b']', output)
|
||||||
self.write_line(b'>>', output)
|
self.write_line(b'>>', output)
|
||||||
self.write_line(b'startxref', output)
|
self.write_line(b'startxref', output)
|
||||||
self.write_line(f'{self.xref_position}'.encode(), output)
|
self.write_line(f'{self.xref_position}'.encode(), output)
|
||||||
|
|
|
@ -8,7 +8,7 @@ description = 'A low-level PDF generator.'
|
||||||
keywords = ['pdf', 'generator']
|
keywords = ['pdf', 'generator']
|
||||||
authors = [{name = 'CourtBouillon', email = 'contact@courtbouillon.org'}]
|
authors = [{name = 'CourtBouillon', email = 'contact@courtbouillon.org'}]
|
||||||
maintainers = [{name = 'CourtBouillon', email = 'contact@courtbouillon.org'}]
|
maintainers = [{name = 'CourtBouillon', email = 'contact@courtbouillon.org'}]
|
||||||
requires-python = '>=3.6'
|
requires-python = '>=3.7'
|
||||||
readme = {file = 'README.rst', content-type = 'text/x-rst'}
|
readme = {file = 'README.rst', content-type = 'text/x-rst'}
|
||||||
license = {file = 'LICENSE'}
|
license = {file = 'LICENSE'}
|
||||||
classifiers = [
|
classifiers = [
|
||||||
|
@ -19,10 +19,10 @@ classifiers = [
|
||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3 :: Only',
|
'Programming Language :: Python :: 3 :: Only',
|
||||||
'Programming Language :: Python :: 3.6',
|
|
||||||
'Programming Language :: Python :: 3.7',
|
'Programming Language :: Python :: 3.7',
|
||||||
'Programming Language :: Python :: 3.8',
|
'Programming Language :: Python :: 3.8',
|
||||||
'Programming Language :: Python :: 3.9',
|
'Programming Language :: Python :: 3.9',
|
||||||
|
'Programming Language :: Python :: 3.10',
|
||||||
'Programming Language :: Python :: Implementation :: CPython',
|
'Programming Language :: Python :: Implementation :: CPython',
|
||||||
'Programming Language :: Python :: Implementation :: PyPy',
|
'Programming Language :: Python :: Implementation :: PyPy',
|
||||||
]
|
]
|
||||||
|
@ -38,13 +38,13 @@ Donation = 'https://opencollective.com/courtbouillon'
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
doc = ['sphinx', 'sphinx_rtd_theme']
|
doc = ['sphinx', 'sphinx_rtd_theme']
|
||||||
test = ['pytest', 'pytest-cov', 'pytest-flake8', 'pytest-isort', 'coverage[toml]', 'pillow']
|
test = ['pytest', 'pytest-xdist', 'pytest-flake8', 'pytest-isort', 'pytest-cov', 'coverage[toml]', 'pillow']
|
||||||
|
|
||||||
[tool.flit.sdist]
|
[tool.flit.sdist]
|
||||||
exclude = ['.*']
|
exclude = ['.*']
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
addopts = '--isort --flake8 --cov --no-cov-on-fail'
|
addopts = '--isort --flake8 --numprocesses=auto'
|
||||||
|
|
||||||
[tool.coverage.run]
|
[tool.coverage.run]
|
||||||
branch = true
|
branch = true
|
||||||
|
|
31
setup.py
31
setup.py
|
@ -1,31 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
# setup.py generated by flit for tools that don't yet use PEP 517
|
|
||||||
|
|
||||||
from distutils.core import setup
|
|
||||||
|
|
||||||
packages = \
|
|
||||||
['pydyf']
|
|
||||||
|
|
||||||
package_data = \
|
|
||||||
{'': ['*']}
|
|
||||||
|
|
||||||
extras_require = \
|
|
||||||
{'doc': ['sphinx', 'sphinx_rtd_theme'],
|
|
||||||
'test': ['pytest',
|
|
||||||
'pytest-cov',
|
|
||||||
'pytest-flake8',
|
|
||||||
'pytest-isort',
|
|
||||||
'coverage[toml]',
|
|
||||||
'pillow']}
|
|
||||||
|
|
||||||
setup(name='pydyf',
|
|
||||||
version='0.1.2',
|
|
||||||
description='A low-level PDF generator.',
|
|
||||||
author=None,
|
|
||||||
author_email='CourtBouillon <contact@courtbouillon.org>',
|
|
||||||
url=None,
|
|
||||||
packages=packages,
|
|
||||||
package_data=package_data,
|
|
||||||
extras_require=extras_require,
|
|
||||||
python_requires='>=3.6',
|
|
||||||
)
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import io
|
||||||
|
|
||||||
import pydyf
|
import pydyf
|
||||||
|
|
||||||
from . import assert_pixels
|
from . import assert_pixels
|
||||||
|
@ -283,10 +285,10 @@ def test_transform():
|
||||||
document = pydyf.PDF()
|
document = pydyf.PDF()
|
||||||
|
|
||||||
draw = pydyf.Stream()
|
draw = pydyf.Stream()
|
||||||
|
draw.transform(1, 0, 0, 1, 1, 1)
|
||||||
draw.move_to(2, 2)
|
draw.move_to(2, 2)
|
||||||
draw.set_line_width(2)
|
draw.set_line_width(2)
|
||||||
draw.line_to(2, 5)
|
draw.line_to(2, 5)
|
||||||
draw.transform(1, 0, 0, 1, 1, 1)
|
|
||||||
draw.stroke()
|
draw.stroke()
|
||||||
document.add_object(draw)
|
document.add_object(draw)
|
||||||
|
|
||||||
|
@ -694,7 +696,7 @@ def test_text():
|
||||||
KKKKKKKKKK
|
KKKKKKKKKK
|
||||||
KKKKKKKKKK
|
KKKKKKKKKK
|
||||||
KKKKKKKKKK
|
KKKKKKKKKK
|
||||||
__________
|
zzzzzzzzzz
|
||||||
__________
|
__________
|
||||||
__________
|
__________
|
||||||
__________
|
__________
|
||||||
|
@ -702,6 +704,20 @@ def test_text():
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
def test_identifier():
|
||||||
|
document = pydyf.PDF()
|
||||||
|
pdf = io.BytesIO()
|
||||||
|
document.write(pdf, identifier=b'abc')
|
||||||
|
assert b'abc' in pdf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
def test_version():
|
||||||
|
document = pydyf.PDF()
|
||||||
|
pdf = io.BytesIO()
|
||||||
|
document.write(pdf, version=b'2.0')
|
||||||
|
assert b'2.0' in pdf.getvalue()
|
||||||
|
|
||||||
|
|
||||||
def test_string_encoding():
|
def test_string_encoding():
|
||||||
assert pydyf.String('abc').data == b'(abc)'
|
assert pydyf.String('abc').data == b'(abc)'
|
||||||
assert pydyf.String('déf').data == b'<feff006400e90066>'
|
assert pydyf.String('déf').data == b'<feff006400e90066>'
|
||||||
|
|
Loading…
Add table
Reference in a new issue