Catching imaplib exception (using IMAPClient package) in Python - python

I am using the external library IMAPClient. When the login fails, i see this error : imaplib.error: [AUTHENTICATIONFAILED] Authentication failed.
When i try except imaplib.error: i get : AttributeError: 'module' object has no attribute 'error'
The documentation of imaplib says that the exception should be IMAP4.error
Then why is IMAPClient raising imaplib.error and how do i catch it ?

The error message you see:
imaplib.error: [AUTHENTICATIONFAILED] Authentication failed.
is describing the error as best it knows how; at the time the exception occurs, the exception class is called "imaplib.error", because whoever is raising it has described it that way (more on this later). I poked around, and I think I've found it for you:
Python 2.7.2 (default, Nov 14 2011, 19:37:59)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import imaplib
>>> imaplib.IMAP4.error
<class 'imaplib.error'>
I opened up the imaplib.py file, and found what seems like an odd exception-throwing mechanism. "IMAP4" is a class, and "error" is a class defined inside the IMAP4 class. Python doesn't appear to "nest" the classes - just the class definitions. So once an object of class "error" exists, it's an object of class "error" which was defined in the scope "imaplib". The fact that the "error" class definition was inside the "IMAP4" class lib definition is irrelevant to Python. On the other hand, in order for you to describe an object of class "error" before such an object exists, you need to reference it as imaplib.IMAP4.error in order for Python to find the definition of the class you are talking about.
Very confusing, I know, and I didn't really know all of this before I started investigating the question. Here's a brief illustration:
Python 2.7.2 (default, Nov 14 2011, 19:37:59)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class foo(object):
... class bar(object):
... pass
... def b(self):
... return bar()
...
>>> bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'bar' is not defined
>>> foo.bar
<class '__main__.bar'>
>>> foo().bar()
<__main__.bar object at 0x10048dd10>
Basically, you were trying to do a very reasonable thing, but the way the imaplib library handles exception throwing is a little odd, making your life difficult. Long story short, you should try to catch imaplib.IMAP4.error and move on with your life.

