mirror of https://github.com/python/cpython
merge heads
This commit is contained in:
commit
059226b8ec
|
@ -1669,6 +1669,24 @@ with the :class:`Pool` class.
|
||||||
returned iterator should be considered arbitrary. (Only when there is
|
returned iterator should be considered arbitrary. (Only when there is
|
||||||
only one worker process is the order guaranteed to be "correct".)
|
only one worker process is the order guaranteed to be "correct".)
|
||||||
|
|
||||||
|
.. method:: starmap(func, iterable[, chunksize])
|
||||||
|
|
||||||
|
Like :meth:`map` except that the elements of the `iterable` are expected
|
||||||
|
to be iterables that are unpacked as arguments.
|
||||||
|
|
||||||
|
Hence an `iterable` of `[(1,2), (3, 4)]` results in `[func(1,2),
|
||||||
|
func(3,4)]`.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
.. method:: starmap_async(func, iterable[, chunksize[, callback[, error_back]]])
|
||||||
|
|
||||||
|
A combination of :meth:`starmap` and :meth:`map_async` that iterates over
|
||||||
|
`iterable` of iterables and calls `func` with the iterables unpacked.
|
||||||
|
Returns a result object.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
.. method:: close()
|
.. method:: close()
|
||||||
|
|
||||||
Prevents any more tasks from being submitted to the pool. Once all the
|
Prevents any more tasks from being submitted to the pool. Once all the
|
||||||
|
|
|
@ -445,6 +445,14 @@ Constants
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
|
.. data:: HAS_ECDH
|
||||||
|
|
||||||
|
Whether the OpenSSL library has built-in support for Elliptic Curve-based
|
||||||
|
Diffie-Hellman key exchange. This should be true unless the feature was
|
||||||
|
explicitly disabled by the distributor.
|
||||||
|
|
||||||
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
.. data:: HAS_SNI
|
.. data:: HAS_SNI
|
||||||
|
|
||||||
Whether the OpenSSL library has built-in support for the *Server Name
|
Whether the OpenSSL library has built-in support for the *Server Name
|
||||||
|
@ -711,6 +719,8 @@ to speed up repeated connections from the same clients.
|
||||||
This setting doesn't apply to client sockets. You can also use the
|
This setting doesn't apply to client sockets. You can also use the
|
||||||
:data:`OP_SINGLE_ECDH_USE` option to further improve security.
|
:data:`OP_SINGLE_ECDH_USE` option to further improve security.
|
||||||
|
|
||||||
|
This method is not available if :data:`HAS_ECDH` is False.
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionadded:: 3.3
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
|
@ -96,47 +96,55 @@ A number of browser types are predefined. This table gives the type names that
|
||||||
may be passed to the :func:`get` function and the corresponding instantiations
|
may be passed to the :func:`get` function and the corresponding instantiations
|
||||||
for the controller classes, all defined in this module.
|
for the controller classes, all defined in this module.
|
||||||
|
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| Type Name | Class Name | Notes |
|
| Type Name | Class Name | Notes |
|
||||||
+=======================+=========================================+=======+
|
+========================+=========================================+=======+
|
||||||
| ``'mozilla'`` | :class:`Mozilla('mozilla')` | |
|
| ``'mozilla'`` | :class:`Mozilla('mozilla')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'firefox'`` | :class:`Mozilla('mozilla')` | |
|
| ``'firefox'`` | :class:`Mozilla('mozilla')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'netscape'`` | :class:`Mozilla('netscape')` | |
|
| ``'netscape'`` | :class:`Mozilla('netscape')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'galeon'`` | :class:`Galeon('galeon')` | |
|
| ``'galeon'`` | :class:`Galeon('galeon')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'epiphany'`` | :class:`Galeon('epiphany')` | |
|
| ``'epiphany'`` | :class:`Galeon('epiphany')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'skipstone'`` | :class:`BackgroundBrowser('skipstone')` | |
|
| ``'skipstone'`` | :class:`BackgroundBrowser('skipstone')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'kfmclient'`` | :class:`Konqueror()` | \(1) |
|
| ``'kfmclient'`` | :class:`Konqueror()` | \(1) |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'konqueror'`` | :class:`Konqueror()` | \(1) |
|
| ``'konqueror'`` | :class:`Konqueror()` | \(1) |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'kfm'`` | :class:`Konqueror()` | \(1) |
|
| ``'kfm'`` | :class:`Konqueror()` | \(1) |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'mosaic'`` | :class:`BackgroundBrowser('mosaic')` | |
|
| ``'mosaic'`` | :class:`BackgroundBrowser('mosaic')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'opera'`` | :class:`Opera()` | |
|
| ``'opera'`` | :class:`Opera()` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'grail'`` | :class:`Grail()` | |
|
| ``'grail'`` | :class:`Grail()` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'links'`` | :class:`GenericBrowser('links')` | |
|
| ``'links'`` | :class:`GenericBrowser('links')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'elinks'`` | :class:`Elinks('elinks')` | |
|
| ``'elinks'`` | :class:`Elinks('elinks')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'lynx'`` | :class:`GenericBrowser('lynx')` | |
|
| ``'lynx'`` | :class:`GenericBrowser('lynx')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'w3m'`` | :class:`GenericBrowser('w3m')` | |
|
| ``'w3m'`` | :class:`GenericBrowser('w3m')` | |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'windows-default'`` | :class:`WindowsDefault` | \(2) |
|
| ``'windows-default'`` | :class:`WindowsDefault` | \(2) |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'internet-config'`` | :class:`InternetConfig` | \(3) |
|
| ``'internet-config'`` | :class:`InternetConfig` | \(3) |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
| ``'macosx'`` | :class:`MacOSX('default')` | \(4) |
|
| ``'macosx'`` | :class:`MacOSX('default')` | \(4) |
|
||||||
+-----------------------+-----------------------------------------+-------+
|
+------------------------+-----------------------------------------+-------+
|
||||||
|
| ``'google-chrome'`` | :class:`Chrome('google-chrome')` | |
|
||||||
|
+------------------------+-----------------------------------------+-------+
|
||||||
|
| ``'chrome'`` | :class:`Chrome('chrome')` | |
|
||||||
|
+------------------------+-----------------------------------------+-------+
|
||||||
|
| ``'chromium'`` | :class:`Chromium('chromium')` | |
|
||||||
|
+------------------------+-----------------------------------------+-------+
|
||||||
|
| ``'chromium-browser'`` | :class:`Chromium('chromium-browser')` | |
|
||||||
|
+------------------------+-----------------------------------------+-------+
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,8 @@ Miscellaneous options
|
||||||
|
|
||||||
Force the binary layer of the stdin, stdout and stderr streams (which is
|
Force the binary layer of the stdin, stdout and stderr streams (which is
|
||||||
available as their ``buffer`` attribute) to be unbuffered. The text I/O
|
available as their ``buffer`` attribute) to be unbuffered. The text I/O
|
||||||
layer will still be line-buffered.
|
layer will still be line-buffered if writing to the console, or
|
||||||
|
block-buffered if redirected to a non-interactive file.
|
||||||
|
|
||||||
See also :envvar:`PYTHONUNBUFFERED`.
|
See also :envvar:`PYTHONUNBUFFERED`.
|
||||||
|
|
||||||
|
|
|
@ -301,6 +301,12 @@ changed.
|
||||||
There is no longer any need for using the encoding-aware streams
|
There is no longer any need for using the encoding-aware streams
|
||||||
in the :mod:`codecs` module.
|
in the :mod:`codecs` module.
|
||||||
|
|
||||||
|
* The initial values of :data:`sys.stdin`, :data:`sys.stdout` and
|
||||||
|
:data:`sys.stderr` are now unicode-only text files (i.e., they are
|
||||||
|
instances of :class:`io.TextIOBase`). To read and write bytes data
|
||||||
|
with these streams, you need to use their :data:`io.TextIOBase.buffer`
|
||||||
|
attribute.
|
||||||
|
|
||||||
* Filenames are passed to and returned from APIs as (Unicode) strings.
|
* Filenames are passed to and returned from APIs as (Unicode) strings.
|
||||||
This can present platform-specific problems because on some
|
This can present platform-specific problems because on some
|
||||||
platforms filenames are arbitrary byte strings. (On the other hand,
|
platforms filenames are arbitrary byte strings. (On the other hand,
|
||||||
|
@ -511,9 +517,7 @@ consulted for longer descriptions.
|
||||||
produces a literal of type :class:`bytes`.
|
produces a literal of type :class:`bytes`.
|
||||||
|
|
||||||
* :ref:`pep-3116`. The :mod:`io` module is now the standard way of
|
* :ref:`pep-3116`. The :mod:`io` module is now the standard way of
|
||||||
doing file I/O, and the initial values of :data:`sys.stdin`,
|
doing file I/O. The built-in :func:`open` function is now an
|
||||||
:data:`sys.stdout` and :data:`sys.stderr` are now instances of
|
|
||||||
:class:`io.TextIOBase`. The built-in :func:`open` function is now an
|
|
||||||
alias for :func:`io.open` and has additional keyword arguments
|
alias for :func:`io.open` and has additional keyword arguments
|
||||||
*encoding*, *errors*, *newline* and *closefd*. Also note that an
|
*encoding*, *errors*, *newline* and *closefd*. Also note that an
|
||||||
invalid *mode* argument now raises :exc:`ValueError`, not
|
invalid *mode* argument now raises :exc:`ValueError`, not
|
||||||
|
|
|
@ -99,11 +99,11 @@ def ismethoddescriptor(object):
|
||||||
tests return false from the ismethoddescriptor() test, simply because
|
tests return false from the ismethoddescriptor() test, simply because
|
||||||
the other tests promise more -- you can, e.g., count on having the
|
the other tests promise more -- you can, e.g., count on having the
|
||||||
__func__ attribute (etc) when an object passes ismethod()."""
|
__func__ attribute (etc) when an object passes ismethod()."""
|
||||||
return (hasattr(object, "__get__")
|
if isclass(object) or ismethod(object) or isfunction(object):
|
||||||
and not hasattr(object, "__set__") # else it's a data descriptor
|
# mutual exclusion
|
||||||
and not ismethod(object) # mutual exclusion
|
return False
|
||||||
and not isfunction(object)
|
tp = type(object)
|
||||||
and not isclass(object))
|
return hasattr(tp, "__get__") and not hasattr(tp, "__set__")
|
||||||
|
|
||||||
def isdatadescriptor(object):
|
def isdatadescriptor(object):
|
||||||
"""Return true if the object is a data descriptor.
|
"""Return true if the object is a data descriptor.
|
||||||
|
@ -113,7 +113,11 @@ def isdatadescriptor(object):
|
||||||
Typically, data descriptors will also have __name__ and __doc__ attributes
|
Typically, data descriptors will also have __name__ and __doc__ attributes
|
||||||
(properties, getsets, and members have both of these attributes), but this
|
(properties, getsets, and members have both of these attributes), but this
|
||||||
is not guaranteed."""
|
is not guaranteed."""
|
||||||
return (hasattr(object, "__set__") and hasattr(object, "__get__"))
|
if isclass(object) or ismethod(object) or isfunction(object):
|
||||||
|
# mutual exclusion
|
||||||
|
return False
|
||||||
|
tp = type(object)
|
||||||
|
return hasattr(tp, "__set__") and hasattr(tp, "__get__")
|
||||||
|
|
||||||
if hasattr(types, 'MemberDescriptorType'):
|
if hasattr(types, 'MemberDescriptorType'):
|
||||||
# CPython and equivalent
|
# CPython and equivalent
|
||||||
|
@ -253,12 +257,23 @@ def isabstract(object):
|
||||||
def getmembers(object, predicate=None):
|
def getmembers(object, predicate=None):
|
||||||
"""Return all members of an object as (name, value) pairs sorted by name.
|
"""Return all members of an object as (name, value) pairs sorted by name.
|
||||||
Optionally, only return members that satisfy a given predicate."""
|
Optionally, only return members that satisfy a given predicate."""
|
||||||
|
if isclass(object):
|
||||||
|
mro = (object,) + getmro(object)
|
||||||
|
else:
|
||||||
|
mro = ()
|
||||||
results = []
|
results = []
|
||||||
for key in dir(object):
|
for key in dir(object):
|
||||||
try:
|
# First try to get the value via __dict__. Some descriptors don't
|
||||||
value = getattr(object, key)
|
# like calling their __get__ (see bug #1785).
|
||||||
except AttributeError:
|
for base in mro:
|
||||||
continue
|
if key in base.__dict__:
|
||||||
|
value = base.__dict__[key]
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
value = getattr(object, key)
|
||||||
|
except AttributeError:
|
||||||
|
continue
|
||||||
if not predicate or predicate(value):
|
if not predicate or predicate(value):
|
||||||
results.append((key, value))
|
results.append((key, value))
|
||||||
results.sort()
|
results.sort()
|
||||||
|
@ -294,30 +309,21 @@ def classify_class_attrs(cls):
|
||||||
names = dir(cls)
|
names = dir(cls)
|
||||||
result = []
|
result = []
|
||||||
for name in names:
|
for name in names:
|
||||||
# Get the object associated with the name.
|
# Get the object associated with the name, and where it was defined.
|
||||||
# Getting an obj from the __dict__ sometimes reveals more than
|
# Getting an obj from the __dict__ sometimes reveals more than
|
||||||
# using getattr. Static and class methods are dramatic examples.
|
# using getattr. Static and class methods are dramatic examples.
|
||||||
if name in cls.__dict__:
|
# Furthermore, some objects may raise an Exception when fetched with
|
||||||
obj = cls.__dict__[name]
|
# getattr(). This is the case with some descriptors (bug #1785).
|
||||||
|
# Thus, we only use getattr() as a last resort.
|
||||||
|
homecls = None
|
||||||
|
for base in (cls,) + mro:
|
||||||
|
if name in base.__dict__:
|
||||||
|
obj = base.__dict__[name]
|
||||||
|
homecls = base
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
obj = getattr(cls, name)
|
obj = getattr(cls, name)
|
||||||
|
homecls = getattr(obj, "__objclass__", homecls)
|
||||||
# Figure out where it was defined.
|
|
||||||
homecls = getattr(obj, "__objclass__", None)
|
|
||||||
if homecls is None:
|
|
||||||
# search the dicts.
|
|
||||||
for base in mro:
|
|
||||||
if name in base.__dict__:
|
|
||||||
homecls = base
|
|
||||||
break
|
|
||||||
|
|
||||||
# Get the object again, in order to get it from the defining
|
|
||||||
# __dict__ instead of via getattr (if possible).
|
|
||||||
if homecls is not None and name in homecls.__dict__:
|
|
||||||
obj = homecls.__dict__[name]
|
|
||||||
|
|
||||||
# Also get the object via getattr.
|
|
||||||
obj_via_getattr = getattr(cls, name)
|
|
||||||
|
|
||||||
# Classify the object.
|
# Classify the object.
|
||||||
if isinstance(obj, staticmethod):
|
if isinstance(obj, staticmethod):
|
||||||
|
@ -326,11 +332,18 @@ def classify_class_attrs(cls):
|
||||||
kind = "class method"
|
kind = "class method"
|
||||||
elif isinstance(obj, property):
|
elif isinstance(obj, property):
|
||||||
kind = "property"
|
kind = "property"
|
||||||
elif (isfunction(obj_via_getattr) or
|
elif ismethoddescriptor(obj):
|
||||||
ismethoddescriptor(obj_via_getattr)):
|
|
||||||
kind = "method"
|
kind = "method"
|
||||||
else:
|
elif isdatadescriptor(obj):
|
||||||
kind = "data"
|
kind = "data"
|
||||||
|
else:
|
||||||
|
obj_via_getattr = getattr(cls, name)
|
||||||
|
if (isfunction(obj_via_getattr) or
|
||||||
|
ismethoddescriptor(obj_via_getattr)):
|
||||||
|
kind = "method"
|
||||||
|
else:
|
||||||
|
kind = "data"
|
||||||
|
obj = obj_via_getattr
|
||||||
|
|
||||||
result.append(Attribute(name, kind, homecls, obj))
|
result.append(Attribute(name, kind, homecls, obj))
|
||||||
|
|
||||||
|
|
|
@ -1066,11 +1066,12 @@ ArrayProxy = MakeProxyType('ArrayProxy', (
|
||||||
|
|
||||||
PoolProxy = MakeProxyType('PoolProxy', (
|
PoolProxy = MakeProxyType('PoolProxy', (
|
||||||
'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join',
|
'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join',
|
||||||
'map', 'map_async', 'terminate'
|
'map', 'map_async', 'starmap', 'starmap_async', 'terminate'
|
||||||
))
|
))
|
||||||
PoolProxy._method_to_typeid_ = {
|
PoolProxy._method_to_typeid_ = {
|
||||||
'apply_async': 'AsyncResult',
|
'apply_async': 'AsyncResult',
|
||||||
'map_async': 'AsyncResult',
|
'map_async': 'AsyncResult',
|
||||||
|
'starmap_async': 'AsyncResult',
|
||||||
'imap': 'Iterator',
|
'imap': 'Iterator',
|
||||||
'imap_unordered': 'Iterator'
|
'imap_unordered': 'Iterator'
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,9 @@ job_counter = itertools.count()
|
||||||
def mapstar(args):
|
def mapstar(args):
|
||||||
return list(map(*args))
|
return list(map(*args))
|
||||||
|
|
||||||
|
def starmapstar(args):
|
||||||
|
return list(itertools.starmap(args[0], args[1]))
|
||||||
|
|
||||||
#
|
#
|
||||||
# Code run by worker processes
|
# Code run by worker processes
|
||||||
#
|
#
|
||||||
|
@ -248,7 +251,25 @@ class Pool(object):
|
||||||
in a list that is returned.
|
in a list that is returned.
|
||||||
'''
|
'''
|
||||||
assert self._state == RUN
|
assert self._state == RUN
|
||||||
return self.map_async(func, iterable, chunksize).get()
|
return self._map_async(func, iterable, mapstar, chunksize).get()
|
||||||
|
|
||||||
|
def starmap(self, func, iterable, chunksize=None):
|
||||||
|
'''
|
||||||
|
Like `map()` method but the elements of the `iterable` are expected to
|
||||||
|
be iterables as well and will be unpacked as arguments. Hence
|
||||||
|
`func` and (a, b) becomes func(a, b).
|
||||||
|
'''
|
||||||
|
assert self._state == RUN
|
||||||
|
return self._map_async(func, iterable, starmapstar, chunksize).get()
|
||||||
|
|
||||||
|
def starmap_async(self, func, iterable, chunksize=None, callback=None,
|
||||||
|
error_callback=None):
|
||||||
|
'''
|
||||||
|
Asynchronous version of `starmap()` method.
|
||||||
|
'''
|
||||||
|
assert self._state == RUN
|
||||||
|
return self._map_async(func, iterable, starmapstar, chunksize,
|
||||||
|
callback, error_callback)
|
||||||
|
|
||||||
def imap(self, func, iterable, chunksize=1):
|
def imap(self, func, iterable, chunksize=1):
|
||||||
'''
|
'''
|
||||||
|
@ -302,6 +323,13 @@ class Pool(object):
|
||||||
Asynchronous version of `map()` method.
|
Asynchronous version of `map()` method.
|
||||||
'''
|
'''
|
||||||
assert self._state == RUN
|
assert self._state == RUN
|
||||||
|
return self._map_async(func, iterable, mapstar, chunksize)
|
||||||
|
|
||||||
|
def _map_async(self, func, iterable, mapper, chunksize=None, callback=None,
|
||||||
|
error_callback=None):
|
||||||
|
'''
|
||||||
|
Helper function to implement map, starmap and their async counterparts.
|
||||||
|
'''
|
||||||
if not hasattr(iterable, '__len__'):
|
if not hasattr(iterable, '__len__'):
|
||||||
iterable = list(iterable)
|
iterable = list(iterable)
|
||||||
|
|
||||||
|
@ -315,7 +343,7 @@ class Pool(object):
|
||||||
task_batches = Pool._get_tasks(func, iterable, chunksize)
|
task_batches = Pool._get_tasks(func, iterable, chunksize)
|
||||||
result = MapResult(self._cache, chunksize, len(iterable), callback,
|
result = MapResult(self._cache, chunksize, len(iterable), callback,
|
||||||
error_callback=error_callback)
|
error_callback=error_callback)
|
||||||
self._taskqueue.put((((result._job, i, mapstar, (x,), {})
|
self._taskqueue.put((((result._job, i, mapper, (x,), {})
|
||||||
for i, x in enumerate(task_batches)), None))
|
for i, x in enumerate(task_batches)), None))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
29
Lib/pydoc.py
29
Lib/pydoc.py
|
@ -748,8 +748,15 @@ class HTMLDoc(Doc):
|
||||||
hr.maybe()
|
hr.maybe()
|
||||||
push(msg)
|
push(msg)
|
||||||
for name, kind, homecls, value in ok:
|
for name, kind, homecls, value in ok:
|
||||||
push(self.document(getattr(object, name), name, mod,
|
try:
|
||||||
funcs, classes, mdict, object))
|
value = getattr(object, name)
|
||||||
|
except Exception:
|
||||||
|
# Some descriptors may meet a failure in their __get__.
|
||||||
|
# (bug #1785)
|
||||||
|
push(self._docdescriptor(name, value, mod))
|
||||||
|
else:
|
||||||
|
push(self.document(value, name, mod,
|
||||||
|
funcs, classes, mdict, object))
|
||||||
push('\n')
|
push('\n')
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
@ -790,7 +797,12 @@ class HTMLDoc(Doc):
|
||||||
mdict = {}
|
mdict = {}
|
||||||
for key, kind, homecls, value in attrs:
|
for key, kind, homecls, value in attrs:
|
||||||
mdict[key] = anchor = '#' + name + '-' + key
|
mdict[key] = anchor = '#' + name + '-' + key
|
||||||
value = getattr(object, key)
|
try:
|
||||||
|
value = getattr(object, name)
|
||||||
|
except Exception:
|
||||||
|
# Some descriptors may meet a failure in their __get__.
|
||||||
|
# (bug #1785)
|
||||||
|
pass
|
||||||
try:
|
try:
|
||||||
# The value may not be hashable (e.g., a data attr with
|
# The value may not be hashable (e.g., a data attr with
|
||||||
# a dict or list value).
|
# a dict or list value).
|
||||||
|
@ -1177,8 +1189,15 @@ location listed above.
|
||||||
hr.maybe()
|
hr.maybe()
|
||||||
push(msg)
|
push(msg)
|
||||||
for name, kind, homecls, value in ok:
|
for name, kind, homecls, value in ok:
|
||||||
push(self.document(getattr(object, name),
|
try:
|
||||||
name, mod, object))
|
value = getattr(object, name)
|
||||||
|
except Exception:
|
||||||
|
# Some descriptors may meet a failure in their __get__.
|
||||||
|
# (bug #1785)
|
||||||
|
push(self._docdescriptor(name, value, mod))
|
||||||
|
else:
|
||||||
|
push(self.document(value,
|
||||||
|
name, mod, object))
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
def spilldescriptors(msg, attrs, predicate):
|
def spilldescriptors(msg, attrs, predicate):
|
||||||
|
|
|
@ -86,7 +86,7 @@ from _ssl import (
|
||||||
SSL_ERROR_EOF,
|
SSL_ERROR_EOF,
|
||||||
SSL_ERROR_INVALID_ERROR_CODE,
|
SSL_ERROR_INVALID_ERROR_CODE,
|
||||||
)
|
)
|
||||||
from _ssl import HAS_SNI
|
from _ssl import HAS_SNI, HAS_ECDH
|
||||||
from _ssl import (PROTOCOL_SSLv3, PROTOCOL_SSLv23,
|
from _ssl import (PROTOCOL_SSLv3, PROTOCOL_SSLv23,
|
||||||
PROTOCOL_TLSv1)
|
PROTOCOL_TLSv1)
|
||||||
from _ssl import _OPENSSL_API_VERSION
|
from _ssl import _OPENSSL_API_VERSION
|
||||||
|
|
|
@ -104,8 +104,9 @@ class ImportTests(unittest.TestCase):
|
||||||
try:
|
try:
|
||||||
fname = TESTFN + os.extsep + "py"
|
fname = TESTFN + os.extsep + "py"
|
||||||
create_empty_file(fname)
|
create_empty_file(fname)
|
||||||
__import__(TESTFN)
|
|
||||||
fn = imp.cache_from_source(fname)
|
fn = imp.cache_from_source(fname)
|
||||||
|
unlink(fn)
|
||||||
|
__import__(TESTFN)
|
||||||
if not os.path.exists(fn):
|
if not os.path.exists(fn):
|
||||||
self.fail("__import__ did not result in creation of "
|
self.fail("__import__ did not result in creation of "
|
||||||
"either a .pyc or .pyo file")
|
"either a .pyc or .pyo file")
|
||||||
|
|
|
@ -425,10 +425,37 @@ class TestNoEOL(GetSourceBase):
|
||||||
def test_class(self):
|
def test_class(self):
|
||||||
self.assertSourceEqual(self.fodderModule.X, 1, 2)
|
self.assertSourceEqual(self.fodderModule.X, 1, 2)
|
||||||
|
|
||||||
|
|
||||||
|
class _BrokenDataDescriptor(object):
|
||||||
|
"""
|
||||||
|
A broken data descriptor. See bug #1785.
|
||||||
|
"""
|
||||||
|
def __get__(*args):
|
||||||
|
raise AssertionError("should not __get__ data descriptors")
|
||||||
|
|
||||||
|
def __set__(*args):
|
||||||
|
raise RuntimeError
|
||||||
|
|
||||||
|
def __getattr__(*args):
|
||||||
|
raise AssertionError("should not __getattr__ data descriptors")
|
||||||
|
|
||||||
|
|
||||||
|
class _BrokenMethodDescriptor(object):
|
||||||
|
"""
|
||||||
|
A broken method descriptor. See bug #1785.
|
||||||
|
"""
|
||||||
|
def __get__(*args):
|
||||||
|
raise AssertionError("should not __get__ method descriptors")
|
||||||
|
|
||||||
|
def __getattr__(*args):
|
||||||
|
raise AssertionError("should not __getattr__ method descriptors")
|
||||||
|
|
||||||
|
|
||||||
# Helper for testing classify_class_attrs.
|
# Helper for testing classify_class_attrs.
|
||||||
def attrs_wo_objs(cls):
|
def attrs_wo_objs(cls):
|
||||||
return [t[:3] for t in inspect.classify_class_attrs(cls)]
|
return [t[:3] for t in inspect.classify_class_attrs(cls)]
|
||||||
|
|
||||||
|
|
||||||
class TestClassesAndFunctions(unittest.TestCase):
|
class TestClassesAndFunctions(unittest.TestCase):
|
||||||
def test_newstyle_mro(self):
|
def test_newstyle_mro(self):
|
||||||
# The same w/ new-class MRO.
|
# The same w/ new-class MRO.
|
||||||
|
@ -525,6 +552,9 @@ class TestClassesAndFunctions(unittest.TestCase):
|
||||||
|
|
||||||
datablob = '1'
|
datablob = '1'
|
||||||
|
|
||||||
|
dd = _BrokenDataDescriptor()
|
||||||
|
md = _BrokenMethodDescriptor()
|
||||||
|
|
||||||
attrs = attrs_wo_objs(A)
|
attrs = attrs_wo_objs(A)
|
||||||
self.assertIn(('s', 'static method', A), attrs, 'missing static method')
|
self.assertIn(('s', 'static method', A), attrs, 'missing static method')
|
||||||
self.assertIn(('c', 'class method', A), attrs, 'missing class method')
|
self.assertIn(('c', 'class method', A), attrs, 'missing class method')
|
||||||
|
@ -533,6 +563,8 @@ class TestClassesAndFunctions(unittest.TestCase):
|
||||||
'missing plain method: %r' % attrs)
|
'missing plain method: %r' % attrs)
|
||||||
self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
|
self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
|
||||||
self.assertIn(('datablob', 'data', A), attrs, 'missing data')
|
self.assertIn(('datablob', 'data', A), attrs, 'missing data')
|
||||||
|
self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
|
||||||
|
self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
|
||||||
|
|
||||||
class B(A):
|
class B(A):
|
||||||
|
|
||||||
|
@ -545,6 +577,8 @@ class TestClassesAndFunctions(unittest.TestCase):
|
||||||
self.assertIn(('m', 'method', B), attrs, 'missing plain method')
|
self.assertIn(('m', 'method', B), attrs, 'missing plain method')
|
||||||
self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
|
self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
|
||||||
self.assertIn(('datablob', 'data', A), attrs, 'missing data')
|
self.assertIn(('datablob', 'data', A), attrs, 'missing data')
|
||||||
|
self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
|
||||||
|
self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
|
||||||
|
|
||||||
|
|
||||||
class C(A):
|
class C(A):
|
||||||
|
@ -559,6 +593,8 @@ class TestClassesAndFunctions(unittest.TestCase):
|
||||||
self.assertIn(('m', 'method', C), attrs, 'missing plain method')
|
self.assertIn(('m', 'method', C), attrs, 'missing plain method')
|
||||||
self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
|
self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
|
||||||
self.assertIn(('datablob', 'data', A), attrs, 'missing data')
|
self.assertIn(('datablob', 'data', A), attrs, 'missing data')
|
||||||
|
self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
|
||||||
|
self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
|
||||||
|
|
||||||
class D(B, C):
|
class D(B, C):
|
||||||
|
|
||||||
|
@ -571,6 +607,49 @@ class TestClassesAndFunctions(unittest.TestCase):
|
||||||
self.assertIn(('m', 'method', B), attrs, 'missing plain method')
|
self.assertIn(('m', 'method', B), attrs, 'missing plain method')
|
||||||
self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
|
self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
|
||||||
self.assertIn(('datablob', 'data', A), attrs, 'missing data')
|
self.assertIn(('datablob', 'data', A), attrs, 'missing data')
|
||||||
|
self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
|
||||||
|
self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
|
||||||
|
|
||||||
|
def test_classify_builtin_types(self):
|
||||||
|
# Simple sanity check that all built-in types can have their
|
||||||
|
# attributes classified.
|
||||||
|
for name in dir(__builtins__):
|
||||||
|
builtin = getattr(__builtins__, name)
|
||||||
|
if isinstance(builtin, type):
|
||||||
|
inspect.classify_class_attrs(builtin)
|
||||||
|
|
||||||
|
def test_getmembers_descriptors(self):
|
||||||
|
class A(object):
|
||||||
|
dd = _BrokenDataDescriptor()
|
||||||
|
md = _BrokenMethodDescriptor()
|
||||||
|
|
||||||
|
def pred_wrapper(pred):
|
||||||
|
# A quick'n'dirty way to discard standard attributes of new-style
|
||||||
|
# classes.
|
||||||
|
class Empty(object):
|
||||||
|
pass
|
||||||
|
def wrapped(x):
|
||||||
|
if '__name__' in dir(x) and hasattr(Empty, x.__name__):
|
||||||
|
return False
|
||||||
|
return pred(x)
|
||||||
|
return wrapped
|
||||||
|
|
||||||
|
ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
|
||||||
|
isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
|
||||||
|
|
||||||
|
self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
|
||||||
|
[('md', A.__dict__['md'])])
|
||||||
|
self.assertEqual(inspect.getmembers(A, isdatadescriptor),
|
||||||
|
[('dd', A.__dict__['dd'])])
|
||||||
|
|
||||||
|
class B(A):
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
|
||||||
|
[('md', A.__dict__['md'])])
|
||||||
|
self.assertEqual(inspect.getmembers(B, isdatadescriptor),
|
||||||
|
[('dd', A.__dict__['dd'])])
|
||||||
|
|
||||||
|
|
||||||
class TestGetcallargsFunctions(unittest.TestCase):
|
class TestGetcallargsFunctions(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import unittest
|
||||||
import queue as pyqueue
|
import queue as pyqueue
|
||||||
import time
|
import time
|
||||||
import io
|
import io
|
||||||
|
import itertools
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import gc
|
import gc
|
||||||
|
@ -1125,6 +1126,9 @@ def sqr(x, wait=0.0):
|
||||||
time.sleep(wait)
|
time.sleep(wait)
|
||||||
return x*x
|
return x*x
|
||||||
|
|
||||||
|
def mul(x, y):
|
||||||
|
return x*y
|
||||||
|
|
||||||
class _TestPool(BaseTestCase):
|
class _TestPool(BaseTestCase):
|
||||||
|
|
||||||
def test_apply(self):
|
def test_apply(self):
|
||||||
|
@ -1138,6 +1142,20 @@ class _TestPool(BaseTestCase):
|
||||||
self.assertEqual(pmap(sqr, list(range(100)), chunksize=20),
|
self.assertEqual(pmap(sqr, list(range(100)), chunksize=20),
|
||||||
list(map(sqr, list(range(100)))))
|
list(map(sqr, list(range(100)))))
|
||||||
|
|
||||||
|
def test_starmap(self):
|
||||||
|
psmap = self.pool.starmap
|
||||||
|
tuples = list(zip(range(10), range(9,-1, -1)))
|
||||||
|
self.assertEqual(psmap(mul, tuples),
|
||||||
|
list(itertools.starmap(mul, tuples)))
|
||||||
|
tuples = list(zip(range(100), range(99,-1, -1)))
|
||||||
|
self.assertEqual(psmap(mul, tuples, chunksize=20),
|
||||||
|
list(itertools.starmap(mul, tuples)))
|
||||||
|
|
||||||
|
def test_starmap_async(self):
|
||||||
|
tuples = list(zip(range(100), range(99,-1, -1)))
|
||||||
|
self.assertEqual(self.pool.starmap_async(mul, tuples).get(),
|
||||||
|
list(itertools.starmap(mul, tuples)))
|
||||||
|
|
||||||
def test_map_chunksize(self):
|
def test_map_chunksize(self):
|
||||||
try:
|
try:
|
||||||
self.pool.map_async(sqr, [], chunksize=1).get(timeout=TIMEOUT1)
|
self.pool.map_async(sqr, [], chunksize=1).get(timeout=TIMEOUT1)
|
||||||
|
|
|
@ -103,6 +103,7 @@ class BasicSocketTests(unittest.TestCase):
|
||||||
if ssl.OPENSSL_VERSION_INFO >= (1, 0):
|
if ssl.OPENSSL_VERSION_INFO >= (1, 0):
|
||||||
ssl.OP_NO_COMPRESSION
|
ssl.OP_NO_COMPRESSION
|
||||||
self.assertIn(ssl.HAS_SNI, {True, False})
|
self.assertIn(ssl.HAS_SNI, {True, False})
|
||||||
|
self.assertIn(ssl.HAS_ECDH, {True, False})
|
||||||
|
|
||||||
def test_random(self):
|
def test_random(self):
|
||||||
v = ssl.RAND_status()
|
v = ssl.RAND_status()
|
||||||
|
@ -561,6 +562,7 @@ class ContextTests(unittest.TestCase):
|
||||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||||
ctx.set_default_verify_paths()
|
ctx.set_default_verify_paths()
|
||||||
|
|
||||||
|
@unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
|
||||||
def test_set_ecdh_curve(self):
|
def test_set_ecdh_curve(self):
|
||||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||||
ctx.set_ecdh_curve("prime256v1")
|
ctx.set_ecdh_curve("prime256v1")
|
||||||
|
@ -984,6 +986,14 @@ else:
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.start(threading.Event())
|
||||||
|
self.flag.wait()
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
self.stop()
|
||||||
|
self.join()
|
||||||
|
|
||||||
def start(self, flag=None):
|
def start(self, flag=None):
|
||||||
self.flag = flag
|
self.flag = flag
|
||||||
threading.Thread.start(self)
|
threading.Thread.start(self)
|
||||||
|
@ -1095,6 +1105,20 @@ else:
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "<%s %s>" % (self.__class__.__name__, self.server)
|
return "<%s %s>" % (self.__class__.__name__, self.server)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.start(threading.Event())
|
||||||
|
self.flag.wait()
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
if support.verbose:
|
||||||
|
sys.stdout.write(" cleanup: stopping server.\n")
|
||||||
|
self.stop()
|
||||||
|
if support.verbose:
|
||||||
|
sys.stdout.write(" cleanup: joining server thread.\n")
|
||||||
|
self.join()
|
||||||
|
if support.verbose:
|
||||||
|
sys.stdout.write(" cleanup: successfully joined.\n")
|
||||||
|
|
||||||
def start (self, flag=None):
|
def start (self, flag=None):
|
||||||
self.flag = flag
|
self.flag = flag
|
||||||
threading.Thread.start(self)
|
threading.Thread.start(self)
|
||||||
|
@ -1122,12 +1146,7 @@ else:
|
||||||
certreqs=ssl.CERT_REQUIRED,
|
certreqs=ssl.CERT_REQUIRED,
|
||||||
cacerts=CERTFILE, chatty=False,
|
cacerts=CERTFILE, chatty=False,
|
||||||
connectionchatty=False)
|
connectionchatty=False)
|
||||||
flag = threading.Event()
|
with server:
|
||||||
server.start(flag)
|
|
||||||
# wait for it to start
|
|
||||||
flag.wait()
|
|
||||||
# try to connect
|
|
||||||
try:
|
|
||||||
try:
|
try:
|
||||||
with socket.socket() as sock:
|
with socket.socket() as sock:
|
||||||
s = ssl.wrap_socket(sock,
|
s = ssl.wrap_socket(sock,
|
||||||
|
@ -1147,9 +1166,6 @@ else:
|
||||||
sys.stdout.write("\IOError is %s\n" % str(x))
|
sys.stdout.write("\IOError is %s\n" % str(x))
|
||||||
else:
|
else:
|
||||||
raise AssertionError("Use of invalid cert should have failed!")
|
raise AssertionError("Use of invalid cert should have failed!")
|
||||||
finally:
|
|
||||||
server.stop()
|
|
||||||
server.join()
|
|
||||||
|
|
||||||
def server_params_test(client_context, server_context, indata=b"FOO\n",
|
def server_params_test(client_context, server_context, indata=b"FOO\n",
|
||||||
chatty=True, connectionchatty=False):
|
chatty=True, connectionchatty=False):
|
||||||
|
@ -1160,12 +1176,7 @@ else:
|
||||||
server = ThreadedEchoServer(context=server_context,
|
server = ThreadedEchoServer(context=server_context,
|
||||||
chatty=chatty,
|
chatty=chatty,
|
||||||
connectionchatty=False)
|
connectionchatty=False)
|
||||||
flag = threading.Event()
|
with server:
|
||||||
server.start(flag)
|
|
||||||
# wait for it to start
|
|
||||||
flag.wait()
|
|
||||||
# try to connect
|
|
||||||
try:
|
|
||||||
s = client_context.wrap_socket(socket.socket())
|
s = client_context.wrap_socket(socket.socket())
|
||||||
s.connect((HOST, server.port))
|
s.connect((HOST, server.port))
|
||||||
for arg in [indata, bytearray(indata), memoryview(indata)]:
|
for arg in [indata, bytearray(indata), memoryview(indata)]:
|
||||||
|
@ -1193,9 +1204,6 @@ else:
|
||||||
}
|
}
|
||||||
s.close()
|
s.close()
|
||||||
return stats
|
return stats
|
||||||
finally:
|
|
||||||
server.stop()
|
|
||||||
server.join()
|
|
||||||
|
|
||||||
def try_protocol_combo(server_protocol, client_protocol, expect_success,
|
def try_protocol_combo(server_protocol, client_protocol, expect_success,
|
||||||
certsreqs=None, server_options=0, client_options=0):
|
certsreqs=None, server_options=0, client_options=0):
|
||||||
|
@ -1264,12 +1272,7 @@ else:
|
||||||
context.load_verify_locations(CERTFILE)
|
context.load_verify_locations(CERTFILE)
|
||||||
context.load_cert_chain(CERTFILE)
|
context.load_cert_chain(CERTFILE)
|
||||||
server = ThreadedEchoServer(context=context, chatty=False)
|
server = ThreadedEchoServer(context=context, chatty=False)
|
||||||
flag = threading.Event()
|
with server:
|
||||||
server.start(flag)
|
|
||||||
# wait for it to start
|
|
||||||
flag.wait()
|
|
||||||
# try to connect
|
|
||||||
try:
|
|
||||||
s = context.wrap_socket(socket.socket())
|
s = context.wrap_socket(socket.socket())
|
||||||
s.connect((HOST, server.port))
|
s.connect((HOST, server.port))
|
||||||
cert = s.getpeercert()
|
cert = s.getpeercert()
|
||||||
|
@ -1292,9 +1295,6 @@ else:
|
||||||
after = ssl.cert_time_to_seconds(cert['notAfter'])
|
after = ssl.cert_time_to_seconds(cert['notAfter'])
|
||||||
self.assertLess(before, after)
|
self.assertLess(before, after)
|
||||||
s.close()
|
s.close()
|
||||||
finally:
|
|
||||||
server.stop()
|
|
||||||
server.join()
|
|
||||||
|
|
||||||
def test_empty_cert(self):
|
def test_empty_cert(self):
|
||||||
"""Connecting with an empty cert file"""
|
"""Connecting with an empty cert file"""
|
||||||
|
@ -1454,13 +1454,8 @@ else:
|
||||||
starttls_server=True,
|
starttls_server=True,
|
||||||
chatty=True,
|
chatty=True,
|
||||||
connectionchatty=True)
|
connectionchatty=True)
|
||||||
flag = threading.Event()
|
|
||||||
server.start(flag)
|
|
||||||
# wait for it to start
|
|
||||||
flag.wait()
|
|
||||||
# try to connect
|
|
||||||
wrapped = False
|
wrapped = False
|
||||||
try:
|
with server:
|
||||||
s = socket.socket()
|
s = socket.socket()
|
||||||
s.setblocking(1)
|
s.setblocking(1)
|
||||||
s.connect((HOST, server.port))
|
s.connect((HOST, server.port))
|
||||||
|
@ -1507,9 +1502,6 @@ else:
|
||||||
conn.close()
|
conn.close()
|
||||||
else:
|
else:
|
||||||
s.close()
|
s.close()
|
||||||
finally:
|
|
||||||
server.stop()
|
|
||||||
server.join()
|
|
||||||
|
|
||||||
def test_socketserver(self):
|
def test_socketserver(self):
|
||||||
"""Using a SocketServer to create and manage SSL connections."""
|
"""Using a SocketServer to create and manage SSL connections."""
|
||||||
|
@ -1545,12 +1537,7 @@ else:
|
||||||
|
|
||||||
indata = b"FOO\n"
|
indata = b"FOO\n"
|
||||||
server = AsyncoreEchoServer(CERTFILE)
|
server = AsyncoreEchoServer(CERTFILE)
|
||||||
flag = threading.Event()
|
with server:
|
||||||
server.start(flag)
|
|
||||||
# wait for it to start
|
|
||||||
flag.wait()
|
|
||||||
# try to connect
|
|
||||||
try:
|
|
||||||
s = ssl.wrap_socket(socket.socket())
|
s = ssl.wrap_socket(socket.socket())
|
||||||
s.connect(('127.0.0.1', server.port))
|
s.connect(('127.0.0.1', server.port))
|
||||||
if support.verbose:
|
if support.verbose:
|
||||||
|
@ -1571,15 +1558,6 @@ else:
|
||||||
s.close()
|
s.close()
|
||||||
if support.verbose:
|
if support.verbose:
|
||||||
sys.stdout.write(" client: connection closed.\n")
|
sys.stdout.write(" client: connection closed.\n")
|
||||||
finally:
|
|
||||||
if support.verbose:
|
|
||||||
sys.stdout.write(" cleanup: stopping server.\n")
|
|
||||||
server.stop()
|
|
||||||
if support.verbose:
|
|
||||||
sys.stdout.write(" cleanup: joining server thread.\n")
|
|
||||||
server.join()
|
|
||||||
if support.verbose:
|
|
||||||
sys.stdout.write(" cleanup: successfully joined.\n")
|
|
||||||
|
|
||||||
def test_recv_send(self):
|
def test_recv_send(self):
|
||||||
"""Test recv(), send() and friends."""
|
"""Test recv(), send() and friends."""
|
||||||
|
@ -1592,19 +1570,14 @@ else:
|
||||||
cacerts=CERTFILE,
|
cacerts=CERTFILE,
|
||||||
chatty=True,
|
chatty=True,
|
||||||
connectionchatty=False)
|
connectionchatty=False)
|
||||||
flag = threading.Event()
|
with server:
|
||||||
server.start(flag)
|
s = ssl.wrap_socket(socket.socket(),
|
||||||
# wait for it to start
|
server_side=False,
|
||||||
flag.wait()
|
certfile=CERTFILE,
|
||||||
# try to connect
|
ca_certs=CERTFILE,
|
||||||
s = ssl.wrap_socket(socket.socket(),
|
cert_reqs=ssl.CERT_NONE,
|
||||||
server_side=False,
|
ssl_version=ssl.PROTOCOL_TLSv1)
|
||||||
certfile=CERTFILE,
|
s.connect((HOST, server.port))
|
||||||
ca_certs=CERTFILE,
|
|
||||||
cert_reqs=ssl.CERT_NONE,
|
|
||||||
ssl_version=ssl.PROTOCOL_TLSv1)
|
|
||||||
s.connect((HOST, server.port))
|
|
||||||
try:
|
|
||||||
# helper methods for standardising recv* method signatures
|
# helper methods for standardising recv* method signatures
|
||||||
def _recv_into():
|
def _recv_into():
|
||||||
b = bytearray(b"\0"*100)
|
b = bytearray(b"\0"*100)
|
||||||
|
@ -1700,9 +1673,6 @@ else:
|
||||||
|
|
||||||
s.write(b"over\n")
|
s.write(b"over\n")
|
||||||
s.close()
|
s.close()
|
||||||
finally:
|
|
||||||
server.stop()
|
|
||||||
server.join()
|
|
||||||
|
|
||||||
def test_handshake_timeout(self):
|
def test_handshake_timeout(self):
|
||||||
# Issue #5103: SSL handshake must respect the socket timeout
|
# Issue #5103: SSL handshake must respect the socket timeout
|
||||||
|
@ -1766,19 +1736,14 @@ else:
|
||||||
cacerts=CERTFILE,
|
cacerts=CERTFILE,
|
||||||
chatty=True,
|
chatty=True,
|
||||||
connectionchatty=False)
|
connectionchatty=False)
|
||||||
flag = threading.Event()
|
with server:
|
||||||
server.start(flag)
|
s = ssl.wrap_socket(socket.socket(),
|
||||||
# wait for it to start
|
server_side=False,
|
||||||
flag.wait()
|
certfile=CERTFILE,
|
||||||
# try to connect
|
ca_certs=CERTFILE,
|
||||||
s = ssl.wrap_socket(socket.socket(),
|
cert_reqs=ssl.CERT_NONE,
|
||||||
server_side=False,
|
ssl_version=ssl.PROTOCOL_TLSv1)
|
||||||
certfile=CERTFILE,
|
s.connect((HOST, server.port))
|
||||||
ca_certs=CERTFILE,
|
|
||||||
cert_reqs=ssl.CERT_NONE,
|
|
||||||
ssl_version=ssl.PROTOCOL_TLSv1)
|
|
||||||
s.connect((HOST, server.port))
|
|
||||||
try:
|
|
||||||
# get the data
|
# get the data
|
||||||
cb_data = s.get_channel_binding("tls-unique")
|
cb_data = s.get_channel_binding("tls-unique")
|
||||||
if support.verbose:
|
if support.verbose:
|
||||||
|
@ -1817,9 +1782,6 @@ else:
|
||||||
self.assertEqual(peer_data_repr,
|
self.assertEqual(peer_data_repr,
|
||||||
repr(new_cb_data).encode("us-ascii"))
|
repr(new_cb_data).encode("us-ascii"))
|
||||||
s.close()
|
s.close()
|
||||||
finally:
|
|
||||||
server.stop()
|
|
||||||
server.join()
|
|
||||||
|
|
||||||
def test_compression(self):
|
def test_compression(self):
|
||||||
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
|
||||||
|
|
|
@ -299,6 +299,18 @@ class Galeon(UnixBrowser):
|
||||||
background = True
|
background = True
|
||||||
|
|
||||||
|
|
||||||
|
class Chrome(UnixBrowser):
|
||||||
|
"Launcher class for Google Chrome browser."
|
||||||
|
|
||||||
|
remote_args = ['%action', '%s']
|
||||||
|
remote_action = ""
|
||||||
|
remote_action_newwin = "--new-window"
|
||||||
|
remote_action_newtab = ""
|
||||||
|
background = True
|
||||||
|
|
||||||
|
Chromium = Chrome
|
||||||
|
|
||||||
|
|
||||||
class Opera(UnixBrowser):
|
class Opera(UnixBrowser):
|
||||||
"Launcher class for Opera browser."
|
"Launcher class for Opera browser."
|
||||||
|
|
||||||
|
@ -466,6 +478,11 @@ def register_X_browsers():
|
||||||
if _iscommand("skipstone"):
|
if _iscommand("skipstone"):
|
||||||
register("skipstone", None, BackgroundBrowser("skipstone"))
|
register("skipstone", None, BackgroundBrowser("skipstone"))
|
||||||
|
|
||||||
|
# Google Chrome/Chromium browsers
|
||||||
|
for browser in ("google-chrome", "chrome", "chromium", "chromium-browser"):
|
||||||
|
if _iscommand(browser):
|
||||||
|
register(browser, None, Chrome(browser))
|
||||||
|
|
||||||
# Opera, quite popular
|
# Opera, quite popular
|
||||||
if _iscommand("opera"):
|
if _iscommand("opera"):
|
||||||
register("opera", None, Opera("opera"))
|
register("opera", None, Opera("opera"))
|
||||||
|
|
|
@ -878,6 +878,7 @@ Michael Scharf
|
||||||
Andreas Schawo
|
Andreas Schawo
|
||||||
Neil Schemenauer
|
Neil Schemenauer
|
||||||
David Scherer
|
David Scherer
|
||||||
|
Hynek Schlawack
|
||||||
Bob Schmertz
|
Bob Schmertz
|
||||||
Gregor Schmid
|
Gregor Schmid
|
||||||
Ralf Schmitt
|
Ralf Schmitt
|
||||||
|
|
|
@ -419,6 +419,14 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #13620: Support for Chrome browser in webbrowser.py Patch contributed
|
||||||
|
by Arnaud Calmettes.
|
||||||
|
|
||||||
|
- Issue #12708: Add starmap() and starmap_async() methods (similar to
|
||||||
|
itertools.starmap()) to multiprocessing.Pool. Patch by Hynek Schlawack.
|
||||||
|
|
||||||
|
- Issue #1785: Fix inspect and pydoc with misbehaving descriptors.
|
||||||
|
|
||||||
- Issue #13637: "a2b" functions in the binascii module now accept ASCII-only
|
- Issue #13637: "a2b" functions in the binascii module now accept ASCII-only
|
||||||
unicode strings.
|
unicode strings.
|
||||||
|
|
||||||
|
|
|
@ -2006,6 +2006,7 @@ set_default_verify_paths(PySSLContext *self, PyObject *unused)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_ECDH
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_ecdh_curve(PySSLContext *self, PyObject *name)
|
set_ecdh_curve(PySSLContext *self, PyObject *name)
|
||||||
{
|
{
|
||||||
|
@ -2032,6 +2033,7 @@ set_ecdh_curve(PySSLContext *self, PyObject *name)
|
||||||
EC_KEY_free(key);
|
EC_KEY_free(key);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static PyGetSetDef context_getsetlist[] = {
|
static PyGetSetDef context_getsetlist[] = {
|
||||||
{"options", (getter) get_options,
|
{"options", (getter) get_options,
|
||||||
|
@ -2054,8 +2056,10 @@ static struct PyMethodDef context_methods[] = {
|
||||||
METH_NOARGS, NULL},
|
METH_NOARGS, NULL},
|
||||||
{"set_default_verify_paths", (PyCFunction) set_default_verify_paths,
|
{"set_default_verify_paths", (PyCFunction) set_default_verify_paths,
|
||||||
METH_NOARGS, NULL},
|
METH_NOARGS, NULL},
|
||||||
|
#ifndef OPENSSL_NO_ECDH
|
||||||
{"set_ecdh_curve", (PyCFunction) set_ecdh_curve,
|
{"set_ecdh_curve", (PyCFunction) set_ecdh_curve,
|
||||||
METH_O, NULL},
|
METH_O, NULL},
|
||||||
|
#endif
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2523,6 +2527,14 @@ PyInit__ssl(void)
|
||||||
Py_INCREF(r);
|
Py_INCREF(r);
|
||||||
PyModule_AddObject(m, "HAS_TLS_UNIQUE", r);
|
PyModule_AddObject(m, "HAS_TLS_UNIQUE", r);
|
||||||
|
|
||||||
|
#ifdef OPENSSL_NO_ECDH
|
||||||
|
r = Py_False;
|
||||||
|
#else
|
||||||
|
r = Py_True;
|
||||||
|
#endif
|
||||||
|
Py_INCREF(r);
|
||||||
|
PyModule_AddObject(m, "HAS_ECDH", r);
|
||||||
|
|
||||||
/* OpenSSL version */
|
/* OpenSSL version */
|
||||||
/* SSLeay() gives us the version of the library linked against,
|
/* SSLeay() gives us the version of the library linked against,
|
||||||
which could be different from the headers version.
|
which could be different from the headers version.
|
||||||
|
|
Loading…
Reference in New Issue