On Tue, Jun 22, 2021 at 3:55 AM Soni L. <fakedme...@gmail.com> wrote: > > > > On 2021-06-21 12:49 p.m., Chris Angelico wrote: > > On Tue, Jun 22, 2021 at 1:44 AM Soni L. <fakedme...@gmail.com> wrote: > > > > > > > > > > > > On 2021-06-21 12:26 p.m., Stephen J. Turnbull wrote: > > > > Soni L. writes: > > > > > > > > > The trick to extension methods is that they're only available when > > > > you > > > > > explicitly use them. > > > > > > > > What does "explicitly use them" mean? How does this help avoid the > > > > kinds of problems we know that monkey-patching causes? > > > > > > Monkey-patching: > > > > > > ```py mod1.py > > > import foo > > > > > > foo.Bar.monkeymethod = ... > > > ``` > > > > > > ```py mod2.py > > > import foo > > > > > > foo.Bar.monkeymethod = ... > > > ``` > > > > > > "Extension methods": > > > > > > ```py mod1.py > > > import foo > > > > > > def __getattr__(o, attr): > > > if isinstance(o, foo.Bar) and attr == "monkeymethod": > > > return ... > > > return getattr(o, attr) > > > ``` > > > > > > ```py mod2.py > > > import foo > > > > > > def __getattr__(o, attr): > > > if isinstance(o, foo.Bar) and attr == "monkeymethod": > > > return ... > > > return getattr(o, attr) > > > ``` > > > > > > Note how the former changes foo.Bar, whereas the latter only changes the > > > module's own __getattr__. You can't have conflicts with the latter. > > > (Also note that this "module's own __getattr__" doesn't provide > > > extension methods by itself, but can be used as a mechanism to implement > > > extension methods.) > > > > So what you're saying is that, in effect, every attribute lookup has > > to first ask the object itself, and then ask the module? Which module? > > The one that the code was compiled in? The one that is currently > > running? Both? > > > > And how is this better than just using a plain ordinary function? Not > > everything has to be a method. > > Quite the opposite. You ask the local module (the one that the code was > compiled in), and the module decides whether/when to ask the object itself. > > In other words, every > > foo.bar > > would be sugar for > > __getattr__(foo, "bar") > > (where __getattr__ defaults to builtins.getattr) instead of being sugar for > > <builtins.getattr>(foo, "bar") > > (where <> is used to indicate that it doesn't quite desugar that way - > otherwise you'd need to recursively desugar it to > builtins.getattr(builtins, "getattr") which uh, doesn't work.) >
Thanks for clarifying. This doesn't change the problem though - it just changes where the issue shows up. (BTW, what you're describing is closer to __getattribute__ than it is to __getattr__, so if you're proposing this as the semantics, I strongly recommend going with that name.) So, here's the question - a clarification of what I asked vaguely up above. Suppose you have a bunch of these extension methods, and a large project. How are you going to register the right extension methods in the right modules within your project? You're binding the functionality to the module in which the code was compiled, which will make exec/eval basically unable to use them, and that means you'll need some way to set them in each module, or to import the setting from somewhere else. How do you propose doing this? ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@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/3DL46SIS2A7D3W4FNSTH37O6VDJJB2ZP/ Code of Conduct: http://python.org/psf/codeofconduct/