mirror of https://github.com/python/cpython
Copied doc for reload() from trunk's function.rst to imp.rst
This commit is contained in:
parent
13a7a21258
commit
043d6f67c7
|
@ -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:
|
||||
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)
|
||||
|
||||
>>> Point = namedtuple('Point', 'x y')
|
||||
>>> Point.__repr__ = lambda self: 'Point(%.3f, %.3f)' % self
|
||||
>>> Point(x=11, y=22)
|
||||
Point(11.000, 22.000)
|
||||
>>> 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`:
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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* | |
|
||||
|
|
|
@ -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).
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -44,6 +44,7 @@ Core and Builtins
|
|||
Extension Modules
|
||||
-----------------
|
||||
|
||||
- Issue #1762972: Readded the reload() function as imp.reload()
|
||||
|
||||
Library
|
||||
-------
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
#
|
||||
|
@ -5388,6 +5388,7 @@ done
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for ac_header in asm/types.h conio.h curses.h direct.h dlfcn.h errno.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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue