summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/howto/descriptor.rst2
-rw-r--r--Doc/library/logging.handlers.rst8
-rw-r--r--Doc/library/smtplib.rst18
-rw-r--r--Doc/library/stdtypes.rst16
-rw-r--r--Doc/reference/expressions.rst2
-rw-r--r--Lib/smtplib.py32
-rw-r--r--Lib/test/test_smtplib.py17
-rw-r--r--Lib/test/test_smtpnet.py8
-rw-r--r--Lib/test/test_urllib2net.py24
-rw-r--r--Makefile.pre.in54
-rw-r--r--Modules/_cursesmodule.c4
-rw-r--r--setup.py6
12 files changed, 115 insertions, 76 deletions
diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index 81bb8ca..1616f67 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -42,7 +42,7 @@ classes (a class is new style if it inherits from :class:`object` or
Descriptors are a powerful, general purpose protocol. They are the mechanism
behind properties, methods, static methods, class methods, and :func:`super()`.
-They are used used throughout Python itself to implement the new style classes
+They are used throughout Python itself to implement the new style classes
introduced in version 2.2. Descriptors simplify the underlying C-code and offer
a flexible set of new tools for everyday Python programs.
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index 82e3969..27d2efd 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -623,7 +623,7 @@ The :class:`SMTPHandler` class, located in the :mod:`logging.handlers` module,
supports sending logging messages to an email address via SMTP.
-.. class:: SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None)
+.. class:: SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None)
Returns a new instance of the :class:`SMTPHandler` class. The instance is
initialized with the from and to addresses and subject line of the email. The
@@ -632,6 +632,12 @@ supports sending logging messages to an email address via SMTP.
the standard SMTP port is used. If your SMTP server requires authentication, you
can specify a (username, password) tuple for the *credentials* argument.
+ To specify the use of a secure protocol (TLS), pass in a tuple to the
+ *secure* argument. This will only be used when authentication credentials are
+ supplied. The tuple should be either an empty tuple, or a single-value tuple
+ with the name of a keyfile, or a 2-value tuple with the names of the keyfile
+ and certificate file. (This tuple is passed to the
+ :meth:`smtplib.SMTP.starttls` method.)
.. method:: emit(record)
diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst
index 4a0f756..7dd038d 100644
--- a/Doc/library/smtplib.rst
+++ b/Doc/library/smtplib.rst
@@ -31,9 +31,9 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
like the connection attempt (if not specified, the global default timeout
setting will be used). The optional source_address parameter allows to bind to some
specific source address in a machine with multiple network interfaces,
- and/or to some specific source tcp port. It takes a 2-tuple (host, port),
+ and/or to some specific source TCP port. It takes a 2-tuple (host, port),
for the socket to bind to as its source address before connecting. If
- ommited (or if host or port are '' and/or 0 respectively) the OS default
+ omitted (or if host or port are ``''`` and/or 0 respectively) the OS default
behavior will be used.
For normal use, you should only require the initialization/connect,
@@ -53,8 +53,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
.. versionchanged:: 3.3
Support for the :keyword:`with` statement was added.
- .. versionadded:: 3.3
- source_address parameter.
+ .. versionchanged:: 3.3
+ source_address argument was added.
.. class:: SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None[, timeout], context=None, source_address=None)
@@ -73,14 +73,14 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
specific source address in a machine with multiple network interfaces,
and/or to some specific source tcp port. It takes a 2-tuple (host, port),
for the socket to bind to as its source address before connecting. If
- ommited (or if host or port are '' and/or 0 respectively) the OS default
+ omitted (or if host or port are ``''`` and/or 0 respectively) the OS default
behavior will be used.
.. versionchanged:: 3.3
*context* was added.
- .. versionadded:: 3.3
- source_address parameter.
+ .. versionchanged:: 3.3
+ source_address argument was added.
.. class:: LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None)
@@ -88,8 +88,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
The LMTP protocol, which is very similar to ESMTP, is heavily based on the
standard SMTP client. It's common to use Unix sockets for LMTP, so our
:meth:`connect` method must support that as well as a regular host:port
- server. The optional parameters local_hostname and source_address has the
- same meaning as that of SMTP client.To specify a Unix socket, you must use
+ server. The optional arguments local_hostname and source_address have the
+ same meaning as that of SMTP client. To specify a Unix socket, you must use
an absolute path for *host*, starting with a '/'.
Authentication is supported, using the regular SMTP mechanism. When using a Unix
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 5660224..8a117ba 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -2706,7 +2706,7 @@ The Null Object
This object is returned by functions that don't explicitly return a value. It
supports no special operations. There is exactly one null object, named
-``None`` (a built-in name).
+``None`` (a built-in name). ``type(None)()`` produces the same singleton.
It is written as ``None``.
@@ -2718,11 +2718,23 @@ The Ellipsis Object
This object is commonly used by slicing (see :ref:`slicings`). It supports no
special operations. There is exactly one ellipsis object, named
-:const:`Ellipsis` (a built-in name).
+:const:`Ellipsis` (a built-in name). ``type(Ellipsis)()`` produces the
+:const:`Ellipsis` singleton.
It is written as ``Ellipsis`` or ``...``.
+The NotImplemented Object
+-------------------------
+
+This object is returned from comparisons and binary operations when they are
+asked to operate on types they don't support. See :ref:`comparisons` for more
+information. There is exactly one ``NotImplemented`` object.
+``type(NotImplemented)()`` produces the singleton instance.
+
+It is written as ``NotImplemented``.
+
+
Boolean Values
--------------
diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst
index d85a9c6..655ebde 100644
--- a/Doc/reference/expressions.rst
+++ b/Doc/reference/expressions.rst
@@ -673,7 +673,7 @@ there were no excess keyword arguments.
If the syntax ``*expression`` appears in the function call, ``expression`` must
evaluate to an iterable. Elements from this iterable are treated as if they
were additional positional arguments; if there are positional arguments
-*x1*, ... ,*xN*, and ``expression`` evaluates to a sequence *y1*, ..., *yM*,
+*x1*, ..., *xN*, and ``expression`` evaluates to a sequence *y1*, ..., *yM*,
this is equivalent to a call with M+N positional arguments *x1*, ..., *xN*,
*y1*, ..., *yM*.
diff --git a/Lib/smtplib.py b/Lib/smtplib.py
index 2039592..a4c0d89 100644
--- a/Lib/smtplib.py
+++ b/Lib/smtplib.py
@@ -282,7 +282,8 @@ class SMTP:
# This makes it simpler for SMTP_SSL to use the SMTP connect code
# and just alter the socket connection bit.
if self.debuglevel > 0:
- print('connect: to', (host, port), self.source_address, file=stderr)
+ print('connect: to', (host, port), self.source_address,
+ file=stderr)
return socket.create_connection((host, port), timeout,
self.source_address)
@@ -297,7 +298,10 @@ class SMTP:
specified during instantiation.
"""
- if source_address: self.source_address = source_address
+
+ if source_address:
+ self.source_address = source_address
+
if not port and (host.find(':') == host.rfind(':')):
i = host.rfind(':')
if i >= 0:
@@ -381,7 +385,8 @@ class SMTP:
errmsg = b"\n".join(resp)
if self.debuglevel > 0:
- print('reply: retcode (%s); Msg: %s' % (errcode, errmsg), file=stderr)
+ print('reply: retcode (%s); Msg: %s' % (errcode, errmsg),
+ file=stderr)
return errcode, errmsg
def docmd(self, cmd, args=""):
@@ -788,7 +793,8 @@ class SMTP:
# TODO implement heuristics to guess the correct Resent-* block with an
# option allowing the user to enable the heuristics. (It should be
# possible to guess correctly almost all of the time.)
- resent =msg.get_all('Resent-Date')
+
+ resent = msg.get_all('Resent-Date')
if resent is None:
header_prefix = ''
elif len(resent) == 1:
@@ -797,13 +803,13 @@ class SMTP:
raise ValueError("message has more than one 'Resent-' header block")
if from_addr is None:
# Prefer the sender field per RFC 2822:3.6.2.
- from_addr = (msg[header_prefix+'Sender']
- if (header_prefix+'Sender') in msg
- else msg[header_prefix+'From'])
+ from_addr = (msg[header_prefix + 'Sender']
+ if (header_prefix + 'Sender') in msg
+ else msg[header_prefix + 'From'])
if to_addrs is None:
- addr_fields = [f for f in (msg[header_prefix+'To'],
- msg[header_prefix+'Bcc'],
- msg[header_prefix+'Cc']) if f is not None]
+ addr_fields = [f for f in (msg[header_prefix + 'To'],
+ msg[header_prefix + 'Bcc'],
+ msg[header_prefix + 'Cc']) if f is not None]
to_addrs = [a[1] for a in email.utils.getaddresses(addr_fields)]
# Make a local copy so we can delete the bcc headers.
msg_copy = copy.copy(msg)
@@ -899,13 +905,13 @@ class LMTP(SMTP):
def __init__(self, host='', port=LMTP_PORT, local_hostname=None,
source_address=None):
"""Initialize a new instance."""
- SMTP.__init__(self, host, port, local_hostname = local_hostname,
- source_address = source_address)
+ SMTP.__init__(self, host, port, local_hostname=local_hostname,
+ source_address=source_address)
def connect(self, host='localhost', port=0, source_address=None):
"""Connect to the LMTP daemon, on either a Unix or a TCP socket."""
if host[0] != '/':
- return SMTP.connect(self, host, port, source_address = source_address)
+ return SMTP.connect(self, host, port, source_address=source_address)
# Handle Unix-domain sockets.
try:
diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py
index 70654c5..969ff15 100644
--- a/Lib/test/test_smtplib.py
+++ b/Lib/test/test_smtplib.py
@@ -216,12 +216,17 @@ class DebuggingServerTests(unittest.TestCase):
def testSourceAddress(self):
# connect
- smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3,
- source_address=('127.0.0.1', 19876))
- self.assertEqual(smtp.source_address, ('127.0.0.1', 19876))
- self.assertEqual(smtp.local_hostname, 'localhost')
- print(dir(smtp))
- smtp.quit()
+ port = support.find_unused_port()
+ try:
+ smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost',
+ timeout=3, source_address=('127.0.0.1', port))
+ self.assertEqual(smtp.source_address, ('127.0.0.1', port))
+ self.assertEqual(smtp.local_hostname, 'localhost')
+ smtp.quit()
+ except IOError as e:
+ if e.errno == errno.EADDRINUSE:
+ self.skipTest("couldn't bind to port %d" % port)
+ raise
def testNOOP(self):
smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
diff --git a/Lib/test/test_smtpnet.py b/Lib/test/test_smtpnet.py
index 7d0fa98..86224ef 100644
--- a/Lib/test/test_smtpnet.py
+++ b/Lib/test/test_smtpnet.py
@@ -18,7 +18,13 @@ class SmtpTest(unittest.TestCase):
support.get_attribute(smtplib, 'SMTP_SSL')
with support.transient_internet(self.testServer):
server = smtplib.SMTP(self.testServer, self.remotePort)
- server.starttls(context=self.context)
+ try:
+ server.starttls(context=self.context)
+ except smtplib.SMTPException as e:
+ if e.args[0] == 'STARTTLS extension not supported by server.':
+ unittest.skip(e.args[0])
+ else:
+ raise
server.ehlo()
server.quit()
diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py
index cd225c9..54f4e0c 100644
--- a/Lib/test/test_urllib2net.py
+++ b/Lib/test/test_urllib2net.py
@@ -178,17 +178,21 @@ class OtherNetworkTests(unittest.TestCase):
# Some sites do not send Connection: close header.
# Verify that those work properly. (#issue12576)
- try:
- with urllib.request.urlopen('http://www.imdb.com') as res:
- pass
- except ValueError as e:
- self.fail("urlopen failed for sites not sending Connection:close")
- else:
- self.assertTrue(res)
+ URL = 'http://www.imdb.com' # mangles Connection:close
+
+ with support.transient_internet(URL):
+ try:
+ with urllib.request.urlopen(URL) as res:
+ pass
+ except ValueError as e:
+ self.fail("urlopen failed for site not sending \
+ Connection:close")
+ else:
+ self.assertTrue(res)
- req = urllib.request.urlopen('http://www.imdb.com')
- res = req.read()
- self.assertTrue(res)
+ req = urllib.request.urlopen(URL)
+ res = req.read()
+ self.assertTrue(res)
def _test_urls(self, urls, handlers, retry=True):
import time
diff --git a/Makefile.pre.in b/Makefile.pre.in
index c2b1a11..0c7b180 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -747,45 +747,41 @@ $(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS)
######################################################################
-# Test the interpreter (twice, once without .pyc files, once with)
-# In the past, we've had problems where bugs in the marshalling or
-# elsewhere caused bytecode read from .pyc files to behave differently
-# than bytecode generated directly from a .py source file. Sometimes
-# the bytecode read from a .pyc file had the bug, somtimes the directly
-# generated bytecode. This is sometimes a very shy bug needing a lot of
-# sample data.
-
-TESTOPTS= -l $(EXTRATESTOPTS)
+# Run a basic set of regression tests.
+# This excludes some tests that are particularly resource-intensive.
+TESTOPTS= $(EXTRATESTOPTS)
TESTPROG= $(srcdir)/Lib/test/regrtest.py
TESTPYTHON= $(RUNSHARED) ./$(BUILDPYTHON) -Wd -E -bb $(TESTPYTHONOPTS)
TESTTIMEOUT= 3600
test: all platform
- -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
- -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
- $(TESTPYTHON) $(TESTPROG) $(TESTOPTS)
+ $(TESTPYTHON) $(TESTPROG) -j0 $(TESTOPTS)
+# Run the full test suite twice - once without .pyc files, and once with.
+# In the past, we've had problems where bugs in the marshalling or
+# elsewhere caused bytecode read from .pyc files to behave differently
+# than bytecode generated directly from a .py source file. Sometimes
+# the bytecode read from a .pyc file had the bug, sometimes the directly
+# generated bytecode. This is sometimes a very shy bug needing a lot of
+# sample data.
testall: all platform
-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
$(TESTPYTHON) $(srcdir)/Lib/compileall.py
-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
- -$(TESTPYTHON) $(TESTPROG) -uall $(TESTOPTS)
- $(TESTPYTHON) $(TESTPROG) -uall $(TESTOPTS)
+ -$(TESTPYTHON) $(TESTPROG) -j0 -uall $(TESTOPTS)
+ $(TESTPYTHON) $(TESTPROG) -j0 -uall $(TESTOPTS)
-# Run the unitests for both architectures in a Universal build on OSX
-# Must be run on an Intel box.
+# Run the test suite for both architectures in a Universal build on OSX.
+# Must be run on an Intel box.
testuniversal: all platform
if [ `arch` != 'i386' ];then \
echo "This can only be used on OSX/i386" ;\
exit 1 ;\
fi
- -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
- -$(TESTPYTHON) $(TESTPROG) -uall $(TESTOPTS)
- $(TESTPYTHON) $(TESTPROG) -uall $(TESTOPTS)
- $(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E $(TESTPROG) -uall $(TESTOPTS)
-
+ $(TESTPYTHON) $(TESTPROG) -j0 -uall $(TESTOPTS)
+ $(RUNSHARED) /usr/libexec/oah/translate ./$(BUILDPYTHON) -E $(TESTPROG) -j0 -uall $(TESTOPTS)
-# Like testall, but with a single pass only
-# run an optional script to include some information about the build environment
+# Like testall, but with only one pass.
+# Run an optional script to include information about the build environment.
buildbottest: all platform
-@if which pybuildbot.identify >/dev/null 2>&1; then \
pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \
@@ -798,15 +794,9 @@ QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io test_lib2to3 \
test_select test_zipfile
quicktest: all platform
-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
- -$(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
- $(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
+ -$(TESTPYTHON) $(TESTPROG) -j0 $(QUICKTESTOPTS)
+ $(TESTPYTHON) $(TESTPROG) -j0 $(QUICKTESTOPTS)
-MEMTESTOPTS= $(QUICKTESTOPTS) -x test_dl test___all__ test_fork1 \
- test_longexp
-memtest: all platform
- -rm -f $(srcdir)/Lib/test/*.py[co]
- -$(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
- $(TESTPYTHON) $(TESTPROG) $(MEMTESTOPTS)
install: altinstall bininstall
@@ -1381,7 +1371,7 @@ patchcheck:
Python/thread.o: @THREADHEADERS@
# Declare targets that aren't real files
-.PHONY: all build_all sharedmods oldsharedmods test quicktest memtest
+.PHONY: all build_all sharedmods oldsharedmods test quicktest
.PHONY: install altinstall oldsharedinstall bininstall altbininstall
.PHONY: maninstall libinstall inclinstall libainstall sharedinstall
.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index 9e57cd9..6d72024 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -906,6 +906,7 @@ PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args)
}
}
+#ifdef HAVE_NCURSESW
static PyObject *
PyCursesWindow_Get_WCh(PyCursesWindowObject *self, PyObject *args)
{
@@ -937,6 +938,7 @@ PyCursesWindow_Get_WCh(PyCursesWindowObject *self, PyObject *args)
}
return PyLong_FromLong(rtn);
}
+#endif
static PyObject *
PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args)
@@ -1636,7 +1638,9 @@ static PyMethodDef PyCursesWindow_Methods[] = {
{"getbkgd", (PyCFunction)PyCursesWindow_GetBkgd, METH_NOARGS},
{"getch", (PyCFunction)PyCursesWindow_GetCh, METH_VARARGS},
{"getkey", (PyCFunction)PyCursesWindow_GetKey, METH_VARARGS},
+#ifdef HAVE_NCURSESW
{"get_wch", (PyCFunction)PyCursesWindow_Get_WCh, METH_VARARGS},
+#endif
{"getmaxyx", (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS},
{"getparyx", (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS},
{"getstr", (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS},
diff --git a/setup.py b/setup.py
index 2426aad..968670c 100644
--- a/setup.py
+++ b/setup.py
@@ -1161,6 +1161,10 @@ class PyBuildExt(build_ext):
else:
missing.extend(['nis', 'resource', 'termios'])
+ curses_defines = []
+ if curses_library == 'ncursesw':
+ curses_defines.append(('HAVE_NCURSESW', '1'))
+
# Curses support, requiring the System V version of curses, often
# provided by the ncurses library.
panel_library = 'panel'
@@ -1171,6 +1175,7 @@ class PyBuildExt(build_ext):
panel_library = 'panelw'
curses_libs = [curses_library]
exts.append( Extension('_curses', ['_cursesmodule.c'],
+ define_macros=curses_defines,
libraries = curses_libs) )
elif curses_library == 'curses' and platform != 'darwin':
# OSX has an old Berkeley curses, not good enough for
@@ -1183,6 +1188,7 @@ class PyBuildExt(build_ext):
curses_libs = ['curses']
exts.append( Extension('_curses', ['_cursesmodule.c'],
+ define_macros=curses_defines,
libraries = curses_libs) )
else:
missing.append('_curses')