diff --git a/addons/stock/tests/test_shipment.py b/addons/stock/tests/test_shipment.py
index 4af36692260e46e4286f747a61cb6040b02295dc..b63c9ea56ddf0df64b04937d20dadcdb59ca2013 100644
--- a/addons/stock/tests/test_shipment.py
+++ b/addons/stock/tests/test_shipment.py
@@ -6,7 +6,6 @@ from odoo.addons.stock.tests.common2 import TestStockCommon
 class TestInventory(TestStockCommon):
 
     def test_shipment(self):
-        # TDE NOTE: this test replaces test/shipment.yml present until saas-10
         # TDE TODO
         # pickign.action_confirm -> confirm moves
         # picking.do_prepare_partial, should create pack ops, write on it ?
diff --git a/odoo/addons/test_impex/__manifest__.py b/odoo/addons/test_impex/__manifest__.py
index f2ce6cd1111595936fff78e8d7259d9dd86b736d..4ace0a66a530bb84fe20e184691319ef24d868c3 100644
--- a/odoo/addons/test_impex/__manifest__.py
+++ b/odoo/addons/test_impex/__manifest__.py
@@ -8,8 +8,4 @@
     'data': ['ir.model.access.csv'],
     'installable': True,
     'auto_install': False,
-    'test': [
-        'tests/test_import_reference.yml',
-        'tests/test_import_menuitem.yml',
-    ]
 }
diff --git a/odoo/addons/test_impex/tests/test_import_menuitem.yml b/odoo/addons/test_impex/tests/test_import_menuitem.yml
deleted file mode 100644
index 15703e0c004da4c9f22cbd8314fd573a9ebeefbb..0000000000000000000000000000000000000000
--- a/odoo/addons/test_impex/tests/test_import_menuitem.yml
+++ /dev/null
@@ -1,67 +0,0 @@
--   |
-    YAML Import menuitem scenario:
-    Check that !menuitem import works with YAML.
-
--   |
-    Given a standard three level menuitem structure including:
-
-    A top level menu item (no parent no action)
--
-    !menuitem {
-        id: test_menu_top,
-        name: "Test Menu Top",
-    }
--   >
-    An intermediary menu item (parent, but no action)
--
-    !menuitem {
-        id: test_menu_sub,
-        parent: test_menu_top,
-        name: "Test Menu Sub",
-    }
-
--   >
-    A leaf menu item (parent and action)
--
-    !menuitem {
-        id: test_menu_action,
-        name: "Test Menu Action",
-        parent: test_menu_sub,
-        action: base.open_module_tree,
-    }
-
--   >
-    Another leaf menu item (parent and action) in another menu structure with
-    dotted parent id
--
-    !menuitem {
-        id: test_menu_action_2,
-        name: "Test Menu Action 2",
-        parent: base.menu_management,
-        action: base.open_module_tree,
-        sequence: 93,
-    }
-
--   >
-    Then these menu items should be present and properly configured.
--
-    !assert { model: ir.ui.menu, id: test_menu_top, string: menu item "top" is properly configured }:
-        - name == 'Test Menu Top'
-        - parent_id.name == False
-        - action == False
--
-    !assert { model: ir.ui.menu, id: test_menu_sub, string: menu item "sub" is properly configured }:
-        - name == 'Test Menu Sub'
-        - parent_id.name == 'Test Menu Top'
-        - action == False
--
-    !assert { model: ir.ui.menu, id: test_menu_action, string: menu item "action" is properly configured  }:
-        - name == 'Test Menu Action'
-        - parent_id.name == 'Test Menu Sub'
-        - action.name == 'Apps'
--
-    !assert { model: ir.ui.menu, id: test_menu_action_2, string: menu item "action_2" is properly configured  }:
-        - name == 'Test Menu Action 2'
-        - sequence == 93
-        - parent_id.name == 'Apps'
-        - action.name == 'Apps'
diff --git a/odoo/addons/test_impex/tests/test_import_reference.yml b/odoo/addons/test_impex/tests/test_import_reference.yml
deleted file mode 100644
index d6a101725a809b7ae605e3330661560ff180b490..0000000000000000000000000000000000000000
--- a/odoo/addons/test_impex/tests/test_import_reference.yml
+++ /dev/null
@@ -1,44 +0,0 @@
--   |
-    YAML Import reference scenario:
-    Check that importing into a "reference" type field works with YAML using
-    both implicit references and !ref.
-
--   |
-    Given records imitating menu entries similar to the following entry from the base module:
-    <menuitem id="menu_module_tree" parent="menu_management" name="Apps"
-              sequence="5" action="open_module_tree" />
-
-    taken from odoo/addons/base/module/module_view.xml
-
--   >
-    A Menu item using !record and implicit xml_id lookup and sequence cast:
--
-    !record { model: ir.ui.menu, id: test_menu_0 }:
-        name: "Local Modules 0"
-        parent_id: base.menu_management
-        sequence: 90
-        action: base.open_module_tree
-
--   >
-    A Menu item using !record and explicit !ref and sequence !eval
--
-    !record { model: ir.ui.menu, id: test_menu_1 }:
-        name: "Local Modules 1"
-        parent_id: !refid base.menu_management
-        sequence: !eval 91
-        action: !refid base.open_module_tree
--   >
-    Then these menu items should be present, properly configured and
-    pointing to the same action.
--
-    !assert { model: ir.ui.menu, id: test_menu_0, string: menu item 0 is properly configured }:
-        - name == 'Local Modules 0'
-        - sequence == 90
-        - parent_id.name == 'Apps'
-        - action.name == 'Apps'
--
-    !assert { model: ir.ui.menu, id: test_menu_1, string: menu item 1 is properly configured }:
-        - name == 'Local Modules 1'
-        - sequence == 91
-        - parent_id.name == 'Apps'
-        - action.name == 'Apps'
diff --git a/odoo/modules/loading.py b/odoo/modules/loading.py
index d8ee12c169043ada584c168c45dfa7489783ae0f..14a71b49e7637ae74426bdc8c922d9c67d8fada4 100644
--- a/odoo/modules/loading.py
+++ b/odoo/modules/loading.py
@@ -65,7 +65,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
                 files.append(f)
                 if k.endswith('_xml') and not (k == 'init_xml' and not f.endswith('.xml')):
                     # init_xml, update_xml and demo_xml are deprecated except
-                    # for the case of init_xml with yaml, csv and sql files as
+                    # for the case of init_xml with csv and sql files as
                     # we can't specify noupdate for those file.
                     correct_key = 'demo' if k.count('demo') else 'data'
                     _logger.warning(
diff --git a/odoo/service/server.py b/odoo/service/server.py
index 70141644b8102ccb9edef55ec528dadc08e472c2..12777da544353b7b6c034a36551091853d11dae3 100644
--- a/odoo/service/server.py
+++ b/odoo/service/server.py
@@ -884,16 +884,6 @@ def _reexec(updated_modules=None):
         args.insert(0, exe)
     os.execv(sys.executable, args)
 
-def load_test_file_yml(registry, test_file):
-    with registry.cursor() as cr:
-        odoo.tools.convert_yaml_import(cr, 'base', open(test_file, 'rb'), 'test', {}, 'init')
-        if config['test_commit']:
-            _logger.info('test %s has been commited', test_file)
-            cr.commit()
-        else:
-            _logger.info('test %s has been rollbacked', test_file)
-            cr.rollback()
-
 def load_test_file_py(registry, test_file):
     # Locate python module based on its filename and run the tests
     test_path, _ = os.path.splitext(os.path.abspath(test_file))
@@ -928,9 +918,7 @@ def preload_registries(dbnames):
                 test_file = config['test_file']
                 _logger.info('loading test file %s', test_file)
                 with odoo.api.Environment.manage():
-                    if test_file.endswith('yml'):
-                        load_test_file_yml(registry, test_file)
-                    elif test_file.endswith('py'):
+                    if test_file.endswith('py'):
                         load_test_file_py(registry, test_file)
 
             # run post-install tests
diff --git a/odoo/tools/__init__.py b/odoo/tools/__init__.py
index b2f2dc522530a0b204841007b2a3e1d7088b8504..1719cb5b80df287c678757cdc98740ba6a4e81e0 100644
--- a/odoo/tools/__init__.py
+++ b/odoo/tools/__init__.py
@@ -11,7 +11,6 @@ from .convert import *
 from .translate import *
 from .graph import graph
 from .image import *
-from .yaml_import import *
 from .sql import *
 from .float_utils import *
 from .mail import *
diff --git a/odoo/tools/assertion_report.py b/odoo/tools/assertion_report.py
index 729309915277cf958efcd8cd82e825939d5507f3..638d2f3aeea7d0edfd74fb11445a2ee117314510 100644
--- a/odoo/tools/assertion_report.py
+++ b/odoo/tools/assertion_report.py
@@ -1,7 +1,7 @@
 
 class assertion_report(object):
     """
-    Simple pair of success and failures counts (used to record YAML and XML
+    Simple pair of success and failures counts (used to record XML
     `assert` tags as well as unittest tests outcome (in this case, not
     individual `assert`)).
     """
diff --git a/odoo/tools/config.py b/odoo/tools/config.py
index 288e29f4464f20d4113e8d09f4762a36b1db6e04..43d11f7b532a123744626cbe76f64f014b52b8f8 100644
--- a/odoo/tools/config.py
+++ b/odoo/tools/config.py
@@ -154,13 +154,13 @@ class configmanager(object):
         # Testing Group
         group = optparse.OptionGroup(parser, "Testing Configuration")
         group.add_option("--test-file", dest="test_file", my_default=False,
-                         help="Launch a python or YML test file.")
+                         help="Launch a python test file.")
         group.add_option("--test-report-directory", dest="test_report_directory", my_default=False,
                          help="If set, will save sample of all reports in this directory.")
         group.add_option("--test-enable", action="store_true", dest="test_enable",
-                         my_default=False, help="Enable YAML and unit tests.")
+                         my_default=False, help="Enable unit tests.")
         group.add_option("--test-commit", action="store_true", dest="test_commit",
-                         my_default=False, help="Commit database changes performed by YAML or XML tests.")
+                         my_default=False, help="Commit database changes performed by XML tests.")
         parser.add_option_group(group)
 
         # Logging Group
diff --git a/odoo/tools/convert.py b/odoo/tools/convert.py
index 6045b70cff68ba2979a3bdcc58c6c786bbbaa564..9a46a88f1754086347d5f15e31b4d62cef6b30d1 100644
--- a/odoo/tools/convert.py
+++ b/odoo/tools/convert.py
@@ -19,7 +19,6 @@ from . import assertion_report, pycompat
 from .config import config
 from .misc import file_open, unquote, ustr, SKIPPED_ELEMENT_TYPES
 from .translate import _
-from .yaml_import import convert_yaml_import
 from odoo import SUPERUSER_ID
 
 _logger = logging.getLogger(__name__)