(Disclaimer: I'm the maintainer of IMAPClient)
IMAPClient uses imaplib under the hood which is why you're seeing imaplib errors when using it. To simplify things a little, imaplib's exceptions are aliased on to the IMAPClient class. To catch errors from IMAPClient you can do something like this:
from imapclient import IMAPClient
try:
client = IMAPClient(...)
client.do_something(...)
client.logout()
except IMAPClient.Error, err:
# handle error here
Error is the base exception class (same as imaplib.IMAP4.error). There's also AbortError and ReadOnlyError.
IMAPClient uses these exceptions when it raises errors itself so there's only one set of exceptions to worry about in your code.

Related

Why do I get a "symbol not found" for a found symbol in Pykd?

I'm working on a dump, which I try to investigate, using PYKD technology.
The result of the x /2 *!*``vtable' (just one backtick) contains the following result:
745293b8 mfc110u!CPtrList::`vftable'
However, when I try to get more information about this class, I get a "symbol not found" exception:
Python source code:
dprintln("name=[%s]" % type_stats.name)
if not type_stats.name in typesize_by_type:
try:
type_info = typeInfo(type_stats.name)
except Exception, e:
dprintln("text=[%s]" % (str(e)))
Output:
name=[mfc110u!CPtrList]
text=['CPtrList' - symbol not found]
The result of the lm command returns the mfc110u symbols, as you can see here:
0:000> lm
start end module name
...
744f0000 74930000 mfc110u (pdb symbols) C:\ProgramData\dbg\sym\mfc110u.i386.pdb\...\mfc110u.i386.pdb
...
For your information, I'm now working with the last version of PYKD:
0:000> .chain
Extension DLL search Path:
...
Extension DLL chain:
pykd.pyd: image 0.3.3.4, API 1.0.0, built Mon May 14 11:14:43 2018
[path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\winext\pykd.pyd]
Meanwhile I've found a very simple way for reproducing the issue without needing to launch the whole script (using the Windbg prompt):
0:000> !py
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> typeInfo("mfc110u!CPtrList")
Traceback (most recent call last):
File "<console>", line 1, in <module>
SymbolException: 'CPtrList' - symbol not found
In addition to ussrhero's answer, there is following extra information:
The result of x /2 *!CPtrList* contains (amongst many others) the following results:
009530c4 <application>!CPtrList::~CPtrList
009530be <application>!CPtrList::CPtrList
... <application>!CPtrList::...
009abc5c <application>!CPtrList::`RTTI Base Class Array'
009abc4c <application>!CPtrList::`RTTI Class Hierarchy Descriptor'
009bcd18 <application>!CPtrList `RTTI Type Descriptor'
009abc30 <application>!CPtrList::`RTTI Base Class Descriptor at (0,-1,0,64)'
7464e9cb mfc110u!CPtrList::~CPtrList
74544a04 mfc110u!CPtrList::CPtrList
... mfc110u!CPtrList::...
745293b8 mfc110u!CPtrList::`vftable'
747510da mfc110u!CPtrList::`vector deleting destructor'
745293cc mfc110u!CPtrList::`RTTI Complete Object Locator'
7452940c mfc110u!CPtrList::`RTTI Base Class Array'
745293fc mfc110u!CPtrList::`RTTI Class Hierarchy Descriptor'
74795778 mfc110u!CPtrList `RTTI Type Descriptor'
745293e0 mfc110u!CPtrList::`RTTI Base Class Descriptor at (0,-1,0,64)'
746fdc68 mfc110u!CPtrList::classCPtrList
The script I'm using (heap_stat.py) browses through the results of !heap -h 0 and searches for the entry, corresponding with mfc110u!CPtrList::``vtable'.
The result of dt CPtrList starts with the following:
0:000> dt CPtrList
<application>!CPtrList => in other words, no 'mfcu110' entry
+0x000 __VFN_table : Ptr32
I'm already wondering for a long time, what's the difference between the mfc110u!CPtrList and the <application>!CPtrList entries and what's the exact role of the vtable entry in x /2 result?
Any ideas?
Thanks
Meanwhile I've found the solution:
Apparently for some objects, the module prefix needs to be removed:
>>> typeInfo("mdf110u!CPtrList")
-> SymbolException
>>> typeInfo("CPtrList")
-> this is working!!!
Try to see how WinDBG locates this type:
dt CPtrList
It maybe mfc110u does not contain type information fot CPtrList

Python embedded in HTML returns error when there is no input

I've written this code:
http://pastebin.com/e3aZzqVB
loading from this page:
nimasa.heliohost.org/RJ/
The problem comes from no-input which returns error, although there is no problem on interpreter as it could be seen at:
repl.it/v88/2
Waiting for your suggestions,
What should I change/or add/ to make it not to return error on no-input?
Thanks,
Nima
form.getvalue("b") will return None if there's no value for b in the request. Trying to slice None (at line 19 : s = b[35:]) - or to apply any string method or function FWIW - will (obviously) raise a TypeError.
For the record, it took me about 30 seconds to find out:
# python
Python 2.7.3 (default, Jun 22 2015, 19:33:41)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cgi
>>> f = cgi.FieldStorage()
>>> f.getvalue("foo") is None
True

Django test - 'HTTP_USER_AGENT' invalid keyword argument to test client

My Django unit tests have stopped working. Instantiating the Django test client now fails with the following error:
Traceback (most recent call last):
File "/vagrant/my/app/tests.py", line 43, in setUp
self.client = Client(HTTP_USER_AGENT='Mozilla/5.0')
File "/usr/local/lib/python2.6/dist-packages/Django-1.4.1-py2.6.egg/django/db/models/base.py", line 367, in __init__
raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.keys()[0])
TypeError: 'HTTP_USER_AGENT' is an invalid keyword argument for this function
They fail when I instantiate the Django test client.
from django.test.client import Client
...
class MyAppTestCase(TestCase):
base_fixtures = ['fixtures.json']
def setUp(self):
self.client = Client(HTTP_USER_AGENT='Mozilla/5.0') # fails here
self.setupSession()
self.authenticateUser()
When I run python manage.py shell and enter the following, it works fine.
vagrant#lucid32:/var/www/mytraps.com/spensa$ python manage.py shell
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.test.client import Client
>>> client = Client(HTTP_USER_AGENT='Mozilla/5.0')
>>>
Any thoughts on why it is chocking on the HTTP_USER_AGENT keyword?
I found the solution.
I had a model class named 'Client'. My models were imported after the django test Client class.
You can't fix stupid.

How to workaround Python "WindowsError messages are not properly encoded" problem?

