[pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way) stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 28 Sep 2011 09:27:42 +0200
branchstable
changeset 7879 9aae456abab5
parent 7874 be04706eacc9
child 7880 f475a34d0ddc
[pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
__init__.py
appobject.py
crypto.py
cwconfig.py
dbapi.py
devtools/__init__.py
devtools/qunit.py
devtools/repotest.py
devtools/testlib.py
entities/adapters.py
entities/wfobjs.py
etwist/request.py
etwist/server.py
ext/rest.py
hooks/metadata.py
hooks/notification.py
hooks/syncschema.py
hooks/syncsession.py
hooks/syncsources.py
hooks/workflow.py
mail.py
md5crypt.py
migration.py
rqlrewrite.py
schema.py
selectors.py
server/hook.py
server/migractions.py
server/msplanner.py
server/server.py
server/sources/__init__.py
server/sources/native.py
server/sources/pyrorql.py
setup.py
sobjects/notification.py
sobjects/parsers.py
toolsutils.py
uilib.py
web/action.py
web/box.py
web/component.py
web/controller.py
web/facet.py
web/formfields.py
web/formwidgets.py
web/request.py
web/test/unittest_formfields.py
web/views/ajaxedit.py
web/views/autoform.py
web/views/basetemplates.py
web/views/cwproperties.py
web/views/cwuser.py
web/views/idownloadable.py
web/views/plots.py
web/views/primary.py
web/views/reledit.py
web/views/tabs.py
web/views/treeview.py
web/views/workflow.py
wsgi/request.py
--- a/__init__.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/__init__.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
--- a/appobject.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/appobject.py	Wed Sep 28 09:27:42 2011 +0200
@@ -324,7 +324,7 @@
     selected according to a context (usually at least a request and a result
     set).
 
-    The following attributes should be set on concret appobject classes:
+    The following attributes should be set on concrete appobject classes:
 
     :attr:`__registry__`
       name of the registry for this object (string like 'views',
@@ -415,7 +415,7 @@
         appobject is returned without any transformation.
         """
         try: # XXX < 3.6 bw compat
-            pdefs = cls.property_defs
+            pdefs = cls.property_defs # pylint: disable=E1101
         except AttributeError:
             pdefs = getattr(cls, 'cw_property_defs', {})
         else:
--- a/crypto.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/crypto.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -15,9 +15,7 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""Simple cryptographic routines, based on python-crypto.
-
-"""
+"""Simple cryptographic routines, based on python-crypto."""
 __docformat__ = "restructuredtext en"
 
 from pickle import dumps, loads
--- a/cwconfig.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/cwconfig.py	Wed Sep 28 09:27:42 2011 +0200
@@ -830,6 +830,13 @@
         """
         return [self.cube_dir(p) for p in self.cubes()]
 
+    # these are overridden by set_log_methods below
+    # only defining here to prevent pylint from complaining
+    @classmethod
+    def debug(cls, msg, *a, **kw):
+        pass
+    info = warning = error = critical = exception = debug
+
 
 class CubicWebConfiguration(CubicWebNoAppConfiguration):
     """base class for cubicweb server and web configurations"""
@@ -853,6 +860,9 @@
     # wouldn't be possible otherwise
     repairing = False
 
+    # set by upgrade command
+    verbosity = 0
+
     options = CubicWebNoAppConfiguration.options + (
         ('log-file',
          {'type' : 'string',
@@ -1072,13 +1082,13 @@
 
     @cached
     def instance_md5_version(self):
-        import hashlib
+        from hashlib import md5 # pylint: disable=E0611
         infos = []
         for pkg in sorted(self.cubes()):
             version = self.cube_version(pkg)
             infos.append('%s-%s' % (pkg, version))
         infos.append('cubicweb-%s' % str(self.cubicweb_version()))
-        return hashlib.md5(';'.join(infos)).hexdigest()
+        return md5(';'.join(infos)).hexdigest()
 
     def load_configuration(self):
         """load instance's configuration files"""
@@ -1188,13 +1198,6 @@
             SMTP_LOCK.release()
         return True
 
-    # these are overridden by set_log_methods below
-    # only defining here to prevent pylint from complaining
-    @classmethod
-    def debug(cls, msg, *a, **kw):
-        pass
-    info = warning = error = critical = exception = debug 
-
 set_log_methods(CubicWebNoAppConfiguration,
                 logging.getLogger('cubicweb.configuration'))
 
@@ -1303,7 +1306,7 @@
             try:
                 return Binary(fpath)
             except OSError, ex:
-                self.critical("can't open %s: %s", fpath, ex)
+                source.critical("can't open %s: %s", fpath, ex)
                 return None
 
     register_function(FSPATH)
--- a/dbapi.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/dbapi.py	Wed Sep 28 09:27:42 2011 +0200
@@ -292,7 +292,7 @@
             self.user = user
             self.set_entity_cache(user)
 
-    def execute(self, *args, **kwargs):
+    def execute(self, *args, **kwargs): # pylint: disable=E0202
         """overriden when session is set. By default raise authentication error
         so authentication is requested.
         """
@@ -621,7 +621,8 @@
         """
         return self._repo.check_session(self.sessionid)
 
-    def _txid(self, cursor=None): # XXX could now handle various isolation level!
+    def _txid(self, cursor=None): # pylint: disable=E0202
+        # XXX could now handle various isolation level!
         # return a dict as bw compat trick
         return {'txid': currentThread().getName()}
 
--- a/devtools/__init__.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/devtools/__init__.py	Wed Sep 28 09:27:42 2011 +0200
@@ -28,7 +28,7 @@
 import pickle
 import glob
 import warnings
-import hashlib
+from hashlib import sha1 # pylint: disable=E0611
 from datetime import timedelta
 from os.path import (abspath, join, exists, basename, dirname, normpath, split,
                      isfile, isabs, splitext, isdir, expanduser)
@@ -598,7 +598,7 @@
 
     @property
     def _config_id(self):
-        return hashlib.sha1(self.config.apphome).hexdigest()[:10]
+        return sha1(self.config.apphome).hexdigest()[:10]
 
     def _backup_name(self, db_id): # merge me with parent
         backup_name = '_'.join(('cache', self._config_id, self.dbname, db_id))
--- a/devtools/qunit.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/devtools/qunit.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,3 +1,21 @@
+# copyright 2010-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+
 import os, os.path as osp
 import signal
 from tempfile import mkdtemp, NamedTemporaryFile, TemporaryFile
--- a/devtools/repotest.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/devtools/repotest.py	Wed Sep 28 09:27:42 2011 +0200
@@ -148,8 +148,7 @@
 from cubicweb.server.sources.rql2sql import SQLGenerator, remove_unused_solutions
 
 class RQLGeneratorTC(TestCase):
-    schema = backend = None # set this in concret test
-
+    schema = backend = None # set this in concrete class
 
     @classmethod
     def setUpClass(cls):
@@ -197,7 +196,7 @@
 
 
 class BaseQuerierTC(TestCase):
-    repo = None # set this in concret test
+    repo = None # set this in concrete class
 
     def setUp(self):
         self.o = self.repo.querier
--- a/devtools/testlib.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/devtools/testlib.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1167,34 +1167,34 @@
         pass
 
 
-def vreg_instrumentize(testclass):
-    # XXX broken
-    from cubicweb.devtools.apptest import TestEnvironment
-    env = testclass._env = TestEnvironment('data', configcls=testclass.configcls)
-    for reg in env.vreg.values():
-        reg._selected = {}
-        try:
-            orig_select_best = reg.__class__.__orig_select_best
-        except Exception:
-            orig_select_best = reg.__class__._select_best
-        def instr_select_best(self, *args, **kwargs):
-            selected = orig_select_best(self, *args, **kwargs)
-            try:
-                self._selected[selected.__class__] += 1
-            except KeyError:
-                self._selected[selected.__class__] = 1
-            except AttributeError:
-                pass # occurs on reg used to restore database
-            return selected
-        reg.__class__._select_best = instr_select_best
-        reg.__class__.__orig_select_best = orig_select_best
+# def vreg_instrumentize(testclass):
+#     # XXX broken
+#     from cubicweb.devtools.apptest import TestEnvironment
+#     env = testclass._env = TestEnvironment('data', configcls=testclass.configcls)
+#     for reg in env.vreg.values():
+#         reg._selected = {}
+#         try:
+#             orig_select_best = reg.__class__.__orig_select_best
+#         except Exception:
+#             orig_select_best = reg.__class__._select_best
+#         def instr_select_best(self, *args, **kwargs):
+#             selected = orig_select_best(self, *args, **kwargs)
+#             try:
+#                 self._selected[selected.__class__] += 1
+#             except KeyError:
+#                 self._selected[selected.__class__] = 1
+#             except AttributeError:
+#                 pass # occurs on reg used to restore database
+#             return selected
+#         reg.__class__._select_best = instr_select_best
+#         reg.__class__.__orig_select_best = orig_select_best
 
 
-def print_untested_objects(testclass, skipregs=('hooks', 'etypes')):
-    for regname, reg in testclass._env.vreg.iteritems():
-        if regname in skipregs:
-            continue
-        for appobjects in reg.itervalues():
-            for appobject in appobjects:
-                if not reg._selected.get(appobject):
-                    print 'not tested', regname, appobject
+# def print_untested_objects(testclass, skipregs=('hooks', 'etypes')):
+#     for regname, reg in testclass._env.vreg.iteritems():
+#         if regname in skipregs:
+#             continue
+#         for appobjects in reg.itervalues():
+#             for appobject in appobjects:
+#                 if not reg._selected.get(appobject):
+#                     print 'not tested', regname, appobject
--- a/entities/adapters.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/entities/adapters.py	Wed Sep 28 09:27:42 2011 +0200
@@ -366,8 +366,8 @@
 class IProgressAdapter(EntityAdapter):
     """something that has a cost, a state and a progression.
 
-    You should at least override progress_info an in_progress methods on concret
-    implementations.
+    You should at least override progress_info an in_progress methods on
+    concrete implementations.
     """
     __needs_bw_compat__ = True
     __regid__ = 'IProgress'
--- a/entities/wfobjs.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/entities/wfobjs.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
--- a/etwist/request.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/etwist/request.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
--- a/etwist/server.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/etwist/server.py	Wed Sep 28 09:27:42 2011 +0200
@@ -28,7 +28,7 @@
 import traceback
 import threading
 import re
-import hashlib
+from hashlib import md5 # pylint: disable=E0611
 from os.path import join
 from time import mktime
 from datetime import date, timedelta
@@ -77,6 +77,11 @@
 
 
 class NoListingFile(static.File):
+    def __init__(self, config, path=None):
+        if path is None:
+            path = config.static_directory
+        static.File.__init__(self, path)
+        self.config = config
 
     def set_expires(self, request):
         if not self.config.debugmode:
@@ -93,8 +98,7 @@
 class DataLookupDirectory(NoListingFile):
     def __init__(self, config, path):
         self.md5_version = config.instance_md5_version()
-        NoListingFile.__init__(self, path)
-        self.config = config
+        NoListingFile.__init__(self, config, path)
         self.here = path
         self._defineChildResources()
         if self.config.debugmode:
@@ -134,13 +138,10 @@
             return resource
         else:
             self.set_expires(request)
-            return NoListingFile(filepath)
+            return NoListingFile(self.config, filepath)
 
 
 class FCKEditorResource(NoListingFile):
-    def __init__(self, config, path):
-        NoListingFile.__init__(self, path)
-        self.config = config
 
     def getChild(self, path, request):
         pre_path = request.path.split('/')[1:]
@@ -179,7 +180,7 @@
         # create a unique / predictable filename. We don't consider cubes
         # version since uicache is cleared at server startup, and file's dates
         # are checked in debug mode
-        fname = 'cache_concat_' + hashlib.md5(';'.join(paths)).hexdigest() + ext
+        fname = 'cache_concat_' + md5(';'.join(paths)).hexdigest() + ext
         filepath = osp.join(config.appdatahome, 'uicache', fname)
         LongTimeExpiringFile.__init__(self, config, filepath)
         self._concat_cached_filepath(filepath, paths)
@@ -239,7 +240,7 @@
         self.https_url = config['https-url']
         global MAX_POST_LENGTH
         MAX_POST_LENGTH = config['max-post-length']
-        self.putChild('static', NoListingFile(config.static_directory))
+        self.putChild('static', NoListingFile(config))
         self.putChild('fckeditor', FCKEditorResource(self.config, ''))
         self.putChild('data', DataLookupDirectory(self.config, ''))
 
@@ -402,6 +403,13 @@
                             stream=content, code=code,
                             headers=request.headers_out)
 
+    # these are overridden by set_log_methods below
+    # only defining here to prevent pylint from complaining
+    @classmethod
+    def debug(cls, msg, *a, **kw):
+        pass
+    info = warning = error = critical = exception = debug
+
 
 JSON_PATHS = set(('json',))
 FRAME_POST_PATHS = set(('validateform',))
--- a/ext/rest.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/ext/rest.py	Wed Sep 28 09:27:42 2011 +0200
@@ -187,7 +187,7 @@
 try:
     from pygments import highlight
     from pygments.lexers import get_lexer_by_name
-    from pygments.formatters import HtmlFormatter
+    from pygments.formatters.html import HtmlFormatter
 except ImportError:
     pygments_directive = None
 else:
--- a/hooks/metadata.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/hooks/metadata.py	Wed Sep 28 09:27:42 2011 +0200
@@ -150,6 +150,8 @@
 # entity source handling #######################################################
 
 class ChangeEntityUpdateCaches(hook.Operation):
+    oldsource = newsource = entity = None # make pylint happy
+
     def postcommit_event(self):
         self.oldsource.reset_caches()
         repo = self.session.repo
--- a/hooks/notification.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/hooks/notification.py	Wed Sep 28 09:27:42 2011 +0200
@@ -28,6 +28,8 @@
 
 class RenderAndSendNotificationView(hook.Operation):
     """delay rendering of notification view until precommit"""
+    view = None # make pylint happy
+
     def precommit_event(self):
         view = self.view
         if view.cw_rset is not None and not view.cw_rset:
--- a/hooks/syncschema.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/hooks/syncschema.py	Wed Sep 28 09:27:42 2011 +0200
@@ -246,6 +246,7 @@
       CWAttribute entities
     * add owned_by relation by creating the necessary CWRelation entity
     """
+    entity = None # make pylint happy
 
     def precommit_event(self):
         session = self.session
@@ -759,6 +760,8 @@
 
 class MemSchemaCWETypeDel(MemSchemaOperation):
     """actually remove the entity type from the instance's schema"""
+    etype = None # make pylint happy
+
     def postcommit_event(self):
         # del_entity_type also removes entity's relations
         self.session.vreg.schema.del_entity_type(self.etype)
@@ -766,6 +769,8 @@
 
 class MemSchemaCWRTypeAdd(MemSchemaOperation):
     """actually add the relation type to the instance's schema"""
+    rtypedef = None # make pylint happy
+
     def precommit_event(self):
         self.session.vreg.schema.add_relation_type(self.rtypedef)
 
@@ -775,6 +780,8 @@
 
 class MemSchemaCWRTypeDel(MemSchemaOperation):
     """actually remove the relation type from the instance's schema"""
+    rtype = None # make pylint happy
+
     def postcommit_event(self):
         try:
             self.session.vreg.schema.del_relation_type(self.rtype)
@@ -786,6 +793,7 @@
 class MemSchemaPermissionAdd(MemSchemaOperation):
     """synchronize schema when a *_permission relation has been added on a group
     """
+    eid = action = group_eid = expr = None # make pylint happy
 
     def precommit_event(self):
         """the observed connections.cnxset has been commited"""
@@ -845,6 +853,7 @@
 
 
 class MemSchemaSpecializesAdd(MemSchemaOperation):
+    etypeeid = parentetypeeid = None # make pylint happy
 
     def precommit_event(self):
         eschema = self.session.vreg.schema.schema_by_eid(self.etypeeid)
@@ -856,6 +865,7 @@
 
 
 class MemSchemaSpecializesDel(MemSchemaOperation):
+    etypeeid = parentetypeeid = None # make pylint happy
 
     def precommit_event(self):
         try:
--- a/hooks/syncsession.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/hooks/syncsession.py	Wed Sep 28 09:27:42 2011 +0200
@@ -40,7 +40,8 @@
 
 class _GroupOperation(hook.Operation):
     """base class for group operation"""
-    geid = None
+    cnxuser = None # make pylint happy
+
     def __init__(self, session, *args, **kwargs):
         """override to get the group name before actual groups manipulation:
 
@@ -55,6 +56,7 @@
 
 class _DeleteGroupOp(_GroupOperation):
     """synchronize user when a in_group relation has been deleted"""
+
     def postcommit_event(self):
         """the observed connections set has been commited"""
         groups = self.cnxuser.groups
@@ -117,9 +119,9 @@
 
 # CWProperty hooks #############################################################
 
-
 class _DelCWPropertyOp(hook.Operation):
     """a user's custom properties has been deleted"""
+    cwpropdict = key = None # make pylint happy
 
     def postcommit_event(self):
         """the observed connections set has been commited"""
@@ -131,6 +133,7 @@
 
 class _ChangeCWPropertyOp(hook.Operation):
     """a user's custom properties has been added/changed"""
+    cwpropdict = key = value = None # make pylint happy
 
     def postcommit_event(self):
         """the observed connections set has been commited"""
@@ -139,6 +142,7 @@
 
 class _AddCWPropertyOp(hook.Operation):
     """a user's custom properties has been added/changed"""
+    cwprop = None # make pylint happy
 
     def postcommit_event(self):
         """the observed connections set has been commited"""
--- a/hooks/syncsources.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/hooks/syncsources.py	Wed Sep 28 09:27:42 2011 +0200
@@ -34,6 +34,7 @@
 # repo sources synchronization #################################################
 
 class SourceAddedOp(hook.Operation):
+    entity = None # make pylint happy
     def postcommit_event(self):
         self.session.repo.add_source(self.entity)
 
@@ -54,6 +55,7 @@
 
 
 class SourceRemovedOp(hook.Operation):
+    uri = None # make pylint happy
     def postcommit_event(self):
         self.session.repo.remove_source(self.uri)
 
@@ -82,6 +84,7 @@
 
 
 class SourceRenamedOp(hook.LateOperation):
+    oldname = newname = None # make pylint happy
 
     def precommit_event(self):
         source = self.session.repo.sources_by_uri[self.oldname]
@@ -141,12 +144,12 @@
 # Expect cw_for_source/cw_schema are immutable relations (i.e. can't change from
 # a source or schema to another).
 
-class SourceMappingDeleteHook(SourceHook):
+class SourceMappingImmutableHook(SourceHook):
     """check cw_for_source and cw_schema are immutable relations
 
     XXX empty delete perms would be enough?
     """
-    __regid__ = 'cw.sources.delschemaconfig'
+    __regid__ = 'cw.sources.mapping.immutable'
     __select__ = SourceHook.__select__ & hook.match_rtype('cw_for_source', 'cw_schema')
     events = ('before_add_relation',)
     def __call__(self):
--- a/hooks/workflow.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/hooks/workflow.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -45,6 +45,7 @@
 
 class _SetInitialStateOp(hook.Operation):
     """make initial state be a default state"""
+    entity = None # make pylint happy
 
     def precommit_event(self):
         session = self.session
@@ -61,6 +62,7 @@
 
 class _FireAutotransitionOp(hook.Operation):
     """try to fire auto transition after state changes"""
+    entity = None # make pylint happy
 
     def precommit_event(self):
         entity = self.entity
@@ -73,6 +75,7 @@
 
 class _WorkflowChangedOp(hook.Operation):
     """fix entity current state when changing its workflow"""
+    eid = wfeid = None # make pylint happy
 
     def precommit_event(self):
         # notice that enforcement that new workflow apply to the entity's type is
@@ -109,6 +112,7 @@
 
 
 class _CheckTrExitPoint(hook.Operation):
+    treid = None # make pylint happy
 
     def precommit_event(self):
         tr = self.session.entity_from_eid(self.treid)
@@ -122,6 +126,7 @@
 
 
 class _SubWorkflowExitOp(hook.Operation):
+    forentity = trinfo = None # make pylint happy
 
     def precommit_event(self):
         session = self.session
--- a/mail.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/mail.py	Wed Sep 28 09:27:42 2011 +0200
@@ -21,10 +21,10 @@
 
 from base64 import b64encode, b64decode
 from time import time
-from email.MIMEMultipart import MIMEMultipart
-from email.MIMEText import MIMEText
-from email.MIMEImage import MIMEImage
-from email.Header import Header
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+from email.mime.image import MIMEImage
+from email.header import Header
 try:
     from socket import gethostname
 except ImportError:
@@ -156,6 +156,10 @@
 
     msgid_timestamp = True
 
+    # to be defined on concrete sub-classes
+    content = None # body of the mail
+    message = None # action verb of the subject
+
     # this is usually the method to call
     def render_and_send(self, **kwargs):
         """generate and send an email message for this view"""
--- a/md5crypt.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/md5crypt.py	Wed Sep 28 09:27:42 2011 +0200
@@ -41,7 +41,7 @@
 MAGIC = '$1$'                        # Magic string
 ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 
-import hashlib as md5
+from hashlib import md5 # pylint: disable=E0611
 
 def to64 (v, n):
     ret = ''
@@ -63,7 +63,7 @@
     salt = salt.split('$', 1)[0]
     salt = salt[:8]
     ctx = pw + magic + salt
-    final = md5.md5(pw + salt + pw).digest()
+    final = md5(pw + salt + pw).digest()
     for pl in xrange(len(pw), 0, -16):
         if pl > 16:
             ctx = ctx + final[:16]
@@ -77,7 +77,7 @@
         else:
             ctx = ctx + pw[0]
         i = i >> 1
-    final = md5.md5(ctx).digest()
+    final = md5(ctx).digest()
     # The following is supposed to make
     # things run slower.
     # my question: WTF???
@@ -95,7 +95,7 @@
             ctx1 = ctx1 + final[:16]
         else:
             ctx1 = ctx1 + pw
-        final = md5.md5(ctx1).digest()
+        final = md5(ctx1).digest()
     # Final xform
     passwd = ''
     passwd = passwd + to64((int(ord(final[0])) << 16)
--- a/migration.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/migration.py	Wed Sep 28 09:27:42 2011 +0200
@@ -201,8 +201,8 @@
         if not ask_confirm or self.confirm(msg):
             return meth(*args, **kwargs)
 
-    def confirm(self, question, shell=True, abort=True, retry=False, pdb=False,
-                default='y'):
+    def confirm(self, question, # pylint: disable=E0202
+                shell=True, abort=True, retry=False, pdb=False, default='y'):
         """ask for confirmation and return true on positive answer
 
         if `retry` is true the r[etry] answer may return 2
--- a/rqlrewrite.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/rqlrewrite.py	Wed Sep 28 09:27:42 2011 +0200
@@ -638,7 +638,7 @@
 
     def visit_mathexpression(self, node):
         cmp_ = n.MathExpression(node.operator)
-        for c in cmp.children:
+        for c in node.children:
             cmp_.append(c.accept(self))
         return cmp_
 
--- a/schema.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/schema.py	Wed Sep 28 09:27:42 2011 +0200
@@ -666,6 +666,8 @@
     # these are overridden by set_log_methods below
     # only defining here to prevent pylint from complaining
     info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
+    # to be defined in concrete classes
+    full_rql = None
 
     def __init__(self, expression, mainvars, eid):
         self.eid = eid # eid of the entity representing this rql expression
--- a/selectors.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/selectors.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
--- a/server/hook.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/server/hook.py	Wed Sep 28 09:27:42 2011 +0200
@@ -537,7 +537,7 @@
     # XXX deprecated
     enabled = True
     # stop pylint from complaining about missing attributes in Hooks classes
-    eidfrom = eidto = entity = rtype = None
+    eidfrom = eidto = entity = rtype = repo = None
 
     @classmethod
     @cached
@@ -580,7 +580,7 @@
             warn('[3.6] %s: accepts is deprecated, define proper __select__'
                  % classid(cls), DeprecationWarning)
             rtypes = []
-            for ertype in cls.accepts:
+            for ertype in cls.accepts: # pylint: disable=E1101
                 if ertype.islower():
                     rtypes.append(ertype)
                 else:
@@ -601,6 +601,7 @@
         if hasattr(self, 'call'):
             warn('[3.6] %s: call is deprecated, implement __call__'
                  % classid(self.__class__), DeprecationWarning)
+            # pylint: disable=E1101
             if self.event.endswith('_relation'):
                 self.call(self._cw, self.eidfrom, self.rtype, self.eidto)
             elif 'delete' in self.event:
@@ -628,7 +629,7 @@
     Notice there are no default behaviour defined when a watched relation is
     deleted, you'll have to handle this by yourself.
 
-    You usually want to use the :class:`match_rtype_sets` selector on concret
+    You usually want to use the :class:`match_rtype_sets` selector on concrete
     classes.
     """
     events = ('after_add_relation',)
@@ -808,7 +809,7 @@
         if event == 'postcommit_event' and hasattr(self, 'commit_event'):
             warn('[3.10] %s: commit_event method has been replaced by postcommit_event'
                  % classid(self.__class__), DeprecationWarning)
-            self.commit_event()
+            self.commit_event() # pylint: disable=E1101
         getattr(self, event)()
 
     def precommit_event(self):
@@ -1092,6 +1093,9 @@
 
 
 class RQLPrecommitOperation(Operation):
+    # to be defined in concrete classes
+    rqls = None
+
     def precommit_event(self):
         execute = self.session.execute
         for rql in self.rqls:
--- a/server/migractions.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/server/migractions.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1563,8 +1563,7 @@
         This may be useful on accidental desync between the repository schema
         and a sql database
         """
-        dbhelper = self.repo.system_source.dbhelper
-        tablesql = rschema2sql(dbhelper, self.repo.schema.rschema(rtype))
+        tablesql = rschema2sql(self.repo.schema.rschema(rtype))
         for sql in tablesql.split(';'):
             if sql.strip():
                 self.sqlexec(sql)
--- a/server/msplanner.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/server/msplanner.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1438,7 +1438,7 @@
                                                          for step in steps
                                                          for select in step.union.children):
                 if temptable:
-                    step = IntersectFetchStep(plan) # XXX not implemented
+                    raise NotImplementedError('oops') # IntersectFetchStep(plan)
                 else:
                     step = IntersectStep(plan)
             else:
--- a/server/server.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/server/server.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -129,6 +129,13 @@
         signal.signal(signal.SIGINT, lambda x, y, s=self: s.quit())
         signal.signal(signal.SIGTERM, lambda x, y, s=self: s.quit())
 
+
+    # these are overridden by set_log_methods below
+    # only defining here to prevent pylint from complaining
+    @classmethod
+    def info(cls, msg, *a, **kw):
+        pass
+
 from logging import getLogger
 from cubicweb import set_log_methods
 LOGGER = getLogger('cubicweb.reposerver')
--- a/server/sources/__init__.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/server/sources/__init__.py	Wed Sep 28 09:27:42 2011 +0200
@@ -118,6 +118,10 @@
     # source configuration options
     options = ()
 
+    # these are overridden by set_log_methods below
+    # only defining here to prevent pylint from complaining
+    info = warning = error = critical = exception = debug = lambda msg,*a,**kw: None
+
     def __init__(self, repo, source_config, eid=None):
         self.repo = repo
         self.set_schema(repo.schema)
--- a/server/sources/native.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/server/sources/native.py	Wed Sep 28 09:27:42 2011 +0200
@@ -865,7 +865,7 @@
             self.exception('failed to query entities table for eid %s', eid)
         raise UnknownEid(eid)
 
-    def eid_type_source(self, session, eid):
+    def eid_type_source(self, session, eid): # pylint: disable=E0202
         """return a tuple (type, source, extid) for the entity with id <eid>"""
         sql = 'SELECT type, source, extid, asource FROM entities WHERE eid=%s' % eid
         res = self._eid_type_source(session, eid, sql)
@@ -924,13 +924,13 @@
             return cursor.fetchone()[0]
 
 
-    def create_eid(self, session):
+    def create_eid(self, session): # pylint: disable=E0202
         # lock needed to prevent 'Connection is busy with results for another
         # command (0)' errors with SQLServer
         with self._eid_cnx_lock:
-            return self._create_eid()
+            return self._create_eid() # pylint: disable=E1102
 
-    def _create_eid(self):
+    def _create_eid(self): # pylint: disable=E0202
         # internal function doing the eid creation without locking.
         # needed for the recursive handling of disconnections (otherwise we
         # deadlock on self._eid_cnx_lock
@@ -946,13 +946,13 @@
             # FIXME: better detection of deconnection pb
             self.warning("trying to reconnect create eid connection")
             self._eid_creation_cnx = None
-            return self._create_eid()
+            return self._create_eid() # pylint: disable=E1102
         except (self.DbapiError,), exc:
             # We get this one with pyodbc and SQL Server when connection was reset
             if exc.args[0] == '08S01':
                 self.warning("trying to reconnect create eid connection")
                 self._eid_creation_cnx = None
-                return self._create_eid()
+                return self._create_eid() # pylint: disable=E1102
             else:
                 raise
         except Exception: # WTF?
--- a/server/sources/pyrorql.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/server/sources/pyrorql.py	Wed Sep 28 09:27:42 2011 +0200
@@ -191,7 +191,7 @@
                 self.support_entities[ertype] = 'write' in options
         else: # CWRType
             if ertype in ('is', 'is_instance_of', 'cw_source') or ertype in VIRTUAL_RTYPES:
-                msg = schemacfg._cw._('%s relation should not be in mapped') % rtype
+                msg = schemacfg._cw._('%s relation should not be in mapped') % ertype
                 raise ValidationError(schemacfg.eid, {role_name('cw_for_schema', 'subject'): msg})
             options = self._check_options(schemacfg, self.rtype_options)
             if 'dontcross' in options:
--- a/setup.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/setup.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # pylint: disable=W0142,W0403,W0404,W0613,W0622,W0622,W0704,R0904,C0103,E0611
 #
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -179,7 +179,7 @@
 if USE_SETUPTOOLS:
     # overwrite MyInstallData to use sys.prefix instead of the egg directory
     MyInstallMoreData = MyInstallData
-    class MyInstallData(MyInstallMoreData):
+    class MyInstallData(MyInstallMoreData): # pylint: disable=E0102
         """A class that manages data files installation"""
         def run(self):
             _old_install_dir = self.install_dir
--- a/sobjects/notification.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/sobjects/notification.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -109,6 +109,8 @@
 
 url: %(url)s
 """
+    # to be defined on concrete sub-classes
+    content_attr = None
 
     def context(self, **kwargs):
         entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)
--- a/sobjects/parsers.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/sobjects/parsers.py	Wed Sep 28 09:27:42 2011 +0200
@@ -32,7 +32,7 @@
 """
 
 import os.path as osp
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, time
 from urllib import urlencode
 from cgi import parse_qs # in urlparse with python >= 2.6
 
@@ -151,7 +151,7 @@
             linker.check_options(options, schemacfg.eid)
         except KeyError:
             msg = _('"action" must be specified in options; allowed values are '
-                    '%s') % ', '.join(self.action_methods)
+                    '%s') % ', '.join(self.list_actions())
             raise ValidationError(schemacfg.eid, {rn('options', 'subject'): msg})
         except RegistryException:
             msg = _('allowed values for "action" are %s') % ', '.join(self.list_actions())
--- a/toolsutils.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/toolsutils.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -36,7 +36,7 @@
 from logilab.common.compat import any
 from logilab.common.shellutils import ASK
 
-from cubicweb import warning
+from cubicweb import warning # pylint: disable=E0611
 from cubicweb import ConfigurationError, ExecutionError
 
 def underline_title(title, car='-'):
--- a/uilib.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/uilib.py	Wed Sep 28 09:27:42 2011 +0200
@@ -161,94 +161,84 @@
 
 REM_ROOT_HTML_TAGS = re.compile('</(body|html)>', re.U)
 
-try:
-    from lxml import etree, html
-    from lxml.html import clean, defs
+from lxml import etree, html
+from lxml.html import clean, defs
 
-    ALLOWED_TAGS = (defs.general_block_tags | defs.list_tags | defs.table_tags |
-                    defs.phrase_tags | defs.font_style_tags |
-                    set(('span', 'a', 'br', 'img', 'map', 'area', 'sub', 'sup'))
-                    )
+ALLOWED_TAGS = (defs.general_block_tags | defs.list_tags | defs.table_tags |
+                defs.phrase_tags | defs.font_style_tags |
+                set(('span', 'a', 'br', 'img', 'map', 'area', 'sub', 'sup'))
+                )
 
-    CLEANER = clean.Cleaner(allow_tags=ALLOWED_TAGS, remove_unknown_tags=False,
-                            style=True, safe_attrs_only=True,
-                            add_nofollow=False,
-                            )
+CLEANER = clean.Cleaner(allow_tags=ALLOWED_TAGS, remove_unknown_tags=False,
+                        style=True, safe_attrs_only=True,
+                        add_nofollow=False,
+                        )
 
-    def soup2xhtml(data, encoding):
-        """tidy html soup by allowing some element tags and return the result
-        """
-        # remove spurious </body> and </html> tags, then normalize line break
-        # (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1)
-        data = REM_ROOT_HTML_TAGS.sub('', u'\n'.join(data.splitlines()))
-        xmltree = etree.HTML(CLEANER.clean_html('<div>%s</div>' % data))
-        # NOTE: lxml 2.0 does support encoding='unicode', but last time I (syt)
-        # tried I got weird results (lxml 2.2.8)
-        body = etree.tostring(xmltree[0], encoding=encoding)
-        # remove <body> and </body> and decode to unicode
-        snippet = body[6:-7].decode(encoding)
-        # take care to bad xhtml (for instance starting with </div>) which
-        # may mess with the <div> we added below. Only remove it if it's
-        # still there...
-        if snippet.startswith('<div>') and snippet.endswith('</div>'):
-            snippet = snippet[5:-6]
-        return snippet
+def soup2xhtml(data, encoding):
+    """tidy html soup by allowing some element tags and return the result
+    """
+    # remove spurious </body> and </html> tags, then normalize line break
+    # (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1)
+    data = REM_ROOT_HTML_TAGS.sub('', u'\n'.join(data.splitlines()))
+    xmltree = etree.HTML(CLEANER.clean_html('<div>%s</div>' % data))
+    # NOTE: lxml 2.0 does support encoding='unicode', but last time I (syt)
+    # tried I got weird results (lxml 2.2.8)
+    body = etree.tostring(xmltree[0], encoding=encoding)
+    # remove <body> and </body> and decode to unicode
+    snippet = body[6:-7].decode(encoding)
+    # take care to bad xhtml (for instance starting with </div>) which
+    # may mess with the <div> we added below. Only remove it if it's
+    # still there...
+    if snippet.startswith('<div>') and snippet.endswith('</div>'):
+        snippet = snippet[5:-6]
+    return snippet
 
-        # lxml.Cleaner envelops text elements by internal logic (not accessible)
-        # see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1
-        # TODO drop attributes in elements
-        # TODO add policy configuration (content only, embedded content, ...)
-        # XXX this is buggy for "<p>text1</p><p>text2</p>"...
-        # XXX drop these two snippets action and follow the lxml behaviour
-        # XXX (tests need to be updated)
-        # if snippet.startswith('<div>') and snippet.endswith('</div>'):
-        #     snippet = snippet[5:-6]
-        # if snippet.startswith('<p>') and snippet.endswith('</p>'):
-        #     snippet = snippet[3:-4]
-        return snippet.decode(encoding)
-
-except (ImportError, AttributeError):
-    # gae environment: lxml not available
-    # fallback implementation
-    def soup2xhtml(data, encoding):
-        # normalize line break
-        # see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1
-        return u'\n'.join(data.splitlines())
-else:
-
-    if hasattr(etree.HTML('<div>test</div>'), 'iter'): # XXX still necessary?
+    # lxml.Cleaner envelops text elements by internal logic (not accessible)
+    # see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1
+    # TODO drop attributes in elements
+    # TODO add policy configuration (content only, embedded content, ...)
+    # XXX this is buggy for "<p>text1</p><p>text2</p>"...
+    # XXX drop these two snippets action and follow the lxml behaviour
+    # XXX (tests need to be updated)
+    # if snippet.startswith('<div>') and snippet.endswith('</div>'):
+    #     snippet = snippet[5:-6]
+    # if snippet.startswith('<p>') and snippet.endswith('</p>'):
+    #     snippet = snippet[3:-4]
+    return snippet.decode(encoding)
 
-        def safe_cut(text, length):
-            """returns an html document of length <length> based on <text>,
-            and cut is necessary.
-            """
-            if text is None:
-                return u''
-            dom = etree.HTML(text)
-            curlength = 0
-            add_ellipsis = False
-            for element in dom.iter():
-                if curlength >= length:
-                    parent = element.getparent()
-                    parent.remove(element)
-                    if curlength == length and (element.text or element.tail):
-                        add_ellipsis = True
-                else:
-                    if element.text is not None:
-                        element.text = cut(element.text, length - curlength)
-                        curlength += len(element.text)
-                    if element.tail is not None:
-                        if curlength < length:
-                            element.tail = cut(element.tail, length - curlength)
-                            curlength += len(element.tail)
-                        elif curlength == length:
-                            element.tail = '...'
-                        else:
-                            element.tail = ''
-            text = etree.tounicode(dom[0])[6:-7] # remove wrapping <body></body>
-            if add_ellipsis:
-                return text + u'...'
-            return text
+if hasattr(etree.HTML('<div>test</div>'), 'iter'): # XXX still necessary?
+    # pylint: disable=E0102
+    def safe_cut(text, length):
+        """returns an html document of length <length> based on <text>,
+        and cut is necessary.
+        """
+        if text is None:
+            return u''
+        dom = etree.HTML(text)
+        curlength = 0
+        add_ellipsis = False
+        for element in dom.iter():
+            if curlength >= length:
+                parent = element.getparent()
+                parent.remove(element)
+                if curlength == length and (element.text or element.tail):
+                    add_ellipsis = True
+            else:
+                if element.text is not None:
+                    element.text = cut(element.text, length - curlength)
+                    curlength += len(element.text)
+                if element.tail is not None:
+                    if curlength < length:
+                        element.tail = cut(element.tail, length - curlength)
+                        curlength += len(element.tail)
+                    elif curlength == length:
+                        element.tail = '...'
+                    else:
+                        element.tail = ''
+        text = etree.tounicode(dom[0])[6:-7] # remove wrapping <body></body>
+        if add_ellipsis:
+            return text + u'...'
+        return text
 
 def text_cut(text, nbwords=30, gotoperiod=True):
     """from the given plain text, return a text with at least <nbwords> words,
--- a/web/action.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/action.py	Wed Sep 28 09:27:42 2011 +0200
@@ -133,10 +133,13 @@
                   & partial_relation_possible(action='add', strict=True))
 
     submenu = 'addrelated'
+    # to be defined in concrete classes
+    target_etype = rtype = None
 
     def url(self):
         try:
-            ttype = self.etype # deprecated in 3.6, already warned by the selector
+            # deprecated in 3.6, already warned by the selector
+            ttype = self.etype # pylint: disable=E1101
         except AttributeError:
             ttype = self.target_etype
         entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)
--- a/web/box.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/box.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -118,7 +118,8 @@
     related to the current result set.
     """
 
-    rql  = None
+    # to be defined in concrete classes
+    rql = title = None
 
     def to_display_rql(self):
         assert self.rql is not None, self.__regid__
@@ -168,7 +169,7 @@
     subclasses should define at least id, rtype and target
     class attributes.
     """
-
+    rtype = None
     def cell_call(self, row, col, view=None, **kwargs):
         self._cw.add_js('cubicweb.ajax.js')
         entity = self.cw_rset.get_entity(row, col)
--- a/web/component.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/component.py	Wed Sep 28 09:27:42 2011 +0200
@@ -321,7 +321,7 @@
             def wview(__vid, rset=None, __fallback_vid=None, **kwargs):
                 self._cw.view(__vid, rset, __fallback_vid, w=self.w, **kwargs)
             self.wview = wview
-            self.call(**kwargs)
+            self.call(**kwargs) # pylint: disable=E1101
             return
         getlayout = self._cw.vreg['components'].select
         layout = getlayout('layout', self._cw, **self.layout_select_args())
@@ -539,6 +539,9 @@
 
     subclasses should define at least id, rtype and target class attributes.
     """
+    # to be defined in concrete classes
+    rtype = None
+
     def render_title(self, w):
         w(display_name(self._cw, self.rtype, role(self),
                        context=self.entity.__regid__))
@@ -566,7 +569,9 @@
     added_msg = None
     removed_msg = None
 
-    # class attributes below *must* be set in concret classes (additionaly to
+    # to be defined in concrete classes
+    rtype = role = target_etype = None
+    # class attributes below *must* be set in concrete classes (additionaly to
     # rtype / role [/ target_etype]. They should correspond to js_* methods on
     # the json controller
 
@@ -706,6 +711,8 @@
     __select__ = EntityVComponent.__select__ & partial_has_related_entities()
 
     vid = 'list'
+    # to be defined in concrete classes
+    rtype = title = None
 
     def rql(self):
         """override this method if you want to use a custom rql query"""
--- a/web/controller.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/controller.py	Wed Sep 28 09:27:42 2011 +0200
@@ -114,7 +114,7 @@
                           [recipient], body, subject)
         if not self._cw.vreg.config.sendmails([(msg, [recipient])]):
             msg = self._cw._('could not connect to the SMTP server')
-            url = self._cw.build_url(__message=msgid)
+            url = self._cw.build_url(__message=msg)
             raise Redirect(url)
 
     def reset(self):
--- a/web/facet.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/facet.py	Wed Sep 28 09:27:42 2011 +0200
@@ -82,9 +82,9 @@
 
 @deprecated('[3.13] filter_hiddens moved to cubicweb.web.views.facets with '
             'slightly modified prototype')
-def filter_hiddens(w, **kwargs):
+def filter_hiddens(w, baserql, **kwargs):
     from cubicweb.web.views.facets import filter_hiddens
-    return filter_hiddens(w, wdgs=kwargs.pop('facets'))
+    return filter_hiddens(w, baserql, wdgs=kwargs.pop('facets'), **kwargs)
 
 
 ## rqlst manipulation functions used by facets ################################
@@ -502,7 +502,7 @@
 
 class RelationFacet(VocabularyFacet):
     """Base facet to filter some entities according to other entities to which
-    they are related. Create concret facet by inheriting from this class an then
+    they are related. Create concrete facet by inheriting from this class an then
     configuring it by setting class attribute described below.
 
     The relation is defined by the `rtype` and `role` attributes.
@@ -751,7 +751,7 @@
                 restrvar, rtrel = _make_relation(self.select, self.filtered_variable,
                                                  self.rtype, self.role)
                 if rel is None:
-                    select.add_restriction(rtrel)
+                    self.select.add_restriction(rtrel)
                 else:
                     rel.parent.replace(rel, nodes.And(rel, rtrel))
                 self._and_restriction(rel, restrvar, value.pop())
--- a/web/formfields.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/formfields.py	Wed Sep 28 09:27:42 2011 +0200
@@ -28,7 +28,7 @@
 
 .. autoclass:: cubicweb.web.formfields.Field
 
-Now, you usually don't use that class but one of the concret field classes
+Now, you usually don't use that class but one of the concrete field classes
 described below, according to what you want to edit.
 
 Basic fields
@@ -107,7 +107,7 @@
 class Field(object):
     """This class is the abstract base class for all fields. It hold a bunch
     of attributes which may be used for fine control of the behaviour of a
-    concret field.
+    concrete field.
 
     **Attributes**
 
@@ -349,6 +349,7 @@
     def initial_typed_value(self, form, load_bytes):
         if self.value is not _MARKER:
             if callable(self.value):
+                # pylint: disable=E1102
                 if support_args(self.value, 'form', 'field'):
                     return self.value(form, self)
                 else:
@@ -389,6 +390,7 @@
         """
         assert self.choices is not None
         if callable(self.choices):
+            # pylint: disable=E1102
             if getattr(self.choices, 'im_self', None) is self:
                 vocab = self.choices(form=form, **kwargs)
             elif support_args(self.choices, 'form', 'field'):
@@ -396,11 +398,11 @@
             else:
                 try:
                     vocab = self.choices(form=form, **kwargs)
-                    warn('[3.6]  %s: choices should now take '
+                    warn('[3.6] %s: choices should now take '
                          'the form and field as named arguments' % self,
                          DeprecationWarning)
                 except TypeError:
-                    warn('[3.3]  %s: choices should now take '
+                    warn('[3.3] %s: choices should now take '
                          'the form and field as named arguments' % self,
                          DeprecationWarning)
                     vocab = self.choices(req=form._cw, **kwargs)
--- a/web/formwidgets.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/formwidgets.py	Wed Sep 28 09:27:42 2011 +0200
@@ -110,8 +110,8 @@
 
     **Attributes**
 
-    Here are standard attributes of a widget, that may be set on concret
-    class to override default behaviours:
+    Here are standard attributes of a widget, that may be set on concrete class
+    to override default behaviours:
 
     :attr:`needs_js`
        list of javascript files needed by the widget.
@@ -134,7 +134,7 @@
 
     Also, widget instances takes as first argument a `attrs` dictionary which
     will be stored in the attribute of the same name. It contains HTML
-    attributes that should be set in the widget's input tag (though concret
+    attributes that should be set in the widget's input tag (though concrete
     classes may ignore it).
 
     .. currentmodule:: cubicweb.web.formwidgets
@@ -190,7 +190,7 @@
         return self._render(form, field, renderer)
 
     def _render(self, form, field, renderer):
-        """This is the method you have to implement in concret widget classes.
+        """This is the method you have to implement in concrete widget classes.
         """
         raise NotImplementedError()
 
@@ -232,7 +232,7 @@
         correctly typed value.
 
         3 and 4 are handle by the :meth:`typed_value` method to ease reuse in
-        concret classes.
+        concrete classes.
         """
         values = None
         if not field.ignore_req_params:
--- a/web/request.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/request.py	Wed Sep 28 09:27:42 2011 +0200
@@ -19,10 +19,10 @@
 
 __docformat__ = "restructuredtext en"
 
-import hashlib
 import time
 import random
 import base64
+from hashlib import sha1 # pylint: disable=E0611
 from Cookie import SimpleCookie
 from calendar import timegm
 from datetime import date
@@ -49,7 +49,7 @@
 _MARKER = object()
 
 def build_cb_uid(seed):
-    sha = hashlib.sha1('%s%s%s' % (time.time(), seed, random.random()))
+    sha = sha1('%s%s%s' % (time.time(), seed, random.random()))
     return 'cb_%s' % (sha.hexdigest())
 
 
--- a/web/test/unittest_formfields.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/test/unittest_formfields.py	Wed Sep 28 09:27:42 2011 +0200
@@ -144,6 +144,17 @@
         self.assertEqual(description_format_field.value(form), 'text/rest')
 
 
+    def test_property_key_field(self):
+        from cubicweb.web.views.cwproperties import PropertyKeyField
+        req = self.request()
+        field = PropertyKeyField()
+        e = self.vreg['etypes'].etype_class('CWProperty')(req)
+        renderer = self.vreg['formrenderers'].select('base', req)
+        form = EntityFieldsForm(req, entity=e)
+        form.formvalues = {}
+        field.render(form, renderer)
+
+
 class UtilsTC(TestCase):
     def test_vocab_sort(self):
         self.assertEqual(vocab_sort([('Z', 1), ('A', 2),
--- a/web/views/ajaxedit.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/ajaxedit.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -70,7 +70,7 @@
         if getattr(self, 'etype', None):
             rset = entity.unrelated(self.rtype, self.etype, role(self),
                                     ordermethod='fetch_order')
-            self.pagination(self._cw, rset, w=self.w)
+            self.paginate(self._cw, rset=rset, w=self.w)
             return rset.entities()
         super(AddRelationView, self).unrelated_entities(self)
 
--- a/web/views/autoform.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/autoform.py	Wed Sep 28 09:27:42 2011 +0200
@@ -198,6 +198,9 @@
     _select_attrs = ('peid', 'rtype', 'role', 'pform', 'etype')
     removejs = "removeInlinedEntity('%s', '%s', '%s')"
 
+    # make pylint happy
+    peid = rtype = role = pform = etype = None
+
     def __init__(self, *args, **kwargs):
         for attr in self._select_attrs:
             # don't pop attributes from kwargs, so the end-up in
@@ -304,6 +307,9 @@
                   & specified_etype_implements('Any'))
     _select_attrs = InlineEntityEditionFormView._select_attrs + ('petype',)
 
+    # make pylint happy
+    petype = None
+
     @property
     def removejs(self):
         entity = self._entity()
@@ -345,6 +351,7 @@
                   & specified_etype_implements('Any'))
 
     _select_attrs = InlineEntityCreationFormView._select_attrs + ('card',)
+    card = None # make pylint happy
     form = None # no actual form wrapped
 
     def call(self, i18nctx, **kwargs):
@@ -752,6 +759,7 @@
 
     def _generic_relations_field(self):
         try:
+            # pylint: disable=E1101
             srels_by_cat = self.srelations_by_category('generic', 'add', strict=True)
             warn('[3.6] %s: srelations_by_category is deprecated, use uicfg or '
                  'override editable_relations instead' % classid(self),
--- a/web/views/basetemplates.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/basetemplates.py	Wed Sep 28 09:27:42 2011 +0200
@@ -56,6 +56,9 @@
         self.wview('htmlheader', rset=self.cw_rset)
         w(u'<title>%s</title>\n' % xml_escape(page_title))
 
+    def content(self):
+        raise NotImplementedError()
+
 
 class LogInTemplate(LogInOutTemplate):
     __regid__ = 'login'
--- a/web/views/cwproperties.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/cwproperties.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
@@ -302,6 +302,7 @@
 
     def render(self, form, renderer):
         wdg = self.get_widget(form)
+        # pylint: disable=E1101
         wdg.attrs['tabindex'] = form._cw.next_tabindex()
         wdg.attrs['onchange'] = "javascript:setPropValueWidget('%s', %s)" % (
             form.edited_entity.eid, form._cw.next_tabindex())
@@ -337,7 +338,7 @@
         try:
             pdef = form._cw.vreg.property_info(entity.pkey)
         except UnknownProperty, ex:
-            self.warning('%s (you should probably delete that property '
+            form.warning('%s (you should probably delete that property '
                          'from the database)', ex)
             msg = form._cw._('you should probably delete that property')
             self.widget = NotEditableWidget(entity.printable_value('value'),
--- a/web/views/cwuser.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/cwuser.py	Wed Sep 28 09:27:42 2011 +0200
@@ -20,7 +20,7 @@
 __docformat__ = "restructuredtext en"
 _ = unicode
 
-import hashlib
+from hashlib import sha1 # pylint: disable=E0611
 
 from logilab.mtconverter import xml_escape
 
@@ -86,7 +86,7 @@
         emailaddr = entity.cw_adapt_to('IEmailable').get_email()
         if emailaddr:
             self.w(u'<foaf:mbox_sha1sum>%s</foaf:mbox_sha1sum>\n'
-                   % hashlib.sha1(emailaddr.encode('utf-8')).hexdigest())
+                   % sha1(emailaddr.encode('utf-8')).hexdigest())
         self.w(u'</foaf:Person>\n')
 
 
--- a/web/views/idownloadable.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/idownloadable.py	Wed Sep 28 09:27:42 2011 +0200
@@ -194,7 +194,7 @@
     def cell_call(self, row, col, link=False, **kwargs):
         entity = self.cw_rset.get_entity(row, col)
         adapter = entity.cw_adapt_to('IDownloadable')
-        tag = self._embedding_tag(src=adapter.download_url(),
+        tag = self._embedding_tag(src=adapter.download_url(), # pylint: disable=E1102
                                   alt=(self._cw._('download %s') % adapter.download_file_name()),
                                   **kwargs)
         if link:
--- a/web/views/plots.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/plots.py	Wed Sep 28 09:27:42 2011 +0200
@@ -79,6 +79,9 @@
         if w is None:
             return self._stream.getvalue()
 
+    def _render(self, *args, **kwargs):
+        raise NotImplementedError
+
 class FlotPlotWidget(PlotWidget):
     """PlotRenderer widget using Flot"""
     onload = u"""
--- a/web/views/primary.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/primary.py	Wed Sep 28 09:27:42 2011 +0200
@@ -130,7 +130,8 @@
         if hasattr(self, 'render_entity_summary'):
             warn('[3.10] render_entity_summary method is deprecated (%s)' % self,
                  DeprecationWarning)
-            self.render_entity_summary(entity)
+            self.render_entity_summary(entity) # pylint: disable=E1101
+
         summary = self.summary(entity)
         if summary:
             warn('[3.10] summary method is deprecated (%s)' % self,
@@ -149,7 +150,7 @@
             self.w(u'<div class="primaryRight">')
             if hasattr(self, 'render_side_related'):
                 warn('[3.2] render_side_related is deprecated')
-                self.render_side_related(entity, [])
+                self.render_side_related(entity, []) # pylint: disable=E1101
             self.render_side_boxes(boxes)
             self.w(u'</div>')
             self.w(u'</td></tr></table>')
@@ -217,20 +218,21 @@
         if display_attributes:
             self.w(u'<table>')
             for rschema, role, dispctrl, value in display_attributes:
+                # pylint: disable=E1101
                 if not hasattr(self, '_render_attribute'):
                     label = self._rel_label(entity, rschema, role, dispctrl)
                     self.render_attribute(label, value, table=True)
                 elif support_args(self._render_attribute, 'dispctrl'):
                     warn('[3.9] _render_attribute prototype has changed and '
                          'renamed to render_attribute, please update %s'
-                         % self.__class___, DeprecationWarning)
+                         % self.__class__, DeprecationWarning)
                     self._render_attribute(dispctrl, rschema, value, role=role,
                                            table=True)
                 else:
                     self._render_attribute(rschema, value, role=role, table=True)
                     warn('[3.6] _render_attribute prototype has changed and '
                          'renamed to render_attribute, please update %s'
-                         % self.__class___, DeprecationWarning)
+                         % self.__class__, DeprecationWarning)
             self.w(u'</table>')
 
     def render_attribute(self, label, value, table=False):
@@ -255,6 +257,7 @@
                 if not rset:
                     continue
                 if hasattr(self, '_render_relation'):
+                    # pylint: disable=E1101
                     if not support_args(self._render_relation, 'showlabel'):
                         self._render_relation(dispctrl, rset, 'autolimited')
                         warn('[3.9] _render_relation prototype has changed and has '
@@ -431,7 +434,7 @@
     __regid__ = 'attribute'
     __select__ = EntityView.__select__ & match_kwargs('rtype')
 
-    def entity_call(self, entity, rtype, **kwargs):
+    def entity_call(self, entity, rtype, role, **kwargs):
         if self._cw.vreg.schema.rschema(rtype).final:
             self.w(entity.printable_value(rtype))
         else:
--- a/web/views/reledit.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/reledit.py	Wed Sep 28 09:27:42 2011 +0200
@@ -106,13 +106,15 @@
     def _handle_attribute(self, rschema, role, divid, reload, action):
         rvid = self._rules.get('rvid', None)
         if rvid is not None:
-            value = self._cw.view(rvid, entity=self.entity, rtype=rschema.type)
+            value = self._cw.view(rvid, entity=self.entity,
+                                  rtype=rschema.type, role=role)
         else:
             value = self.entity.printable_value(rschema.type)
         if not self._should_edit_attribute(rschema):
             self.w(value)
             return
-        form, renderer = self._build_form(self.entity, rschema, role, divid, 'base', reload, action)
+        form, renderer = self._build_form(self.entity, rschema, role, divid,
+                                          'base', reload, action)
         value = value or self._compute_default_value(rschema, role)
         self.view_form(divid, value, form, renderer)
 
--- a/web/views/tabs.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/tabs.py	Wed Sep 28 09:27:42 2011 +0200
@@ -190,6 +190,8 @@
     """
     __select__ = EntityView.__select__ & partial_has_related_entities()
     vid = 'list'
+    # to be defined in concrete classes
+    rtype = title = None
 
     def cell_call(self, row, col):
         rset = self.cw_rset.get_entity(row, col).related(self.rtype, role(self))
--- a/web/views/treeview.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/treeview.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.
--- a/web/views/workflow.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/web/views/workflow.py	Wed Sep 28 09:27:42 2011 +0200
@@ -174,6 +174,7 @@
             warn('[3.10] %s should now implement render_body instead of cell_call'
                  % self.__class__, DeprecationWarning)
             self.w = w
+            # pylint: disable=E1101
             self.cell_call(self.entity.cw_row, self.entity.cw_col)
         else:
             self.entity.view('wfhistory', w=w, title=None)
--- a/wsgi/request.py	Tue Sep 27 16:04:30 2011 +0200
+++ b/wsgi/request.py	Wed Sep 28 09:27:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
 #
 # This file is part of CubicWeb.