@@ -786,8 +785,6 @@ def convert_file(cr, module, filename, idref, mode='update', noupdate=False, kin
             convert_csv_import(cr, module, pathname, fp.read(), idref, mode, noupdate)
         elif ext == '.sql':
             convert_sql_import(cr, fp)
-        elif ext == '.yml':
-            convert_yaml_import(cr, module, fp, kind, idref, mode, noupdate, report)
         elif ext == '.xml':
             convert_xml_import(cr, module, fp, idref, mode, noupdate, report)
         elif ext == '.js':
diff --git a/odoo/tools/test_reports.py b/odoo/tools/test_reports.py
index a3588577c08e9c4446e3a899e6d8fad3d46ffdc7..6b9b21d18c03986422a6c18ab23df6da77e24fc4 100644
--- a/odoo/tools/test_reports.py
+++ b/odoo/tools/test_reports.py
@@ -4,7 +4,7 @@
 """ Helper functions for reports testing.
 
     Please /do not/ import this file by default, but only explicitly call it
-    through the code of yaml tests.
+    through the code of python tests.
 """
 
 import logging
diff --git a/odoo/tools/yaml_import.py b/odoo/tools/yaml_import.py
deleted file mode 100644
index b87c3bcf4b4550c300b79a1f7cc5abfec54ca0d1..0000000000000000000000000000000000000000
--- a/odoo/tools/yaml_import.py
+++ /dev/null
@@ -1,857 +0,0 @@
-# -*- coding: utf-8 -*-
-# Part of Odoo. See LICENSE file for full copyright and licensing details.
-
-from collections import OrderedDict
-from datetime import datetime, timedelta
-import logging
-import re
-import time # used to eval time.strftime expressions
-import types
-
-from lxml import etree
-import yaml
-
-import odoo
-from . import assertion_report, pycompat, yaml_tag
-from .config import config
-from .misc import file_open, DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
-from odoo import SUPERUSER_ID
-
-# YAML import needs both safe and unsafe eval, but let's
-# default to /safe/.
-unsafe_eval = eval
-from .safe_eval import safe_eval
-
-_logger = logging.getLogger(__name__)
-
-class YamlImportException(Exception):
-    pass
-
-class YamlImportAbortion(Exception):
-    pass
-
-def _is_yaml_mapping(node, tag_constructor):
-    value = isinstance(node, dict) \
-        and len(node) == 1 \
-        and isinstance(next(iter(node)), tag_constructor)
-    return value
-
-def is_comment(node):
-    return isinstance(node, pycompat.string_types)
-
-def is_assert(node):
-    return isinstance(node, yaml_tag.Assert) \
-        or _is_yaml_mapping(node, yaml_tag.Assert)
-
-def is_record(node):
-    return _is_yaml_mapping(node, yaml_tag.Record)
-
-def is_python(node):
-    return _is_yaml_mapping(node, yaml_tag.Python)
-
-def is_menuitem(node):
-    return isinstance(node, yaml_tag.Menuitem) \
-        or _is_yaml_mapping(node, yaml_tag.Menuitem)
-
-def is_function(node):
-    return isinstance(node, yaml_tag.Function) \
-        or _is_yaml_mapping(node, yaml_tag.Function)
-
-def is_report(node):
-    return isinstance(node, yaml_tag.Report)
-
-def is_act_window(node):
-    return isinstance(node, yaml_tag.ActWindow)
-
-def is_delete(node):
-    return isinstance(node, yaml_tag.Delete)
-
-def is_context(node):
-    return isinstance(node, yaml_tag.Context)
-
-def is_url(node):
-    return isinstance(node, yaml_tag.Url)
-
-def is_eval(node):
-    return isinstance(node, yaml_tag.Eval)
-
-def is_ref(node):
-    return isinstance(node, yaml_tag.Ref) \
-        or _is_yaml_mapping(node, yaml_tag.Ref)
-
-def is_string(node):
-    return isinstance(node, pycompat.string_types)
-
-class RecordDictWrapper(dict):
-    """
-    Used to pass a record as locals in eval:
-    records do not strictly behave like dict, so we force them to.
-    """
-    def __init__(self, record):
-        self.record = record
-    def __getitem__(self, key):
-        if key in self.record:
-            return self.record[key]
-        return dict.__getitem__(self, key)
-
-class YamlInterpreter(object):
-    def __init__(self, cr, module, id_map, mode, filename, report=None, noupdate=False, loglevel=logging.DEBUG):
-        self.cr = cr
-        self.module = module
-        self.id_map = id_map
-        self.mode = mode
-        self.filename = filename
-        if report is None:
-            report = assertion_report.assertion_report()
-        self.assertion_report = report
-        self.noupdate = noupdate
-        self.loglevel = loglevel
-        self.uid = SUPERUSER_ID
-        self.context = {} # opererp context
-        self.eval_context = {'ref': self.get_id,
-                             '_ref': self.get_id, # added '_ref' so that record['ref'] is possible
-                             'time': time,
-                             'datetime': datetime,
-                             'timedelta': timedelta}
-        self.env = odoo.api.Environment(self.cr, self.uid, self.context)
-        self.sudo_env = self.env
-
-    def _log(self, *args, **kwargs):
-        _logger.log(self.loglevel, *args, **kwargs)
-
-    def validate_xml_id(self, xml_id):
-        id = xml_id
-        if '.' in xml_id:
-            module, id = xml_id.split('.', 1)
-            assert '.' not in id, "The ID reference '%s' must contain at most one dot.\n" \
-                                  "It is used to refer to other modules ID, in the form: module.record_id" \
-                                  % (xml_id,)
-            if module != self.module:
-                module_count = self.env['ir.module.module'].search_count([('name', '=', module), ('state', '=', 'installed')])
-                assert module_count == 1, 'The ID "%s" refers to an uninstalled module.' % (xml_id,)
-
-    def get_id(self, xml_id):
-        if xml_id is False or xml_id is None:
-            return False
-        #if not xml_id:
-        #    raise YamlImportException("The xml_id should be a non empty string.")
-        elif isinstance(xml_id, int):
-            id = xml_id
-        elif xml_id in self.id_map:
-            id = self.id_map[xml_id]
-        else:
-            full_xml_id = xml_id
-            if '.' not in full_xml_id:
-                full_xml_id = self.module + '.' + full_xml_id
-            try:
-                id = self.env.ref(full_xml_id).id
-                self.id_map[xml_id] = id
-            except ValueError:
-                raise ValueError("""%r not found when processing %s.
-    This Yaml file appears to depend on missing data. This often happens for
-    tests that belong to a module's test suite and depend on each other.""" % (xml_id, self.filename))
-
-        return id
-
-    def get_record(self, xml_id):
-        if '.' not in xml_id:
-            xml_id = "%s.%s" % (self.module, xml_id)
-        return self.env.ref(xml_id)
-
-    def get_context(self, node, eval_dict):
-        context = self.context.copy()
-        if node.context:
-            context.update(safe_eval(node.context, eval_dict))
-        return context
-
-    def isnoupdate(self, node):
-        return self.noupdate or node.noupdate or False
-
-    def _get_first_result(self, results, default=False):
-        if len(results):
-            value = results[0]
-            if isinstance(value, tuple):
-                value = value[0]
-        else:
-            value = default
-        return value
-
-    def process_comment(self, node):
-        return node
-
-    def _log_assert_failure(self, msg, *args):
-        self.assertion_report.record_failure()
-        _logger.error(msg, *args)
-
-    def _get_assertion_id(self, assertion):
-        if assertion.id:
-            ids = [self.get_id(assertion.id)]
-        elif assertion.search:
-            q = safe_eval(assertion.search, self.eval_context)
-            ids = self.env(context=assertion.context)[assertion.model].search(q)
-        else:
-            raise YamlImportException('Nothing to assert: you must give either an id or a search criteria.')
-        return ids
-
-    def process_assert(self, node):
-        if isinstance(node, dict):
-            assertion, expressions = list(node.items())[0]
-        else:
-            assertion, expressions = node, []
-
-        if self.isnoupdate(assertion) and self.mode != 'init':
-            _logger.warning('This assertion was not evaluated ("%s").', assertion.string)
-            return
-        model = self.env[assertion.model]
-        ids = self._get_assertion_id(assertion)
-        if assertion.count is not None and len(ids) != assertion.count:
-            msg = 'assertion "%s" failed!\n'   \
-                  ' Incorrect search count:\n' \
-                  ' expected count: %d\n'      \
-                  ' obtained count: %d\n'
-            args = (assertion.string, assertion.count, len(ids))
-            self._log_assert_failure(msg, *args)
-        else:
-            context = self.get_context(assertion, self.eval_context)
-            records = model.with_context(context).browse(ids)
-            for record in records:
-                for test in expressions:
-                    try:
-                        success = unsafe_eval(test, self.eval_context, RecordDictWrapper(record))
-                    except Exception as e:
-                        _logger.debug('Exception during evaluation of !assert block in yaml_file %s.', self.filename, exc_info=True)
-                        raise YamlImportAbortion(e)
-                    if not success:
-                        msg = 'Assertion "%s" FAILED\ntest: %s\n'
-                        args = (assertion.string, test)
-                        for aop in ('==', '!=', '<>', 'in', 'not in', '>=', '<=', '>', '<'):
-                            if aop in test:
-                                left, right = test.split(aop,1)
-                                lmsg = ''
-                                rmsg = ''
-                                try:
-                                    lmsg = unsafe_eval(left, self.eval_context, RecordDictWrapper(record))
-                                except Exception as e:
-                                    lmsg = '<exc>'
-
-                                try:
-                                    rmsg = unsafe_eval(right, self.eval_context, RecordDictWrapper(record))
-                                except Exception as e:
-                                    rmsg = '<exc>'
-
-                                msg += 'values: ! %s %s %s'
-                                args += ( lmsg, aop, rmsg )
-                                break
-
-                        self._log_assert_failure(msg, *args)
-                        return
-            else: # all tests were successful for this assertion tag (no break)
-                self.assertion_report.record_success()
-
-    def _coerce_bool(self, value, default=False):
-        if isinstance(value, bool):
-            b = value
-        if isinstance(value, str):
-            b = value.strip().lower() not in ('0', 'false', 'off', 'no')
-        elif isinstance(value, int):
-            b = bool(value)
-        else:
-            b = default
-        return b
-
-    def create_osv_memory_record(self, record, fields):
-        model = self.env[record.model]
-        context = self.get_context(record, self.eval_context)
-        record_dict = self._create_record(model, fields, context=context)
-        id_new = model.with_context(context).create(record_dict).id
-        self.id_map[record.id] = int(id_new)
-        return record_dict
-
-    def process_record(self, node):
-        record, fields = list(node.items())[0]
-        model = self.env[record.model]
-        view_id = record.view
-        if view_id and (view_id is not True) and isinstance(view_id, pycompat.string_types):
-            if '.' not in view_id:
-                view_id = self.module + '.' + view_id
-            view_id = self.env.ref(view_id).id
-
-        if model.is_transient():
-            record_dict=self.create_osv_memory_record(record, fields)
-        else:
-            self.validate_xml_id(record.id)
-            module = self.module
-            record_id = record.id
-            if '.' in record_id:
-                module, record_id = record_id.split('.',1)
-            try:
-                self.sudo_env['ir.model.data']._get_id(module, record_id)
-                default = False
-            except ValueError:
-                default = True
-
-            if self.isnoupdate(record) and self.mode != 'init':
-                id = self.sudo_env['ir.model.data']._update_dummy(record.model, module, record_id)
-                # check if the resource already existed at the last update
-                if id:
-                    self.id_map[record] = int(id)
-                    return None
-                else:
-                    if not self._coerce_bool(record.forcecreate):
-                        return None
-
-            #context = self.get_context(record, self.eval_context)
-            # FIXME: record.context like {'withoutemployee':True} should pass from self.eval_context. example: test_project.yml in project module
-            # TODO: cleaner way to avoid resetting password in auth_signup (makes user creation costly)
-            context = dict(record.context or {}, no_reset_password=True)
-            env = self.env(user=SUPERUSER_ID, context=context)
-            view_info = False
-            if view_id:
-                varg = view_id
-                if view_id is True: varg = False
-                view_info = model.with_env(env).fields_view_get(varg, 'form')
-
-            record_dict = self._create_record(model, fields, view_info, default=default, context=context)
-            id = env['ir.model.data']._update(record.model, \
-                    module, record_dict, record_id, noupdate=self.isnoupdate(record), mode=self.mode)
-            self.id_map[record.id] = int(id)
-            if config.get('import_partial'):
-                self.cr.commit()
-
-    def _create_record(self, model, fields, view_info=None, parent={}, default=True, context=None):
-        """This function processes the !record tag in yaml files. It simulates the record creation through an xml
-            view (either specified on the !record tag or the default one for this object), including the calls to
-            on_change() functions, and sending only values for fields that aren't set as readonly.
-            :param model: model instance (new API)
-            :param fields: dictionary mapping the field names and their values
-            :param view_info: result of fields_view_get() called on the object
-            :param parent: dictionary containing the values already computed for the parent, in case of one2many fields
-            :param default: if True, the default values must be processed too or not
-            :return: dictionary mapping the field names and their values, ready to use when calling the create() function
-            :rtype: dict
-        """
-        readonly_re = re.compile(r"""("readonly"|'readonly'): *true""")
-
-        class dotdict(object):
-            """ Dictionary class that allow to access a dictionary value by using '.'.
-                This is needed to eval correctly statements like 'parent.fieldname' in context.
-            """
-            def __init__(self, d):
-                self._dict = d
-            def __getattr__(self, attr):
-                return self._dict.get(attr, False)
-
-        def get_field_elems(view):
-            """ return the field elements from a view as an OrderedDict """
-            def traverse(node, elems):
-                if node.tag == 'field':
-                    elems[node.get('name')] = node
-                else:
-                    for child in node:
-                        traverse(child, elems)
-
-            elems = OrderedDict()
-            arch = view['arch']
-            if isinstance(arch, pycompat.text_type):
-                arch = arch.encode('utf-8')
-            traverse(etree.fromstring(arch), elems)
-            return elems
-
-        def is_readonly(field_elem):
-            """ return whether a given field is readonly """
-            # TODO: currently we only support if readonly is True in modifiers.
-            # Some improvement may be done in order to support modifiers like
-            # {"readonly": [["state", "not in", ["draft", "confirm"]]]}
-            return readonly_re.search(field_elem.get('modifiers', '{}'))
-
-        def get_2many_view(fg, field_name, view_type):
-            """ return a view of the given type for the given field's comodel """
-            fdesc = fg[field_name]
-            return fdesc['views'].get(view_type) or \
-                   self.sudo_env[fdesc['relation']].fields_view_get(False, view_type)
-
-        def process_vals(fg, vals):
-            """ sanitize the given field values """
-            result = {}
-            for field_name, field_value in vals.items():
-                if field_name not in fg:
-                    continue
-                if fg[field_name]['type'] == 'many2one' and isinstance(field_value, (tuple, list)):
-                    field_value = field_value[0]
-                elif fg[field_name]['type'] in ('one2many', 'many2many'):
-                    # 2many fields: sanitize field values of sub-records
-                    sub_fg = get_2many_view(fg, field_name, 'form')['fields']
-                    def process(command):
-                        if isinstance(command, (tuple, list)) and command[0] in (0, 1):
-                            return (command[0], command[1], process_vals(sub_fg, command[2]))
-                        elif isinstance(command, dict):
-                            return process_vals(sub_fg, command)
-                        return command
-                    field_value = [process(v) for v in (field_value or [])]
-                result[field_name] = field_value
-            return result
-
-        def post_process(fg, elems, vals):
-            """ filter out readonly fields from vals """
-            result = {}
-            for field_name, field_value in vals.items():
-                if is_readonly(elems[field_name]):
-                    continue
-                if fg[field_name]['type'] in ('one2many', 'many2many'):
-                    # 2many fields: filter field values of sub-records
-                    sub_view = get_2many_view(fg, field_name, 'form')
-                    sub_fg = sub_view['fields']
-                    sub_elems = get_field_elems(sub_view)
-                    def process(command):
-                        if isinstance(command, (tuple, list)) and command[0] in (0, 1):
-                            return (command[0], command[1], post_process(sub_fg, sub_elems, command[2]))
-                        elif isinstance(command, dict):
-                            return (0, 0, post_process(sub_fg, sub_elems, command))
-                        return command
-                    field_value = [process(v) for v in (field_value or [])]
-                result[field_name] = field_value
-            return result
-
-        context = context or {}
-        fields = fields or {}
-        parent_values = {context['field_parent']: parent} if context.get('field_parent') else {}
-
-        if view_info:
-            fg = view_info['fields']
-            elems = get_field_elems(view_info)
-            recs = model.sudo().with_context(**context)
-            onchange_spec = recs._onchange_spec(view_info)
-            record_dict = {}
-
-            if default:
-                # gather the default values on the object. (Can't use `fields´ as parameter instead of {} because we may
-                # have references like `base.main_company´ in the yaml file and it's not compatible with the function)
-                defaults = recs.sudo(self.uid)._add_missing_default_values({})
-
-                # copy the default values in record_dict, only if they are in the view (because that's what the client does)
-                # the other default values will be added later on by the create(). The other fields in the view that haven't any
-                # default value are set to False because we may have references to them in other field's context
-                record_dict = dict.fromkeys(fg, False)
-                record_dict.update(process_vals(fg, defaults))
-
-                # execute onchange on default values first
-                default_names = [name for name in elems if name in record_dict]
-                result = recs.onchange(dict(record_dict, **parent_values), default_names, onchange_spec)
-                record_dict.update(process_vals(fg, result.get('value', {})))
-
-            # fill in fields, and execute onchange where necessary
-            for field_name, field_elem in elems.items():
-                assert field_name in fg, "The field '%s' is defined in the form view but not on the object '%s'!" % (field_name, model._name)
-                if is_readonly(field_elem):
-                    # skip readonly fields
-                    continue
-
-                if field_name not in fields:
-                    continue
-
-                ctx = dict(context)
-                form_view = view_info
-                if fg[field_name]['type'] == 'one2many':
-                    # evaluate one2many fields using the inline form view defined in the parent
-                    form_view = get_2many_view(fg, field_name, 'form')
-                    ctx['field_parent'] = fg[field_name]['relation_field']
-                if default and field_elem.get('context'):
-                    ctx.update(safe_eval(field_elem.get('context'),
-                                         globals_dict={'parent': dotdict(parent)},
-                                         locals_dict=record_dict))
-
-                field_value = self._eval_field(model, field_name, fields[field_name], form_view, parent=record_dict, default=default, context=ctx)
-                record_dict.update(process_vals(fg, {field_name: field_value}))
-
-                # if field_name is given or has a default value, we evaluate its onchanges
-                if not field_elem.attrib.get('on_change', False):
-                    continue
-
-                result = recs.onchange(dict(record_dict, **parent_values), field_name, onchange_spec)
-                record_dict.update(process_vals(fg, {
-                    key: val
-                    for key, val in result.get('value', {}).items()
-                    if key not in fields        # do not shadow values explicitly set in yaml
-                }))
-
-            record_dict = post_process(fg, elems, record_dict)
-
-        else:
-            record_dict = {}
-
-        for field_name, expression in fields.items():
-            if record_dict.get(field_name):
-                continue
-            field_value = self._eval_field(model, field_name, expression, parent=record_dict, default=False, context=context)
-            record_dict[field_name] = field_value
-
-        # filter returned values; indeed the last modification in the import process have added a default
-        # value for all fields in the view; however some fields present in the view are not stored and
-        # should not be sent to create. This bug appears with not stored function fields in the new API.
-        return {
-            key: val
-            for key, val in record_dict.items()
-            for field in [model._fields[key].base_field]
-            if field.store or field.inverse
-        }
-
-    def process_ref(self, node, field=None):
-        assert node.search or node.id, '!ref node should have a `search` attribute or `id` attribute'
-        if node.search:
-            if node.model:
-                model_name = node.model
-            elif field:
-                model_name = field.comodel_name
-            else:
-                raise YamlImportException('You need to give a model for the search, or a field to infer it.')
-            model = self.env[model_name]
-            q = safe_eval(node.search, self.eval_context)
-            instances = model.search(q)
-            if node.use:
-                value = [inst[node.use] for inst in instances]
-            else:
-                value = instances.ids
-        elif node.id:
-            if field and field.type == 'reference':
-                record = self.get_record(node.id)
-                value = "%s,%s" % (record._name, record.id)
-            else:
-                value = self.get_id(node.id)
-        else:
-            value = None
-        return value
-
-    def process_eval(self, node):
-        return safe_eval(node.expression, self.eval_context)
-
-    def _eval_field(self, model, field_name, expression, view_info=False, parent={}, default=True, context=None):
-        # TODO this should be refactored as something like model.get_field() in bin/osv
-        if field_name not in model._fields:
-            raise KeyError("Object '%s' does not contain field '%s'" % (model, field_name))
-        field = model._fields[field_name]
-
-        if is_ref(expression):
-            elements = self.process_ref(expression, field)
-            if field.type in ("many2many", "one2many"):
-                value = [(6, 0, elements)]
-            else: # many2one or reference
-                if isinstance(elements, (list,tuple)):
-                    value = self._get_first_result(elements)
-                else:
-                    value = elements
-        elif field.type == "many2one":
-            value = self.get_id(expression)
-        elif field.type == "one2many":
-            comodel = self.env[field.comodel_name]
-            value = [(0, 0, self._create_record(comodel, fields, view_info, parent=parent, default=default, context=context)) for fields in expression]
-        elif field.type == "many2many":
-            ids = [self.get_id(xml_id) for xml_id in expression]
-            value = [(6, 0, ids)]
-        elif field.type == "date" and is_string(expression):
-            # enforce ISO format for string date values, to be locale-agnostic during tests
-            time.strptime(expression, DEFAULT_SERVER_DATE_FORMAT)
-            value = expression
-        elif field.type == "datetime" and is_string(expression):
-            # enforce ISO format for string datetime values, to be locale-agnostic during tests
-            time.strptime(expression, DEFAULT_SERVER_DATETIME_FORMAT)
-            value = expression
-        elif field.type == "reference":
-            record = self.get_record(expression)
-            value = "%s,%s" % (record._name, record.id)
-        else: # scalar field
-            if is_eval(expression):
-                value = self.process_eval(expression)
-            else:
-                value = expression
-            # raise YamlImportException('Unsupported field "%s" or value %s:%s' % (field_name, type(expression), expression))
-        return value
-
-    def process_context(self, node):
-        self.context = node.__dict__
-        if node.uid:
-            self.uid = self.get_id(node.uid)
-        if node.noupdate:
-            self.noupdate = node.noupdate
-        self.env = odoo.api.Environment(self.cr, self.uid, self.context)
-        self.sudo_env = self.env(user=SUPERUSER_ID)
-
-    def process_python(self, node):
-        python, statements = list(node.items())[0]
-        assert python.model or python.id, "!python node must have attribute `model` or `id`"
-        if python.id is None:
-            record = self.env[python.model]
-        elif isinstance(python.id, pycompat.string_types):
-            record = self.get_record(python.id)
-        else:
-            record = self.env[python.model].browse(python.id)
-        if python.model:
-            assert record._name == python.model, "`id` is not consistent with `model`"
-        statements = "\n" * python.first_line + statements.replace("\r\n", "\n")
-        code_context = {
-            'self': record,
-            'model': record,
-            'cr': self.cr,
-            'uid': self.uid,
-            'log': self._log,
-            'context': self.context,
-            'openerp': odoo,
-        }
-        try:
-            code_obj = compile(statements, self.filename, 'exec')
-            unsafe_eval(code_obj, {'ref': self.get_id}, code_context)
-        except AssertionError as e:
-            self._log_assert_failure('AssertionError in Python code %s (line %d): %s',
-                python.name, python.first_line, e)
-            return
-        except Exception as e:
-            _logger.debug('Exception during evaluation of !python block in yaml_file %s.', self.filename, exc_info=True)
-            raise
-        else:
-            self.assertion_report.record_success()
-
-    def _eval_params(self, model, params):
-        args = []
-        for i, param in enumerate(params):
-            if isinstance(param, list):
-                value = self._eval_params(model, param)
-            elif is_ref(param):
-                value = self.process_ref(param)
-            elif is_eval(param):
-                value = self.process_eval(param)
-            elif isinstance(param, dict): # supports XML syntax
-                param_model = self.env[param.get('model', model)]
-                if 'search' in param:
-                    q = safe_eval(param['search'], self.eval_context)
-                    ids = param_model.search(q).ids
-                    value = self._get_first_result(ids)
-                elif 'eval' in param:
-                    local_context = {'obj': param_model.browse}
-                    local_context.update(self.id_map)
-                    value = safe_eval(param['eval'], self.eval_context, local_context)
-                else:
-                    raise YamlImportException('You must provide either a !ref or at least a "eval" or a "search" to function parameter #%d.' % i)
-            else:
-                value = param # scalar value
-            args.append(value)
-        return args
-
-    def process_function(self, node):
-        function, params = list(node.items())[0]
-        if self.isnoupdate(function) and self.mode != 'init':
-            return
-        model = self.env[function.model]
-        if function.eval:
-            args = self.process_eval(function.eval)
-        else:
-            args = self._eval_params(function.model, params)
-        # this one still depends on the old API
-        return odoo.api.call_kw(model, function.name, args, {})
-
-    def _set_group_values(self, node, values):
-        if node.groups:
-            group_names = node.groups.split(',')
-            groups_value = []
-            for group in group_names:
-                if group.startswith('-'):
-                    group_id = self.get_id(group[1:])
-                    groups_value.append((3, group_id))
-                else:
-                    group_id = self.get_id(group)
-                    groups_value.append((4, group_id))
-            values['groups_id'] = groups_value
-
-    def process_menuitem(self, node):
-        self.validate_xml_id(node.id)
-
-        if not node.parent:
-            parent_id = False
-            self.cr.execute('select id from ir_ui_menu where parent_id is null and name=%s', (node.name,))
-            res = self.cr.fetchone()
-            values = {'parent_id': parent_id, 'name': node.name}
-        else:
-            parent_id = self.get_id(node.parent)
-            values = {'parent_id': parent_id}
-            if node.name:
-                values['name'] = node.name
-            try:
-                res = [ self.get_id(node.id) ]
-            except: # which exception ?
-                res = None
-
-        if node.action:
-            action = self.get_record(node.action)
-            values['action'] = '%s,%s' % (action._name, action.id)
-            if not values.get('name'):
-                values['name'] = action.name
-
-        if node.sequence:
-            values['sequence'] = node.sequence
-
-        self._set_group_values(node, values)
-
-        pid = self.sudo_env['ir.model.data']._update('ir.ui.menu', self.module, values, node.id, \
-                mode=self.mode, noupdate=self.isnoupdate(node), res_id=res and res[0] or False)
-
-        if node.id and pid:
-            self.id_map[node.id] = int(pid)
-
-    def process_act_window(self, node):
-        assert getattr(node, 'id'), "Attribute %s of act_window is empty !" % ('id',)
-        assert getattr(node, 'name'), "Attribute %s of act_window is empty !" % ('name',)
-        assert getattr(node, 'res_model'), "Attribute %s of act_window is empty !" % ('res_model',)
-        self.validate_xml_id(node.id)
-        view_id = False
-        if node.view:
-            view_id = self.get_id(node.view)
-        if not node.context:
-            node.context={}
-        context = safe_eval(str(node.context), self.eval_context)
-        values = {
-            'name': node.name,
-            'type': node.type or 'ir.actions.act_window',
-            'view_id': view_id,
-            'domain': node.domain,
-            'context': context,
-            'res_model': node.res_model,
-            'src_model': node.src_model,
-            'view_type': node.view_type or 'form',
-            'view_mode': node.view_mode or 'tree,form',
-            'usage': node.usage,
-            'limit': node.limit,
-            'multi': getattr(node, 'multi', False),
-        }
-
-        self._set_group_values(node, values)
-
-        if node.target:
-            values['target'] = node.target
-
-        if node.src_model and isinstance(node.src_model, basestring):
-            values['binding_model_id'] = self.env['ir.model']._get(node.src_model).id
-
-        id = self.sudo_env['ir.model.data']._update('ir.actions.act_window', self.module, values, node.id, mode=self.mode)
-        self.id_map[node.id] = int(id)
-        # TODO add remove ir.model.data
-
-    def process_delete(self, node):
-        assert getattr(node, 'model'), "Attribute %s of delete tag is empty !" % ('model',)
-        if node.model in self.env:
-            if node.search:
-                records = self.env[node.model].search(safe_eval(node.search, self.eval_context))
-            else:
-                records = self.env[node.model].browse(self.get_id(node.id))
-            if records:
-                records.unlink()
-        else:
-            self._log("Record not deleted.")
-
-    def process_url(self, node):
-        self.validate_xml_id(node.id)
-        res = {'name': node.name, 'url': node.url, 'target': node.target}
-        id = self.sudo_env['ir.model.data']._update("ir.actions.act_url", self.module, res, node.id, mode=self.mode)
-        self.id_map[node.id] = int(id)
-        # ir_set
-        if (not node.menu or safe_eval(node.menu)) and id:
-            action = self.env['ir.actions.actions'].browse(int(id))
-            action.binding_model_id = self.env['ir.model']._get('ir.actions.act_url')
-
-    def process_report(self, node):
-        values = {}
-        for dest, f in (('name','string'), ('model','model'), ('report_name','name')):
-            values[dest] = getattr(node, f)
-            assert values[dest], "Attribute %s of report is empty !" % (f,)
-        for field,dest in (('file', 'report_file'), ('attachment','attachment'),('attachment_use','attachment_use')):
-            if getattr(node, field):
-                values[dest] = getattr(node, field)
-        values['multi'] = node.multi and safe_eval(node.multi)
-        xml_id = node.id
-        self.validate_xml_id(xml_id)
-
-        self._set_group_values(node, values)
-
-        id = self.sudo_env['ir.model.data']._update("ir.actions.report", \
-                self.module, values, xml_id, noupdate=self.isnoupdate(node), mode=self.mode)
-        self.id_map[xml_id] = int(id)
-
-        if not node.menu or safe_eval(node.menu):
-            report = self.env['ir.actions.report'].browse(id)
-            report.create_action()
-
-    def process_none(self):
-        """
-        Empty node or commented node should not pass silently.
-        """
-        self._log_assert_failure("You have an empty block in your tests.")
-
-
-    def process(self, yaml_string):
-        """
-        Processes a Yaml string. Custom tags are interpreted by 'process_' instance methods.
-        """
-        yaml_tag.add_constructors()
-
-        is_preceded_by_comment = False
-        for node in yaml.load(yaml_string):
-            is_preceded_by_comment = self._log_node(node, is_preceded_by_comment)
-            try:
-                self._process_node(node)
-            except Exception as e:
-                _logger.exception(e)
-                raise
-
-    def _process_node(self, node):
-        if is_comment(node):
-            self.process_comment(node)
-        elif is_assert(node):
-            self.process_assert(node)
-        elif is_record(node):
-            self.process_record(node)
-        elif is_python(node):
-            self.process_python(node)
-        elif is_menuitem(node):
-            self.process_menuitem(node)
-        elif is_delete(node):
-            self.process_delete(node)
-        elif is_url(node):
-            self.process_url(node)
-        elif is_context(node):
-            self.process_context(node)
-        elif is_act_window(node):
-            self.process_act_window(node)
-        elif is_report(node):
-            self.process_report(node)
-        elif is_function(node):
-            if isinstance(node, dict):
-                self.process_function(node)
-            else:
-                self.process_function({node: []})
-        elif node is None:
-            self.process_none()
-        else:
-            raise YamlImportException("Can not process YAML block: %s" % node)
-
-    def _log_node(self, node, is_preceded_by_comment):
-        if is_comment(node):
-            is_preceded_by_comment = True
-            self._log(node)
-        elif not is_preceded_by_comment:
-            if isinstance(node, dict):
-                msg = "Creating %s\n with %s"
-                args = list(node.items())[0]
-                self._log(msg, *args)
-            else:
-                self._log(node)
-        else:
-            is_preceded_by_comment = False
-        return is_preceded_by_comment
-
-def yaml_import(cr, module, yamlfile, kind, idref=None, mode='init', noupdate=False, report=None):
-    if idref is None:
-        idref = {}
-    loglevel = logging.DEBUG
-    yaml_string = yamlfile.read()
-    yaml_interpreter = YamlInterpreter(cr, module, idref, mode, filename=yamlfile.name, report=report, noupdate=noupdate, loglevel=loglevel)
-    yaml_interpreter.process(yaml_string)
-
-# keeps convention of convert.py
-convert_yaml_import = yaml_import
diff --git a/odoo/tools/yaml_tag.py b/odoo/tools/yaml_tag.py
deleted file mode 100644
index 86a1e1f7f9951d8d7405c73751fa438f40a5e63d..0000000000000000000000000000000000000000
--- a/odoo/tools/yaml_tag.py
+++ /dev/null
@@ -1,164 +0,0 @@
-import yaml
-import logging
-
-
-class YamlTag(object):
-    """
-    Superclass for constructors of custom tags defined in yaml file.
-    __str__ is overridden in subclass and used for serialization in module recorder.
-    """
-    def __init__(self, **kwargs):
-        self.__dict__.update(kwargs)
-    def __getitem__(self, key):
-        return getattr(self, key)
-    def __getattr__(self, attr):
-        return None
-    def __repr__(self):
-        return "<%s %s>" % (self.__class__.__name__, sorted(self.__dict__.items()))
-
-class Assert(YamlTag):
-    def __init__(self, model, id=None, severity=logging.WARNING, string="NONAME", **kwargs):
-        self.model = model
-        self.id = id
-        self.severity = severity
-        self.string = string
-        super(Assert, self).__init__(**kwargs)
-    
-class Record(YamlTag):
-    def __init__(self, model, id, use='id', view=True, **kwargs):
-        self.model = model
-        self.id = id
-        self.view = view
-        super(Record, self).__init__(**kwargs)
-    def __str__(self):
-        return '!record {model: %s, id: %s}:' % (str(self.model,), str(self.id,))
-
-class Python(YamlTag):
-    def __init__(self, model, severity=logging.ERROR, name="", **kwargs):
-        self.model= model
-        self.severity = severity
-        self.name = name
-        super(Python, self).__init__(**kwargs)
-    def __str__(self):
-        return '!python {model: %s}: |' % (str(self.model), )
-
-class Menuitem(YamlTag):
-    def __init__(self, id, name, **kwargs):
-        self.id = id
-        self.name = name
-        super(Menuitem, self).__init__(**kwargs)
-
-class ActWindow(YamlTag):
-    def __init__(self, **kwargs):
-        super(ActWindow, self).__init__(**kwargs)
-
-class Function(YamlTag):
-    def __init__(self, model, name, **kwargs):
-        self.model = model
-        self.name = name
-        super(Function, self).__init__(**kwargs)
-
-class Report(YamlTag):
-    def __init__(self, model, name, string, **kwargs):
-        self.model = model
-        self.name = name
-        self.string = string
-        super(Report, self).__init__(**kwargs)
-
-class Delete(YamlTag):
-    def __init__(self, **kwargs):
-        super(Delete, self).__init__(**kwargs)
-
-class Context(YamlTag):
-    def __init__(self, **kwargs):
-        super(Context, self).__init__(**kwargs)
-
-class Url(YamlTag):
-    def __init__(self, **kwargs):
-        super(Url, self).__init__(**kwargs)
-
-class Eval(YamlTag):
-    def __init__(self, expression):
-        self.expression = expression
-        super(Eval, self).__init__()
-    def __str__(self):
-        return '!eval %s' % str(self.expression)
-    
-class Ref(YamlTag):
-    def __init__(self, expr="False", *args, **kwargs):
-        self.expr = expr
-        super(Ref, self).__init__(*args, **kwargs)
-    def __str__(self):
-        return 'ref(%s)' % repr(self.expr)
-    
-def assert_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    return Assert(**kwargs)
-
-def record_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    assert "model" in kwargs, "'model' argument is required for !record"
-    assert "id" in kwargs, "'id' argument is required for !record"
-    return Record(**kwargs)
-
-def python_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    kwargs['first_line'] = node.start_mark.line + 1
-    return Python(**kwargs)
-
-def menuitem_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    return Menuitem(**kwargs)
-
-def act_window_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    return ActWindow(**kwargs)
-
-def function_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    return Function(**kwargs)
-
-def report_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    return Report(**kwargs)
-
-def delete_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    return Delete(**kwargs)
-
-def context_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    return Context(**kwargs)
-
-def url_constructor(loader, node):
-    kwargs = loader.construct_mapping(node)
-    return Url(**kwargs)
-
-def eval_constructor(loader, node):
-    expression = loader.construct_scalar(node)
-    return Eval(expression)
-    
-def ref_constructor(loader, tag_suffix, node):
-    if tag_suffix == "id":
-        kwargs = {"id": loader.construct_scalar(node)}
-    else:
-        kwargs = loader.construct_mapping(node)
-    return Ref(**kwargs)
-    
-# Registers constructors for custom tags.
-# Constructors are actually defined globally: do not redefined them in another
-# class/file/package.  This means that module recorder need import this file.
-def add_constructors():
-    yaml.add_constructor(u"!assert", assert_constructor)
-    yaml.add_constructor(u"!record", record_constructor)
-    yaml.add_constructor(u"!python", python_constructor)
-    yaml.add_constructor(u"!menuitem", menuitem_constructor)
-    yaml.add_constructor(u"!act_window", act_window_constructor)
-    yaml.add_constructor(u"!function", function_constructor)
-    yaml.add_constructor(u"!report", report_constructor)
-    yaml.add_constructor(u"!context", context_constructor)
-    yaml.add_constructor(u"!delete", delete_constructor)
-    yaml.add_constructor(u"!url", url_constructor)
-    yaml.add_constructor(u"!eval", eval_constructor)
-    yaml.add_multi_constructor(u"!ref", ref_constructor)
-add_constructors()
diff --git a/setup.py b/setup.py
index 64e78ba54e285570ba67eccc53021322d600083e..a85c9e3fcdbf7bc28e92eb7607658bb0361910c2 100644
--- a/setup.py
+++ b/setup.py
@@ -108,7 +108,6 @@ def py2exe_options():
                         'xlsxwriter',
                         'xlwt',
                         'xml', 'xml.dom',
-                        'yaml',
                     ],
                     'excludes': ['Tkconstants', 'Tkinter', 'tcl'],
                 }
@@ -157,7 +156,6 @@ setup(
         'python-dateutil',
         'pytz',
         'pyusb >= 1.0.0b1',
-        'pyyaml',
         'qrcode',
         'reportlab',  # windows binary pypi.python.org/pypi/reportlab
         'requests',