It's a trouble when Python raised a WindowsError, the encoding of message of the exception is always os-native-encoded. For example:
import os
os.remove('does_not_exist.file')
Well, here we get an exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
WindowsError: [Error 2] 系統找不到指定的檔案。: 'does_not_exist.file'
As the language of my Windows7 is Traditional Chinese, the default error message I get is in big5 encoding (as know as CP950).
>>> try:
... os.remove('abc.file')
... except WindowsError, value:
... print value.args
...
(2, '\xa8t\xb2\xce\xa7\xe4\xa4\xa3\xa8\xec\xab\xfc\xa9w\xaa\xba\xc0\xc9\xae\xd7\xa1C')
>>>
As you see here, error message is not Unicode, then I will get another encoding exception when I try to print it out. Here is the issue, it can be found in Python issue list:
http://bugs.python.org/issue1754
The question is, how to workaround this? How to get the native encoding of WindowsError?
The version of Python I use is 2.6.
Thanks.
We have the same problem in Russian version of MS Windows: the code page of the default locale is cp1251, but the default code page of the Windows console is cp866:
>>> import sys
>>> print sys.stdout.encoding
cp866
>>> import locale
>>> print locale.getdefaultlocale()
('ru_RU', 'cp1251')
The solution should be to decode the Windows message with default locale encoding:
>>> try:
... os.remove('abc.file')
... except WindowsError, err:
... print err.args[1].decode(locale.getdefaultlocale()[1])
...
The bad news is that you still can't use exc_info=True in logging.error().
sys.getfilesystemencoding() should help.
import os, sys
try:
os.delete('nosuchfile.txt')
except WindowsError, ex:
enc = sys.getfilesystemencoding()
print (u"%s: %s" % (ex.strerror, ex.filename.decode(enc))).encode(enc)
For other purposes than printing to console you may want to change final encoding to 'utf-8'
That is just the repr() string of the same error message. Since your console already supports cp950, just print the component you want. This works on my system after reconfiguring to use cp950 in my console. I had to explicitly raise the error message since my system is English and not Chinese:
>>> try:
... raise WindowsError(2,'系統找不到指定的檔案。')
... except WindowsError, value:
... print value.args
...
(2, '\xa8t\xb2\xce\xa7\xe4\xa4\xa3\xa8\xec\xab\xfc\xa9w\xaa\xba\xc0\xc9\xae\xd7\xa1C')
>>> try:
... raise WindowsError(2,'系統找不到指定的檔案。')
... except WindowsError, value:
... print value.args[1]
...
系統找不到指定的檔案。
Alternatively, use Python 3.X. It prints repr() using the console encoding. Here's an example:
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> '系統找不到指定的檔案。'
'\xa8t\xb2\xce\xa7\xe4\xa4\xa3\xa8\xec\xab\xfc\xa9w\xaa\xba\xc0\xc9\xae\xd7\xa1C'
Python 3.1.2 (r312:79149, Mar 21 2010, 00:41:52) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> '系統找不到指定的檔案。'
'系統找不到指定的檔案。'

Why would traceback.extract_stack() return [] when there is definitely a call stack?

I have a class that calls
traceback.extract_stack()
in its __init__(), but whenever I do that, the value of traceback.extract_stack() is [].
What are some reasons that this could be the case?
Is there another way to get a traceback that will be more reliable?
I think the problem is that the code is running in Pylons. Here is some code for a controller action:
def test_tb(self):
import traceback
return a.lib.htmlencode(traceback.extract_stack())
It generates a webpage that is just
[]
So, I don't think it has anything to do with being in the constructor of an object or anything like that. Could it have to do with an incompatibility between some kinds of threading and the traceback module or something like that?
Following shows traceback.extract_stack() working when called from a class's __init__ method. Please post your code showing that it doesn't work. Include the Python version. Don't type from memory; use copy/paste as I have done.
Python 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import traceback as tb
>>> tb.extract_stack()
[('<stdin>', 1, '<module>', None)]
>>> def func():
... print tb.extract_stack()
...
>>> func()
[('<stdin>', 1, '<module>', None), ('<stdin>', 2, 'func', None)]
>>> class Klass(object):
... def __init__(self):
... print tb.extract_stack()
...
>>> k = Klass()
[('<stdin>', 1, '<module>', None), ('<stdin>', 3, '__init__', None)]
>>>
UPDATE Instead of looking at return a.lib.htmlencode(traceback.extract_stack()) and wondering, tap into the pipeline:
(1) do tb_stack = repr((traceback.extract_stack()) and write the result to your logfile for checking
(2) do return a.lib.htmlencode(some_known_constant_data) and check that the known data shows up correctly where you expect it to show up.
Looking at the code for the traceback module, one possibility is that you've got sys.tracebacklimit set to zero, though that seems like a longshot...
The reason turned out to be that someone turned on Pysco on the project, and Psyco doesn't play nice with the traceback module.

Categories