[Python-ideas] Re: Mapping unpacking assignment

2022-02-12 Thread Joao S. O. Bueno
I'd be in favor of a nice syntax for named mapping unpacking.

But while we are at discussion - I'd point out it is "possible" (not easy)
with
current day syntax, by abusing the command "import" -
One can set appropriate import hooks that would enable
either for the current module, or maybe, in a context ("with") block
the use of import targeting a variable - so, the syntax

from mymap import key1, key2

can work.
Downside: it will be much slower than an assignment.

I have something similar working, but it is currently based
on monkey patching builtins.__import__ - upgrading it to properly
using the import machinery is on the roadmap.


On Fri, Feb 11, 2022 at 8:25 AM Matsuoka Takuo 
wrote:

> On Fri, 11 Feb 2022 at 04:02, Christopher Barker 
> wrote:
> >
> > Just one note:
> >
> > On Thu, Feb 10, 2022 at 6:56 AM Chris Angelico  wrote:
> >>
> >> > (2) For the form of the assignment target, I think an analogy with the
> >> > reception of function arguments could also be considered.
> >
> >
> > I think so -- maybe only because it's new, but folks are certainly far
> more familiar with **kwargs than pattern matching.
>
> Structural pattern matching does a more general assignment than
> happens at passing of function arguments.  So the latter is simpler,
> but is sufficient (at least conceptually) for the form of assignment
> considered here.  However, both of them may lead to distinct pieces of
> syntax, both of which might possibly be useful.
>
> Best regards,
> Takuo Matsuoka
> ___
> 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/N6MXW3HNFJBBUY3BCJBQTGA6WGEQGDMI/
> 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/UC57YSWO7KLAXADXE5UCL3ILP4W7ZNMO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Mapping unpacking assignment

2022-02-11 Thread Matsuoka Takuo
On Fri, 11 Feb 2022 at 04:02, Christopher Barker  wrote:
>
> Just one note:
>
> On Thu, Feb 10, 2022 at 6:56 AM Chris Angelico  wrote:
>>
>> > (2) For the form of the assignment target, I think an analogy with the
>> > reception of function arguments could also be considered.
>
>
> I think so -- maybe only because it's new, but folks are certainly far more 
> familiar with **kwargs than pattern matching.

Structural pattern matching does a more general assignment than
happens at passing of function arguments.  So the latter is simpler,
but is sufficient (at least conceptually) for the form of assignment
considered here.  However, both of them may lead to distinct pieces of
syntax, both of which might possibly be useful.

Best regards,
Takuo Matsuoka
___
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/N6MXW3HNFJBBUY3BCJBQTGA6WGEQGDMI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Mapping unpacking assignment

2022-02-11 Thread Matsuoka Takuo
I'm sorry for the inaccuracy, and thank you for the corrections!

On Fri, 11 Feb 2022 at 01:56, Chris Angelico  wrote:
>
> On Fri, 11 Feb 2022 at 00:33, Matsuoka Takuo  wrote:
> >
..
>
> But the crucial thing is to figure out the syntax. Without good
> syntax, this is not of interest.
>
> I'm personally inclined towards marking the assignment target in some
> way, since that would extrapolate conveniently to all other assignment
> types (eg "for match {MATCH_EXPR} in iterable:"), but I don't like the
> specific placeholder example I've used here.

Having special notation for the assignment target sounds like a good
way to me.

Best regards,
Takuo Matsuoka
___
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/3E6MKKC3ZXYR36VRPUMD2PJT5KNLIGST/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Mapping unpacking assignment

2022-02-10 Thread Christopher Barker
Just one note:

On Thu, Feb 10, 2022 at 6:56 AM Chris Angelico  wrote:

> > (2) For the form of the assignment target, I think an analogy with the
> > reception of function arguments could also be considered.


I think so -- maybe only because it's new, but folks are certainly far more
familiar with **kwargs than pattern matching.


