mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
Another refactoring. Changed 'socket' from being a factory function
to being a new-style class, to be more similar to the socket class in the _socket module; it is now the same as the _socketobject class. Added __slots__. Added docstrings, copied from the real socket class where possible. The _fileobject class is now also a new-style class with __slots__ (though without docstrings). The mode, name, softspace, bufsize and closed attributes are properly supported (closed as a property; name as a class attributes; the softspace, mode and bufsize as slots).
This commit is contained in:
parent
824574d3d4
commit
c18993f84a
1 changed files with 49 additions and 26 deletions
|
@ -43,12 +43,12 @@ the setsockopt() and getsockopt() methods.
|
||||||
import _socket
|
import _socket
|
||||||
from _socket import *
|
from _socket import *
|
||||||
|
|
||||||
SSL_EXISTS = 1
|
_have_ssl = False
|
||||||
try:
|
try:
|
||||||
import _ssl
|
|
||||||
from _ssl import *
|
from _ssl import *
|
||||||
|
_have_ssl = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
SSL_EXISTS = 0
|
pass
|
||||||
|
|
||||||
import os, sys
|
import os, sys
|
||||||
|
|
||||||
|
@ -56,27 +56,20 @@ __all__ = ["getfqdn"]
|
||||||
__all__.extend(os._get_exports_list(_socket))
|
__all__.extend(os._get_exports_list(_socket))
|
||||||
# XXX shouldn't there be something similar to the above for _ssl exports?
|
# XXX shouldn't there be something similar to the above for _ssl exports?
|
||||||
|
|
||||||
|
_realsocket = socket
|
||||||
|
_needwrapper = False
|
||||||
if (sys.platform.lower().startswith("win")
|
if (sys.platform.lower().startswith("win")
|
||||||
or (hasattr(os, 'uname') and os.uname()[0] == "BeOS")
|
or (hasattr(os, 'uname') and os.uname()[0] == "BeOS")
|
||||||
or sys.platform=="riscos"):
|
or sys.platform=="riscos"):
|
||||||
|
|
||||||
_realsocketcall = _socket.socket
|
_needwrapper = True
|
||||||
|
|
||||||
def socket(family=AF_INET, type=SOCK_STREAM, proto=0):
|
if _have_ssl:
|
||||||
return _socketobject(_realsocketcall(family, type, proto))
|
_realssl = ssl
|
||||||
socket.__doc__ = _realsocketcall.__doc__
|
|
||||||
|
|
||||||
if SSL_EXISTS:
|
|
||||||
_realsslcall = _ssl.ssl
|
|
||||||
def ssl(sock, keyfile=None, certfile=None):
|
def ssl(sock, keyfile=None, certfile=None):
|
||||||
if hasattr(sock, "_sock"):
|
if hasattr(sock, "_sock"):
|
||||||
sock = sock._sock
|
sock = sock._sock
|
||||||
return _realsslcall(sock, keyfile, certfile)
|
return _realssl(sock, keyfile, certfile)
|
||||||
|
|
||||||
del _socket
|
|
||||||
if SSL_EXISTS:
|
|
||||||
del _ssl
|
|
||||||
del SSL_EXISTS
|
|
||||||
|
|
||||||
# WSA error codes
|
# WSA error codes
|
||||||
if sys.platform.lower().startswith("win"):
|
if sys.platform.lower().startswith("win"):
|
||||||
|
@ -140,47 +133,73 @@ _socketmethods = (
|
||||||
'recv', 'recvfrom', 'send', 'sendall', 'sendto', 'setblocking',
|
'recv', 'recvfrom', 'send', 'sendall', 'sendto', 'setblocking',
|
||||||
'settimeout', 'gettimeout', 'shutdown')
|
'settimeout', 'gettimeout', 'shutdown')
|
||||||
|
|
||||||
class _socketobject:
|
class _socketobject(object):
|
||||||
|
|
||||||
class _closedsocket:
|
__doc__ = _realsocket.__doc__
|
||||||
|
|
||||||
|
__slots__ = ["_sock"]
|
||||||
|
|
||||||
|
class _closedsocket(object):
|
||||||
|
__slots__ = []
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
raise error(9, 'Bad file descriptor')
|
raise error(9, 'Bad file descriptor')
|
||||||
|
|
||||||
def __init__(self, sock):
|
def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None):
|
||||||
self._sock = sock
|
if _sock is None:
|
||||||
|
_sock = _realsocket(family, type, proto)
|
||||||
|
self._sock = _sock
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
# Avoid referencing globals here
|
# Avoid referencing globals here
|
||||||
self._sock = self.__class__._closedsocket()
|
self._sock = self.__class__._closedsocket()
|
||||||
|
close.__doc__ = _realsocket.close.__doc__
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
sock, addr = self._sock.accept()
|
sock, addr = self._sock.accept()
|
||||||
return _socketobject(sock), addr
|
return _socketobject(_sock=sock), addr
|
||||||
|
accept.__doc__ = _realsocket.accept.__doc__
|
||||||
|
|
||||||
def dup(self):
|
def dup(self):
|
||||||
return _socketobject(self._sock)
|
"""dup() -> socket object
|
||||||
|
|
||||||
|
Return a new socket object connected to the same system resource."""
|
||||||
|
return _socketobject(_sock=self._sock)
|
||||||
|
|
||||||
def makefile(self, mode='r', bufsize=-1):
|
def makefile(self, mode='r', bufsize=-1):
|
||||||
|
"""makefile([mode[, bufsize]]) -> file object
|
||||||
|
|
||||||
|
Return a regular file object corresponding to the socket. The mode
|
||||||
|
and bufsize arguments are as for the built-in open() function."""
|
||||||
return _fileobject(self._sock, mode, bufsize)
|
return _fileobject(self._sock, mode, bufsize)
|
||||||
|
|
||||||
_s = "def %s(self, *args): return self._sock.%s(*args)\n\n"
|
_s = ("def %s(self, *args): return self._sock.%s(*args)\n\n"
|
||||||
|
"%s.__doc__ = _realsocket.%s.__doc__\n")
|
||||||
for _m in _socketmethods:
|
for _m in _socketmethods:
|
||||||
exec _s % (_m, _m)
|
exec _s % (_m, _m, _m, _m)
|
||||||
|
|
||||||
|
if _needwrapper:
|
||||||
|
socket = _socketobject
|
||||||
|
|
||||||
class _fileobject:
|
class _fileobject(object):
|
||||||
"""Faux file object attached to a socket object."""
|
"""Faux file object attached to a socket object."""
|
||||||
|
|
||||||
default_bufsize = 8192
|
default_bufsize = 8192
|
||||||
|
name = "<socket>"
|
||||||
|
|
||||||
|
__slots__ = ["mode", "bufsize", "softspace",
|
||||||
|
# "closed" is a property, see below
|
||||||
|
"_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf"]
|
||||||
|
|
||||||
def __init__(self, sock, mode='rb', bufsize=-1):
|
def __init__(self, sock, mode='rb', bufsize=-1):
|
||||||
self._sock = sock
|
self._sock = sock
|
||||||
self._mode = mode # Not actually used in this version
|
self.mode = mode # Not actually used in this version
|
||||||
if bufsize < 0:
|
if bufsize < 0:
|
||||||
bufsize = self.default_bufsize
|
bufsize = self.default_bufsize
|
||||||
|
self.bufsize = bufsize
|
||||||
|
self.softspace = False
|
||||||
if bufsize == 0:
|
if bufsize == 0:
|
||||||
self._rbufsize = 1
|
self._rbufsize = 1
|
||||||
elif bufsize == 1:
|
elif bufsize == 1:
|
||||||
|
@ -192,6 +211,10 @@ class _fileobject:
|
||||||
self._rbuf = []
|
self._rbuf = []
|
||||||
self._wbuf = []
|
self._wbuf = []
|
||||||
|
|
||||||
|
def _getclosed(self):
|
||||||
|
return self._sock is not None
|
||||||
|
closed = property(_getclosed, doc="True if the file is closed")
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
try:
|
try:
|
||||||
if self._sock:
|
if self._sock:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue