[Python-ideas] Re: s?scanf [was: A string function idea]

2022-03-29 Thread Chris Angelico
On Wed, 30 Mar 2022 at 15:11, Stephen J. Turnbull
 wrote:
>
> Chris Angelico writes:
>
>  > [fruit] = sscanf(sample, "%*sfruit:%s\n")
>
> I'm warming to this idea.  It does hit the sweet spot of doing exactly
> what you want -- except when it can't do what you want at all. :-)
> It's concise and quite powerful, applicable to many common use cases.

It fits nicely between "x,sep,y = str.partition(...)" and a regular expression.

> I do have one windowframe of the bikeshed to paint: this is Python, so
> maybe just "scanf" is a fine name?

Sure, whether it's scanf or sscanf doesn't really matter to me. And -
I had to look this up - the converse is referred to in the docs as
"printf-style formatting", not sprintf. So that's an argument in
favour of "scanf".

> The first argument can be any
> iterable of characters, and if an iterator it would leave the
> iteration pointer where it left off (eg, beginning of next line in
> 'sample' above).

Hmm, I'm not really a fan. To be efficient, scanf will need to be able
to use core string searching functionality - str.index() is faster
than simply iterating over a string and comparing character by
character. I don't think, for instance, that json.load() promises
anything about where it leaves an iterable; in fact, I believe it
simply reads everything into a string and then parses that.

It would be worth supporting both byte strings and text strings,
though, for the same reason that they both support printf formatting.

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/5LHEYKCKVIYHEVCBVVEZDCWCZ4SCZKRX/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] s?scanf [was: A string function idea]

2022-03-29 Thread Stephen J. Turnbull
Chris Angelico writes:

 > [fruit] = sscanf(sample, "%*sfruit:%s\n")

I'm warming to this idea.  It does hit the sweet spot of doing exactly
what you want -- except when it can't do what you want at all. :-)
It's concise and quite powerful, applicable to many common use cases.

I do have one windowframe of the bikeshed to paint: this is Python, so
maybe just "scanf" is a fine name?  The first argument can be any
iterable of characters, and if an iterator it would leave the
iteration pointer where it left off (eg, beginning of next line in
'sample' above).

Then the question would be how to use that feature.  Specifically, how
does scanf deal with the case that the parse fails?  Consider

while True:
fruits.append(scanf(input_file, "%*sfruit:%s\n")[0])

Neither returning a sentinel (presumably None) nor raising a NotFound
exception seems palatable.  Can it raise StopIteration, perhaps
conditional on the first argument having a .__next__?

___
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/HP2FSLOKABQM7HS2ZGKVSRVAI7SSIQYW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread Christopher Barker
On Tue, Mar 29, 2022 at 4:08 PM Steven D'Aprano  wrote:


> I have no strong opinion on whether this simple function should be built
> into the string class,


I do -- this is not sufficiently general to be a string method.


> but I do have a strong opinion about re-writing
> it into a slower, more fragile, harder to understand, less user-friendly
> regex.
>

I do agree there.

I also agree with Chris A's suggestion:

*some* scanner / parser that could be used for this and many other things
that's significantly more straightforward that regex's.

-CHB


-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/LOHHZQD2ZPAZL52OLOWIB5IBCFQQH6KN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread Chris Angelico
On Wed, 30 Mar 2022 at 10:08, Steven D'Aprano  wrote:
> Here's the version of grab I used:
>
> def grab(text, start, end):
> a = text.index(start)
> b = text.index(end, a+len(start))
> return text[a+len(start):b]
>

This is where Python would benefit from an sscanf-style parser.
Instead of regexps, something this simple could be written like this:

[fruit] = sscanf(sample, "%*sfruit:%s\n")

It's simple left-to-right tokenization, so it's faster than a regex
(due to the lack of backtracking). It's approximately as clear, and
doesn't require playing with the index and remembering to skip
len(start).

That said, though - I do think the OP's task is better served by a
tokenization pass that transforms the string into something easier to
look things up in.

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/U4BFSBS5EAD7QNBMHZXOXYMBQVMNXCFB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread Steven D'Aprano
On Tue, Mar 29, 2022 at 11:00:41AM +0300, Serhiy Storchaka wrote:
> 28.03.22 15:13, StrikerOmega пише:
> >And I want to grab some kind of value from it.
> 
> There is a powerful tool designed for solving such problems. Is is 
> called regular expressions.
> 
> >sample.grab(start="fruit:", end="\n")
> > >> 'apple'
> 
> re.search(r'fruit:(.*?)\n', sample)[1]

Now do grab(start="*", end=".").

Of course you know how to do it, but a naive solution:

re.search(r'*(.*?).', sample)[1]

will fail. So now we have to learn about escaping characters in order to 
do a simple find-and-extract. And you need to memorise what characters 
have to be escaped, and if your start and end parameters are expressions 
or parameters rather than literals, the complexity goes up a lot:

# Untested, so probably wrong.
re.search(re.escape(start) + "(.*?)" + re.escape(end))[1]

and we both know that many people won't bother with the escapes until 
they get bitten by bugs in their production code. And even then, regexes 
are a leading source of serious software vulnerabilities.

https://cwe.mitre.org/data/definitions/185.html

Yes, regular expressions can be used. We know that regexes can be used 
to solve most problems, for some definition of "solve". Including 
finding prime numbers:

https://iluxonchik.github.io/regular-expression-check-if-number-is-prime/

A method can raise a useful, self-explanatory error message on failure. 
Your regex raises "TypeError: 'NoneType' object is not subscriptable".

A method can be written to parse nested brackets correctly. A regular 
expression cannot.

And then regexes are significantly slower:

>>> sample = 'Hello world fruit: apple\n'
>>> setup = "from __main__ import grab, sample; import re"
>>> t_grab = Timer("grab(sample, 'fruit', '\\n')", setup=setup)
>>> t_regex = Timer("re.search(r'fruit:(.*?)\\n', sample)[1]", setup=setup)
>>> min(t_grab.repeat())
0.47571489959955215
>>> min(t_regex.repeat())
0.8434272557497025

Here's the version of grab I used:

def grab(text, start, end):
a = text.index(start)
b = text.index(end, a+len(start))
return text[a+len(start):b]

I have no strong opinion on whether this simple function should be built 
into the string class, but I do have a strong opinion about re-writing 
it into a slower, more fragile, harder to understand, less user-friendly 
regex.

Don't make me quote Jamie Zawinski again.


-- 
Steve
___
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/HB34UPEP7B3S5O76KEL3B5GN5TB4ODCJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Ethan Furman

On 3/29/22 14:41, Christopher Barker wrote:
> Ethan Furman queried:

>> The `__dict__` is needed to store the field names -- did you add `__dict__` 
to the
>> `__slots__`?
>
> Nope — though the error indicated that I couldn’t add anything to __slots__ 
when subclassing tuple. But I may have
> misunderstood the error.

Ah, that's right -- it's saying that *instances* cannot have anything in 
`__slots__`, but the class can still have fields:

>>> class Tuple(tuple):
... this = 'eggs'
... that = 'spam'
... __slots__ = ()
... def __new__(cls, *args):
... return tuple.__new__(cls, *args)
...
>>> t = Tuple((1,))
>>> t
(1,)
>>> t.this
'eggs'
>>> t.that
'spam'

So the Tuple class would have properties that redirect to the correct offset -- but that would require a different tuple 
class for each field configuration.


--
~Ethan~


___
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/IHOJQLM5KZIKC6TNKZCYHQ25MICBIIW5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread Steven D'Aprano
On Tue, Mar 29, 2022 at 12:35:56AM -0700, Paul Bryan wrote:

> I wonder if applying regular expressions would sufficiently address
> your use case.

'Some people, when confronted with a problem, think "I know, I'll use 
regular expressions." Now they have two problems.' -- Jamie Zawinski

Apart from (probably) being slower and harder to understand, what 
benefit would a regular expression bring to this problem? Julio already 
has a working solution that does exactly what he wants:

> > I have implemented this function locally to use it for my personal
> > projects and It has proven to be really useful in practice, so I hope
> > you find it useful as well and consider adding it as a class method
> > for strings in Python.


-- 
Steve
___
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/MCIOI2RB24NOHVGF7IFQDXPJILLSKEAW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread Steven D'Aprano
On Tue, Mar 29, 2022 at 09:12:36AM +0200, StrikerOmega wrote:

> The grab function would find the index of the first occurrence of the
> "start" string in the parent string and then the next occurrence of the
> "end" string starting from that index and return the substring between
> those.

That's what I guessed it would do. So your earlier statement:

"You can also "grab" values enclosed in brackets or in any kind of 
character and It works as you would expect."

is wrong. When using brackets I expect it to understand nesting.


-- 
Steve
___
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/OY3QBRRJVRRB3SWS54CRUFA2O6QA22X5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Christopher Barker
>  >> The `__dict__` is needed to store the field names -- did you add
> `__dict__` to the
>  >> `__slots__`?


Nope — though the error indicated that I couldn’t add anything to __slots__
when subclassing tuple. But I may have misunderstood the error.

Also, frankly, I’m completely confused by __slots__ : looking at the
namedtuple implementation, it sets slots to an empty tuple. But it does
have instance attributes without a __dict__.

 > Maybe I'm being an ignoramus but: how would it be possible to even use
> slots? Slots
>  > are descriptors living in the class namespace. You don't know ahead of
> time what the
>  > member names are, so you can't use slots, right?


The idea there is that you’d store the field names in a slot, and
dynamically return the values in __getattr__.

In that case, frozen dict would be nice :-)

Anyway — good idea? I don’t know, ‘cause I did get it to work :-)

-CHB


> You can use them, just make sure one of the slots is `__dict__`.
>
> Of course, by adding `__dict__` you lose most (all?) of the advantages of
> using `__slots__` in the first place.
>
> --
> ~Ethan~
> ___
> 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/QM7MIHKP2GSBN6TYMPDIFKGHGC7KEH6E/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/JHPTA3REQEUTRNZWBLDYRC2MEWKWDL6C/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: mro and super don't feel so pythonic

2022-03-29 Thread malmiteria
Alright everyone.

First of all, thanks for all your answers, I really appreciate the discussion 
we're having.
Turns out i won't have so much free time tonight, and probably tomorrow night 
either, so i won't be able to answer the last few comments before some then.
I apologise if i'm missing some of your answers, if you feel like i missed your 
post, feel free to reiterate your questions / remarks

So, i wanna take that opportunity to step back just a moment, and "list out" 
everything i need to do in the next answer.
1) I've been requested to provide "real life" examples of code, I'll try to 
provide it
2) I think I failed at explaining my idea clearly enough, there are points that 
i wanna make more clear, and overall, I think it would be nice to provide a 
"round 2" of my idea, improved by all your remarks, and made more explicit 
where it was unclear. This is probably gonna be a very lenghty post, and i 
apologise for that in advance. I started a draft here if you are curious : 
https://github.com/malmiteria/super-alternative-to-super/blob/master/conversation/README.md.
 When ready, i'll copy paste it here, but i'll leave it up on that link.
3) I'm also thinking about adding personas to the mix, so we can discuss in 
more depths how this proposal would affect the overall community. (I think 
that's a valuable exercice to do at least once to check if a solution we would 
come up with would be a fit for everyone)
 so far, i can think of :
  - 'the scientist' : he doesn't care about the langage much, he just needs a 
tool for work, and it happens to be python
  - 'the web dev' : he doesn't necesserly know the langage in depths, do not 
need to implement the perfect solution, but is still fairly knowledgable
  - 'the lib maker' : he's very knowledgable, has to think of it's users as 
varying in knowledge and skill, can't let responsibility of his lib leap into 
the lib client hands
  - 'the tester' : wanna test everything
  - 'the refactorer' : hates all code smells

If you think i'm missing important persona that would constitute a decent chunk 
of the python user community, please feel free to add them to the list.

4) I think it is sometimes unclear when i'm talking about how things are rn, 
how things should be, how i imagine things in my solution, and so on.
I'll try to be expllicit about the full context of my statements in the future
5) I'll try to explicit the assumption i work under. Those are sometime hard to 
detect for me, I do not always realise what it is i consider obvious, when it 
might not be so obvious in fact. I'm sure i'll have more to explicit in the 
future.

I think that's it.
I'll also try to take some time to read the link you shared and i didn't know 
about, but i don't wanna leave you hanging for too long either, so I might read 
it this weekend.

If you have any question about things that you want me to make more explicit, 
point that you think i might have forgotten, or anything you wanna make me 
aware of, please keep posting it here, i'll be reading it when i can get more 
free time.
___
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/OLATMNG5R4WFMSVIGAJYVSER6AKSEFFT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Ethan Furman

On 3/29/22 09:57, Ricky Teachey wrote:
> On Tue, Mar 29, 2022 at 12:49 PM Ethan Furman wrote:

>> The `__dict__` is needed to store the field names -- did you add `__dict__` 
to the
>> `__slots__`?  (Of course, if you've added `__dict__` then you lose the 
limited size
>> of `__slots__`.)
>
> Maybe I'm being an ignoramus but: how would it be possible to even use slots? 
Slots
> are descriptors living in the class namespace. You don't know ahead of time 
what the
> member names are, so you can't use slots, right?

You can use them, just make sure one of the slots is `__dict__`.

Of course, by adding `__dict__` you lose most (all?) of the advantages of using 
`__slots__` in the first place.

--
~Ethan~
___
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/QM7MIHKP2GSBN6TYMPDIFKGHGC7KEH6E/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Ricky Teachey
On Tue, Mar 29, 2022 at 12:49 PM Ethan Furman  wrote:

> On 3/29/22 09:14, Christopher Barker wrote:
>
>  > [...] I tried to use __slots__ in TupleWithNames, but apparently you
> can't use __slots__ in a
>  > tuple subclass ('cause tuple's already using it ??) -- but that could
> be done in a builtin.
>  > then it wouldn't need a __dict__
>
> The `__dict__` is needed to store the field names -- did you add
> `__dict__` to the `__slots__`?  (Of course, if you've
> added `__dict__` then you lose the limited size of `__slots__`.)
>
> --
> ~Ethan~
>

Maybe I'm being an ignoramus but: how would it be possible to even use
slots? Slots are descriptors living in the class namespace. You don't know
ahead of time what the member names are, so you can't use slots, right?
Unless you modify the TupleWithNames class on the fly, adding slot names as
they are needed. But then you need some kind of machinery for each instance
to know which slots are valid for that instance, and to block access to
slots that aren't part of that instance.

Again, I might just be a doof.


---
Ricky.

"I've never met a Kentucky man who wasn't either thinking about going home
or actually going home." - Happy Chandler
___
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/GPDPVTWALPF63QBD4BPSAXA2VTQOTIIJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Ethan Furman

On 3/29/22 09:14, Christopher Barker wrote:

> [...] I tried to use __slots__ in TupleWithNames, but apparently you can't 
use __slots__ in a
> tuple subclass ('cause tuple's already using it ??) -- but that could be done 
in a builtin.
> then it wouldn't need a __dict__

The `__dict__` is needed to store the field names -- did you add `__dict__` to the `__slots__`?  (Of course, if you've 
added `__dict__` then you lose the limited size of `__slots__`.)


--
~Ethan~
___
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/B3JZKXQ4HDW5IRNMYKDKB5QFGHRR42AH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Christopher Barker
On Tue, Mar 29, 2022 at 6:37 AM Joseph Martinot-Lagarde <
contreba...@gmail.com> wrote:

> Both suggested implementations are very interesting. If I'm not wrong they
> have exactly the same behavior (except for __dict__).
>

pretty close, yes -- probably differences with pickling, and if you did an
type checking, very different.