> > For an assignment without **rest, the
> > assignment source can just be sliced beforehand.
>
> Yeah, that's something that could be considered, but it's worth noting
> that PEP 622 says that match syntax doesn't demand {**_} for mapping
> patterns.
>


> Extra keys in the subject are ignored even if **rest is not present.
> This is different from sequence pattern, where extra items will cause
> a match to fail. But mappings are actually different from sequences:
> they have natural structural sub-typing behavior, i.e., passing a
> dictionary with extra keys somewhere will likely just work.


Except in unpacking in a function call -- which I this "feels" more like to
me.

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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-10 Thread Chris Angelico
On Fri, 11 Feb 2022 at 00:33, Matsuoka Takuo  wrote:
>
> On Mon, 7 Feb 2022 at 16:43, Chris Angelico  wrote:
> >
> > There have been thoughts thrown around in the past of having a "match
> > assignment" concept. The OP is far from the first to notice the
> > parallel. Maybe that's what we should be looking at - but the biggest
> > question is syntax. What should it look like?
> >
> > # A different type of assignment operator?
> > {codec_type, width, height} $= info["streams"]
> > # A special assignment target?
> > match {codec_type, width, height} = info["streams"]
> > # A special assignment source?
> > {codec_type, width, height = match info["streams"]
> > # Something else?
>
> A question and two thoughts...
>
> (1) Has there been any way to use the operator "=" in which the right
> hand side was not just an expression specifying an object?

I think not, with the caveat that "a = b = 1" has multiple assignment
targets, so the "right hand side" has to be interpreted as the 1 and
not "b = 1".

The "special assignment source" wouldn't really work as an object. It
would still, in effect, be a syntactic structure (you wouldn't be able
to call "f(match x)", for instance - it's not an expression), a type
of assignment that isn't simple object referencing.

> (2) For the form of the assignment target, I think an analogy with the
> reception of function arguments could also be considered.  Note the
> intended assignment could be done by
>
> locals().update(
> (lambda codec_type, width, height, **rest: locals())(
> **info["streams"]
> )
> )
>
> if none of the variables were not local.

You can't actually update locals(), unless it happens to be an alias
for globals(), so that doesn't technically work - but it's a good way
to say "kinda like this".

> (3) If some keys in the mapping object may not appear on the left hand
> side, then demanding **rest part would be consistent with the case of
> iterable unpacking, structural pattern matching, as well as the case
> for function arguments.  For an assignment without **rest, the
> assignment source can just be sliced beforehand.

Yeah, that's something that could be considered, but it's worth noting
that PEP 622 says that match syntax doesn't demand {**_} for mapping
patterns. (You can use **rest to capture it, but you don't have to.)
Personally, I think the argument in the PEP would apply here too:

"""
Extra keys in the subject are ignored even if **rest is not present.
This is different from sequence pattern, where extra items will cause
a match to fail. But mappings are actually different from sequences:
they have natural structural sub-typing behavior, i.e., passing a
dictionary with extra keys somewhere will likely just work.
"""

In any case, it's probably simplest to look at a "match assignment"
syntax, and then define that it is absolutely equivalent to the
equivalent match block:

match TARGET:
case MATCH_EXPR: pass
case _: raise ValueError

# <=>

match MATCH_EXPR = TARGET

But the crucial thing is to figure out the syntax. Without good
syntax, this is not of interest.

I'm personally inclined towards marking the assignment target in some
way, since that would extrapolate conveniently to all other assignment
types (eg "for match {MATCH_EXPR} in iterable:"), but I don't like the
specific placeholder example I've used here.

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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-10 Thread Matsuoka Takuo
On Mon, 7 Feb 2022 at 16:43, Chris Angelico  wrote:
>
> There have been thoughts thrown around in the past of having a "match
> assignment" concept. The OP is far from the first to notice the
> parallel. Maybe that's what we should be looking at - but the biggest
> question is syntax. What should it look like?
>
> # A different type of assignment operator?
> {codec_type, width, height} $= info["streams"]
> # A special assignment target?
> match {codec_type, width, height} = info["streams"]
> # A special assignment source?
> {codec_type, width, height = match info["streams"]
> # Something else?

A question and two thoughts...

(1) Has there been any way to use the operator "=" in which the right
hand side was not just an expression specifying an object?

(2) For the form of the assignment target, I think an analogy with the
reception of function arguments could also be considered.  Note the
intended assignment could be done by

locals().update(
(lambda codec_type, width, height, **rest: locals())(
**info["streams"]
)
)

if none of the variables were not local.

(3) If some keys in the mapping object may not appear on the left hand
side, then demanding **rest part would be consistent with the case of
iterable unpacking, structural pattern matching, as well as the case
for function arguments.  For an assignment without **rest, the
assignment source can just be sliced beforehand.

Best regards,
Takuo Matsuoka
___
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/JORGO6KH22A5YGFVEZK4Z74MGK2GADYS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Mapping unpacking assignment

2022-02-07 Thread Eric V. Smith

> On Feb 7, 2022, at 1:55 AM, Chris Angelico  wrote:
> 
…
> def spam():
>bird = "Norwegian Blue"
>volts = 4e6
>return "{volts}V insufficient to voom {bird}".format(**locals())

This is completely off topic, but: the better way to do this is with 
.format_map(locals()).

This public service announcement is part of my goal to increase knowledge of 
format_map(). 

Eric 


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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-07 Thread Chris Angelico
On Tue, 8 Feb 2022 at 01:27, Eric V. Smith  wrote:
>
>
> > On Feb 7, 2022, at 1:55 AM, Chris Angelico  wrote:
> >
> …
> > def spam():
> >bird = "Norwegian Blue"
> >volts = 4e6
> >return "{volts}V insufficient to voom {bird}".format(**locals())
>
> This is completely off topic, but: the better way to do this is with 
> .format_map(locals()).
>
> This public service announcement is part of my goal to increase knowledge of 
> format_map().
>

Fair point. Still, my original statement was that it is even better to do it as:

return f"{volts}V insufficient to voom {bird}"

which treats it fully as code. But if the information wasn't from
locals and was from some other dict, then yes, I fully accept the
correction, format_map would have been the correct choice.

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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread Chris Angelico
On Mon, 7 Feb 2022 at 17:35, Christopher Barker  wrote:
> After I posted, I realized that dataclasses are probably not the simplest 
> solution -- but SimpleNamespace could be:
>
> In [9]: stream_info = {'codec_type': 'video',
>...:'width': 1024,
>...:'height': 768,
>...:}
>
> In [10]: stream = types.SimpleNamespace(**stream_info)
>
> In [11]: stream.codec_type
> Out[11]: 'video'
>
> In [12]: stream.height
> Out[12]: 768
>
> In [13]: stream.width
> Out[13]: 1024
>
> In any case, if you don't like how dataclasses or SimpleNamespace does it, 
> then write you own custom class / converter -- I don't see the need for it to 
> be a language feature.

This doesn't really buy much. (You say in your footnote that
stream.width is nicer than stream["width"], and you're absolutely
right, but it's still not as convenient as unpacking.) This is
particularly notable when you're unpacking something deep in the
structure, and you might have something like:

{width, height} =  info["streams"][0]["panel"][1] # hypothetical example

which means you either have to create a variable and then still repeat
that everywhere, or repeat the long part.

Honestly, neither dataclasses nor SimpleNamespace buy enough over
direct dict access (with some strategic variable assignments) to be
worth the hassle. Which basically means we're back at status quo: it's
easy to unpack rigid, inflexible structures, and hard to unpack named
ones that have room for augmentation. Which seems a little backwards.

>> I'm not sure what you mean here about code vs data. What is the
>> difference that you're drawing? Ultimately, I need to read a
>> particular data structure and find the interesting parts of it. It's
>> not about code. The only code is "iterate over info->streams, look at
>> the codec_type, width, height, perform arithmetic on videos".
>
>
> The distinction I'm trying to draw (and I did say it was a fuzzy one in 
> Python) is that data are things you can store in variables -- e.g. the keys 
> of a dict can be hard coded (known at code-writing time) or stored in a 
> variable.
>
> Code is things like variable and attribute names that have to known at 
> code-writing time (baring metaprogramming techniques, get/setattr, etc).
>

I think I see what you mean, but yeah, it's a very very fuzzy
distinction. For instance, let's say it's not a JSON file, but
something in some other format (a Europa Universalis IV savefile,
perhaps). I could write a parser that steps byte-by-byte through the
file and builds a dict out of it; or I could reach for yacc and define
a full grammar, just like a programming language does. (Case in point:
I actually did design a recursive grammar for an EU4 savefile,
although not in Python, since Python doesn't have convenient grammar
tools available. This might change in the future, which would be very
convenient.)

This actually reminds me of some of the discussions regarding what
ended up becoming f-strings. You have the same "dict or variable?"
consideration, but the other way around:

def spam():
bird = "Norwegian Blue"
volts = 4e6
return "{volts}V insufficient to voom {bird}".format(**locals())

Python gives us some tools for switching viewpoints between "this is
data" and "this is code", and your parenthetical comment about
metaprogramming actually fits into that too (and believe you me, it
hurts when I'm stuck in a language without it!).

> In this case, we are looking to auto-extract variable from a dict -- you 
> can't even start to write that code unless you know what the keys in the dict 
> are -- if that's the case, then you know (at least part of) the schema, and 
> you can use dataclasses, etc, and get your code.
>

Yeah, but why write a dataclass and then write the code, instead of
just writing the code? There are exceptions, of course; if you're
parsing something that simply doesn't *have* all the information, and
you have to go "take four bytes, that's an integer called Volts, take
bytes until you get a \0, that's an ASCII string called Bird, take
four bytes, we don't know what they are", then it makes perfect sense
to make a dataclass (again, have done this); but when the file can be
parsed without any external references, I'd rather do that, and stay
generic.

> So: I say, keep your data in dicts, and if you want to load a code object 
> with that data, do it in a clearly defined way.
>

Exactly what the OP wanted, except instead of loading *a* code object,
loading *several* code objects at once, to avoid the repetition. :)

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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread Christopher Barker
On Sun, Feb 6, 2022 at 9:42 PM Chris Angelico  wrote:

> > As for dataclasses, this is what i mean by "code" vs "data" -- if you
> know when you are writing the code exactly what key (fields, etc) you
> expect , and you want to be able to work with that data model as code (e.g.
> attribute access, maybe some methods, then you do:
> >
> > In [10]: @dataclass
> > ...: class Stream:
> > ...: codec_type : str
> > ...: width: int
> > ...: height: int
> >
> > And if you have that data in a dict (say, from JSON, then you can
> extract it like this:
> >
> > In [11]: stream_info = {'codec_type': 'video',
> > ...:'width': 1024,
> > ...:'height': 768,
> > ...:}
> >
> > In [12]: stream = Stream(**stream_info)
> >
> > In [13]: stream
> > Out[13]: Stream(codec_type='video', width=1024, height=768)
> >
> > That only works if you dict is in exactly the right form, but that would
> be the case anyway.
>
> One very *very* important aspect of a huge number of JSON-based
> protocols is that they absolutely will not break if new elements are
> added. In other words, I look at the things I'm interested in, but
> those streams also have a ton of other information (frame rate,
> metadata, pixel format), which could get augmented at any time, and I
> should just happily ignore the parts I'm not looking for. Making that
> work with dataclasses (a) is even more boilerplate, and (b) would
> obscure the relationship between the dataclass and the JSON schema.
>

I believe some folks have asked for the ability for  **kwargs to be tacked
on to the dataclass generated __init__ -- I don't know if it will happen,
but that would address this use case.

Not sure what you mean by "obscure the relationship between the dataclass
and the JSON schema."

I guess you mean that the dataclass will then accept non-schema conforming
JSON, but if you don't want it to do that, then do allow that. For my part,
in an application that I'm doing all of of JSON -- data classes, I
explicitly add and "extra_data" field, so I can capture anything in the
JSON that doesn't have a "proper" place.

After I posted, I realized that dataclasses are probably not the simplest
solution -- but SimpleNamespace could be:

In [9]: stream_info = {'codec_type': 'video',
   ...:'width': 1024,
   ...:'height': 768,
   ...:}

In [10]: stream = types.SimpleNamespace(**stream_info)

In [11]: stream.codec_type
Out[11]: 'video'

In [12]: stream.height
Out[12]: 768

In [13]: stream.width
Out[13]: 1024

In any case, if you don't like how dataclasses or SimpleNamespace does it,
then write you own custom class / converter -- I don't see the need for it
to be a language feature.

I'm not sure what you mean here about code vs data. What is the
> difference that you're drawing? Ultimately, I need to read a
> particular data structure and find the interesting parts of it. It's
> not about code. The only code is "iterate over info->streams, look at
> the codec_type, width, height, perform arithmetic on videos".
>

The distinction I'm trying to draw (and I did say it was a fuzzy one in
Python) is that data are things you can store in variables -- e.g. the keys
of a dict can be hard coded (known at code-writing time) or stored in a
variable.

Code is things like variable and attribute names that have to known at
code-writing time (baring metaprogramming techniques, get/setattr, etc).

In this case, we are looking to auto-extract variable from a dict -- you
can't even start to write that code unless you know what the keys in the
dict are -- if that's the case, then you know (at least part of) the
schema, and you can use dataclasses, etc, and get your code.

I"ve worked with systems (the netcdf4 library for example, if you want an
obscure one :-) ) that auto translate essentially keys in a dict to object
attributes. it seems pretty nifty at first:

ds = Dataset("the_file.nc")
ds.sea_surface_temp.units

But it ends up just making things harder -- you need to poke into the file
to see what names will be there, it's actually harder to introspect (can't
just look at .keys() ) -- and things really go to heck if the keys in your
data don't follow Python variable naming rules:

In [14]: stream_info = {'codec-type': 'video',
...:'width': 1024,
...:'height': 768,
...:}

In [15]: stream = types.SimpleNamespace(**stream_info)

In [16]: stream.codec-type
---
AttributeErrorTraceback (most recent call last)
 in 
> 1 stream.codec-type

AttributeError: 'types.SimpleNamespace' object has no attribute 'codec'

In [17]: stream.codec_type
---
AttributeErrorTraceback (most recent call last)
 in 
> 1 stream.codec_type


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread Chris Angelico
On Mon, 7 Feb 2022 at 15:17, Christopher Barker  wrote:
> Using Chris's example:
>
>> for {codec_type, width, height} in info["streams"]:
>> if codec_type == "video":
>> ...
>> This would be extremely convenient, and it doesn't really work with 
>> dataclasses.
>
>
> First, how does this work now? This?
>
> for  stream in info["streams"]:
> if stream['codec_type'] == "video":
> 
>
> Is that so bad? as you have hard_coded codec_type, I suppose it's a bit more 
> kludgy, but if the codec_type was in a variable, it would be more convenient.
>

Yes, and it's not hugely terrible, which is why I'm not pushing hard
for this sort of unpacking. (To be honest, I don't use it much in JS
either.)

> As for dataclasses, this is what i mean by "code" vs "data" -- if you know 
> when you are writing the code exactly what key (fields, etc) you expect , and 
> you want to be able to work with that data model as code (e.g. attribute 
> access, maybe some methods, then you do:
>
>
> In [10]: @dataclass
> ...: class Stream:
> ...: codec_type : str
> ...: width: int
> ...: height: int
>
> And if you have that data in a dict (say, from JSON, then you can extract it 
> like this:
>
> In [11]: stream_info = {'codec_type': 'video',
> ...:'width': 1024,
> ...:'height': 768,
> ...:}
>
> In [12]: stream = Stream(**stream_info)
>
> In [13]: stream
> Out[13]: Stream(codec_type='video', width=1024, height=768)
>
> That only works if you dict is in exactly the right form, but that would be 
> the case anyway.

One very *very* important aspect of a huge number of JSON-based
protocols is that they absolutely will not break if new elements are
added. In other words, I look at the things I'm interested in, but
those streams also have a ton of other information (frame rate,
metadata, pixel format), which could get augmented at any time, and I
should just happily ignore the parts I'm not looking for. Making that
work with dataclasses (a) is even more boilerplate, and (b) would
obscure the relationship between the dataclass and the JSON schema.

I'm not sure what you mean here about code vs data. What is the
difference that you're drawing? Ultimately, I need to read a
particular data structure and find the interesting parts of it. It's
not about code. The only code is "iterate over info->streams, look at
the codec_type, width, height, perform arithmetic on videos".

> Granted, that's a lot of code for a quickscript, but if it's a quick script, 
> just work with the dict.
>

Which is exactly the OP's view. Work with the dict. But preferably,
make it easier to work with the dict.

> IN practice, it's not so simple when you have a more nested data structure, 
> but I don't think this proposal would help with that, and it's not hard to 
> build that on top of dataclasses either, see Pydantic, or attrs, or my own 
> half-baked flexi project:
>
> https://github.com/PythonCHB/flexi
>
> (note: half-baked because the public project is not well tested nor 
> documented, but I am using this very code in a pretty substantial system with 
> a very highly nested structure:
>
> https://adios.orr.noaa.gov
>
> (and the code: https://github.com/NOAA-ORR-ERD/adios_oil_database)
>

If your data structure is incredibly rigid, you can take advantage of
sequence unpacking, and it'll work really nicely:

for x, y, z in data["points_3d"]: ...

IMO it's not unreasonable to want the same kind of flexibility for
named data. The trouble is, it would end up quite complicated, which
inevitably means we're going to come back to match/case syntax.

There have been thoughts thrown around in the past of having a "match
assignment" concept. The OP is far from the first to notice the
parallel. Maybe that's what we should be looking at - but the biggest
question is syntax. What should it look like?

# A different type of assignment operator?
{codec_type, width, height} $= info["streams"]
# A special assignment target?
match {codec_type, width, height} = info["streams"]
# A special assignment source?
{codec_type, width, height = match info["streams"]
# Something else?

I'm not a fan of any of these, but maybe someone can figure out a
better way to write it. It's one of those things where, if it existed
in the language, I would certainly use it, but it's not something that
causes all that much pain.

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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread Bruce Leban
On Thu, Feb 3, 2022 at 11:53 AM Yurii Karabas <1998uri...@gmail.com> wrote:

>
> Proposed syntax:
>
> m = {"a": 1, "b": 2, "c": 3, "d": 4}
>
> {a, b} = m # a: 1, b: 2
> {a, b, **rest} = m # a: 1, b: 2, rest: {c: 3, d: 4}
>
> as equivalent to this from PEP 634:


> match m:
> case {"a": a, "b": b, **rest}:
> pass
> case _:
> raise ValueError


What I find particularly unsatisfying is that the left hand side syntax in
your proposal {a, b, **rest} is not at all like, the case syntax {"a": a,
"b": b, **rest} so that's twice as much syntax to learn.
*IF* this is really used often enough that it is worth adding to the
language it should be a variation of match, something like:

match m as  {"a": a, "b": b, **rest}

The match clause defaults to doing nothing if the value doesn't match but
that's less useful here (and harder to deal with since figuring out that a,
b, and rest are still unbound is clumsy, so I would agree that it should
raise ValueError if there's no match.

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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread Christopher Barker
TL;DR

I think Python's distinction between code (e.g. classes) and data (e.g.
dicts) is a good distinction to keep -- if you want code, define code, and
datcalasses make that very easy these days.

And now the detailed version:

On Sun, Feb 6, 2022 at 6:05 AM Chris Angelico  wrote:

> > This feature is far more useful in JS because JS objects double up as
> mappings -


Exactly. And because of this the behaviour is well defined. However, I
think that there's alway as issue with "data", e.g. mappings, and "code",
e.g. classes with attributes.

Given how dynamic Python is, it can be a fuzzy boundary, but I don't think
we should make it even fuzzier. (and it JS, there is no boundary at all).

Using Chris's example:

for {codec_type, width, height} in info["streams"]:
> if codec_type == "video":
> ...
> This would be extremely convenient, and it doesn't really work with
> dataclasses.
>

First, how does this work now? This?

for  stream in info["streams"]:
if stream['codec_type'] == "video":


Is that so bad? as you have hard_coded codec_type, I suppose it's a bit
more kludgy, but if the codec_type was in a variable, it would be more
convenient.

As for dataclasses, this is what i mean by "code" vs "data" -- if you know
when you are writing the code exactly what key (fields, etc) you expect ,
and you want to be able to work with that data model as code (e.g.
attribute access, maybe some methods, then you do:

In [10]: @dataclass
...: class Stream:
...: codec_type : str
...: width: int
...: height: int

And if you have that data in a dict (say, from JSON, then you can extract
it like this:

In [11]: stream_info = {'codec_type': 'video',
...:'width': 1024,
...:'height': 768,
...:}

In [12]: stream = Stream(**stream_info)

In [13]: stream
Out[13]: Stream(codec_type='video', width=1024, height=768)

That only works if you dict is in exactly the right form, but that would be
the case anyway.

Granted, that's a lot of code for a quickscript, but if it's a quick
script, just work with the dict.

IN practice, it's not so simple when you have a more nested data structure,
but I don't think this proposal would help with that, and it's not hard to
build that on top of dataclasses either, see Pydantic, or attrs, or my own
half-baked flexi project:

https://github.com/PythonCHB/flexi

(note: half-baked because the public project is not well tested nor
documented, but I am using this very code in a pretty substantial system
with a very highly nested structure:

https://adios.orr.noaa.gov

(and the code: https://github.com/NOAA-ORR-ERD/adios_oil_database)

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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread layday--- via Python-ideas
> Please can you quote some text to show who and what you're responding
to? I *think* you're responding to my post, but it's hard to be sure.

Sorry, I'm using the web UI which nests replies - I forgot this is a mailing 
list!  I was responding to your message.
___
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/PN4TEWO6OE7NLJK7MJK6NAR2SDHDY2IU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread Chris Angelico
On Mon, 7 Feb 2022 at 06:03, layday--- via Python-ideas
 wrote:
>
> I don't think we're saying anything different, I agree.  The point I was 
> making was that _after_ loading the data onto a dataclass (or equivalent), 
> you wouldn't be able to unpack it.  In JS, you can use destructuring 
> assignment when working with "classes" (and therefore well-defined APIs), 
> which is why it has wider applicability in JS.
>

Please can you quote some text to show who and what you're responding
to? I *think* you're responding to my post, but it's hard to be sure.

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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread layday--- via Python-ideas
I don't think we're saying anything different, I agree.  The point I was making 
was that _after_ loading the data onto a dataclass (or equivalent), you 
wouldn't be able to unpack it.  In JS, you can use destructuring assignment 
when working with "classes" (and therefore well-defined APIs), which is why it 
has wider applicability in JS.
___
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/JBPJJBKUWPPYN2AM3RRC7S4B46XGPX3K/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread Chris Angelico
On Mon, 7 Feb 2022 at 00:10, layday--- via Python-ideas
 wrote:
>
> This feature is far more useful in JS because JS objects double up as 
> mappings - Python dataclasses/attrs models/Pydantic models/named tuples/who 
> knows what are all represented by (typed) objects in JS/TS.  As soon as you 
> want to describe your data e.g. by encoding it in a dataclass you'll no 
> longer be able to dictionary-unpack it which will prove very frustrating.
>

That's not entirely true, because there are a ton of places where you
can read something generically and then process it afterwards. For
instance, I can run "ffprobe -print_format json", then use json.loads
to parse the output, and I'll get back a completely generic dictionary
with all its information. Suppose I then want to iterate over the
video streams:

for {codec_type, width, height} in info["streams"]:
if codec_type == "video":
...

This would be extremely convenient, and it doesn't really work with dataclasses.

A match/case block would kinda work here, but it's overkill, like
using a for/break block to fetch the first element from a list.

But I'm not convinced of the syntax, and there's only a small number
of places where I'd actually use this. Consider me +0.25.

(BTW Steven, you can consider this to be one real-world example; I
lifted this straight from an actual script of mine. But the whole
script is a dozen lines long, so this isn't exactly a strong demo
case!)

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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-06 Thread layday--- via Python-ideas
This feature is far more useful in JS because JS objects double up as mappings 
- Python dataclasses/attrs models/Pydantic models/named tuples/who knows what 
are all represented by (typed) objects in JS/TS.  As soon as you want to 
describe your data e.g. by encoding it in a dataclass you'll no longer be able 
to dictionary-unpack it which will prove very frustrating.
___
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/BOTEVLGLW325Y26ZP2BLSZGUQIVZXLZV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Mapping unpacking assignment

2022-02-04 Thread Steven D'Aprano
On Thu, Feb 03, 2022 at 07:50:50PM -, Yurii Karabas wrote:

> I am proposing to add smth like JS destructing assignment to python.
> Basically, it will allow unpacking any mapping (should have 
> __getitem__ and keys() methods) into variables.


This idea would be more compelling if you can show examples from real 
code (not made up pretend examples) where this would be useful, and 
contrast the existing solution with the proposed syntax.


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


[Python-ideas] Re: Mapping unpacking assignment

2022-02-03 Thread Yurii Karabas
I can, but it seems like the wrong usage of pattern matching and it requires 
much more code.
```
match m:
case {"a": a, "b": b, **rest}:
pass
case _:
raise ValueError
```

We can use pattern matching to unpack sequences, but we have special syntax for 
this:
```
s = range(100)

match s:
case (a, b, *rest):
pass
case _:
raise ValueError

(a, b, *rest) = s  # solve same problem with one line
```
___
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/GCMKZFHIB5S6DT24HZ42WLEUBMGTGJKU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Mapping unpacking assignment

2022-02-03 Thread Piper Thunstrom
On Thu, Feb 3, 2022 at 11:51 AM Yurii Karabas <1998uri...@gmail.com> wrote:
>
> I am proposing to add smth like JS destructing assignment to python.
> Basically, it will allow unpacking any mapping (should have __getitem__ and 
> keys() methods) into variables.
>
> Proposed syntax:
> ```
> m = {"a": 1, "b": 2, "c": 3, "d": 4}
>
> {a, b} = m # a: 1, b: 2
> {a, b, **rest} = m # a: 1, b: 2, rest: {c: 3, d: 4}
> ```

Can't you solve the same problem with structural pattern matching
against mappings?
https://www.python.org/dev/peps/pep-0622/#mapping-patterns

Piper Thunstrom
Senior Software Engineer/Open Source Maintainer
___
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/GBNGVK72CJE4AT52M6N5BWJIAX6UVNXX/
Code of Conduct: http://python.org/psf/codeofconduct/