[Bug pyserial:172] applySettingsDict() throws an error if the settings dictionary is not complete
diff --git a/CHANGES.rst b/CHANGES.rst
index 1e34b4f..5340e85 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -517,6 +517,10 @@
 - finish update to BSD license
 - update links to point to github
 
+Bugfixes:
+
+- [Bug pyserial:172] applySettingsDict() throws an error if the settings dictionary is not complete
+
 Bugfixes (posix):
 
 - fix setXON
diff --git a/serial/serialutil.py b/serial/serialutil.py
index 0790d7d..1bd0f0c 100644
--- a/serial/serialutil.py
+++ b/serial/serialutil.py
@@ -347,7 +347,7 @@
         values will simply left unchanged.
         """
         for key in self._SETTINGS:
-            if d[key] != getattr(self, '_'+key):   # check against internal "_" value
+            if key in d and d[key] != getattr(self, '_'+key):   # check against internal "_" value
                 setattr(self, key, d[key])          # set non "_" value to use properties write function
 
     #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
diff --git a/test/test_settings_dict.py b/test/test_settings_dict.py
new file mode 100644
index 0000000..2e2e77f
--- /dev/null
+++ b/test/test_settings_dict.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+# Python Serial Port Extension for Win32, Linux, BSD, Jython
+# see __init__.py
+#
+# (C) 2015 Chris Liechti <cliechti@gmx.net>
+# this is distributed under a free software license, see license.txt
+
+"""\
+Test the ability to get and set the settings with a dictionary.
+
+Part of pyserial (http://pyserial.sf.net)  (C)2002 cliechti@gmx.net
+
+Intended to be run on different platforms, to ensure portability of
+the code.
+
+These tests open a serial port and change all the settings on the fly.
+If the port is really correctly configured cannot be determined - that
+would require external hardware or a null modem cable and an other
+serial port library... Thus it mainly tests that all features are
+correctly implemented and that the interface does what it should.
+"""
+
+import unittest
+import serial
+
+# on which port should the tests be performed:
+PORT = 0
+
+
+SETTINGS = ('baudrate', 'bytesize', 'parity', 'stopbits', 'xonxoff',
+            'dsrdtr', 'rtscts', 'timeout', 'writeTimeout', 'interCharTimeout')
+
+
+class Test_SettingsDict(unittest.TestCase):
+    """Test with ettings dictionary"""
+
+    def setUp(self):
+        # create a closed serial port
+        self.s = serial.serial_for_url(PORT, do_not_open=True)
+
+    def tearDown(self):
+        self.s.close()
+
+    def test_getsettings(self):
+        """the settings dict reflects the current settings"""
+        d = self.s.getSettingsDict()
+        for setting in SETTINGS:
+            self.failUnlessEqual(getattr(self.s, setting), d[setting])
+
+    def test_partial_settings(self):
+        """partial settings dictionaries are also accepted"""
+        d = self.s.getSettingsDict()
+        del d['baudrate']
+        del d['bytesize']
+        self.s.applySettingsDict(d)
+        for setting in d:
+            self.failUnlessEqual(getattr(self.s, setting), d[setting])
+
+    def test_unknown_settings(self):
+        """unknown settings are ignored"""
+        d = self.s.getSettingsDict()
+        d['foobar'] = 'ignore me'
+        self.s.applySettingsDict(d)
+
+
+if __name__ == '__main__':
+    import sys
+    sys.stdout.write(__doc__)
+    if len(sys.argv) > 1:
+        PORT = sys.argv[1]
+    sys.stdout.write("Testing port: %r\n" % PORT)
+    sys.argv[1:] = ['-v']
+    # When this module is executed from the command-line, it runs all its tests
+    unittest.main()