LWN: Comments on "Improving Python's SimpleNamespace" https://lwn.net/Articles/818777/ This is a special feed containing comments posted to the individual LWN article titled "Improving Python's SimpleNamespace". en-us Tue, 30 Sep 2025 09:02:24 +0000 Tue, 30 Sep 2025 09:02:24 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Improving Python's SimpleNamespace https://lwn.net/Articles/904115/ https://lwn.net/Articles/904115/ LtWorf <div class="FormattedComment"> After over 2 years I got around to try jsons :D<br> <p> It seems to be very low quality. For example loading 1.1 into a Union[int, float] returns 1, which is obviously wrong.<br> <p> It&#x27;s also 10x to 40x times slower than typedload.<br> <p> Despite this it has 8x more downloads :)<br> </div> Sun, 07 Aug 2022 21:48:59 +0000 Typing costs of non-English keyboard layouts in programming languages https://lwn.net/Articles/820060/ https://lwn.net/Articles/820060/ smurf <div class="FormattedComment"> That's a good idea in principle – I tried, but I need to use computers where this is not possible far too often. The mental effort to switch is … painful. I positively envy people who can do that on the fly.<br> </div> Sat, 09 May 2020 16:42:08 +0000 Typing costs of non-English keyboard layouts in programming languages https://lwn.net/Articles/819868/ https://lwn.net/Articles/819868/ Cyberax <div class="FormattedComment"> Have you tried installing two keyboard layouts and switching between them (CapsLock is the best switch key)?<br> </div> Thu, 07 May 2020 23:01:35 +0000 Typing costs of non-English keyboard layouts in programming languages https://lwn.net/Articles/819862/ https://lwn.net/Articles/819862/ flussence <div class="FormattedComment"> I've been using a weird mini keyboard for a few years now. Having {}[]()&lt;&gt; all equally awkward to reach (though thankfully none of them require one-hand chording) has really made me appreciate programming languages that offer more than one way to do it.<br> <p> But now I can emphasise with the plight of users who get this experience by default. A lot of programming's still too ASCII-centric.<br> </div> Thu, 07 May 2020 22:24:47 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819682/ https://lwn.net/Articles/819682/ njs <div class="FormattedComment"> This kind of stuff is exactly what the 'glom' package (linked in the article) is all about.<br> </div> Thu, 07 May 2020 05:45:01 +0000 Typing costs of non-English keyboard layouts in programming languages https://lwn.net/Articles/819354/ https://lwn.net/Articles/819354/ mathstuf <div class="FormattedComment"> I use Xcompose settings which still seem to work even in the xkb era. `setxkbmap` is how I enable AltGr/compose keys on my layout as well. `xmodmap` seems mostly replaced with libinput these days. For example, here's how I remap Caps Lock to be Backspace:<br> <p> % cat /etc/udev/99-kb-capslock.hwdb<br> evdev:input:b0011v0001p0001eAB41-*:<br> KEYBOARD_KEY_70039=backspace<br> <p> which means that it also works on the TTY and not just when X is running (and apps can't sniff the fact that it is Caps Lock behind my back and do the wrong thing).<br> </div> Mon, 04 May 2020 12:58:04 +0000 Typing costs of non-English keyboard layouts in programming languages https://lwn.net/Articles/819346/ https://lwn.net/Articles/819346/ ballombe <div class="FormattedComment"> I do something similar. I stopped using X for typing when xmodmap was deprecated in favor of unusable xkb.<br> <p> </div> Mon, 04 May 2020 12:14:24 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819308/ https://lwn.net/Articles/819308/ kleptog When dealing with complex data structures from a database or client it's useful to have a kind of "deep get" like you have, but one that gracefully handles missing entries well. Otherwise you end up with horrors like: <pre> a.get('foo', {}).get('bar', {}).get('baz', None) </pre> Ideally you'd like something that also handled arrays, but Python doesn't have an easy way to index an array with a default when you go off the end. <p> I've often ended up coding methods to do this, but it'd be cool if there was something standard. Sun, 03 May 2020 14:35:35 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819300/ https://lwn.net/Articles/819300/ mathstuf <div class="FormattedComment"> I've always ended up using the JSON Pointer standard for stuff like this. Are they basically the same, with Pointer preferring `/` rather than `.`. But it seems there are quite a few existing standards for this. `-` truly would be an xkcd#927 instance :) .<br> </div> Sun, 03 May 2020 11:24:20 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819251/ https://lwn.net/Articles/819251/ dtlin <p>Yeah, that would be simple, but precedence doesn't work out entirely in our favor: <pre> w/'hello world'[0] </pre> <p>would result in <code>"h"</code> instead of <code>"hello"</code>. Sat, 02 May 2020 10:30:41 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819250/ https://lwn.net/Articles/819250/ smurf <div class="FormattedComment"> <font class="QuotedText">&gt; w'hello world' == ["hello", "world"]</font><br> <p> One more character and it works today.<br> <p> w/'hello world'<br> <p> Writing the three-line singleton object 'w', with an appropriate dunder method, is left as an exercise to the reader.<br> </div> Sat, 02 May 2020 08:47:25 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819249/ https://lwn.net/Articles/819249/ PhilippWendler <div class="FormattedComment"> Especially in complex cases JSONPath is a nice standard for this, it would allow you to write 'clothing.mens.shoes.extra_wide.quantity' here but also supports arrays etc. (like if shoes where an array and you need to find the element in it that has the extra_wide property set to true, and then retrieve quantity from it). I have not yet used it from a Python project, but it seems there are libraries implementing.<br> </div> Sat, 02 May 2020 08:03:42 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819246/ https://lwn.net/Articles/819246/ dtlin <p>Seems to me that it makes more sense to keep splitting the responsibility of the caller: <pre> def deep_getitem(obj, *path): return functools.reduce(operator.getitem, path, obj) deep_getitem(catalog, *'clothing mens shoes extra_wide quantity'.split()) </pre> <p>The caller should know what an appropriate separator is, and could even build the path up from multiple parts split in different ways if that's appropriate. <p>Although that reminds me of how convenient Perl's <code>qw(...)</code> and Ruby's <code>%w[...]</code> are. I wonder if there might be interest in some hypothetical w-string in Python, such that <pre> w'hello world' == ["hello", "world"] </pre> Sat, 02 May 2020 07:12:24 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819244/ https://lwn.net/Articles/819244/ NYKevin <p> One of the more interesting suggestions in that thread, from <a href="https://lwn.net/ml/python-dev/CAPTjJmqwN0q+tC-T6KNG_TPRgdcwdNK=HTJ810aGe3KmB0g3ew@mail.gmail.com/">Chris Angelico</a>: <blockquote> <p> My solution to that has usually been something along the lines of: <pre> def get(obj, path): for step in path.split("-"): obj = obj[step] return obj print(get(catalog, 'clothing-mens-shoes-extra_wide-quantity')) </pre> <p> Will often be custom-tweaked to the situation, but the basic idea is the same. </blockquote> <p> My 2 cents: I would much prefer forward slashes as the separator (by analogy with filesystem paths), but otherwise that looks quite reasonable to me. It also solves the <tt>foo["names with multiple words aren't valid identifiers"]</tt> problem. And as an extra bonus, this requires no changes to core Python or the standard library, and can traverse any dict-like object that supports <tt>__getitem__()</tt>, rather than being a class in its own right (no ugly multiple inheritance if you want to combine functionality with another mapping type). Sat, 02 May 2020 04:20:33 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819213/ https://lwn.net/Articles/819213/ LtWorf <div class="FormattedComment"> Yes they are pretty similar.<br> <p> I'd trust mine more because it has tests running on all the python versions that are supported and on mypy.<br> <p> jsons doesn't seem to use mypy, because at a casual glance I found some typing errors.<br> <p> jsons supports more types, but typedload has a better code for unions and is more customisable.<br> <p> Pretty similar but jsons is MIT licensed and typedload is GPL3 so I guess I lose on the license. Which is pretty deliberate because I don't want my free time work to be used for free by proprietary projects.<br> <p> Ah, mine one already exists in Debian, so that's a slight advantage.<br> <p> </div> Fri, 01 May 2020 15:01:00 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819158/ https://lwn.net/Articles/819158/ tamasrepus <div class="FormattedComment"> Similar to <a href="https://jsons.readthedocs.io/en/latest/">https://jsons.readthedocs.io/en/latest/</a>.<br> </div> Fri, 01 May 2020 09:52:40 +0000 Typing costs of non-English keyboard layouts in programming languages https://lwn.net/Articles/819151/ https://lwn.net/Articles/819151/ knuto <div class="FormattedComment"> This brought back some old memories here...<br> Yes, same issue in Norwegian, both {} and [] requires AltGr. But when iso8859-1 emerged, <br> it was still an enormous a relief compared to back in the 7 bit ascii days when a construct like <br> <p> \documentstyle[12pt]{report}<br> <p> would show up on Norwegian screens as <br> <p> ØdocumentstyleÆ12ptÅæreportå<br> <p> and 'hopeless' == 'håpløst' in Norwegian<br> would have to be written as the less readable 'hØaaplØost'<br> <p> I ended up writing a small 138 lines of c code preprocessor for TeX which I used for all my early years of TeX and subsequently LaTeX work that used /&lt;&gt; instead of \{} , translated all the æøå variants to the right escape sequences and an escape construct @( @) and special handling of \begin{verbatim} .. \end{verbatim}.<br> </div> Fri, 01 May 2020 08:03:20 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819145/ https://lwn.net/Articles/819145/ moxfyre I agree. It's a matter of convenient access, whether you're populating contents “on the fly” (more a use case for <tt>dict</tt>) or with a relatively small set of fixed names (more a use case for a custom <tt>class</tt> or <tt>attrs</tt>).<p> In my <tt>vpn-slice</tt> and <tt>wtf</tt> utilities, I have long used an even simpler version of <tt>SimpleNameSpace</tt>, dubbed <tt>slurpy</tt>:<p> <pre> # Quacks like a dict and an object class slurpy(dict): def __getattr__(self, k): try: return self[k] except KeyError as e: raise AttributeError(*e.args) def __setattr__(self, k, v): self[k]=v </pre> This allows you to create an object like <tt>d = slurpy(foo="bar", baz=1)</tt> and then refer to any of its members/contents <b><i>either</i></b> by member access (<tt>.foo</tt>) <b><i>or</i></b> by item access (<tt>["foo"]</tt>).<p> It's very simple and performs well for a pure-Python implementation, and it even throws <tt>KeyError</tt> or <tt>AttributeError</tt> appropriately so that callers/REPLs don't get confused by the “wrong” kind of exception.<p> (See <a rel="nofollow" href="https://github.com/dlenski/vpn-slice/blob/HEAD/vpn_slice/util.py#L13-L22">https://github.com/dlenski/vpn-slice/blob/HEAD/vpn_slice/util.py#L13-L22</a> and <a rel="nofollow" href="https://github.com/dlenski/wtf/blob/HEAD/wtf.py#L10-L18">https://github.com/dlenski/wtf/blob/HEAD/wtf.py#L10-L18</a> for some context as to how this is useful.) Fri, 01 May 2020 01:18:57 +0000 Typing costs of non-English keyboard layouts in programming languages https://lwn.net/Articles/819022/ https://lwn.net/Articles/819022/ NAR This is the reason why I use "hunglish" layout: English layout, extra Hungarian characters available by AltGr (mostly) on the right side of the keyboard (e.g. 0-=[];'\), so it's fairly easy to type them. I never understood people who can use Hungarian layout for programming... BTW Elixir has maps (the usual associative arrays) in the language. It has also structs, but those are implemented using maps with a special <CODE>__struct__</CODE> field containing the type and the field names of the structs are keys in the map (as atoms). The generic syntax for accessing maps is the usual <CODE>map[key]</CODE>, while for structs it is <CODE>struct.attribute</CODE>. So far so good, it's probably what people from other languages expect. However, for some reason if the keys of a map are atoms, the "struct syntax" also works - which sometimes drives me nuts as I can't tell by looking at code like this: <P> <CODE> some.thing </CODE> <P> that it's accessing a struct or a map. It also has an interesting interplay with command line expansion - it is possible to create atom names with space (crazy idea, but possible): <P> <CODE> iex(8)&gt; m3 = %{:"a b" =&gt; "c"} <BR> %{"a b": "c"} </CODE> <P> Then when I type <CODE>m3.</CODE> followed by TAB, the shell helpfully extends the field name, so I get <P> <CODE> iex(9)&gt; m3.a b <BR> ** (CompileError) iex:9: undefined function b/0 </CODE> <P> Of course, <CODE>m3."a b"</CODE> or <CODE>m3[:"a b"]</CODE> works. Thu, 30 Apr 2020 14:12:44 +0000 Typing costs of non-English keyboard layouts in programming languages https://lwn.net/Articles/819013/ https://lwn.net/Articles/819013/ mbunkus <div class="FormattedComment"> This is a real problem. I'm German like most Germans used to use German keyboard layout. A lot of years ago I had to write so much LaTeX by day (job) &amp; C++ by night (hobby) that I developed pain in my right wrist (possibly RPI, though I never went to see a doctor). The reason is that on German keyboards you need to press AltGr (think "right Alt key" for non-German keyboard users) for all of the most often used characters in LaTeX: \ { } [ ]<br> <p> Not only that, for pressing{ with one hand you really need to do funky acrobatics as it's on AltGr+7. Doing that for several hours a day _hurt_! Look at images of German keyboard layouts to get an idea how you have to contort your hand for that.<br> <p> The result was that I switched to English layouts, even with German keyboards. I then spent hours on implementing some way to write German Umlauts &amp; ß without too much hassle (I also switched to using ergonomic keyboards, but that's a different topic).<br> <p> smurf is right, having to type asd['qwe']['whatever'] requires a LOT of changing states of different modifier keys, it slows down typing significantly: a s d press&amp;hold AltGr 8 release AltGr press&amp;hold Shift # release Shift q w e press&amp;hold Shift # release Shift press&amp;hold AltGr+9 etc. etc.<br> <p> I'm pretty sure other non-English languages have similar problems typing something like that.<br> </div> Thu, 30 Apr 2020 10:42:13 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819007/ https://lwn.net/Articles/819007/ LtWorf <div class="FormattedComment"> I have written a library, called typedload[1], that I use to put json data into dataclass or similar.<br> <p> @dataclass<br> class A:<br> a: int<br> b: List[str] = field(default_factory=list)<br> <p> typedload.load(data, A)<br> <p> It tells mypy of the output type, will do the runtime checks to make sure the type is actually correct, the exceptions offer a way to figure out where exactly in the data the error happened.<br> <p> It has a number of options, for example to disallow unknown fields in the dictionaries that are not in the classes, and allows to define custom functions to load into whatever type.<br> <p> Personally I'd rather be able to access fields that exist for sure than expect exceptions to happen all over the place.<br> <p> [1]: <a href="https://github.com/ltworf/typedload">https://github.com/ltworf/typedload</a><br> </div> Thu, 30 Apr 2020 07:27:15 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819006/ https://lwn.net/Articles/819006/ smurf <div class="FormattedComment"> Well, I disagree. I also seem not to be the only person who has re-invented "AttrDict" (even using that exact name), so I might be a bit prejudiced.<br> <p> It's also not just readability but also typing. One dot is one keystroke with pretty much any keyboard layout ever. On a German keyboard, however, [''] requires eight (brackets require AltGr while single quotes need Shift). Owch.<br> </div> Thu, 30 Apr 2020 07:16:43 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/819005/ https://lwn.net/Articles/819005/ smurf <div class="FormattedComment"> That's true, and a JsonSchemaDict that enforces not storing nonsense into it would be a superb idea (assuming it doesn't exist already), but this is orthogonal to the current discussion.<br> </div> Thu, 30 Apr 2020 07:11:49 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/818994/ https://lwn.net/Articles/818994/ dtlin <blockquote>There should be one-- and preferably only one --obvious way to do it.</blockquote> <p>Obviously there's other forms of syntactic sugar in Python. But it seems to me like other sugar has more benefit than saving 3 characters - or 2 characters, in the case of <code>obj..abc..def..ghi</code>. IMO <code>obj['abc']['def']['ghi']</code> already scores reasonably well along simple, readable, and now measures, so a proposal should be substantially better. Thu, 30 Apr 2020 06:19:14 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/818990/ https://lwn.net/Articles/818990/ neilbrown <div class="FormattedComment"> <font class="QuotedText">&gt; Still feels pretty foreign to Python though. </font><br> <p> I wonder what you mean by that exactly. For example, does it contravene some part of the Zen of Python?<br> <p> Simple is better than complex.<br> Readability counts.<br> Now is better than never.<br> <p> All seem to support it.<br> <p> The article mentioned a ".." suggestion which is much like this "!" suggestion. Would ".." feel less foreign??<br> <p> </div> Thu, 30 Apr 2020 05:12:53 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/818985/ https://lwn.net/Articles/818985/ dtlin That's an interesting idea. Using something like <code>obj!abc!def!ghi</code> to mean <code>obj['abc']['def']['ghi']</code> wouldn't break any existing code. Still feels pretty foreign to Python though. Thu, 30 Apr 2020 02:22:59 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/818976/ https://lwn.net/Articles/818976/ NYKevin <p>Dynamically-typed JSON seems like a really Bad Idea to me. JSON is an interaction point with the outside world, and very likely to contain untrusted (or only marginally trusted) data. At a bare minimum, you should be checking the types of the parsed objects, recursively in all sub-objects. Otherwise, it's ridiculously easy for an attacker to cause all sorts of headaches. Consider: <pre> &gt;&gt;&gt; ham = json.loads(r'{"eggs": 5}') &gt;&gt;&gt; ham['eggs'] * 1000000000 # Convert seconds to nanoseconds 5000000000 &gt;&gt;&gt; spam = json.loads(r'{"eggs": [1, 2, 3]}') &gt;&gt;&gt; spam['eggs'] * 1000000000 # Convert tiny list to MemoryError </pre> <p>And I'm sure there are more "interesting" examples than just OOMing the client. But by the time you're doing recursive type checking, it's really hard to justify <em>not</em> using a "real" statically-checkable type like a dataclass. The only excuse I can think of is that the standard library lacks a facility to do it automatically, which is a shame because I could probably bang that out in an hour or two (with the bulk of that time devoted to re-normalizing the weird type objects in typing.py back into classes that you can hand to isinstance()). Wed, 29 Apr 2020 22:03:02 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/818971/ https://lwn.net/Articles/818971/ amarao <div class="FormattedComment"> I think the problem everyone is fixing not a dict/attr thing, but a simple convince. Nested dicts and frequent access to dicts through constant keys is a pattern everyone is using. To use a value from a dict a rather bizzare operator is needed. [' and then ']. If someone made it one character everyone would be happy.<br> <p> </div> Wed, 29 Apr 2020 20:21:47 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/818968/ https://lwn.net/Articles/818968/ martin.langhoff <div class="FormattedComment"> In some languages, simple-ish objects and dicts are used (almost) interchangeably. Some folks "fold" this into their coding style. I've seen it done in PHP and in JS. <br> <p> In other words -- it's dynamic typing, applied to complex variables.<br> <p> Just like dynamic typing, it works well for small projects, breaks down eventually because they are not the same thing.<br> </div> Wed, 29 Apr 2020 19:44:26 +0000 Improving Python's SimpleNamespace https://lwn.net/Articles/818953/ https://lwn.net/Articles/818953/ NYKevin <div class="FormattedComment"> Honestly, SimpleNamespace has always struck me as a weird class. It feels like a dict() playing dress-up as a "real" object. But I've never understood why that is considered useful or desirable. If you have a particular schema in mind, then surely dataclasses (or attrs) are more useful than SimpleNamespace, and if you don't, then you probably ought to be using a dict instead, to call attention to the fact that d['key'] can throw. I suppose it might be useful as a shortcut for "I would use dataclasses but I don't actually need their functionality" - but then you really ought to document the schema somewhere else, and I don't think that actually saves you all that much work. dataclasses do not take a lot of typing to create, after all.<br> <p> (I'm also not a huge fan of JSON's object_hook, since it's slightly too dumb to actually deal with complicated JSON object structures correctly - the type of an object is context-sensitive and needs to be recursively deduced based on the parent type, unless you were clever and preemptively tagged all of your JSON objects with a type hint. Unfortunately, I don't see that sort of tagging much in practice. So you end up just converting everything to dicts and then manually parsing it into the actual object type. A declarative way of writing these schemata, and passing them directly to json.load(), would be Nice To Have. Perhaps just pass the dataclass of the root object as an argument or something like that? dataclasses already have all the introspection support required for json to figure the rest out on its own.)<br> </div> Wed, 29 Apr 2020 17:18:04 +0000