As of 0.14, the "use either attribute or dict syntax" behavior for Context/Config/DataProxy functions reasonably well, except for when setting brand new config keys that don't already exist, in which case the attribute approach doesn't work - it simply sets a real attribute on whatever DataProxy is being touched.
This is very foot-gunny as it leads to difficult to understand/troubleshoot behavior - no error, and attribute access sometimes works after due to happenstance, but any e.g. cloning of the config, or dict access, or etc, does not preserve the attribute; tests like "if key in config" fail; etc.
What should happen is that new attribute accesses do set config values...but only from "outside" the class, and not in, say, __init__, otherwise there's a chicken/egg problem re: how to set initial, real attributes.
Strongly related is an issue where the "real attributes win over config values w/ same name, during attribute access" behavior - changed for 0.14 - is inconsistent because it only looks at self/type, and not supertypes, so it still doesn't quite work when one is dealing with Context or Config (versus a nested config values, which becomes a 'raw' DataProxy).
Neither of those is a clear winner but I'm leaning towards the latter (less code and state is better) so I may try it first to see just how verbose it is and whether it even works as expected.
object.__setattr__ appears to do the job, including under Python 3. Yea, it makes Config.__init__ a good amount more verbose (we initialize a few dozen attributes there) but I still feel better about doing it this way vs introducing more custom state crap.
My real world code that was working around this via dict-style setting, also appears to work fine with this change in place. Yay.
Failing test proving the other half of #413
Namely that 'is it an attr?' test isn't rigorous enough
Changelog re #413, closes #413