0

I'm trying to use logging's SMTPHandler. From Python 3.3 on, you can specify a timeout keyword argument. If you add that argument in older versions, it fails. To get around this, I used the following:

import sys

if sys.version_info >= (3, 3):
    smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT, timeout=20.0)
else:
    smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT)

Is there a better way of doing this?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Tamerz
  • 897
  • 1
  • 10
  • 25

3 Answers3

4

Rather than test for the version, use exception handling:

try:
    smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT, timeout=20.0)
except TypeError:
    # Python < 3.3, no timeout parameter
    smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT)

Now you can conceivably upgrade your standard library in-place with a patch or a backport module and it'll continue to work.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2

I would do something like this:

kargs = {}
if sys.version_info >= (3, 3):
    kargs['timeout'] = 20.0

smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT, **kargs)

UPDATE: The idea of try/catch of other answers is nice, but it assumes that it fails because of the timeout argument. Here I present an extra-smart test for the availability of the argument. What if future versions of this class add more and more optional arguments? (Disclaimer: not claimed as portable):

if 'timeout' in SMTPHandler.__init__.__code__.co_varnames:
    kargs['timeout'] = 20.0
rodrigo
  • 94,151
  • 12
  • 143
  • 190
1

Here is another slightly different approach:

from logging.handlers import SMTPHandler
import sys

if sys.version_info >= (3, 3):
    # patch in timeout where available
    from functools import partial
    SMTPHandler = partial(SMTPHandler, timeout=20.0)

Now in the rest of the code you can just use:

smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT)

and know that the timeout argument is being used if available. This does still rely on static version checking, but means that all of the version-specific config is in one place and may reduce duplication elsewhere.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437