diff --git a/addons/mail/models/html2text.py b/addons/mail/models/html2text.py
index fb16b1fbda0..11844ef7720 100755
--- a/addons/mail/models/html2text.py
+++ b/addons/mail/models/html2text.py
@@ -187,16 +187,16 @@ class _html2text(sgmllib.SGMLParser):
If the set of attributes is not found, returns None
"""
- if not attrs.has_key('href'): return None
+ if 'href' not in attrs: return None
i = -1
for a in self.a:
i += 1
match = 0
- if a.has_key('href') and a['href'] == attrs['href']:
- if a.has_key('title') or attrs.has_key('title'):
- if (a.has_key('title') and attrs.has_key('title') and
+ if 'href' in a and a['href'] == attrs['href']:
+ if 'title' in a or 'title' in attrs:
+ if ('title' in a and 'title' in attrs and
a['title'] == attrs['title']):
match = True
else:
@@ -246,7 +246,7 @@ class _html2text(sgmllib.SGMLParser):
self.abbr_title = None
self.abbr_data = ''
- if attrs.has_key('title'):
+ if 'title' in attrs:
self.abbr_title = attrs['title']
else:
if self.abbr_title != None:
@@ -259,7 +259,7 @@ class _html2text(sgmllib.SGMLParser):
attrsD = {}
for (x, y) in attrs: attrsD[x] = y
attrs = attrsD
- if attrs.has_key('href') and not (SKIP_INTERNAL_LINKS and attrs['href'].startswith('#')):
+ if 'href' in attrs and not (SKIP_INTERNAL_LINKS and attrs['href'].startswith('#')):
self.astack.append(attrs)
self.o("[")
else:
@@ -282,7 +282,7 @@ class _html2text(sgmllib.SGMLParser):
attrsD = {}
for (x, y) in attrs: attrsD[x] = y
attrs = attrsD
- if attrs.has_key('src'):
+ if 'src' in attrs:
attrs['href'] = attrs['src']
alt = attrs.get('alt', '')
i = self.previousIndex(attrs)
@@ -390,7 +390,7 @@ class _html2text(sgmllib.SGMLParser):
for link in self.a:
if self.outcount > link['outcount']:
self.out(" ["+repr(link['count'])+"]: " + urlparse.urljoin(self.baseurl, link['href']))
- if link.has_key('title'): self.out(" ("+link['title']+")")
+ if 'title' in link: self.out(" ("+link['title']+")")
self.out("\n")
else:
newa.append(link)
diff --git a/doc/python3.rst b/doc/python3.rst
index 55047f16d4b..b339e0a98b0 100644
--- a/doc/python3.rst
+++ b/doc/python3.rst
@@ -98,3 +98,14 @@ Removed Operators
These two operators were long recommended against/deprecated in Python 2,
Python 3 removed them from the language.
+
+Removed/renamed methods
+-----------------------
+
+.. important::
+
+ * the ``has_key`` method on dicts must be replaced by use of the ``in``
+ operator e.g. ``foo.has_key(bar)`` becomes ``bar in foo``.
+
+``in`` for dicts was introduced in Python 2.3, leading to ``has_key`` being
+redundant, and removed in Python 3.
diff --git a/odoo/tools/amount_to_text.py b/odoo/tools/amount_to_text.py
index 8e89b48fbc4..6916306bf99 100644
--- a/odoo/tools/amount_to_text.py
+++ b/odoo/tools/amount_to_text.py
@@ -161,7 +161,7 @@ def amount_to_text(nbr, lang='fr', currency='euro'):
# print "WARNING: number too large '%d', can't translate it!" % (nbr,)
# return str(nbr)
- if not _translate_funcs.has_key(lang):
+ if lang not in _translate_funcs:
#TODO: use logger
print "WARNING: no translation function found for lang: '%s'" % (lang,)
#TODO: (default should be en) same as above
diff --git a/odoo/tools/amount_to_text_en.py b/odoo/tools/amount_to_text_en.py
index 3dd138f43fa..c69e0204132 100644
--- a/odoo/tools/amount_to_text_en.py
+++ b/odoo/tools/amount_to_text_en.py
@@ -94,7 +94,7 @@ def amount_to_text(nbr, lang='en', currency='euro'):
# _logger.warning(_("Number too large '%d', can not translate it"))
# return str(nbr)
- if not _translate_funcs.has_key(lang):
+ if lang not in _translate_funcs:
_logger.warning(_("no translation function found for lang: '%s'"), lang)
#TODO: (default should be en) same as above
lang = 'en'
diff --git a/odoo/tools/config.py b/odoo/tools/config.py
index 5056ae77880..dcbad18edb2 100644
--- a/odoo/tools/config.py
+++ b/odoo/tools/config.py
@@ -510,8 +510,7 @@ class configmanager(object):
for sec in p.sections():
if sec == 'options':
continue
- if not self.misc.has_key(sec):
- self.misc[sec]= {}
+ self.misc.setdefault(sec, {})
for (name, value) in p.items(sec):
if value=='True' or value=='true':
value = True
diff --git a/odoo/tools/import_email.py b/odoo/tools/import_email.py
index 0e7926aeb0a..4178ca14a06 100644
--- a/odoo/tools/import_email.py
+++ b/odoo/tools/import_email.py
@@ -62,7 +62,7 @@ class ReceiverEmail2Event(object):
def get_addresses(self, headers, msg):
hcontent = ''
- for header in [h for h in headers if msg.has_key(h)]:
+ for header in [h for h in headers if h in msg]:
hcontent += msg[header]
return self.email_re.findall(hcontent)
diff --git a/odoo/tools/misc.py b/odoo/tools/misc.py
index e84b139f81d..e0456a8429b 100644
--- a/odoo/tools/misc.py
+++ b/odoo/tools/misc.py
@@ -355,123 +355,6 @@ try:
except ImportError:
xlwt = None
-
-class UpdateableStr(local):
- """ Class that stores an updateable string (used in wizards)
- """
-
- def __init__(self, string=''):
- self.string = string
-
- def __str__(self):
- return str(self.string)
-
- def __repr__(self):
- return str(self.string)
-
- def __nonzero__(self):
- return bool(self.string)
-
-
-class UpdateableDict(local):
- """Stores an updateable dict to use in wizards
- """
-
- def __init__(self, dict=None):
- if dict is None:
- dict = {}
- self.dict = dict
-
- def __str__(self):
- return str(self.dict)
-
- def __repr__(self):
- return str(self.dict)
-
- def clear(self):
- return self.dict.clear()
-
- def keys(self):
- return self.dict.keys()
-
- def __setitem__(self, i, y):
- self.dict.__setitem__(i, y)
-
- def __getitem__(self, i):
- return self.dict.__getitem__(i)
-
- def copy(self):
- return self.dict.copy()
-
- def iteritems(self):
- return self.dict.iteritems()
-
- def iterkeys(self):
- return self.dict.iterkeys()
-
- def itervalues(self):
- return self.dict.itervalues()
-
- def pop(self, k, d=None):
- return self.dict.pop(k, d)
-
- def popitem(self):
- return self.dict.popitem()
-
- def setdefault(self, k, d=None):
- return self.dict.setdefault(k, d)
-
- def update(self, E, **F):
- return self.dict.update(E, F)
-
- def values(self):
- return self.dict.values()
-
- def get(self, k, d=None):
- return self.dict.get(k, d)
-
- def has_key(self, k):
- return self.dict.has_key(k)
-
- def items(self):
- return self.dict.items()
-
- def __cmp__(self, y):
- return self.dict.__cmp__(y)
-
- def __contains__(self, k):
- return self.dict.__contains__(k)
-
- def __delitem__(self, y):
- return self.dict.__delitem__(y)
-
- def __eq__(self, y):
- return self.dict.__eq__(y)
-
- def __ge__(self, y):
- return self.dict.__ge__(y)
-
- def __gt__(self, y):
- return self.dict.__gt__(y)
-
- def __hash__(self):
- return self.dict.__hash__()
-
- def __iter__(self):
- return self.dict.__iter__()
-
- def __le__(self, y):
- return self.dict.__le__(y)
-
- def __len__(self):
- return self.dict.__len__()
-
- def __lt__(self, y):
- return self.dict.__lt__(y)
-
- def __ne__(self, y):
- return self.dict.__ne__(y)
-
def to_xml(s):
return s.replace('&','&').replace('<','<').replace('>','>')