summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml62
-rw-r--r--.travis.yml223
-rw-r--r--README.md2
-rw-r--r--azure-pipelines.yml328
-rw-r--r--azure-pipelines/build.bash5
-rw-r--r--debian/changelog6
-rw-r--r--docs/installation.rst5
-rw-r--r--docs/release_notes.rst11
-rw-r--r--setup.py8
-rw-r--r--src/qpdf/object.cpp5
-rw-r--r--src/qpdf/pikepdf.h2
-rw-r--r--src/qpdf/shims.cpp45
-rw-r--r--src/qpdf/shims.h30
-rw-r--r--tests/test_object.py18
-rw-r--r--tests/test_pages.py41
15 files changed, 282 insertions, 509 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
deleted file mode 100644
index 83a108e..0000000
--- a/.appveyor.yml
+++ /dev/null
@@ -1,62 +0,0 @@
-version: "{build}"
-image: Visual Studio 2015
-platform:
- - x64
- - x86
-environment:
- global:
- DISTUTILS_USE_SDK: 1
- MSSdk: 1
- matrix:
- - PYTHON: 35
- - PYTHON: 36
- - PYTHON: 37
- #- PYTHON: 38
- TWINE_PASSWORD:
- secure: RZZXYbbTOzKMSE/GdzIG/x+eqehSEeu98j0Ggs+/fG8=
-install:
- - cmd: '"%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" %PLATFORM%'
- - ps: |
- $userpath = "$env:APPDATA\Python\Python$env:PYTHON\Scripts"
- if ($env:PLATFORM -eq "x64") {
- $env:PYTHON = "$env:PYTHON-x64"
- $qpdfzip = "https://github.com/qpdf/qpdf/releases/download/release-qpdf-9.0.0/qpdf-9.0.0-bin-msvc64.zip"
- } else {
- $qpdfzip = "https://github.com/qpdf/qpdf/releases/download/release-qpdf-9.0.0/qpdf-9.0.0-bin-msvc32.zip"
- }
- $env:PATH = "C:\Python$env:PYTHON;C:\Python$env:PYTHON\Scripts;$userpath;$env:PATH"
- echo $env:PATH
- python -m pip install --disable-pip-version-check --upgrade pip setuptools wheel
- pip install pybind11
-
- Invoke-WebRequest -Uri $qpdfzip -OutFile "qpdf-release.zip"
- 7z x "qpdf-release.zip" -oc:\
- $qpdfdir = Get-ChildItem c:\qpdf-*
- Move-Item -Path $qpdfdir -Destination c:\qpdf
-
-build_script:
- - ps: |
- cp c:\qpdf\bin\qpdf*.dll src\pikepdf
- $env:INCLUDE += ";c:\qpdf\include"
- $env:LIB += ";c:\qpdf\lib"
- $env:LIBPATH +=";c:\qpdf\lib"
- python setup.py bdist_wheel
- $wheel = Get-ChildItem -Path dist\pikepdf*.whl
- pip install --verbose $wheel
-
-test_script:
- - pip install -r requirements/test.txt
- - pytest -n auto
-
-artifacts:
- - path: dist\*.whl
- name: pypi
-
-deploy_script:
- - ps: |
- if ($env:APPVEYOR_REPO_TAG -eq "true")
- {
- pip install twine
- $env:TWINE_USERNAME = "ocrmypdf-travis"
- twine upload dist\*.whl
- }
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 4aefe18..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,223 +0,0 @@
-language: python
-dist: trusty
-sudo: false
-cache:
- ccache: true
- directories:
- - $HOME/Library/Caches/Homebrew
-
-env:
- global:
- - QPDF_RELEASE=https://github.com/qpdf/qpdf/releases/download/release-qpdf-9.0.0/qpdf-9.0.0.tar.gz
- - JPEG_RELEASE=https://www.ijg.org/files/jpegsrc.v9c.tar.gz
- - ZLIB_RELEASE=https://www.zlib.net/zlib-1.2.11.tar.gz
- - TWINE_USERNAME=ocrmypdf-travis
- # TWINE_PASSWORD
- - secure: "d1PfCVoqvFFwAqm0QEozLLoUdEHaY0kAvawfc4lKdLSjI+yOJYoNdknU0r3TdwttNEF2VV+aY9q/4wVnYrEiF4L13E3s+UtDqIXwGk/b14JrdExIx/0yj642kbCJPycZqqRZgvGwYuhb6EF7e/QrsNYMwZ95E9oTyWa0ZaEkiPrrVJh9XSNDpw9I8REL3GecpfvF/GpHWX0VBHoaJfCgDzDDvHQPdfIXAZg+OLJOLNrR2ivvUD3gR371376fYPMPNsqMNqBghLdX8lnX2zkEc67An9ZBLi1dx46PhHjn8c06QOBQ25wcwtCxSnaXygkq5HXUXnpWmCbPcy3n98bJBE1P86M1eWo5c3KV4zwY3pvC6/ldFFAX0nC5Qr8xVpiBZIZKhqBEsX7HlCIRdN5OzmWXTkRhO05GtloH+IPuS8PH09vlaGfdCmBdJkvQjnkXL9Jdw5JJcIt9c//CgRjJ4CtHySA3I0XEnqbLHRhsYAyfJfM4ya3ou+eETpWVpnkZ4kbn8fuUkIpZL6YS9XtJCVCfh5uNpJ7BV0DzlZqdV//K3s9CTNyFac0L521YcFRwl0Nb72AlzbtGwWgWh1C8qmlJ/ENf0XI3dafvcqzPL61rwBlo0sah9DWxwUDWMUicUtp8qP5GK8VxHse+QlolJQVSb07jD6bf7+mILX0B3Mg="
- # RTD_TOKEN
- - secure: "jD4S2pEvuf9oWv7RTWkdgrRw62WoUISiLFnPN9gPJ5ZeqdLeL8r3/+2x7tKa9xo6u6HWKVzo88+gg+HZCHIIZafWqxbhYsdl2g4dp3v807UVdp7rdqd7KkFl8/0XDR9p1J1g0RnRHp2qYtORqPZ0hustXnBQyiA0cA+a7qH9AWfhiU6iUV193YJAwYumSBeDAWgJN6OXAYKaZdLqynC/bmXYMfYM7Xg3sEnKv8eig+gQeSxyN2A/foTG/OgwUc8KVNTvO7w3xqXvfVUc7zm9P8Pdalay0V/8/0DAgZVSLjjnxqfOhmlDfE8OQeDLITBrD2GW0mPlSHP9ic0ymsltayR5Bg8opf3//+HBGoAyVDl0zwDVje4KX1QW2FzRri2ZQ+Lr25nvLkFIwQva2H+PuNUqB3Xw2JzZc4wsEqA83Y8Ijj8Cfc7Xd6hHIttWNe1D+n1tLSf123IW1QNMj7n2xr0AJi3ty1sTnr5WAgBEIR5WSy/roFdbHtLy/8wLE2AtKmhqKWndkSx17K45c35geuxmfthPrh6v1XPAgZZU0sza6dnrdD53WXwV8Z5+y4U+KD9YLf2gydfMSCrImdFWfjy3wMZci8Mn14uAZawwWyo2mfXvRXIVuUQdAx+uPnbkV4KzoAp7Xj7dJlpCxzphnX//1DLczOUJ6EdknbeIH6o="
-
-matrix:
- include:
- - env: PYTHON=3.5 GCC=4.8
- os: linux
- sudo: required
- python: "3.5"
- addons: &gcc48
- apt:
- sources: [ubuntu-toolchain-r-test]
- packages: [g++-4.8, libexempi-dev] # g++-4.8 supports c++11 but not c++14 at all; g++-4.9 won't work
- config:
- retries: true
-
- - env: PYTHON=3.6 GCC=4.8
- os: linux
- sudo: required
- python: "3.6"
- addons: *gcc48
-
- - env: PYTHON=3.6 GCC=8
- os: linux
- sudo: required
- python: "3.6"
- addons:
- apt:
- sources: [ubuntu-toolchain-r-test]
- packages: [g++-8, libexempi-dev] # g++-7 supports c++14
- config:
- retries: true
-
- - env: PYTHON=3.7 GCC=5
- os: linux
- sudo: required
- dist: xenial
- python: "3.7"
- addons: &gcc5_xenial
- apt:
- sources:
- - sourceline: "ppa:deadsnakes/ppa"
- packages: [python3.7-dev, python3.7-venv, g++-5, libexempi-dev]
- config:
- retries: true
-
- - env: PYTHON=3.8 GCC=5
- os: linux
- sudo: required
- dist: xenial
- python: "3.8"
- addons: &gcc5_xenial
- apt:
- sources:
- - sourceline: "ppa:deadsnakes/ppa"
- packages: [python3.8-dev, python3.8-venv, g++-5, libexempi-dev]
- config:
- retries: true
-
- - os: osx
- osx_image: xcode9.4
- language: generic
- addons:
- homebrew:
- update: true
- packages:
- - ccache
- - exempi
- - python
- - qpdf
-
- - stage: wheels
- os: osx
- osx_image: xcode9.4
- language: cpp # osx + language: python is broken
- addons:
- homebrew:
- update: true
- packages:
- - python
- - qpdf
- install:
- - clang --version
- - $PYTHON_CMD --version
- - echo "CC=$CC CXX=$CXX"
- - $PYTHON_CMD -m pip install --user cibuildwheel==0.12.0
- script:
- - $PYTHON_CMD setup.py sdist -d wheelhouse
- - export CCACHE_BASEDIR=`python3 -c "import tempfile; import os; print(os.path.realpath(tempfile.gettempdir()))"`
- - export CIBW_BEFORE_BUILD='pip install pybind11'
- - export CIBW_SKIP="cp27-* cp34-*"
- - $PYTHON_CMD -m cibuildwheel --output-dir wheelhouse
- - |
- if [[ $TRAVIS_TAG ]]; then
- $PYTHON_CMD -m pip install --user twine
- $PYTHON_CMD -m twine upload wheelhouse/*.whl wheelhouse/*.tar.gz
- fi
-
- - stage: wheels
- os: linux
- python: "3.6" # only need one environment to build all linux wheels
- sudo: required
- services:
- - docker
- install:
- - $PYTHON_CMD -m pip install cibuildwheel==0.12.0
- #- mkdir gcc-x86_64 && wget -q https://github.com/Noctem/pogeo-toolchain/releases/download/v1.4/gcc-7.2-binutils-2.29-centos5-x86-64.tar.bz2 -O - | tar xj -C gcc-x86_64 --strip-components=1
- #- mkdir ccache && wget -q https://www.samba.org/ftp/ccache/ccache-3.3.4.tar.bz2 -O - | tar xj -C ccache --strip-components=1
- - mkdir zlib && wget -q $ZLIB_RELEASE -O - | tar xz -C zlib --strip-components=1
- - mkdir jpeg && wget -q $JPEG_RELEASE -O - | tar xz -C jpeg --strip-components=1
- - mkdir qpdf && wget -q $QPDF_RELEASE -O - | tar xz -C qpdf --strip-components=1
- script:
- #- export CIBW_ENVIRONMENT='ARCH=x86_64 PATH="`pwd`/gcc-$ARCH/bin:$PATH" CC="ccache cc" CXX="ccache c++" CXXFLAGS="-static-libstdc++" LD_LIBRARY_PATH="`pwd`/gcc-$ARCH/lib" CCACHE_BASEDIR=`python -c "import tempfile; import os; print(os.path.realpath(tempfile.gettempdir()))"` CCACHE_DIR=/host'$HOME'/.ccache'
- #- export CIBW_BEFORE_BUILD='pip install pybind11 && [ -d ccache/$ARCH ] || (unset CC CXX CXXFLAGS && mkdir ccache/$ARCH && cd ccache/$ARCH && ../configure && make install)'
- #- export CIBW_ENVIRONMENT='ARCH=x86_64 PATH="`pwd`/gcc-$ARCH/bin:$PATH" CC="cc" CXX="c++" CXXFLAGS="-static-libstdc++" LD_LIBRARY_PATH="`pwd`/gcc-$ARCH/lib:$LD_LIBRARY_PATH"'
- - >-
- export CIBW_ENVIRONMENT='
- LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
- CXXFLAGS="-I/usr/local/include"
- LDFLAGS="-L/usr/local/lib"'
- - >-
- export CIBW_BEFORE_BUILD='
- [ ! -f /usr/local/lib/libz.a ] &&
- cd zlib &&
- ./configure &&
- make -j install &&
- cd .. ;
- [ ! -f /usr/local/lib/libjpeg.a ] &&
- cd jpeg &&
- ./configure &&
- make -j install &&
- cd .. ;
- [ ! -f /usr/local/lib/libqpdf.a ] &&
- cd qpdf &&
- ./autogen.sh &&
- ./configure &&
- make -j install &&
- cd .. ;
- pip install pybind11'
- - export CIBW_SKIP="cp27-* cp34-* *i686"
- - export CIBW_TEST_REQUIRES="-r requirements/test.txt"
- - export CIBW_TEST_COMMAND="pytest -nauto {project}/tests"
- - cibuildwheel --output-dir wheelhouse
- - |
- if [[ $TRAVIS_TAG ]]; then
- $PYTHON_CMD -m pip install twine
- $PYTHON_CMD -m twine upload wheelhouse/*.whl
- fi
- after_script:
- - curl -X POST -d "token=$RTD_TOKEN" https://readthedocs.org/api/v2/webhook/pikepdf/39557/
-
-stages:
- - name: test
- - name: wheels
-
-before_install:
- - |
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
- if [ -n "$GCC" ]; then
- export CC="gcc-$GCC"
- export CXX="g++-$GCC"
- export LD_LIBRARY_PATH="/lib:/usr/lib:/usr/local/lib"
- elif [ -n "$CLANG" ]; then
- CC="ccache clang-$CLANG"
- CXX="ccache clang++-$CLANG"
- export CFLAGS="-Qunused-arguments"
- export CXXFLAGS="-Qunused-arguments -stdlib=libc++"
- fi
- if [ "$PYTHON" = "3.6" ]; then
- pyenv global system $PYTHON # https://github.com/travis-ci/travis-ci/issues/8363
- else
- python$PYTHON -m ensurepip
- fi
- PYTHON_CMD=python$PYTHON
- elif [ "$TRAVIS_OS_NAME" == "osx" ]; then
- export PATH=/usr/local/opt/ccache/libexec:/usr/local/bin:$PATH
- CC=clang
- CXX=clang++
- PYTHON_CMD=python3
- fi
- $PYTHON_CMD -m pip install --upgrade pip wheel
-
-install:
- - |
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
- mkdir qpdf
- wget -q $QPDF_RELEASE -O - | tar xz -C qpdf --strip-components=1
- cd qpdf/
- ./configure CC="ccache $CC" CXX="ccache $CXX"
- make -j 2
- sudo make install
- cd ..
- elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
- : # no op for now
- fi
- - $PYTHON_CMD setup.py sdist
- - $PYTHON_CMD -m pip install pybind11
- - $PYTHON_CMD -m pip install --verbose dist/*.tar.gz
- - $PYTHON_CMD -m pip install -r requirements/test.txt
-
-script:
- - python3 -m pytest
-
-branches:
- except:
- - docs
- - azure-pipelines
diff --git a/README.md b/README.md
index 74bbb5c..df1ab73 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ pikepdf
**pikepdf** is a Python library for reading and writing PDF files.
-[![Travis CI build status (Linux and macOS)](https://img.shields.io/travis/pikepdf/pikepdf/master.svg?label=Linux%2fmacOS%20build)](https://travis-ci.org/pikepdf/pikepdf) [![AppVeyor CI build status (Windows)](https://img.shields.io/appveyor/ci/jbarlow83/pikepdf/master.svg?label=Windows%20build)](https://ci.appveyor.com/project/jbarlow83/pikepdf) [![PyPI](https://img.shields.io/pypi/v/pikepdf.svg)](https://pypi.org/project/pikepdf/) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pikepdf)
+[![Build Status](https://dev.azure.com/jim0585/pikepdf/_apis/build/status/pikepdf.pikepdf?branchName=master)](https://dev.azure.com/jim0585/pikepdf/_build/latest?definitionId=1&branchName=master) [![PyPI](https://img.shields.io/pypi/v/pikepdf.svg)](https://pypi.org/project/pikepdf/) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pikepdf)
pikepdf is based on [QPDF](https://github.com/qpdf/qpdf), a powerful PDF manipulation and repair library.
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 93d39e6..db6a4d7 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -4,141 +4,199 @@ variables:
jpeg_release: "https://www.ijg.org/files/jpegsrc.v9c.tar.gz"
zlib_release: "https://www.zlib.net/zlib-1.2.11.tar.gz"
cibw_skip: "cp27-* cp34-*"
- cibw_test_command: "pytest -nauto {project}/tests"
+ cibw_test_command: "pytest -nauto --junitxml=test.xml {project}/tests"
cibw_test_requires: "-r requirements/test.txt"
- cibuildwheel_version: "0.12.0"
+ cibuildwheel_version: "0375e92110113689025a5f05376f77d220d8b5c9"
cibw_before_build: "pip install pybind11"
-jobs:
- - job: linux_sdist
- pool: { vmImage: "Ubuntu-16.04" }
- steps:
- - task: UsePythonVersion@0
- - bash: |
- mkdir qpdf && wget -q $QPDF_RELEASE -O - | tar xz -C qpdf --strip-components=1
- cd qpdf/
- ./configure
- make -j 2
- sudo make install
- cd ..
- displayName: "Build QPDF"
- - bash: |
- python -m pip install --upgrade pip
- python setup.py sdist
- python -m pip install pybind11
- python -m pip install --verbose dist/*.tar.gz
- python -m pip install -r requirements/test.txt
- displayName: "Build sdist"
- - bash: |
- export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
- python -m pytest -nauto
- displayName: "Test"
- - task: PublishBuildArtifacts@1
- inputs: { pathtoPublish: "dist" }
- - job: linux
- pool: { vmImage: "Ubuntu-16.04" }
- variables:
- cibw_environment: >-
- LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
- CXXFLAGS="-I/usr/local/include"
- LDFLAGS="-L/usr/local/lib"
- cibw_before_build: >- # yaml: folded newlines to spaces, no newline at end
- [ ! -f /usr/local/lib/libz.a ] &&
- cd zlib &&
- ./configure &&
- make -j install &&
- cd .. ;
- [ ! -f /usr/local/lib/libjpeg.a ] &&
- cd jpeg &&
- ./configure &&
- make -j install &&
- cd .. ;
- [ ! -f /usr/local/lib/libqpdf.a ] &&
- cd qpdf &&
- ./autogen.sh &&
- ./configure &&
- make -j install &&
- cd .. ;
- pip install pybind11
- steps:
- - task: UsePythonVersion@0
- - bash: |
- mkdir zlib && wget -q $ZLIB_RELEASE -O - | tar xz -C zlib --strip-components=1
- mkdir jpeg && wget -q $JPEG_RELEASE -O - | tar xz -C jpeg --strip-components=1
- mkdir qpdf && wget -q $QPDF_RELEASE -O - | tar xz -C qpdf --strip-components=1
- - bash: source azure-pipelines/build.bash
- - task: PublishBuildArtifacts@1
- inputs: { pathtoPublish: "wheelhouse" }
- - job: macos
- pool: { vmImage: "macOS-10.13" }
- variables:
- cibw_before_build: >-
- pip install pybind11 &&
- brew install qpdf
- steps:
- - task: UsePythonVersion@0
- - bash: source azure-pipelines/build.bash
- - task: PublishBuildArtifacts@1
- inputs: { pathtoPublish: "wheelhouse" }
- - job: windows64
- pool: { vmImage: "vs2017-win2016" }
- variables:
- qpdf_windows: ${{ format('https://github.com/qpdf/qpdf/releases/download/release-qpdf-{0}/qpdf-{0}-bin-msvc64.zip', variables.qpdf_version) }}
- cibw_skip: "cp27-* cp34-* cp35-win32* cp36-win32* cp37-win32* cp38-win32*"
- cibw_environment: >-
- INCLUDE="$INCLUDE;c:\\qpdf\\include"
- LIB="$LIB;c:\\qpdf\\lib"
- LIBPATH="$LIBPATH;c:\\qpdf\\lib"
- steps:
- - {
- task: UsePythonVersion@0,
- inputs: { versionSpec: "3.5", architecture: x64 },
- }
- - {
- task: UsePythonVersion@0,
- inputs: { versionSpec: "3.6", architecture: x64 },
- }
- - {
- task: UsePythonVersion@0,
- inputs: { versionSpec: "3.7", architecture: x64 },
- }
- # - {
- # task: UsePythonVersion@0,
- # inputs: { versionSpec: "3.8", architecture: x64 },
- # }
- - powershell: azure-pipelines/win-download-qpdf.ps1
- displayName: "Download QPDF"
- - bash: source azure-pipelines/build.bash
- - task: PublishBuildArtifacts@1
- inputs: { pathtoPublish: "wheelhouse" }
- - job: windows32
- pool: { vmImage: "vs2017-win2016" }
- variables:
- qpdf_windows: ${{ format('https://github.com/qpdf/qpdf/releases/download/release-qpdf-{0}/qpdf-{0}-bin-msvc32.zip', variables.qpdf_version) }}
- cibw_skip: "cp27-* cp34-* cp35-win_amd64* cp36-win_amd64* cp37-win_amd64* cp38-win_amd64*"
- cibw_environment: >-
- INCLUDE="$INCLUDE;c:\\qpdf\\include"
- LIB="$LIB;c:\\qpdf\\lib"
- LIBPATH="$LIBPATH;c:\\qpdf\\lib"
- steps:
- - {
- task: UsePythonVersion@0,
- inputs: { versionSpec: "3.5", architecture: x86 },
- }
- - {
- task: UsePythonVersion@0,
- inputs: { versionSpec: "3.6", architecture: x86 },
- }
- - {
- task: UsePythonVersion@0,
- inputs: { versionSpec: "3.7", architecture: x86 },
- }
- # - {
- # task: UsePythonVersion@0,
- # inputs: { versionSpec: "3.8", architecture: x64 },
- # }
- - powershell: azure-pipelines/win-download-qpdf.ps1
- displayName: "Download QPDF"
- - bash: source azure-pipelines/build.bash
- - task: PublishBuildArtifacts@1
- inputs: { pathtoPublish: "wheelhouse" }
+trigger:
+ tags:
+ include:
+ - v*
+ branches:
+ include:
+ - "*"
+
+stages:
+ - stage: "Build_and_test"
+ jobs:
+ - job: linux_sdist
+ pool: { vmImage: "Ubuntu-16.04" }
+ steps:
+ - task: UsePythonVersion@0
+ - bash: |
+ mkdir qpdf && wget -q $QPDF_RELEASE -O - | tar xz -C qpdf --strip-components=1
+ cd qpdf/
+ ./configure
+ make -j 2
+ sudo make install
+ cd ..
+ displayName: "Build QPDF"
+ - bash: |
+ python -m pip install --upgrade pip
+ python setup.py sdist
+ python -m pip install pybind11
+ python -m pip install --verbose dist/*.tar.gz
+ python -m pip install -r requirements/test.txt
+ displayName: "Build sdist"
+ - bash: |
+ export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
+ python -m pytest -nauto --junitxml=test-sdist.xml
+ displayName: "Test"
+ - task: PublishTestResults@2
+ inputs:
+ testResultsFiles: "test-sdist.xml"
+ testRunTitle: "$(Agent.OS) - $(Build.DefinitionName) - Python $(python.version)"
+ condition: succeededOrFailed()
+ - publish: dist
+ artifact: sdist
+ - job: linux
+ pool: { vmImage: "Ubuntu-16.04" }
+ variables:
+ cibw_environment: >-
+ LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
+ CXXFLAGS="-I/usr/local/include"
+ LDFLAGS="-L/usr/local/lib"
+ cibw_before_build:
+ >- # yaml: folded newlines to spaces, no newline at end
+ [ ! -f /usr/local/lib/libz.a ] &&
+ cd zlib &&
+ ./configure &&
+ make -j install &&
+ cd .. ;
+ [ ! -f /usr/local/lib/libjpeg.a ] &&
+ cd jpeg &&
+ ./configure &&
+ make -j install &&
+ cd .. ;
+ [ ! -f /usr/local/lib/libqpdf.a ] &&
+ cd qpdf &&
+ ./autogen.sh &&
+ ./configure &&
+ make -j install &&
+ cd .. ;
+ pip install pybind11
+ steps:
+ - task: UsePythonVersion@0
+ - bash: |
+ mkdir zlib && wget -q $ZLIB_RELEASE -O - | tar xz -C zlib --strip-components=1
+ mkdir jpeg && wget -q $JPEG_RELEASE -O - | tar xz -C jpeg --strip-components=1
+ mkdir qpdf && wget -q $QPDF_RELEASE -O - | tar xz -C qpdf --strip-components=1
+ displayName: "Download QPDF and components"
+ - bash: source azure-pipelines/build.bash
+ displayName: "cibuildwheel"
+ - task: PublishTestResults@2
+ inputs:
+ testResultsFiles: "test.xml"
+ testRunTitle: "$(Agent.OS) - $(Build.DefinitionName) - Python $(python.version)"
+ condition: succeededOrFailed()
+ - publish: dist
+ artifact: linux
+ - job: macos
+ pool: { vmImage: "macOS-10.13" }
+ variables:
+ cibw_before_build: >-
+ pip install pybind11 &&
+ brew install qpdf
+ steps:
+ - task: UsePythonVersion@0
+ - bash: source azure-pipelines/build.bash
+ displayName: cibuildwheel
+ - publish: dist
+ artifact: macos
+ - job: windows64
+ pool: { vmImage: "vs2017-win2016" }
+ variables:
+ qpdf_windows: ${{ format('https://github.com/qpdf/qpdf/releases/download/release-qpdf-{0}/qpdf-{0}-bin-msvc64.zip', variables.qpdf_version) }}
+ cibw_skip: "cp27-* cp34-* cp35-win32* cp36-win32* cp37-win32* cp38-win32*"
+ cibw_environment: >-
+ INCLUDE="$INCLUDE;c:\\qpdf\\include"
+ LIB="$LIB;c:\\qpdf\\lib"
+ LIBPATH="$LIBPATH;c:\\qpdf\\lib"
+ steps:
+ - task: UsePythonVersion@0
+ - powershell: azure-pipelines/win-download-qpdf.ps1
+ displayName: "Download QPDF"
+ - bash: source azure-pipelines/build.bash
+ displayName: "cibuildwheel"
+ - publish: dist
+ artifact: win64
+ - job: windows32
+ pool: { vmImage: "vs2017-win2016" }
+ variables:
+ qpdf_windows: ${{ format('https://github.com/qpdf/qpdf/releases/download/release-qpdf-{0}/qpdf-{0}-bin-msvc32.zip', variables.qpdf_version) }}
+ cibw_skip: "cp27-* cp34-* cp35-win_amd64* cp36-win_amd64* cp37-win_amd64* cp38-win_amd64*"
+ cibw_environment: >-
+ INCLUDE="$INCLUDE;c:\\qpdf\\include"
+ LIB="$LIB;c:\\qpdf\\lib"
+ LIBPATH="$LIBPATH;c:\\qpdf\\lib"
+ steps:
+ - task: UsePythonVersion@0
+ - powershell: azure-pipelines/win-download-qpdf.ps1
+ displayName: "Download QPDF"
+ - bash: source azure-pipelines/build.bash
+ displayName: "cibuildwheel"
+ - publish: dist
+ artifact: win32
+
+ - stage: "Deploy"
+ jobs:
+ - deployment: "PyPI"
+ pool: { vmImage: "ubuntu-18.04" }
+ environment: "deploy"
+ strategy:
+ runOnce:
+ deploy:
+ steps:
+ - task: UsePythonVersion@0
+ inputs:
+ versionSpec: "3.8"
+ architecture: x64
+ - download: current
+ artifact: sdist
+ - download: current
+ artifact: linux
+ - download: current
+ artifact: macos
+ - download: current
+ artifact: win64
+ - download: current
+ artifact: win32
+ - script: |
+ mkdir -p dist
+ mv $(Pipeline.Workspace)/sdist/* dist
+ mv $(Pipeline.Workspace)/linux/* dist
+ mv $(Pipeline.Workspace)/macos/* dist
+ mv $(Pipeline.Workspace)/win64/* dist
+ mv $(Pipeline.Workspace)/win32/* dist
+ displayName: "Organize artifacts"
+ - script: |
+ python -m pip install -U pip
+ python -m pip install -U twine
+ cat <<FILE >.pypirc
+ [distutils]
+ index-servers =
+ pypi
+ testpypi
+
+ [pypi]
+ username: __token__
+ password: $(TOKEN_PYPI)
+
+ [testpypi]
+ repository: https://test.pypi.org/legacy/
+ username: __token__
+ password: $(TOKEN_TESTPYPI)
+ FILE
+ displayName: "Generate PyPI auth file"
+ - script: |
+ python -m twine upload -r "testpypi" --config-file .pypirc dist/*
+ displayName: "Upload to TestPyPI"
+ condition: not(startsWith(variables['Build.SourceBranch'], 'refs/tags/'))
+ - script: |
+ python -m twine upload --config-file .pypirc dist/*
+ displayName: "Upload to PyPI"
+ condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/')
+ - script: |
+ curl -X POST -d "token=$(RTD_TOKEN)" https://readthedocs.org/api/v2/webhook/pikepdf/39557/
+ displayName: "Trigger ReadTheDocs"
diff --git a/azure-pipelines/build.bash b/azure-pipelines/build.bash
index 0f57954..7b1b765 100644
--- a/azure-pipelines/build.bash
+++ b/azure-pipelines/build.bash
@@ -1,5 +1,6 @@
#!/bin/bash
set -ex
python -m pip install --upgrade pip
-pip install cibuildwheel==$CIBUILDWHEEL_VERSION
-cibuildwheel --output-dir wheelhouse .
+pip install cibuildwheel==$CIBUILDWHEEL_VERSION || \
+ pip install git+git://github.com/joerick/cibuildwheel.git@$CIBUILDWHEEL_VERSION
+cibuildwheel --output-dir dist .
diff --git a/debian/changelog b/debian/changelog
index d1fae08..499aaa8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+pikepdf (1.7.0+dfsg-1) unstable; urgency=medium
+
+ * New upstream release.
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Tue, 12 Nov 2019 09:40:42 -0700
+
pikepdf (1.6.5+dfsg-1) unstable; urgency=medium
* New upstream release.
diff --git a/docs/installation.rst b/docs/installation.rst
index 2ae0d7a..28af78a 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -116,8 +116,7 @@ Building from source
pikepdf requires:
-- a C++11 compliant compiler - GCC (4.8 and up) and clang (3.3 and up); C++14
- is recommended and will produced smaller binaries
+- a C++14 compliant compiler - GCC (5 and up) and clang (3.3 and up)
- `pybind11 <https://github.com/pybind/pybind11>`_
- libqpdf |qpdf-version| or higher from the
`QPDF <https://github.com/qpdf/qpdf>`_ project.
@@ -152,7 +151,7 @@ libqpdf.)
.. |msvc-zip| replace:: qpdf-|qpdf-version|-bin-msvc64.zip
-pikepdf requires a C++11 compliant compiler (i.e. Visual Studio 2015 on
+pikepdf requires a C++14 compliant compiler (i.e. Visual Studio 2015 on
Windows). See our continuous integration build script in ``.appveyor.yml``
for detailed and current instructions. Or use the wheels which save this pain.
diff --git a/docs/release_notes.rst b/docs/release_notes.rst
index c306f13..713fcea 100644
--- a/docs/release_notes.rst
+++ b/docs/release_notes.rst
@@ -18,11 +18,20 @@ is in production use. Note that the C++ extension module
``pikepdf._qpdf`` is a private interface within pikepdf that applications
should not access directly, along with any modules with a prefixed underscore.
+v1.7.0
+======
+
+- Shallow object copy with ``copy.copy(pikepdf.Object)`` is now supported.
+- Support for building on C++11 has been removed. A C++14 compiler is now required.
+- pikepdf now generates manylinux2010 wheels on Linux.
+- Build and deploy infrastructure migrated to Azure Pipelines.
+- All wheels are now available for Python 3.5 through 3.8.
+
v1.6.5
======
- Fixed build settings to support Python 3.8 on macOS and Linux. Windows support
- for Python 3.8 is not currently available since continuous integration providers
+ for Python 3.8 is not currently tested since continuous integration providers
have not updated to Python 3.8 yet.
- pybind11 2.4.3 is now required, to support Python 3.8.
diff --git a/setup.py b/setup.py
index 8f55f90..7b39a67 100644
--- a/setup.py
+++ b/setup.py
@@ -74,17 +74,17 @@ def has_flag(compiler, flagname):
def cpp_flag(compiler):
- """Return the -std=c++[11/14] compiler flag.
+ """Return the -std=c++[XX] compiler flag.
Notes on c++17 and macOS:
https://github.com/pybind/python_example/issues/44
"""
- flags = ['-std=c++14', '-std=c++11']
+ flags = ['-std=c++14']
for flag in flags:
if has_flag(compiler, flag):
return flag
- raise RuntimeError('Unsupported compiler -- at least C++11 support ' 'is needed!')
+ raise RuntimeError('Unsupported compiler -- at least C++14 support ' 'is needed!')
class BuildExt(build_ext):
@@ -94,7 +94,7 @@ class BuildExt(build_ext):
l_opts = {'msvc': [], 'unix': []}
if sys.platform == 'darwin':
- darwin_opts = ['-stdlib=libc++', '-mmacosx-version-min=10.7']
+ darwin_opts = ['-stdlib=libc++', '-mmacosx-version-min=10.9']
c_opts['unix'] += darwin_opts
l_opts['unix'] += darwin_opts
diff --git a/src/qpdf/object.cpp b/src/qpdf/object.cpp
index 0aed39b..190bf97 100644
--- a/src/qpdf/object.cpp
+++ b/src/qpdf/object.cpp
@@ -302,6 +302,11 @@ void init_object(py::module& m)
return py::bool_(result);
}
)
+ .def("__copy__",
+ [](QPDFObjectHandle &h) {
+ return h.shallowCopy();
+ }
+ )
.def("__len__",
[](QPDFObjectHandle &h) {
if (h.isDictionary())
diff --git a/src/qpdf/pikepdf.h b/src/qpdf/pikepdf.h
index 5fa9e53..3499847 100644
--- a/src/qpdf/pikepdf.h
+++ b/src/qpdf/pikepdf.h
@@ -12,8 +12,6 @@
#include <vector>
#include <map>
-#include "shims.h"
-
#include <qpdf/PointerHolder.hh>
#include <qpdf/QPDF.hh>
#include <qpdf/QPDFObjectHandle.hh>
diff --git a/src/qpdf/shims.cpp b/src/qpdf/shims.cpp
deleted file mode 100644
index 0020f12..0000000
--- a/src/qpdf/shims.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright (C) 2017, James R. Barlow (https://github.com/jbarlow83/)
- */
-
-/* Support for features missing from C++11, minimal versions */
-
-#if __cplusplus < 201402L // If C++11
-
-#include <string>
-#include <sstream>
-
-#include "pikepdf.h"
-
-namespace std {
-
-string quoted(const string &s)
-{
- stringstream ss;
- ss << '"';
- for (const char &c : s) {
- if (c == '"') {
- ss << "\\\"";
- } else if (c == '\\') {
- ss << "\\\\";
- } else {
- ss << c;
- }
- }
- ss << '"';
- return ss.str();
-}
-
-string quoted(const char* s)
-{
- return quoted(string(s));
-}
-
-
-};
-
-#endif // End C++11 \ No newline at end of file
diff --git a/src/qpdf/shims.h b/src/qpdf/shims.h
deleted file mode 100644
index 1f14388..0000000
--- a/src/qpdf/shims.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * Copyright (C) 2017, James R. Barlow (https://github.com/jbarlow83/)
- */
-
-#if __cplusplus < 201402L // If C++11
-
-#include <memory>
-#include <type_traits>
-#include <utility>
-#include <string>
-
-namespace std {
- // Provide make_unique for C++11 (not array-capable)
- // See https://stackoverflow.com/questions/17902405/how-to-implement-make-unique-function-in-c11/17902439#17902439 for full version if needed
- template<typename T, typename ...Args>
- unique_ptr<T> make_unique( Args&& ...args )
- {
- return unique_ptr<T>( new T( std::forward<Args>(args)... ) );
- }
-
- // Provide basic std::quoted for C++11
- string quoted(const char* s);
- string quoted(const string &s);
-};
-
-#endif // }}
diff --git a/tests/test_object.py b/tests/test_object.py
index d100ed6..55cb314 100644
--- a/tests/test_object.py
+++ b/tests/test_object.py
@@ -1,5 +1,6 @@
import json
import sys
+from copy import copy
from decimal import Decimal, InvalidOperation
from math import isclose, isfinite
from zlib import compress
@@ -465,3 +466,20 @@ class TestStreamReadWrite:
def test_stream_bytes(self, stream_object):
stream_object.write(b'pi')
assert bytes(stream_object) == b'pi'
+
+
+def test_copy():
+ d = Dictionary(
+ {
+ '/Boolean': True,
+ '/Integer': 42,
+ '/Real': Decimal('42.42'),
+ '/String': String('hi'),
+ '/Array': Array([1, 2, 3.14]),
+ '/Dictionary': Dictionary({'/Color': 'Red'}),
+ }
+ )
+ d2 = copy(d)
+ assert d2 == d
+ assert d2 is not d
+ assert d2['/Dictionary'] == d['/Dictionary']
diff --git a/tests/test_pages.py b/tests/test_pages.py
index c3b2ec9..a6d0053 100644
--- a/tests/test_pages.py
+++ b/tests/test_pages.py
@@ -250,7 +250,6 @@ def test_negative_indexing(fourpages, graph):
def test_concatenate(resources, outdir):
# Issue #22
def concatenate(n):
- print('concatenating same page', n, 'times')
output_pdf = Pdf.new()
for i in range(n):
print(i)
@@ -268,3 +267,43 @@ def test_emplace(fourpages):
assert fourpages.pages[0].keys() == fourpages.pages[1].keys()
for k in fourpages.pages[0].keys():
assert fourpages.pages[0][k] == fourpages.pages[1][k]
+
+
+def test_duplicate_page(sandwich, outpdf):
+ sandwich.pages.append(sandwich.pages[0])
+ assert len(sandwich.pages) == 2
+ sandwich.save(outpdf)
+
+
+def test_repeat_using_intermediate(graph, outpdf):
+ def _repeat_page(pdf_in, page, count, pdf_out):
+ for dup in range(count):
+ pdf_new = Pdf.new()
+ pdf_new.pages.append(pdf_in.pages[page])
+ pdf_out.pages.extend(pdf_new.pages)
+ return pdf_out
+
+ with Pdf.new() as out:
+ _repeat_page(graph, 0, 3, out)
+ assert len(out.pages) == 3
+ out.save(outpdf)
+
+
+def test_repeat(graph, outpdf):
+ def _repeat_page(pdf, page, count):
+ for dup in range(count):
+ pdf.pages.append(pdf.pages[page])
+ return pdf
+
+ _repeat_page(graph, 0, 3)
+ assert len(graph.pages) == 4
+ graph.save(outpdf)
+
+
+def test_add_foreign_twice(graph, outpdf):
+ out = Pdf.new()
+ out.pages.append(out.copy_foreign(graph.pages[0]))
+ assert len(out.pages) == 1
+ out.pages.append(out.copy_foreign(graph.pages[0]))
+ assert len(out.pages) == 2
+ out.save(outpdf)