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
  • 107,083
  • 22
  • 201
  • 376
Tamerz
  • 868
  • 1
  • 9
  • 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
  • 963,270
  • 265
  • 3,804
  • 3,187
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
  • 86,825
  • 11
  • 134
  • 175
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
  • 107,083
  • 22
  • 201
  • 376