0

I build an app compatible between Python 2 and 3. In order to provide compatibility between those two Python versions, I use six library.

My code uses sockets. Under Python 3 it is possible to create them using with statement, but under Python 2 it claims on missing __exit__ attribute.

Is there any function of six providing disposable socket? If not, what solution would you consider as the most clear in this case?

pt12lol
  • 2,332
  • 1
  • 22
  • 48

1 Answers1

1

AFAIK (by scanning through its docs) six doesn't do much in this case. In Python 2, you could wrap socket up in a context manager with the contextmanager decorator and supply that:

from sys import version_info 
import socket

if version_info[0] == 2:
    from contextlib import contextmanager

    @contextmanager
    def sock(*args, **kwargs):
        s = socket.socket(*args, **kwargs)
        try:
            yield s
        finally:
            s.close()
else:  # Python 3
    sock = socket.socket

In both cases you use the with statement accordingly:

with sock(socket.AF_INET, socket.SOCK_STREAM) as s:
    # use s
pt12lol
  • 2,332
  • 1
  • 22
  • 48
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • good point. the only change I would apply in comparison to your suggestion is using six Python version checking (https://pythonhosted.org/six/#package-contents) instead of `version_info[0]`. – pt12lol Sep 11 '17 at 10:38
  • Additional question: what is the benefit of introducing two versions instead of using python2 version only? – pt12lol Sep 11 '17 at 10:44
  • @pt12lol yes, I missed the try-finally. I'm guessing you could rebind the name `socket` to the context manager version in Python 2 but I don't like renaming standard names like that. Instead, I opted to bind it to a new name which you can use unconditionally. – Dimitris Fasarakis Hilliard Sep 11 '17 at 10:49