From 03f1ddc6657e93ed466858761c0ae62c6c64c072 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20Michael=20O=2E=20Hegg=C3=B8?= <danmichaelo@gmail.com>
Date: Sun, 16 Jun 2013 23:09:01 +0200
Subject: [PATCH] PEP8: Fix W291 trailing whitespace

---
 mwclient/__init__.py        |   4 +-
 mwclient/client.py          | 203 ++++++++++++++++++------------------
 mwclient/compatibility.py   |  26 +++--
 mwclient/errors.py          |   7 +-
 mwclient/ex.py              |  32 +++---
 mwclient/http.py            |  73 +++++++------
 mwclient/listing.py         |  61 ++++++-----
 mwclient/page.py            | 131 ++++++++++++-----------
 mwclient/page_nowriteapi.py |  45 ++++----
 mwclient/upload.py          |  42 ++++----
 10 files changed, 307 insertions(+), 317 deletions(-)

diff --git a/mwclient/__init__.py b/mwclient/__init__.py
index afc17bf..0289838 100644
--- a/mwclient/__init__.py
+++ b/mwclient/__init__.py
@@ -9,10 +9,10 @@
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:
- 
+
  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.
- 
+
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
diff --git a/mwclient/client.py b/mwclient/client.py
index 7df3f70..c1906af 100644
--- a/mwclient/client.py
+++ b/mwclient/client.py
@@ -29,7 +29,7 @@ def parse_timestamp(t):
     if t == '0000-00-00T00:00:00Z':
         return (0, 0, 0, 0, 0, 0, 0, 0)
     return time.strptime(t, '%Y-%m-%dT%H:%M:%SZ')
-    
+
 class WaitToken(object):
     def __init__(self):
         self.id = '%x' % random.randint(0, sys.maxint)
@@ -38,7 +38,7 @@ class WaitToken(object):
 
 class Site(object):
     api_limit = 500
