[pypy-commit] pypy reflex-support: merge default into branch
wlav
noreply at buildbot.pypy.org
Wed Dec 18 23:18:14 CET 2013
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r68472:db156904ed81
Date: 2013-12-18 12:27 -0800
http://bitbucket.org/pypy/pypy/changeset/db156904ed81/
Log: merge default into branch
diff too long, truncating to 2000 out of 47038 lines
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,38 @@
all: pypy-c
+PYPY_EXECUTABLE := $(shell which pypy)
+URAM := $(shell python -c "import sys; print 4.5 if sys.maxint>1<<32 else 2.5")
+
+ifeq ($(PYPY_EXECUTABLE),)
+RUNINTERP = python
+else
+RUNINTERP = $(PYPY_EXECUTABLE)
+endif
+
pypy-c:
- @echo "Building PyPy with JIT, it'll take about 40 minutes and 4G of RAM"
- @sleep 3
- rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py
+ @echo
+ @echo "===================================================================="
+ifeq ($(PYPY_EXECUTABLE),)
+ @echo "Building a regular (jitting) version of PyPy, using CPython."
+ @echo "This takes around 2 hours and $(URAM) GB of RAM."
+ @echo "Note that pre-installing a PyPy binary would reduce this time"
+ @echo "and produce basically the same result."
+else
+ @echo "Building a regular (jitting) version of PyPy, using"
+ @echo "$(PYPY_EXECUTABLE) to run the translation itself."
+ @echo "This takes up to 1 hour and $(URAM) GB of RAM."
+endif
+ @echo
+ @echo "For more control (e.g. to use multiple CPU cores during part of"
+ @echo "the process) you need to run \`\`rpython/bin/rpython'' directly."
+ @echo "For more information see \`\`http://pypy.org/download.html''."
+ @echo "===================================================================="
+ @echo
+ @sleep 5
+ $(RUNINTERP) rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py
+
+# Note: the -jN option, or MAKEFLAGS=-jN, are not usable. They are
+# replaced with an opaque --jobserver option by the time this Makefile
+# runs. We cannot get their original value either:
+# http://lists.gnu.org/archive/html/help-make/2010-08/msg00106.html
diff --git a/README.rst b/README.rst
--- a/README.rst
+++ b/README.rst
@@ -1,5 +1,5 @@
=====================================
-PyPy: Python in Python Implementation
+PyPy: Python in Python Implementation
=====================================
Welcome to PyPy!
@@ -26,12 +26,14 @@
Building
========
-build with::
+build with:
- rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py
+.. code-block:: console
+
+ $ rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py
This ends up with ``pypy-c`` binary in the main pypy directory. We suggest
-to use virtualenv with the resulting pypy-c as the interpreter, you can
+to use virtualenv with the resulting pypy-c as the interpreter; you can
find more details about various installation schemes here:
http://doc.pypy.org/en/latest/getting-started.html#installing-pypy
diff --git a/lib-python/2.7/ctypes/test/test_python_api.py b/lib-python/2.7/ctypes/test/test_python_api.py
--- a/lib-python/2.7/ctypes/test/test_python_api.py
+++ b/lib-python/2.7/ctypes/test/test_python_api.py
@@ -73,6 +73,7 @@
del pyobj
self.assertEqual(grc(s), ref)
+ @xfail
def test_PyOS_snprintf(self):
PyOS_snprintf = pythonapi.PyOS_snprintf
PyOS_snprintf.argtypes = POINTER(c_char), c_size_t, c_char_p
diff --git a/lib-python/2.7/json/encoder.py b/lib-python/2.7/json/encoder.py
--- a/lib-python/2.7/json/encoder.py
+++ b/lib-python/2.7/json/encoder.py
@@ -4,6 +4,21 @@
from __pypy__.builders import StringBuilder, UnicodeBuilder
+class StringOrUnicodeBuilder(object):
+ def __init__(self):
+ self._builder = StringBuilder()
+ def append(self, string):
+ try:
+ self._builder.append(string)
+ except UnicodeEncodeError:
+ ub = UnicodeBuilder()
+ ub.append(self._builder.build())
+ self._builder = ub
+ ub.append(string)
+ def build(self):
+ return self._builder.build()
+
+
ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')
ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
HAS_UTF8 = re.compile(r'[\x80-\xff]')
@@ -192,7 +207,7 @@
if self.ensure_ascii:
builder = StringBuilder()
else:
- builder = UnicodeBuilder()
+ builder = StringOrUnicodeBuilder()
self.__encode(o, markers, builder, 0)
return builder.build()
diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py
--- a/lib-python/2.7/socket.py
+++ b/lib-python/2.7/socket.py
@@ -335,9 +335,10 @@
s = self._sock
self._sock = None
if s is not None:
- s._drop()
if self._close:
s.close()
+ else:
+ s._drop()
def __del__(self):
try:
diff --git a/lib-python/2.7/string.py b/lib-python/2.7/string.py
--- a/lib-python/2.7/string.py
+++ b/lib-python/2.7/string.py
@@ -66,16 +66,17 @@
must be of the same length.
"""
- if len(fromstr) != len(tostr):
+ n = len(fromstr)
+ if n != len(tostr):
raise ValueError, "maketrans arguments must have same length"
- global _idmapL
- if not _idmapL:
- _idmapL = list(_idmap)
- L = _idmapL[:]
- fromstr = map(ord, fromstr)
- for i in range(len(fromstr)):
- L[fromstr[i]] = tostr[i]
- return ''.join(L)
+ # this function has been rewritten to suit PyPy better; it is
+ # almost 10x faster than the original.
+ buf = bytearray(256)
+ for i in range(256):
+ buf[i] = i
+ for i in range(n):
+ buf[ord(fromstr[i])] = tostr[i]
+ return str(buf)
diff --git a/lib-python/2.7/test/keycert.pem b/lib-python/2.7/test/keycert.pem
--- a/lib-python/2.7/test/keycert.pem
+++ b/lib-python/2.7/test/keycert.pem
@@ -1,32 +1,31 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXwIBAAKBgQC8ddrhm+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9L
-opdJhTvbGfEj0DQs1IE8M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVH
-fhi/VwovESJlaBOp+WMnfhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQAB
-AoGBAK0FZpaKj6WnJZN0RqhhK+ggtBWwBnc0U/ozgKz2j1s3fsShYeiGtW6CK5nU
-D1dZ5wzhbGThI7LiOXDvRucc9n7vUgi0alqPQ/PFodPxAN/eEYkmXQ7W2k7zwsDA
-IUK0KUhktQbLu8qF/m8qM86ba9y9/9YkXuQbZ3COl5ahTZrhAkEA301P08RKv3KM
-oXnGU2UHTuJ1MAD2hOrPxjD4/wxA/39EWG9bZczbJyggB4RHu0I3NOSFjAm3HQm0
-ANOu5QK9owJBANgOeLfNNcF4pp+UikRFqxk5hULqRAWzVxVrWe85FlPm0VVmHbb/
-loif7mqjU8o1jTd/LM7RD9f2usZyE2psaw8CQQCNLhkpX3KO5kKJmS9N7JMZSc4j
-oog58yeYO8BBqKKzpug0LXuQultYv2K4veaIO04iL9VLe5z9S/Q1jaCHBBuXAkEA
-z8gjGoi1AOp6PBBLZNsncCvcV/0aC+1se4HxTNo2+duKSDnbq+ljqOM+E7odU+Nq
-ewvIWOG//e8fssd0mq3HywJBAJ8l/c8GVmrpFTx8r/nZ2Pyyjt3dH1widooDXYSV
-q6Gbf41Llo5sYAtmxdndTLASuHKecacTgZVhy0FryZpLKrU=
------END RSA PRIVATE KEY-----
+-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANtb0+YrKuxevGpm
+LrjaUhZSgz6zFAmuGFmKmUbdjmfv9zSmmdsQIksK++jK0Be9LeZy20j6ahOfuVa0
+ufEmPoP7Fy4hXegKZR9cCWcIe/A6H2xWF1IIJLRTLaU8ol/I7T+um5HD5AwAwNPP
+USNU0Eegmvp+xxWu3NX2m1Veot85AgMBAAECgYA3ZdZ673X0oexFlq7AAmrutkHt
+CL7LvwrpOiaBjhyTxTeSNWzvtQBkIU8DOI0bIazA4UreAFffwtvEuPmonDb3F+Iq
+SMAu42XcGyVZEl+gHlTPU9XRX7nTOXVt+MlRRRxL6t9GkGfUAXI3XxJDXW3c0vBK
+UL9xqD8cORXOfE06rQJBAP8mEX1ERkR64Ptsoe4281vjTlNfIbs7NMPkUnrn9N/Y
+BLhjNIfQ3HFZG8BTMLfX7kCS9D593DW5tV4Z9BP/c6cCQQDcFzCcVArNh2JSywOQ
+ZfTfRbJg/Z5Lt9Fkngv1meeGNPgIMLN8Sg679pAOOWmzdMO3V706rNPzSVMME7E5
+oPIfAkEA8pDddarP5tCvTTgUpmTFbakm0KoTZm2+FzHcnA4jRh+XNTjTOv98Y6Ik
+eO5d1ZnKXseWvkZncQgxfdnMqqpj5wJAcNq/RVne1DbYlwWchT2Si65MYmmJ8t+F
+0mcsULqjOnEMwf5e+ptq5LzwbyrHZYq5FNk7ocufPv/ZQrcSSC+cFwJBAKvOJByS
+x56qyGeZLOQlWS2JS3KJo59XuLFGqcbgN9Om9xFa41Yb4N9NvplFivsvZdw3m1Q/
+SPIXQuT8RMPDVNQ=
+-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
-MIICpzCCAhCgAwIBAgIJAP+qStv1cIGNMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD
-VQQGEwJVUzERMA8GA1UECBMIRGVsYXdhcmUxEzARBgNVBAcTCldpbG1pbmd0b24x
-IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMQwwCgYDVQQLEwNT
-U0wxHzAdBgNVBAMTFnNvbWVtYWNoaW5lLnB5dGhvbi5vcmcwHhcNMDcwODI3MTY1
-NDUwWhcNMTMwMjE2MTY1NDUwWjCBiTELMAkGA1UEBhMCVVMxETAPBgNVBAgTCERl
-bGF3YXJlMRMwEQYDVQQHEwpXaWxtaW5ndG9uMSMwIQYDVQQKExpQeXRob24gU29m
-dHdhcmUgRm91bmRhdGlvbjEMMAoGA1UECxMDU1NMMR8wHQYDVQQDExZzb21lbWFj
-aGluZS5weXRob24ub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8ddrh
-m+LutBvjYcQlnH21PPIseJ1JVG2HMmN2CmZk2YukO+9LopdJhTvbGfEj0DQs1IE8
-M+kTUyOmuKfVrFMKwtVeCJphrAnhoz7TYOuLBSqt7lVHfhi/VwovESJlaBOp+WMn
-fhcduPEYHYx/6cnVapIkZnLt30zu2um+DzA9jQIDAQABoxUwEzARBglghkgBhvhC
-AQEEBAMCBkAwDQYJKoZIhvcNAQEFBQADgYEAF4Q5BVqmCOLv1n8je/Jw9K669VXb
-08hyGzQhkemEBYQd6fzQ9A/1ZzHkJKb1P6yreOLSEh4KcxYPyrLRC1ll8nr5OlCx
-CMhKkTnR6qBsdNV0XtdU2+N25hqW+Ma4ZeqsN/iiJVCGNOZGnvQuvCAGWF8+J/f/
-iHkC6gGdBJhogs4=
+MIICVDCCAb2gAwIBAgIJANfHOBkZr8JOMA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNV
+BAYTAlhZMRcwFQYDVQQHEw5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9u
+IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMDEw
+MDgyMzAxNTZaFw0yMDEwMDUyMzAxNTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH
+Ew5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9uIFNvZnR3YXJlIEZvdW5k
+YXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+gYkCgYEA21vT5isq7F68amYuuNpSFlKDPrMUCa4YWYqZRt2OZ+/3NKaZ2xAiSwr7
+6MrQF70t5nLbSPpqE5+5VrS58SY+g/sXLiFd6AplH1wJZwh78DofbFYXUggktFMt
+pTyiX8jtP66bkcPkDADA089RI1TQR6Ca+n7HFa7c1fabVV6i3zkCAwEAAaMYMBYw
+FAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBBQUAA4GBAHPctQBEQ4wd
+BJ6+JcpIraopLn8BGhbjNWj40mmRqWB/NAWF6M5ne7KpGAu7tLeG4hb1zLaldK8G
+lxy2GPSRF6LFS48dpEj2HbMv2nvv6xxalDMJ9+DicWgAKTQ6bcX2j3GUkCR0g/T1
+CRlNBAAlvhKzO7Clpf9l0YKBEfraJByX
-----END CERTIFICATE-----
diff --git a/lib-python/2.7/test/sha256.pem b/lib-python/2.7/test/sha256.pem
--- a/lib-python/2.7/test/sha256.pem
+++ b/lib-python/2.7/test/sha256.pem
@@ -1,129 +1,128 @@
# Certificate chain for https://sha256.tbs-internet.com
- 0 s:/C=FR/postalCode=14000/ST=Calvados/L=CAEN/street=22 rue de Bretagne/O=TBS INTERNET/OU=0002 440443810/OU=sha-256 production/CN=sha256.tbs-internet.com
- i:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA SGC
+ 0 s:/C=FR/postalCode=14000/ST=Calvados/L=CAEN/street=22 rue de Bretagne/O=TBS INTERNET/OU=0002 440443810/OU=Certificats TBS X509/CN=ecom.tbs-x509.com
+ i:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA business
-----BEGIN CERTIFICATE-----
-MIIGXTCCBUWgAwIBAgIRAMmag+ygSAdxZsbyzYjhuW0wDQYJKoZIhvcNAQELBQAw
-gcQxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl
+MIIGTjCCBTagAwIBAgIQOh3d9dNDPq1cSdJmEiMpqDANBgkqhkiG9w0BAQUFADCB
+yTELMAkGA1UEBhMCRlIxETAPBgNVBAgTCENhbHZhZG9zMQ0wCwYDVQQHEwRDYWVu
+MRUwEwYDVQQKEwxUQlMgSU5URVJORVQxSDBGBgNVBAsTP1Rlcm1zIGFuZCBDb25k
+aXRpb25zOiBodHRwOi8vd3d3LnRicy1pbnRlcm5ldC5jb20vQ0EvcmVwb3NpdG9y
+eTEYMBYGA1UECxMPVEJTIElOVEVSTkVUIENBMR0wGwYDVQQDExRUQlMgWDUwOSBD
+QSBidXNpbmVzczAeFw0xMTAxMjUwMDAwMDBaFw0xMzAyMDUyMzU5NTlaMIHHMQsw
+CQYDVQQGEwJGUjEOMAwGA1UEERMFMTQwMDAxETAPBgNVBAgTCENhbHZhZG9zMQ0w
+CwYDVQQHEwRDQUVOMRswGQYDVQQJExIyMiBydWUgZGUgQnJldGFnbmUxFTATBgNV
+BAoTDFRCUyBJTlRFUk5FVDEXMBUGA1UECxMOMDAwMiA0NDA0NDM4MTAxHTAbBgNV
+BAsTFENlcnRpZmljYXRzIFRCUyBYNTA5MRowGAYDVQQDExFlY29tLnRicy14NTA5
+LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKRrlHUnJ++1lpcg
+jtYco7cdmRe+EEfTmwPfCdfV3G1QfsTSvY6FfMpm/83pqHfT+4ANwr18wD9ZrAEN
+G16mf9VdCGK12+TP7DmqeZyGIqlFFoahQnmb8EarvE43/1UeQ2CV9XmzwZvpqeli
+LfXsFonawrY3H6ZnMwS64St61Z+9gdyuZ/RbsoZBbT5KUjDEG844QRU4OT1IGeEI
+eY5NM5RNIh6ZNhVtqeeCxMS7afONkHQrOco73RdSTRck/Hj96Ofl3MHNHryr+AMK
+DGFk1kLCZGpPdXtkxXvaDeQoiYDlil26CWc+YK6xyDPMdsWvoG14ZLyCpzMXA7/7
+4YAQRH0CAwEAAaOCAjAwggIsMB8GA1UdIwQYMBaAFBoJBMz5CY+7HqDO1KQUf0vV
+I1jNMB0GA1UdDgQWBBQgOU8HsWzbmD4WZP5Wtdw7jca2WDAOBgNVHQ8BAf8EBAMC
+BaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
+TAYDVR0gBEUwQzBBBgsrBgEEAYDlNwIBATAyMDAGCCsGAQUFBwIBFiRodHRwczov
+L3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL0NQUzEwdwYDVR0fBHAwbjA3oDWgM4Yx
+aHR0cDovL2NybC50YnMtaW50ZXJuZXQuY29tL1RCU1g1MDlDQWJ1c2luZXNzLmNy
+bDAzoDGgL4YtaHR0cDovL2NybC50YnMteDUwOS5jb20vVEJTWDUwOUNBYnVzaW5l
+c3MuY3JsMIGwBggrBgEFBQcBAQSBozCBoDA9BggrBgEFBQcwAoYxaHR0cDovL2Ny
+dC50YnMtaW50ZXJuZXQuY29tL1RCU1g1MDlDQWJ1c2luZXNzLmNydDA5BggrBgEF
+BQcwAoYtaHR0cDovL2NydC50YnMteDUwOS5jb20vVEJTWDUwOUNBYnVzaW5lc3Mu
+Y3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC50YnMteDUwOS5jb20wMwYDVR0R
+BCwwKoIRZWNvbS50YnMteDUwOS5jb22CFXd3dy5lY29tLnRicy14NTA5LmNvbTAN
+BgkqhkiG9w0BAQUFAAOCAQEArT4NHfbY87bGAw8lPV4DmHlmuDuVp/y7ltO3Ynse
+3Rz8RxW2AzuO0Oy2F0Cu4yWKtMyEyMXyHqWtae7ElRbdTu5w5GwVBLJHClCzC8S9
+SpgMMQTx3Rgn8vjkHuU9VZQlulZyiPK7yunjc7c310S9FRZ7XxOwf8Nnx4WnB+No
+WrfApzhhQl31w+RyrNxZe58hCfDDHmevRvwLjQ785ZoQXJDj2j3qAD4aI2yB8lB5
+oaE1jlCJzC7Kmz/Y9jzfmv/zAs1LQTm9ktevv4BTUFaGjv9jxnQ1xnS862ZiouLW
+zZYIlYPf4F6JjXGiIQgQRglILUfq3ftJd9/ok9W9ZF8h8w==
+-----END CERTIFICATE-----
+ 1 s:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA business
+ i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
+-----BEGIN CERTIFICATE-----
+MIIFPzCCBCegAwIBAgIQDlBz/++iRSmLDeVRHT/hADANBgkqhkiG9w0BAQUFADBv
+MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
+ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
+eHRlcm5hbCBDQSBSb290MB4XDTA1MTIwMTAwMDAwMFoXDTE5MDcwOTE4MTkyMlow
+gckxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl
bjEVMBMGA1UEChMMVEJTIElOVEVSTkVUMUgwRgYDVQQLEz9UZXJtcyBhbmQgQ29u
ZGl0aW9uczogaHR0cDovL3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL3JlcG9zaXRv
-cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEYMBYGA1UEAxMPVEJTIFg1MDkg
-Q0EgU0dDMB4XDTEwMDIxODAwMDAwMFoXDTEyMDIxOTIzNTk1OVowgcsxCzAJBgNV
-BAYTAkZSMQ4wDAYDVQQREwUxNDAwMDERMA8GA1UECBMIQ2FsdmFkb3MxDTALBgNV
-BAcTBENBRU4xGzAZBgNVBAkTEjIyIHJ1ZSBkZSBCcmV0YWduZTEVMBMGA1UEChMM
-VEJTIElOVEVSTkVUMRcwFQYDVQQLEw4wMDAyIDQ0MDQ0MzgxMDEbMBkGA1UECxMS
-c2hhLTI1NiBwcm9kdWN0aW9uMSAwHgYDVQQDExdzaGEyNTYudGJzLWludGVybmV0
-LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbuM8VT7f0nntwu
-N3F7v9KIBlhKNAxqCrziOXU5iqUt8HrQB3DtHbdmII+CpVUlwlmepsx6G+srEZ9a
-MIGAy0nxi5aLb7watkyIdPjJTMvTUBQ/+RPWzt5JtYbbY9BlJ+yci0dctP74f4NU
-ISLtlrEjUbf2gTohLrcE01TfmOF6PDEbB5PKDi38cB3NzKfizWfrOaJW6Q1C1qOJ
-y4/4jkUREX1UFUIxzx7v62VfjXSGlcjGpBX1fvtABQOSLeE0a6gciDZs1REqroFf
-5eXtqYphpTa14Z83ITXMfgg5Nze1VtMnzI9Qx4blYBw4dgQVEuIsYr7FDBOITDzc
-VEVXZx0CAwEAAaOCAj8wggI7MB8GA1UdIwQYMBaAFAdEdoWTKLx/bXjSCuv6TEvf
-2YIfMB0GA1UdDgQWBBSJKI/AYVI9RQNY0QPIqc8ej2QivTAOBgNVHQ8BAf8EBAMC
-BaAwDAYDVR0TAQH/BAIwADA0BgNVHSUELTArBggrBgEFBQcDAQYIKwYBBQUHAwIG
-CisGAQQBgjcKAwMGCWCGSAGG+EIEATBMBgNVHSAERTBDMEEGCysGAQQBgOU3AgQB
-MDIwMAYIKwYBBQUHAgEWJGh0dHBzOi8vd3d3LnRicy1pbnRlcm5ldC5jb20vQ0Ev
-Q1BTNDBtBgNVHR8EZjBkMDKgMKAuhixodHRwOi8vY3JsLnRicy1pbnRlcm5ldC5j
-b20vVEJTWDUwOUNBU0dDLmNybDAuoCygKoYoaHR0cDovL2NybC50YnMteDUwOS5j
-b20vVEJTWDUwOUNBU0dDLmNybDCBpgYIKwYBBQUHAQEEgZkwgZYwOAYIKwYBBQUH
-MAKGLGh0dHA6Ly9jcnQudGJzLWludGVybmV0LmNvbS9UQlNYNTA5Q0FTR0MuY3J0
-MDQGCCsGAQUFBzAChihodHRwOi8vY3J0LnRicy14NTA5LmNvbS9UQlNYNTA5Q0FT
-R0MuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC50YnMteDUwOS5jb20wPwYD
-VR0RBDgwNoIXc2hhMjU2LnRicy1pbnRlcm5ldC5jb22CG3d3dy5zaGEyNTYudGJz
-LWludGVybmV0LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAA5NL0D4QSqhErhlkdPmz
-XtiMvdGL+ZehM4coTRIpasM/Agt36Rc0NzCvnQwKE+wkngg1Gy2qe7Q0E/ziqBtB
-fZYzdVgu1zdiL4kTaf+wFKYAFGsFbyeEmXysy+CMwaNoF2vpSjCU1UD56bEnTX/W
-fxVZYxtBQUpnu2wOsm8cDZuZRv9XrYgAhGj9Tt6F0aVHSDGn59uwShG1+BVF/uju
-SCyPTTjL1oc7YElJUzR/x4mQJYvtQI8gDIDAGEOs7v3R/gKa5EMfbUQUI4C84UbI
-Yz09Jdnws/MkC/Hm1BZEqk89u7Hvfv+oHqEb0XaUo0TDfsxE0M1sMdnLb91QNQBm
-UQ==
------END CERTIFICATE-----
- 1 s:/C=FR/ST=Calvados/L=Caen/O=TBS INTERNET/OU=Terms and Conditions: http://www.tbs-internet.com/CA/repository/OU=TBS INTERNET CA/CN=TBS X509 CA SGC
- i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
------BEGIN CERTIFICATE-----
-MIIFVjCCBD6gAwIBAgIQXpDZ0ETJMV02WTx3GTnhhTANBgkqhkiG9w0BAQUFADBv
-MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
-ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF
-eHRlcm5hbCBDQSBSb290MB4XDTA1MTIwMTAwMDAwMFoXDTE5MDYyNDE5MDYzMFow
-gcQxCzAJBgNVBAYTAkZSMREwDwYDVQQIEwhDYWx2YWRvczENMAsGA1UEBxMEQ2Fl
-bjEVMBMGA1UEChMMVEJTIElOVEVSTkVUMUgwRgYDVQQLEz9UZXJtcyBhbmQgQ29u
-ZGl0aW9uczogaHR0cDovL3d3dy50YnMtaW50ZXJuZXQuY29tL0NBL3JlcG9zaXRv
-cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEYMBYGA1UEAxMPVEJTIFg1MDkg
-Q0EgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgOkO3f7wzN6
-rOjg45tR5vjBfzK7qmV9IBxb/QW9EEXxG+E7FNhZqQLtwGBKoSsHTnQqV75wWMk0
-9tinWvftBkSpj5sTi/8cbzJfUvTSVYh3Qxv6AVVjMMH/ruLjE6y+4PoaPs8WoYAQ
-ts5R4Z1g8c/WnTepLst2x0/Wv7GmuoQi+gXvHU6YrBiu7XkeYhzc95QdviWSJRDk
-owhb5K43qhcvjRmBfO/paGlCliDGZp8mHwrI21mwobWpVjTxZRwYO3bd4+TGcI4G
-Ie5wmHwE8F7SK1tgSqbBacKjDa93j7txKkfz/Yd2n7TGqOXiHPsJpG655vrKtnXk
-9vs1zoDeJQIDAQABo4IBljCCAZIwHQYDVR0OBBYEFAdEdoWTKLx/bXjSCuv6TEvf
-2YIfMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMCAGA1UdJQQZ
-MBcGCisGAQQBgjcKAwMGCWCGSAGG+EIEATAYBgNVHSAEETAPMA0GCysGAQQBgOU3
-AgQBMHsGA1UdHwR0MHIwOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0Fk
-ZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMDagNKAyhjBodHRwOi8vY3JsLmNvbW9k
-by5uZXQvQWRkVHJ1c3RFeHRlcm5hbENBUm9vdC5jcmwwgYAGCCsGAQUFBwEBBHQw
-cjA4BggrBgEFBQcwAoYsaHR0cDovL2NydC5jb21vZG9jYS5jb20vQWRkVHJ1c3RV
-VE5TR0NDQS5jcnQwNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuY29tb2RvLm5ldC9B
-ZGRUcnVzdFVUTlNHQ0NBLmNydDARBglghkgBhvhCAQEEBAMCAgQwDQYJKoZIhvcN
-AQEFBQADggEBAK2zEzs+jcIrVK9oDkdDZNvhuBYTdCfpxfFs+OAujW0bIfJAy232
-euVsnJm6u/+OrqKudD2tad2BbejLLXhMZViaCmK7D9nrXHx4te5EP8rL19SUVqLY
-1pTnv5dhNgEgvA7n5lIzDSYs7yRLsr7HJsYPr6SeYSuZizyX1SNz7ooJ32/F3X98
-RB0Mlc/E0OyOrkQ9/y5IrnpnaSora8CnUrV5XNOg+kyCz9edCyx4D5wXYcwZPVWz
-8aDqquESrezPyjtfi4WRO4s/VD3HLZvOxzMrWAVYCDG9FxaOhF0QGuuG1F7F3GKV
-v6prNyCl016kRl2j1UT+a7gLd8fA25A4C9E=
+cnkxGDAWBgNVBAsTD1RCUyBJTlRFUk5FVCBDQTEdMBsGA1UEAxMUVEJTIFg1MDkg
+Q0EgYnVzaW5lc3MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDB1PAU
+qudCcz3tmyGcf+u6EkZqonKKHrV4gZYbvVkIRojmmlhfi/jwvpHvo8bqSt/9Rj5S
+jhCDW0pcbI+IPPtD1Jy+CHNSfnMqVDy6CKQ3p5maTzCMG6ZT+XjnvcND5v+FtaiB
+xk1iCX6uvt0jeUtdZvYbyytsSDE6c3Y5//wRxOF8tM1JxibwO3pyER26jbbN2gQz
+m/EkdGjLdJ4svPk23WDAvQ6G0/z2LcAaJB+XLfqRwfQpHQvfKa1uTi8PivC8qtip
+rmNQMMPMjxSK2azX8cKjjTDJiUKaCb4VHlJDWKEsCFRpgJAoAuX8f7Yfs1M4esGo
+sWb3PGspK3O22uIlAgMBAAGjggF6MIIBdjAdBgNVHQ4EFgQUGgkEzPkJj7seoM7U
+pBR/S9UjWM0wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwGAYD
+VR0gBBEwDzANBgsrBgEEAYDlNwIBATB7BgNVHR8EdDByMDigNqA0hjJodHRwOi8v
+Y3JsLmNvbW9kb2NhLmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDA2oDSg
+MoYwaHR0cDovL2NybC5jb21vZG8ubmV0L0FkZFRydXN0RXh0ZXJuYWxDQVJvb3Qu
+Y3JsMIGGBggrBgEFBQcBAQR6MHgwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29t
+b2RvY2EuY29tL0FkZFRydXN0VVROU2VydmVyQ0EuY3J0MDkGCCsGAQUFBzAChi1o
+dHRwOi8vY3J0LmNvbW9kby5uZXQvQWRkVHJ1c3RVVE5TZXJ2ZXJDQS5jcnQwEQYJ
+YIZIAYb4QgEBBAQDAgIEMA0GCSqGSIb3DQEBBQUAA4IBAQA7mqrMgk/MrE6QnbNA
+h4nRCn2ti4bg4w2C3lB6bSvRPnYwuNw9Jb8vuKkNFzRDxNJXqVDZdfFW5CVQJuyd
+nfAx83+wk+spzvFaE1KhFYfN9G9pQfXUfvDRoIcJgPEKUXL1wRiOG+IjU3VVI8pg
+IgqHkr7ylln5i5zCiFAPuIJmYUSFg/gxH5xkCNcjJqqrHrHatJr6Qrrke93joupw
+oU1njfAcZtYp6fbiK6u2b1pJqwkVBE8RsfLnPhRj+SFbpvjv8Od7o/ieJhFIYQNU
+k2jX2u8qZnAiNw93LZW9lpYjtuvMXq8QQppENNja5b53q7UwI+lU7ZGjZ7quuESp
+J6/5
-----END CERTIFICATE-----
2 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
- i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC
+ i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware
-----BEGIN CERTIFICATE-----
-MIIEZjCCA06gAwIBAgIQUSYKkxzif5zDpV954HKugjANBgkqhkiG9w0BAQUFADCB
-kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+MIIETzCCAzegAwIBAgIQHM5EYpUZep1jUvnyI6m2mDANBgkqhkiG9w0BAQUFADCB
+lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
-IFNHQzAeFw0wNTA2MDcwODA5MTBaFw0xOTA2MjQxOTA2MzBaMG8xCzAJBgNVBAYT
-AlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0
-ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
-IFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC39xoz5vIABC05
-4E5b7R+8bA/Ntfojts7emxEzl6QpTH2Tn71KvJPtAxrjj8/lbVBa1pcplFqAsEl6
-2y6V/bjKvzc4LR4+kUGtcFbH8E8/6DKedMrIkFTpxl8PeJ2aQDwOrGGqXhSPnoeh
-alDc15pOrwWzpnGUnHGzUGAKxxOdOAeGAqjpqGkmGJCrTLBPI6s6T4TY386f4Wlv
-u9dC12tE5Met7m1BX3JacQg3s3llpFmglDf3AC8NwpJy2tA4ctsUqEXEXSp9t7TW
-xO6szRNEt8kr3UMAJfphuWlqWCMRt6czj1Z1WfXNKddGtworZbbTQm8Vsrh7++/p
-XVPVNFonAgMBAAGjgdgwgdUwHwYDVR0jBBgwFoAUUzLRs89/+uDxoF2FTpLSnkUd
-tE8wHQYDVR0OBBYEFK29mHo0tCb3+sQmVO8DveAky1QaMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MBEGCWCGSAGG+EIBAQQEAwIBAjAgBgNVHSUEGTAX
-BgorBgEEAYI3CgMDBglghkgBhvhCBAEwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDov
-L2NybC51c2VydHJ1c3QuY29tL1VUTi1EQVRBQ29ycFNHQy5jcmwwDQYJKoZIhvcN
-AQEFBQADggEBAMbuUxdoFLJRIh6QWA2U/b3xcOWGLcM2MY9USEbnLQg3vGwKYOEO
-rVE04BKT6b64q7gmtOmWPSiPrmQH/uAB7MXjkesYoPF1ftsK5p+R26+udd8jkWjd
-FwBaS/9kbHDrARrQkNnHptZt9hPk/7XJ0h4qy7ElQyZ42TCbTg0evmnv3+r+LbPM
-+bDdtRTKkdSytaX7ARmjR3mfnYyVhzT4HziS2jamEfpr62vp3EV4FTkG101B5CHI
-3C+H0be/SGB1pWLLJN47YaApIKa+xWycxOkKaSLvkTr6Jq/RW0GnOuL4OAdCq8Fb
-+M5tug8EPzI0rNwEKNdwMBQmBsTkm5jVz3g=
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
+SGFyZHdhcmUwHhcNMDUwNjA3MDgwOTEwWhcNMTkwNzA5MTgxOTIyWjBvMQswCQYD
+VQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0
+IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5h
+bCBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt/caM+by
+AAQtOeBOW+0fvGwPzbX6I7bO3psRM5ekKUx9k5+9SryT7QMa44/P5W1QWtaXKZRa
+gLBJetsulf24yr83OC0ePpFBrXBWx/BPP+gynnTKyJBU6cZfD3idmkA8Dqxhql4U
+j56HoWpQ3NeaTq8Fs6ZxlJxxs1BgCscTnTgHhgKo6ahpJhiQq0ywTyOrOk+E2N/O
+n+Fpb7vXQtdrROTHre5tQV9yWnEIN7N5ZaRZoJQ39wAvDcKSctrQOHLbFKhFxF0q
+fbe01sTurM0TRLfJK91DACX6YblpalgjEbenM49WdVn1zSnXRrcKK2W200JvFbK4
+e/vv6V1T1TRaJwIDAQABo4G9MIG6MB8GA1UdIwQYMBaAFKFyXyYbKJhDlV0HN9WF
+lp1L0sNFMB0GA1UdDgQWBBStvZh6NLQm9/rEJlTvA73gJMtUGjAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAQIwRAYDVR0f
+BD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly
+c3QtSGFyZHdhcmUuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQByQhANOs4kClrwF8BW
+onvUOGCSjRK52zYZgDXYNjDtmr5rJ6NyPFDNn+JxkLpjYetIFMTbSRe679Bt8m7a
+gIAoQYFQtxMuyLnJegB2aEbQiIxh/tC21UcFF7ktdnDoTlA6w3pLuvunaI84Of3o
+2YBrhzkTbCfaYk5JRlTpudW9DkUkHBsyx3nknPKnplkIGaK0jgn8E0n+SFabYaHk
+I9LroYT/+JtLefh9lgBdAgVv0UPbzoGfuDsrk/Zh+UrgbLFpHoVnElhzbkh64Z0X
+OGaJunQc68cCZu5HTn/aK7fBGMcVflRCXLVEQpU9PIAdGA8Ynvg684t8GMaKsRl1
+jIGZ
-----END CERTIFICATE-----
- 3 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC
- i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN - DATACorp SGC
+ 3 s:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware
+ i:/C=US/ST=UT/L=Salt Lake City/O=The USERTRUST Network/OU=http://www.usertrust.com/CN=UTN-USERFirst-Hardware
-----BEGIN CERTIFICATE-----
-MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB
-kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
+MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
+lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
-IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG
-EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
-VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu
-dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN
-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6
-E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ
-D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK
-4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq
-lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW
-bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB
-o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
-MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js
-LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr
-BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB
-AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
-Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj
-j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH
-KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
-2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
-mfnGV/TJVTl4uix5yaaIK/QI
+dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
+SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
+A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
+MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
+d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
+cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
+0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
+M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
+MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
+oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
+DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
+oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
+dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
+bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
+BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
+//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
+CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
+CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
+3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
+KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
-----END CERTIFICATE-----
diff --git a/lib-python/2.7/test/test_mailbox.py b/lib-python/2.7/test/test_mailbox.py
--- a/lib-python/2.7/test/test_mailbox.py
+++ b/lib-python/2.7/test/test_mailbox.py
@@ -38,14 +38,9 @@
def _delete_recursively(self, target):
# Delete a file or delete a directory recursively
if os.path.isdir(target):
- for path, dirs, files in os.walk(target, topdown=False):
- for name in files:
- os.remove(os.path.join(path, name))
- for name in dirs:
- os.rmdir(os.path.join(path, name))
- os.rmdir(target)
+ test_support.rmtree(target)
elif os.path.exists(target):
- os.remove(target)
+ test_support.unlink(target)
class TestMailbox(TestBase):
@@ -137,6 +132,7 @@
msg = self._box.get(key1)
self.assertEqual(msg['from'], 'foo')
self.assertEqual(msg.fp.read(), '1')
+ msg.fp.close()
def test_getitem(self):
# Retrieve message using __getitem__()
@@ -169,10 +165,14 @@
# Get file representations of messages
key0 = self._box.add(self._template % 0)
key1 = self._box.add(_sample_message)
- self.assertEqual(self._box.get_file(key0).read().replace(os.linesep, '\n'),
+ msg0 = self._box.get_file(key0)
+ self.assertEqual(msg0.read().replace(os.linesep, '\n'),
self._template % 0)
- self.assertEqual(self._box.get_file(key1).read().replace(os.linesep, '\n'),
+ msg1 = self._box.get_file(key1)
+ self.assertEqual(msg1.read().replace(os.linesep, '\n'),
_sample_message)
+ msg0.close()
+ msg1.close()
def test_get_file_can_be_closed_twice(self):
# Issue 11700
@@ -407,6 +407,7 @@
self._box.add(contents[0])
self._box.add(contents[1])
self._box.add(contents[2])
+ oldbox = self._box
method()
if should_call_close:
self._box.close()
@@ -415,6 +416,7 @@
self.assertEqual(len(keys), 3)
for key in keys:
self.assertIn(self._box.get_string(key), contents)
+ oldbox.close()
def test_dump_message(self):
# Write message representations to disk
@@ -1835,6 +1837,10 @@
def setUp(self):
# create a new maildir mailbox to work with:
self._dir = test_support.TESTFN
+ if os.path.isdir(self._dir):
+ test_support.rmtree(self._dir)
+ if os.path.isfile(self._dir):
+ test_support.unlink(self._dir)
os.mkdir(self._dir)
os.mkdir(os.path.join(self._dir, "cur"))
os.mkdir(os.path.join(self._dir, "tmp"))
@@ -1844,10 +1850,10 @@
def tearDown(self):
map(os.unlink, self._msgfiles)
- os.rmdir(os.path.join(self._dir, "cur"))
- os.rmdir(os.path.join(self._dir, "tmp"))
- os.rmdir(os.path.join(self._dir, "new"))
- os.rmdir(self._dir)
+ test_support.rmdir(os.path.join(self._dir, "cur"))
+ test_support.rmdir(os.path.join(self._dir, "tmp"))
+ test_support.rmdir(os.path.join(self._dir, "new"))
+ test_support.rmdir(self._dir)
def createMessage(self, dir, mbox=False):
t = int(time.time() % 1000000)
@@ -1883,7 +1889,9 @@
self.createMessage("cur")
self.mbox = mailbox.Maildir(test_support.TESTFN)
#self.assertTrue(len(self.mbox.boxes) == 1)
- self.assertIsNot(self.mbox.next(), None)
+ msg = self.mbox.next()
+ self.assertIsNot(msg, None)
+ msg.fp.close()
self.assertIs(self.mbox.next(), None)
self.assertIs(self.mbox.next(), None)
@@ -1891,7 +1899,9 @@
self.createMessage("new")
self.mbox = mailbox.Maildir(test_support.TESTFN)
#self.assertTrue(len(self.mbox.boxes) == 1)
- self.assertIsNot(self.mbox.next(), None)
+ msg = self.mbox.next()
+ self.assertIsNot(msg, None)
+ msg.fp.close()
self.assertIs(self.mbox.next(), None)
self.assertIs(self.mbox.next(), None)
@@ -1900,8 +1910,12 @@
self.createMessage("new")
self.mbox = mailbox.Maildir(test_support.TESTFN)
#self.assertTrue(len(self.mbox.boxes) == 2)
- self.assertIsNot(self.mbox.next(), None)
- self.assertIsNot(self.mbox.next(), None)
+ msg = self.mbox.next()
+ self.assertIsNot(msg, None)
+ msg.fp.close()
+ msg = self.mbox.next()
+ self.assertIsNot(msg, None)
+ msg.fp.close()
self.assertIs(self.mbox.next(), None)
self.assertIs(self.mbox.next(), None)
@@ -1910,11 +1924,13 @@
import email.parser
fname = self.createMessage("cur", True)
n = 0
- for msg in mailbox.PortableUnixMailbox(open(fname),
+ fid = open(fname)
+ for msg in mailbox.PortableUnixMailbox(fid,
email.parser.Parser().parse):
n += 1
self.assertEqual(msg["subject"], "Simple Test")
self.assertEqual(len(str(msg)), len(FROM_)+len(DUMMY_MESSAGE))
+ fid.close()
self.assertEqual(n, 1)
## End: classes from the original module (for backward compatibility).
diff --git a/lib-python/2.7/test/test_mmap.py b/lib-python/2.7/test/test_mmap.py
--- a/lib-python/2.7/test/test_mmap.py
+++ b/lib-python/2.7/test/test_mmap.py
@@ -11,7 +11,7 @@
def setUp(self):
if os.path.exists(TESTFN):
- os.unlink(TESTFN)
+ unlink(TESTFN)
def tearDown(self):
try:
diff --git a/lib-python/2.7/test/test_multiprocessing.py b/lib-python/2.7/test/test_multiprocessing.py
--- a/lib-python/2.7/test/test_multiprocessing.py
+++ b/lib-python/2.7/test/test_multiprocessing.py
@@ -1,5 +1,10 @@
#!/usr/bin/env python
+## FIXME: remove when https://bugs.pypy.org/issue1644 is resolved
+import sys
+if sys.platform.startswith('freebsd'):
+ raise Exception("This test hangs on FreeBSD. Test deactivated for now until https://bugs.pypy.org/issue1644 get resolved")
+
#
# Unit tests for the multiprocessing package
#
diff --git a/lib-python/2.7/test/test_old_mailbox.py b/lib-python/2.7/test/test_old_mailbox.py
--- a/lib-python/2.7/test/test_old_mailbox.py
+++ b/lib-python/2.7/test/test_old_mailbox.py
@@ -73,7 +73,9 @@
self.createMessage("cur")
self.mbox = mailbox.Maildir(test_support.TESTFN)
self.assertTrue(len(self.mbox) == 1)
- self.assertTrue(self.mbox.next() is not None)
+ msg = self.mbox.next()
+ self.assertTrue(msg is not None)
+ msg.fp.close()
self.assertTrue(self.mbox.next() is None)
self.assertTrue(self.mbox.next() is None)
@@ -81,7 +83,9 @@
self.createMessage("new")
self.mbox = mailbox.Maildir(test_support.TESTFN)
self.assertTrue(len(self.mbox) == 1)
- self.assertTrue(self.mbox.next() is not None)
+ msg = self.mbox.next()
+ self.assertTrue(msg is not None)
+ msg.fp.close()
self.assertTrue(self.mbox.next() is None)
self.assertTrue(self.mbox.next() is None)
@@ -90,8 +94,12 @@
self.createMessage("new")
self.mbox = mailbox.Maildir(test_support.TESTFN)
self.assertTrue(len(self.mbox) == 2)
- self.assertTrue(self.mbox.next() is not None)
- self.assertTrue(self.mbox.next() is not None)
+ msg = self.mbox.next()
+ self.assertTrue(msg is not None)
+ msg.fp.close()
+ msg = self.mbox.next()
+ self.assertTrue(msg is not None)
+ msg.fp.close()
self.assertTrue(self.mbox.next() is None)
self.assertTrue(self.mbox.next() is None)
diff --git a/lib-python/2.7/test/test_os.py b/lib-python/2.7/test/test_os.py
--- a/lib-python/2.7/test/test_os.py
+++ b/lib-python/2.7/test/test_os.py
@@ -75,7 +75,7 @@
self.assertFalse(os.path.exists(name),
"file already exists for temporary file")
# make sure we can create the file
- open(name, "w")
+ open(name, "w").close()
self.files.append(name)
def test_tempnam(self):
diff --git a/lib-python/2.7/test/test_ssl.py b/lib-python/2.7/test/test_ssl.py
--- a/lib-python/2.7/test/test_ssl.py
+++ b/lib-python/2.7/test/test_ssl.py
@@ -111,13 +111,12 @@
if test_support.verbose:
sys.stdout.write("\n" + pprint.pformat(p) + "\n")
self.assertEqual(p['subject'],
- ((('countryName', u'US'),),
- (('stateOrProvinceName', u'Delaware'),),
- (('localityName', u'Wilmington'),),
- (('organizationName', u'Python Software Foundation'),),
- (('organizationalUnitName', u'SSL'),),
- (('commonName', u'somemachine.python.org'),)),
+ ((('countryName', 'XY'),),
+ (('localityName', 'Castle Anthrax'),),
+ (('organizationName', 'Python Software Foundation'),),
+ (('commonName', 'localhost'),))
)
+ self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
# Issue #13034: the subjectAltName in some certificates
# (notably projects.developer.nokia.com:443) wasn't parsed
p = ssl._ssl._test_decode_cert(NOKIACERT)
diff --git a/lib-python/2.7/test/test_support.py b/lib-python/2.7/test/test_support.py
--- a/lib-python/2.7/test/test_support.py
+++ b/lib-python/2.7/test/test_support.py
@@ -179,15 +179,79 @@
except KeyError:
pass
+if sys.platform.startswith("win"):
+ def _waitfor(func, pathname, waitall=False):
+ # Peform the operation
+ func(pathname)
+ # Now setup the wait loop
+ if waitall:
+ dirname = pathname
+ else:
+ dirname, name = os.path.split(pathname)
+ dirname = dirname or '.'
+ # Check for `pathname` to be removed from the filesystem.
+ # The exponential backoff of the timeout amounts to a total
+ # of ~1 second after which the deletion is probably an error
+ # anyway.
+ # Testing on a i7 at 4.3GHz shows that usually only 1 iteration is
+ # required when contention occurs.
+ timeout = 0.001
+ while timeout < 1.0:
+ # Note we are only testing for the existance of the file(s) in
+ # the contents of the directory regardless of any security or
+ # access rights. If we have made it this far, we have sufficient
+ # permissions to do that much using Python's equivalent of the
+ # Windows API FindFirstFile.
+ # Other Windows APIs can fail or give incorrect results when
+ # dealing with files that are pending deletion.
+ L = os.listdir(dirname)
+ if not (L if waitall else name in L):
+ return
+ # Increase the timeout and try again
+ time.sleep(timeout)
+ timeout *= 2
+ warnings.warn('tests may fail, delete still pending for ' + pathname,
+ RuntimeWarning, stacklevel=4)
+
+ def _unlink(filename):
+ _waitfor(os.unlink, filename)
+
+ def _rmdir(dirname):
+ _waitfor(os.rmdir, dirname)
+
+ def _rmtree(path):
+ def _rmtree_inner(path):
+ for name in os.listdir(path):
+ fullname = os.path.join(path, name)
+ if os.path.isdir(fullname):
+ _waitfor(_rmtree_inner, fullname, waitall=True)
+ os.rmdir(fullname)
+ else:
+ os.unlink(fullname)
+ _waitfor(_rmtree_inner, path, waitall=True)
+ _waitfor(os.rmdir, path)
+else:
+ _unlink = os.unlink
+ _rmdir = os.rmdir
+ _rmtree = shutil.rmtree
+
def unlink(filename):
try:
- os.unlink(filename)
+ _unlink(filename)
except OSError:
pass
+def rmdir(dirname):
+ try:
+ _rmdir(dirname)
+ except OSError as error:
+ # The directory need not exist.
+ if error.errno != errno.ENOENT:
+ raise
+
def rmtree(path):
try:
- shutil.rmtree(path)
+ _rmtree(path)
except OSError, e:
# Unix returns ENOENT, Windows returns ESRCH.
if e.errno not in (errno.ENOENT, errno.ESRCH):
diff --git a/lib-python/2.7/test/test_tarfile.py b/lib-python/2.7/test/test_tarfile.py
--- a/lib-python/2.7/test/test_tarfile.py
+++ b/lib-python/2.7/test/test_tarfile.py
@@ -300,26 +300,21 @@
def test_extract_hardlink(self):
# Test hardlink extraction (e.g. bug #857297).
- tar = tarfile.open(tarname, errorlevel=1, encoding="iso8859-1")
+ with tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") as tar:
+ tar.extract("ustar/regtype", TEMPDIR)
+ self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/regtype"))
- tar.extract("ustar/regtype", TEMPDIR)
- try:
tar.extract("ustar/lnktype", TEMPDIR)
- except EnvironmentError, e:
- if e.errno == errno.ENOENT:
- self.fail("hardlink not extracted properly")
+ self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/lnktype"))
+ with open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb") as f:
+ data = f.read()
+ self.assertEqual(md5sum(data), md5_regtype)
- data = open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb").read()
- self.assertEqual(md5sum(data), md5_regtype)
-
- try:
tar.extract("ustar/symtype", TEMPDIR)
- except EnvironmentError, e:
- if e.errno == errno.ENOENT:
- self.fail("symlink not extracted properly")
-
- data = open(os.path.join(TEMPDIR, "ustar/symtype"), "rb").read()
- self.assertEqual(md5sum(data), md5_regtype)
+ self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/symtype"))
+ with open(os.path.join(TEMPDIR, "ustar/symtype"), "rb") as f:
+ data = f.read()
+ self.assertEqual(md5sum(data), md5_regtype)
def test_extractall(self):
# Test if extractall() correctly restores directory permissions
@@ -340,7 +335,7 @@
# constructor in case of an error. For the test we rely on
# the fact that opening an empty file raises a ReadError.
empty = os.path.join(TEMPDIR, "empty")
- open(empty, "wb").write("")
+ open(empty, "wb").close()
try:
tar = object.__new__(tarfile.TarFile)
@@ -351,7 +346,7 @@
else:
self.fail("ReadError not raised")
finally:
- os.remove(empty)
+ test_support.unlink(empty)
class StreamReadTest(CommonReadTest):
@@ -1327,7 +1322,7 @@
def setUp(self):
self.tarname = tmpname
if os.path.exists(self.tarname):
- os.remove(self.tarname)
+ test_support.unlink(self.tarname)
def _add_testfile(self, fileobj=None):
tar = tarfile.open(self.tarname, "a", fileobj=fileobj)
diff --git a/lib-python/2.7/traceback.py b/lib-python/2.7/traceback.py
--- a/lib-python/2.7/traceback.py
+++ b/lib-python/2.7/traceback.py
@@ -107,7 +107,7 @@
return list
-def print_exception(etype, value, tb, limit=None, file=None):
+def print_exception(etype, value, tb, limit=None, file=None, _encoding=None):
"""Print exception up to 'limit' stack trace entries from 'tb' to 'file'.
This differs from print_tb() in the following ways: (1) if
@@ -123,7 +123,7 @@
if tb:
_print(file, 'Traceback (most recent call last):')
print_tb(tb, limit, file)
- lines = format_exception_only(etype, value)
+ lines = format_exception_only(etype, value, _encoding)
for line in lines:
_print(file, line, '')
@@ -144,7 +144,7 @@
list = list + format_exception_only(etype, value)
return list
-def format_exception_only(etype, value):
+def format_exception_only(etype, value, _encoding=None):
"""Format the exception part of a traceback.
The arguments are the exception type and value such as given by
@@ -170,12 +170,12 @@
if (isinstance(etype, BaseException) or
isinstance(etype, types.InstanceType) or
etype is None or type(etype) is str):
- return [_format_final_exc_line(etype, value)]
+ return [_format_final_exc_line(etype, value, _encoding)]
stype = etype.__name__
if not issubclass(etype, SyntaxError):
- return [_format_final_exc_line(stype, value)]
+ return [_format_final_exc_line(stype, value, _encoding)]
# It was a syntax error; show exactly where the problem was found.
lines = []
@@ -196,26 +196,26 @@
lines.append(' %s^\n' % ''.join(caretspace))
value = msg
- lines.append(_format_final_exc_line(stype, value))
+ lines.append(_format_final_exc_line(stype, value, _encoding))
return lines
-def _format_final_exc_line(etype, value):
+def _format_final_exc_line(etype, value, _encoding=None):
"""Return a list of a single line -- normal case for format_exception_only"""
- valuestr = _some_str(value)
+ valuestr = _some_str(value, _encoding)
if value is None or not valuestr:
line = "%s\n" % etype
else:
line = "%s: %s\n" % (etype, valuestr)
return line
-def _some_str(value):
+def _some_str(value, _encoding=None):
try:
return str(value)
except Exception:
pass
try:
value = unicode(value)
- return value.encode("ascii", "backslashreplace")
+ return value.encode(_encoding or "ascii", "backslashreplace")
except Exception:
pass
return '<unprintable %s object>' % type(value).__name__
diff --git a/lib-python/2.7/uuid.py b/lib-python/2.7/uuid.py
--- a/lib-python/2.7/uuid.py
+++ b/lib-python/2.7/uuid.py
@@ -128,10 +128,10 @@
"""
if hex is not None:
- if (bytes is not None or bytes_le is not None or fields is not None
- or int is not None):
- raise TypeError('if the hex argument is given, bytes, bytes_le, fields,'
- ' and int need to be None')
+ if (bytes is not None or bytes_le is not None or
+ fields is not None or int is not None):
+ raise TypeError('if the hex argument is given, bytes,'
+ ' bytes_le, fields, and int need to be None')
hex = hex.replace('urn:', '').replace('uuid:', '')
hex = hex.strip('{}').replace('-', '')
if len(hex) != 32:
@@ -139,8 +139,8 @@
int = long(hex, 16)
elif bytes_le is not None:
if bytes is not None or fields is not None or int is not None:
- raise TypeError('if the bytes_le argument is given, bytes, fields,'
- ' and int need to be None')
+ raise TypeError('if the bytes_le argument is given, bytes,'
+ ' fields, and int need to be None')
if len(bytes_le) != 16:
raise ValueError('bytes_le is not a 16-char string')
bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] +
@@ -150,15 +150,16 @@
struct.unpack('>Q', bytes[8:])[0])
elif bytes is not None:
if fields is not None or int is not None:
- raise TypeError('if the bytes argument is given, fields'
- ' and int need to be None')
+ raise TypeError('if the bytes argument is given, fields '
+ 'and int need to be None')
if len(bytes) != 16:
raise ValueError('bytes is not a 16-char string')
int = (struct.unpack('>Q', bytes[:8])[0] << 64 |
struct.unpack('>Q', bytes[8:])[0])
elif fields is not None:
if int is not None:
- raise TypeError('if the fields argument is given, int needs to be None')
+ raise TypeError('if the fields argument is given, int needs'
+ ' to be None')
if len(fields) != 6:
raise ValueError('fields is not a 6-tuple')
(time_low, time_mid, time_hi_version,
diff --git a/lib-python/2.7/weakref.py b/lib-python/2.7/weakref.py
--- a/lib-python/2.7/weakref.py
+++ b/lib-python/2.7/weakref.py
@@ -48,7 +48,14 @@
def remove(wr, selfref=ref(self)):
self = selfref()
if self is not None:
- del self.data[wr.key]
+ # Changed this for PyPy: made more resistent. The
+ # issue is that in some corner cases, self.data
+ # might already be changed or removed by the time
+ # this weakref's callback is called. If that is
+ # the case, we don't want to randomly kill an
+ # unrelated entry.
+ if self.data.get(wr.key) is wr:
+ del self.data[wr.key]
self._remove = remove
UserDict.UserDict.__init__(self, *args, **kw)
@@ -160,22 +167,26 @@
try:
o = self.data.pop(key)()
except KeyError:
+ o = None
+ if o is None:
if args:
return args[0]
- raise
- if o is None:
raise KeyError, key
else:
return o
+ # The logic above was fixed in PyPy
def setdefault(self, key, default=None):
try:
- wr = self.data[key]
+ o = self.data[key]()
except KeyError:
+ o = None
+ if o is None:
self.data[key] = KeyedRef(default, self._remove, key)
return default
else:
- return wr()
+ return o
+ # The logic above was fixed in PyPy
def update(self, dict=None, **kwargs):
d = self.data
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -328,21 +328,23 @@
raise ValueError(
"native COM method call without 'this' parameter"
)
- thisarg = cast(args[0], POINTER(POINTER(c_void_p)))
- keepalives, newargs, argtypes, outargs = self._convert_args(argtypes,
- args[1:], kwargs)
- newargs.insert(0, args[0].value)
+ thisvalue = args.pop(0)
+ thisarg = cast(thisvalue, POINTER(POINTER(c_void_p)))
+ keepalives, newargs, argtypes, outargs, errcheckargs = (
+ self._convert_args(argtypes, args, kwargs))
+ args.insert(0, thisvalue)
+ newargs.insert(0, thisvalue.value)
argtypes.insert(0, c_void_p)
else:
thisarg = None
- keepalives, newargs, argtypes, outargs = self._convert_args(argtypes,
- args, kwargs)
+ keepalives, newargs, argtypes, outargs, errcheckargs = (
+ self._convert_args(argtypes, args, kwargs))
funcptr = self._getfuncptr(argtypes, self._restype_, thisarg)
result = self._call_funcptr(funcptr, *newargs)
- result = self._do_errcheck(result, args)
+ result, forced = self._do_errcheck(result, errcheckargs)
- if not outargs:
+ if not outargs or forced:
return result
from ctypes import c_void_p
@@ -377,22 +379,22 @@
set_last_error(tmp)
#
try:
- return self._build_result(self._restype_, result, newargs)
+ return self._build_result(self._restype_, result)
finally:
funcptr.free_temp_buffers()
def _do_errcheck(self, result, args):
# The 'errcheck' protocol
if self._errcheck_:
- v = self._errcheck_(result, self, args)
+ v = self._errcheck_(result, self, tuple(args))
# If the errcheck funtion failed, let it throw
# If the errcheck function returned newargs unchanged,
# continue normal processing.
# If the errcheck function returned something else,
# use that as result.
if v is not args:
- return v
- return result
+ return v, True
+ return result, False
def _getfuncptr_fromaddress(self, argtypes, restype):
address = self._get_address()
@@ -495,16 +497,16 @@
newargtypes = []
total = len(args)
paramflags = self._paramflags
- inargs_idx = 0
if not paramflags and total < len(argtypes):
raise TypeError("not enough arguments")
- for i, argtype in enumerate(argtypes):
- flag = 0
- name = None
- defval = marker
- if paramflags:
+ if paramflags:
+ errcheckargs = []
+ inargs_idx = 0
+ for i, argtype in enumerate(argtypes):
+ flag = 0
+ defval = marker
paramflag = paramflags[i]
paramlen = len(paramflag)
name = None
@@ -519,6 +521,7 @@
val = defval
if val is marker:
val = 0
+ errcheckargs.append(val)
keepalive, newarg, newargtype = self._conv_param(argtype, val)
keepalives.append(keepalive)
newargs.append(newarg)
@@ -536,27 +539,31 @@
raise TypeError("required argument '%s' missing" % name)
else:
raise TypeError("not enough arguments")
+ errcheckargs.append(val)
keepalive, newarg, newargtype = self._conv_param(argtype, val)
keepalives.append(keepalive)
newargs.append(newarg)
newargtypes.append(newargtype)
elif flag == PARAMFLAG_FOUT:
if defval is not marker:
- outargs.append(defval)
+ val = defval
keepalive, newarg, newargtype = self._conv_param(argtype, defval)
else:
import ctypes
val = argtype._type_()
- outargs.append(val)
keepalive = None
newarg = ctypes.byref(val)
newargtype = type(newarg)
+ errcheckargs.append(val)
+ outargs.append(val)
keepalives.append(keepalive)
newargs.append(newarg)
newargtypes.append(newargtype)
else:
raise ValueError("paramflag %d not yet implemented" % flag)
- else:
+ else:
+ errcheckargs = args
+ for i, argtype in enumerate(argtypes):
try:
keepalive, newarg, newargtype = self._conv_param(argtype, args[i])
except (UnicodeError, TypeError, ValueError), e:
@@ -564,7 +571,6 @@
keepalives.append(keepalive)
newargs.append(newarg)
newargtypes.append(newargtype)
- inargs_idx += 1
if len(newargs) < len(args):
extra = args[len(newargs):]
@@ -576,7 +582,7 @@
keepalives.append(keepalive)
newargs.append(newarg)
newargtypes.append(newargtype)
- return keepalives, newargs, newargtypes, outargs
+ return keepalives, newargs, newargtypes, outargs, errcheckargs
@staticmethod
def _is_primitive(argtype):
@@ -601,7 +607,7 @@
retval = restype._CData_retval(buf)
return retval
- def _build_result(self, restype, result, argsandobjs):
+ def _build_result(self, restype, result):
"""Build the function result:
If there is no OUT parameter, return the actual function result
If there is one OUT parameter, return it
@@ -611,11 +617,6 @@
# i.e. an array of ints. Now it takes a result, which is already a
# python object. All places that do "resbuffer[0]" should check that
# result is actually an int and just use it.
- #
- # Also, argsandobjs used to be "args" in __call__, now it's "newargs"
- # (i.e., the already unwrapped objects). It's used only when we have a
- # PARAMFLAG_FOUT and it's probably wrong, I'll fix it when I find a
- # failing test
retval = None
@@ -704,7 +705,7 @@
funcptr = self._getfuncptr(argtypes, restype, thisarg)
try:
result = self._call_funcptr(funcptr, *args)
- result = self._do_errcheck(result, args)
+ result, _ = self._do_errcheck(result, args)
except (TypeError, ArgumentError, UnicodeDecodeError):
assert self._slowpath_allowed
return CFuncPtr.__call__(self, *args)
diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -33,14 +33,13 @@
# set link options
output_filename = modulename + _get_c_extension_suffix()
if sys.platform == 'win32':
- # XXX libpypy-c.lib is currently not installed automatically
- library = os.path.join(thisdir, '..', 'include', 'libpypy-c')
+ # XXX pyconfig.h uses a pragma to link to the import library,
+ # which is currently python27.lib
+ library = os.path.join(thisdir, '..', 'include', 'python27')
if not os.path.exists(library + '.lib'):
- #For a nightly build
- library = os.path.join(thisdir, '..', 'include', 'python27')
- if not os.path.exists(library + '.lib'):
- # For a local translation
- library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c')
+ # For a local translation or nightly build
+ library = os.path.join(thisdir, '..', 'pypy', 'goal', 'python27')
+ assert os.path.exists(library + '.lib'),'Could not find import library "%s"' % library
libraries = [library, 'oleaut32']
extra_ldargs = ['/MANIFEST', # needed for VC10
'/EXPORT:init' + modulename]
diff --git a/lib_pypy/_sha.py b/lib_pypy/_sha.py
--- a/lib_pypy/_sha.py
+++ b/lib_pypy/_sha.py
@@ -115,14 +115,14 @@
]
class sha:
- "An implementation of the MD5 hash function in pure Python."
+ "An implementation of the SHA hash function in pure Python."
digest_size = digestsize = 20
- block_size = 1
+ block_size = 512 // 8
def __init__(self):
"Initialisation."
-
+
# Initial message length in bits(!).
self.length = 0
self.count = [0, 0]
@@ -209,7 +209,7 @@
self.H2 = (self.H2 + C) & 0xffffffff
self.H3 = (self.H3 + D) & 0xffffffff
self.H4 = (self.H4 + E) & 0xffffffff
-
+
# Down from here all methods follow the Python Standard Library
# API of the sha module.
@@ -295,13 +295,13 @@
_long2bytesBigEndian(self.H3, 4) + \
_long2bytesBigEndian(self.H4, 4)
- self.H0 = H0
- self.H1 = H1
+ self.H0 = H0
+ self.H1 = H1
self.H2 = H2
self.H3 = H3
self.H4 = H4
- self.input = input
- self.count = count
+ self.input = input
+ self.count = count
return digest
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -268,10 +268,18 @@
if _has_load_extension():
_ffi.cdef("int sqlite3_enable_load_extension(sqlite3 *db, int onoff);")
-_lib = _ffi.verify("""
-#include <sqlite3.h>
-""", libraries=['sqlite3']
-)
+if sys.platform.startswith('freebsd'):
+ _lib = _ffi.verify("""
+ #include <sqlite3.h>
+ """, libraries=['sqlite3'],
+ include_dirs=['/usr/local/include'],
+ library_dirs=['/usr/local/lib']
+ )
+else:
+ _lib = _ffi.verify("""
+ #include <sqlite3.h>
+ """, libraries=['sqlite3']
+ )
exported_sqlite_symbols = [
'SQLITE_ALTER_TABLE',
@@ -363,9 +371,11 @@
pass
-def connect(database, **kwargs):
- factory = kwargs.get("factory", Connection)
- return factory(database, **kwargs)
+def connect(database, timeout=5.0, detect_types=0, isolation_level="",
+ check_same_thread=True, factory=None, cached_statements=100):
+ factory = Connection if not factory else factory
+ return factory(database, timeout, detect_types, isolation_level,
+ check_same_thread, factory, cached_statements)
def _unicode_text_factory(x):
diff --git a/lib_pypy/_tkinter/tclobj.py b/lib_pypy/_tkinter/tclobj.py
--- a/lib_pypy/_tkinter/tclobj.py
+++ b/lib_pypy/_tkinter/tclobj.py
@@ -28,9 +28,11 @@
return result
elif value.typePtr == typeCache.BooleanType:
- return result
+ return bool(value.internalRep.longValue)
elif value.typePtr == typeCache.ByteArrayType:
- return result
+ size = tkffi.new('int*')
+ data = tklib.Tcl_GetByteArrayFromObj(value, size)
+ return tkffi.buffer(data, size[0])[:]
elif value.typePtr == typeCache.DoubleType:
return value.internalRep.doubleValue
elif value.typePtr == typeCache.IntType:
@@ -50,7 +52,7 @@
result.append(FromObj(app, tcl_elem[0]))
return tuple(result)
elif value.typePtr == typeCache.ProcBodyType:
- return result
+ pass # fall through and return tcl object.
elif value.typePtr == typeCache.StringType:
buf = tklib.Tcl_GetUnicode(value)
length = tklib.Tcl_GetCharLength(value)
diff --git a/lib_pypy/_tkinter/tklib.py b/lib_pypy/_tkinter/tklib.py
--- a/lib_pypy/_tkinter/tklib.py
+++ b/lib_pypy/_tkinter/tklib.py
@@ -72,6 +72,7 @@
int Tcl_GetBoolean(Tcl_Interp* interp, const char* src, int* boolPtr);
char *Tcl_GetString(Tcl_Obj* objPtr);
char *Tcl_GetStringFromObj(Tcl_Obj* objPtr, int* lengthPtr);
+unsigned char *Tcl_GetByteArrayFromObj(Tcl_Obj* objPtr, int* lengthPtr);
Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj* objPtr);
int Tcl_GetCharLength(Tcl_Obj* objPtr);
@@ -111,6 +112,14 @@
incdirs = ['/usr/local/include/tcl8.5', '/usr/local/include/tk8.5', '/usr/X11R6/include']
linklibs = ['tk85', 'tcl85']
libdirs = ['/usr/local/lib', '/usr/X11R6/lib']
+elif sys.platform.startswith("freebsd"):
+ incdirs = ['/usr/local/include/tcl8.6', '/usr/local/include/tk8.6', '/usr/local/include/X11', '/usr/local/include']
+ linklibs = ['tk86', 'tcl86']
+ libdirs = ['/usr/local/lib']
+elif sys.platform == 'win32':
+ incdirs = []
+ linklibs = ['tcl85', 'tk85']
+ libdirs = []
else:
incdirs=['/usr/include/tcl']
linklibs=['tcl', 'tk']
diff --git a/lib_pypy/cffi.egg-info b/lib_pypy/cffi.egg-info
--- a/lib_pypy/cffi.egg-info
+++ b/lib_pypy/cffi.egg-info
@@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: cffi
-Version: 0.7
+Version: 0.8
Summary: Foreign Function Interface for Python calling C code.
Home-page: http://cffi.readthedocs.org
Author: Armin Rigo, Maciej Fijalkowski
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -4,5 +4,5 @@
from .api import FFI, CDefError, FFIError
from .ffiplatform import VerificationError, VerificationMissing
-__version__ = "0.7.2"
-__version_info__ = (0, 7, 2)
+__version__ = "0.8.1"
+__version_info__ = (0, 8, 1)
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -1,4 +1,5 @@
import types
+from .lock import allocate_lock
try:
callable
@@ -61,6 +62,7 @@
# rely on it! It's probably not going to work well.)
self._backend = backend
+ self._lock = allocate_lock()
self._parser = cparser.Parser()
self._cached_btypes = {}
self._parsed_types = types.ModuleType('parsed_types').__dict__
@@ -74,7 +76,8 @@
if name.startswith('RTLD_'):
setattr(self, name, getattr(backend, name))
#
- self.BVoidP = self._get_cached_btype(model.voidp_type)
+ with self._lock:
+ self.BVoidP = self._get_cached_btype(model.voidp_type)
if isinstance(backend, types.ModuleType):
# _cffi_backend: attach these constants to the class
if not hasattr(FFI, 'NULL'):
@@ -95,11 +98,12 @@
if not isinstance(csource, basestring):
raise TypeError("cdef() argument must be a string")
csource = csource.encode('ascii')
- self._parser.parse(csource, override=override)
- self._cdefsources.append(csource)
- if override:
- for cache in self._function_caches:
- cache.clear()
+ with self._lock:
+ self._parser.parse(csource, override=override)
+ self._cdefsources.append(csource)
+ if override:
+ for cache in self._function_caches:
+ cache.clear()
def dlopen(self, name, flags=0):
"""Load and return a dynamic library identified by 'name'.
@@ -109,31 +113,47 @@
library we only look for the actual (untyped) symbols.
"""
assert isinstance(name, basestring) or name is None
- lib, function_cache = _make_ffi_library(self, name, flags)
- self._function_caches.append(function_cache)
- self._libraries.append(lib)
+ with self._lock:
+ lib, function_cache = _make_ffi_library(self, name, flags)
+ self._function_caches.append(function_cache)
+ self._libraries.append(lib)
return lib
+ def _typeof_locked(self, cdecl):
+ # call me with the lock!
+ key = cdecl
+ if key in self._parsed_types:
+ return self._parsed_types[key]
+ #
+ if not isinstance(cdecl, str): # unicode, on Python 2
+ cdecl = cdecl.encode('ascii')
+ #
+ type = self._parser.parse_type(cdecl)
+ really_a_function_type = type.is_raw_function
+ if really_a_function_type:
+ type = type.as_function_pointer()
+ btype = self._get_cached_btype(type)
+ result = btype, really_a_function_type
+ self._parsed_types[key] = result
+ return result
+
def _typeof(self, cdecl, consider_function_as_funcptr=False):
# string -> ctype object
try:
- btype, cfaf = self._parsed_types[cdecl]
- if consider_function_as_funcptr and not cfaf:
- raise KeyError
+ result = self._parsed_types[cdecl]
except KeyError:
- key = cdecl
- if not isinstance(cdecl, str): # unicode, on Python 2
- cdecl = cdecl.encode('ascii')
- cfaf = consider_function_as_funcptr
- type = self._parser.parse_type(cdecl,
- consider_function_as_funcptr=cfaf)
- btype = self._get_cached_btype(type)
- self._parsed_types[key] = btype, cfaf
+ with self._lock:
+ result = self._typeof_locked(cdecl)
+ #
+ btype, really_a_function_type = result
+ if really_a_function_type and not consider_function_as_funcptr:
+ raise CDefError("the type %r is a function type, not a "
+ "pointer-to-function type" % (cdecl,))
return btype
def typeof(self, cdecl):
"""Parse the C type given as a string and return the
- corresponding Python type: <class 'ffi.CData<...>'>.
+ corresponding <ctype> object.
It can also be used on 'cdata' instance to get its C type.
"""
if isinstance(cdecl, basestring):
@@ -144,6 +164,10 @@
res = _builtin_function_type(cdecl)
if res is not None:
return res
+ if (isinstance(cdecl, types.FunctionType)
+ and hasattr(cdecl, '_cffi_base_type')):
+ with self._lock:
+ return self._get_cached_btype(cdecl._cffi_base_type)
raise TypeError(type(cdecl))
def sizeof(self, cdecl):
@@ -280,14 +304,17 @@
data. Later, when this new cdata object is garbage-collected,
'destructor(old_cdata_object)' will be called.
"""
- try:
- gc_weakrefs = self.gc_weakrefs
- except AttributeError:
- from .gc_weakref import GcWeakrefs
- gc_weakrefs = self.gc_weakrefs = GcWeakrefs(self)
- return gc_weakrefs.build(cdata, destructor)
+ with self._lock:
+ try:
+ gc_weakrefs = self.gc_weakrefs
+ except AttributeError:
+ from .gc_weakref import GcWeakrefs
+ gc_weakrefs = self.gc_weakrefs = GcWeakrefs(self)
+ return gc_weakrefs.build(cdata, destructor)
def _get_cached_btype(self, type):
+ assert self._lock.acquire(False) is False
+ # call me with the lock!
try:
BType = self._cached_btypes[type]
except KeyError:
@@ -320,9 +347,13 @@
errno = property(_get_errno, _set_errno, None,
"the value of 'errno' from/to the C calls")
+ def getwinerror(self, code=-1):
+ return self._backend.getwinerror(code)
+
def _pointer_to(self, ctype):
from . import model
- return model.pointer_cache(self, ctype)
+ with self._lock:
+ return model.pointer_cache(self, ctype)
def addressof(self, cdata, field=None):
"""Return the address of a <cdata 'struct-or-union'>.
@@ -342,10 +373,12 @@
variables, which must anyway be accessed directly from the
lib object returned by the original FFI instance.
"""
- self._parser.include(ffi_to_include._parser)
- self._cdefsources.append('[')
- self._cdefsources.extend(ffi_to_include._cdefsources)
- self._cdefsources.append(']')
+ with ffi_to_include._lock:
+ with self._lock:
+ self._parser.include(ffi_to_include._parser)
+ self._cdefsources.append('[')
+ self._cdefsources.extend(ffi_to_include._cdefsources)
+ self._cdefsources.append(']')
def new_handle(self, x):
return self._backend.newp_handle(self.BVoidP, x)
@@ -372,7 +405,7 @@
backendlib = backend.load_library(path, flags)
copied_enums = []
#
- def make_accessor(name):
+ def make_accessor_locked(name):
key = 'function ' + name
if key in ffi._parser._declarations:
tp = ffi._parser._declarations[key]
@@ -404,11 +437,17 @@
if enumname not in library.__dict__:
library.__dict__[enumname] = enumval
copied_enums.append(True)
+ if name in library.__dict__:
+ return
#
- if name in library.__dict__: # copied from an enum value just above,
- return # or multithread's race condition
raise AttributeError(name)
#
+ def make_accessor(name):
+ with ffi._lock:
+ if name in library.__dict__ or name in FFILibrary.__dict__:
+ return # added by another thread while waiting for the lock
+ make_accessor_locked(name)
+ #
class FFILibrary(object):
def __getattr__(self, name):
make_accessor(name)
@@ -444,4 +483,5 @@
except (KeyError, AttributeError, TypeError):
return None
else:
- return ffi._get_cached_btype(tp)
+ with ffi._lock:
+ return ffi._get_cached_btype(tp)
diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -142,7 +142,7 @@
if 1 <= linenum <= len(csourcelines):
line = csourcelines[linenum-1]
if line:
- msg = 'cannot parse "%s"\n%s' % (line, msg)
+ msg = 'cannot parse "%s"\n%s' % (line.strip(), msg)
else:
msg = 'parse error\n%s' % (msg,)
raise api.CDefError(msg)
@@ -217,19 +217,18 @@
#
if decl.name:
tp = self._get_type(node, partial_length_ok=True)
- if self._is_constant_declaration(node):
+ if self._is_constant_globalvar(node):
self._declare('constant ' + decl.name, tp)
else:
self._declare('variable ' + decl.name, tp)
- def parse_type(self, cdecl, consider_function_as_funcptr=False):
+ def parse_type(self, cdecl):
ast, macros = self._parse('void __dummy(\n%s\n);' % cdecl)
assert not macros
exprnode = ast.ext[-1].type.args.params[0]
if isinstance(exprnode, pycparser.c_ast.ID):
raise api.CDefError("unknown identifier '%s'" % (exprnode.name,))
- return self._get_type(exprnode.type,
- consider_function_as_funcptr=consider_function_as_funcptr)
+ return self._get_type(exprnode.type)
def _declare(self, name, obj):
if name in self._declarations:
@@ -249,28 +248,17 @@
return model.ConstPointerType(type)
return model.PointerType(type)
- def _get_type(self, typenode, convert_array_to_pointer=False,
- name=None, partial_length_ok=False,
- consider_function_as_funcptr=False):
+ def _get_type(self, typenode, name=None, partial_length_ok=False):
# first, dereference typedefs, if we have it already parsed, we're good
if (isinstance(typenode, pycparser.c_ast.TypeDecl) and
isinstance(typenode.type, pycparser.c_ast.IdentifierType) and
len(typenode.type.names) == 1 and
('typedef ' + typenode.type.names[0]) in self._declarations):
type = self._declarations['typedef ' + typenode.type.names[0]]
- if isinstance(type, model.ArrayType):
- if convert_array_to_pointer:
- return type.item
- else:
- if (consider_function_as_funcptr and
- isinstance(type, model.RawFunctionType)):
- return type.as_function_pointer()
return type
#
if isinstance(typenode, pycparser.c_ast.ArrayDecl):
# array type
- if convert_array_to_pointer:
- return self._get_type_pointer(self._get_type(typenode.type))
if typenode.dim is None:
length = None
else:
@@ -331,10 +319,7 @@
#
if isinstance(typenode, pycparser.c_ast.FuncDecl):
# a function type
- result = self._parse_function_type(typenode, name)
- if consider_function_as_funcptr:
- result = result.as_function_pointer()
- return result
+ return self._parse_function_type(typenode, name)
#
# nested anonymous structs or unions end up here
if isinstance(typenode, pycparser.c_ast.Struct):
@@ -365,21 +350,24 @@
isinstance(params[0].type.type, pycparser.c_ast.IdentifierType)
and list(params[0].type.type.names) == ['void']):
del params[0]
- args = [self._get_type(argdeclnode.type,
- convert_array_to_pointer=True,
- consider_function_as_funcptr=True)
+ args = [self._as_func_arg(self._get_type(argdeclnode.type))
for argdeclnode in params]
result = self._get_type(typenode.type)
return model.RawFunctionType(tuple(args), result, ellipsis)
- def _is_constant_declaration(self, typenode, const=False):
- if isinstance(typenode, pycparser.c_ast.ArrayDecl):
- return self._is_constant_declaration(typenode.type)
+ def _as_func_arg(self, type):
+ if isinstance(type, model.ArrayType):
+ return model.PointerType(type.item)
+ elif isinstance(type, model.RawFunctionType):
+ return type.as_function_pointer()
+ else:
+ return type
+
+ def _is_constant_globalvar(self, typenode):
if isinstance(typenode, pycparser.c_ast.PtrDecl):
- const = 'const' in typenode.quals
- return self._is_constant_declaration(typenode.type, const)
+ return 'const' in typenode.quals
if isinstance(typenode, pycparser.c_ast.TypeDecl):
- return const or 'const' in typenode.quals
+ return 'const' in typenode.quals
return False
def _get_struct_union_enum_type(self, kind, type, name=None, nested=False):
@@ -491,7 +479,7 @@
return tp
def _make_partial(self, tp, nested):
- if not isinstance(tp, model.StructType):
+ if not isinstance(tp, model.StructOrUnion):
raise api.CDefError("%s cannot be partial" % (tp,))
if not tp.has_c_name() and not nested:
raise NotImplementedError("%s is partial but has no C name" %(tp,))
@@ -511,7 +499,7 @@
if (isinstance(exprnode, pycparser.c_ast.ID) and
exprnode.name == '__dotdotdotarray__'):
self._partial_length = True
- return None
+ return '...'
#
raise api.FFIError("unsupported expression: expected a "
"simple numeric constant")
diff --git a/lib_pypy/cffi/gc_weakref.py b/lib_pypy/cffi/gc_weakref.py
--- a/lib_pypy/cffi/gc_weakref.py
+++ b/lib_pypy/cffi/gc_weakref.py
@@ -14,6 +14,6 @@
def build(self, cdata, destructor):
# make a new cdata of the same type as the original one
- new_cdata = self.ffi.cast(self.ffi.typeof(cdata), cdata)
+ new_cdata = self.ffi.cast(self.ffi._backend.typeof(cdata), cdata)
self.data[ref(new_cdata, self.remove)] = destructor, cdata
return new_cdata
diff --git a/lib_pypy/cffi/lock.py b/lib_pypy/cffi/lock.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/cffi/lock.py
@@ -0,0 +1,30 @@
+import sys
+
+if sys.version_info < (3,):
+ try:
+ from thread import allocate_lock
+ except ImportError:
+ from dummy_thread import allocate_lock
+else:
+ try:
+ from _thread import allocate_lock
+ except ImportError:
+ from _dummy_thread import allocate_lock
+
+
+##import sys
+##l1 = allocate_lock
+
+##class allocate_lock(object):
+## def __init__(self):
+## self._real = l1()
+## def __enter__(self):
+## for i in range(4, 0, -1):
+## print sys._getframe(i).f_code
+## print
+## return self._real.__enter__()
+## def __exit__(self, *args):
+## return self._real.__exit__(*args)
+## def acquire(self, f):
+## assert f is False
+## return self._real.acquire(f)
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -1,7 +1,10 @@
import weakref
+from .lock import allocate_lock
+
class BaseTypeByIdentity(object):
is_array_type = False
+ is_raw_function = False
def get_c_name(self, replace_with='', context='a C file'):
result = self.c_name_with_marker
@@ -146,6 +149,7 @@
# a function, but not a pointer-to-function. The backend has no
# notion of such a type; it's used temporarily by parsing.
_base_pattern = '(&)(%s)'
+ is_raw_function = True
def build_backend_type(self, ffi, finishlist):
from . import api
@@ -192,10 +196,6 @@
_base_pattern = " const *&"
_base_pattern_array = "(const *&)"
- def build_backend_type(self, ffi, finishlist):
- BPtr = PointerType(self.totype).get_cached_btype(ffi, finishlist)
- return BPtr
-
const_voidp_type = ConstPointerType(void_type)
@@ -216,10 +216,12 @@
self.item = item
self.length = length
#
- if self.length is None:
+ if length is None:
brackets = '&[]'
+ elif length == '...':
+ brackets = '&[/*...*/]'
else:
- brackets = '&[%d]' % self.length
+ brackets = '&[%d]' % length
self.c_name_with_marker = (
self.item.c_name_with_marker.replace('&', brackets))
@@ -227,6 +229,10 @@
return ArrayType(self.item, newlength)
def build_backend_type(self, ffi, finishlist):
+ if self.length == '...':
+ from . import api
+ raise api.CDefError("cannot render the type %r: unknown length" %
+ (self,))
self.item.get_cached_btype(ffi, finishlist) # force the item BType
BPtrItem = PointerType(self.item).get_cached_btype(ffi, finishlist)
return global_cache(self, ffi, 'new_array_type', BPtrItem, self.length)
@@ -252,6 +258,7 @@
class StructOrUnion(StructOrUnionOrEnum):
fixedlayout = None
completed = False
+ partial = False
def __init__(self, name, fldnames, fldtypes, fldbitsize):
self.name = name
@@ -303,20 +310,21 @@
return # not completing it: it's an opaque struct
#
self.completed = 1
- fldtypes = tuple(tp.get_cached_btype(ffi, finishlist)
- for tp in self.fldtypes)
#
if self.fixedlayout is None:
+ fldtypes = [tp.get_cached_btype(ffi, finishlist)
+ for tp in self.fldtypes]
lst = list(zip(self.fldnames, fldtypes, self.fldbitsize))
ffi._backend.complete_struct_or_union(BType, lst, self)
#
else:
+ fldtypes = []
fieldofs, fieldsize, totalsize, totalalignment = self.fixedlayout
for i in range(len(self.fldnames)):
fsize = fieldsize[i]
ftype = self.fldtypes[i]
#
- if isinstance(ftype, ArrayType) and ftype.length is None:
+ if isinstance(ftype, ArrayType) and ftype.length == '...':
# fix the length to match the total size
BItemType = ftype.item.get_cached_btype(ffi, finishlist)
nlen, nrest = divmod(fsize, ffi.sizeof(BItemType))
@@ -327,18 +335,20 @@
ftype = ftype.resolve_length(nlen)
self.fldtypes = (self.fldtypes[:i] + (ftype,) +
self.fldtypes[i+1:])
- BArrayType = ftype.get_cached_btype(ffi, finishlist)
- fldtypes = (fldtypes[:i] + (BArrayType,) +
- fldtypes[i+1:])
- continue
#
- bitemsize = ffi.sizeof(fldtypes[i])
- if bitemsize != fsize:
- self._verification_error(
- "field '%s.%s' is declared as %d bytes, but is "
- "really %d bytes" % (self.name,
- self.fldnames[i] or '{}',
- bitemsize, fsize))
+ BFieldType = ftype.get_cached_btype(ffi, finishlist)
+ if isinstance(ftype, ArrayType) and ftype.length is None:
+ assert fsize == 0
+ else:
+ bitemsize = ffi.sizeof(BFieldType)
+ if bitemsize != fsize:
+ self._verification_error(
+ "field '%s.%s' is declared as %d bytes, but is "
+ "really %d bytes" % (self.name,
+ self.fldnames[i] or '{}',
+ bitemsize, fsize))
+ fldtypes.append(BFieldType)
+ #
lst = list(zip(self.fldnames, fldtypes, self.fldbitsize, fieldofs))
ffi._backend.complete_struct_or_union(BType, lst, self,
totalsize, totalalignment)
@@ -348,11 +358,6 @@
from .ffiplatform import VerificationError
raise VerificationError(msg)
-
-class StructType(StructOrUnion):
- kind = 'struct'
- partial = False
-
def check_not_partial(self):
if self.partial and self.fixedlayout is None:
from . import ffiplatform
@@ -361,19 +366,18 @@
def build_backend_type(self, ffi, finishlist):
self.check_not_partial()
finishlist.append(self)
-
- return global_cache(self, ffi, 'new_struct_type',
+ #
+ return global_cache(self, ffi, 'new_%s_type' % self.kind,
self.get_official_name(), key=self)
+class StructType(StructOrUnion):
+ kind = 'struct'
+
+
class UnionType(StructOrUnion):
kind = 'union'
- def build_backend_type(self, ffi, finishlist):
- finishlist.append(self)
- return global_cache(self, ffi, 'new_union_type',
- self.get_official_name(), key=self)
-
class EnumType(StructOrUnionOrEnum):
kind = 'enum'
@@ -387,6 +391,12 @@
self.baseinttype = baseinttype
self.build_c_name_with_marker()
+ def force_the_name(self, forcename):
+ StructOrUnionOrEnum.force_the_name(self, forcename)
+ if self.forcename is None:
+ name = self.get_official_name()
+ self.forcename = '$' + name.replace(' ', '_')
+
def check_not_partial(self):
if self.partial and not self.partial_resolved:
from . import ffiplatform
@@ -444,6 +454,9 @@
tp = StructType(structname, None, None, None)
return NamedPointerType(tp, name)
+
+global_lock = allocate_lock()
+
def global_cache(srctype, ffi, funcname, *args, **kwds):
key = kwds.pop('key', (funcname, args))
assert not kwds
@@ -464,8 +477,17 @@
res = getattr(ffi._backend, funcname)(*args)
except NotImplementedError as e:
raise NotImplementedError("%r: %s" % (srctype, e))
- ffi._backend.__typecache[key] = res
- return res
+ # note that setdefault() on WeakValueDictionary is not atomic
+ # and contains a rare bug (http://bugs.python.org/issue19542);
+ # we have to use a lock and do it ourselves
+ cache = ffi._backend.__typecache
+ with global_lock:
+ res1 = cache.get(key)
+ if res1 is None:
+ cache[key] = res
+ return res
+ else:
+ return res1
def pointer_cache(ffi, BType):
return global_cache('?', ffi, 'new_pointer_type', BType)
diff --git a/lib_pypy/cffi/vengine_cpy.py b/lib_pypy/cffi/vengine_cpy.py
--- a/lib_pypy/cffi/vengine_cpy.py
More information about the pypy-commit
mailing list