[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()