-    def __init__(self, host, path='/w/', ext='.php', pool=None, retry_timeout=30, 
+    def __init__(self, host, path='/w/', ext='.php', pool=None, retry_timeout=30,
             max_retries=25, wait_callback=lambda *x: None, clients_useragent=None,
             max_lag=3, compress=True, force_login=True, do_init=True):
         # Setup member variables
@@ -47,16 +47,16 @@ class Site(object):
         self.ext = ext
         self.credentials = None
         self.compress = compress
-        
+
         self.retry_timeout = retry_timeout
         self.max_retries = max_retries
         self.wait_callback = wait_callback
         self.max_lag = str(max_lag)
         self.force_login = force_login
-                
+
         # The token string => token object mapping
         self.wait_tokens = weakref.WeakKeyDictionary()
-        
+
         # Site properties
         self.blocked = False    # Whether current user is blocked
         self.hasmsg = False # Whether current user has new messages
@@ -64,47 +64,47 @@ class Site(object):
         self.rights = []    # Rights current user has
         self.tokens = {}    # Edit tokens of the current user
         self.version = None
-        
+
         self.namespaces = self.default_namespaces
         self.writeapi = False
-            
+
         # Setup connection
         if pool is None:
             self.connection = http.HTTPPool(clients_useragent)
         else:
             self.connection = pool
-        
+
         # Page generators
         self.pages = listing.PageList(self)
         self.categories = listing.PageList(self, namespace=14)
         self.images = listing.PageList(self, namespace=6)
-        
+
         # Compat page generators
         self.Pages = self.pages
         self.Categories = self.categories
         self.Images = self.images
-        
+
         # Initialization status
         self.initialized = False
-        
+
         if do_init:
             try:
                 self.site_init()
             except errors.APIError, e:
                 # Private wiki, do init after login
-                if e[0] not in (u'unknown_action', u'readapidenied'): 
+                if e[0] not in (u'unknown_action', u'readapidenied'):
                     raise
-                
-            
+
+
     def site_init(self):
-        meta = self.api('query', meta='siteinfo|userinfo', 
+        meta = self.api('query', meta='siteinfo|userinfo',
             siprop='general|namespaces', uiprop='groups|rights')
-        
+
         # Extract site info
         self.site = meta['query']['general']
         self.namespaces = dict(((i['id'], i.get('*', '')) for i in meta['query']['namespaces'].itervalues()))
         self.writeapi = 'writeapi' in self.site
-        
+
         # Determine version
         if self.site['generator'].startswith('MediaWiki '):
             version = self.site['generator'][10:].split('.')
@@ -119,30 +119,30 @@ class Site(object):
                 else:
                     return (int(s[:i]), )
             self.version = sum((split_num(s) for s in version), ())
-            
+
             if len(self.version) < 2:
                 raise errors.MediaWikiVersionError('Unknown MediaWiki %s' % '.'.join(version))
         else:
             raise errors.MediaWikiVersionError('Unknown generator %s' % self.site['generator'])
         # Require 1.11 until some compatibility issues are fixed
         self.require(1, 11)
-        
-        # User info 
+
+        # User info
         userinfo = compatibility.userinfo(meta, self.require(1, 12, raise_error=False))
         self.username = userinfo['name']
         self.groups = userinfo.get('groups', [])
         self.rights = userinfo.get('rights', [])
         self.initialized = True
-        
-        
-    default_namespaces = {0: u'', 1: u'Talk', 2: u'User', 3: u'User talk', 4: u'Project', 5: u'Project talk', 
-        6: u'Image', 7: u'Image talk', 8: u'MediaWiki', 9: u'MediaWiki talk', 10: u'Template', 11: u'Template talk', 
+
+
+    default_namespaces = {0: u'', 1: u'Talk', 2: u'User', 3: u'User talk', 4: u'Project', 5: u'Project talk',
+        6: u'Image', 7: u'Image talk', 8: u'MediaWiki', 9: u'MediaWiki talk', 10: u'Template', 11: u'Template talk',
         12: u'Help', 13: u'Help talk', 14: u'Category', 15: u'Category talk', -1: u'Special', -2: u'Media'}
-        
+
     def __repr__(self):
         return "<Site object '%s%s'>" % (self.host, self.path)
-        
-    
+
+
     def api(self, action, *args, **kwargs):
         """ An API call. Handles errors and returns dict object. """
         kwargs.update(args)
@@ -155,7 +155,7 @@ class Site(object):
                 kwargs['uiprop'] += '|blockinfo|hasmsg'
             else:
                 kwargs['uiprop'] = 'blockinfo|hasmsg'
-            
+
         token = self.wait_token()
         while True:
             info = self.raw_api(action, **kwargs)
@@ -163,12 +163,12 @@ class Site(object):
             res = self.handle_api_result(info, token=token)
             if res:
                 return info
-                
-    
+
+
     def handle_api_result(self, info, kwargs=None, token=None):
         if token is None:
             token = self.wait_token()
-        
+
         try:
             userinfo = compatibility.userinfo(info, self.require(1, 12, raise_error=None))
         except KeyError:
@@ -189,7 +189,7 @@ class Site(object):
             raise errors.APIError(info['error']['code'],
                     info['error']['info'], kwargs)
         return True
-        
+
     @staticmethod
     def _to_str(data):
         if type(data) is unicode:
@@ -200,10 +200,10 @@ class Site(object):
         kwargs.update(args)
         qs = urllib.urlencode([(k, Site._to_str(v)) for k, v in kwargs.iteritems()
             if k != 'wpEditToken'])
-        if 'wpEditToken' in kwargs: 
+        if 'wpEditToken' in kwargs:
             qs += '&wpEditToken=' + urllib.quote(Site._to_str(kwargs['wpEditToken']))
         return qs
-        
+
     def raw_call(self, script, data):
         url = self.path + script + self.ext
         headers = {}
@@ -211,18 +211,18 @@ class Site(object):
             headers['Content-Type'] = 'application/x-www-form-urlencoded'
         if self.compress and gzip:
             headers['Accept-Encoding'] = 'gzip'
-        
+
         token = self.wait_token((script, data))
         while True:
             try:
-                stream = self.connection.post(self.host, 
+                stream = self.connection.post(self.host,
                     url, data=data, headers=headers)
                 if stream.getheader('Content-Encoding') == 'gzip':
                     # BAD.
                     seekable_stream = StringIO(stream.read())
                     stream = gzip.GzipFile(fileobj=seekable_stream)
                 return stream
-                
+
             except errors.HTTPStatusError, e:
                 if e[0] == 503 and e[1].getheader('X-Database-Lag'):
                     self.wait(token, int(e[1].getheader('Retry-After')))
@@ -236,7 +236,7 @@ class Site(object):
                 self.wait(token)
             except ValueError:
                 self.wait(token)
-                
+
     def raw_api(self, action, *args, **kwargs):
         """Sends a call to the API."""
         kwargs['action'] = action
@@ -249,14 +249,14 @@ class Site(object):
             if json_data.startswith('MediaWiki API is not enabled for this site.'):
                 raise errors.APIDisabledError
             raise
-                
+
     def raw_index(self, action, *args, **kwargs):
         """Sends a call to index.php rather than the API."""
         kwargs['action'] = action
         kwargs['maxlag'] = self.max_lag
         data = self._query_string(*args, **kwargs)
-        return self.raw_call('index', data).read().decode('utf-8', 'ignore')            
-                
+        return self.raw_call('index', data).read().decode('utf-8', 'ignore')
+
     def wait_token(self, args=None):
         token = WaitToken()
         self.wait_tokens[token] = (0, args)
@@ -268,7 +268,7 @@ class Site(object):
         if retry > self.max_retries and self.max_retries != -1:
             raise errors.MaximumRetriesExceeded(self, token, args)
         self.wait_callback(self, token, retry, args)
-        
+
         timeout = self.retry_timeout * retry
         if timeout < min_wait: timeout = min_wait
         time.sleep(timeout)
@@ -276,20 +276,20 @@ class Site(object):
 
     def require(self, major, minor, revision=None, raise_error=True):
         if self.version is None:
-            if raise_error is None: return 
+            if raise_error is None: return
             raise RuntimeError('Site %s has not yet been initialized' % repr(self))
-        
+
         if revision is None:
             if self.version[:2] >= (major, minor):
                 return True
             elif raise_error:
-                raise errors.MediaWikiVersionError('Requires version %s.%s, current version is %s.%s' 
+                raise errors.MediaWikiVersionError('Requires version %s.%s, current version is %s.%s'
                     % ((major, minor) + self.version[:2]))
             else:
                 return False
         else:
             raise NotImplementedError
-        
+
 
     # Actions
     def email(self, user, text, subject, cc=False):
@@ -314,14 +314,14 @@ class Site(object):
     def login(self, username=None, password=None, cookies=None, domain=None):
         """Login to the wiki."""
         if self.initialized: self.require(1, 10)
-        
-        if username and password: 
+
+        if username and password:
             self.credentials = (username, password, domain)
         if cookies:
             if self.host not in self.conn.cookies:
                 self.conn.cookies[self.host] = http.CookieJar()
             self.conn.cookies[self.host].update(cookies)
-            
+
         if self.credentials:
             wait_token = self.wait_token()
             kwargs = {
@@ -340,8 +340,8 @@ class Site(object):
                     self.wait(wait_token, login['login'].get('wait', 5))
                 else:
                     raise errors.LoginError(self, login['login'])
-                
-        if self.initialized:                
+
+        if self.initialized:
             info = self.api('query', meta='userinfo', uiprop='groups|rights')
             userinfo = compatibility.userinfo(info, self.require(1, 12, raise_error=False))
             self.username = userinfo['name']
@@ -356,25 +356,25 @@ class Site(object):
             url=None, session_key=None, comment=None):
         """Upload a file to the wiki."""
         if self.version[:2] < (1, 16):
-            return compatibility.old_upload(self, file=file, filename=filename, 
-                        description=description, ignore=ignore, 
+            return compatibility.old_upload(self, file=file, filename=filename,
+                        description=description, ignore=ignore,
                         file_size=file_size)
-        
+
         image = self.Images[filename]
         if not image.can('upload'):
             raise errors.InsufficientPermission(filename)
-        
 
-        
+
+
         predata = {}
-        
+
         if comment is None:
             predata['comment'] = description
         else:
             predata['comment'] = comment
             predata['text'] = description
 
-        if ignore: 
+        if ignore:
             predata['ignorewarnings'] = 'true'
         predata['token'] = image.get_token('edit')
         predata['action'] = 'upload'
@@ -383,11 +383,11 @@ class Site(object):
         if url:
             predata['url'] = url
         if session_key:
-            predata['session_key'] = session_key 
-        
+            predata['session_key'] = session_key
+
         if file is None:
             postdata = self._query_string(predata)
-        else:           
+        else:
             if type(file) is str:
                 file_size = len(file)
                 file = StringIO(file)
@@ -395,9 +395,9 @@ class Site(object):
                 file.seek(0, 2)
                 file_size = file.tell()
                 file.seek(0, 0)
-                
+
             postdata = upload.UploadFile('file', filename, file_size, file, predata)
-        
+
         wait_token = self.wait_token()
         while True:
             try:
@@ -417,7 +417,7 @@ class Site(object):
             except errors.HTTPError:
                 self.wait(wait_token)
             file.seek(0, 0)
-            
+
     def parse(self, text=None, title=None, page=None):
         kwargs = {}
         if text is not None: kwargs['text'] = text
@@ -425,23 +425,23 @@ class Site(object):
         if page is not None: kwargs['page'] = page
         result = self.api('parse', **kwargs)
         return result['parse']
-    
+
     # def block: requires 1.12
     # def unblock: requires 1.12
     # def patrol: requires 1.14
     # def import: requires 1.15
-            
+
     # Lists
     def allpages(self, start=None, prefix=None, namespace='0', filterredir='all',
             minsize=None, maxsize=None, prtype=None, prlevel=None,
             limit=None, dir='ascending', filterlanglinks='all', generator=True):
         """Retrieve all pages on the wiki as a generator."""
         self.require(1, 9)
-        
+
         pfx = listing.List.get_prefix('ap', generator)
         kwargs = dict(listing.List.generate_kwargs(pfx, ('from', start), prefix=prefix,
             minsize=minsize, maxsize=maxsize, prtype=prtype, prlevel=prlevel,
-            namespace=namespace, filterredir=filterredir, dir=dir, 
+            namespace=namespace, filterredir=filterredir, dir=dir,
             filterlanglinks=filterlanglinks))
         return listing.List.get_list(generator)(self, 'allpages', 'ap', limit=limit, return_values='title', **kwargs)
     # def allimages(self): requires 1.12
@@ -451,7 +451,7 @@ class Site(object):
             namespace='0', limit=None, generator=True):
         """Retrieve a list of all links on the wiki as a generator."""
         self.require(1, 11)
-            
+
         pfx = listing.List.get_prefix('al', generator)
         kwargs = dict(listing.List.generate_kwargs(pfx, ('from', start), prefix=prefix,
             prop=prop, namespace=namespace))
@@ -461,20 +461,20 @@ class Site(object):
     def allcategories(self, start=None, prefix=None, dir='ascending', limit=None, generator=True):
         """Retrieve all categories on the wiki as a generator."""
         self.require(1, 12)
-        
+
         pfx = listing.List.get_prefix('ac', generator)
         kwargs = dict(listing.List.generate_kwargs(pfx, ('from', start), prefix=prefix, dir=dir))
         return listing.List.get_list(generator)(self, 'allcategories', 'ac', limit=limit, **kwargs)
-    
+
     def allusers(self, start=None, prefix=None, group=None, prop=None, limit=None):
         """Retrieve all users on the wiki as a generator."""
         self.require(1, 11)
-        
+
         kwargs = dict(listing.List.generate_kwargs('au', ('from', start), prefix=prefix,
             group=group, prop=prop))
         return listing.List(self, 'allusers', 'au', limit=limit, **kwargs)
 
-    def blocks(self, start=None, end=None, dir='older', ids=None, users=None, limit=None, 
+    def blocks(self, start=None, end=None, dir='older', ids=None, users=None, limit=None,
             prop='id|user|by|timestamp|expiry|reason|flags'):
         """Retrieve blocks as a generator.
 
@@ -487,20 +487,20 @@ class Site(object):
         - allowusertalk: key is present (empty string) if the user is allowed to edit their user talk page
         - by: the administrator who blocked the user
         - nocreate: key is present (empty string) if the user's ability to create accounts has been disabled.
-        
+
         """
 
         self.require(1, 12)
         # TODO: Fix. Fix what?
-        kwargs = dict(listing.List.generate_kwargs('bk', start=start, end=end, dir=dir, 
+        kwargs = dict(listing.List.generate_kwargs('bk', start=start, end=end, dir=dir,
             users=users, prop=prop))
         return listing.List(self, 'blocks', 'bk', limit=limit, **kwargs)
 
-    def deletedrevisions(self, start=None, end=None, dir='older', namespace=None, 
+    def deletedrevisions(self, start=None, end=None, dir='older', namespace=None,
             limit=None, prop='user|comment'):
         # TODO: Fix
         self.require(1, 12)
-        
+
         kwargs = dict(listing.List.generate_kwargs('dr', start=start, end=end, dir=dir,
             namespace=namespace, prop=prop))
         return listing.List(self, 'deletedrevs', 'dr', limit=limit, **kwargs)
@@ -521,18 +521,18 @@ class Site(object):
         - ns: namespace of the wiki page
         - pageid: the ID of the wiki page
         - title: the page title.
-        
+
         """
         self.require(1, 11)
-        
-        kwargs = dict(listing.List.generate_kwargs('eu', query=query, prop=prop, 
+
+        kwargs = dict(listing.List.generate_kwargs('eu', query=query, prop=prop,
             protocol=protocol, namespace=namespace))
-        return listing.List(self, 'exturlusage', 'eu', limit=limit, **kwargs) 
+        return listing.List(self, 'exturlusage', 'eu', limit=limit, **kwargs)
 
-    def logevents(self, type=None, prop=None, start=None, end=None, 
+    def logevents(self, type=None, prop=None, start=None, end=None,
             dir='older', user=None, title=None, limit=None, action=None):
         self.require(1, 10)
-        
+
         kwargs = dict(listing.List.generate_kwargs('le', prop=prop, type=type, start=start,
             end=end, dir=dir, user=user, title=title, action=action))
         return listing.List(self, 'logevents', 'le', limit=limit, **kwargs)
@@ -540,67 +540,66 @@ class Site(object):
     # def protectedtitles requires 1.15
     def random(self, namespace, limit=20):
         """Retrieves a generator of random page from a particular namespace.
-        
+
         limit specifies the number of random articles retrieved.
         namespace is a namespace identifier integer.
-        
+
         Generator contains dictionary with namespace, page ID and title.
-        
+
         """
         self.require(1, 12)
-        
+
         kwargs = dict(listing.List.generate_kwargs('rn', namespace=namespace))
         return listing.List(self, 'random', 'rn', limit=limit, **kwargs)
 
-    def recentchanges(self, start=None, end=None, dir='older', namespace=None, 
+    def recentchanges(self, start=None, end=None, dir='older', namespace=None,
                 prop=None, show=None, limit=None, type=None):
         self.require(1, 9)
-        
+
         kwargs = dict(listing.List.generate_kwargs('rc', start=start, end=end, dir=dir,
             namespace=namespace, prop=prop, show=show, type=type))
         return listing.List(self, 'recentchanges', 'rc', limit=limit, **kwargs)
 
     def search(self, search, namespace='0', what='title', redirects=False, limit=None):
         self.require(1, 11)
-        
+
         kwargs = dict(listing.List.generate_kwargs('sr', search=search, namespace=namespace, what=what))
         if redirects: kwargs['srredirects'] = '1'
         return listing.List(self, 'search', 'sr', limit=limit, **kwargs)
 
-    def usercontributions(self, user, start=None, end=None, dir='older', namespace=None, 
+    def usercontributions(self, user, start=None, end=None, dir='older', namespace=None,
             prop=None, show=None, limit=None):
         self.require(1, 9)
-        
-        kwargs = dict(listing.List.generate_kwargs('uc', user=user, start=start, end=end, 
+
+        kwargs = dict(listing.List.generate_kwargs('uc', user=user, start=start, end=end,
             dir=dir, namespace=namespace, prop=prop, show=show))
         return listing.List(self, 'usercontribs', 'uc', limit=limit, **kwargs)
 
     def users(self, users, prop='blockinfo|groups|editcount'):
         self.require(1, 12)
-        
+
         return listing.List(self, 'users', 'us', ususers='|'.join(users), usprop=prop)
-        
+
     def watchlist(self, allrev=False, start=None, end=None, namespace=None, dir='older',
             prop=None, show=None, limit=None):
         self.require(1, 9)
-        
-        kwargs = dict(listing.List.generate_kwargs('wl', start=start, end=end, 
+
+        kwargs = dict(listing.List.generate_kwargs('wl', start=start, end=end,
             namespace=namespace, dir=dir, prop=prop, show=show))
         if allrev: kwargs['wlallrev'] = '1'
         return listing.List(self, 'watchlist', 'wl', limit=limit, **kwargs)
-        
+
     def expandtemplates(self, text, title=None, generatexml=False):
         """Takes wikitext (text) and expands templates."""
         self.require(1, 11)
-        
+
         kwargs = {}
         if title is None: kwargs['title'] = title
         if generatexml: kwargs['generatexml'] = '1'
-        
+
         result = self.api('expandtemplates', text=text, **kwargs)
-        
+
         if generatexml:
             return result['expandtemplates']['*'], result['parsetree']['*']
         else:
             return result['expandtemplates']['*']
-        
diff --git a/mwclient/compatibility.py b/mwclient/compatibility.py
index 65b5b3e..f2d8794 100644
--- a/mwclient/compatibility.py
+++ b/mwclient/compatibility.py
@@ -1,19 +1,19 @@
 import upload, errors
 
 def title(prefix, new_format):
-    if new_format: 
+    if new_format:
         return prefix + 'title'
     else:
         return 'titles'
-        
+
 def userinfo(data, new_format=None):
     if new_format is None:
         # Unknown version; trying to guess
-        if 'userinfo' in data: 
+        if 'userinfo' in data:
             return data['userinfo']
         elif 'userinfo' in data.get('query', ()):
             return data['query']['userinfo']
-        else: 
+        else:
             return {}
     elif new_format:
         return data['query']['userinfo']
@@ -27,13 +27,13 @@ def iiprop(version):
         return 'timestamp|user|comment|url|size|sha1|metadata'
     else:
         return 'timestamp|user|comment|url|size|sha1'
-        
+
 def cmtitle(page, new_format, prefix=''):
     if new_format:
         return prefix + 'title', page.name
     else:
         return prefix + 'category', page.strip_namespace(page.name)
-        
+
 def protectright(version):
     if version[:2] >= (1, 13):
         return 'editprotected'
@@ -41,13 +41,13 @@ def protectright(version):
         return 'protect'
 
 from cStringIO import StringIO
-def old_upload(self, file, filename, description, license='', ignore=False, file_size=None): 
+def old_upload(self, file, filename, description, license='', ignore=False, file_size=None):
     image = self.Images[filename]
     if not image.can('upload'):
         raise errors.InsufficientPermission(filename)
     if image.exists and not ignore:
         raise errors.FileExists(filename)
-        
+
     if type(file) is str:
         file_size = len(file)
         file = StringIO(file)
@@ -55,7 +55,7 @@ def old_upload(self, file, filename, description, license='', ignore=False, file
         file.seek(0, 2)
         file_size = file.tell()
         file.seek(0, 0)
-            
+
     predata = {}
     # Do this thing later so that an incomplete upload won't work
     # predata['wpDestFile'] = filename
@@ -66,14 +66,14 @@ def old_upload(self, file, filename, description, license='', ignore=False, file
     predata['wpSourceType'] = 'file'
     predata['wpDestFile'] = filename
     predata['wpEditToken'] = image.get_token('edit')
-        
+
     postdata = upload.UploadFile('wpUploadFile', filename, file_size, file, predata)
-        
+
     wait_token = self.wait_token()
     while True:
         try:
             self.connection.post(self.host,
-                    self.path + 'index.php?title=Special:Upload&maxlag=' 
+                    self.path + 'index.php?title=Special:Upload&maxlag='
                     + self.max_lag, data=postdata).read()
         except errors.HTTPStatusError, e:
             if e[0] == 503 and e[1].getheader('X-Database-Lag'):
@@ -87,5 +87,3 @@ def old_upload(self, file, filename, description, license='', ignore=False, file
         else:
             return
         file.seek(0, 0)
-
-            
\ No newline at end of file
diff --git a/mwclient/errors.py b/mwclient/errors.py
index 59e1b44..0a17132 100644
--- a/mwclient/errors.py
+++ b/mwclient/errors.py
@@ -16,13 +16,13 @@ class HTTPRedirectError(HTTPError):
 
 class MaximumRetriesExceeded(MwClientError):
     pass
-    
+
 class APIError(MwClientError):
     def __init__(self, code, info, kwargs):
         self.code = code
         self.info = info
         MwClientError.__init__(self, code, info, kwargs)
-    
+
 class InsufficientPermission(MwClientError):
     pass
 class UserBlocked(InsufficientPermission):
@@ -34,7 +34,7 @@ class ProtectedPageError(EditError, InsufficientPermission):
     pass
 class FileExists(EditError):
     pass
-    
+
 
 class LoginError(MwClientError):
     pass
@@ -43,4 +43,3 @@ class EmailError(MwClientError):
     pass
 class NoSpecifiedEmail(EmailError):
     pass
-    
diff --git a/mwclient/ex.py b/mwclient/ex.py
index 730fd05..2e0f239 100644
--- a/mwclient/ex.py
+++ b/mwclient/ex.py
@@ -6,12 +6,12 @@ def read_config(config_files, **predata):
         cfg.update(_read_config_file(
             config_file, predata))
     return cfg
-    
+
 def _read_config_file(_config_file, predata):
     _file = open(_config_file)
     exec _file in globals(), predata
     _file.close()
-    
+
     for _k, _v in predata.iteritems():
         if not _k.startswith('_'):
             yield _k, _v
@@ -32,39 +32,39 @@ class SiteList(object):
 class ConfiguredSite(client.Site):
     def __init__(self, *config_files, **kwargs):
         self.config = read_config(config_files, sites=SiteList())
-        
+
         if 'name' in kwargs:
             self.config.update(self.config['sites'][kwargs['name']])
-        
+
         do_login = 'username' in self.config and 'password' in self.config
-        
+
         client.Site.__init__(self, host=self.config['host'],
-            path=self.config['path'], ext=self.config.get('ext', '.php'), 
+            path=self.config['path'], ext=self.config.get('ext', '.php'),
             do_init=not do_login,
-            retry_timeout =self.config.get('retry_timeout', 30),
+            retry_timeout=self.config.get('retry_timeout', 30),
             max_retries=self.config.get('max_retries', -1))
-            
-            
+
+
         if do_login:
             self.login(self.config['username'],
                 self.config['password'])
-    
+
 class ConfiguredPool(list):
     def __init__(self, *config_files):
         self.config = read_config(config_files, sites=SiteList())
         self.pool = http.HTTPPool()
-        
+
         config = dict([(k, v) for k, v in self.config.iteritems()
             if k != 'sites'])
-        
+
         for site in self.config['sites']:
             cfg = config.copy()
             cfg.update(site)
             site.update(cfg)
-            
+
             do_login = 'username' in site and 'password' in site
-                    
-            self.append(client.Site(host=site['host'], 
+
+            self.append(client.Site(host=site['host'],
                 path=site['path'], ext=site.get('ext', '.php'),
                 pool=self.pool, do_init=not do_login,
                 retry_timeout=site.get('retry_timeout', 30),
@@ -72,5 +72,3 @@ class ConfiguredPool(list):
             if do_login:
                 self[-1].login(site['username'], site['password'])
             self[-1].config = site
-            
-
diff --git a/mwclient/http.py b/mwclient/http.py
index daafa70..7fb3d54 100644
--- a/mwclient/http.py
+++ b/mwclient/http.py
@@ -22,27 +22,27 @@ class CookieJar(dict):
         if not cookie: return
         value, attrs = cookie.split(': ', 1)[1].split(';', 1)
         i = value.strip().split('=')
-        if len(i) == 1 and i[0] in self: 
+        if len(i) == 1 and i[0] in self:
             del self[i[0]]
         else:
             self[i[0]] = i[1]
-        
+
     def get_cookie_header(self):
         return '; '.join(('%s=%s' % i for i in self.iteritems()))
     def __iter__(self):
         for k, v in self.iteritems():
             yield Cookie(k, v)
-        
+
 class Cookie(object):
     def __init__(self, name, value):
         self.name = name
         self.value = value
-        
+
 class HTTPPersistentConnection(object):
     http_class = httplib.HTTPConnection
     scheme_name = 'http'
     useragent = None
-    
+
     def __init__(self, host, pool=None, clients_useragent=None):
         self._conn = self.http_class(host)
         self._conn.connect()
@@ -55,35 +55,35 @@ class HTTPPersistentConnection(object):
         clients_useragent = clients_useragent or ""
         if clients_useragent != "": clients_useragent += " "
         self.useragent = clients_useragent + 'MwClient/' + __ver__
-        
+
     def request(self, method, host, path, headers, data,
-            raise_on_not_ok=True, auto_redirect=True):      
-        
+            raise_on_not_ok=True, auto_redirect=True):
+
         # Strip scheme
         if type(host) is tuple:
             host = host[1]
-            
+
         # Dirty hack...
         if (time.time() - self.last_request) > 60:
             self._conn.close()
-            self._conn.connect()            
-        
+            self._conn.connect()
+
         _headers = headers
         headers = {}
-        
+
         headers['Connection'] = 'Keep-Alive'
         headers['User-Agent'] = self.useragent
         headers['Host'] = host
-        if host in self.cookies: 
+        if host in self.cookies:
             headers['Cookie'] = self.cookies[host].get_cookie_header()
         if issubclass(data.__class__, upload.Upload):
             headers['Content-Type'] = data.content_type
             headers['Content-Length'] = str(data.length)
         elif data:
             headers['Content-Length'] = str(len(data))
-            
+
         if _headers: headers.update(_headers)
-        
+
         try:
             self._conn.request(method, path, headers=headers)
             if issubclass(data.__class__, upload.Upload):
@@ -91,7 +91,7 @@ class HTTPPersistentConnection(object):
                     self._conn.send(s)
             elif data:
                 self._conn.send(data)
-            
+
             self.last_request = time.time()
             try:
                 res = self._conn.getresponse()
@@ -105,13 +105,13 @@ class HTTPPersistentConnection(object):
             raise errors.HTTPError, e
         #except Exception, e:
         #   raise errors.HTTPError, e
-                
+
         if not host in self.cookies: self.cookies[host] = CookieJar()
         self.cookies[host].extract_cookies(res)
-        
+
         if res.status >= 300 and res.status <= 399 and auto_redirect:
             res.read()
-            
+
             location = urlparse.urlparse(res.getheader('Location'))
             if res.status in (302, 303):
                 if 'Content-Type' in headers:
@@ -123,14 +123,14 @@ class HTTPPersistentConnection(object):
             old_path = path
             path = location[2]
             if location[4]: path = path + '?' + location[4]
-            
+
             if location[0].lower() != self.scheme_name:
                 raise errors.HTTPRedirectError, ('Only HTTP connections are supported',
                     res.getheader('Location'))
-            
+
             if self.pool is None:
-                if location[1] != host: 
-                    raise errors.HTTPRedirectError, ('Redirecting to different hosts not supported', 
+                if location[1] != host:
+                    raise errors.HTTPRedirectError, ('Redirecting to different hosts not supported',
                         res.getheader('Location'))
 
                 return self.request(method, host, path, headers, data)
@@ -138,28 +138,28 @@ class HTTPPersistentConnection(object):
                 if host == location[1] and path == old_path:
                     conn = self.__class__(location[1], self.pool)
                     self.pool.append(([location[1]], conn))
-                return self.pool.request(method, location[1], path, 
+                return self.pool.request(method, location[1], path,
                     headers, data, raise_on_not_ok, auto_redirect)
-            
+
         if res.status != 200 and raise_on_not_ok:
             try:
                 raise errors.HTTPStatusError, (res.status, res)
             finally:
                 res.close()
-            
+
         return res
-        
+
     def get(self, host, path, headers=None):
         return self.request('GET', host, path, headers, None)
     def post(self, host, path, headers=None, data=None):
         return self.request('POST', host, path, headers, data)
     def head(self, host, path, headers=None, auto_redirect=False):
-        res = self.request('HEAD', host, path, headers, 
+        res = self.request('HEAD', host, path, headers,
             data=None, raise_on_not_ok=False,
             auto_redirect=auto_redirect)
         res.read()
         return res.status, res.getheaders()
-        
+
     def close(self):
         self._conn.close()
     def fileno(self):
@@ -170,7 +170,7 @@ class HTTPConnection(HTTPPersistentConnection):
             raise_on_not_ok=True, auto_redirect=True):
         if not headers: headers = {}
         headers['Connection'] = 'Close'
-        res = HTTPPersistentConnection.request(self, method, host, path, headers, data, 
+        res = HTTPPersistentConnection.request(self, method, host, path, headers, data,
             raise_on_not_ok, auto_redirect)
         return res
 
@@ -178,7 +178,7 @@ class HTTPSPersistentConnection(HTTPPersistentConnection):
     http_class = httplib.HTTPSConnection
     scheme_name = 'https'
 
-    
+
 class HTTPPool(list):
     def __init__(self, clients_useragent=None):
         list.__init__(self)
@@ -188,10 +188,10 @@ class HTTPPool(list):
     def find_connection(self, host, scheme='http'):
         if type(host) is tuple:
             scheme, host = host
-            
+
         for hosts, conn in self:
             if (scheme, host) in hosts: return conn
-        
+
         redirected_host = None
         for hosts, conn in self:
             status, headers = conn.head(host, '/')
@@ -215,13 +215,13 @@ class HTTPPool(list):
         self.append(([(scheme, host)], conn))
         return conn
     def get(self, host, path, headers=None):
-        return self.find_connection(host).get(host, 
+        return self.find_connection(host).get(host,
             path, headers)
     def post(self, host, path, headers=None, data=None):
-        return self.find_connection(host).post(host, 
+        return self.find_connection(host).post(host,
             path, headers, data)
     def head(self, host, path, headers=None, auto_redirect=False):
-        return self.find_connection(host).head(host, 
+        return self.find_connection(host).head(host,
             path, headers, auto_redirect)
     def request(self, method, host, path, headers, data,
             raise_on_not_ok, auto_redirect):
@@ -230,4 +230,3 @@ class HTTPPool(list):
     def close(self):
         for hosts, conn in self:
             conn.close()
-            
diff --git a/mwclient/listing.py b/mwclient/listing.py
index 4ae49c4..152c89d 100644
--- a/mwclient/listing.py
+++ b/mwclient/listing.py
@@ -8,25 +8,25 @@ class List(object):
         self.list_name = list_name
         self.generator = 'list'
         self.prefix = prefix
-        
+
         kwargs.update(args)
         self.args = kwargs
-        
+
         if limit is None: limit = site.api_limit
         self.args[self.prefix + 'limit'] = str(limit)
-        
+
         self.count = 0
         self.max_items = max_items
-        
+
         self._iter = iter(xrange(0))
-        
+
         self.last = False
         self.result_member = list_name
         self.return_values = return_values
-        
+
     def __iter__(self):
         return self
-        
+
     def next(self, full=False):
         if self.max_items is not None:
             if self.count >= self.max_items:
@@ -37,26 +37,26 @@ class List(object):
             if 'timestamp' in item:
                 item['timestamp'] = client.parse_timestamp(item['timestamp'])
             if full: return item
-                
+
             if type(self.return_values) is tuple:
                 return tuple((item[i] for i in self.return_values))
             elif self.return_values is None:
                 return item
             else:
                 return item[self.return_values]
-            
+
         except StopIteration:
             if self.last: raise StopIteration
             self.load_chunk()
             return List.next(self, full=full)
-            
+
     def load_chunk(self):
         data = self.site.api('query', (self.generator, self.list_name), *[(str(k), v) for k, v in self.args.iteritems()])
         if not data:
             # Non existent page
             raise StopIteration
         self.set_iter(data)
-        
+
         if self.list_name in data.get('query-continue', ()):
             self.args.update(data['query-continue'][self.list_name])
         else:
@@ -69,12 +69,12 @@ class List(object):
             self._iter = iter(data['query'][self.result_member])
         else:
             self._iter = data['query'][self.result_member].itervalues()
-                
-        
+
+
     def __repr__(self):
         return "<List object '%s' for %s>" % (self.list_name, self.site)
 
-    @staticmethod 
+    @staticmethod
     def generate_kwargs(_prefix, *args, **kwargs):
         kwargs.update(args)
         for key, value in kwargs.iteritems():
@@ -99,18 +99,18 @@ class List(object):
 class GeneratorList(List):
     def __init__(self, site, list_name, prefix, *args, **kwargs):
         List.__init__(self, site, list_name, prefix, *args, **kwargs)
-        
+
         self.args['g' + self.prefix + 'limit'] = self.args[self.prefix + 'limit']
         del self.args[self.prefix + 'limit']
         self.generator = 'generator'
-        
+
         self.args['prop'] = 'info|imageinfo'
         self.args['inprop'] = 'protection'
-        
+
         self.result_member = 'pages'
-        
+
         self.page_class = page.Page
-        
+
     def next(self):
         info = List.next(self, full=True)
         if info['ns'] == 14:
@@ -118,14 +118,14 @@ class GeneratorList(List):
         if info['ns'] == 6:
             return page.Image(self.site, u'', info)
         return page.Page(self.site, u'', info)
-        
+
     def load_chunk(self):
-        # Put this here so that the constructor does not fail 
+        # Put this here so that the constructor does not fail
         # on uninitialized sites
         self.args['iiprop'] = compatibility.iiprop(self.site.version)
         return List.load_chunk(self)
-        
-    
+
+
 class Category(page.Page, GeneratorList):
     def __init__(self, site, name, info=None, namespace=None):
         page.Page.__init__(self, site, name, info)
@@ -138,22 +138,22 @@ class Category(page.Page, GeneratorList):
     def __repr__(self):
         return "<Category object '%s' for %s>" % (self.name.encode('utf-8'), self.site)
 
-    def members(self, prop='ids|title', namespace=None, sort='sortkey', 
+    def members(self, prop='ids|title', namespace=None, sort='sortkey',
             dir='asc', start=None, end=None, generator=True):
         prefix = self.get_prefix('cm', generator)
         kwargs = dict(self.generate_kwargs(prefix, prop=prop, namespace=namespace,
             sort=sort, dir=dir, start=start, end=end, *(compatibility.cmtitle(
             self, self.site.require(1, 12, raise_error=False)), )))
         return self.get_list(generator)(self.site, 'categorymembers', 'cm', **kwargs)
-        
+
 class PageList(GeneratorList):
     def __init__(self, site, prefix=None, start=None, namespace=0, redirects='all'):
         self.namespace = namespace
-        
+
         kwargs = {}
         if prefix: kwargs['apprefix'] = prefix
         if start: kwargs['apfrom'] = start
-            
+
         GeneratorList.__init__(self, site, 'allpages', 'ap',
             apnamespace=str(namespace), apfilterredir=redirects, **kwargs)
 
@@ -176,7 +176,7 @@ class PageList(GeneratorList):
                 elif namespace == 6:
                     return page.Image(self.site, name, info)
             return page.Page(self.site, name, info)
-        
+
     def guess_namespace(self, name):
         normal_name = page.Page.normalize_title(name)
         for ns in self.site.namespaces:
@@ -188,7 +188,7 @@ class PageList(GeneratorList):
                     return ns
         return 0
 
-        
+
 class PageProperty(List):
     def __init__(self, page, prop, prefix, *args, **kwargs):
         List.__init__(self, page.site, prop, prefix, titles=page.name, *args, **kwargs)
@@ -202,7 +202,7 @@ class PageProperty(List):
                 return
         raise StopIteration
 
-        
+
 class PagePropertyGenerator(GeneratorList):
     def __init__(self, page, prop, prefix, *args, **kwargs):
         GeneratorList.__init__(self, page.site, prop, prefix, titles=page.name, *args, **kwargs)
@@ -213,4 +213,3 @@ class RevisionsIterator(PageProperty):
         if 'rvstartid' in self.args and 'rvstart' in self.args:
             del self.args['rvstart']
         return PageProperty.load_chunk(self)
-    
diff --git a/mwclient/page.py b/mwclient/page.py
index fee2542..7ec1773 100644
--- a/mwclient/page.py
+++ b/mwclient/page.py
@@ -3,7 +3,7 @@ import compatibility
 from page_nowriteapi import OldPage
 
 import urllib, urlparse, time
-    
+
 class Page(object):
     def __init__(self, site, name, info=None, extra_properties={}):
         if type(name) is type(self):
@@ -11,25 +11,25 @@ class Page(object):
         self.site = site
         self.name = name
         self.section = None
-        
+
         if not info:
             if extra_properties:
                 prop = 'info|' + '|'.join(extra_properties.iterkeys())
                 extra_props = []
-                [extra_props.extend(extra_prop) for extra_prop in extra_properties.itervalues()]                    
+                [extra_props.extend(extra_prop) for extra_prop in extra_properties.itervalues()]
             else:
                 prop = 'info'
                 extra_props = ()
-            
+
             if type(name) is int:
-                info = self.site.api('query', prop=prop, pageids=name, 
+                info = self.site.api('query', prop=prop, pageids=name,
                     inprop='protection', *extra_props)
             else:
-                info = self.site.api('query', prop=prop, titles=name, 
+                info = self.site.api('query', prop=prop, titles=name,
                     inprop='protection', *extra_props)
             info = info['query']['pages'].itervalues().next()
         self._info = info
-                
+
         self.namespace = info.get('ns', 0)
         self.name = info.get('title', u'')
         if self.namespace:
@@ -43,7 +43,7 @@ class Page(object):
         self.length = info.get('length')
         self.protection = dict([(i['type'], (i['level'], i['expiry'])) for i in info.get('protection', ()) if i])
         self.redirect = 'redirect' in info
-        
+
         self.last_rev_time = None
         self.edit_time = None
 
@@ -60,7 +60,7 @@ class Page(object):
 
     def resolve_redirect(self):
         """ Returns the redirect target page, or the current page if it's not a redirect page."""
-        target_page = self.redirects_to() 
+        target_page = self.redirects_to()
         if target_page == None:
             return self
         else:
@@ -71,7 +71,7 @@ class Page(object):
 
     def __unicode__(self):
         return self.name
-        
+
     @staticmethod
     def strip_namespace(title):
         if title[0] == ':':
@@ -81,23 +81,23 @@ class Page(object):
     @staticmethod
     def normalize_title(title):
         # TODO: Make site dependent
-        title = title.strip()       
+        title = title.strip()
         if title[0] == ':':
             title = title[1:]
         title = title[0].upper() + title[1:]
         title = title.replace(' ', '_')
         return title
 
-        
+
     def can(self, action):
         level = self.protection.get(action, (action, ))[0]
         if level == 'sysop': level = compatibility.protectright(self.site.version)
-        
+
         return level in self.site.rights
-        
+
     def get_token(self, type, force=False):
         self.site.require(1, 11)
-        
+
         if type not in self.site.tokens:
             self.site.tokens[type] = '0'
         if self.site.tokens.get(type, '0') == '0' or force:
@@ -107,27 +107,27 @@ class Page(object):
                 if i['title'] == self.name:
                     self.site.tokens[type] = i['%stoken' % type]
         return self.site.tokens[type]
-                    
+
     def get_expanded(self):
         self.site.require(1, 12)
-        
+
         revs = self.revisions(prop='content', limit=1, expandtemplates=True)
         try:
             return revs.next()['*']
         except StopIteration:
             return u''
-            
+
     def edit(self, section=None, readonly=False):
         """Returns wikitext for a specified section or for the whole page.
-        
+
         Retrieves the latest edit.
-        
+
         """
         if not self.can('read'):
             raise errors.InsufficientPermission(self)
         if not self.exists:
             return u''
-            
+
         revs = self.revisions(prop='content|timestamp', limit=1, section=section)
         try:
             rev = revs.next()
@@ -140,7 +140,7 @@ class Page(object):
             self.edit_time = None
         self.edit_time = time.gmtime()
         return self.text
-    
+
     def save(self, text=u'', summary=u'', minor=False, bot=True, section=None, **kwargs):
         """Save text of page."""
         if not self.site.logged_in and self.site.force_login:
@@ -150,13 +150,13 @@ class Page(object):
             raise errors.UserBlocked(self.site.blocked)
         if not self.can('edit'):
             raise errors.ProtectedPageError(self)
-        
+
         if not text: text = self.text
         if not section: section = self.section
-        
+
         if not self.site.writeapi:
             return OldPage.save(self, text=text, summary=summary, minor=False)
-        
+
         data = {}
         if minor: data['minor'] = '1'
         if not minor: data['notminor'] = '1'
@@ -164,16 +164,16 @@ class Page(object):
         if self.edit_time: data['starttimestamp'] = time.strftime('%Y%m%d%H%M%S', self.edit_time)
         if bot: data['bot'] = '1'
         if section: data['section'] = section
-        
+
         data.update(kwargs)
-        
+
         def do_edit():
-            result = self.site.api('edit', title=self.name, text=text, 
-                    summary=summary, token=self.get_token('edit'), 
-                    **data)     
+            result = self.site.api('edit', title=self.name, text=text,
+                    summary=summary, token=self.get_token('edit'),
+                    **data)
             if result['edit'].get('result').lower() == 'failure':
                 raise errors.EditError(self, result['edit'])
-            return result   
+            return result
         try:
             result = do_edit()
         except errors.APIError, e:
@@ -190,89 +190,89 @@ class Page(object):
         if result['edit'] == 'Success':
             self.last_rev_time = client.parse_timestamp(result['newtimestamp'])
         return result['edit']
-    
+
     def handle_edit_error(self, e,  summary):
         if e.code == 'editconflict':
             raise errors.EditError(self, summary, e.info)
-        elif e.code in ('protectedtitle', 'cantcreate', 'cantcreate-anon', 'noimageredirect-anon', 
+        elif e.code in ('protectedtitle', 'cantcreate', 'cantcreate-anon', 'noimageredirect-anon',
                 'noimageredirect', 'noedit-anon', 'noedit'):
             raise errors.ProtectedPageError(self, e.code, e.info)
         else:
-            raise       
+            raise
 
     def get_expanded(self):
         self.site.require(1, 12)
-        
+
         revs = self.revisions(prop='content', limit=1, expandtemplates=True)
         try:
             return revs.next()['*']
         except StopIteration:
             return u''
-            
+
     def move(self, new_title, reason='', move_talk=True, no_redirect=False):
         """Move (rename) page to new_title.
 
         If user account is an administrator, specify no_direct as True to not
         leave a redirect.
-        
+
         If user does not have permission to move page, an InsufficientPermission
         exception is raised.
-        
+
         """
         if not self.can('move'): raise errors.InsufficientPermission(self)
-        
+
         if not self.site.writeapi:
-            return OldPage.move(self, new_title=new_title, 
+            return OldPage.move(self, new_title=new_title,
                 reason=reason, move_talk=move_talk)
-        
+
         data = {}
         if move_talk: data['movetalk'] = '1'
         if no_redirect: data['noredirect'] = '1'
-        result = self.site.api('move', ('from', self.name), to=new_title, 
+        result = self.site.api('move', ('from', self.name), to=new_title,
             token=self.get_token('move'), reason=reason, **data)
         return result['move']
-        
-            
+
+
     def delete(self, reason='', watch=False, unwatch=False, oldimage=False):
         """Delete page.
-        
+
         If user does not have permission to delete page, an InsufficientPermission
         exception is raised.
-        
+
         """
         if not self.can('delete'): raise errors.InsufficientPermission(self)
-        
+
         if not self.site.writeapi:
             return OldPage.delete(self, reason=reason)
-        
+
         data = {}
         if watch: data['watch'] = '1'
         if unwatch: data['unwatch'] = '1'
         if oldimage: data['oldimage'] = oldimage
-        result = self.site.api('delete', title=self.name, 
-                token=self.get_token('delete'), 
+        result = self.site.api('delete', title=self.name,
+                token=self.get_token('delete'),
                 reason=reason, **data)
         return result['delete']
-        
+
     def purge(self):
         """Purge server-side cache of page. This will re-render templates and other
         dynamic content.
-        
+
         """
         self.site.raw_index('purge', title=self.name)
-        
+
     # def watch: requires 1.14
-        
+
     # Properties
     def backlinks(self, namespace=None, filterredir='all', redirect=False, limit=None, generator=True):
         self.site.require(1, 9)
         # Fix title for < 1.11 !!
         prefix = listing.List.get_prefix('bl', generator)
-        kwargs = dict(listing.List.generate_kwargs(prefix, 
+        kwargs = dict(listing.List.generate_kwargs(prefix,
             namespace=namespace, filterredir=filterredir))
         if redirect: kwargs['%sredirect' % prefix] = '1'
         kwargs[compatibility.title(prefix, self.site.require(1, 11, raise_error=False))] = self.name
-            
+
         return listing.List.get_list(generator)(self.site, 'backlinks', 'bl', limit=limit, return_values='title', **kwargs)
 
     def categories(self, generator=True):
@@ -291,7 +291,7 @@ class Page(object):
             namespace=namespace, filterredir=filterredir))
         if redirect: kwargs['%sredirect' % prefix] = '1'
         kwargs[compatibility.title(prefix, self.site.require(1, 11, raise_error=False))] = self.name
-            
+
         return listing.List.get_list(generator)(self.site, 'embeddedin', 'ei', limit=limit, return_values='title', **kwargs)
 
     def extlinks(self):
@@ -318,8 +318,8 @@ class Page(object):
         else:
             return listing.PageProperty(self, 'links', 'pl', return_values='title', **kwargs)
 
-    def revisions(self, startid=None, endid=None, start=None, end=None, 
-            dir='older', user=None, excludeuser=None, limit=50, 
+    def revisions(self, startid=None, endid=None, start=None, end=None,
+            dir='older', user=None, excludeuser=None, limit=50,
              prop='ids|timestamp|flags|comment|user', expandtemplates=False, section=None):
         self.site.require(1, 8)
         kwargs = dict(listing.List.generate_kwargs('rv', startid=startid, endid=endid,
@@ -328,7 +328,7 @@ class Page(object):
         kwargs['rvprop'] = prop
         if expandtemplates: kwargs['rvexpandtemplates'] = '1'
         if section: kwargs['rvsection'] = section
-        
+
         return listing.RevisionsIterator(self, 'revisions', 'rv', limit=limit, **kwargs)
 
     def templates(self, namespace=None, generator=True):
@@ -343,16 +343,16 @@ class Image(Page):
     def __init__(self, site, name, info=None):
         site.require(1, 11)
         Page.__init__(self, site, name, info,
-            extra_properties={'imageinfo': (('iiprop', 
+            extra_properties={'imageinfo': (('iiprop',
                 compatibility.iiprop(site.version)), )})
         self.imagerepository = self._info.get('imagerepository', '')
         self.imageinfo = self._info.get('imageinfo', ({}, ))[0]
 
     def imagehistory(self):
-        return listing.PageProperty(self, 'imageinfo', 'ii', 
+        return listing.PageProperty(self, 'imageinfo', 'ii',
             iiprop=compatibility.iiprop(self.site.version))
 
-    def imageusage(self, namespace=None, filterredir='all', redirect=False, 
+    def imageusage(self, namespace=None, filterredir='all', redirect=False,
             limit=None, generator=True):
         self.site.require(1, 11)
         # TODO: Fix for versions < 1.11
@@ -360,7 +360,7 @@ class Image(Page):
         kwargs = dict(listing.List.generate_kwargs(prefix, title=self.name,
             namespace=namespace, filterredir=filterredir))
         if redirect: kwargs['%sredirect' % prefix] = '1'
-        return listing.List.get_list(generator)(self.site, 'imageusage', 'iu', 
+        return listing.List.get_list(generator)(self.site, 'imageusage', 'iu',
             limit=limit, return_values='title', **kwargs)
 
     def duplicatefiles(self, limit=None):
@@ -375,7 +375,6 @@ class Image(Page):
         url = urlparse.urlparse(url)
         # TODO: query string
         return self.site.connection.get(url[1], url[2])
-        
+
     def __repr__(self):
         return "<Image object '%s' for %s>" % (self.name.encode('utf-8'), self.site)
-    
diff --git a/mwclient/page_nowriteapi.py b/mwclient/page_nowriteapi.py
index 81e97ef..2373b46 100644
--- a/mwclient/page_nowriteapi.py
+++ b/mwclient/page_nowriteapi.py
@@ -1,6 +1,6 @@
 import time
 from HTMLParser import HTMLParser
-from htmlentitydefs import name2codepoint 
+from htmlentitydefs import name2codepoint
 
 import errors
 
@@ -24,13 +24,13 @@ class OldPage(object):
 
         if minor: data['wpMinoredit'] = '1'
         data['title'] = self.name
-        
+
         page_data = self.site.raw_index('submit', **data)
-                
+
         page = EditPage('editform')
         page.feed(page_data)
         page.close()
-        
+
         if page.data:
             if page.readonly: raise errors.ProtectedPageError(self)
             self.get_token('edit',  True)
@@ -45,16 +45,16 @@ class OldPage(object):
             'wpEditToken': self.get_token('move')}
         if move_talk: postdata['wpMovetalk'] = '1'
         postdata['title'] = 'Special:Movepage'
-        
+
         page_data = self.site.raw_index('submit', **data)
-                
+
         page = EditPage('movepage')
         page.feed(page_data.decode('utf-8', 'ignore'))
         page.close()
-        
+
         if 'wpEditToken' in page.data:
             raise errors.EditError(page.title, postdata)
-            
+
     @staticmethod
     def delete(self, reason=''):
         postdata = {'wpReason': reason,
@@ -62,54 +62,54 @@ class OldPage(object):
             'mw-filedelete-submit': 'Delete',
             'wpEditToken': self.get_token('delete'),
             'title': self.name}
-            
+
         page_data = self.site.raw_index('delete', **postdata)
 
 class EditPage(HTMLParser):
     def __init__(self, form):
         HTMLParser.__init__(self)
-        
+
         self.form = form
-        
+
         self.in_form = False
         self.in_text = False
         self.in_title = False
-        
+
         self.data = {}
         self.textdata = []
         self.title = u''
-        
+
         self.readonly = True
-        
+
     def handle_starttag(self, tag, attrs):
         self.in_title = (tag == 'title')
-        
+
         if (u'id', self.form) in attrs:
             attrs = dict(attrs)
             self.in_form = True
             self.action = attrs['action']
-            
+
         if tag == 'input' and self.in_form and (u'type', u'submit') \
                 not in attrs and (u'type', u'checkbox') not in attrs:
             attrs = dict(attrs)
             if u'name' in attrs: self.data[attrs[u'name']] = attrs.get(u'value', u'')
-            
+
         if self.in_form and tag == 'textarea':
             self.in_text = True
             self.readonly = (u'readonly', u'readonly') in attrs
-    
-            
+
+
     def handle_endtag(self, tag):
         if self.in_title and tag == 'title': self.in_title = False
         if self.in_form and tag == 'form': self.in_form = False
         if self.in_text and tag == 'textarea': self.in_text = False
-    
+
     def handle_data(self, data):
         if self.in_text: self.textdata.append(data)
         if self.in_title: self.title += data
-        
+
     def handle_entityref(self, name):
-        if name in name2codepoint: 
+        if name in name2codepoint:
             self.handle_data(unichr(name2codepoint[name]))
         else:
             self.handle_data(u'&%s;' % name)
@@ -118,4 +118,3 @@ class EditPage(HTMLParser):
             self.handle_data(unichr(int(name)))
         except ValueError:
             self.handle_data(u'&#$s;' % name)
-        
diff --git a/mwclient/upload.py b/mwclient/upload.py
index a84d7e3..ec82edf 100644
--- a/mwclient/upload.py
+++ b/mwclient/upload.py
@@ -3,18 +3,18 @@ from cStringIO import StringIO
 
 class Upload(object):
     """
-    Base class for upload objects. This class should always be subclassed 
+    Base class for upload objects. This class should always be subclassed
     by upload classes and its constructor always be called.
-    
-    Upload classes are file like object/iterators that have additional 
+
+    Upload classes are file like object/iterators that have additional
     variables length and content_type.
     """
-    
+
     BLOCK_SIZE = 8192
     def __init__(self, length, content_type):
         self.length = length
         self.content_type = content_type
-        
+
     def __iter__(self):
         return self
     def next(self):
@@ -22,7 +22,7 @@ class Upload(object):
         if data == '':
             raise StopIteration
         return data
-        
+
     @staticmethod
     def encode(s):
         if type(s) is str:
@@ -34,24 +34,24 @@ class Upload(object):
 
 class UploadRawData(Upload):
     """
-    This upload class is simply a wrapper around StringIO 
+    This upload class is simply a wrapper around StringIO
     """
     def __init__(self, data, content_type='application/x-www-form-urlencoded'):
         self.fstr = StringIO(data)
         Upload.__init__(self, len(data), content_type)
-    def read(self, length = -1):
+    def read(self, length=-1):
         return self.fstr.read(length)
-        
-        
+
+
 class UploadDict(UploadRawData):
     """
-    This class creates an x-www-form-urlencoded representation of a dict 
-    and then passes it through its parent UploadRawData 
+    This class creates an x-www-form-urlencoded representation of a dict
+    and then passes it through its parent UploadRawData
     """
     def __init__(self, data):
         postdata = '&'.join('%s=%s' % (self.encode(i), self.encode(data[i])) for i in data)
         UploadRawData.__init__(self, postdata)
-        
+
 class UploadFile(Upload):
     """
     This class accepts a file with information and a postdata dictionary
@@ -74,14 +74,14 @@ class UploadFile(Upload):
         self.file = file
         self.length_left = filelength
         self.str_data = None
-        
+
         Upload.__init__(self, len(self.fileheader) + filelength + len(self.postdata) + len(self.footer) + 2,
             'multipart/form-data; boundary=' + self.boundary)
-        
+
     def read(self, length):
         if self.stage == self.STAGE_DONE:
             return ''
-        elif self.stage != self.STAGE_FILE: 
+        elif self.stage != self.STAGE_FILE:
             if self.str_data is None:
                 if self.stage == self.STAGE_FILEHEADER:
                     self.str_data = StringIO(self.fileheader)
@@ -99,24 +99,24 @@ class UploadFile(Upload):
             else:
                 self.stage += 1
                 return '\r\n'
-        
+
         if data == '':
             self.stage += 1
             self.str_data = None
             return self.read(length)
         return data
 
-        
+
     @staticmethod
     def generate_boundary():
         return '----%s----' % ''.join((random.choice(
-            'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') 
+            'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789')
             for i in xrange(32)))
-    
+
     def generate_multipart_from_dict(self, data):
         postdata = []
         for i in data:
-            postdata.append('--' + self.boundary) 
+            postdata.append('--' + self.boundary)
             postdata.append('Content-Disposition: form-data; name="%s"' % self.encode(i))
             postdata.append('')
             postdata.append(self.encode(data[i]))
-- 
GitLab