Repository: duartegroup/autodE
Pull request #200 (2022-11-15 18:54:35)

Add checking for incompatible charge

codecov[bot]: # [Codecov](https://codecov.io/gh/duartegroup/autodE/pull/200?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup) Report
> Merging [#200](https://codecov.io/gh/duartegroup/autodE/pull/200?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup) (b8ce7af) into [v1.3.3](https://codecov.io/gh/duartegroup/autodE/commit/6a4709992c1866adfd18ea57bbf2957d5be1f6ac?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup) (6a47099) will **increase** coverage by `0.00%`.
> The diff coverage is `93.75%`.

```diff
@@           Coverage Diff           @@
##           v1.3.3     #200   +/-   ##
=======================================
  Coverage   96.97%   96.98%           
=======================================
  Files         195      195           
  Lines       19845    19860   +15     
=======================================
+ Hits        19245    19261   +16     
+ Misses        600      599    -1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `96.98% <93.75%> (+<0.01%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/duartegroup/autodE/pull/200?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup) | Coverage Δ | |
|---|---|---|
| [setup.py](https://codecov.io/gh/duartegroup/autodE/pull/200/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup#diff-c2V0dXAucHk=) | `0.00% <ø> (ø)` | |
| [autode/species/molecule.py](https://codecov.io/gh/duartegroup/autodE/pull/200/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup#diff-YXV0b2RlL3NwZWNpZXMvbW9sZWN1bGUucHk=) | `98.01% <85.71%> (-0.92%)` | :arrow_down: |
| [autode/\_\_init\_\_.py](https://codecov.io/gh/duartegroup/autodE/pull/200/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup#diff-YXV0b2RlL19faW5pdF9fLnB5) | `100.00% <100.00%> (ø)` | |
| [tests/test\_molecule.py](https://codecov.io/gh/duartegroup/autodE/pull/200/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup#diff-dGVzdHMvdGVzdF9tb2xlY3VsZS5weQ==) | `96.17% <100.00%> (+0.20%)` | :arrow_up: |
| [autode/smiles/smiles.py](https://codecov.io/gh/duartegroup/autodE/pull/200/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup#diff-YXV0b2RlL3NtaWxlcy9zbWlsZXMucHk=) | `95.34% <0.00%> (+2.32%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=duartegroup)


Patch:
diff --git a/autode/__init__.py b/autode/__init__.py
index af21c8a..eff4ba3 100644
--- a/autode/__init__.py
+++ b/autode/__init__.py
@@ -38,7 +38,7 @@ Bumping the version number requires following the release proceedure:
   - Merge when tests pass
 """
 
-__version__ = "1.3.2"
+__version__ = "1.3.3"
 
 
 __all__ = [
diff --git a/autode/species/molecule.py b/autode/species/molecule.py
index e298350..f59ce0a 100644
--- a/autode/species/molecule.py
+++ b/autode/species/molecule.py
@@ -87,6 +87,7 @@ class Molecule(Species):
             smiles (str):
         """
         at_strings = re.findall(r"\[.*?]", smiles)
+        init_charge = self._charge
 
         if any(metal in string for metal in metals for string in at_strings):
             init_smiles(self, smiles)
@@ -94,6 +95,12 @@ class Molecule(Species):
         else:
             init_organic_smiles(self, smiles)
 
+        if not _is_default_charge(init_charge) and init_charge != self._charge:
+            raise ValueError(
+                "SMILES charge was not the same as the "
+                f"defined value. {self._charge} ≠ {init_charge}"
+            )
+
         logger.info(
             f"Initialisation with SMILES successful. "
             f"Charge={self.charge}, Multiplicity={self.mult}, "
@@ -242,3 +249,7 @@ class Reactant(Molecule):
 
 class Product(Molecule):
     """Product molecule"""
+
+
+def _is_default_charge(value) -> bool:
+    return value == 0
diff --git a/doc/changelog.rst b/doc/changelog.rst
index 8818dee..1f215dd 100644
--- a/doc/changelog.rst
+++ b/doc/changelog.rst
@@ -1,6 +1,18 @@
 Changelog
 =========
 
+1.3.3
+--------
+----------
+
+Bugfix release.
+
+
+Bug Fixes
+*********
+- Adds checking of SMILES-defined charge and multiplicity against user-specified values
+
+
 1.3.2
 --------
 ----------
diff --git a/setup.py b/setup.py
index 9822fe3..b8206c6 100644
--- a/setup.py
+++ b/setup.py
@@ -24,7 +24,7 @@ extensions = [
 
 setup(
     name="autode",
-    version="1.3.2",
+    version="1.3.3",
     python_requires=">3.7",
     packages=[
         "autode",


Test patch:
diff --git a/tests/test_molecule.py b/tests/test_molecule.py
index 4372605..10c9e43 100644
--- a/tests/test_molecule.py
+++ b/tests/test_molecule.py
@@ -271,3 +271,18 @@ def test_atom_class_defined_for_organic():
 
     mol = Molecule(smiles="[Br-:1]")
     assert mol.atoms[0].atom_class is not None
+
+
+def test_smiles_and_user_defined_charge_raises_exception():
+
+    with pytest.raises(Exception):
+        _ = Molecule(smiles="[Cl-]", charge=1)
+
+
+def test_user_defined_charge_overrides_smiles_mult():
+
+    ch2 = Molecule(smiles="[H][C][H]")
+    default_mult = ch2.mult
+
+    ch2_alt = Molecule(smiles="[H][C][H]", mult=3 if default_mult == 1 else 1)
+    assert ch2_alt.mult != default_mult