summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleg Pudeyev <code@olegp.name>2021-07-17 16:14:49 -0400
committerOleg Pudeyev <code@olegp.name>2021-07-17 16:14:49 -0400
commit9d20c737e150a3b9110d0b88f7218a590bb30121 (patch)
treefd1b9eff9c0a805c28b799d609b6d77183ba0c86
parent3a97433c3920b01303de0b8ba918ec03120fd167 (diff)
parent6b637a03ff8c6b640ca7a0f7e354351b2385109b (diff)
downloadpycurl-9d20c737e150a3b9110d0b88f7218a590bb30121.tar.gz
Merge branch 'master' into pr-655
* master: Depend on o-nose-show-skipped to get unreleased fixes i nose-show-skipped Best effort python 2 support. See #652 failonerror_test: skip the test with curl-7.75.0+ option_constants_test: skip check of SSLVERSION_SSLv* curl_version_info_struct lags behind curl #662 Allow to get CURLINFO_CONDITION_UNMET Remove bintray from docs docs: fix typos docs(quickstart): only show Python 3 code Expose MAX_CONCURRENT_STREAMS in CurlMulti src/module.c: make the code compile against python-3.10.0a1 Build documentation using specified Python version Use make -C for building fake-curl
-rw-r--r--INSTALL.rst5
-rw-r--r--Makefile10
-rw-r--r--README.kr.rst3
-rw-r--r--README.rst3
-rw-r--r--doc/index.rst5
-rw-r--r--doc/quickstart.rst62
-rw-r--r--setup.py14
-rw-r--r--src/easy.c2
-rw-r--r--src/easyinfo.c4
-rw-r--r--src/module.c40
-rw-r--r--src/multi.c13
-rw-r--r--src/pycurl.h4
-rw-r--r--tests/failonerror_test.py6
-rw-r--r--tests/option_constants_test.py9
-rwxr-xr-xtests/travis/run.sh2
-rw-r--r--tests/util.py15
16 files changed, 125 insertions, 72 deletions
diff --git a/INSTALL.rst b/INSTALL.rst
index f1d0acd..8f085c9 100644
--- a/INSTALL.rst
+++ b/INSTALL.rst
@@ -128,9 +128,6 @@ install PycURL by running:
pip install pycurl
-If you are not using pip, EXE and MSI installers are available in the
-`download area`_.
-
Both 32-bit and 64-bit builds of PycURL are available for Windows.
@@ -265,8 +262,6 @@ Prerequisites:
if this is not the case edit it as needed. ``winbuild.py`` itself can be run
with any Python it supports.
-.. _`download area`: https://dl.bintray.com/pycurl/pycurl/
-
Git Checkout
------------
diff --git a/Makefile b/Makefile
index 55537ed..77973d0 100644
--- a/Makefile
+++ b/Makefile
@@ -100,7 +100,7 @@ build-release: $(RELEASE_SOURCES)
PYCURL_RELEASE=1 $(PYTHON) setup.py build
do-test:
- cd tests/fake-curl/libcurl && make
+ make -C tests/fake-curl/libcurl
./tests/run.sh
./tests/ext/test-suite.sh
$(PYFLAKES) python examples tests setup.py
@@ -145,9 +145,9 @@ run-quickstart:
docs: build
mkdir -p build/docstrings
for file in doc/docstrings/*.rst; do tail -n +3 $$file >build/docstrings/`basename $$file`; done
- PYTHONSUFFIX=$$(python -V 2>&1 |awk '{print $$2}' |awk -F. '{print $$1 "." $$2}') && \
+ PYTHONSUFFIX=$$($(PYTHON) -V 2>&1 |awk '{print $$2}' |awk -F. '{print $$1 "." $$2}') && \
PYTHONPATH=$$(ls -d build/lib.*$$PYTHONSUFFIX):$$PYTHONPATH \
- sphinx-build doc build/doc
+ $(PYTHON) -m sphinx doc build/doc
cp ChangeLog build/doc
# Rebuild all documentation.
@@ -157,9 +157,9 @@ docs-force: build
# sphinx-docs has an -a option but it does not seem to always
# rebuild everything
rm -rf build/doc
- PYTHONSUFFIX=$$(python -V 2>&1 |awk '{print $$2}' |awk -F. '{print $$1 "." $$2}') && \
+ PYTHONSUFFIX=$$($(PYTHON) -V 2>&1 |awk '{print $$2}' |awk -F. '{print $$1 "." $$2}') && \
PYTHONPATH=$$(ls -d build/lib.*$$PYTHONSUFFIX):$$PYTHONPATH \
- sphinx-build doc build/doc
+ $(PYTHON) -m sphinx doc build/doc
cp ChangeLog build/doc
www: docs
diff --git a/README.kr.rst b/README.kr.rst
index 0684e66..536fe0a 100644
--- a/README.kr.rst
+++ b/README.kr.rst
@@ -34,13 +34,12 @@ urllib_ Python 모듈과 마찬가지로, PycURL 을 사용하여 Python프로
설치
----
-`PyPI`_ 또는 `Bintray`_ 에서 소스 및 바이너리 배포판을 다운로드 하십시오.
+`PyPI`_ 에서 소스 및 바이너리 배포판을 다운로드 하십시오.
이제 바이너리 휘을 32 비트 및 64 비트 Windows 버전에서 사용할 수 있습니다.
설치 지침은 `INSTALL.rst`_ 를 참조하십시오. Git checkout에서 설치하는 경우, INSTALL.rst 의 `Git Checkout`_ 섹션의 지침을 따르십시오.
.. _PyPI: https://pypi.python.org/pypi/pycurl
-.. _Bintray: https://dl.bintray.com/pycurl/pycurl/
.. _INSTALL.rst: http://pycurl.io/docs/latest/install.html
.. _Git Checkout: http://pycurl.io/docs/latest/install.html#git-checkout
diff --git a/README.rst b/README.rst
index 5262517..1aed703 100644
--- a/README.rst
+++ b/README.rst
@@ -39,7 +39,7 @@ Requirements
Installation
------------
-Download source and binary distributions from `PyPI`_ or `Bintray`_.
+Download source and binary distributions from `PyPI`_.
Binary wheels are now available for 32 and 64 bit Windows versions.
Please see `INSTALL.rst`_ for installation instructions. If installing from
@@ -47,7 +47,6 @@ a Git checkout, please follow instruction in the `Git Checkout`_ section
of INSTALL.rst.
.. _PyPI: https://pypi.python.org/pypi/pycurl
-.. _Bintray: https://dl.bintray.com/pycurl/pycurl/
.. _INSTALL.rst: http://pycurl.io/docs/latest/install.html
.. _Git Checkout: http://pycurl.io/docs/latest/install.html#git-checkout
diff --git a/doc/index.rst b/doc/index.rst
index 7dc1d73..1d26d74 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -78,11 +78,6 @@ On Windows, use pip to install a binary wheel for Python 2.7, 3.5 or 3.6::
pip install pycurl
-If not using pip, binary distributions in other formats are available
-`on Bintray`_.
-
-.. _on Bintray: https://dl.bintray.com/pycurl/pycurl/
-
Support
-------
diff --git a/doc/quickstart.rst b/doc/quickstart.rst
index 7170e36..22607f9 100644
--- a/doc/quickstart.rst
+++ b/doc/quickstart.rst
@@ -12,24 +12,29 @@ PycURL, the following steps are required:
2. Use ``setopt`` to set options.
3. Call ``perform`` to perform the operation.
-Here is how we can retrieve a network resource in Python 2::
+Here is how we can retrieve a network resource in Python 3::
import pycurl
- from StringIO import StringIO
+ import certifi
+ from io import BytesIO
- buffer = StringIO()
+ buffer = BytesIO()
c = pycurl.Curl()
c.setopt(c.URL, 'http://pycurl.io/')
c.setopt(c.WRITEDATA, buffer)
+ c.setopt(c.CAINFO, certifi.where())
c.perform()
c.close()
body = buffer.getvalue()
- # Body is a string in some encoding.
- # In Python 2, we can print it without knowing what the encoding is.
- print(body)
+ # Body is a byte string.
+ # We have to know the encoding in order to print it to a text file
+ # such as standard output.
+ print(body.decode('iso-8859-1'))
-This code is available as ``examples/quickstart/get_python2.py``.
+This code is available as ``examples/quickstart/get_python3.py``.
+For a Python 2 only example, see ``examples/quickstart/get_python2.py``.
+For an example targeting Python 2 and 3, see ``examples/quickstart/get.py``.
PycURL does not provide storage for the network response - that is the
application's job. Therefore we must setup a buffer (in the form of a
@@ -44,36 +49,6 @@ While the WRITEFUNCTION idiom continues to work, it is now unnecessary.
As of PycURL 7.19.3 WRITEDATA accepts any Python object with a ``write``
method.
-Python 3 version is slightly more complicated::
-
- import pycurl
- from io import BytesIO
-
- buffer = BytesIO()
- c = pycurl.Curl()
- c.setopt(c.URL, 'http://pycurl.io/')
- c.setopt(c.WRITEDATA, buffer)
- c.perform()
- c.close()
-
- body = buffer.getvalue()
- # Body is a byte string.
- # We have to know the encoding in order to print it to a text file
- # such as standard output.
- print(body.decode('iso-8859-1'))
-
-This code is available as ``examples/quickstart/get_python3.py``.
-
-In Python 3, PycURL returns the response body as a byte string.
-This is handy if we are downloading a binary file, but for text documents
-we must decode the byte string. In the above example, we assume that the
-body is encoded in iso-8859-1.
-
-Python 2 and Python 3 versions can be combined. Doing so requires decoding
-the response body as in Python 3 version. The code for the combined
-example can be found in ``examples/quickstart/get.py``.
-
-
Working With HTTPS
------------------
@@ -85,9 +60,9 @@ if not, consider using the `certifi`_ Python package::
import pycurl
import certifi
- from StringIO import StringIO
+ from io import BytesIO
- buffer = StringIO()
+ buffer = BytesIO()
c = pycurl.Curl()
c.setopt(c.URL, 'https://python.org/')
c.setopt(c.WRITEDATA, buffer)
@@ -96,10 +71,13 @@ if not, consider using the `certifi`_ Python package::
c.close()
body = buffer.getvalue()
- print(body)
+ # Body is a byte string.
+ # We have to know the encoding in order to print it to a text file
+ # such as standard output.
+ print(body.decode('iso-8859-1'))
-This code is available as ``examples/quickstart/get_python2_https.py`` and
-``examples/quickstart/get_python3_https.py``.
+This code is available as ``examples/quickstart/get_python3_https.py``.
+For a Python 2 example, see ``examples/quickstart/get_python2_https.py``.
Troubleshooting
diff --git a/setup.py b/setup.py
index e0d849f..1218377 100644
--- a/setup.py
+++ b/setup.py
@@ -511,6 +511,17 @@ manually. For other SSL backends please ignore this message.''')
('libidn', ctypes.c_char_p),
('iconv_ver_num', ctypes.c_int),
('libssh_version', ctypes.c_char_p),
+ ('brotli_ver_num', ctypes.c_uint),
+ ('brotli_version', ctypes.c_char_p),
+ ('nghttp2_ver_num', ctypes.c_uint),
+ ('nghttp2_version', ctypes.c_char_p),
+ ('quic_version', ctypes.c_char_p),
+ ('cainfo', ctypes.c_char_p),
+ ('capath', ctypes.c_char_p),
+ ('zstd_ver_num', ctypes.c_uint),
+ ('zstd_version', ctypes.c_char_p),
+ ('hyper_version', ctypes.c_char_p),
+ ('gsasl_version', ctypes.c_char_p),
]
dll = ctypes.CDLL(dll_path)
@@ -850,13 +861,12 @@ Requirements
Installation
------------
-Download source and binary distributions from `PyPI`_ or `Bintray`_.
+Download source and binary distributions from `PyPI`_.
Binary wheels are now available for 32 and 64 bit Windows versions.
Please see `the installation documentation`_ for installation instructions.
.. _PyPI: https://pypi.python.org/pypi/pycurl
-.. _Bintray: https://dl.bintray.com/pycurl/pycurl/
.. _the installation documentation: http://pycurl.io/docs/latest/install.html
diff --git a/src/easy.c b/src/easy.c
index 7d10418..a22ad9c 100644
--- a/src/easy.c
+++ b/src/easy.c
@@ -43,7 +43,7 @@ check_curl_state(const CurlObject *self, int flags, const char *name)
/* --------------- construct/destruct (i.e. open/close) --------------- */
-/* initializer - used to intialize curl easy handles for use with pycurl */
+/* initializer - used to initialize curl easy handles for use with pycurl */
static int
util_curl_init(CurlObject *self)
{
diff --git a/src/easyinfo.c b/src/easyinfo.c
index 3712646..5412a5a 100644
--- a/src/easyinfo.c
+++ b/src/easyinfo.c
@@ -157,7 +157,9 @@ do_curl_getinfo_raw(CurlObject *self, PyObject *args)
#ifdef HAVE_CURLINFO_HTTP_VERSION
case CURLINFO_HTTP_VERSION:
#endif
-
+#ifdef HAVE_CURL_7_19_4_OPTS
+ case CURLINFO_CONDITION_UNMET:
+#endif
{
/* Return PyInt as result */
long l_res = -1;
diff --git a/src/module.c b/src/module.c
index 65e8c3a..8bb0fd3 100644
--- a/src/module.c
+++ b/src/module.c
@@ -11,6 +11,12 @@
#define PYCURL_VERSION_PREFIX "PycURL/" PYCURL_VERSION_STRING
+/* needed for compatibility with python < 3.10, as suggested at:
+ * https://docs.python.org/3.10/whatsnew/3.10.html#id2 */
+#if PY_VERSION_HEX < 0x030900A4
+# define Py_SET_TYPE(obj, type) ((Py_TYPE(obj) = (type)), (void)0)
+#endif
+
PYCURL_INTERNAL char *empty_keywords[] = { NULL };
PYCURL_INTERNAL PyObject *bytesio = NULL;
@@ -412,9 +418,9 @@ initpycurl(void)
p_Curl_Type = &Curl_Type;
p_CurlMulti_Type = &CurlMulti_Type;
p_CurlShare_Type = &CurlShare_Type;
- Py_TYPE(&Curl_Type) = &PyType_Type;
- Py_TYPE(&CurlMulti_Type) = &PyType_Type;
- Py_TYPE(&CurlShare_Type) = &PyType_Type;
+ Py_SET_TYPE(&Curl_Type, &PyType_Type);
+ Py_SET_TYPE(&CurlMulti_Type, &PyType_Type);
+ Py_SET_TYPE(&CurlShare_Type, &PyType_Type);
/* Create the module and add the functions */
if (PyType_Ready(&Curl_Type) < 0)
@@ -1065,6 +1071,9 @@ initpycurl(void)
insint_m(d, "M_PIPELINING_SITE_BL", CURLMOPT_PIPELINING_SITE_BL);
insint_m(d, "M_PIPELINING_SERVER_BL", CURLMOPT_PIPELINING_SERVER_BL);
#endif
+#ifdef HAVE_CURL_7_67_0_MULTI_STREAMS
+ insint_m(d, "M_MAX_CONCURRENT_STREAMS", CURLMOPT_MAX_CONCURRENT_STREAMS);
+#endif
#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 43, 0)
insint_m(d, "PIPE_NOTHING", CURLPIPE_NOTHING);
@@ -1362,6 +1371,31 @@ initpycurl(void)
#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 47, 0)
insint(d, "VERSION_PSL", CURL_VERSION_PSL);
#endif
+#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0)
+ insint(d, "CURL_VERSION_HTTPS_PROXY", CURL_VERSION_HTTPS_PROXY);
+#endif
+#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 56, 0)
+ insint(d, "CURL_VERSION_MULTI_SSL", CURL_VERSION_MULTI_SSL);
+#endif
+#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 57, 0)
+ insint(d, "CURL_VERSION_BROTLI", CURL_VERSION_BROTLI);
+#endif
+#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 64, 1)
+ insint(d, "CURL_VERSION_ALTSVC", CURL_VERSION_ALTSVC);
+#endif
+#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 66, 0)
+ insint(d, "CURL_VERSION_HTTP3", CURL_VERSION_HTTP3);
+#endif
+#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 72, 0)
+ insint(d, "CURL_VERSION_UNICODE", CURL_VERSION_UNICODE);
+ insint(d, "CURL_VERSION_ZSTD", CURL_VERSION_ZSTD);
+#endif
+#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 74, 0)
+ insint(d, "CURL_VERSION_HSTS", CURL_VERSION_HSTS);
+#endif
+#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 76, 0)
+ insint(d, "CURL_VERSION_GSASL", CURL_VERSION_GSASL);
+#endif
/**
** the order of these constants mostly follows <curl/multi.h>
diff --git a/src/multi.c b/src/multi.c
index 5181119..4bade73 100644
--- a/src/multi.c
+++ b/src/multi.c
@@ -276,6 +276,9 @@ do_multi_setopt_int(CurlMultiObject *self, int option, PyObject *obj)
case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
#endif
+#ifdef HAVE_CURL_7_67_0_MULTI_STREAMS
+ case CURLMOPT_MAX_CONCURRENT_STREAMS:
+#endif
curl_multi_setopt(self->multi_handle, option, d);
break;
default:
@@ -806,11 +809,17 @@ do_multi_info_read(CurlMultiObject *self, PyObject *args)
}
else {
/* Create a result tuple that will get added to err_list. */
- PyObject *error_str = PyUnicode_DecodeLocale(co->error, "surrogateescape");
+ PyObject *error_str = NULL;
+ PyObject *v;
+#if PY_MAJOR_VERSION >= 3
+ error_str = PyUnicode_DecodeLocale(co->error, "surrogateescape");
if (error_str == NULL) {
goto error;
}
- PyObject *v = Py_BuildValue("(OiO)", (PyObject *)co, (int)msg->data.result, error_str);
+ v = Py_BuildValue("(OiO)", (PyObject *)co, (int)msg->data.result, error_str);
+#else
+ v = Py_BuildValue("(Ois)", (PyObject *)co, (int)msg->data.result, co->error);
+#endif
/* Append curl object to list of objects which failed */
if (v == NULL || PyList_Append(err_list, v) != 0) {
Py_XDECREF(error_str);
diff --git a/src/pycurl.h b/src/pycurl.h
index 95e08b3..31d1eac 100644
--- a/src/pycurl.h
+++ b/src/pycurl.h
@@ -163,6 +163,10 @@ pycurl_inet_ntop (int family, void *addr, char *string, size_t string_size);
#define HAVE_CURL_GLOBAL_SSLSET
#endif
+#if LIBCURL_VERSION_NUM >= 0x074300 /* check for 7.67.0 or greater */
+#define HAVE_CURL_7_67_0_MULTI_STREAMS
+#endif
+
#undef UNUSED
#define UNUSED(var) ((void)&var)
diff --git a/tests/failonerror_test.py b/tests/failonerror_test.py
index dc4d8cd..519aed8 100644
--- a/tests/failonerror_test.py
+++ b/tests/failonerror_test.py
@@ -21,6 +21,8 @@ class FailonerrorTest(unittest.TestCase):
# not sure what the actual min is but 7.26 is too old
# and does not include status text, only the status code
@util.min_libcurl(7, 38, 0)
+ # no longer supported by libcurl: https://github.com/curl/curl/issues/6615
+ @util.removed_in_libcurl(7, 75, 0)
def test_failonerror(self):
self.curl.setopt(pycurl.URL, 'http://%s:8380/status/403' % localhost)
sio = util.BytesIO()
@@ -41,6 +43,8 @@ class FailonerrorTest(unittest.TestCase):
# not sure what the actual min is but 7.26 is too old
# and does not include status text, only the status code
@util.min_libcurl(7, 38, 0)
+ # no longer supported by libcurl: https://github.com/curl/curl/issues/6615
+ @util.removed_in_libcurl(7, 75, 0)
def test_failonerror_status_line_invalid_utf8_python2(self):
self.curl.setopt(pycurl.URL, 'http://%s:8380/status_invalid_utf8' % localhost)
sio = util.BytesIO()
@@ -61,6 +65,8 @@ class FailonerrorTest(unittest.TestCase):
# not sure what the actual min is but 7.26 is too old
# and does not include status text, only the status code
@util.min_libcurl(7, 38, 0)
+ # no longer supported by libcurl: https://github.com/curl/curl/issues/6615
+ @util.removed_in_libcurl(7, 75, 0)
def test_failonerror_status_line_invalid_utf8_python3(self):
self.curl.setopt(pycurl.URL, 'http://%s:8380/status_invalid_utf8' % localhost)
sio = util.BytesIO()
diff --git a/tests/option_constants_test.py b/tests/option_constants_test.py
index 6791c31..b8aab1e 100644
--- a/tests/option_constants_test.py
+++ b/tests/option_constants_test.py
@@ -163,9 +163,16 @@ class OptionConstantsTest(unittest.TestCase):
def test_sslversion_options(self):
curl = pycurl.Curl()
curl.setopt(curl.SSLVERSION, curl.SSLVERSION_DEFAULT)
+ curl.setopt(curl.SSLVERSION, curl.SSLVERSION_TLSv1)
+ curl.close()
+
+ # SSLVERSION_SSLv* return CURLE_BAD_FUNCTION_ARGUMENT with curl-7.77.0
+ @util.removed_in_libcurl(7, 77, 0)
+ @util.only_ssl
+ def test_legacy_sslversion_options(self):
+ curl = pycurl.Curl()
curl.setopt(curl.SSLVERSION, curl.SSLVERSION_SSLv2)
curl.setopt(curl.SSLVERSION, curl.SSLVERSION_SSLv3)
- curl.setopt(curl.SSLVERSION, curl.SSLVERSION_TLSv1)
curl.close()
@util.min_libcurl(7, 34, 0)
diff --git a/tests/travis/run.sh b/tests/travis/run.sh
index 7eaf7ad..c71630f 100755
--- a/tests/travis/run.sh
+++ b/tests/travis/run.sh
@@ -45,7 +45,7 @@ fi
make gen
python setup.py build $setup_args
-(cd tests/fake-curl/libcurl && make)
+make -C tests/fake-curl/libcurl
ldd build/lib*/pycurl*.so
diff --git a/tests/util.py b/tests/util.py
index c53b96a..542175f 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -115,6 +115,21 @@ def min_libcurl(major, minor, patch):
return decorator
+def removed_in_libcurl(major, minor, patch):
+ import nose.plugins.skip
+
+ def decorator(fn):
+ @functools.wraps(fn)
+ def decorated(*args, **kwargs):
+ if not pycurl_version_less_than(major, minor, patch):
+ raise nose.plugins.skip.SkipTest('libcurl >= %d.%d.%d' % (major, minor, patch))
+
+ return fn(*args, **kwargs)
+
+ return decorated
+
+ return decorator
+
def only_ssl(fn):
import pycurl