mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Adds an optional source_address parameter to socket.create_connection().
For use by issue3972.
This commit is contained in:
		
							parent
							
								
									7f8ebdbad5
								
							
						
					
					
						commit
						79a3eb1058
					
				
					 4 changed files with 32 additions and 5 deletions
				
			
		|  | @ -205,7 +205,7 @@ The module :mod:`socket` exports the following constants and functions: | ||||||
|    .. versionadded:: 2.3 |    .. versionadded:: 2.3 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| .. function:: create_connection(address[, timeout]) | .. function:: create_connection(address[, timeout[, source_address]]) | ||||||
| 
 | 
 | ||||||
|    Convenience function.  Connect to *address* (a 2-tuple ``(host, port)``), |    Convenience function.  Connect to *address* (a 2-tuple ``(host, port)``), | ||||||
|    and return the socket object.  Passing the optional *timeout* parameter will |    and return the socket object.  Passing the optional *timeout* parameter will | ||||||
|  | @ -215,6 +215,12 @@ The module :mod:`socket` exports the following constants and functions: | ||||||
| 
 | 
 | ||||||
|    .. versionadded:: 2.6 |    .. versionadded:: 2.6 | ||||||
| 
 | 
 | ||||||
|  |    If supplied, *source_address* must be a 2-tuple ``(host, port)`` for the | ||||||
|  |    socket to bind to as its source address before connecting.  If host or port | ||||||
|  |    are '' or 0 respectively the OS default behavior will be used. | ||||||
|  | 
 | ||||||
|  |    .. versionadded:: 2.7 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| .. function:: getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]]) | .. function:: getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]]) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -24,7 +24,8 @@ | ||||||
| ssl() -- secure socket layer support (only available if configured) | ssl() -- secure socket layer support (only available if configured) | ||||||
| socket.getdefaulttimeout() -- get the default timeout value | socket.getdefaulttimeout() -- get the default timeout value | ||||||
| socket.setdefaulttimeout() -- set the default timeout value | socket.setdefaulttimeout() -- set the default timeout value | ||||||
| create_connection() -- connects to an address, with an optional timeout | create_connection() -- connects to an address, with an optional timeout and | ||||||
|  |                        optional source address. | ||||||
| 
 | 
 | ||||||
|  [*] not available on all platforms! |  [*] not available on all platforms! | ||||||
| 
 | 
 | ||||||
|  | @ -531,7 +532,8 @@ def next(self): | ||||||
| 
 | 
 | ||||||
| _GLOBAL_DEFAULT_TIMEOUT = object() | _GLOBAL_DEFAULT_TIMEOUT = object() | ||||||
| 
 | 
 | ||||||
| def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT): | def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, | ||||||
|  |                       source_address=None): | ||||||
|     """Connect to *address* and return the socket object. |     """Connect to *address* and return the socket object. | ||||||
| 
 | 
 | ||||||
|     Convenience function.  Connect to *address* (a 2-tuple ``(host, |     Convenience function.  Connect to *address* (a 2-tuple ``(host, | ||||||
|  | @ -539,7 +541,9 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT): | ||||||
|     *timeout* parameter will set the timeout on the socket instance |     *timeout* parameter will set the timeout on the socket instance | ||||||
|     before attempting to connect.  If no *timeout* is supplied, the |     before attempting to connect.  If no *timeout* is supplied, the | ||||||
|     global default timeout setting returned by :func:`getdefaulttimeout` |     global default timeout setting returned by :func:`getdefaulttimeout` | ||||||
|     is used. |     is used.  If *source_address* is set it must be a tuple of (host, port) | ||||||
|  |     for the socket to bind as a source address before making the connection. | ||||||
|  |     An host of '' or port 0 tells the OS to use the default. | ||||||
|     """ |     """ | ||||||
| 
 | 
 | ||||||
|     msg = "getaddrinfo returns an empty list" |     msg = "getaddrinfo returns an empty list" | ||||||
|  | @ -551,6 +555,8 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT): | ||||||
|             sock = socket(af, socktype, proto) |             sock = socket(af, socktype, proto) | ||||||
|             if timeout is not _GLOBAL_DEFAULT_TIMEOUT: |             if timeout is not _GLOBAL_DEFAULT_TIMEOUT: | ||||||
|                 sock.settimeout(timeout) |                 sock.settimeout(timeout) | ||||||
|  |             if source_address: | ||||||
|  |                 sock.bind(source_address) | ||||||
|             sock.connect(sa) |             sock.connect(sa) | ||||||
|             return sock |             return sock | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -995,7 +995,7 @@ def __init__(self, methodName='runTest'): | ||||||
|         ThreadableTest.__init__(self) |         ThreadableTest.__init__(self) | ||||||
| 
 | 
 | ||||||
|     def clientSetUp(self): |     def clientSetUp(self): | ||||||
|         pass |         self.source_port = test_support.find_unused_port() | ||||||
| 
 | 
 | ||||||
|     def clientTearDown(self): |     def clientTearDown(self): | ||||||
|         self.cli.close() |         self.cli.close() | ||||||
|  | @ -1010,6 +1010,19 @@ def _testFamily(self): | ||||||
|         self.cli = socket.create_connection((HOST, self.port), timeout=30) |         self.cli = socket.create_connection((HOST, self.port), timeout=30) | ||||||
|         self.assertEqual(self.cli.family, 2) |         self.assertEqual(self.cli.family, 2) | ||||||
| 
 | 
 | ||||||
|  |     testSourcePort = _justAccept | ||||||
|  |     def _testSourcePort(self): | ||||||
|  |         self.cli = socket.create_connection((HOST, self.port), timeout=30, | ||||||
|  |                 source_address=('', self.source_port)) | ||||||
|  |         self.assertEqual(self.cli.getsockname()[1], self.source_port) | ||||||
|  | 
 | ||||||
|  |     testSourceAddress = _justAccept | ||||||
|  |     def _testSourceAddress(self): | ||||||
|  |         self.cli = socket.create_connection( | ||||||
|  |                 (HOST, self.port), 30, ('127.0.0.1', self.source_port)) | ||||||
|  |         self.assertEqual(self.cli.getsockname(), | ||||||
|  |                          ('127.0.0.1', self.source_port)) | ||||||
|  | 
 | ||||||
|     testTimeoutDefault = _justAccept |     testTimeoutDefault = _justAccept | ||||||
|     def _testTimeoutDefault(self): |     def _testTimeoutDefault(self): | ||||||
|         # passing no explicit timeout uses socket's global default |         # passing no explicit timeout uses socket's global default | ||||||
|  |  | ||||||
|  | @ -62,6 +62,8 @@ Core and Builtins | ||||||
| Library | Library | ||||||
| ------- | ------- | ||||||
| 
 | 
 | ||||||
|  | - socket.create_connection now accepts an optional source_address parameter. | ||||||
|  | 
 | ||||||
| - Issue #5511: now zipfile.ZipFile can be used as a context manager. | - Issue #5511: now zipfile.ZipFile can be used as a context manager. | ||||||
|   Initial patch by Brian Curtin. |   Initial patch by Brian Curtin. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gregory P. Smith
						Gregory P. Smith