From cb628dd5ce1cb75cdb16793248ed63cfcfdf2e50 Mon Sep 17 00:00:00 2001 From: Christian Hill Date: Fri, 11 Feb 2022 13:05:58 +0100 Subject: [PATCH] Forbid whitespace in key-value pairs, allow whitespace to delimit states in StatefulSpecies --- doc/stateful_species.rst | 9 +++++---- doc/states.rst | 7 +++---- setup.py | 2 +- src/pyvalem/stateful_species.py | 3 ++- src/pyvalem/states/key_value_pair.py | 10 ++++++++-- tests/test_key_value_pairs.py | 20 +++----------------- tests/test_stateful_species.py | 10 +++++----- 7 files changed, 27 insertions(+), 34 deletions(-) diff --git a/doc/stateful_species.rst b/doc/stateful_species.rst index 646c594..1eade48 100644 --- a/doc/stateful_species.rst +++ b/doc/stateful_species.rst @@ -7,8 +7,9 @@ with one or more quantum states of labels, and can be represented by an instance A ``StatefulSpecies`` object can be instantiated by providing a string consisting of the formula (which can be parsed into a ``Formula`` object), followed by whitespace -and a semicolon delimited sequence of strings that can be parsed by one of the -``State`` classes described previously. +and a whitespace-delimited sequence of strings that can be parsed by one of the +``State`` classes described previously. For clarity, a semi-colon or comma can also be +used as a delimiter between states. The state type is deduced from the format of the string. Examples: @@ -16,9 +17,9 @@ Examples: .. code-block:: pycon >>> from pyvalem.stateful_species import StatefulSpecies - >>> ss1 = StatefulSpecies('HCl v=2;J=0') + >>> ss1 = StatefulSpecies('HCl v=2 J=0') >>> ss2 = StatefulSpecies('NCO v2+3v1;J=10.5;a(2Σ-g)') - >>> ss3 = StatefulSpecies('Ar+ 1s2.2s2.2p5; 2P_3/2') + >>> ss3 = StatefulSpecies('Ar+ 1s2.2s2.2p5, 2P_3/2') >>> ss4 = StatefulSpecies('CrH 1sigma2.2sigma1.1pi4.3sigma1; 6SIGMA+') An HTML representation is accessible through the ``html`` attribute: diff --git a/doc/states.rst b/doc/states.rst index 8e11b52..5e3d74c 100644 --- a/doc/states.rst +++ b/doc/states.rst @@ -321,13 +321,12 @@ Examples: The ``KeyValuePair`` class represents an arbitrary quantum number or symmetry provided as a (key, value) pair. It is instantiated with a string of the form ``key=value``. +Whitespace within a key-value pair is illegal. For example: .. code-block:: pycon >>> from pyvalem.states import KeyValuePair >>> kv1 = KeyValuePair('n=1') - >>> kv2 = KeyValuePair('C = 45a#') - - - + >>> kv2 = KeyValuePair('|M|=2') + >>> kv3 = KeyValuePair('sym=anti') diff --git a/setup.py b/setup.py index 65bec1e..b65a056 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name="pyvalem", - version="2.5.3", + version="2.5.4", description="A package for managing simple chemical species and states", long_description=long_description, long_description_content_type="text/x-rst", diff --git a/src/pyvalem/stateful_species.py b/src/pyvalem/stateful_species.py index 02610b2..43fa39b 100644 --- a/src/pyvalem/stateful_species.py +++ b/src/pyvalem/stateful_species.py @@ -29,7 +29,8 @@ def __init__(self, s): i = s.index(" ") self.formula = Formula(s[:i]) - self.states = state_parser(s[i + 1 :].split(";")) + s = s.replace(";", " ").replace(",", " ") + self.states = state_parser(s[i + 1 :].split()) self._verify_states() diff --git a/src/pyvalem/states/key_value_pair.py b/src/pyvalem/states/key_value_pair.py index 66ade64..cfab1f9 100644 --- a/src/pyvalem/states/key_value_pair.py +++ b/src/pyvalem/states/key_value_pair.py @@ -31,9 +31,15 @@ def _parse_state(self, state_str): """ Parse state_str into a KeyValuePair object. - Whitespace is tolerated in the input, i.e both 'key=value' and - 'key = value' are parsed, but no spaces are inserted in the output. + Whitespace is not tolerated in the input, i.e only 'key=value' and not + 'key = value' are allowed. No spaces are inserted in the output. """ + + if any(c.isspace() for c in state_str): + raise KeyValuePairError( + "No whitespace allowed in key-value pair: {}".format(state_str) + ) + try: key, value = state_str.split("=") except ValueError: diff --git a/tests/test_key_value_pairs.py b/tests/test_key_value_pairs.py index 4eb90fe..8ca5a94 100644 --- a/tests/test_key_value_pairs.py +++ b/tests/test_key_value_pairs.py @@ -15,13 +15,9 @@ def test_key_value_pair(self): self.assertEqual(str(kv1), "n=1") self.assertEqual(kv1.html, "n=1") - kv2 = KeyValuePair("C = 45a#") - self.assertEqual(kv2.key, "C") - self.assertEqual(kv2.value, "45a#") - self.assertEqual(str(kv2), "C=45a#") - self.assertEqual(kv2.html, "C=45a#") - - self.assertRaises(KeyValuePairError, KeyValuePair, "*") + self.assertRaises(KeyValuePairError, KeyValuePair, "C = 3") + self.assertRaises(KeyValuePairError, KeyValuePair, "k= 3") + self.assertRaises(KeyValuePairError, KeyValuePair, "k =v") def test_key_value_pair_equality(self): kv1 = KeyValuePair("nd=1") @@ -33,16 +29,6 @@ def test_key_value_pair_equality(self): self.assertNotEqual(kv1, kv3) self.assertNotEqual(kv2, kv4) - def test_key_value_pair_repr(self): - kv1 = KeyValuePair("n=2") - kv2 = KeyValuePair("n =2") - kv3 = KeyValuePair("n= 2") - kv4 = KeyValuePair("n = 2") - kv5 = KeyValuePair("n = 2") - self.assertTrue( - repr(kv1) == repr(kv2) == repr(kv3) == repr(kv4) == repr(kv5) == "n=2" - ) - def test_html_escaping(self): kv1 = KeyValuePair('S="5