Performance-wise with a quick test I get the following results:
>
> t = (1, 2)
> print("sizeof", sys.getsizeof(t))  # 56
> print("sizeof type", sys.getsizeof(type(t)))  # 408
> print(timeit.timeit("(1, 2)"))  # ~0.01
>
> nt = namedtuple("nt", ["x", "y"])
> print("sizeof", sys.getsizeof(nt(1, 2)))  # 56
> print("sizeof type", sys.getsizeof(type(nt(1, 2  # 896
> print(timeit.timeit("nt(1, 2)", setup="from __main__ import nt"))  # ~0.2
>
> pt = atuple(x=1, y=2)
> print("sizeof", sys.getsizeof(pt))  # 56
> print("sizeof type", sys.getsizeof(type(pt)))  # 896
> print(timeit.timeit("atuple(x=12, y=16)", setup="from __main__ import
> atuple"))  # ~0.8
>
> point = TupleWithNames(x=1, y=2)
> print("sizeof", sys.getsizeof(point))  # 64
> print("sizeof type", sys.getsizeof(type(point)))  # 1064
> print(timeit.timeit("TupleWithNames(x=12, y=16)", setup="from __main__
> import TupleWithNames"))  # ~0.8
>

you have to be careful with getsizeof() -- I don't think it digs into
nested objects. Anyway, it would certainly require a close look.

The timing performance of both solutions is roughly the same given the
> measurament variation,


That surprises me -- a tuple has to call namedtuple, and there's a lot of
work done in there -- very odd. I guess that's why we have to profile, but
I'd still give that a closer look.


> but way slower than tuple an namedtuple.
>

well, with namedtuple, you aren't taking into account the creation of the
class -- so if you make thousands of the same one, yes, but if you make
only a couple, then not so much.


> TupleWithNames is a bit more memory hungry than atuple and namedtuple, but
> there is only one type so if I understand correctly it would be a win for
> multiple instances.
>

I think so -- at least of atuple -- though one could create a cache of
namedtuples so that atuple would reuse an existing one if was already there.

Maybe there is room for optimisation in both cases ?
>

I"m sure -- namedtuple use sys.intern on the names, that would help. and I
tried to use __slots__ in TupleWithNames (sorry for that horrible name ;-)
), but apparently you can't use __slots__ in a tuple subclass ('cause
tuple's already using it ??) -- but that could be done in a builtin. then
it wouldn't need a __dict__

There's also various options for storing the fields -- I only tried the
first one I thought of.

This reminds me -- it would be kinda cool if there was an easier, more
robust way to make an immutable in Python -- maybe a frozendict for
__dict__?

Anyway, if someone wants to take this further, I'd be glad to help.

-CHB



-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/OHM6KLGJSQUNP7VBXBCFCHRUONJ6MS67/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread Abdulla Al Kathiri
Thanks for teaching me about the __getitem__ method of the Match class. I 
always do .group(1) before. 

Abdulla

Sent from my iPhone

> On 29 Mar 2022, at 12:02 PM, Serhiy Storchaka  wrote:
> 
> re.search(r'fruit:(.*?)\n', sample)[1]
___
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/PM3DNWEP4NFXT25GPHGP4I4J6YFKQNVZ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: mro and super don't feel so pythonic

2022-03-29 Thread Stephen J. Turnbull
malmiteria  writes:

 > class An:
 >   def method(self):
 > print('An')
 > class A[n-1](An): pass
 > ...
 > class A1(A2): pass
 > class A0(A1):
 >   def method(self):
 > self.__as_parent__(An).method()
 > 
 > A0().method() prints 'An'

Of course it prints 'An', and so does

class A00(A1):
def method(self):
super(A[n-1], self).method()

A00().method()

Equally of course, __as_parent__(An) is exactly what I mean by
"arbitrarily deep".  Note that all you need to identify A[n-1] in this
case is its class definition, and that's probably the great majority
of cases.  To find out, all you need to do is type

>>> class A00(A1): pass
... 
>>> A00.__mro__
[A00, A1, ..., A[n-1], An]

so it's not hard to figure this out.

 > > (a) there are
 > > people who use it for more advanced purposes and (b) it can't cause you
 > > any confusion in that case.
 > 
 > (a) What are those more advanced feature? On top of the classic
 > inheritance features, I can only think of dependency injection
 > in the inheritance tree.

Yes, that's precisely what I have in mind.  However, the application
is declarative composition (I think I just invented that name), as
"Python's super() considered super" demonstrates with the trivial
class LoggingOD[1].  This is very powerful and expressive (when it
works).  At this time, it seems like C3 provides the largest set of
cases where it works.

 > Such a feature could be replaced, although i didn't provide a
 > replacment for this feature, it doesn't seem like it's gonna be
 > hard to do, __as_parent__ could rely on a dict, which would hold as
 > key a class, and as value a class too. If the targeted class is in
 > the keys, target the corresponding value instead. This class could
 > then inherit from the class it replaced, and you got your
 > dependency injection.

Have you read "Python's super() considered super!"?  I definitely get
the impression that you have not understood it.  The point of several
of the examples is that by using super() you can allow a future
subclass to insert a method implementation in the MRO without knowing
either the future subclass nor the class that currently implements the
method.  There are constraints on it, but the MRO allows you to
express many such dependencies in a straightforward declarative
manner, whereas your dict implementation is going to require a lot of
explicit plumbing in derived classes.  Also, the MRO approach allows
different classes to inject different methods, but you're going to
need something more complicated than the simple class -> class
mapping.

 > On top of that, it unties a lot more this dependency injection
 > feature from the method resolution algorithm.

You write that like you think that's a good thing, or it's not already
possible to do that. ;-)

 > (b) Wrong! The common use case for inheritance and super is what
 > informs most people of its behavior,

I think that's irrelevant, since the most common case is single
inheritance, and there's only one (sane) way to resolve methods in
that case.  Trying to extrapolate from that to behavior in a multiple
inheritance context simply means you haven't thought about multiple
inheritance.

 > My alternative doesn't do those jumps, and i think overall matches
 > more closely what an untrained mind [...] would expect.

I think that's probably the worst possible criterion for systems
design.  "Principle of Least Astonishment", sure, but at some point
you want your systems to have some power.  In theory any 3rd grader
could fly a plane with a Wii handset, but maybe it's a better idea to
employ a trained pilot.

 > > But C3/super assumes nothing of the kind.
 > 
 > At first i was gonna answer that it of course does make this
 > assumption, but I think we aren't exactly talking about the same
 > thing. 
 > I was saying that the assumption that it can make sense to order
 > class inheritance trees

C3/super doesn't *assume* it makes sense.  It proposes it, and then
demonstrates that it satisfies the useful and intuitive properties of
local precedence ordering and monotonicity.  Experience shows it
*obviously* *does* make sense in many cases, in particular with single
inheritance.  But there are also many cases where it makes sense with
multiple inheritance.

 > which it turns out can't solve all scenarios. I think this proves
 > that this assumption was wrong.

But the assumption that something needs to solve all scenarios to be
useful and usable is *your* assumption, which is clearly *wrong*.

 > So overall, i think we agree on the matter of fact of today's C3
 > behavior, and overall, i think we agree that C3 is an incomplete
 > solution?

Yes.  Who cares?

 > The solution i propose would be able to cover those cases C3
 > doesn't. Because it wasn't build around the idea of ordering.

Sure, but it gives up on many useful cases of declarative composition,
basically limiting it to sets of mixins with disjoint attribute sets.
And in any case, super() also covers 

[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Joseph Martinot-Lagarde
@Michael: As the previous author I fully support this proposal! ;) Thank you 
for the revival. For reference, since you linked one of the answer of the 
original thread, this is my original proposal: 
https://mail.python.org/pipermail/python-ideas/2016-April/039836.html

Both suggested implementations are very interesting. If I'm not wrong they have 
exactly the same behavior (except for __dict__).

Performance-wise with a quick test I get the following results:

t = (1, 2)
print("sizeof", sys.getsizeof(t))  # 56
print("sizeof type", sys.getsizeof(type(t)))  # 408
print(timeit.timeit("(1, 2)"))  # ~0.01

nt = namedtuple("nt", ["x", "y"])
print("sizeof", sys.getsizeof(nt(1, 2)))  # 56
print("sizeof type", sys.getsizeof(type(nt(1, 2  # 896
print(timeit.timeit("nt(1, 2)", setup="from __main__ import nt"))  # ~0.2

pt = atuple(x=1, y=2)
print("sizeof", sys.getsizeof(pt))  # 56
print("sizeof type", sys.getsizeof(type(pt)))  # 896
print(timeit.timeit("atuple(x=12, y=16)", setup="from __main__ import atuple")) 
 # ~0.8

point = TupleWithNames(x=1, y=2)
print("sizeof", sys.getsizeof(point))  # 64
print("sizeof type", sys.getsizeof(type(point)))  # 1064
print(timeit.timeit("TupleWithNames(x=12, y=16)", setup="from __main__ import 
TupleWithNames"))  # ~0.8

The timing performance of both solutions is roughly the same given the 
measurament variation, but way slower than tuple an namedtuple.
TupleWithNames is a bit more memory hungry than atuple and namedtuple, but 
there is only one type so if I understand correctly it would be a win for 
multiple instances.
Maybe there is room for optimisation in both cases ?
___
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/YKTIWCHLNUONTVCXU3C26CJ5VTB6L2OH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Joao S. O. Bueno
On Fri, Mar 25, 2022 at 12:17 AM Brendan Barnwell 
wrote:

> On 2022-03-24 10:43, Andrew Svetlov wrote:
> > The proposal doesn't work well with type hints: atuple(a=1, b=2) and
> > atuple(a="a", b="b") generates the same type.
>
> I'm neither here nor there on the original proposal, but I just
> want to
> push back against this reasoning.  Type hints are an entirely optional
> feature of Python which do not affect the runtime behavior of Python
> code in any way (except insofar as other code explicitly reads the
> annotations), and this has been explicitly reiterated multiple times
> (e.g., in PEPs).  In my view, how something interacts with typing has no
> relevance in evaluating a proposal such as this.  To allow typing
> considerations to constrain Python's future development in any way
> whatsoever is to slide down the slippery slope which was explicitly
> disavowed in PEP 484, namely a gradual move towards a de facto
> "requirement" for static typing.  I would most heartily prefer to avoid
> that.
>
> strong +1


> --
> Brendan Barnwell
> "Do not follow where the path may lead.  Go, instead, where there is no
> path, and leave a trail."
> --author unknown
> ___
> 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/L67XX3TUEOFNLL4EJ56SX4UQAAV3TOU5/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/5TFHEWOGACIWV5N5CGI64UAELCXVUIUQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Ricky Teachey
I think I'd often reach for an optimized version of something like this
over SimpleNamespace or even a Dataclass if it existed.

On Tue, Mar 29, 2022, 2:04 AM Christopher Barker 
wrote:

> Finally got around to fleshing out my idea here.
>
> My thought was to make an anonymous names tuple not as a new anonymous
> class, but simply as an instance with specific field names. So all of these
> would the the same class, but they would also be lightweight, and all
> subclasses of tuple -- from a typing perspective, it's just be a tuple -
> and could be used anywhere a tuple could.
>
> Here's a quick prototype I came up with:
>
> class TupleWithNames(tuple):
> def __new__(cls, **fields):
> self = tuple.__new__(cls, fields.values())
> for name, val in fields.items():
> self.__dict__[name] = val
> return self
>
> def __setattr__(self, attr, val):
> raise AttributeError("Can't set attributes on TupleWithNames")
>
> def __repr__(self):
> return f"TupleWithNames({', '.join(f'{k}={v}' for k, v in
> self.__dict__.items())})"
> In [172]: point = TupleWithNames(x=5, y=10)
>
> In [173]: point
> Out[173]: TupleWithNames(x=5, y=10)
>
> In [174]: point.x
> Out[174]: 5
>
> In [175]: point.y
> Out[175]: 10
>
> In [176]: point.x = 2
> ---
> AttributeErrorTraceback (most recent call last)
>  in 
> > 1 point.x = 2
>
> ~/PythonStuff/tuplewithnames/tuplewithnames.py in __setattr__(self, attr,
> val)
>  11
>  12 def __setattr__(self, attr, val):
> ---> 13 raise AttributeError("Can't set attributes on
> TupleWithNames")
>  14
>  15 def __repr__(self):
>
> AttributeError: Can't set attributes on TupleWithNames
>
> In [177]: point.z = 3
> ---
> AttributeErrorTraceback (most recent call last)
>  in 
> > 1 point.z = 3
>
> ~/PythonStuff/tuplewithnames/tuplewithnames.py in __setattr__(self, attr,
> val)
>  11
>  12 def __setattr__(self, attr, val):
> ---> 13 raise AttributeError("Can't set attributes on
> TupleWithNames")
>  14
>  15 def __repr__(self):
>
> AttributeError: Can't set attributes on TupleWithNames
>
> In [178]: point[0]
> Out[178]: 5
>
> In [179]: point[1]
> Out[179]: 10
>
> In [180]: point[1] = 3
> ---
> TypeError Traceback (most recent call last)
>  in 
> > 1 point[1] = 3
>
> TypeError: 'TupleWithNames' object does not support item assignment
>
> So it's a (subclass of) tuple -- you can access the entries by name, you
> can't change them.
>
> It's truly immutable, 'cause the __dict __ is there to mess with, but that
> (I think) could be fixed if it were implemented in C.
>
> This really simple version hashes as the tuple -- so it's the same as a
> tuple with the same values, or a TupleWithNames with the same values, and
> any arbitrary names.
>
> Which I think is OK -- the idea here is that it IS just like a tuple
> except you can use the field names to access items for readability. But you
> could customize the hash, too if you wanted.
>
> Anyway -- that's in idea -- details to be fleshed out if anyone wanted to
> pursue this.
>
> -CHB
>
>
>
>
> On Sat, Mar 26, 2022 at 1:49 PM Christopher Barker 
> wrote:
>
>>
>> If I wanted to submit this as a pep (or even just submit this for a
>>> potential sponsorship), is the best way to go about it to work directly in
>>> a clone of the c/python repo, or to write a standalone library first and
>>> then after preliminary approval, add it to c/python?
>>
>>
>> You don’t need an implementation to write a PEP, and certainly not to get
>> a sponsor.
>>
>> That being said, a prototype can be helpful to work out the issues.
>>
>> You could go either way, but if it can be stand-alone, that’s easier,
>> especially for others to try it out.
>>
>> -CHB
>>
>>
>>> ___
>>> 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/Q6JTO37I42OKOAIJVBD63UL5QO3KEYLI/
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>> --
>> Christopher Barker, PhD (Chris)
>>
>> Python Language Consulting
>>   - Teaching
>>   - Scientific Software Development
>>   - Desktop GUI and Web Development
>>   - wxPython, numpy, scipy, Cython
>>
>
>
> --
> Christopher Barker, PhD (Chris)
>
> Python Language Consulting
>   - Teaching
>   - Scientific Software Development
>   - Desktop GUI and Web Development
>   - wxPython, numpy, scipy, Cython
> ___
> Python-ideas 

[Python-ideas] Re: mro and super don't feel so pythonic

2022-03-29 Thread Chris Angelico
On Tue, 29 Mar 2022 at 21:34, Steven D'Aprano  wrote:
>
> On Tue, Mar 29, 2022 at 06:23:06AM +1100, Chris Angelico wrote:
>
> > If I'm reading this correctly, you're defining a "conflict" as finding
> > two implementations of the same-named method in independent subtrees
> > of inheritance - that is, when you say "class Pizza(Crust, Topping):",
> > you're treating Crust and Topping as completely independent, and if
> > they both define an add_cheese method, that's a conflict.
>
> You've never had pizza with cheesy crust *and* cheese as a topping?

That's exactly my point: I don't see this as a conflict. I *like* my
pizza to have all the cheeses!

> > That's not inheritance. That's composition.
>
> I wouldn't call it composition unless it was implemented using
> composition instead of inheritance.
>
> I would call it a *subset* of inheritance.

Hmm, my point is that, if it's considered a conflict, then this isn't
really acting as inheritance. If it's inheritance, then each method is
acting on *the pizza*, but if it's composition, then some methods are
acting on the pizza's crust, and others are acting on the pizza's
toppings.

Ultimately, the difference between composition and inheritance is one
of design, and there are no fundamentally wrong decisions, just
decisions where you might not like the consequences.

But this is why I keep asking for non-toy examples, as it's extremely
hard to discuss design matters when all we have is "class C(A, B):" to
go on.

> That doesn't mean that cooperative MI doesn't have problems. Other
> languages forbid MI altogether because of those problems, or only allow
> it in a severely restricted version, or use a more primitive form of
> super. MI as defined by Python is perhaps the most powerful, but also
> the most potentially complicated, complex, convoluted and confusing.

Agreed, all forms of MI have their problems. Python, by its nature, is
guaranteed to create diamond inheritance with any form of MI (in
contrast, C++ can have MI where two subbranches never intersect, which
has quite different consequences); of all the ways of coping with the
effects of diamond inheritance, the two I've found most useful in
practice are Python's super ("go to the next one, not always up the
hierarchy") and a broad idea of calling every parent (effective, but
needs quite different concepts of cooperation - works well for init
methods though).

The term "cooperative" shouldn't put people off. I've almost never
seen any form of object orientation in which it isn't at least
somewhat cooperative. Some are more loosely coupled than others (IBM's
SOM was an amazingly good system that allowed inheritance from other
people's code, but required a complex build system), but you still
have to follow protocol to make sure your class plays nicely with
others. Most of the time, MI hierarchies are tightly coupled, since
it's extremely difficult to negotiate anything otherwise.

And honestly, I'm fine with that.

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/JESQPVJMPO74VRKIFQWKROIK2LIJJC2W/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: mro and super don't feel so pythonic

2022-03-29 Thread Steven D'Aprano
On Tue, Mar 29, 2022 at 06:23:06AM +1100, Chris Angelico wrote:

> If I'm reading this correctly, you're defining a "conflict" as finding
> two implementations of the same-named method in independent subtrees
> of inheritance - that is, when you say "class Pizza(Crust, Topping):",
> you're treating Crust and Topping as completely independent, and if
> they both define an add_cheese method, that's a conflict.

You've never had pizza with cheesy crust *and* cheese as a topping?

 
> That's not inheritance. That's composition.

I wouldn't call it composition unless it was implemented using 
composition instead of inheritance.

I would call it a *subset* of inheritance.

Artima is back up, so people interested in this topic **REALLY** should 
read what Michele Simionato has to say about it.

I'm not going to apologise for dumping so many links here, I think that 
Michele is really onto something: OOP with inheritance is an important 
technique to use, but it is also widely over-sold as the solution to 
maintainability in large software projects and frameworks, especially 
when you move from single to multiple inheritance.

Unfortunately, MI is just as likely to *hurt* maintainability as to help 
it, hence the move to composition and generics, or more restrictive 
forms of inheritance such as traits https://pypi.org/project/strait/

Things to know about Python super:

Part 1 https://www.artima.com/weblogs/viewpost.jsp?thread=236275
Part 2 https://www.artima.com/weblogs/viewpost.jsp?thread=236278
Part 3 https://www.artima.com/weblogs/viewpost.jsp?thread=237121

Mixins considered harmful:

Part 1 https://www.artima.com/weblogs/viewpost.jsp?thread=246341
Part 2 https://www.artima.com/weblogs/viewpost.jsp?thread=246483
Part 3 https://www.artima.com/weblogs/viewpost.jsp?thread=254367
Part 4 https://www.artima.com/weblogs/viewpost.jsp?thread=254507

Setting Multiple Inheritance Straight:

https://www.artima.com/weblogs/viewpost.jsp?thread=246488

The wonders of cooperative inheritance, or using super in Python 3

https://www.artima.com/weblogs/viewpost.jsp?thread=281127

Multiple inheritance in Python works the way it does because it is 
modelling cooperative MI and the MRO and super are the Right Way to 
handle cooperative MI.

That doesn't mean that cooperative MI doesn't have problems. Other 
languages forbid MI altogether because of those problems, or only allow 
it in a severely restricted version, or use a more primitive form of 
super. MI as defined by Python is perhaps the most powerful, but also 
the most potentially complicated, complex, convoluted and confusing.


-- 
Steve
___
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/6M7XPNKQF5IPWAK4XPJIGTKLTZBDYGK4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread Serhiy Storchaka

28.03.22 15:13, StrikerOmega пише:

And I want to grab some kind of value from it.


There is a powerful tool designed for solving such problems. Is is 
called regular expressions.



sample.grab(start="fruit:", end="\n")
 >> 'apple'


re.search(r'fruit:(.*?)\n', sample)[1]


sample.grab(start="tree:[", end="]")
 >> 'Apple tree'


re.search(r'tree:\[(.*?)\]', sample)[1]



sample.grab(start="quantity:{", end="}", list_out=True)
 >> [5, 3]


list(re.findall(r'quantity:\{(.*?)\}', sample))

___
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/X5EOH4P6KOWIJ3CSPWY76H6BHRDU42P5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread Paul Bryan
I wonder if applying regular expressions would sufficiently address
your use case.

On Mon, 2022-03-28 at 14:13 +0200, StrikerOmega wrote:
> Hello everyone,
> 
> When I am coding in Python I often encounter situations where I have
> a string like this one.
> 
> sample="""
> fruit:apple
> tree:[Apple tree]
> quantity:{5}
> quantity:{3}
> """
> 
> And I want to grab some kind of value from it. 
> 
> So let me introduce you to the grab function. This is the definition:
> 
> def grab(start, end, list_out=False):
> 
> Now, if you want to get the fruit from the sample string you can just
> "grab" it as follows:
> 
> sample.grab(start="fruit:", end="\n")
> >> 'apple'
> 
> You can also "grab" values enclosed in brackets or in any kind of
> character and It works as you would expect.
> 
> sample.grab(start="tree:[", end="]")
> >> 'Apple tree'
> 
> The optional argument "list_out" makes the function return a list of
> values, for cases where there are several of them to grab.
> 
> sample.grab(start="quantity:{", end="}", list_out=True)
> >> [5, 3]
> 
> The "grab" function will return only the first occurrence if
> "list_out" is omitted or passed as False.
> 
> sample.grab(start="quantity:{", end="}")
> >> 5
> 
> sample.grab(start="quantity:{", end="}", list_out=False)
> >> 5
> 
> As you can see, it is incredibly useful for extracting substrings
> from a larger and more complex string and can change the way we parse
> strings for the better. 
> 
> For example, it could simplify the way we parse the fields of HTTP
> headers. It also has many applications for the parsing of
> configuration files and the construction of strings for SQL queries
> and bash commands among others.
> 
> I have implemented this function locally to use it for my personal
> projects and It has proven to be really useful in practice, so I hope
> you find it useful as well and consider adding it as a class method
> for strings in Python.
> 
> Julio Cabria
> Engineering student 
> Autonomous University of Madrid
> ___
> 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/NV7G6W4RHTMMVIUDHQAATSVYFRIV6G7Z/
> Code of Conduct: http://python.org/psf/codeofconduct/

___
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/WXHJEJBB5BGI7HJJ63NPZDAV7QX6XF4G/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread Chris Angelico
On Tue, 29 Mar 2022 at 18:13, StrikerOmega
 wrote:
>
> The grab function would find the index of the first occurrence of the "start" 
> string in the parent string and then the next occurrence of the "end" string 
> starting from that index and return the substring between those.
>

This sounds like a really good job for preparsing. Take your string,
parse it according to your rules, and build a list or dict of the
cooked results. Then you can look up in that very easily and
efficiently. Going back to the string every time tends to be
inefficient, but a single pass that gives you a convenient lookup
table is both easier to work with and easier to execute. In your
example:

sample="""
fruit:apple
tree:[Apple tree]
quantity:{5}
quantity:{3}
"""

I'd start by splitting it into lines, then for each line, partitioning
it on the colon, thus giving you a keyword and a value. (I'm not sure
what it means to have quantity 5 and quantity 3, but I'm sure you'd
define that in some way - maybe first one wins, or last one wins, or
build a list of all the values, whatever makes sense.) You could end
up with something like:

{
"fruit": "apple",
"tree": "Apple tree",
"quantity": ...
}

depending on how you resolve the conflict.

Python is an excellent language for text processing; you have a wide
variety of pretty cool tools available.

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/OLJRRLAGOKY74SPWEK3B47QKDUMHGEZI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: A string function idea

2022-03-29 Thread StrikerOmega
The grab function would find the index of the first occurrence of the
"start" string in the parent string and then the next occurrence of the
"end" string starting from that index and return the substring between
those.

So in the example:

sample = "sqrt(sin(x) + cos(y))"

The grab function would return:

sample.grab(start="sqrt(", end=")")
>> "sin(x"

This shows that "grab" is only useful given that you specify the "start"
and "end" delimiters unambiguously. It depends on that to produce the
correct output.

Julio Cabria
Engineering student
Autonomous University of Madrid

On Tue, Mar 29, 2022, Steven D'Aprano  wrote:
> On Mon, Mar 28, 2022 at 02:13:32PM +0200, StrikerOmega wrote:
>
>> You can also "grab" values enclosed in brackets or in any kind of
character
>> and It works as you would expect.
>>
>> sample.grab(start="tree:[", end="]")
>> >> 'Apple tree'
>
> If we have
>
> sample = "sqrt(sin(x) + cos(y))"
>
> and sample.grab(start="sqrt(", end=")") which of these does it return?
>
> 1. "sin(x"
>
> 2. "sin(x) + cos(y)"
>
>
> --
> Steve
>
___
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/X7VPVCTEJ5PYGPMTNIHIG3FI73WPHIQ4/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Allow `return yield from`

2022-03-29 Thread Patrick Reader


On 29/03/2022 03:18, Michael Smith wrote:
On Mon, Mar 28, 2022 at 16:06 Patrick Reader  
wrote:


I would like to be able to use a `yield from` expression in a
`return`
statement without parentheses, as a small quality of life tweak, i.e.:

return yield from gen

instead of

return (yield from gen)


What does this do? `return (yield …)` is the expression form, so this 
generator is really a coroutine, but unless I missed it your gist 
doesn't have a `.send` or `.throw` and you aren't using the value of 
StopIteration.


So I think your idea is really to create a shorthand for

```
yield from gen
return
```

Is that what you mean? or if I misunderstand please explain further.



In my example, the return value (StopIteration value) of the generator 
is the function which will handle the next character in the lexer. The 
value of a `yield from` expression is the StopIteration value.
___
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/XYGZJXWP3ZTYJOILNXW6M2KU5UTUXQIO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: mro and super don't feel so pythonic

2022-03-29 Thread Robert Collins
On Sat, 26 Mar 2022 at 18:01, malmiteria  wrote:

> Hi,
>
> Before anything, i made a github repository about this topic here :
> https://github.com/malmiteria/super-alternative-to-super
>
> The core of what i wanna discuss here is that i don't think mro and super
> (mainly because it relies on mro) are very pythonic. Mainly that some
> behaviors of the mro are too implicit, and are silencing what really should
> be errors.
>

Coming in to the start late, sorry. But having read a lot of the discussion
in this thread I think the disconnect is really back in your first post:
why don't let programmers solve it themselves? We do. super() is optional.

In languages where there are multiple instances of a parent type in a
diamond situation, e.g. C, every parent instance has to be called every
time.

In languages where it is possible to have just one instance of a parent
type, like Python (always), or C++ (with virtual), calling base methods
multiple times will occur (e.g.
https://stackoverflow.com/questions/55829798/c-diamond-problem-how-to-call-base-method-only-once
), so developers need to come up with ways to avoid it (e.g. not calling
parent methods from some specific methods).

In Python we picked a particular way of projecting the diamond inheritance
pattern that has some very useful properties, and then allowed programmers
to use that, or not, as they choose.

The useful properties being that parents are always ordered before *all*
children, and that the order is deterministic; super() then just walks back
up the ordered list to make calls.

The contrived examples in your git repo suggest to me a misunderstanding of
diamond inheritance (in general) - if you want to define a new protocol,
you need an abstract base:

```
class Family:
def method(self): pass
class C(Family):
def method(self):
print('C')
super().method()
class B(Family):
def method(self):
print('B')
super().method() # HERE
class A(B,C):
def method(self):
print('A')
super().method()

A().method()
print("--")
B().method()
print("--")
C().method()
```

otherwise, super() is inappropriate and you should just call B.method(self)
from A.method, etc.

-Rob
___
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/DWWDYRH3U4FHSPKWX2ZTL5CFCVFDK456/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Anonymous namedtuples, revisited

2022-03-29 Thread Christopher Barker
Finally got around to fleshing out my idea here.

My thought was to make an anonymous names tuple not as a new anonymous
class, but simply as an instance with specific field names. So all of these
would the the same class, but they would also be lightweight, and all
subclasses of tuple -- from a typing perspective, it's just be a tuple -
and could be used anywhere a tuple could.

Here's a quick prototype I came up with:

class TupleWithNames(tuple):
def __new__(cls, **fields):
self = tuple.__new__(cls, fields.values())
for name, val in fields.items():
self.__dict__[name] = val
return self

def __setattr__(self, attr, val):
raise AttributeError("Can't set attributes on TupleWithNames")

def __repr__(self):
return f"TupleWithNames({', '.join(f'{k}={v}' for k, v in
self.__dict__.items())})"
In [172]: point = TupleWithNames(x=5, y=10)

In [173]: point
Out[173]: TupleWithNames(x=5, y=10)

In [174]: point.x
Out[174]: 5

In [175]: point.y
Out[175]: 10

In [176]: point.x = 2
---
AttributeErrorTraceback (most recent call last)
 in 
> 1 point.x = 2

~/PythonStuff/tuplewithnames/tuplewithnames.py in __setattr__(self, attr,
val)
 11
 12 def __setattr__(self, attr, val):
---> 13 raise AttributeError("Can't set attributes on
TupleWithNames")
 14
 15 def __repr__(self):

AttributeError: Can't set attributes on TupleWithNames

In [177]: point.z = 3
---
AttributeErrorTraceback (most recent call last)
 in 
> 1 point.z = 3

~/PythonStuff/tuplewithnames/tuplewithnames.py in __setattr__(self, attr,
val)
 11
 12 def __setattr__(self, attr, val):
---> 13 raise AttributeError("Can't set attributes on
TupleWithNames")
 14
 15 def __repr__(self):

AttributeError: Can't set attributes on TupleWithNames

In [178]: point[0]
Out[178]: 5

In [179]: point[1]
Out[179]: 10

In [180]: point[1] = 3
---
TypeError Traceback (most recent call last)
 in 
> 1 point[1] = 3

TypeError: 'TupleWithNames' object does not support item assignment

So it's a (subclass of) tuple -- you can access the entries by name, you
can't change them.

It's truly immutable, 'cause the __dict __ is there to mess with, but that
(I think) could be fixed if it were implemented in C.

This really simple version hashes as the tuple -- so it's the same as a
tuple with the same values, or a TupleWithNames with the same values, and
any arbitrary names.

Which I think is OK -- the idea here is that it IS just like a tuple except
you can use the field names to access items for readability. But you could
customize the hash, too if you wanted.

Anyway -- that's in idea -- details to be fleshed out if anyone wanted to
pursue this.

-CHB




On Sat, Mar 26, 2022 at 1:49 PM Christopher Barker 
wrote:

>
> If I wanted to submit this as a pep (or even just submit this for a
>> potential sponsorship), is the best way to go about it to work directly in
>> a clone of the c/python repo, or to write a standalone library first and
>> then after preliminary approval, add it to c/python?
>
>
> You don’t need an implementation to write a PEP, and certainly not to get
> a sponsor.
>
> That being said, a prototype can be helpful to work out the issues.
>
> You could go either way, but if it can be stand-alone, that’s easier,
> especially for others to try it out.
>
> -CHB
>
>
>> ___
>> 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/Q6JTO37I42OKOAIJVBD63UL5QO3KEYLI/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
> --
> Christopher Barker, PhD (Chris)
>
> Python Language Consulting
>   - Teaching
>   - Scientific Software Development
>   - Desktop GUI and Web Development
>   - wxPython, numpy, scipy, Cython
>


-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/I6VTNHH4OTBLF65HDBW6NFXAAW2C6PGX/
Code of Conduct: http://python.org/psf/codeofconduct/