Repository: matthewwardrop/formulaic

Issue:
`model_spec.transform_state` bugged when formula is not correctly written
In case the given formula is not correctly written i.e., with extra or forgotten spaces then the `transform_state` dictionary keys does not match and the dictionary results in `{}`. Here is an example:

`import numpy as np
import pandas as pd
from formulaic import Formula

df = pd.DataFrame({
    'y': np.linspace(1,5,10),
    'x': np.linspace(0,1,10),
})

\# Formula well written
y, X = Formula('y ~ bs(x, df=4) ').get_model_matrix(df)
print(X.model_spec.__dict__["transform_state"])
`

results in `{'bs(x, df=4)': {'lower_bound': 0.0, 'upper_bound': 1.0, 'knots': [0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0]}}` while

`\# Formula not well written (note the whitespaces)

y, X = Formula('y ~ bs( x, df = 4) ').get_model_matrix(df)
print(X.model_spec.__dict__["transform_state"])
`

results in `{}`

I am using Formulaic version 0.6.6

Discussion:

Patch:
diff --git a/formulaic/materializers/base.py b/formulaic/materializers/base.py
index 9a097eb..6393769 100644
--- a/formulaic/materializers/base.py
+++ b/formulaic/materializers/base.py
@@ -186,14 +186,7 @@ class FormulaMaterializer(metaclass=FormulaMaterializerMeta):
         # the shared transform state pool.
         model_specs._map(
             lambda ms: ms.transform_state.update(
-                {
-                    factor.expr: factor_evaluation_model_spec.transform_state[
-                        factor.expr
-                    ]
-                    for term in ms.formula
-                    for factor in term.factors
-                    if factor.expr in factor_evaluation_model_spec.transform_state
-                }
+                factor_evaluation_model_spec.transform_state
             )
         )
 


Test patch:
diff --git a/tests/materializers/test_pandas.py b/tests/materializers/test_pandas.py
index 889616e..b85cda4 100644
--- a/tests/materializers/test_pandas.py
+++ b/tests/materializers/test_pandas.py
@@ -472,3 +472,12 @@ class TestPandasMaterializer:
             ),
         ):
             PandasMaterializer(data).get_model_matrix("I(a)")
+
+    def test_transform_state_with_inconsistent_formatting(self, data):
+        ms1 = PandasMaterializer(data).get_model_matrix("bs(a, df=4)").model_spec
+        ms2 = PandasMaterializer(data).get_model_matrix("bs( `a`, df = 4) ").model_spec
+        assert ms1.transform_state == ms2.transform_state
+
+    def test_nested_transform_state(self, data):
+        ms = PandasMaterializer(data).get_model_matrix("bs(bs(a))").model_spec
+        assert {"bs(a)", "bs(bs(a))"}.issubset(ms.transform_state)