SimpleNamespace vs object
Starting this as a new thread for the interested reader: On 17.02.21 11:18, Chris Angelico wrote:
On Wed, Feb 17, 2021 at 9:11 PM Sven R. Kunze <srkunze@mail.de> wrote:
Still think that "object()" should be writable since this seems like an arbitrary restriction (+SimpleNamespace is no builtin and at least I would use object() for fast PoCs or dirty hackery). But I guess there's been discussion around this already.
[...]
Using SimpleNamespace is the best way to do this, and maybe there's a good argument for making it a builtin (or at least giving it a shorter name), but changing object would be problematic.
I would be skeptical that either those ideas would help a lot. My reasoning is the following: Given the usual terminology in computer science and programming courses, we think in "objects". "Namespaces" on the other side are quite static, usual representing surroundings or environments which in turn can contain "objects". Sadly, the terminology-wise ideal solution is blocked by technical reasons. The thinking in the concepting use-case goes like "I need a blank object which I can do random things with" (yes, including attaching new attributes to it, maybe other stuff as well). The thinking "hey I need a (simple) namespace which I can attach attributes to" requires quite some thoughts especially when being in a more "concepting"/"trying out ideas" mood. In this phase, one does not simply know what one needs ("could be sentinel only", "could be data carrying", "could be signalling", "could something else") and things move quickly. So, just as an example when renaming/aliasing "types.SimpleNamespace" to "builtins.thing", my expectation would be that people could be horribly confused seeing "object" and "thing" being a builtin when used in a project simultaneously. This always leads to questions like "what to use now?" As a conclusion I would say let's leave it like it is since it's a minor issue. Best Sven
From other thread: On Wed, Feb 17, 2021 at 5:19 AM Chris Angelico <rosuav@gmail.com> wrote:
On Wed, Feb 17, 2021 at 9:11 PM Sven R. Kunze <srkunze@mail.de> wrote:
Still think that "object()" should be writable since this seems like an arbitrary restriction (+SimpleNamespace is no builtin and at least I would use object() for fast PoCs or dirty hackery). But I guess there's been discussion around this already.
It can't, because subclasses of object would then ALSO be writable, and that would break a lot of things. Also, a lot of use-cases for object() just need sentinels, with no attributes, so this would cost them a lot of efficiency.
Using SimpleNamespace is the best way to do this, and maybe there's a good argument for making it a builtin (or at least giving it a shorter name), but changing object would be problematic.
ChrisA
I would personally love for SimpleNamespace to get a shorter name and become a built-in. It is a fantastic object to use in all kinds of situations and if it were given the same status as dict, tuple, etc etc, many more people would benefit from it. Right now it is pretty obscure and you could use python for years and not know about it. I think all but the most casual of python users at least end up on the built-in webpage at least once, clicking through to read about the different built-ins and what they are for. Rick. --- Ricky. "I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler On Wed, Feb 17, 2021 at 9:46 AM Sven R. Kunze <srkunze@mail.de> wrote:
Starting this as a new thread for the interested reader:
On 17.02.21 11:18, Chris Angelico wrote:
On Wed, Feb 17, 2021 at 9:11 PM Sven R. Kunze <srkunze@mail.de> wrote:
Still think that "object()" should be writable since this seems like an arbitrary restriction (+SimpleNamespace is no builtin and at least I would use object() for fast PoCs or dirty hackery). But I guess there's been discussion around this already.
[...]
Using SimpleNamespace is the best way to do this, and maybe there's a good argument for making it a builtin (or at least giving it a shorter name), but changing object would be problematic.
I would be skeptical that either those ideas would help a lot. My reasoning is the following:
Given the usual terminology in computer science and programming courses, we think in "objects". "Namespaces" on the other side are quite static, usual representing surroundings or environments which in turn can contain "objects". Sadly, the terminology-wise ideal solution is blocked by technical reasons.
The thinking in the concepting use-case goes like "I need a blank object which I can do random things with" (yes, including attaching new attributes to it, maybe other stuff as well).
The thinking "hey I need a (simple) namespace which I can attach attributes to" requires quite some thoughts especially when being in a more "concepting"/"trying out ideas" mood.
In this phase, one does not simply know what one needs ("could be sentinel only", "could be data carrying", "could be signalling", "could something else") and things move quickly.
So, just as an example when renaming/aliasing "types.SimpleNamespace" to "builtins.thing", my expectation would be that people could be horribly confused seeing "object" and "thing" being a builtin when used in a project simultaneously. This always leads to questions like "what to use now?"
As a conclusion I would say let's leave it like it is since it's a minor issue.
Best Sven _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/3IICAA... Code of Conduct: http://python.org/psf/codeofconduct/
On Thu, Feb 18, 2021 at 1:53 AM Ricky Teachey <ricky@teachey.org> wrote:
From other thread:
On Wed, Feb 17, 2021 at 5:19 AM Chris Angelico <rosuav@gmail.com> wrote:
On Wed, Feb 17, 2021 at 9:11 PM Sven R. Kunze <srkunze@mail.de> wrote:
Still think that "object()" should be writable since this seems like an arbitrary restriction (+SimpleNamespace is no builtin and at least I would use object() for fast PoCs or dirty hackery). But I guess there's been discussion around this already.
It can't, because subclasses of object would then ALSO be writable, and that would break a lot of things. Also, a lot of use-cases for object() just need sentinels, with no attributes, so this would cost them a lot of efficiency.
Using SimpleNamespace is the best way to do this, and maybe there's a good argument for making it a builtin (or at least giving it a shorter name), but changing object would be problematic.
ChrisA
I would personally love for SimpleNamespace to get a shorter name and become a built-in.
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use. * namespace * ns * Thing * dump * plunkit I'm not a fan of any of those, but let's see how inspired other people are :) ChrisA
On 2021-02-17 11:21, Chris Angelico wrote:
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
* namespace * ns * Thing * dump * plunkit
Does using SimpleNamespace have any other meaningful ramifications besides being able to add attributes? When I see people suggest SimpleNamespace, it's usually just to use it as a dict which is accessed with attribute syntax instead of item syntax. Given that, I think a name like `attrdict` would be appropriate. (There is already a PyPI package called attrdict that uses this name for this purpose: https://pypi.org/project/attrdict/ , And I feel like I've seen other examples of similar names where someone wrote their own mini-implementation of such a thing.) -- Brendan Barnwell "Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail." --author unknown
On Thu, Feb 18, 2021 at 8:53 AM Brendan Barnwell <brenbarn@brenbarn.net> wrote:
On 2021-02-17 11:21, Chris Angelico wrote:
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
* namespace * ns * Thing * dump * plunkit
Does using SimpleNamespace have any other meaningful ramifications besides being able to add attributes? When I see people suggest SimpleNamespace, it's usually just to use it as a dict which is accessed with attribute syntax instead of item syntax. Given that, I think a name like `attrdict` would be appropriate. (There is already a PyPI package called attrdict that uses this name for this purpose: https://pypi.org/project/attrdict/ , And I feel like I've seen other examples of similar names where someone wrote their own mini-implementation of such a thing.)
The main thing it has is a very useful repr, but that doesn't conflict with the name attrdict. ChrisA
If we're bike shedding, I'd go for "mutableobject". It's not terribly short, but it is built on familiar python terminology and does exactly what it says in the box: like object() but mutable On Wed, 17 Feb 2021, 23:01 Chris Angelico, <rosuav@gmail.com> wrote:
On Thu, Feb 18, 2021 at 8:53 AM Brendan Barnwell <brenbarn@brenbarn.net> wrote:
On 2021-02-17 11:21, Chris Angelico wrote:
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
* namespace * ns * Thing * dump * plunkit
Does using SimpleNamespace have any other meaningful
ramifications
besides being able to add attributes? When I see people suggest SimpleNamespace, it's usually just to use it as a dict which is accessed with attribute syntax instead of item syntax. Given that, I think a name like `attrdict` would be appropriate. (There is already a PyPI package called attrdict that uses this name for this purpose: https://pypi.org/project/attrdict/ , And I feel like I've seen other examples of similar names where someone wrote their own mini-implementation of such a thing.)
The main thing it has is a very useful repr, but that doesn't conflict with the name attrdict.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/BNXRZJ... Code of Conduct: http://python.org/psf/codeofconduct/
Why is this a discussion?! Just start your program with: from types import SimpleNamespace as myfavname On Wed, Feb 17, 2021 at 11:22 PM Daniel Moisset <dfmoisset@gmail.com> wrote:
If we're bike shedding, I'd go for "mutableobject". It's not terribly short, but it is built on familiar python terminology and does exactly what it says in the box: like object() but mutable
On Wed, 17 Feb 2021, 23:01 Chris Angelico, <rosuav@gmail.com> wrote:
On Thu, Feb 18, 2021 at 8:53 AM Brendan Barnwell <brenbarn@brenbarn.net> wrote:
On 2021-02-17 11:21, Chris Angelico wrote:
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
* namespace * ns * Thing * dump * plunkit
Does using SimpleNamespace have any other meaningful
ramifications
besides being able to add attributes? When I see people suggest SimpleNamespace, it's usually just to use it as a dict which is accessed with attribute syntax instead of item syntax. Given that, I think a name like `attrdict` would be appropriate. (There is already a PyPI package called attrdict that uses this name for this purpose: https://pypi.org/project/attrdict/ , And I feel like I've seen other examples of similar names where someone wrote their own mini-implementation of such a thing.)
The main thing it has is a very useful repr, but that doesn't conflict with the name attrdict.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/BNXRZJ... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/VZ7ZAX... Code of Conduct: http://python.org/psf/codeofconduct/
-- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.
On Wed, Feb 17, 2021, 6:20 PM Daniel Moisset <dfmoisset@gmail.com> wrote:
If we're bike shedding, I'd go for "mutableobject". It's not terribly short, but it is built on familiar python terminology and does exactly what it says in the box: like object() but mutable
That is a pretty good suggestion. I'd like it to be shorter though. mobject?
On Wed, Feb 17, 2021 at 11:28:05AM -0800, Brendan Barnwell wrote:
When I see people suggest SimpleNamespace, it's usually just to use it as a dict which is accessed with attribute syntax instead of item syntax.
If its a dict, it must have dict methods. That leads to conflict: data fields and methods collide. A Bunch (see my previous post) or SimpleNamespace doesn't have that problem. A Bunch has no methods (apart from dunders) and so there is no way for them to collide with field names. Things like attrdict, and the Javascript "convenience" short-cut that allows dict key:item pairs to be accessed through attribute syntax, are an attractive nuisance because of that collision problem. -- Steve
On 18.02.2021 12:00, Steven D'Aprano wrote:
On Wed, Feb 17, 2021 at 11:28:05AM -0800, Brendan Barnwell wrote:
When I see people suggest SimpleNamespace, it's usually just to use it as a dict which is accessed with attribute syntax instead of item syntax.
If its a dict, it must have dict methods. That leads to conflict: data fields and methods collide.
A Bunch (see my previous post) or SimpleNamespace doesn't have that problem. A Bunch has no methods (apart from dunders) and so there is no way for them to collide with field names.
Things like attrdict, and the Javascript "convenience" short-cut that allows dict key:item pairs to be accessed through attribute syntax, are an attractive nuisance because of that collision problem.
I use a Namespace class for such things, with methods using an underscore as prefix to avoid clashes with attributes. It supports the attribute protocol, the dictionary protocol and also comes with some extras, such as optional defaults for unknown attributes, or formatting support. Oh, and acquisition is also supported, for those who still know how this was used in Zope to do attribute access across hierarchies. You can find this in the egenix-mx-base package under mx.Misc.Namespace. -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Experts (#1, Feb 18 2021)
Python Projects, Coaching and Support ... https://www.egenix.com/ Python Product Development ... https://consulting.egenix.com/
::: We implement business ideas - efficiently in both time and costs ::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 https://www.egenix.com/company/contact/ https://www.malemburg.com/
On 2021-02-18 at 06:21:19 +1100, Chris Angelico <rosuav@gmail.com> wrote:
On Thu, Feb 18, 2021 at 1:53 AM Ricky Teachey <ricky@teachey.org> wrote:
I would personally love for SimpleNamespace to get a shorter name and become a built-in.
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
* namespace * ns * Thing * dump * plunkit
I'm not a fan of any of those, but let's see how inspired other people are :)
stuff (thank you, George Carlin!) bag Using a initial lower case letter makes it feel more built in, at the expense of likely breaking more existing code. Using an initial capital letter makes it feel more like a class, which may or may not be a good thing.
On Wed, Feb 17, 2021 at 2:32 PM <2QdxY4RzWzUUiLuE@potatochowder.com> wrote:
On 2021-02-18 at 06:21:19 +1100, Chris Angelico <rosuav@gmail.com> wrote:
On Thu, Feb 18, 2021 at 1:53 AM Ricky Teachey <ricky@teachey.org> wrote:
I would personally love for SimpleNamespace to get a shorter name and
become a built-in.
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
* namespace * ns * Thing * dump * plunkit
I'm not a fan of any of those, but let's see how inspired other people are :)
stuff (thank you, George Carlin!) bag
Using a initial lower case letter makes it feel more built in, at the expense of likely breaking more existing code. Using an initial capital letter makes it feel more like a class, which may or may not be a good thing.
a few monty python inspired ideas that aren't likely to conflict with much existing code: * circus * parrot * swallow * nudge * grail * patsy --- Ricky. "I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler
On Sat, Feb 20, 2021, 12:56 PM Jan Kaliszewski <zuo@kaliszewski.net> wrote:
2021-02-17 Ricky Teachey <ricky@teachey.org> dixit:
* patsy
I love this one! :-)
Cheers. *j
PS. But it should be callable and, when called, it should raise RuntimeError("It's only a model!")
Have to admit I was proud of this idea. Haha. Glad someone else picked up on it.
Chris Angelico writes:
On Thu, Feb 18, 2021 at 1:53 AM Ricky Teachey <ricky@teachey.org> wrote:
I would personally love for SimpleNamespace to get a shorter name and become a built-in.
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short,
"It". Too bad about the "not TOO short" requirement, you can't always get what you want, but if you try sometime.... :-)
On Thu, Feb 18, 2021 at 5:25 PM Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Chris Angelico writes:
On Thu, Feb 18, 2021 at 1:53 AM Ricky Teachey <ricky@teachey.org> wrote:
I would personally love for SimpleNamespace to get a shorter name and become a built-in.
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short,
"It". Too bad about the "not TOO short" requirement, you can't always get what you want, but if you try sometime.... :-)
As someone who's worked in IT all my life, I should have seen that one coming :) ChrisA
On Thu, Feb 18, 2021 at 06:21:19AM +1100, Chris Angelico wrote:
I would personally love for SimpleNamespace to get a shorter name and become a built-in.
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be?
The traditional name is "Bunch". Nineteen years ago, Alex Martelli's recipe for Bunch was published in the Python Cookbook. You can still find the recipe here: https://code.activestate.com/recipes/52308-the-simple-but-handy-collector-of... Another common name is "Bag", although I've also seen that used as a name for a multiset. -- Steve
On Thu, Feb 18, 2021 at 9:57 PM Steven D'Aprano <steve@pearwood.info> wrote:
On Thu, Feb 18, 2021 at 06:21:19AM +1100, Chris Angelico wrote:
I would personally love for SimpleNamespace to get a shorter name and become a built-in.
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be?
The traditional name is "Bunch". Nineteen years ago, Alex Martelli's recipe for Bunch was published in the Python Cookbook. You can still find the recipe here:
https://code.activestate.com/recipes/52308-the-simple-but-handy-collector-of...
Another common name is "Bag", although I've also seen that used as a name for a multiset.
Yeah, not a fan of Bag because of that usage, but I'm liking Bunch. ChrisA
If SimpleNamespace were to become a builtin, what should its name be?
Just to have the obvious out of the way: * obj() - fits with most other builtins in that they are abbreviations and 3-4 letters * data() - same, might be confused with dataclass * container() * values() Most of these are likely *widely used* as variables already, but at least they are descriptive. :) (As a related point, this could become really nice to use if we ever got an "auto" return type. Most of the time the return type *name* of a single-use function is largely important and annoying to have to define in a different place from its usage, but I'd still like to have it type checked. https://github.com/python/typing/issues/727) Ciao, Dan Strokirk
2021-02-18 Chris Angelico <rosuav@gmail.com> dixit: [...]
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
* namespace * ns * Thing * dump * plunkit
I'm not a fan of any of those, but let's see how inspired other people are :)
* plate * tray * depot * board * attrboard * attrholder * attrpanel * attrspace Cheers. *j
Cheeseshop! On Sat, Feb 20, 2021, 1:08 PM Jan Kaliszewski <zuo@kaliszewski.net> wrote:
2021-02-18 Chris Angelico <rosuav@gmail.com> dixit:
[...]
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
* namespace * ns * Thing * dump * plunkit
I'm not a fan of any of those, but let's see how inspired other people are :)
* plate * tray * depot * board * attrboard * attrholder * attrpanel * attrspace
Cheers. *j _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/MIWUHK... Code of Conduct: http://python.org/psf/codeofconduct/
Are we just trying to list every imaginable word that is even vaguely related to the concept of "something that holds something"? If we have plate, tray, board then surely we should include saucer, cup, bowl, pot, frying_pan, cheeseboard, box, suitcase, luggage, handbag, ... Trying to exhaustively list every synonym is just exhausting and not very productive. It is okay to have a first pass filter and reject words which are clearly unsuitable, like "plate" and "panel" (with or without the "attr" prefix) etc. - A plate is a plain, featureless object, the very opposite of something that has arbitrary attributes; - a panel is best used for compound UI elements like *instrument panel*. There isn't a generic name for "thing that we attach other things to". There are specific concrete examples of such: a notice board, a tool board, a coat rack, letter spike, meat hook, etc but they're too specific. The general term "board" has the wrong connotations, e.g. flat rather than abstract. Other naming problems: - it's an object, but `object` is already in use for the immutable base object; - "thing" is too generic; - anything like "plate", "bag" etc is too specific and usually a bad analogy; - "Bunch" at least has historical usage, but it's not really a good analogy for a single object with arbitrary attributes; - anything related to "namespace" is problematic because, although the object actually *is* a namespace, so is every other object; even None has (dunder) attributes; - and also we're not using it as a namespace in the classical sense of globals or local namespace. Fundamentally, this object with attributes doesn't have a good name, and the data model is suspect too. It's not really a collection, as such, since attributes are semantically *part of the object* as opposed to arbitrary data (dog.tail versus dog carrying a bone). Nevertheless, a collection is what we're going to use it as, a key:value mapping where the keys are limited to identifiers and access is via attribute access rather than subscripting. That conflict makes it hard to come up with a good name for it. Honestly, I think that while it's fun to try to imagine names for this, I don't think that there is a *good* name for it that everyone will agree on. So let's just import it using whatever name you like: from types import SimpleNamespace as apparatus -- Steve
On 2021-02-17 11:21, Chris Angelico wrote:
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
Thinking about this more, I think the main obstacle to use of SimpleNamespace isn't the name, it's its the location. No one is going to look in the types module for something like this. Why not just put SimpleNamespace in the collections module? The one in types could be aliased to it (or vice versa if we really don't want to change anything). That seems like it's a trivial change that would greatly increase discoverability of SimpleNamespace without adding complexity of any kind. -- Brendan Barnwell "Do not follow where the path may lead. Go, instead, where there is no path, and leave a trail." --author unknown
On Mon, Feb 22, 2021 at 2:09 AM Brendan Barnwell <brenbarn@brenbarn.net> wrote:
Thinking about this more, I think the main obstacle to use of SimpleNamespace isn't the name, it's its the location. No one is going to look in the types module for something like this. Why not just put SimpleNamespace in the
collections module? THIS I completely agree with! I absolutely do not think this needs a built-in. But I also find that I've nearly never used SimpleNamespace; and 95% of the reason I don't is because of where it lives. Very commonly, I think about what particular collection is most relevant for my data. And if it's not a set, list, or dict, I nearly always look in `collections`. Looking in `types` feels just weird, and it probably has slipped my mind sometimes even when it would be the best choice. OK, yes occasionally I look in `queue`, which is collection-like. And dataclasses, of course (which I thought should have gone in `collections`). Or if I want some extra useful behaviors, maybe I use dbm or sqlite3, which are kinda collections too (or NumPy, Pandas, xarray, etc). But looking in `types` for a collection feels very wrong. -- The dead increasingly dominate and strangle both the living and the not-yet born. Vampiric capital and undead corporate persons abuse the lives and control the thoughts of homo faber. Ideas, once born, become abortifacients against new conceptions.
On Mon, Feb 22, 2021 at 1:11 PM Brendan Barnwell <brenbarn@brenbarn.net> wrote:
On 2021-02-17 11:21, Chris Angelico wrote:
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
Thinking about this more, I think the main obstacle to use of SimpleNamespace isn't the name, it's its the location. No one is going to look in the types module for something like this.
Why not just put SimpleNamespace in the collections module? The one in types could be aliased to it (or vice versa if we really don't want to change anything). That seems like it's a trivial change that would greatly increase discoverability of SimpleNamespace without adding complexity of any kind.
I absolutely agree, and that's going to be the cornerstone of the proposal :) But at the same time as putting into collections, we can also give it a much shorter name. Whatever happens, it's going to be an exact alias for types.SimpleNamespace, which isn't going away. In my mind, the current front-runners are: * namespace * ns * thing * mutableobject * mobject * attrobject * bunch I've written them all in lowercase, but equally viable would be to spell it MutableObject etc. Half of the collections module is each way at the moment. Picture yourself in need of something like this. Would you browse the collections module, and if so, which of these names would grab your attention? Counter: Picture yourself needing something unrelated, like a way to figure out the ten most common numbers in a list. If you were to browse the collections module looking for that, which of these names would falsely grab your attention? Those names are too generic. ChrisA
Hello, On Mon, 22 Feb 2021 15:51:37 +1100 Chris Angelico <rosuav@gmail.com> wrote: []
In my mind, the current front-runners are:
* namespace
* ns * thing * mobject * bunch
Such short generic names shouldn't be used for types added so late in the language evolution. Those are names for variables. (And lowercase in general, with the exception of handful(!) core types). A typical use is: ns = SimpleNamespace() Anyone who doesn't agree always has "import as" in their disposal (as a more structured form of "whatever_i_want = official_descriptive_name").
* mutableobject * attrobject
I've written them all in lowercase, but equally viable would be to spell it MutableObject etc. Half of the collections module is each way at the moment.
There's only one lower-case type name in "collections" - deque. Umm, with some squinting, you can see that as "semi-core" type, like "list". namedtuple() is not a type, it's a function. Yes, semantically it's a type constructor, and somewhere like in Haskell it would follow naming conventions for types, but in Python, it happens to be just a function, and happened to follow naming conventions for functions. So, hopefully window for the lower-case types is as closed as anytime (last case was indeed adding "odict" as a builtin alias for collection.OrderedDict instead of falling for 3.6 mapping algorithmic fiasco), and all newly added types will follow the established naming conventions. [] -- Best regards, Paul mailto:pmiscml@gmail.com
On Mon, Feb 22, 2021 at 6:27 PM Paul Sokolovsky <pmiscml@gmail.com> wrote:
Hello,
On Mon, 22 Feb 2021 15:51:37 +1100 Chris Angelico <rosuav@gmail.com> wrote:
[]
In my mind, the current front-runners are:
* namespace
* ns * thing * mobject * bunch
Such short generic names shouldn't be used for types added so late in the language evolution. Those are names for variables. (And lowercase in general, with the exception of handful(!) core types).
A typical use is:
ns = SimpleNamespace()
Anyone who doesn't agree always has "import as" in their disposal (as a more structured form of "whatever_i_want = official_descriptive_name").
* mutableobject * attrobject
I've written them all in lowercase, but equally viable would be to spell it MutableObject etc. Half of the collections module is each way at the moment.
There's only one lower-case type name in "collections" - deque. Umm, with some squinting, you can see that as "semi-core" type, like "list".
Two - deque and defaultdict.
namedtuple() is not a type, it's a function. Yes, semantically it's a type constructor, and somewhere like in Haskell it would follow naming conventions for types, but in Python, it happens to be just a function, and happened to follow naming conventions for functions.
Just as int used to be a function, not a type. The distinction really isn't all that fundamental (and people periodically ask about issubclass(x, namedtuple), which would depend on it becoming a type after all).
So, hopefully window for the lower-case types is as closed as anytime (last case was indeed adding "odict" as a builtin alias for collection.OrderedDict instead of falling for 3.6 mapping algorithmic fiasco), and all newly added types will follow the established naming conventions.
I'm fine with it ending up with an uppercase name, as mentioned in the summary a couple of posts back. Doesn't really bother me either way, and I doubt it'll bother most of the people who use it. But a short name, and in collections rather than types, will be a definite improvement. ChrisA
On Mon, Feb 22, 2021 at 10:27:55AM +0300, Paul Sokolovsky wrote:
Such short generic names shouldn't be used for types added so late in the language evolution. Those are names for variables. (And lowercase in general, with the exception of handful(!) core types).
A handful you say. int, float, str, list, tuple, dict, bytes, bytearray, set, frozenset, bool, memoryview, object, complex; plus some more in the stdlib such as deque,; plus some which are technically types but are usually used as if they were functions, such as slice, range, map, filter, zip, etc. So by my count that makes at least 15, or 20 if you include the function-like types. You must have big hands. If this bunch-of-attributes object was to move into the std lib, it would likely become a "core type" and we'd want it to have a short, simple, all-lowercase name, like the other core types.
A typical use is:
ns = SimpleNamespace()
Anyone who doesn't agree always has "import as" in their disposal (as a more structured form of "whatever_i_want = official_descriptive_name").
The type is not going to be called "ns", that's too cryptic for a core type. We have "dict", not "dt", "int", not "it", "complex, not "cx". So you will still be able to say: ns = obj = o = bunch() for example. You always have `from builtins import bunch as MyLongDescriptiveName` if you disagree. [...]
So, hopefully window for the lower-case types is as closed as anytime (last case was indeed adding "odict" as a builtin alias for collection.OrderedDict instead of falling for 3.6 mapping algorithmic fiasco),
"Fiasco"?
and all newly added types will follow the established naming conventions.
The established naming conversion for built-in standard types other than exceptions is all lowercase. -- Steve
On 22/02/2021 04:51, Chris Angelico wrote:
On Mon, Feb 22, 2021 at 1:11 PM Brendan Barnwell <brenbarn@brenbarn.net> wrote:
Why not just put SimpleNamespace in the collections module? The one in types could be aliased to it (or vice versa if we really don't want to change anything). That seems like it's a trivial change that would greatly increase discoverability of SimpleNamespace without adding complexity of any kind.
I absolutely agree, and that's going to be the cornerstone of the proposal :) Seems sensible. But at the same time as putting into collections, we can also give it a much shorter name. Whatever happens, it's going to be an exact alias for types.SimpleNamespace, which isn't going away.
In my mind, the current front-runners are:
* namespace * ns * thing * mutableobject * mobject * attrobject * bunch
I What's wrong with "namespace"? None of the other names IMO convey the intended/suggested use nearly as well. Rob Cliffe
On Mon, Feb 22, 2021 at 11:22:09AM +0000, Rob Cliffe via Python-ideas wrote:
What's wrong with "namespace"? None of the other names IMO convey the intended/suggested use nearly as well.
The problem with "namespace" is that the intended us is not as a namespace, but as a dict using `.` syntax instead of `["key"]` syntax, as in Javascript. The normal use of a namespace is something that you *implicitly* lookup names in, e.g. locals, globals, builtins. Whereas this is more of a key:value store where the keys are restricted to identifiers and you use attribute syntax to access the values. I know there's a lot of overlap in functionality and semantics between objects, namespaces and dicts, but generally speaking we don't talk about an int being a namespace when we look up a method: (47295).bit_length() nor do we normally think of a dict as a namespace, unless it's the backend data store of globals etc. So we have the funny situation that *technically* every object is a namespace, but the objects that we use as namespaces are usually dicts, and we don't use dict attributes as the namespace names/values, we use keys/values instead.
On 2021-02-21 20:51, Chris Angelico wrote:
In my mind, the current front-runners are:
* namespace * ns * thing * mutableobject * mobject * attrobject * bunch
Short and PascalCase please, to avoid collisions: * Stuff With credit to George Carlin. ;-) Some of these work as well, Kit is not bad: https://www.thesaurus.com/browse/stuff -Mike
Hello, On Sun, 21 Feb 2021 16:51:37 -0800 Brendan Barnwell <brenbarn@brenbarn.net> wrote:
On 2021-02-17 11:21, Chris Angelico wrote:
Okay. Let's start bikeshedding. If SimpleNamespace were to become a builtin, what should its name be? It needs to be short (obviously), but not TOO short, and it needs to be at least somewhat descriptive, and it needs to not cause confusion with "object". Ideally, it should get a name that's unlikely to conflict with names already in frequent use.
Thinking about this more, I think the main obstacle to use of SimpleNamespace isn't the name, it's its the location. No one is going to look in the types module for something like this.
Well, they should (start to look around).
Why not just put SimpleNamespace in the collections module? The one in types could be aliased to it (or vice versa if we really don't want to change anything). That seems like it's a trivial change that would greatly increase discoverability of SimpleNamespace without adding complexity of any kind.
One explanation why SimpleNamespace is not in "collections" is because ... it's not a collection. One of the basic traits of any collection is that it "contains" things, and thus it can be directly iterated over to traverse those contents: for item in collection: ... SimpleNamespace is not like that. It doesn't "contain" things (no more than overdynamic mata-protocols allow, and those are implementation details). It "holds" things. It's, well, just a simple namespace. But seems that people mix up it with that thingy which allows ambiguous access both by a key indexing and attribute access. And that puts SimpleNamespace in danger, because after "let's munge its name/location" requests, what will follow is "let's add unrelated methods to it". But I agree that putting it in "collections" is an interesting plot twist. We already gave up hope for "types", and knowing that it contains lotsa mess, simply don't look for pearls which may be there. Let's now do the same to "collections". [] -- Best regards, Paul mailto:pmiscml@gmail.com
On Mon, Feb 22, 2021 at 6:08 PM Paul Sokolovsky <pmiscml@gmail.com> wrote:
One explanation why SimpleNamespace is not in "collections" is because ... it's not a collection. One of the basic traits of any collection is that it "contains" things, and thus it can be directly iterated over to traverse those contents:
for item in collection: ...
SimpleNamespace is not like that.
So it's not iterable. But does everything HAVE to be iterable to go into that module? UserString technically is, but I don't think it's there to function as an iterable - it's there to function as a string. (TBH I think that UserDict/UserList/UserString would probably fit better into types than collections.) One very common use for SimpleNamespace is a sort of "generic record type", kinda like a namedtuple but minus the iteration and without needing to predefine the attributes. Placing it alongside namedtuple will make that easier to work with. OTOH, that also makes it kinda like a generic dataclass, but this isn't going to go into the dataclasses module, so I'm not sure how strong an argument that is. Ultimately, SimpleNamespace is useless if it can't be found. If people looking for this are not going to look in types, then either people need to be educated (good luck with that - you can't fight human nature), or it needs to be placed where people will find it. ChrisA
Hello, On Mon, 22 Feb 2021 18:26:28 +1100 Chris Angelico <rosuav@gmail.com> wrote:
On Mon, Feb 22, 2021 at 6:08 PM Paul Sokolovsky <pmiscml@gmail.com> wrote:
One explanation why SimpleNamespace is not in "collections" is because ... it's not a collection. One of the basic traits of any collection is that it "contains" things, and thus it can be directly iterated over to traverse those contents:
for item in collection: ...
SimpleNamespace is not like that.
[]
Ultimately, SimpleNamespace is useless if it can't be found. If people looking for this are not going to look in types, then either people need to be educated (good luck with that - you can't fight human nature), or it needs to be placed where people will find it.
Well, I tried to put all devil's advocate counter-arguments I could come up with in the first mail, and have nothing to add. No wait, I have another one! I hope people factored in that typing "collections" is 2.2 times harder than "types" :-D.
Two - deque and defaultdict.
Well, I tell me to not write emails before morning coffee, but on weekdays, that's the only time I have for it. But actually, I guess it's only more useful in the wider context, tells us something how well the table at the beginning of https://docs.python.org/3/library/collections.html is structured for quick-looking, and how logical vs random the order of rows in it ;-). -- Best regards, Paul mailto:pmiscml@gmail.com
On Mon, Feb 22, 2021 at 06:26:28PM +1100, Chris Angelico wrote:
Ultimately, SimpleNamespace is useless if it can't be found.
"Can't" be found is an exaggeration. The std lib is full of little gems, and people learn them and use them. Generally when people talk about something that "can't be found" they mean *undocumented* features, like simplegeneric in pkgutil, which became the inspiration for functools.singledispatch. (And even then, some people obviously did find it.)
If people looking for this are not going to look in types, then either people need to be educated (good luck with that - you can't fight human nature), or it needs to be placed where people will find it.
Of course we can fight human nature. That's what education, school, manners, coding standards, documentation, codes of conduct, laws and community mores are all about. The fact that hardly anyone chased me down the street today with an antelope thighbone to bash my head in is, I think, good evidence that we have mostly been successful. We can't force people to look in `types`, but I don't think that the problem is that they refuse to. It's that they don't know about it's existence. We don't make everything a builtin because people might not know glob; "people don't know about the types module and don't think to look in there" is likewise a weak argument for moving SimpleNamespace into another module. It is an argument, but a weak one. Given that SimpleNamespace objects aren't a collection, they don't meet the collection API, I think that I'm -0.5 on that change. https://docs.python.org/3/library/collections.abc.html A Collection is sized, iterable, and supports `in`; SimpleNamespace supports none of those.
On 18/02/21 3:51 am, Ricky Teachey wrote:
I would personally love for SimpleNamespace to get a shorter name and become a built-in. It is a fantastic object to use in all kinds of situations
I find myself disagreeing with that. It's dead simple to define your own blank-object class, and you get to give it a name that reflects what you're really doing with it. I don't understand why there's such a fascination with things like SimpleNamespace. -- Greg
I agree, I don't think it justifies a builtin, because it is so simple to just define your own empty class. That said, it does come in handy, and I do use it for same reasons others have expressed. On Thu, 2021-02-18 at 11:50 +1300, Greg Ewing wrote:
On 18/02/21 3:51 am, Ricky Teachey wrote:
I would personally love for SimpleNamespace to get a shorter name and become a built-in. It is a fantastic object to use in all kinds of situations
I find myself disagreeing with that. It's dead simple to define your own blank-object class, and you get to give it a name that reflects what you're really doing with it. I don't understand why there's such a fascination with things like SimpleNamespace.
On Thu, Feb 18, 2021 at 11:50:17AM +1300, Greg Ewing wrote:
It's dead simple to define your own blank-object class, and you get to give it a name that reflects what you're really doing with it. I don't understand why there's such a fascination with things like SimpleNamespace.
Right, it takes only two lines of code. So let's do it! >>> class Thing: ... pass ... >>> obj = Thing(attr='value') Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Thing() takes no arguments Hmmm. Okay, *three* lines of code: >>> class Thing: ... def __init__(self, **kw): ... vars(self).update(kw) ... >>> obj = Thing(attr='value') >>> print(obj) <__main__.Thing object at 0x7f2b07c23b80> Damn, that's about as useful as a screen door on a submarine. Let's give it a repr, so when debugging we can see what it actually is. So *five* lines of code: >>> class Thing: ... def __init__(self, **kw): ... vars(self).update(kw) ... def __repr__(self): ... return f'Thing({vars(self)})' ... >>> obj = Thing(attr='value') >>> print(obj) Thing({'attr': 'value'}) >>> obj == Thing(attr='value') False Bugger. So **ten** lines of code: >>> class Thing: ... def __init__(self, **kw): ... vars(self).update(kw) ... def __repr__(self): ... return f'Thing({vars(self)})' ... def __eq__(self, other): ... if isinstance(other, Thing): ... return vars(self) == vars(other) ... else: ... return NotImplemented ... >>> obj = Thing(attr='value') >>> print(obj) Thing({'attr': 'value'}) >>> obj == Thing(attr='value') True So we've gone from a trivial two-liner that doesn't do what we need, to ten lines, without docs or tests. Or we could just use a one-liner: >>> from types import SimpleNamespace and get all of that for free. And if it were a builtin, it would be a zero-liner. -- Steve
Hello, On Thu, 18 Feb 2021 21:27:18 +1100 Steven D'Aprano <steve@pearwood.info> wrote: []
Or we could just use a one-liner:
>>> from types import SimpleNamespace
and get all of that for free. And if it were a builtin, it would be a zero-liner.
Right. If the whole CPython stdlib were builtin, it all would be zero-liner. But it's not, and won't be. Even such important things as OrderedDict and namedtuple live in a module. So, SimpleNamespace will hopefully remain there too. And good luck with renaming it to something not obscure. My bet is on AttrObject ;-). [] -- Best regards, Paul mailto:pmiscml@gmail.com
On Wed, Feb 17, 2021 at 9:11 PM Sven R. Kunze <srkunze@mail.de> wrote:
Still think that "object()" should be writable since this seems like an arbitrary restriction
...
But I guess there's been discussion around this already.
... but changing object would be problematic.
Well, yes, due to backward compatibility -- though how much code is counting on not being able to add attributes to an instance of object? I think someone on this thread (sorry can't find it now) said something like: if you could add attributes to object(), then you'd be able to add attributes to subclasses of object. -- but you can already: Isn't every class a subclass of object? class C: pass C.this = "something" c = C() c.that = "something else" It seems the difference is that both a new class and class instances get a __dict__. But given that all classes derive from object, and object is of type type, and classes are of type type -- I still have no idea why we can't add things to an instance of object. I suppose adding stuff to the object class itself would be very weird -- as that would mess with ALL classes. But adding to an instance of object? why not? -Chris B -- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
On Thu, Feb 18, 2021 at 1:00 PM Christopher Barker <pythonchb@gmail.com> wrote:
On Wed, Feb 17, 2021 at 9:11 PM Sven R. Kunze <srkunze@mail.de> wrote:
Still think that "object()" should be writable since this seems like an arbitrary restriction
...
But I guess there's been discussion around this already.
... but changing object would be problematic.
Well, yes, due to backward compatibility -- though how much code is counting on not being able to add attributes to an instance of object?
I think someone on this thread (sorry can't find it now) said something like:
if you could add attributes to object(), then you'd be able to add attributes to subclasses of object. -- but you can already:
Isn't every class a subclass of object?
class C: pass
You can add attributes to THIS subclass of object. But you can't add attributes to EVERY subclass of object. For instance: x = 1 x.something = 123 If object() could have attributes added, then 1 would have to be able to have attributes added too. And that would cause all manner of problems.
It seems the difference is that both a new class and class instances get a __dict__. But given that all classes derive from object, and object is of type type, and classes are of type type -- I still have no idea why we can't add things to an instance of object.
When you create a class as you did above, it gets a __dict__. But if you set __slots__, the only valid attributes are those listed in the slots. These are inherited:
class X: __slots__ = 'a', 'b' ... class Y(X): __slots__ = 'q', 'w' ... Y.__slots__ ('q', 'w') Y().a = 1 Y().q = 1 Y().z = 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Y' object has no attribute 'z'
But if object() could get arbitrary attributes, then __slots__ wouldn't work. ChrisA
On Wed, Feb 17, 2021 at 6:12 PM Chris Angelico <rosuav@gmail.com> wrote:
But if object() could get arbitrary attributes, then __slots__ wouldn't work.
It seems to me that all you'd have to do is add a line or two to the add_dict logic in type_new so that instances of object get a dict. Then instances of object would get a dict, and nothing else would change. In languages like C++ where an instance of a class contains actual in-memory instances of all of its superclasses, that wouldn't work. In Python, where instances of different classes have a priori nothing to do with each other, I think it would work.
On Thu, Feb 18, 2021 at 1:59 PM Ben Rudiak-Gould <benrudiak@gmail.com> wrote:
On Wed, Feb 17, 2021 at 6:12 PM Chris Angelico <rosuav@gmail.com> wrote:
But if object() could get arbitrary attributes, then __slots__ wouldn't work.
It seems to me that all you'd have to do is add a line or two to the add_dict logic in type_new so that instances of object get a dict. Then instances of object would get a dict, and nothing else would change.
In languages like C++ where an instance of a class contains actual in-memory instances of all of its superclasses, that wouldn't work. In Python, where instances of different classes have a priori nothing to do with each other, I think it would work.
Even if it's possible, though, it's a fairly significant breach of Liskov. And I don't know that other Python implementations would be able to do this so cleanly. What's so hard about using a different type? Especially since the vanilla object repr is basically useless, but SimpleNamespace can tell you what it's carrying. Orthogonal point: SimpleNamespace could easily be made JSON-serializable (as a dict), if that would be of value. ChrisA
On 18.02.21 05:43, Chris Angelico wrote:
On Thu, Feb 18, 2021 at 1:59 PM Ben Rudiak-Gould <benrudiak@gmail.com> wrote:
It seems to me that all you'd have to do is add a line or two to the add_dict logic in type_new so that instances of object get a dict. Then instances of object would get a dict, and nothing else would change.
That's actually a pretty neat idea. :-)
What's so hard about using a different type?
Didnt we already discuss it somewhere else? Many programmers and computer scientists think in "objects", "object-oriented programming" etc.
Especially since the vanilla object repr is basically useless, but SimpleNamespace can tell you what it's carrying.
True but it seems this have never been an issue with "lambda:0".
Orthogonal point: SimpleNamespace could easily be made JSON-serializable (as a dict), if that would be of value.
Sounds great. :-) Best, Sven
participants (19)
-
2QdxY4RzWzUUiLuE@potatochowder.com
-
Ben Rudiak-Gould
-
Brendan Barnwell
-
Chris Angelico
-
Christopher Barker
-
Dan Strokirk
-
Daniel Moisset
-
David Mertz
-
Greg Ewing
-
Jan Kaliszewski
-
M.-A. Lemburg
-
Mike Miller
-
Paul Bryan
-
Paul Sokolovsky
-
Ricky Teachey
-
Rob Cliffe
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Sven R. Kunze