[Python-modules-commits] [pycurl] 123/140: Import pycurl_7.19.3.1.orig.tar.gz
Barry Warsaw
barry at moszumanska.debian.org
Wed Oct 1 21:45:16 UTC 2014
This is an automated email from the git hooks/post-receive script.
barry pushed a commit to branch master
in repository pycurl.
commit 8e6f1b9f15258f380b8f8d7252c8c1a6dfe32900
Author: Barry Warsaw <barry at python.org>
Date: Wed Oct 1 16:44:08 2014 -0400
Import pycurl_7.19.3.1.orig.tar.gz
---
AUTHORS | 46 ++
ChangeLog | 16 +
INSTALL | 94 ----
INSTALL.rst | 148 +++++++
MANIFEST.in | 5 +-
Makefile | 14 +-
PKG-INFO | 2 +-
README.rst | 58 +--
RELEASE-NOTES.rst | 7 +
doc/callbacks.html | 147 -------
doc/callbacks.rst | 122 ++++++
doc/curlmultiobject.html | 135 ------
doc/curlmultiobject.rst | 104 +++++
doc/curlobject.html | 132 ------
doc/curlobject.rst | 95 ++++
doc/curlshareobject.html | 53 ---
doc/curlshareobject.rst | 29 ++
doc/pycurl.html | 138 ------
doc/pycurl.rst | 114 +++++
doc/release-process.rst | 25 +-
setup.py | 535 +++++++++++++----------
src/pycurl.c | 56 +--
tests/app.py | 25 +-
tests/fake-curl/curl-config-empty | 15 +
tests/fake-curl/curl-config-libs-and-static-libs | 17 +
tests/fake-curl/curl-config-ssl-feature-only | 18 +
tests/fake-curl/curl-config-ssl-in-libs | 14 +
tests/fake-curl/curl-config-ssl-in-static-libs | 17 +
tests/ftp_test.py | 4 +-
tests/multi_option_constants_test.py | 24 +
tests/setup_test.py | 103 +++++
winbuild.py | 4 +-
32 files changed, 1267 insertions(+), 1049 deletions(-)
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..01d2a8e
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,46 @@
+Copyright (C) 2001-2008 by Kjetil Jacobsen <kjetilja at gmail.com>
+Copyright (C) 2001-2008 by Markus F.X.J. Oberhumer <markus at oberhumer.com>
+Copyright (C) 2013-2014 by Oleg Pudeyev <oleg at bsdpower.com>
+
+Please see README, COPYING-LGPL and COPYING-MIT for license information.
+
+The following individuals contributed code to PycURL:
+
+Aaron Hill <visine19 at hotmail.com>
+Adam Guthrie <therigu at users.sourceforge.net>
+Adam Jacob Muller <adam at isprime.com>
+Amit Mongia <amit_mongia at hotmail.com>
+Andjelko Horvat <comel at vingd.com>
+Bastian Kleineidam
+Christopher Warner <cwarner at kernelcode.com>
+Conrad Steenberg <conrad at hep.caltech.edu>
+Daniel Pena Arteaga <dpena at ph.tum.de>
+Domenico Andreoli <cavok at libero.it>
+Dominique <curl-and-python at d242.net>
+Eric S. Raymond <esr at thyrsus.com>
+Gisle Vanem <gvanem at yahoo.no>
+Jakob Truelsen <jakob at scalgo.com>
+Jayne <corvine at gmail.com>
+Jim Patterson
+K.S.Sreeram <sreeram at tachyontech.net>
+Kamil Dudka <kdudka at redhat.com>
+Kevin Ko <kevin.s.ko at gmail.com>
+Marcelo Jorge Vieira <metal at alucinados.com>
+Marien Zwart
+Mark Eichin
+Martin Muenstermann <mamuema at sourceforge.net>
+Matt King <matt at gnik.com>
+Nick Pilon <npilon at oreilly.com>
+Oskari Saarenmaa <os at ohmu.fi>
+Paul Pacheco
+Roland Sommer <rol at ndsommer.de>
+Romuald Brunet <romuald at gandi.net>
+Romulo A. Ceccon <romuloceccon at gmail.com>
+Thomas Hunger <teh at camvine.org>
+Tino Lange <Tino.Lange at gmx.de>
+Tom Pierce <tom.pierce0 at gmail.com>
+Victor Lascurain <bittor at eleka.net>
+Wim Lewis
+Yuhui H <eyecat at gmail.com>
+Yuri Ushakov <yuri.ushakov at gmail.com>
+Zdenek Pavlas <zpavlas at redhat.com>
diff --git a/ChangeLog b/ChangeLog
index 3c90a29..ee89790 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+Version 7.19.3.1 [requires libcurl-7.19.0 or better] - 2014-02-05
+-----------------------------------------------------------------
+
+ * Added --avoid-stdio setup.py option to avoid passing FILE
+ pointers from Python to libcurl. Applies to Python 2 only.
+
+ * Added CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE,
+ CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE, CURLMOPT_MAX_HOST_CONNECTIONS
+ CURLMOPT_MAX_PIPELINE_LENGTH, CURLMOPT_MAX_TOTAL_CONNECTIONS
+ multi options (patch by Jakob Truelsen).
+
+ * SSL detection logic changed to consult `curl-config --static-libs`
+ even if `curl-config --libs` succeeded. This should achieve
+ pre-7.19.3 behavior with respect to automatic SSL detection
+ (patch by Andjelko Horvat).
+
Version 7.19.3 [requires libcurl-7.19.0 or better] - 2014-01-09
---------------------------------------------------------------
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 4440e7a..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,94 +0,0 @@
-NOTE: You need Python and libcurl installed on your system to use or
-build pycurl. Some RPM distributions of curl/libcurl do not include
-everything necessary to build pycurl, in which case you need to
-install the developer specific RPM which is usually called curl-dev.
-
-
-Distutils
----------
-
-Build and install pycurl with the following commands:
-
- (if necessary, become root)
- tar -zxvf pycurl-$VER.tar.gz
- cd pycurl-$VER
- python setup.py install
-
-$VER should be substituted with the pycurl version number, e.g. 7.10.5.
-
-Note that the installation script assumes that 'curl-config' can be
-located in your path setting. If curl-config is installed outside
-your path or you want to force installation to use a particular
-version of curl-config, use the '--curl-config' commandline option to
-specify the location of curl-config. Example:
-
- python setup.py install --curl-config=/usr/local/bin/curl-config
-
-If libcurl is linked dynamically with pycurl, you may have to alter the
-LD_LIBRARY_PATH environment variable accordingly. This normally
-applies only if there is more than one version of libcurl installed,
-e.g. one in /usr/lib and one in /usr/local/lib.
-
-
-easy_install / pip
-----------------
-
- easy_install pycurl
- pip install pycurl
-
-If you need to specify an alternate curl-config, it can be done via an
-environment variable:
-
- export PYCURL_CURL_CONFIG=/usr/local/bin/curl-config
- easy_install pycurl
-
-The same applies to the SSL backend, if you need to specify it (see the SSL
-section below):
-
- export PYCURL_SSL_LIBRARY=openssl
- easy_install pycurl
-
-
-SSL
----
-
-PycURL has locks around crypto functions. In order to compile correct locking
-code, it has to know which SSL library is going to be used by libcurl at
-runtime. setup.py will attempt to automatically detect the SSL library that
-libcurl uses, but this does not always work. In the cases when setup.py cannot
-figure out the SSL library, it must be provided via --with-ssl/--with-gnutls/
---with-nss arguments, just like libcurl's configure script uses, or via
-PYCURL_SSL_LIBRARY=openssl|gnutls|nss environment variable.
-
-Please note the difference in spelling that concerns OpenSSL: the command-line
-argument is --with-ssl, to match libcurl, but the environment variable value is
-"openssl".
-
-
-Windows
--------
-
-First, you will need to obtain dependencies. These can be precompiled binaries
-or source packages that you are going to compile yourself.
-
-For a minimum build you will just need libcurl source. Follow its Windows
-build instructions to build either a static or a DLL version of the library,
-then configure PycURL as follows to use it:
-
- python setup.py --curl-dir=c:\dev\curl-7.33.0\builds\libcurl-vc-x86-release-dll-ipv6-sspi-spnego-winssl --use-libcurl-dll
-
-Note that --curl-dir does not point to libcurl source but rather to headers
-and compiled libraries.
-
-Additional Windows setup.py options:
-
---use-libcurl-dll - build against libcurl DLL, if not given PycURL will be built
-against libcurl statically.
-
---libcurl-lib-name=libcurl_imp.lib - specify a different name for libcurl
-import library. The default is libcurl.lib which is appropriate for static
-linking and is sometimes the correct choice for dynamic linking as well. The
-other possibility for dynamic linking is libcurl_imp.lib.
-
-A good setup.py target to use is bdist_wininst which produces an executable
-installer that you can run to install PycURL.
diff --git a/INSTALL.rst b/INSTALL.rst
new file mode 100644
index 0000000..e40903f
--- /dev/null
+++ b/INSTALL.rst
@@ -0,0 +1,148 @@
+PycURL Installation
+===================
+
+NOTE: You need Python and libcurl installed on your system to use or
+build pycurl. Some RPM distributions of curl/libcurl do not include
+everything necessary to build pycurl, in which case you need to
+install the developer specific RPM which is usually called curl-dev.
+
+
+Distutils
+---------
+
+Build and install pycurl with the following commands::
+
+ (if necessary, become root)
+ tar -zxvf pycurl-$VER.tar.gz
+ cd pycurl-$VER
+ python setup.py install
+
+$VER should be substituted with the pycurl version number, e.g. 7.10.5.
+
+Note that the installation script assumes that 'curl-config' can be
+located in your path setting. If curl-config is installed outside
+your path or you want to force installation to use a particular
+version of curl-config, use the '--curl-config' command line option to
+specify the location of curl-config. Example::
+
+ python setup.py install --curl-config=/usr/local/bin/curl-config
+
+If libcurl is linked dynamically with pycurl, you may have to alter the
+LD_LIBRARY_PATH environment variable accordingly. This normally
+applies only if there is more than one version of libcurl installed,
+e.g. one in /usr/lib and one in /usr/local/lib.
+
+PycURL requires that the SSL library that it is built against is the same
+one libcurl, and therefore PycURL, uses at runtime. PycURL's ``setup.py``
+uses ``curl-config`` to attempt to figure out which SSL library libcurl
+was compiled against, however this does not always work. If PycURL is unable
+to determine the SSL library in use it will print a warning similar to
+the following::
+
+ src/pycurl.c:137:4: warning: #warning "libcurl was compiled with SSL support, but configure could not determine which " "library was used; thus no SSL crypto locking callbacks will be set, which may " "cause random crashes on SSL requests" [-Wcpp]
+
+It will then fail at runtime as follows::
+
+ ImportError: pycurl: libcurl link-time ssl backend (openssl) is different from compile-time ssl backend (none/other)
+
+To fix this, you need to tell ``setup.py`` what SSL backend is used::
+
+ python setup.py --with-[ssl|gnutls|nss] install
+
+
+easy_install / pip
+------------------
+
+::
+
+ easy_install pycurl
+ pip install pycurl
+
+If you need to specify an alternate curl-config, it can be done via an
+environment variable::
+
+ export PYCURL_CURL_CONFIG=/usr/local/bin/curl-config
+ easy_install pycurl
+
+The same applies to the SSL backend, if you need to specify it (see the SSL
+note above)::
+
+ export PYCURL_SSL_LIBRARY=[openssl|gnutls|nss]
+ easy_install pycurl
+
+Please note the difference in spelling that concerns OpenSSL: the command-line
+argument is --with-ssl, to match libcurl, but the environment variable value is
+"openssl".
+
+
+Windows
+-------
+
+First, you will need to obtain dependencies. These can be precompiled binaries
+or source packages that you are going to compile yourself.
+
+For a minimum build you will just need libcurl source. Follow its Windows
+build instructions to build either a static or a DLL version of the library,
+then configure PycURL as follows to use it::
+
+ python setup.py --curl-dir=c:\dev\curl-7.33.0\builds\libcurl-vc-x86-release-dll-ipv6-sspi-spnego-winssl --use-libcurl-dll
+
+Note that ``--curl-dir`` does not point to libcurl source but rather to headers
+and compiled libraries.
+
+If libcurl and Python are not linked against the same exact C runtime
+(version number, static/dll, single-threaded/multi-threaded) you must use
+``--avoid-stdio`` option (see below).
+
+Additional Windows setup.py options:
+
+- ``--use-libcurl-dll``: build against libcurl DLL, if not given PycURL will
+ be built against libcurl statically.
+- ``--libcurl-lib-name=libcurl_imp.lib``: specify a different name for libcurl
+ import library. The default is ``libcurl.lib`` which is appropriate for
+ static linking and is sometimes the correct choice for dynamic linking as
+ well. The other possibility for dynamic linking is ``libcurl_imp.lib``.
+- ``--avoid-stdio``: on windows, a process and each library it is using
+ may be linked to its own version of the C runtime (msvcrt).
+ FILE pointers from one C runtime may not be passed to another C runtime.
+ This option prevents direct passing of FILE pointers from Python to libcurl,
+ thus permitting Python and libcurl to be linked against different C runtimes.
+ This option may carry a performance penalty when Python file objects are
+ given directly to PycURL in CURLOPT_READDATA, CURLOPT_WRITEDATA or
+ CURLOPT_WRITEHEADER options. This option applies only on Python 2; on
+ Python 3, file objects no longer expose C library FILE pointers and the
+ C runtime issue does not exist. On Python 3, this option is recognized but
+ does nothing. You can also give ``--avoid-stdio`` option in
+ PYCURL_SETUP_OPTIONS environment variable as follows::
+
+ PYCURL_SETUP_OPTIONS=--avoid-stdio pip install pycurl
+
+A good ``setup.py`` target to use is ``bdist_wininst`` which produces an
+executable installer that you can run to install PycURL.
+
+You may find the following mailing list posts helpful:
+
+- http://curl.haxx.se/mail/curlpython-2009-11/0010.html
+- http://curl.haxx.se/mail/curlpython-2013-11/0002.html
+
+
+winbuild.py
+^^^^^^^^^^^
+
+This script is used to build official PycURL Windows packages. You can
+use it to build a full complement of packages with your own options or modify
+it to build a single package you need.
+
+Prerequisites:
+
+- msysgit_.
+- Appropriate `Python versions`_ installed.
+- MS Visual C++ 9/2008 for Python <= 3.2, MS Visual C++ 10/2010 for
+ Python >= 3.3. Express versions of Visual Studio work fine for this.
+
+.. _msysgit: http://msysgit.github.io/
+.. _Python versions: http://python.org/download/
+
+``winbuild.py`` assumes all programs are installed in their default locations,
+if this is not the case edit it as needed. ``winbuild.py`` can be run
+with Python 2.6, 2.7, 3.2 or 3.3.
diff --git a/MANIFEST.in b/MANIFEST.in
index 25f8ffa..24031e1 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -3,15 +3,15 @@
# Manifest template for creating the source distribution.
#
+include AUTHORS
include COPYING-LGPL
include COPYING-MIT
include ChangeLog
-include INSTALL
+include INSTALL.rst
include MANIFEST.in
include Makefile
include README.rst
include RELEASE-NOTES.rst
-include doc/*.html
include doc/*.rst
include examples/*.py
include examples/tests/*.py
@@ -23,6 +23,7 @@ include tests/*.py
include tests/certs/*.crt
include tests/certs/*.key
include tests/ext/*.sh
+include tests/fake-curl/*
include tests/matrix/*.patch
include tests/vsftpd.conf
include winbuild.py
diff --git a/Makefile b/Makefile
index 082af4f..c45a310 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ all build:
build-7.10.8:
$(PYTHON) setup.py build --curl-config=/home/hosts/localhost/packages/curl-7.10.8/bin/curl-config
-test: build
+do-test:
mkdir -p tests/tmp
PYTHONSUFFIX=$$(python -V 2>&1 |awk '{print $$2}' |awk -F. '{print $$1 "." $$2}') && \
PYTHONPATH=$$(ls -d build/lib.*$$PYTHONSUFFIX):$$PYTHONPATH \
@@ -23,6 +23,8 @@ test: build
$(NOSETESTS)
./tests/ext/test-suite.sh
+test: build do-test
+
# (needs GNU binutils)
strip: build
strip -p --strip-unneeded build/lib*/*.so
@@ -60,11 +62,13 @@ windist: distclean
python2.4 setup_win32_ssl.py bdist_wininst
rm -rf build
-docs:
- cd doc && for file in *.rst; do rst2html "$$file" ../www/htdocs/doc/`echo "$$file" |sed -e 's/.rst$$/.html/'`; done
- rst2html RELEASE-NOTES.rst www/htdocs/release-notes.html
+www docs:
+ mkdir -p build
+ rsync -av www build
+ cd doc && for file in *.rst; do rst2html "$$file" ../build/www/htdocs/doc/`echo "$$file" |sed -e 's/.rst$$/.html/'`; done
+ rst2html RELEASE-NOTES.rst build/www/htdocs/release-notes.html
-.PHONY: all build test strip install install_lib clean distclean maintainer-clean dist sdist windist
+.PHONY: all build test do-test strip install install_lib clean distclean maintainer-clean dist sdist windist
.NOEXPORT:
diff --git a/PKG-INFO b/PKG-INFO
index 86f09b9..c43896d 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pycurl
-Version: 7.19.3
+Version: 7.19.3.1
Summary: PycURL -- cURL library module for Python
Home-page: http://pycurl.sourceforge.net/
Author: Oleg Pudeyev
diff --git a/README.rst b/README.rst
index 2d8277d..1f9dd50 100644
--- a/README.rst
+++ b/README.rst
@@ -46,63 +46,7 @@ Requirements
Installation
------------
-You can install the most recent PycURL version using `easy_install`_::
-
- easy_install pycurl
-
-or `pip`_::
-
- pip install pycurl
-
-Installing from source is performed via ``setup.py``::
-
- python setup.py install
-
-You will need libcurl headers and libraries installed to install PycURL
-from source. PycURL uses ``curl-config`` to determine correct flags/libraries
-to use during compilation; you can override the location of ``curl-config``
-if it is not in PATH or you want to use a custom libcurl installation::
-
- python setup.py --curl-config=/path/to/curl-config install
-
-Sometimes it is more convenient to use an environment variable, if
-you are not directly invoking ``setup.py``::
-
- PYCURL_CURL_CONFIG=/path/to/curl-config python setup.py install
-
-``curl-config`` is expected to support the following options:
-
-- ``--version``
-- ``--cflags``
-- ``--libs``
-- ``--static-libs`` (if ``--libs`` does not work)
-
-PycURL requires that the SSL library that it is built against is the same
-one libcurl, and therefore PycURL, uses at runtime. PycURL's ``setup.py``
-uses ``curl-config`` to attempt to figure out which SSL library libcurl
-was compiled against, however this does not always work. If PycURL is unable
-to determine the SSL library in use it will print a warning similar to
-the following::
-
- src/pycurl.c:137:4: warning: #warning "libcurl was compiled with SSL support, but configure could not determine which " "library was used; thus no SSL crypto locking callbacks will be set, which may " "cause random crashes on SSL requests" [-Wcpp]
-
-It will then fail at runtime as follows::
-
- ImportError: pycurl: libcurl link-time ssl backend (openssl) is different from compile-time ssl backend (none/other)
-
-To fix this, you need to tell ``setup.py`` what SSL backend is used::
-
- python setup.py --with-[ssl|gnutls|nss] install
-
-Or use an environment variable::
-
- PYCURL_SSL_LIBRARY=openssl|gnutls|nss python setup.py installl
-
-Note the difference between ``--with-ssl`` (for compatibility with libcurl) and
-``PYCURL_SSL_LIBRARY=openssl``.
-
-.. _easy_install: http://peak.telecommunity.com/DevCenter/EasyInstall
-.. _pip: http://pypi.python.org/pypi/pip
+Please see README.rst for installation instructions.
Support
-------
diff --git a/RELEASE-NOTES.rst b/RELEASE-NOTES.rst
index c89466c..7fdd74b 100644
--- a/RELEASE-NOTES.rst
+++ b/RELEASE-NOTES.rst
@@ -1,6 +1,13 @@
Release Notes
=============
+PycURL 7.19.3.1 - 2014-02-05
+----------------------------
+
+This release restores PycURL's ability to automatically detect SSL library
+in use in most circumstances, thanks to Andjelko Horvat.
+
+
PycURL 7.19.3 - 2014-01-09
--------------------------
diff --git a/doc/callbacks.html b/doc/callbacks.html
deleted file mode 100644
index 83b1445..0000000
--- a/doc/callbacks.html
+++ /dev/null
@@ -1,147 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <title>PyCurl: Callbacks</title>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <meta name="revisit-after" content="30 days" />
- <meta name="robots" content="noarchive, index, follow" />
-</head>
-<body>
-
-<h1>Callbacks</h1>
-
-<p>For more fine-grained control, libcurl allows a
-number of callbacks to be associated with each connection. In
-pycurl, callbacks are defined using the <code>setopt()</code> method for
-Curl objects with options WRITEFUNCTION, READFUNCTION, HEADERFUNCTION,
-PROGRESSFUNCTION, IOCTLFUNCTION, or DEBUGFUNCTION. These options
-correspond to the libcurl options with CURLOPT_* prefix removed. A
-callback in pycurl must be either a regular Python function, a class
-method or an extension type function.</p>
-
-<p>There are some limitations to some of the options which can be used
-concurrently with the pycurl callbacks compared to the libcurl callbacks.
-This is to allow different callback functions to be associated with
-different Curl objects. More specifically, WRITEDATA cannot
-be used with WRITEFUNCTION, READDATA cannot be used with READFUNCTION,
-WRITEHEADER cannot be used with HEADERFUNCTION, PROGRESSDATA cannot be
-used with PROGRESSFUNCTION, IOCTLDATA cannot be used with IOCTLFUNCTION,
-and DEBUGDATA cannot be used with DEBUGFUNCTION.
-In practice, these limitations can be overcome by having a callback
-function be a class instance method and rather use the class instance
-attributes to store per object data such as files used in the callbacks.
-</p>
-
-The signature of each callback used in pycurl is as follows:<br/>
-<br/>
-<code>WRITEFUNCTION(</code><em>string</em><code>) </code><em>-> number of characters written<br/>
-</em>
-<br/>
-<code>READFUNCTION(</code><em>number of characters to read</em><code>)</code><em>->
-string</em><br/>
-<br/>
-<code>HEADERFUNCTION(</code><em>string</em><code>)</code><em> -> number of characters written<br/>
-</em><br/>
-<code>PROGRESSFUNCTION(</code><em>download total, downloaded, upload total, uploaded</em><code>) </code><em>-> status</em><br/>
-<br/>
-<code>DEBUGFUNCTION(</code><em>debug message type, debug message string</em><code>)</code>
-<em>-> None<br/></em>
-<br/>
-<code>IOCTLFUNCTION(</code><em>ioctl cmd</em><code>)</code>
-<em>-> status<br/></em>
-<br/>
-
-<p>In addition, <code>READFUNCTION</code> may return
-<code>READFUNC_ABORT</code> or <code>READFUNC_PAUSE</code>. See the libcurl
-documentation for an explanation of these values.
-The <code>WRITEFUNCTION</code> and <code>HEADERFUNCTION</code> callbacks
-may return <code>None</code>, which is an alternate way of indicating that
-the callback has consumed all of the string passed to it.</p>
-
-<hr/>
-
-<h2>Example: Callbacks for document header and body</h2>
-
-<p>This example prints the header data to stderr and the body data to
-stdout. Also note that neither callback returns the number of bytes
-written. For WRITEFUNCTION and HEADERFUNCTION callbacks, returning
-None implies that all bytes where written.</p>
-
-<pre>
- ## Callback function invoked when body data is ready
- def body(buf):
- # Print body data to stdout
- import sys
- sys.stdout.write(buf)
- # Returning None implies that all bytes were written
-
- ## Callback function invoked when header data is ready
- def header(buf):
- # Print header data to stderr
- import sys
- sys.stderr.write(buf)
- # Returning None implies that all bytes were written
-
- c = pycurl.Curl()
- c.setopt(pycurl.URL, "http://www.python.org/")
- c.setopt(pycurl.WRITEFUNCTION, body)
- c.setopt(pycurl.HEADERFUNCTION, header)
- c.perform()
-</pre>
-
-<h2>Example: Download/upload progress callback</h2>
-
-<p>This example shows how to use the progress callback. When downloading
-a document, the arguments related to uploads are zero, and vice versa.</p>
-
-<pre>
- ## Callback function invoked when download/upload has progress
- def progress(download_t, download_d, upload_t, upload_d):
- print "Total to download", download_t
- print "Total downloaded", download_d
- print "Total to upload", upload_t
- print "Total uploaded", upload_d
-
- c.setopt(c.URL, "http://slashdot.org/")
- c.setopt(c.NOPROGRESS, 0)
- c.setopt(c.PROGRESSFUNCTION, progress)
- c.perform()
-</pre>
-
-<h2>Example: Debug callbacks</h2>
-
-<p>This example shows how to use the debug callback. The debug message
-type is an integer indicating the type of debug message. The
-VERBOSE option must be enabled for this callback to be invoked.</p>
-
-<pre>
- def test(debug_type, debug_msg):
- print "debug(%d): %s" % (debug_type, debug_msg)
-
- c = pycurl.Curl()
- c.setopt(pycurl.URL, "http://curl.haxx.se/")
- c.setopt(pycurl.VERBOSE, 1)
- c.setopt(pycurl.DEBUGFUNCTION, test)
- c.perform()
-</pre>
-
-<h2>Other examples</h2>
-<p>The pycurl distribution also contains a number of test scripts and
-examples which show how to use the various callbacks in libcurl.
-For instance, the file 'examples/file_upload.py' in the distribution contains
-example code for using READFUNCTION, 'tests/test_cb.py' shows
-WRITEFUNCTION and HEADERFUNCTION, 'tests/test_debug.py' shows DEBUGFUNCTION,
-and 'tests/test_getinfo.py' shows PROGRESSFUNCTION.</p>
-
-
-<hr />
-<p>
- <a href="http://validator.w3.org/check/referer"><img align="right"
- src="http://www.w3.org/Icons/valid-xhtml10"
- alt="Valid XHTML 1.0!" height="31" width="88" border="0" /></a>
-</p>
-
-</body>
-</html>
diff --git a/doc/callbacks.rst b/doc/callbacks.rst
new file mode 100644
index 0000000..bfe1835
--- /dev/null
+++ b/doc/callbacks.rst
@@ -0,0 +1,122 @@
+Callbacks
+=========
+
+For more fine-grained control, libcurl allows a number of callbacks to be
+associated with each connection. In pycurl, callbacks are defined using the
+``setopt()`` method for Curl objects with options WRITEFUNCTION,
+READFUNCTION, HEADERFUNCTION, PROGRESSFUNCTION, IOCTLFUNCTION, or
+DEBUGFUNCTION. These options correspond to the libcurl options with CURLOPT_*
+prefix removed. A callback in pycurl must be either a regular Python
+function, a class method or an extension type function.
+
+There are some limitations to some of the options which can be used
+concurrently with the pycurl callbacks compared to the libcurl callbacks.
+This is to allow different callback functions to be associated with different
+Curl objects. More specifically, WRITEDATA cannot be used with WRITEFUNCTION,
+READDATA cannot be used with READFUNCTION, WRITEHEADER cannot be used with
+HEADERFUNCTION, PROGRESSDATA cannot be used with PROGRESSFUNCTION, IOCTLDATA
+cannot be used with IOCTLFUNCTION, and DEBUGDATA cannot be used with
+DEBUGFUNCTION. In practice, these limitations can be overcome by having a
+callback function be a class instance method and rather use the class
+instance attributes to store per object data such as files used in the
+callbacks.
+
+The signature of each callback used in pycurl is as follows:
+
+**WRITEFUNCTION**\ (*string*) -> *number of characters written*
+
+**READFUNCTION**\ (*number of characters to read*) -> *string*
+
+**HEADERFUNCTION**\ (*string*) -> *number of characters written*
+
+**PROGRESSFUNCTION**\ (*download total, downloaded, upload total,
+uploaded*) -> *status*
+
+**DEBUGFUNCTION**\ (*debug message type, debug message string*) -> *None*
+
+**IOCTLFUNCTION**\ (*ioctl cmd*) -> *status*
+
+In addition, ``READFUNCTION`` may return ``READFUNC_ABORT`` or
+``READFUNC_PAUSE``. See the libcurl documentation for an explanation of these
+values. The ``WRITEFUNCTION`` and ``HEADERFUNCTION`` callbacks may return
+``None``, which is an alternate way of indicating that the callback has
+consumed all of the string passed to it.
+
+Example: Callbacks for document header and body
+-----------------------------------------------
+
+This example prints the header data to stderr and the body data to stdout.
+Also note that neither callback returns the number of bytes written. For
+WRITEFUNCTION and HEADERFUNCTION callbacks, returning None implies that all
+bytes where written.
+
+::
+
+ ## Callback function invoked when body data is ready
+ def body(buf):
+ # Print body data to stdout
+ import sys
+ sys.stdout.write(buf)
+ # Returning None implies that all bytes were written
+
+ ## Callback function invoked when header data is ready
+ def header(buf):
+ # Print header data to stderr
+ import sys
+ sys.stderr.write(buf)
+ # Returning None implies that all bytes were written
+
+ c = pycurl.Curl()
+ c.setopt(pycurl.URL, "http://www.python.org/")
+ c.setopt(pycurl.WRITEFUNCTION, body)
+ c.setopt(pycurl.HEADERFUNCTION, header)
+ c.perform()
+
+Example: Download/upload progress callback
+------------------------------------------
+
+This example shows how to use the progress callback. When downloading a
+document, the arguments related to uploads are zero, and vice versa.
+
+::
+
+ ## Callback function invoked when download/upload has
+ progress
+ def progress(download_t, download_d, upload_t, upload_d):
+ print "Total to download", download_t
+ print "Total downloaded", download_d
+ print "Total to upload", upload_t
+ print "Total uploaded", upload_d
+
+ c.setopt(c.URL, "http://slashdot.org/")
+ c.setopt(c.NOPROGRESS, 0)
+ c.setopt(c.PROGRESSFUNCTION, progress)
+ c.perform()
+
+Example: Debug callbacks
+------------------------
+
+This example shows how to use the debug callback. The debug message type is
+an integer indicating the type of debug message. The VERBOSE option must be
+enabled for this callback to be invoked.
+
+::
+
+ def test(debug_type, debug_msg):
+ print "debug(%d): %s" % (debug_type, debug_msg)
+
+ c = pycurl.Curl()
+ c.setopt(pycurl.URL, "http://curl.haxx.se/")
+ c.setopt(pycurl.VERBOSE, 1)
+ c.setopt(pycurl.DEBUGFUNCTION, test)
+ c.perform()
+
+Other examples
+--------------
+
+The pycurl distribution also contains a number of test scripts and examples
+which show how to use the various callbacks in libcurl. For instance, the
+file 'examples/file_upload.py' in the distribution contains example code for
+using READFUNCTION, 'tests/test_cb.py' shows WRITEFUNCTION and
+HEADERFUNCTION, 'tests/test_debug.py' shows DEBUGFUNCTION, and
+'tests/test_getinfo.py' shows PROGRESSFUNCTION.
diff --git a/doc/curlmultiobject.html b/doc/curlmultiobject.html
deleted file mode 100644
index f14827c..0000000
--- a/doc/curlmultiobject.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <title>PycURL: CurlMulti Objects</title>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <meta name="revisit-after" content="30 days" />
- <meta name="robots" content="noarchive, index, follow" />
-</head>
-<body>
-
-<h1>CurlMulti Object</h1>
-
-<p>CurlMulti objects have the following methods: </p>
-
-<dl>
-<dt><code>close()</code> -> <em>None</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_multi_cleanup.html"><code>curl_multi_cleanup()</code></a> in libcurl.
-This method is automatically called by pycurl when a CurlMulti object no
-longer has any references to it, but can also be called
-explicitly.</p>
-</dd>
-
-<dt><code>perform()</code> -> <em>tuple of status and the number of active Curl objects</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_multi_perform.html"><code>curl_multi_perform()</code></a> in libcurl.</p>
-</dd>
-
-<dt><code>add_handle(</code><em>Curl object</em><code>) </code>-> <em>None</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_multi_add_handle.html"><code>curl_multi_add_handle()</code></a> in libcurl.
-This method adds an existing and valid Curl object to the CurlMulti
-object.</p>
-
-<p>IMPORTANT NOTE: add_handle does not implicitly add a Python reference
-to the Curl object (and thus does not increase the reference count on the Curl
-object).</p>
-</dd>
-
-<dt><code>remove_handle(</code><em>Curl object</em><code>)</code> -> <em>None</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_multi_remove_handle.html"><code>curl_multi_remove_handle()</code></a> in libcurl.
-This method removes an existing and valid Curl object from the CurlMulti
-object.</p>
-
-<p>IMPORTANT NOTE: remove_handle does not implicitly remove a Python reference
-from the Curl object (and thus does not decrease the reference count on the Curl
-object).</p>
-</dd>
-
-<dt><code>fdset()</code> ->
-<em>triple of lists with active file descriptors,
-readable, writeable, exceptions.</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_multi_fdset.html"><code>curl_multi_fdset()</code></a> in libcurl.
-This method extracts the file descriptor information from a CurlMulti object.
-The returned lists can be used with the <code>select</code> module to
-poll for events.</p>
-
-<p>Example usage:</p>
-
-<pre>
-import pycurl
-c = pycurl.Curl()
-c.setopt(pycurl.URL, "http://curl.haxx.se")
-m = pycurl.CurlMulti()
-m.add_handle(c)
-while 1:
- ret, num_handles = m.perform()
- if ret != pycurl.E_CALL_MULTI_PERFORM: break
-while num_handles:
- apply(select.select, m.fdset() + (1,))
- while 1:
- ret, num_handles = m.perform()
- if ret != pycurl.E_CALL_MULTI_PERFORM: break
-</pre>
-</dd>
-
-<dt><code>select(</code><em>timeout</em><code>)</code> ->
-<em>number of ready file descriptors or -1 on timeout</em></dt>
-<dd>
-<p>This is a convenience function which simplifies the combined
-use of <code>fdset()</code> and the <code>select</code> module.</p>
-
-<p>Example usage:</p>
-
-<pre>import pycurl
-c = pycurl.Curl()
-c.setopt(pycurl.URL, "http://curl.haxx.se")
-m = pycurl.CurlMulti()
-m.add_handle(c)
-while 1:
- ret, num_handles = m.perform()
- if ret != pycurl.E_CALL_MULTI_PERFORM: break
-while num_handles:
- ret = m.select(1.0)
- if ret == -1: continue
- while 1:
- ret, num_handles = m.perform()
- if ret != pycurl.E_CALL_MULTI_PERFORM: break
-</pre>
-</dd>
-
-<dt><code>info_read(</code><em>[max]</em><code>)</code> ->
-<em>numberof queued messages, a list of successful objects, a list of
-failed objects</em></dt>
-<dd>
-<p>Corresponds to the
-<a href="http://curl.haxx.se/libcurl/c/curl_multi_info_read.html"><code>curl_multi_info_read()</code></a> function in libcurl.
-This method extracts at most <em>max</em> messages
-from the multi stack and returns them in two lists. The first
-list contains the handles which completed successfully and the second
-list contains a tuple <em><curl object, curl error number, curl
-error message></em> for each failed curl object. The number
-of queued messages after this method has been called is also
-returned.</p>
-</dd>
-</dl>
-
-<hr />
-<p>
- <a href="http://validator.w3.org/check/referer"><img align="right"
- src="http://www.w3.org/Icons/valid-xhtml10"
- alt="Valid XHTML 1.0!" height="31" width="88" border="0" /></a>
-</p>
-
-</body>
-</html>
diff --git a/doc/curlmultiobject.rst b/doc/curlmultiobject.rst
new file mode 100644
index 0000000..f09a8c3
--- /dev/null
+++ b/doc/curlmultiobject.rst
@@ -0,0 +1,104 @@
+CurlMulti Object
+================
+
+CurlMulti objects have the following methods:
+
+**close**\ () -> *None*
+
+Corresponds to `curl_multi_cleanup`_ in libcurl. This method is
+automatically called by pycurl when a CurlMulti object no longer has any
+references to it, but can also be called explicitly.
+
+**perform**\ () -> *tuple of status and the number of active Curl objects*
+
+Corresponds to `curl_multi_perform`_ in libcurl.
+
+**add_handle**\ (*Curl object*) -> *None*
+
+Corresponds to `curl_multi_add_handle`_ in libcurl. This method adds an
+existing and valid Curl object to the CurlMulti object.
+
+IMPORTANT NOTE: add_handle does not implicitly add a Python reference to the
+Curl object (and thus does not increase the reference count on the Curl
+object).
+
+**remove_handle**\ (*Curl object*) -> *None*
+
+Corresponds to `curl_multi_remove_handle`_ in libcurl. This method
+removes an existing and valid Curl object from the CurlMulti object.
+
+IMPORTANT NOTE: remove_handle does not implicitly remove a Python reference
+from the Curl object (and thus does not decrease the reference count on the
+Curl object).
+
+**fdset**\ () -> *triple of lists with active file descriptors, readable,
+writeable, exceptions.*
+
+Corresponds to `curl_multi_fdset`_ in libcurl. This method extracts the
+file descriptor information from a CurlMulti object. The returned lists can
+be used with the ``select`` module to poll for events.
+
+Example usage:
+
+::
+
+ import pycurl
+ c = pycurl.Curl()
+ c.setopt(pycurl.URL, "http://curl.haxx.se")
+ m = pycurl.CurlMulti()
+ m.add_handle(c)
+ while 1:
+ ret, num_handles = m.perform()
+ if ret != pycurl.E_CALL_MULTI_PERFORM: break
+ while num_handles:
+ apply(select.select, m.fdset() + (1,))
+ while 1:
+ ret, num_handles = m.perform()
+ if ret != pycurl.E_CALL_MULTI_PERFORM: break
+
+**select**\ (*timeout*) -> *number of ready file descriptors or -1 on timeout*
+
+This is a convenience function which simplifies the combined use of
+``fdset()`` and the ``select`` module.
+
+Example usage:
+
+::
+
+ import pycurl
+ c = pycurl.Curl()
+ c.setopt(pycurl.URL, "http://curl.haxx.se")
+ m = pycurl.CurlMulti()
+ m.add_handle(c)
+ while 1:
+ ret, num_handles = m.perform()
+ if ret != pycurl.E_CALL_MULTI_PERFORM: break
+ while num_handles:
+ ret = m.select(1.0)
+ if ret == -1: continue
+ while 1:
+ ret, num_handles = m.perform()
+ if ret != pycurl.E_CALL_MULTI_PERFORM: break
+
+**info_read**\ (*[max]*) -> *number of queued messages, a list of
+successful objects, a list of failed objects*
+
+Corresponds to the `curl_multi_info_read`_ function in libcurl. This
+method extracts at most *max* messages from the multi stack and returns them
+in two lists. The first list contains the handles which completed
+successfully and the second list contains a tuple *(curl object, curl error
+number, curl error message)* for each failed curl object. The number of
+queued messages after this method has been called is also returned.
+
+.. _curl_multi_cleanup:
+ http://curl.haxx.se/libcurl/c/curl_multi_cleanup.html
+.. _curl_multi_perform:
+ http://curl.haxx.se/libcurl/c/curl_multi_perform.html
+.. _curl_multi_add_handle:
+ http://curl.haxx.se/libcurl/c/curl_multi_add_handle.html
+.. _curl_multi_remove_handle:
+ http://curl.haxx.se/libcurl/c/curl_multi_remove_handle.html
+.. _curl_multi_fdset:
+ http://curl.haxx.se/libcurl/c/curl_multi_fdset.html
+.. _curl_multi_info_read:
+ http://curl.haxx.se/libcurl/c/curl_multi_info_read.html
diff --git a/doc/curlobject.html b/doc/curlobject.html
deleted file mode 100644
index 0de0730..0000000
--- a/doc/curlobject.html
+++ /dev/null
@@ -1,132 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <title>PycURL: Curl Objects</title>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <meta name="revisit-after" content="30 days" />
- <meta name="robots" content="noarchive, index, follow" />
-</head>
-<body>
-
-<h1>Curl Object</h1>
-
-<p>Curl objects have the following methods:</p>
-
-<dl>
-<dt><code>close()</code> -> <em>None</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_easy_cleanup.html"><code>curl_easy_cleanup</code></a> in libcurl.
-This method is automatically called by pycurl when a Curl object no longer has
-any references to it, but can also be called explicitly.</p>
-</dd>
-
-<dt><code>perform()</code> -> <em>None</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_easy_perform.html"><code>curl_easy_perform</code></a> in libcurl.</p>
-</dd>
-
-<dt><code>reset()</code> -> <em>None</em></dt>
-<dd>
-<p>Corresponds to
-<a
-href="http://curl.haxx.se/libcurl/c/curl_easy_reset.html"><code>curl_easy_reset</code></a> in libcurl.</p>
-</dd>
-
-
-<dt><code>setopt(</code><em>option, value</em><code>)</code> -> <em>None</em></dt>
-<dd>
-
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_easy_setopt.html"><code>curl_easy_setopt</code></a> in libcurl, where
-<em>option</em> is specified with the CURLOPT_* constants in libcurl,
-except that the CURLOPT_ prefix has been removed.
-(See below for exceptions.)
-The type for
-<em>value</em> depends on the option, and can be either a string,
-integer, long integer, file object, list, or function.</p>
-
-<p>Example usage:</p>
-
-<pre>
-import pycurl
-c = pycurl.Curl()
-c.setopt(pycurl.URL, "http://www.python.org/")
-c.setopt(pycurl.HTTPHEADER, ["Accept:"])
-import StringIO
-b = StringIO.StringIO()
-c.setopt(pycurl.WRITEFUNCTION, b.write)
-c.setopt(pycurl.FOLLOWLOCATION, 1)
-c.setopt(pycurl.MAXREDIRS, 5)
-c.perform()
-print b.getvalue()
-...
-</pre>
-</dd>
-
-<dt><code>getinfo(</code><em>option</em><code>) </code>-> <em>Result</em></dt>
-<dd>
-
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html"><code>curl_easy_getinfo</code></a> in libcurl, where
-<em>option</em> is the same as the CURLINFO_* constants in libcurl,
-except that the CURLINFO_ prefix has been removed.
-(See below for exceptions.)
-<em>Result</em> contains an integer, float or string, depending on
-which option is given. The <code>getinfo</code> method should
-not be called unless <code>perform</code> has been called and
-finished.</p>
-
-<p>Example usage:</p>
-
-<pre>
-import pycurl
-c = pycurl.Curl()
-c.setopt(pycurl.URL, "http://sf.net")
-c.setopt(pycurl.FOLLOWLOCATION, 1)
-c.perform()
-print c.getinfo(pycurl.HTTP_CODE), c.getinfo(pycurl.EFFECTIVE_URL)
-...
---> 200 "http://sourceforge.net/"
-</pre>
-</dd>
-
-<dt><code>pause(</code><em>bitmask</em><code>) </code>-> <em>None</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_easy_pause.html"><code>curl_easy_pause</code></a>
-in libcurl. The argument should be derived from
-the <code>PAUSE_RECV</code>, <code>PAUSE_SEND</code>, <code>PAUSE_ALL</code>
-and <code>PAUSE_CONT</code> constants.</p>
-
-<dt><code>errstr()</code> -> <em>String</em></dt>
-<dd>
-<p>Returns the internal libcurl error buffer of this handle as a string.</p>
-</dd>
-</dl>
-
-<p>In order to distinguish between similarly-named CURLOPT and
-CURLINFO constants, some have <code>OPT_</code>
-and <code>INFO_</code> prefixes. These are
-<code>INFO_FILETIME</code>, <code>OPT_FILETIME</code>,
-<code>INFO_COOKIELIST</code> (but <code>setopt</code> uses <code>COOKIELIST</code>!),
-<code>INFO_CERTINFO</code>, and <code>OPT_CERTINFO</code>.</p>
-
-<p>The value returned by <code>getinfo(INFO_CERTINFO)</code> is a list
-with one element per certificate in the chain, starting with the leaf;
-each element is a sequence
-of <code>(</code><em>key</em><code>, </code><em>value</em><code>)</code>
-tuples.</p>
-
-<hr />
-<p>
- <a href="http://validator.w3.org/check/referer"><img align="right"
- src="http://www.w3.org/Icons/valid-xhtml10"
- alt="Valid XHTML 1.0!" height="31" width="88" border="0" /></a>
-</p>
-
-</body>
-</html>
diff --git a/doc/curlobject.rst b/doc/curlobject.rst
new file mode 100644
index 0000000..3720766
--- /dev/null
+++ b/doc/curlobject.rst
@@ -0,0 +1,95 @@
+Curl Object
+===========
+
+Curl objects have the following methods:
+
+**close**\ () -> *None*
+
+Corresponds to `curl_easy_cleanup`_ in libcurl. This method is
+automatically called by pycurl when a Curl object no longer has any
+references to it, but can also be called explicitly.
+
+**perform**\ () -> *None*
+
+Corresponds to `curl_easy_perform`_ in libcurl.
+
+**reset**\ () -> *None*
+
+Corresponds to `curl_easy_reset`_ in libcurl.
+
+**setopt**\ (*option, value*) -> *None*
+
+Corresponds to `curl_easy_setopt`_ in libcurl, where *option* is
+specified with the ``CURLOPT_*`` constants in libcurl, except that the
+``CURLOPT_``
+prefix has been removed. (See below for exceptions.) The type for *value*
+depends on the option, and can be either a string, integer, long integer,
+file object, list, or function.
+
+Example usage:
+
+::
+
+ import pycurl
+ c = pycurl.Curl()
+ c.setopt(pycurl.URL, "http://www.python.org/")
+ c.setopt(pycurl.HTTPHEADER, ["Accept:"])
+ import StringIO
+ b = StringIO.StringIO()
+ c.setopt(pycurl.WRITEFUNCTION, b.write)
+ c.setopt(pycurl.FOLLOWLOCATION, 1)
+ c.setopt(pycurl.MAXREDIRS, 5)
+ c.perform()
+ print b.getvalue()
+ ...
+
+**getinfo**\ (*option*) -> *Result*
+
+Corresponds to `curl_easy_getinfo`_ in libcurl, where *option* is the
+same as the ``CURLINFO_*`` constants in libcurl, except that the ``CURLINFO_``
+prefix
+has been removed. (See below for exceptions.) *Result* contains an integer,
+float or string, depending on which option is given. The ``getinfo`` method
+should not be called unless ``perform`` has been called and finished.
+
+Example usage:
+
+::
+
+ import pycurl
+ c = pycurl.Curl()
+ c.setopt(pycurl.URL, "http://sf.net")
+ c.setopt(pycurl.FOLLOWLOCATION, 1)
+ c.perform()
+ print c.getinfo(pycurl.HTTP_CODE), c.getinfo(pycurl.EFFECTIVE_URL)
+ ...
+ --> 200 "http://sourceforge.net/"
+
+**pause**\ (*bitmask*) -> *None*
+
+Corresponds to `curl_easy_pause`_ in libcurl. The argument should be
+derived from the ``PAUSE_RECV``, ``PAUSE_SEND``, ``PAUSE_ALL`` and
+``PAUSE_CONT`` constants.
+
+**errstr**\ () -> *String*
+
+Returns the internal libcurl error buffer of this handle as a string.
+
+In order to distinguish between similarly-named CURLOPT and CURLINFO
+constants, some have ``OPT_`` and ``INFO_`` prefixes. These are
+``INFO_FILETIME``, ``OPT_FILETIME``, ``INFO_COOKIELIST`` (but ``setopt`` uses
+``COOKIELIST``!), ``INFO_CERTINFO``, and ``OPT_CERTINFO``.
+
+The value returned by ``getinfo(INFO_CERTINFO)`` is a list with one element
+per certificate in the chain, starting with the leaf; each element is a
+sequence of ``(``*key*``, ``*value*``)`` tuples.
+
+.. _curl_easy_cleanup:
+ http://curl.haxx.se/libcurl/c/curl_easy_cleanup.html
+.. _curl_easy_perform:
+ http://curl.haxx.se/libcurl/c/curl_easy_perform.html
+.. _curl_easy_reset: http://curl.haxx.se/libcurl/c/curl_easy_reset.html
+.. _curl_easy_setopt: http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+.. _curl_easy_getinfo:
+ http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html
+.. _curl_easy_pause: http://curl.haxx.se/libcurl/c/curl_easy_pause.html
diff --git a/doc/curlshareobject.html b/doc/curlshareobject.html
deleted file mode 100644
index a624f48..0000000
--- a/doc/curlshareobject.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <title>PycURL: CurlShare Objects</title>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <meta name="revisit-after" content="30 days" />
- <meta name="robots" content="noarchive, index, follow" />
-</head>
-<body>
-
-<h1>CurlShare Object</h1>
-
-<p>CurlShare objects have the following methods:</p>
-
-<dl>
-<dt><code>setopt(</code><em>option, value</em><code>)</code> -> <em>None</em></dt>
-<dd>
-
-<p>Corresponds to
-<a
-href="http://curl.haxx.se/libcurl/c/curl_share_setopt.html"><code>curl_share_setopt</code></a> in libcurl, where
-<em>option</em> is specified with the CURLSHOPT_* constants in libcurl,
-except that the CURLSHOPT_ prefix has been changed to SH_. Currently,
-<em>value</em> must be either LOCK_DATA_COOKIE or LOCK_DATA_DNS.</p>
-
-<p>Example usage:</p>
-
-<pre>
-import pycurl
-curl = pycurl.Curl()
-s = pycurl.CurlShare()
-s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_COOKIE)
-s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_DNS)
-curl.setopt(pycurl.URL, 'http://curl.haxx.se')
-curl.setopt(pycurl.SHARE, s)
-curl.perform()
-curl.close()
-</pre>
-</dd>
-
-</dl>
-
-<hr />
-<p>
- <a href="http://validator.w3.org/check/referer"><img align="right"
- src="http://www.w3.org/Icons/valid-xhtml10"
- alt="Valid XHTML 1.0!" height="31" width="88" border="0" /></a>
-</p>
-
-</body>
-</html>
diff --git a/doc/curlshareobject.rst b/doc/curlshareobject.rst
new file mode 100644
index 0000000..cf1d17b
--- /dev/null
+++ b/doc/curlshareobject.rst
@@ -0,0 +1,29 @@
+CurlShare Object
+================
+
+CurlShare objects have the following methods:
+
+**setopt**\ (*option, value*) -> *None*
+
+Corresponds to `curl_share_setopt`_ in libcurl, where *option* is
+specified with the ``CURLSHOPT_*`` constants in libcurl, except that the
+``CURLSHOPT_`` prefix has been changed to ``SH_``. Currently, *value* must be
+either ``LOCK_DATA_COOKIE`` or ``LOCK_DATA_DNS``.
+
+Example usage:
+
+::
+
+ import pycurl
+ curl = pycurl.Curl()
+ s = pycurl.CurlShare()
+ s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_COOKIE)
+ s.setopt(pycurl.SH_SHARE, pycurl.LOCK_DATA_DNS)
+ curl.setopt(pycurl.URL, 'http://curl.haxx.se')
+ curl.setopt(pycurl.SHARE, s)
+ curl.perform()
+ curl.close()
+
+
+.. _curl_share_setopt:
+ http://curl.haxx.se/libcurl/c/curl_share_setopt.html
diff --git a/doc/pycurl.html b/doc/pycurl.html
deleted file mode 100644
index bde7753..0000000
--- a/doc/pycurl.html
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <title>PycURL Documentation</title>
- <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
- <meta name="revisit-after" content="30 days" />
- <meta name="robots" content="noarchive, index, follow" />
-</head>
-<body>
-
-<h1><tt>PycURL</tt> — A Python Interface To The cURL library</h1>
-
-<p>The pycurl package is a Python interface to libcurl (<a
-href="http://curl.haxx.se/libcurl/">http://curl.haxx.se/libcurl/</a>). pycurl
-has been successfully built and tested with Python versions from
-2.4 to 2.7.</p>
-
-<p>libcurl is a client-side URL transfer library supporting FTP, FTPS,
-HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and LDAP. libcurl
-also supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploads, proxies,
-cookies, basic authentication, file transfer resume of FTP sessions, HTTP
-proxy tunneling and more.</p>
-
-<p>All the functionality provided by libcurl can used through the
-pycurl interface. The following subsections describe how to use the
-pycurl interface, and assume familiarity with how libcurl works. For
-information on how libcurl works, please consult the curl library web pages
-(<a href="http://curl.haxx.se/libcurl/c/">http://curl.haxx.se/libcurl/c/</a>).</p>
-
-<hr/>
-
-<h1>Module Functionality</h1>
-
-<dl>
-<dt><code>pycurl.global_init(</code><em>option</em><code>)</code> -><em>None</em></dt>
-
-<dd><p><em>option</em> is one of the constants
-pycurl.GLOBAL_SSL, pycurl.GLOBAL_WIN32, pycurl.GLOBAL_ALL,
-pycurl.GLOBAL_NOTHING, pycurl.GLOBAL_DEFAULT. Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_global_init.html"><code>curl_global_init()</code></a> in libcurl.</p>
-</dd>
-
-<dt><code>pycurl.global_cleanup()</code> -> <em>None</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_global_cleanup.html"><code>curl_global_cleanup()</code></a> in libcurl.</p>
-</dd>
-
-<dt><code>pycurl.version</code></dt>
-
-<dd><p>This is a string with version information on libcurl,
-corresponding to
-<a href="http://curl.haxx.se/libcurl/c/curl_version.html"><code>curl_version()</code></a> in libcurl.</p>
-
-<p>Example usage:</p>
-<pre>
->>> import pycurl
->>> pycurl.version
-'libcurl/7.12.3 OpenSSL/0.9.7e zlib/1.2.2.1 libidn/0.5.12'
-</pre>
-</dd>
-
-<dt><code>pycurl.version_info()</code> -> <em>Tuple</em></dt>
-<dd>
-<p>Corresponds to
-<a href="http://curl.haxx.se/libcurl/c/curl_version_info.html"><code>curl_version_info()</code></a> in libcurl.
-Returns a tuple of information which is similar to the
-<code>curl_version_info_data</code> struct returned by
-<code>curl_version_info()</code> in libcurl.</p>
-
-<p>Example usage:</p>
-<pre>
->>> import pycurl
->>> pycurl.version_info()
-(2, '7.12.3', 461827, 'i586-pc-linux-gnu', 1565, 'OpenSSL/0.9.7e', 9465951,
-'1.2.2.1', ('ftp', 'gopher', 'telnet', 'dict', 'ldap', 'http', 'file',
-'https', 'ftps'), None, 0, '0.5.12')
-</pre>
-</dd>
-
-<dt><code>pycurl.Curl()</code> -> <em>Curl object</em></dt>
-<dd>
-<p>This function creates a new
-<a href="curlobject.html">Curl object</a> which corresponds to a
-<code>CURL</code> handle in libcurl. Curl objects automatically
-set CURLOPT_VERBOSE to 0, CURLOPT_NOPROGRESS to 1,
-provide a default CURLOPT_USERAGENT and setup
-CURLOPT_ERRORBUFFER to point to a private error buffer.</p>
-</dd>
-
-<dt><code>pycurl.CurlMulti()</code> -> <em>CurlMulti object</em></dt>
-<dd>
-<p>This function creates a new
-<a href="curlmultiobject.html">CurlMulti object</a> which corresponds to
-a <code>CURLM</code> handle in libcurl.</p>
-</dd>
-
-<dt><code>pycurl.CurlShare()</code> -> <em>CurlShare object</em></dt>
-<dd>
-<p>This function creates a new
-<a href="curlshareobject.html">CurlShare object</a> which corresponds to
-a <code>CURLSH</code> handle in libcurl. CurlShare objects is what you
-pass as an argument to the SHARE option on Curl objects.</p>
-</dd>
-
-</dl>
-
-<hr/>
-
-<h1>Subsections</h1>
-
-<ul>
- <li><a href="curlobject.html">Curl objects</a></li>
- <li><a href="curlmultiobject.html">CurlMulti objects</a></li>
- <li><a href="curlshareobject.html">CurlShare objects</a></li>
- <li><a href="callbacks.html">Callbacks</a></li>
- <li><a href="unicode.html">Unicode handling</a></li>
- <li><a href="files.html">File handling</a></li>
-</ul>
-
-<h1>Documentation For Developers</h1>
-
-<ul>
- <li><a href="internals.html">Notes on PycURL internals</a></li>
- <li><a href="release-process.html">Release process</a></li>
-</ul>
-
-<hr />
-<p>
- <a href="http://validator.w3.org/check/referer"><img align="right"
- src="http://www.w3.org/Icons/valid-xhtml10"
- alt="Valid XHTML 1.0!" height="31" width="88" border="0" /></a>
-</p>
-
-</body>
-</html>
diff --git a/doc/pycurl.rst b/doc/pycurl.rst
new file mode 100644
index 0000000..60971df
--- /dev/null
+++ b/doc/pycurl.rst
@@ -0,0 +1,114 @@
+``PycURL`` -- A Python Interface To The cURL library
+====================================================
+
+The pycurl package is a Python interface to `libcurl`_.
+pycurl has been successfully built and
+tested with Python versions from 2.4 to 2.7 and 3.1 to 3.3.
+
+libcurl is a client-side URL transfer library supporting FTP, FTPS, HTTP,
+HTTPS, GOPHER, TELNET, DICT, FILE and LDAP. libcurl also supports HTTPS
+certificates, HTTP POST, HTTP PUT, FTP uploads, proxies, cookies, basic
+authentication, file transfer resume of FTP sessions, HTTP proxy tunneling
+and more.
+
+All the functionality provided by libcurl can used through the pycurl
+interface. The following subsections describe how to use the pycurl
+interface, and assume familiarity with how libcurl works. For information on
+how libcurl works, please consult the `curl library C API`_.
+
+Module Functionality
+--------------------
+
+**pycurl.global_init**\ (*option*) -> *None*
+
+*option* is one of the constants pycurl.GLOBAL_SSL, pycurl.GLOBAL_WIN32,
+pycurl.GLOBAL_ALL, pycurl.GLOBAL_NOTHING, pycurl.GLOBAL_DEFAULT. Corresponds
+to `curl_global_init`_ in libcurl.
+
+**pycurl.global_cleanup**\ () -> *None*
+
+Corresponds to `curl_global_cleanup`_ in libcurl.
+
+**pycurl.version**
+
+This is a string with version information on libcurl, corresponding to
+`curl_version`_ in libcurl.
+
+Example usage:
+
+::
+
+ >>> import pycurl
+ >>> pycurl.version
+ 'PycURL/7.19.3 libcurl/7.33.0 OpenSSL/0.9.8x zlib/1.2.7'
+
+**pycurl.version_info**\ () -> *Tuple*
+
+Corresponds to `curl_version_info`_ in libcurl. Returns a tuple of
+information which is similar to the ``curl_version_info_data`` struct
+returned by ``curl_version_info()`` in libcurl.
+
+Example usage:
+
+::
+
+ >>> import pycurl
+ >>> pycurl.version_info()
+ (3, '7.33.0', 467200, 'amd64-portbld-freebsd9.1', 33436, 'OpenSSL/0.9.8x',
+ 0, '1.2.7', ('dict', 'file', 'ftp', 'ftps', 'gopher', 'http', 'https',
+ 'imap', 'imaps', 'pop3', 'pop3s', 'rtsp', 'smtp', 'smtps', 'telnet',
+ 'tftp'), None, 0, None)
+
+**pycurl.Curl**\ () -> *Curl object*
+
+This function creates a new `Curl object`_ which corresponds to a ``CURL``
+handle in libcurl. Curl objects automatically set CURLOPT_VERBOSE to 0,
+CURLOPT_NOPROGRESS to 1, provide a default CURLOPT_USERAGENT and setup
+CURLOPT_ERRORBUFFER to point to a private error buffer.
+
+**pycurl.CurlMulti**\ () -> *CurlMulti object*
+
+This function creates a new `CurlMulti object`_ which corresponds to a
+``CURLM`` handle in libcurl.
+
+**pycurl.CurlShare**\ () -> *CurlShare object*
+
+This function creates a new `CurlShare object`_ which corresponds to a
+``CURLSH`` handle in libcurl. CurlShare objects is what you pass as an
+argument to the SHARE option on Curl objects.
+
+
+Subsections
+-----------
+
+- `Curl objects`_
+- `CurlMulti objects`_
+- `CurlShare objects`_
+- `Callbacks`_
+- `Unicode handling`_
+- `File handling`_
+
+
+Documentation For Developers
+============================
+
+- `Notes on PycURL internals`_
+- `Release process`_
+
+.. _libcurl: http://curl.haxx.se/libcurl/
+.. _curl library C API: http://curl.haxx.se/libcurl/c/
+.. _curl_global_init: http://curl.haxx.se/libcurl/c/curl_global_init.html
+.. _curl_global_cleanup: http://curl.haxx.se/libcurl/c/curl_global_cleanup.html
+.. _curl_version: http://curl.haxx.se/libcurl/c/curl_version.html
+.. _curl_version_info: http://curl.haxx.se/libcurl/c/curl_version_info.html
+.. _Curl object: curlobject.html
+.. _Curl objects: curlobject.html
+.. _CurlMulti object: curlmultiobject.html
+.. _CurlMulti objects: curlmultiobject.html
+.. _CurlShare object: curlshareobject.html
+.. _CurlShare objects: curlshareobject.html
+.. _Callbacks: callbacks.html
+.. _Unicode handling: unicode.html
+.. _File handling: files.html
+.. _Notes on PycURL internals: internals.html
+.. _Release process: release-process.html
diff --git a/doc/release-process.rst b/doc/release-process.rst
index 813cd51..e967f41 100644
--- a/doc/release-process.rst
+++ b/doc/release-process.rst
@@ -2,28 +2,29 @@ Release Process
===============
1. Ensure changelog is up to date with commits in master.
-2. Run `python setup.py manifest`, check that none of the listed files
+2. Run ``python setup.py manifest``, check that none of the listed files
should be in MANIFEST.in.
-3. Make sure travis is green for master.
-4. Update version numbers in:
- - Changelog
+3. Check ``get_data_files()`` in ``setup.py`` to see if any new files should
+ be included in binary distributions.
+4. Make sure travis is green for master.
+5. Update version numbers in:
+ - Changelog (also record release date)
- setup.py
- winbuild.py
- - www/htdocs/index.php
-5. Copy Changelog to www/htdocs.
-6. Draft release notes.
-7. `make docs`.
-8. `python setup.py sdist`.
+ - www/htdocs/index.php (also update release date)
+6. Draft release notes, add to RELEASE-NOTES.rst.
+7. ``make docs``.
+8. ``python setup.py sdist``.
9. Manually test install the built package.
10. Build windows packages using winbuild.py.
11. Add windows packages to downloads repo on github.
12. Tag the new version.
-13. Register new version with pypi - `python setup.py register`.
-14. Upload source distribution to pypi - `python setup.py sdist upload`.
+13. Register new version with pypi - ``python setup.py register``.
+14. Upload source distribution to pypi - ``python setup.py sdist upload``.
This recreates the source distribution.
15. Add the source distribution to downloads repo on github.
16. Rsync downloads repo to sourceforge.
-17. Rsync www/htdocs to sourceforge.
+17. Rsync build/www/htdocs to sourceforge.
18. Push tag to github pycurl repo.
19. Announce release on mailing list.
20. Link to announcement from website.
diff --git a/setup.py b/setup.py
index 40603ff..d35f151 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@
PACKAGE = "pycurl"
PY_PACKAGE = "curl"
-VERSION = "7.19.3"
+VERSION = "7.19.3.1"
import glob, os, re, sys, string, subprocess
import distutils
@@ -24,15 +24,6 @@ except NameError:
class ConfigurationError(exception_base):
pass
-include_dirs = []
-define_macros = [("PYCURL_VERSION", '"%s"' % VERSION)]
-library_dirs = []
-libraries = []
-runtime_library_dirs = []
-extra_objects = []
-extra_compile_args = []
-extra_link_args = []
-
def fail(msg):
sys.stderr.write(msg + "\n")
@@ -60,75 +51,270 @@ def scan_argv(s, default=None):
return p
-# append contents of an environment variable to library_dirs[]
-def add_libdirs(envvar, sep, fatal=False):
- v = os.environ.get(envvar)
- if not v:
- return
- for dir in str.split(v, sep):
- dir = str.strip(dir)
- if not dir:
- continue
- dir = os.path.normpath(dir)
- if os.path.isdir(dir):
- if not dir in library_dirs:
- library_dirs.append(dir)
- elif fatal:
- fail("FATAL: bad directory %s in environment variable %s" % (dir, envvar))
-
-
-def configure_windows():
- # Windows users have to pass --curl-dir parameter to specify path
- # to libcurl, because there is no curl-config on windows at all.
- curl_dir = scan_argv("--curl-dir=")
- if curl_dir is None:
- fail("Please specify --curl-dir=/path/to/built/libcurl")
- if not os.path.exists(curl_dir):
- fail("Curl directory does not exist: %s" % curl_dir)
- if not os.path.isdir(curl_dir):
- fail("Curl directory is not a directory: %s" % curl_dir)
- print("Using curl directory: %s" % curl_dir)
- include_dirs.append(os.path.join(curl_dir, "include"))
-
- # libcurl windows documentation states that for linking against libcurl
- # dll, the import library name is libcurl_imp.lib.
- # in practice, the library name sometimes is libcurl.lib.
- # override with: --libcurl-lib-name=libcurl_imp.lib
- curl_lib_name = scan_argv('--libcurl-lib-name=', 'libcurl.lib')
-
- if scan_argv("--use-libcurl-dll") is not None:
- libcurl_lib_path = os.path.join(curl_dir, "lib", curl_lib_name)
- extra_link_args.extend(["ws2_32.lib"])
+class ExtensionConfiguration(object):
+ def __init__(self):
+ self.include_dirs = []
+ self.define_macros = [("PYCURL_VERSION", '"%s"' % VERSION)]
+ self.library_dirs = []
+ self.libraries = []
+ self.runtime_library_dirs = []
+ self.extra_objects = []
+ self.extra_compile_args = []
+ self.extra_link_args = []
+
+ self.configure()
+
+ @property
+ def define_symbols(self):
+ return [symbol for symbol, expansion in self.define_macros]
+
+ # append contents of an environment variable to library_dirs[]
+ def add_libdirs(self, envvar, sep, fatal=False):
+ v = os.environ.get(envvar)
+ if not v:
+ return
+ for dir in str.split(v, sep):
+ dir = str.strip(dir)
+ if not dir:
+ continue
+ dir = os.path.normpath(dir)
+ if os.path.isdir(dir):
+ if not dir in library_dirs:
+ self.library_dirs.append(dir)
+ elif fatal:
+ fail("FATAL: bad directory %s in environment variable %s" % (dir, envvar))
+
+
+ def configure_unix(self):
+ OPENSSL_DIR = scan_argv("--openssl-dir=")
+ if OPENSSL_DIR is not None:
+ self.include_dirs.append(os.path.join(OPENSSL_DIR, "include"))
+ CURL_CONFIG = os.environ.get('PYCURL_CURL_CONFIG', "curl-config")
+ CURL_CONFIG = scan_argv("--curl-config=", CURL_CONFIG)
+ try:
+ p = subprocess.Popen((CURL_CONFIG, '--version'),
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ except OSError:
+ exc = sys.exc_info()[1]
+ msg = 'Could not run curl-config: %s' % str(exc)
+ raise ConfigurationError(msg)
+ stdout, stderr = p.communicate()
+ if p.wait() != 0:
+ msg = "`%s' not found -- please install the libcurl development files or specify --curl-config=/path/to/curl-config" % CURL_CONFIG
+ if stderr:
+ msg += ":\n" + stderr.decode()
+ raise ConfigurationError(msg)
+ libcurl_version = stdout.decode().strip()
+ print("Using %s (%s)" % (CURL_CONFIG, libcurl_version))
+ p = subprocess.Popen((CURL_CONFIG, '--cflags'),
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ if p.wait() != 0:
+ msg = "Problem running `%s' --cflags" % CURL_CONFIG
+ if stderr:
+ msg += ":\n" + stderr.decode()
+ raise ConfigurationError(msg)
+ for arg in split_quoted(stdout.decode()):
+ if arg[:2] == "-I":
+ # do not add /usr/include
+ if not re.search(r"^\/+usr\/+include\/*$", arg[2:]):
+ self.include_dirs.append(arg[2:])
+ else:
+ self.extra_compile_args.append(arg)
+
+ # Obtain linker flags/libraries to link against.
+ # In theory, all we should need is `curl-config --libs`.
+ # Apparently on some platforms --libs fails and --static-libs works,
+ # so try that.
+ # If --libs succeeds do not try --static-libs; see
+ # https://github.com/pycurl/pycurl/issues/52 for more details.
+ # If neither --libs nor --static-libs work, fail.
+ #
+ # --libs/--static-libs are also used for SSL detection.
+ # libcurl may be configured such that --libs only includes -lcurl
+ # without any of libcurl's dependent libraries, but the dependent
+ # libraries would be included in --static-libs (unless libcurl
+ # was built with static libraries disabled).
+ # Therefore we largely ignore (see below) --static-libs output for
+ # libraries and flags if --libs succeeded, but consult both outputs
+ # for hints as to which SSL library libcurl is linked against.
+ # More information: https://github.com/pycurl/pycurl/pull/147
+ #
+ # The final point is we should link agaist the SSL library in use
+ # even if libcurl does not tell us to, because *we* invoke functions
+ # in that SSL library. This means any SSL libraries found in
+ # --static-libs are forwarded to our libraries.
+ optbuf = ''
+ sslhintbuf = ''
+ errtext = ''
+ for option in ["--libs", "--static-libs"]:
+ p = subprocess.Popen((CURL_CONFIG, option),
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ if p.wait() == 0:
+ if optbuf == '':
+ # first successful call
+ optbuf = stdout.decode()
+ # optbuf only has output from this call
+ sslhintbuf += optbuf
+ else:
+ # second successful call
+ sslhintbuf += stdout.decode()
+ else:
+ if optbuf == '':
+ # no successful call yet
+ errtext += stderr.decode()
+ else:
+ # first call succeeded and second call failed
+ # ignore stderr and the error exit
+ pass
+ if optbuf == "":
+ msg = "Neither curl-config --libs nor curl-config --static-libs" +\
+ " succeeded and produced output"
+ if errtext:
+ msg += ":\n" + errtext
+ raise ConfigurationError(msg)
+
+ ssl_lib_detected = False
+ if 'PYCURL_SSL_LIBRARY' in os.environ:
+ ssl_lib = os.environ['PYCURL_SSL_LIBRARY']
+ if ssl_lib in ['openssl', 'gnutls', 'nss']:
+ ssl_lib_detected = True
+ self.define_macros.append(('HAVE_CURL_%s' % ssl_lib.upper(), 1))
+ else:
+ raise ConfigurationError('Invalid value "%s" for PYCURL_SSL_LIBRARY' % ssl_lib)
+ ssl_options = {
+ '--with-ssl': 'HAVE_CURL_OPENSSL',
+ '--with-gnutls': 'HAVE_CURL_GNUTLS',
+ '--with-nss': 'HAVE_CURL_NSS',
+ }
+ for option in ssl_options:
+ if scan_argv(option) is not None:
+ for other_option in ssl_options:
+ if option != other_option:
+ if scan_argv(other_option) is not None:
+ raise ConfigurationError('Cannot give both %s and %s' % (option, other_option))
+ ssl_lib_detected = True
+ self.define_macros.append((ssl_options[option], 1))
+
+ # libraries and options - all libraries and options are forwarded
+ # but if --libs succeeded, --static-libs output is ignored
+ for arg in split_quoted(optbuf):
+ if arg[:2] == "-l":
+ self.libraries.append(arg[2:])
+ elif arg[:2] == "-L":
+ self.library_dirs.append(arg[2:])
+ else:
+ self.extra_link_args.append(arg)
+ # ssl detection - ssl libraries are forwarded
+ for arg in split_quoted(sslhintbuf):
+ if arg[:2] == "-l":
+ if not ssl_lib_detected and arg[2:] == 'ssl':
+ self.define_macros.append(('HAVE_CURL_OPENSSL', 1))
+ ssl_lib_detected = True
+ self.libraries.append('ssl')
+ if not ssl_lib_detected and arg[2:] == 'gnutls':
+ self.define_macros.append(('HAVE_CURL_GNUTLS', 1))
+ ssl_lib_detected = True
+ self.libraries.append('gnutls')
+ if not ssl_lib_detected and arg[2:] == 'ssl3':
+ self.define_macros.append(('HAVE_CURL_NSS', 1))
+ ssl_lib_detected = True
+ self.libraries.append('ssl3')
+ if not ssl_lib_detected:
+ p = subprocess.Popen((CURL_CONFIG, '--features'),
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ if p.wait() != 0:
+ msg = "Problem running `%s' --features" % CURL_CONFIG
+ if stderr:
+ msg += ":\n" + stderr.decode()
+ raise ConfigurationError(msg)
+ for feature in split_quoted(stdout.decode()):
+ if feature == 'SSL':
+ # this means any ssl library, not just openssl
+ self.define_macros.append(('HAVE_CURL_SSL', 1))
+ else:
+ # if we are configuring for a particular ssl library,
+ # we can assume that ssl is being used
+ self.define_macros.append(('HAVE_CURL_SSL', 1))
+ if not self.libraries:
+ self.libraries.append("curl")
+
+ # Add extra compile flag for MacOS X
+ if sys.platform[:-1] == "darwin":
+ self.extra_link_args.append("-flat_namespace")
+
+ # Recognize --avoid-stdio on Unix so that it can be tested
+ self.check_avoid_stdio()
+
+
+ def configure_windows(self):
+ # Windows users have to pass --curl-dir parameter to specify path
+ # to libcurl, because there is no curl-config on windows at all.
+ curl_dir = scan_argv("--curl-dir=")
+ if curl_dir is None:
+ fail("Please specify --curl-dir=/path/to/built/libcurl")
+ if not os.path.exists(curl_dir):
+ fail("Curl directory does not exist: %s" % curl_dir)
+ if not os.path.isdir(curl_dir):
+ fail("Curl directory is not a directory: %s" % curl_dir)
+ print("Using curl directory: %s" % curl_dir)
+ self.include_dirs.append(os.path.join(curl_dir, "include"))
+
+ # libcurl windows documentation states that for linking against libcurl
+ # dll, the import library name is libcurl_imp.lib.
+ # in practice, the library name sometimes is libcurl.lib.
+ # override with: --libcurl-lib-name=libcurl_imp.lib
+ curl_lib_name = scan_argv('--libcurl-lib-name=', 'libcurl.lib')
+
+ if scan_argv("--use-libcurl-dll") is not None:
+ libcurl_lib_path = os.path.join(curl_dir, "lib", curl_lib_name)
+ self.extra_link_args.extend(["ws2_32.lib"])
+ if str.find(sys.version, "MSC") >= 0:
+ # build a dll
+ self.extra_compile_args.append("-MD")
+ else:
+ self.extra_compile_args.append("-DCURL_STATICLIB")
+ libcurl_lib_path = os.path.join(curl_dir, "lib", curl_lib_name)
+ self.extra_link_args.extend(["gdi32.lib", "wldap32.lib", "winmm.lib", "ws2_32.lib",])
+
+ if not os.path.exists(libcurl_lib_path):
+ fail("libcurl.lib does not exist at %s.\nCurl directory must point to compiled libcurl (bin/include/lib subdirectories): %s" %(libcurl_lib_path, curl_dir))
+ self.extra_objects.append(libcurl_lib_path)
+
+ self.check_avoid_stdio()
+
+ # make pycurl binary work on windows xp.
+ # we use inet_ntop which was added in vista and implement a fallback.
+ # our implementation will not be compiled with _WIN32_WINNT targeting
+ # vista or above, thus said binary won't work on xp.
+ # http://curl.haxx.se/mail/curlpython-2013-12/0007.html
+ self.extra_compile_args.append("-D_WIN32_WINNT=0x0501")
+
if str.find(sys.version, "MSC") >= 0:
- # build a dll
- extra_compile_args.append("-MD")
- else:
- extra_compile_args.append("-DCURL_STATICLIB")
- libcurl_lib_path = os.path.join(curl_dir, "lib", curl_lib_name)
- extra_link_args.extend(["gdi32.lib", "wldap32.lib", "winmm.lib", "ws2_32.lib",])
+ self.extra_compile_args.append("-O2")
+ self.extra_compile_args.append("-GF") # enable read-only string pooling
+ self.extra_compile_args.append("-WX") # treat warnings as errors
+ p = subprocess.Popen(['cl.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ match = re.search(r'Version (\d+)', err.decode().split("\n")[0])
+ if match and int(match.group(1)) < 16:
+ # option removed in vs 2010:
+ # connect.microsoft.com/VisualStudio/feedback/details/475896/link-fatal-error-lnk1117-syntax-error-in-option-opt-nowin98/
+ self.extra_link_args.append("/opt:nowin98") # use small section alignment
- if not os.path.exists(libcurl_lib_path):
- fail("libcurl.lib does not exist at %s.\nCurl directory must point to compiled libcurl (bin/include/lib subdirectories): %s" %(libcurl_lib_path, curl_dir))
- extra_objects.append(libcurl_lib_path)
+ if sys.platform == "win32":
+ configure = configure_windows
+ else:
+ configure = configure_unix
- # make pycurl binary work on windows xp.
- # we use inet_ntop which was added in vista and implement a fallback.
- # our implementation will not be compiled with _WIN32_WINNT targeting
- # vista or above, thus said binary won't work on xp.
- # http://curl.haxx.se/mail/curlpython-2013-12/0007.html
- extra_compile_args.append("-D_WIN32_WINNT=0x0501")
-
- if str.find(sys.version, "MSC") >= 0:
- extra_compile_args.append("-O2")
- extra_compile_args.append("-GF") # enable read-only string pooling
- extra_compile_args.append("-WX") # treat warnings as errors
- p = subprocess.Popen(['cl.exe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = p.communicate()
- match = re.search(r'Version (\d+)', err.decode().split("\n")[0])
- if match and int(match.group(1)) < 16:
- # option removed in vs 2010:
- # connect.microsoft.com/VisualStudio/feedback/details/475896/link-fatal-error-lnk1117-syntax-error-in-option-opt-nowin98/
- extra_link_args.append("/opt:nowin98") # use small section alignment
+
+ def check_avoid_stdio(self):
+ if 'PYCURL_SETUP_OPTIONS' in os.environ and '--avoid-stdio' in os.environ['PYCURL_SETUP_OPTIONS']:
+ self.extra_compile_args.append("-DPYCURL_AVOID_STDIO")
+ if scan_argv('--avoid-stdio') is not None:
+ self.extra_compile_args.append("-DPYCURL_AVOID_STDIO")
def get_bdist_msi_version_hack():
# workaround for distutils/msi version requirement per
@@ -164,145 +350,14 @@ def get_bdist_msi_version_hack():
return bdist_msi_version_hack
-def configure_unix():
- # Find out the rest the hard way
- OPENSSL_DIR = scan_argv("--openssl-dir=")
- if OPENSSL_DIR is not None:
- include_dirs.append(os.path.join(OPENSSL_DIR, "include"))
- CURL_CONFIG = os.environ.get('PYCURL_CURL_CONFIG', "curl-config")
- CURL_CONFIG = scan_argv("--curl-config=", CURL_CONFIG)
- try:
- p = subprocess.Popen((CURL_CONFIG, '--version'),
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- except OSError:
- exc = sys.exc_info()[1]
- msg = 'Could not run curl-config: %s' % str(exc)
- raise ConfigurationError(msg)
- stdout, stderr = p.communicate()
- if p.wait() != 0:
- msg = "`%s' not found -- please install the libcurl development files or specify --curl-config=/path/to/curl-config" % CURL_CONFIG
- if stderr:
- msg += ":\n" + stderr.decode()
- raise ConfigurationError(msg)
- libcurl_version = stdout.decode().strip()
- print("Using %s (%s)" % (CURL_CONFIG, libcurl_version))
- p = subprocess.Popen((CURL_CONFIG, '--cflags'),
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout, stderr = p.communicate()
- if p.wait() != 0:
- msg = "Problem running `%s' --cflags" % CURL_CONFIG
- if stderr:
- msg += ":\n" + stderr.decode()
- raise ConfigurationError(msg)
- for arg in split_quoted(stdout.decode()):
- if arg[:2] == "-I":
- # do not add /usr/include
- if not re.search(r"^\/+usr\/+include\/*$", arg[2:]):
- include_dirs.append(arg[2:])
- else:
- extra_compile_args.append(arg)
-
- # Obtain linker flags/libraries to link against.
- # In theory, all we should need is `curl-config --libs`.
- # Apparently on some platforms --libs fails and --static-libs works,
- # so try that.
- # If --libs succeeds do not try --static libs; see
- # https://github.com/pycurl/pycurl/issues/52 for more details.
- # If neither --libs nor --static-libs work, fail.
- optbuf = ""
- errtext = ''
- for option in ["--libs", "--static-libs"]:
- p = subprocess.Popen((CURL_CONFIG, option),
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout, stderr = p.communicate()
- if p.wait() == 0:
- optbuf = stdout.decode()
- break
- else:
- errtext += stderr.decode()
- if optbuf == "":
- msg = "Neither curl-config --libs nor curl-config --static-libs" +\
- " succeeded and produced output"
- if errtext:
- msg += ":\n" + errtext
- raise ConfigurationError(msg)
- libs = split_quoted(optbuf)
-
- ssl_lib_detected = False
- if 'PYCURL_SSL_LIBRARY' in os.environ:
- ssl_lib = os.environ['PYCURL_SSL_LIBRARY']
- if ssl_lib in ['openssl', 'gnutls', 'nss']:
- ssl_lib_detected = True
- define_macros.append(('HAVE_CURL_%s' % ssl_lib.upper(), 1))
- else:
- raise ConfigurationError('Invalid value "%s" for PYCURL_SSL_LIBRARY' % ssl_lib)
- ssl_options = {
- '--with-ssl': 'HAVE_CURL_OPENSSL',
- '--with-gnutls': 'HAVE_CURL_GNUTLS',
- '--with-nss': 'HAVE_CURL_NSS',
- }
- for option in ssl_options:
- if scan_argv(option) is not None:
- for other_option in ssl_options:
- if option != other_option:
- if scan_argv(other_option) is not None:
- raise ConfigurationError('Cannot give both %s and %s' % (option, other_option))
- ssl_lib_detected = True
- define_macros.append((ssl_options[option], 1))
-
- for arg in libs:
- if arg[:2] == "-l":
- libraries.append(arg[2:])
- if not ssl_lib_detected and arg[2:] == 'ssl':
- define_macros.append(('HAVE_CURL_OPENSSL', 1))
- ssl_lib_detected = True
- if not ssl_lib_detected and arg[2:] == 'gnutls':
- define_macros.append(('HAVE_CURL_GNUTLS', 1))
- ssl_lib_detected = True
- if not ssl_lib_detected and arg[2:] == 'ssl3':
- define_macros.append(('HAVE_CURL_NSS', 1))
- ssl_lib_detected = True
- elif arg[:2] == "-L":
- library_dirs.append(arg[2:])
- else:
- extra_link_args.append(arg)
- if not ssl_lib_detected:
- p = subprocess.Popen((CURL_CONFIG, '--features'),
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout, stderr = p.communicate()
- if p.wait() != 0:
- msg = "Problem running `%s' --features" % CURL_CONFIG
- if stderr:
- msg += ":\n" + stderr.decode()
- raise ConfigurationError(msg)
- for feature in split_quoted(stdout.decode()):
- if feature == 'SSL':
- # this means any ssl library, not just openssl
- define_macros.append(('HAVE_CURL_SSL', 1))
- else:
- # if we are configuring for a particular ssl library,
- # we can assume that ssl is being used
- define_macros.append(('HAVE_CURL_SSL', 1))
- if not libraries:
- libraries.append("curl")
- # Add extra compile flag for MacOS X
- if sys.platform[:-1] == "darwin":
- extra_link_args.append("-flat_namespace")
-
-
-def configure():
- if sys.platform == "win32":
- configure_windows()
- else:
- configure_unix()
-
-
-
def strip_pycurl_options():
if sys.platform == 'win32':
- options = ['--curl-dir=', '--curl-lib-name=', '--use-libcurl-dll']
+ options = [
+ '--curl-dir=', '--curl-lib-name=', '--use-libcurl-dll',
+ '--avoid-stdio',
+ ]
else:
- options = ['--openssl-dir', '--curl-config']
+ options = ['--openssl-dir=', '--curl-config=', '--avoid-stdio']
for option in options:
scan_argv(option)
@@ -310,19 +365,20 @@ def strip_pycurl_options():
###############################################################################
def get_extension():
+ ext_config = ExtensionConfiguration()
ext = Extension(
name=PACKAGE,
sources=[
os.path.join("src", "pycurl.c"),
],
- include_dirs=include_dirs,
- define_macros=define_macros,
- library_dirs=library_dirs,
- libraries=libraries,
- runtime_library_dirs=runtime_library_dirs,
- extra_objects=extra_objects,
- extra_compile_args=extra_compile_args,
- extra_link_args=extra_link_args,
+ include_dirs=ext_config.include_dirs,
+ define_macros=ext_config.define_macros,
+ library_dirs=ext_config.library_dirs,
+ libraries=ext_config.libraries,
+ runtime_library_dirs=ext_config.runtime_library_dirs,
+ extra_objects=ext_config.extra_objects,
+ extra_compile_args=ext_config.extra_compile_args,
+ extra_link_args=ext_config.extra_link_args,
)
##print(ext.__dict__); sys.exit(1)
return ext
@@ -340,12 +396,13 @@ def get_data_files():
else:
datadir = os.path.join("share", "doc", PACKAGE)
#
- files = ["ChangeLog", "COPYING-LGPL", "COPYING-MIT", "INSTALL", "README.rst"]
+ files = ["AUTHORS", "ChangeLog", "COPYING-LGPL", "COPYING-MIT",
+ "INSTALL.rst", "README.rst"]
if files:
data_files.append((os.path.join(datadir), files))
- files = glob.glob(os.path.join("doc", "*.html"))
+ files = glob.glob(os.path.join("doc", "*.rst"))
if files:
- data_files.append((os.path.join(datadir, "html"), files))
+ data_files.append((os.path.join(datadir, "rst"), files))
files = glob.glob(os.path.join("examples", "*.py"))
if files:
data_files.append((os.path.join(datadir, "examples"), files))
@@ -360,8 +417,6 @@ def get_data_files():
assert os.path.isfile(f), (f, install_dir)
return data_files
-##print get_data_files(); sys.exit(1)
-
###############################################################################
@@ -401,6 +456,32 @@ def check_manifest():
if not included:
print(path)
+AUTHORS_PARAGRAPH = 3
+
+def check_authors():
+ f = open('AUTHORS')
+ try:
+ contents = f.read()
+ finally:
+ f.close()
+
+ paras = contents.split("\n\n")
+ authors_para = paras[AUTHORS_PARAGRAPH]
+ authors = [author for author in authors_para.strip().split("\n")]
+
+ log = subprocess.check_output(['git', 'log', '--format=%an (%ae)'])
+ for author in log.strip().split("\n"):
+ author = author.replace('@', ' at ').replace('(', '<').replace(')', '>')
+ if author not in authors:
+ authors.append(author)
+ authors.sort()
+ paras[AUTHORS_PARAGRAPH] = "\n".join(authors)
+ f = open('AUTHORS', 'w')
+ try:
+ f.write("\n\n".join(paras))
+ finally:
+ f.close()
+
###############################################################################
setup_args = dict(
@@ -475,9 +556,9 @@ if __name__ == "__main__":
setup(**setup_args)
elif len(sys.argv) > 1 and sys.argv[1] == 'manifest':
check_manifest()
+ elif len(sys.argv) > 1 and sys.argv[1] == 'authors':
+ check_authors()
else:
- configure()
-
setup_args['data_files'] = get_data_files()
ext = get_extension()
setup_args['ext_modules'] = [ext]
diff --git a/src/pycurl.c b/src/pycurl.c
index 0a9f7b8..5f6afaa 100644
--- a/src/pycurl.c
+++ b/src/pycurl.c
@@ -1,36 +1,4 @@
/* PycURL -- cURL Python module
- *
- * Authors:
- * Copyright (C) 2001-2008 by Kjetil Jacobsen <kjetilja at gmail.com>
- * Copyright (C) 2001-2008 by Markus F.X.J. Oberhumer <markus at oberhumer.com>
- * Copyright (C) 2013-2014 by Oleg Pudeyev <oleg at bsdpower.com>
- *
- * All rights reserved.
- *
- * Contributions:
- * Tino Lange <Tino.Lange at gmx.de>
- * Matt King <matt at gnik.com>
- * Conrad Steenberg <conrad at hep.caltech.edu>
- * Amit Mongia <amit_mongia at hotmail.com>
- * Eric S. Raymond <esr at thyrsus.com>
- * Martin Muenstermann <mamuema at sourceforge.net>
- * Domenico Andreoli <cavok at libero.it>
- * Dominique <curl-and-python at d242.net>
- * Paul Pacheco
- * Victor Lascurain <bittor at eleka.net>
- * K.S.Sreeram <sreeram at tachyontech.net>
- * Jayne <corvine at gmail.com>
- * Bastian Kleineidam
- * Mark Eichin
- * Aaron Hill <visine19 at hotmail.com>
- * Daniel Pena Arteaga <dpena at ph.tum.de>
- * Jim Patterson
- * Yuhui H <eyecat at gmail.com>
- * Nick Pilon <npilon at oreilly.com>
- * Thomas Hunger <teh at camvine.org>
- * Wim Lewis
- *
- * See file README for license information.
*/
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
@@ -117,6 +85,10 @@
#define HAVE_CURL_REDIR_POST_303
#endif
+#if LIBCURL_VERSION_NUM >= 0x071E00 /* check for 7.30.0 or greater */
+#define HAVE_CURL_7_30_0_PIPELINE_OPTS
+#endif
+
/* Python < 2.5 compat for Py_ssize_t */
#if PY_VERSION_HEX < 0x02050000
typedef int Py_ssize_t;
@@ -2272,7 +2244,7 @@ do_curl_setopt(CurlObject *self, PyObject *args)
#undef IS_LONG_OPTION
#undef IS_OFF_T_OPTION
-#if PY_MAJOR_VERSION < 3
+#if PY_MAJOR_VERSION < 3 && !defined(PYCURL_AVOID_STDIO)
/* Handle the case of file objects */
if (PyFile_Check(obj)) {
FILE *fp;
@@ -3200,10 +3172,15 @@ do_multi_setopt(CurlMultiObject *self, PyObject *args)
if (PyInt_Check(obj)) {
long d = PyInt_AsLong(obj);
switch(option) {
- case CURLMOPT_PIPELINING:
- curl_multi_setopt(self->multi_handle, option, d);
- break;
case CURLMOPT_MAXCONNECTS:
+ case CURLMOPT_PIPELINING:
+#ifdef HAVE_CURL_7_30_0_PIPELINE_OPTS
+ case CURLMOPT_MAX_HOST_CONNECTIONS:
+ case CURLMOPT_MAX_TOTAL_CONNECTIONS:
+ case CURLMOPT_MAX_PIPELINE_LENGTH:
+ case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
+ case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
+#endif
curl_multi_setopt(self->multi_handle, option, d);
break;
default:
@@ -4870,6 +4847,13 @@ initpycurl(void)
insint_c(d, "M_SOCKETFUNCTION", CURLMOPT_SOCKETFUNCTION);
insint_c(d, "M_PIPELINING", CURLMOPT_PIPELINING);
insint_c(d, "M_MAXCONNECTS", CURLMOPT_MAXCONNECTS);
+#ifdef HAVE_CURL_7_30_0_PIPELINE_OPTS
+ insint_c(d, "M_MAX_HOST_CONNECTIONS", CURLMOPT_MAX_HOST_CONNECTIONS);
+ insint_c(d, "M_MAX_TOTAL_CONNECTIONS", CURLMOPT_MAX_TOTAL_CONNECTIONS);
+ insint_c(d, "M_MAX_PIPELINE_LENGTH", CURLMOPT_MAX_PIPELINE_LENGTH);
+ insint_c(d, "M_CONTENT_LENGTH_PENALTY_SIZE", CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE);
+ insint_c(d, "M_CHUNK_LENGTH_PENALTY_SIZE", CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE);
+#endif
/* constants for setopt(IPRESOLVE, x) */
insint_c(d, "IPRESOLVE_WHATEVER", CURL_IPRESOLVE_WHATEVER);
diff --git a/tests/app.py b/tests/app.py
index 78a2064..20658bc 100644
--- a/tests/app.py
+++ b/tests/app.py
@@ -48,12 +48,25 @@ def convert_file(key, file):
'data': file.read(),
}
-def convert_file(key, file):
- return {
- 'name': file.name,
- 'filename': file.filename,
- 'data': file.file.read().decode(),
- }
+if hasattr(bottle, 'FileUpload'):
+ # bottle 0.12
+ def convert_file(key, file):
+ return {
+ 'name': file.name,
+ # file.filename lowercases the file name
+ # https://github.com/defnull/bottle/issues/582
+ # raw_filenames is a string on python 3
+ 'filename': file.raw_filename,
+ 'data': file.file.read().decode(),
+ }
+else:
+ # bottle 0.11
+ def convert_file(key, file):
+ return {
+ 'name': file.name,
+ 'filename': file.filename,
+ 'data': file.file.read().decode(),
+ }
@app.route('/files', method='post')
def files():
diff --git a/tests/fake-curl/curl-config-empty b/tests/fake-curl/curl-config-empty
new file mode 100755
index 0000000..cf93615
--- /dev/null
+++ b/tests/fake-curl/curl-config-empty
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# A curl-config that returns empty responses as much as possible
+
+output=
+
+while test -n "$1"; do
+ case "$1" in
+ --libs)
+ # --libs or --static-libs must succeed and produce output
+ echo '-lcurl'
+ ;;
+ esac
+ shift
+done
diff --git a/tests/fake-curl/curl-config-libs-and-static-libs b/tests/fake-curl/curl-config-libs-and-static-libs
new file mode 100755
index 0000000..56135e0
--- /dev/null
+++ b/tests/fake-curl/curl-config-libs-and-static-libs
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# A curl-config that returns different libraries in --libs and --static-libs
+
+output=
+
+while test -n "$1"; do
+ case "$1" in
+ --libs)
+ echo '-lcurl -lflurby'
+ ;;
+ --static-libs)
+ echo '-lkzzert'
+ ;;
+ esac
+ shift
+done
diff --git a/tests/fake-curl/curl-config-ssl-feature-only b/tests/fake-curl/curl-config-ssl-feature-only
new file mode 100755
index 0000000..3999f11
--- /dev/null
+++ b/tests/fake-curl/curl-config-ssl-feature-only
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# A curl-config that indicates SSL is supported but does not say
+# which SSL library is being used
+
+output=
+
+while test -n "$1"; do
+ case "$1" in
+ --libs)
+ echo '-lcurl'
+ ;;
+ --features)
+ echo 'SSL'
+ ;;
+ esac
+ shift
+done
diff --git a/tests/fake-curl/curl-config-ssl-in-libs b/tests/fake-curl/curl-config-ssl-in-libs
new file mode 100755
index 0000000..905024b
--- /dev/null
+++ b/tests/fake-curl/curl-config-ssl-in-libs
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# A curl-config that returns -lssl in --libs but not in --static-libs
+
+output=
+
+while test -n "$1"; do
+ case "$1" in
+ --libs)
+ echo '-lcurl -lssl'
+ ;;
+ esac
+ shift
+done
diff --git a/tests/fake-curl/curl-config-ssl-in-static-libs b/tests/fake-curl/curl-config-ssl-in-static-libs
new file mode 100755
index 0000000..b3c96c0
--- /dev/null
+++ b/tests/fake-curl/curl-config-ssl-in-static-libs
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# A curl-config that returns -lssl in --static-libs but not in --libs
+
+output=
+
+while test -n "$1"; do
+ case "$1" in
+ --libs)
+ echo '-lcurl'
+ ;;
+ --static-libs)
+ echo '-lssl'
+ ;;
+ esac
+ shift
+done
diff --git a/tests/ftp_test.py b/tests/ftp_test.py
index a88fc44..5a4d8e8 100644
--- a/tests/ftp_test.py
+++ b/tests/ftp_test.py
@@ -27,7 +27,7 @@ class FtpTest(unittest.TestCase):
result = sio.getvalue().decode()
assert 'README.rst' in result
- assert 'INSTALL' in result
+ assert 'INSTALL.rst' in result
# XXX this test needs to be fixed
def test_quote(self):
@@ -50,4 +50,4 @@ class FtpTest(unittest.TestCase):
result = sio.getvalue().decode()
assert 'README.rst' in result
- assert 'INSTALL' in result
+ assert 'INSTALL.rst' in result
diff --git a/tests/multi_option_constants_test.py b/tests/multi_option_constants_test.py
new file mode 100644
index 0000000..d44976c
--- /dev/null
+++ b/tests/multi_option_constants_test.py
@@ -0,0 +1,24 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# vi:ts=4:et
+
+import pycurl
+import unittest
+
+from . import util
+
+class MultiOptionConstantsTest(unittest.TestCase):
+ @util.min_libcurl(7, 30, 0)
+ def test_multi_pipeline_opts(self):
+ assert hasattr(pycurl, 'M_MAX_HOST_CONNECTIONS')
+ assert hasattr(pycurl, 'M_MAX_PIPELINE_LENGTH')
+ assert hasattr(pycurl, 'M_CONTENT_LENGTH_PENALTY_SIZE')
+ assert hasattr(pycurl, 'M_CHUNK_LENGTH_PENALTY_SIZE')
+ assert hasattr(pycurl, 'M_MAX_TOTAL_CONNECTIONS')
+ m = pycurl.CurlMulti()
+ m.setopt(pycurl.M_MAX_HOST_CONNECTIONS, 2)
+ m.setopt(pycurl.M_MAX_PIPELINE_LENGTH, 2)
+ m.setopt(pycurl.M_CONTENT_LENGTH_PENALTY_SIZE, 2)
+ m.setopt(pycurl.M_CHUNK_LENGTH_PENALTY_SIZE, 2)
+ m.setopt(pycurl.M_MAX_TOTAL_CONNECTIONS, 2)
+ m.close()
diff --git a/tests/setup_test.py b/tests/setup_test.py
new file mode 100644
index 0000000..d5b302e
--- /dev/null
+++ b/tests/setup_test.py
@@ -0,0 +1,103 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+# vi:ts=4:et
+
+import setup as pycurl_setup
+import unittest
+import os, os.path
+import nose.plugins.skip
+
+try:
+ import functools
+except ImportError:
+ import functools_backport as functools
+
+def set_env(key, new_value):
+ old_value = os.environ.get(key)
+ if new_value is not None:
+ os.environ[key] = new_value
+ elif old_value is not None:
+ del os.environ[key]
+ else:
+ # new and old values are None which mean the variable is not set
+ pass
+ return old_value
+
+def reset_env(key, old_value):
+ # empty string means environment variable was empty
+ # None means it was not set
+ if old_value is not None:
+ os.environ[key] = old_value
+ elif key in os.environ:
+ del os.environ[key]
+
+def using_curl_config(path, ssl_library=None):
+ path = os.path.join(os.path.dirname(__file__), 'fake-curl', path)
+ def decorator(fn):
+ @functools.wraps(fn)
+ def decorated(*args, **kwargs):
+ old_path = set_env('PYCURL_CURL_CONFIG', path)
+ old_ssl_library = set_env('PYCURL_SSL_LIBRARY', ssl_library)
+ try:
+ return fn(*args, **kwargs)
+ finally:
+ reset_env('PYCURL_CURL_CONFIG', old_path)
+ reset_env('PYCURL_SSL_LIBRARY', old_ssl_library)
+ return decorated
+ return decorator
+
+class SetupTest(unittest.TestCase):
+ def test_sanity_check(self):
+ config = pycurl_setup.ExtensionConfiguration()
+ # we should link against libcurl, one would expect
+ assert 'curl' in config.libraries
+
+ @using_curl_config('curl-config-empty')
+ def test_no_ssl(self):
+ config = pycurl_setup.ExtensionConfiguration()
+ # do not expect anything to do with ssl
+ assert 'ssl' not in config.libraries
+
+ @using_curl_config('curl-config-libs-and-static-libs')
+ def test_does_not_use_static_libs(self):
+ config = pycurl_setup.ExtensionConfiguration()
+ # should not link against any libraries from --static-libs if
+ # --libs succeeded
+ assert 'flurby' in config.libraries
+ assert 'kzzert' not in config.libraries
+
+ @using_curl_config('curl-config-ssl-in-libs')
+ def test_ssl_in_libs(self):
+ config = pycurl_setup.ExtensionConfiguration()
+ # should link against openssl
+ assert 'ssl' in config.libraries
+
+ @using_curl_config('curl-config-ssl-in-static-libs')
+ def test_ssl_in_static_libs(self):
+ config = pycurl_setup.ExtensionConfiguration()
+ # should link against openssl
+ assert 'ssl' in config.libraries
+
+ @using_curl_config('curl-config-empty')
+ def test_no_ssl_define(self):
+ config = pycurl_setup.ExtensionConfiguration()
+ # ssl define should be off
+ assert 'HAVE_CURL_SSL' not in config.define_symbols
+
+ @using_curl_config('curl-config-ssl-in-libs')
+ def test_ssl_in_libs_sets_ssl_define(self):
+ config = pycurl_setup.ExtensionConfiguration()
+ # ssl define should be on
+ assert 'HAVE_CURL_SSL' in config.define_symbols
+
+ @using_curl_config('curl-config-ssl-in-static-libs')
+ def test_ssl_in_static_libs_sets_ssl_define(self):
+ config = pycurl_setup.ExtensionConfiguration()
+ # ssl define should be on
+ assert 'HAVE_CURL_SSL' in config.define_symbols
+
+ @using_curl_config('curl-config-ssl-feature-only')
+ def test_ssl_feature_sets_ssl_define(self):
+ config = pycurl_setup.ExtensionConfiguration()
+ # ssl define should be on
+ assert 'HAVE_CURL_SSL' in config.define_symbols
diff --git a/winbuild.py b/winbuild.py
index 2ba10a4..7c41bf5 100644
--- a/winbuild.py
+++ b/winbuild.py
@@ -17,9 +17,9 @@ use_zlib = False
# which version of zlib to use, will be downloaded from internet
zlib_version = '1.2.8'
# which version of libcurl to use, will be downloaded from the internet
-libcurl_version = '7.34.0'
+libcurl_version = '7.35.0'
# pycurl version to build, we should know this ourselves
-pycurl_version = '7.19.3'
+pycurl_version = '7.19.3.1'
import os, os.path, sys, subprocess, shutil, contextlib
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pycurl.git
More information about the Python-modules-commits
mailing list