(solved) smtplib, capturing output from set_debuglevel ??

Andrew Dalke adalke at mindspring.com
Fri Oct 8 18:50:03 EDT 2004


Josiah Carlson wrote:
> I hope you didn't change your own copy of smtplib, but just subclassed
> it. Changing a standard module is a good way to get bitten in the ass,
> especially during Python upgrades.

There's no way to get what the OP wanted through subclassing.
Rather, any subclassing would end up rewriting non-trivial
amount of smtp logic so the subclass would break whenever a
copy would break.

The choice is to copy into new file with different name or
do your solution.  The new thread-specific data storage in
2.4 should also make that much easier to implement.

The OP also likes being able to add new debug messages,
which can't be done through subclassing.  Perhaps through
AOP?  :)

> In regards to changing the standard library's smtplib permanently, you
> may or may not find support.  A good way to find out is to post here
> with the subject "proposed change to smtplib in standard library",
> describe your changes, and if it has support, head to
> sf.net/projects/python, list it as an RFE, and offer the code you have
> written yourself.

What the OP wants is handy for things like email programs
that want to give feedback to the user about what's going on.
It captures some steps that can't otherwise be done via
subclassing.

Another option is to change the code so that things like

for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
   af, socktype, proto, canonname, sa = res
   try:
     self.sock = socket.socket(af, socktype, proto)
     if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
     self.sock.connect(sa)
   except socket.error, msg:
     if self.debuglevel > 0: print>>stderr, 'connect fail:', (host, port)
     if self.sock:
       self.sock.close()
     self.sock = None
     continue
   break
if not sock:
   ...

uses methods, like

sock = None
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
   sock = self.open_socket(host, port, res)
   if sock:
     self.sock = sock
     break
if not sock:
   ...

def open_socket(self, host, port, res):
   af, socktype, proto, canonname, sa = res
   try:
     sock = socket.socket(af, socktype, proto)
     self.sock.connect(sa)
   except socket.error, msg:
     sock = None
   return



so that subclasses can intercept the self.open_socket
call to add debug messages as desired.

class MySMTP(smtplib.SMTP):
   def open_socket(self, host, port, res):
     sock = smtplib.SMTP.open_socket(self, host, port, res)
     if sock:
       print "connect:", (host, port)
     else:
       print "connect fail:", (host, port)
     return sock

This approach may be better, though I'm not sure.  I
would rather use a callback handler.  In any case it's
more complicated than I would suggest for a self-described
new Python programmer.

				Andrew
				dalke at dalkescientific.com



More information about the Python-list mailing list