summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Heimes <christian@cheimes.de>2008-01-07 17:19:16 +0000
committerChristian Heimes <christian@cheimes.de>2008-01-07 17:19:16 +0000
commit043d6f67c7b79a6d268c6ad31d8ff7710ac3e5ee (patch)
tree0ea113cd3a06b4ecbb27a82154174e1846ce1804
parent13a7a21258f0cd241c2cf1367a954d6742daa2a6 (diff)
downloadcpython-git-043d6f67c7b79a6d268c6ad31d8ff7710ac3e5ee.tar.gz
Copied doc for reload() from trunk's function.rst to imp.rst
-rw-r--r--Doc/library/collections.rst37
-rw-r--r--Doc/library/getopt.rst2
-rw-r--r--Doc/library/imp.rst62
-rw-r--r--Doc/library/logging.rst23
-rw-r--r--Doc/library/socket.rst27
-rw-r--r--Doc/library/stdtypes.rst12
-rw-r--r--Doc/tutorial/controlflow.rst53
-rw-r--r--Doc/tutorial/introduction.rst2
-rw-r--r--Lib/abc.py2
-rw-r--r--Lib/collections.py22
-rw-r--r--Lib/test/test_abc.py14
-rw-r--r--Lib/test/test_socket.py82
-rw-r--r--Misc/NEWS1
-rw-r--r--Misc/developers.txt3
-rw-r--r--Modules/socketmodule.c154
-rw-r--r--Modules/socketmodule.h4
-rw-r--r--Python/future.c2
-rwxr-xr-xconfigure5
-rw-r--r--configure.in2
-rw-r--r--pyconfig.h.in4
20 files changed, 465 insertions, 48 deletions
diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst
index 5b625ee3ae..cb3a029301 100644
--- a/Doc/library/collections.rst
+++ b/Doc/library/collections.rst
@@ -489,7 +489,7 @@ three additional methods and one attribute.
>>> Point._make(t)
Point(x=11, y=22)
-.. method:: somenamedtuple._asdict()
+.. method:: namedtuple._asdict()
Return a new dict which maps field names to their corresponding values:
@@ -498,7 +498,7 @@ three additional methods and one attribute.
>>> p._asdict()
{'x': 11, 'y': 22}
-.. method:: somenamedtuple._replace(kwargs)
+.. method:: namedtuple._replace(kwargs)
Return a new instance of the named tuple replacing specified fields with new values:
@@ -511,7 +511,7 @@ three additional methods and one attribute.
>>> for partnum, record in inventory.items():
... inventory[partnum] = record._replace(price=newprices[partnum], updated=time.now())
-.. attribute:: somenamedtuple._fields
+.. attribute:: namedtuple._fields
Tuple of strings listing the field names. This is useful for introspection
and for creating new named tuple types from existing named tuples.
@@ -541,15 +541,28 @@ When casting a dictionary to a named tuple, use the double-star-operator [#]_::
Point(x=11, y=22)
Since a named tuple is a regular Python class, it is easy to add or change
-functionality. For example, the display format can be changed by overriding
-the :meth:`__repr__` method:
-
-::
-
- >>> Point = namedtuple('Point', 'x y')
- >>> Point.__repr__ = lambda self: 'Point(%.3f, %.3f)' % self
- >>> Point(x=11, y=22)
- Point(11.000, 22.000)
+functionality with a subclass. Here is how to add a calculated field and
+a fixed-width print format::
+
+ >>> class Point(namedtuple('Point', 'x y')):
+ @property
+ def hypot(self):
+ return (self.x ** 2 + self.y ** 2) ** 0.5
+ def __repr__(self):
+ return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot)
+
+ >>> print Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6)
+ Point(x=3.000, y=4.000, hypot=5.000)
+ Point(x=2.000, y=5.000, hypot=5.385)
+ Point(x=1.286, y=6.000, hypot=6.136)
+
+Another use for subclassing is to replace performance critcal methods with
+faster versions that bypass error-checking and localize variable access::
+
+ >>> class Point(namedtuple('Point', 'x y')):
+ _make = classmethod(tuple.__new__)
+ def _replace(self, _map=map, **kwds):
+ return self._make(_map(kwds.pop, ('x', 'y'), self))
Default values can be implemented by starting with a prototype instance
and customizing it with :meth:`_replace`:
diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst
index 35d91d28db..8b8e326a28 100644
--- a/Doc/library/getopt.rst
+++ b/Doc/library/getopt.rst
@@ -11,7 +11,7 @@ This module helps scripts to parse the command line arguments in ``sys.argv``.
It supports the same conventions as the Unix :cfunc:`getopt` function (including
the special meanings of arguments of the form '``-``' and '``--``'). Long
options similar to those supported by GNU software may be used as well via an
-optional third argument. This module provides a single function and an
+optional third argument. This module provides two functions and an
exception:
diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst
index 7b8133beca..831d1a7d24 100644
--- a/Doc/library/imp.rst
+++ b/Doc/library/imp.rst
@@ -123,6 +123,68 @@ This module provides an interface to the mechanisms used to implement the
function does nothing.
+.. function:: reload(module)
+
+ Reload a previously imported *module*. The argument must be a module object, so
+ it must have been successfully imported before. This is useful if you have
+ edited the module source file using an external editor and want to try out the
+ new version without leaving the Python interpreter. The return value is the
+ module object (the same as the *module* argument).
+
+ When ``reload(module)`` is executed:
+
+ * Python modules' code is recompiled and the module-level code reexecuted,
+ defining a new set of objects which are bound to names in the module's
+ dictionary. The ``init`` function of extension modules is not called a second
+ time.
+
+ * As with all other objects in Python the old objects are only reclaimed after
+ their reference counts drop to zero.
+
+ * The names in the module namespace are updated to point to any new or changed
+ objects.
+
+ * Other references to the old objects (such as names external to the module) are
+ not rebound to refer to the new objects and must be updated in each namespace
+ where they occur if that is desired.
+
+ There are a number of other caveats:
+
+ If a module is syntactically correct but its initialization fails, the first
+ :keyword:`import` statement for it does not bind its name locally, but does
+ store a (partially initialized) module object in ``sys.modules``. To reload the
+ module you must first :keyword:`import` it again (this will bind the name to the
+ partially initialized module object) before you can :func:`reload` it.
+
+ When a module is reloaded, its dictionary (containing the module's global
+ variables) is retained. Redefinitions of names will override the old
+ definitions, so this is generally not a problem. If the new version of a module
+ does not define a name that was defined by the old version, the old definition
+ remains. This feature can be used to the module's advantage if it maintains a
+ global table or cache of objects --- with a :keyword:`try` statement it can test
+ for the table's presence and skip its initialization if desired::
+
+ try:
+ cache
+ except NameError:
+ cache = {}
+
+ It is legal though generally not very useful to reload built-in or dynamically
+ loaded modules, except for :mod:`sys`, :mod:`__main__` and :mod:`__builtin__`.
+ In many cases, however, extension modules are not designed to be initialized
+ more than once, and may fail in arbitrary ways when reloaded.
+
+ If a module imports objects from another module using :keyword:`from` ...
+ :keyword:`import` ..., calling :func:`reload` for the other module does not
+ redefine the objects imported from it --- one way around this is to re-execute
+ the :keyword:`from` statement, another is to use :keyword:`import` and qualified
+ names (*module*.*name*) instead.
+
+ If a module instantiates instances of a class, reloading the module that defines
+ the class does not affect the method definitions of the instances --- they
+ continue to use the old class definition. The same is true for derived classes.
+
+
The following constants with integer values, defined in this module, are used to
indicate the search result of :func:`find_module`.
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index a95e2b5c6c..bf6ad71a16 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -688,7 +688,8 @@ functions.
Does basic configuration for the logging system by creating a
:class:`StreamHandler` with a default :class:`Formatter` and adding it to the
- root logger. The functions :func:`debug`, :func:`info`, :func:`warning`,
+ root logger. The function does nothing if any handlers have been defined for
+ the root logger. The functions :func:`debug`, :func:`info`, :func:`warning`,
:func:`error` and :func:`critical` will call :func:`basicConfig` automatically
if no handlers are defined for the root logger.
@@ -2384,24 +2385,24 @@ Here is the auxiliary module::
The output looks like this::
- 2005-03-23 23:47:11,663 - spam_application - INFO -
+ 2005-03-23 23:47:11,663 - spam_application - INFO -
creating an instance of auxiliary_module.Auxiliary
- 2005-03-23 23:47:11,665 - spam_application.auxiliary.Auxiliary - INFO -
+ 2005-03-23 23:47:11,665 - spam_application.auxiliary.Auxiliary - INFO -
creating an instance of Auxiliary
- 2005-03-23 23:47:11,665 - spam_application - INFO -
+ 2005-03-23 23:47:11,665 - spam_application - INFO -
created an instance of auxiliary_module.Auxiliary
- 2005-03-23 23:47:11,668 - spam_application - INFO -
+ 2005-03-23 23:47:11,668 - spam_application - INFO -
calling auxiliary_module.Auxiliary.do_something
- 2005-03-23 23:47:11,668 - spam_application.auxiliary.Auxiliary - INFO -
+ 2005-03-23 23:47:11,668 - spam_application.auxiliary.Auxiliary - INFO -
doing something
- 2005-03-23 23:47:11,669 - spam_application.auxiliary.Auxiliary - INFO -
+ 2005-03-23 23:47:11,669 - spam_application.auxiliary.Auxiliary - INFO -
done doing something
- 2005-03-23 23:47:11,670 - spam_application - INFO -
+ 2005-03-23 23:47:11,670 - spam_application - INFO -
finished auxiliary_module.Auxiliary.do_something
- 2005-03-23 23:47:11,671 - spam_application - INFO -
+ 2005-03-23 23:47:11,671 - spam_application - INFO -
calling auxiliary_module.some_function()
- 2005-03-23 23:47:11,672 - spam_application.auxiliary - INFO -
+ 2005-03-23 23:47:11,672 - spam_application.auxiliary - INFO -
received a call to "some_function"
- 2005-03-23 23:47:11,673 - spam_application - INFO -
+ 2005-03-23 23:47:11,673 - spam_application - INFO -
done with auxiliary_module.some_function()
diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst
index cc16150588..406c1365a5 100644
--- a/Doc/library/socket.rst
+++ b/Doc/library/socket.rst
@@ -65,6 +65,27 @@ numeric address in *host* portion.
AF_NETLINK sockets are represented as pairs ``pid, groups``.
+
+Linux-only support for TIPC is also available using the :const:`AF_TIPC`
+address family. TIPC is an open, non-IP based networked protocol designed
+for use in clustered computer environments. Addresses are represented by a
+tuple, and the fields depend on the address type. The general tuple form is
+``(addr_type, v1, v2, v3 [, scope])``, where:
+
+ - *addr_type* is one of TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, or
+ TIPC_ADDR_ID.
+ - *scope* is one of TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and
+ TIPC_NODE_SCOPE.
+ - If *addr_type* is TIPC_ADDR_NAME, then *v1* is the server type, *v2* is
+ the port identifier, and *v3* should be 0.
+
+ If *addr_type* is TIPC_ADDR_NAMESEQ, then *v1* is the server type, *v2*
+ is the lower port number, and *v3* is the upper port number.
+
+ If *addr_type* is TIPC_ADDR_ID, then *v1* is the node, *v2* is the
+ reference, and *v3* should be set to 0.
+
+
All errors raise exceptions. The normal exceptions for invalid argument types
and out-of-memory conditions can be raised; errors related to socket or address
semantics raise the error :exc:`socket.error`.
@@ -162,6 +183,12 @@ The module :mod:`socket` exports the following constants and functions:
:meth:`ioctl` method of socket objects.
+.. data:: TIPC_*
+
+ TIPC related constants, matching the ones exported by the C socket API. See
+ the TIPC documentation for more information.
+
+
.. data:: has_ipv6
This constant contains a boolean value which indicates if IPv6 is supported on
diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst
index 7a4938c537..4a1d566af5 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -389,9 +389,9 @@ This table lists the bit-string operations sorted in ascending priority
| ``x & y`` | bitwise :dfn:`and` of *x* and | |
| | *y* | |
+------------+--------------------------------+----------+
-| ``x << n`` | *x* shifted left by *n* bits | (1), (2) |
+| ``x << n`` | *x* shifted left by *n* bits | (1)(2) |
+------------+--------------------------------+----------+
-| ``x >> n`` | *x* shifted right by *n* bits | (1), (3) |
+| ``x >> n`` | *x* shifted right by *n* bits | (1)(3) |
+------------+--------------------------------+----------+
| ``~x`` | the bits of *x* inverted | |
+------------+--------------------------------+----------+
@@ -436,7 +436,7 @@ One method needs to be defined for container objects to provide iteration
support:
-.. method:: container.__iter__()
+.. method:: object.__iter__()
Return an iterator object. The object is required to support the iterator
protocol described below. If a container supports different types of
@@ -537,7 +537,7 @@ support slicing, concatenation or repetition, and using ``in``, ``not in``,
Most sequence types support the following operations. The ``in`` and ``not in``
operations have the same priorities as the comparison operations. The ``+`` and
``*`` operations have the same priority as the corresponding numeric operations.
-[#]_
+[#]_ Additional methods are provided for :ref:`typesseq-mutable`.
This table lists the sequence operations sorted in ascending priority
(operations in the same box have the same priority). In the table, *s* and *t*
@@ -560,9 +560,9 @@ are sequences of the same type; *n*, *i* and *j* are integers:
+------------------+--------------------------------+----------+
| ``s[i]`` | *i*'th item of *s*, origin 0 | \(3) |
+------------------+--------------------------------+----------+
-| ``s[i:j]`` | slice of *s* from *i* to *j* | (3), (4) |
+| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |
+------------------+--------------------------------+----------+
-| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3), (5) |
+| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |
| | with step *k* | |
+------------------+--------------------------------+----------+
| ``len(s)`` | length of *s* | |
diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst
index 5b05aed2d2..3fedb56bcb 100644
--- a/Doc/tutorial/controlflow.rst
+++ b/Doc/tutorial/controlflow.rst
@@ -595,10 +595,57 @@ Here is an example of a multi-line docstring::
No, really, it doesn't do anything.
+.. _tut-codingstyle:
+
+Intermezzo: Coding Style
+========================
+
+.. sectionauthor:: Georg Brandl <georg@python.org>
+.. index:: pair: coding; style
+
+Now that you are about to write longer, more complex pieces of Python, it is a
+good time to talk about *coding style*. Most languages can be written (or more
+concise, *formatted*) in different styles; some are more readable than others.
+Making it easy for others to read your code is always a good idea, and adopting
+a nice coding style helps tremendously for that.
+
+For Python, :pep:`8` has emerged as the style guide that most projects adher to;
+it promotes a very readable and eye-pleasing coding style. Every Python
+developer should read it at some point; here are the most important points
+extracted for you:
+
+* Use 4-space indentation, and no tabs.
+
+ 4 spaces are a good compromise between small indentation (allows greater
+ nesting depth) and large indentation (easier to read). Tabs introduce
+ confusion, and are best left out.
+
+* Wrap lines so that they don't exceed 79 characters.
+
+ This helps users with small displays and makes it possible to have several
+ code files side-by-side on larger displays.
+
+* Use blank lines to separate functions and classes, and larger blocks of
+ code inside functions.
+
+* When possible, put comments on a line of their own.
+
+* Use docstrings.
+
+* Use spaces around operators and after commas, but not directly inside
+ bracketing constructs: ``a = f(1, 2) + g(3, 4)``.
+
+* Name your classes and functions consistently; the convention is to use
+ ``CamelCase`` for classes and ``lower_case_with_underscores`` for functions
+ and methods. Always use ``self`` as the name for the first method argument.
+
+* Don't use fancy encodings if your code is meant to be used in international
+ environments. Plain ASCII works best in any case.
+
.. rubric:: Footnotes
-.. [#] Actually, *call by object reference* would be a better description, since if a
- mutable object is passed, the caller will see any changes the callee makes to it
- (items inserted into a list).
+.. [#] Actually, *call by object reference* would be a better description,
+ since if a mutable object is passed, the caller will see any changes the
+ callee makes to it (items inserted into a list).
diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst
index a99e7d2211..1189ce8cea 100644
--- a/Doc/tutorial/introduction.rst
+++ b/Doc/tutorial/introduction.rst
@@ -548,7 +548,7 @@ series as follows::
... # the sum of two elements defines the next
... a, b = 0, 1
>>> while b < 10:
- ... print(b)
+ ... print b
... a, b = b, a+b
...
1
diff --git a/Lib/abc.py b/Lib/abc.py
index 54dc8e2d97..875115361d 100644
--- a/Lib/abc.py
+++ b/Lib/abc.py
@@ -187,7 +187,7 @@ class ABCMeta(type):
cls._abc_negative_cache.add(subclass)
return ok
# Check if it's a direct subclass
- if cls in subclass.__mro__:
+ if cls in getattr(subclass, '__mro__', ()):
cls._abc_cache.add(subclass)
return True
# Check if it's a subclass of a registered class (recursive)
diff --git a/Lib/collections.py b/Lib/collections.py
index 504ae19549..884c91f1e7 100644
--- a/Lib/collections.py
+++ b/Lib/collections.py
@@ -65,9 +65,9 @@ def namedtuple(typename, field_names, verbose=False):
def __new__(cls, %(argtxt)s):
return tuple.__new__(cls, (%(argtxt)s)) \n
@classmethod
- def _make(cls, iterable):
+ def _make(cls, iterable, new=tuple.__new__, len=len):
'Make a new %(typename)s object from a sequence or iterable'
- result = tuple.__new__(cls, iterable)
+ result = new(cls, iterable)
if len(result) != %(numfields)d:
raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
return result \n
@@ -115,8 +115,22 @@ if __name__ == '__main__':
assert p == loads(dumps(p))
# test and demonstrate ability to override methods
- Point.__repr__ = lambda self: 'Point(%.3f, %.3f)' % self
- print(p)
+ class Point(namedtuple('Point', 'x y')):
+ @property
+ def hypot(self):
+ return (self.x ** 2 + self.y ** 2) ** 0.5
+ def __repr__(self):
+ return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot)
+
+ print(Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6))
+
+ class Point(namedtuple('Point', 'x y')):
+ 'Point class with optimized _make() and _replace() without error-checking'
+ _make = classmethod(tuple.__new__)
+ def _replace(self, _map=map, **kwds):
+ return self._make(_map(kwds.pop, ('x', 'y'), self))
+
+ print(Point(11, 22)._replace(x=100))
import doctest
TestResults = namedtuple('TestResults', 'failed attempted')
diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py
index e6c84154fe..884dd322b4 100644
--- a/Lib/test/test_abc.py
+++ b/Lib/test/test_abc.py
@@ -56,10 +56,18 @@ class TestABC(unittest.TestCase):
self.assertEqual(F.__abstractmethods__, {"bar"})
self.assertRaises(TypeError, F) # because bar is abstract now
+ def test_subclass_oldstyle_class(self):
+ class A:
+ __metaclass__ = abc.ABCMeta
+ class OldstyleClass:
+ pass
+ self.assertFalse(issubclass(OldstyleClass, A))
+ self.assertFalse(issubclass(A, OldstyleClass))
+
def test_registration_basics(self):
class A(metaclass=abc.ABCMeta):
pass
- class B:
+ class B(object):
pass
b = B()
self.assertEqual(issubclass(B, A), False)
@@ -94,7 +102,7 @@ class TestABC(unittest.TestCase):
class A1(A):
pass
self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed
- class B:
+ class B(object):
pass
A1.register(B) # ok
A1.register(B) # should pass silently
@@ -135,7 +143,7 @@ class TestABC(unittest.TestCase):
def test_all_new_methods_are_called(self):
class A(metaclass=abc.ABCMeta):
pass
- class B:
+ class B(object):
counter = 0
def __new__(cls):
B.counter += 1
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 535f0ef81e..facf9fda67 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -1114,6 +1114,85 @@ class BufferIOTest(SocketConnectedTest):
buf = bytes(MSG)
self.serv_conn.send(buf)
+
+TIPC_STYPE = 2000
+TIPC_LOWER = 200
+TIPC_UPPER = 210
+
+def isTipcAvailable():
+ """Check if the TIPC module is loaded
+
+ The TIPC module is not loaded automatically on Ubuntu and probably
+ other Linux distros.
+ """
+ if not hasattr(socket, "AF_TIPC"):
+ return False
+ if not os.path.isfile("/proc/modules"):
+ return False
+ with open("/proc/modules") as f:
+ for line in f:
+ if line.startswith("tipc "):
+ return True
+ if test_support.debug:
+ print("TIPC module is not loaded, please 'sudo modprobe tipc'")
+ return False
+
+class TIPCTest (unittest.TestCase):
+ def testRDM(self):
+ srv = socket.socket(socket.AF_TIPC, socket.SOCK_RDM)
+ cli = socket.socket(socket.AF_TIPC, socket.SOCK_RDM)
+
+ srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ srvaddr = (socket.TIPC_ADDR_NAMESEQ, TIPC_STYPE,
+ TIPC_LOWER, TIPC_UPPER)
+ srv.bind(srvaddr)
+
+ sendaddr = (socket.TIPC_ADDR_NAME, TIPC_STYPE,
+ TIPC_LOWER + int((TIPC_UPPER - TIPC_LOWER) / 2), 0)
+ cli.sendto(MSG, sendaddr)
+
+ msg, recvaddr = srv.recvfrom(1024)
+
+ self.assertEqual(cli.getsockname(), recvaddr)
+ self.assertEqual(msg, MSG)
+
+
+class TIPCThreadableTest (unittest.TestCase, ThreadableTest):
+ def __init__(self, methodName = 'runTest'):
+ unittest.TestCase.__init__(self, methodName = methodName)
+ ThreadableTest.__init__(self)
+
+ def setUp(self):
+ self.srv = socket.socket(socket.AF_TIPC, socket.SOCK_STREAM)
+ self.srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ srvaddr = (socket.TIPC_ADDR_NAMESEQ, TIPC_STYPE,
+ TIPC_LOWER, TIPC_UPPER)
+ self.srv.bind(srvaddr)
+ self.srv.listen(5)
+ self.serverExplicitReady()
+ self.conn, self.connaddr = self.srv.accept()
+
+ def clientSetUp(self):
+ # The is a hittable race between serverExplicitReady() and the
+ # accept() call; sleep a little while to avoid it, otherwise
+ # we could get an exception
+ time.sleep(0.1)
+ self.cli = socket.socket(socket.AF_TIPC, socket.SOCK_STREAM)
+ addr = (socket.TIPC_ADDR_NAME, TIPC_STYPE,
+ TIPC_LOWER + int((TIPC_UPPER - TIPC_LOWER) / 2), 0)
+ self.cli.connect(addr)
+ self.cliaddr = self.cli.getsockname()
+
+ def testStream(self):
+ msg = self.conn.recv(1024)
+ self.assertEqual(msg, MSG)
+ self.assertEqual(self.cliaddr, self.connaddr)
+
+ def _testStream(self):
+ self.cli.send(MSG)
+ self.cli.close()
+
+
def test_main():
tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest,
TestExceptions, BufferIOTest, BasicTCPTest2]
@@ -1134,6 +1213,9 @@ def test_main():
tests.append(BasicSocketPairTest)
if sys.platform == 'linux2':
tests.append(TestLinuxAbstractNamespace)
+ if isTipcAvailable():
+ tests.append(TIPCTest)
+ tests.append(TIPCThreadableTest)
thread_info = test_support.threading_setup()
test_support.run_unittest(*tests)
diff --git a/Misc/NEWS b/Misc/NEWS
index ee156cb7c9..9ff17b43cc 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -44,6 +44,7 @@ Core and Builtins
Extension Modules
-----------------
+- Issue #1762972: Readded the reload() function as imp.reload()
Library
-------
diff --git a/Misc/developers.txt b/Misc/developers.txt
index 7fdfb33ff9..ba1c16b840 100644
--- a/Misc/developers.txt
+++ b/Misc/developers.txt
@@ -17,6 +17,9 @@ the format to accommodate documentation needs as they arise.
Permissions History
-------------------
+- Mark Dickinson was given SVN access on 6 January 2008 by Facundo
+ Batista for his work on mathemathics and number related issues.
+
- Amaury Forgeot d'Arc was given SVN access on 9 November 2007 by MvL,
for general contributions to Python.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index b59c15dc51..dc05108f34 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -7,7 +7,8 @@ This module provides an interface to Berkeley socket IPC.
Limitations:
- Only AF_INET, AF_INET6 and AF_UNIX address families are supported in a
- portable manner, though AF_PACKET and AF_NETLINK are supported under Linux.
+ portable manner, though AF_PACKET, AF_NETLINK and AF_TIPC are supported
+ under Linux.
- No read/write operations (use sendall/recv or makefile instead).
- Additional restrictions apply on some non-Unix platforms (compensated
for by socket.py).
@@ -51,6 +52,25 @@ Module interface:
the Ethernet protocol number to be received. For example:
("eth0",0x1234). Optional 3rd,4th,5th elements in the tuple
specify packet-type and ha-type/addr.
+- an AF_TIPC socket address is expressed as
+ (addr_type, v1, v2, v3 [, scope]); where addr_type can be one of:
+ TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, and TIPC_ADDR_ID;
+ and scope can be one of:
+ TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and TIPC_NODE_SCOPE.
+ The meaning of v1, v2 and v3 depends on the value of addr_type:
+ if addr_type is TIPC_ADDR_NAME:
+ v1 is the server type
+ v2 is the port identifier
+ v3 is ignored
+ if addr_type is TIPC_ADDR_NAMESEQ:
+ v1 is the server type
+ v2 is the lower port number
+ v3 is the upper port number
+ if addr_type is TIPC_ADDR_ID:
+ v1 is the node
+ v2 is the ref
+ v3 is ignored
+
Local naming conventions:
@@ -1058,6 +1078,39 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
}
#endif
+#ifdef HAVE_LINUX_TIPC_H
+ case AF_TIPC:
+ {
+ struct sockaddr_tipc *a = (struct sockaddr_tipc *) addr;
+ if (a->addrtype == TIPC_ADDR_NAMESEQ) {
+ return Py_BuildValue("IIIII",
+ a->addrtype,
+ a->addr.nameseq.type,
+ a->addr.nameseq.lower,
+ a->addr.nameseq.upper,
+ a->scope);
+ } else if (a->addrtype == TIPC_ADDR_NAME) {
+ return Py_BuildValue("IIIII",
+ a->addrtype,
+ a->addr.name.name.type,
+ a->addr.name.name.instance,
+ a->addr.name.name.instance,
+ a->scope);
+ } else if (a->addrtype == TIPC_ADDR_ID) {
+ return Py_BuildValue("IIIII",
+ a->addrtype,
+ a->addr.id.node,
+ a->addr.id.ref,
+ 0,
+ a->scope);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Invalid address type");
+ return NULL;
+ }
+ }
+#endif
+
/* More cases here... */
default:
@@ -1343,6 +1396,56 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
}
#endif
+#ifdef HAVE_LINUX_TIPC_H
+ case AF_TIPC:
+ {
+ unsigned int atype, v1, v2, v3;
+ unsigned int scope = TIPC_CLUSTER_SCOPE;
+ struct sockaddr_tipc *addr;
+
+ if (!PyTuple_Check(args)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "getsockaddrarg: "
+ "AF_TIPC address must be tuple, not %.500s",
+ Py_TYPE(args)->tp_name);
+ return 0;
+ }
+
+ if (!PyArg_ParseTuple(args,
+ "IIII|I;Invalid TIPC address format",
+ &atype, &v1, &v2, &v3, &scope))
+ return 0;
+
+ addr = (struct sockaddr_tipc *) addr_ret;
+ memset(addr, 0, sizeof(struct sockaddr_tipc));
+
+ addr->family = AF_TIPC;
+ addr->scope = scope;
+ addr->addrtype = atype;
+
+ if (atype == TIPC_ADDR_NAMESEQ) {
+ addr->addr.nameseq.type = v1;
+ addr->addr.nameseq.lower = v2;
+ addr->addr.nameseq.upper = v3;
+ } else if (atype == TIPC_ADDR_NAME) {
+ addr->addr.name.name.type = v1;
+ addr->addr.name.name.instance = v2;
+ } else if (atype == TIPC_ADDR_ID) {
+ addr->addr.id.node = v1;
+ addr->addr.id.ref = v2;
+ } else {
+ /* Shouldn't happen */
+ PyErr_SetString(PyExc_TypeError, "Invalid address type");
+ return 0;
+ }
+
+ *len_ret = sizeof(*addr);
+
+ return 1;
+ }
+#endif
+
/* More cases here... */
default:
@@ -1428,6 +1531,14 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
}
#endif
+#ifdef HAVE_LINUX_TIPC_H
+ case AF_TIPC:
+ {
+ *len_ret = sizeof (struct sockaddr_tipc);
+ return 1;
+ }
+#endif
+
/* More cases here... */
default:
@@ -4211,6 +4322,47 @@ init_socket(void)
PyModule_AddIntConstant(m, "PACKET_FASTROUTE", PACKET_FASTROUTE);
#endif
+#ifdef HAVE_LINUX_TIPC_H
+ PyModule_AddIntConstant(m, "AF_TIPC", AF_TIPC);
+
+ /* for addresses */
+ PyModule_AddIntConstant(m, "TIPC_ADDR_NAMESEQ", TIPC_ADDR_NAMESEQ);
+ PyModule_AddIntConstant(m, "TIPC_ADDR_NAME", TIPC_ADDR_NAME);
+ PyModule_AddIntConstant(m, "TIPC_ADDR_ID", TIPC_ADDR_ID);
+
+ PyModule_AddIntConstant(m, "TIPC_ZONE_SCOPE", TIPC_ZONE_SCOPE);
+ PyModule_AddIntConstant(m, "TIPC_CLUSTER_SCOPE", TIPC_CLUSTER_SCOPE);
+ PyModule_AddIntConstant(m, "TIPC_NODE_SCOPE", TIPC_NODE_SCOPE);
+
+ /* for setsockopt() */
+ PyModule_AddIntConstant(m, "SOL_TIPC", SOL_TIPC);
+ PyModule_AddIntConstant(m, "TIPC_IMPORTANCE", TIPC_IMPORTANCE);
+ PyModule_AddIntConstant(m, "TIPC_SRC_DROPPABLE", TIPC_SRC_DROPPABLE);
+ PyModule_AddIntConstant(m, "TIPC_DEST_DROPPABLE",
+ TIPC_DEST_DROPPABLE);
+ PyModule_AddIntConstant(m, "TIPC_CONN_TIMEOUT", TIPC_CONN_TIMEOUT);
+
+ PyModule_AddIntConstant(m, "TIPC_LOW_IMPORTANCE",
+ TIPC_LOW_IMPORTANCE);
+ PyModule_AddIntConstant(m, "TIPC_MEDIUM_IMPORTANCE",
+ TIPC_MEDIUM_IMPORTANCE);
+ PyModule_AddIntConstant(m, "TIPC_HIGH_IMPORTANCE",
+ TIPC_HIGH_IMPORTANCE);
+ PyModule_AddIntConstant(m, "TIPC_CRITICAL_IMPORTANCE",
+ TIPC_CRITICAL_IMPORTANCE);
+
+ /* for subscriptions */
+ PyModule_AddIntConstant(m, "TIPC_SUB_PORTS", TIPC_SUB_PORTS);
+ PyModule_AddIntConstant(m, "TIPC_SUB_SERVICE", TIPC_SUB_SERVICE);
+ PyModule_AddIntConstant(m, "TIPC_SUB_CANCEL", TIPC_SUB_CANCEL);
+ PyModule_AddIntConstant(m, "TIPC_WAIT_FOREVER", TIPC_WAIT_FOREVER);
+ PyModule_AddIntConstant(m, "TIPC_PUBLISHED", TIPC_PUBLISHED);
+ PyModule_AddIntConstant(m, "TIPC_WITHDRAWN", TIPC_WITHDRAWN);
+ PyModule_AddIntConstant(m, "TIPC_SUBSCR_TIMEOUT", TIPC_SUBSCR_TIMEOUT);
+ PyModule_AddIntConstant(m, "TIPC_CFG_SRV", TIPC_CFG_SRV);
+ PyModule_AddIntConstant(m, "TIPC_TOP_SRV", TIPC_TOP_SRV);
+#endif
+
/* Socket types */
PyModule_AddIntConstant(m, "SOCK_STREAM", SOCK_STREAM);
PyModule_AddIntConstant(m, "SOCK_DGRAM", SOCK_DGRAM);
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
index 43c95fd5f6..114084cea7 100644
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -61,6 +61,10 @@
# include <netpacket/packet.h>
#endif
+#ifdef HAVE_LINUX_TIPC_H
+# include <linux/tipc.h>
+#endif
+
#ifndef Py__SOCKET_H
#define Py__SOCKET_H
#ifdef __cplusplus
diff --git a/Python/future.c b/Python/future.c
index dca1d8373d..80a3006a3d 100644
--- a/Python/future.c
+++ b/Python/future.c
@@ -65,7 +65,7 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
/* A subsequent pass will detect future imports that don't
appear at the beginning of the file. There's one case,
- however, that is easier to handl here: A series of imports
+ however, that is easier to handle here: A series of imports
joined by semi-colons, where the first import is a future
statement but some subsequent import has the future form
but is preceded by a regular import.
diff --git a/configure b/configure
index 786bcd29fc..0d2a04b2e6 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 59558 .
+# From configure.in Revision: 59625 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for python 3.0.
#
@@ -5390,6 +5390,7 @@ done
+
for ac_header in asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \
fcntl.h grp.h \
io.h langinfo.h libintl.h ncurses.h poll.h process.h pthread.h \
@@ -5401,7 +5402,7 @@ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/statvfs.h sys/stat.h \
sys/time.h \
sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
-bluetooth/bluetooth.h
+bluetooth/bluetooth.h linux/tipc.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
diff --git a/configure.in b/configure.in
index 9a1f915cb3..a92705c0c5 100644
--- a/configure.in
+++ b/configure.in
@@ -1082,7 +1082,7 @@ sys/param.h sys/poll.h sys/select.h sys/socket.h sys/statvfs.h sys/stat.h \
sys/time.h \
sys/times.h sys/types.h sys/un.h sys/utsname.h sys/wait.h pty.h libutil.h \
sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
-bluetooth/bluetooth.h)
+bluetooth/bluetooth.h linux/tipc.h)
AC_HEADER_DIRENT
AC_HEADER_MAJOR
diff --git a/pyconfig.h.in b/pyconfig.h.in
index ac6d9f634c..dbd7f0484b 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -351,6 +351,9 @@
/* Define to 1 if you have the <linux/netlink.h> header file. */
#undef HAVE_LINUX_NETLINK_H
+/* Define to 1 if you have the <linux/tipc.h> header file. */
+#undef HAVE_LINUX_TIPC_H
+
/* Define this if you have the type long double. */
#undef HAVE_LONG_DOUBLE
@@ -1046,4 +1049,3 @@
#endif /*Py_PYCONFIG_H*/
-