[Python-Dev] Dataclasses and correct hashability

2018-02-05 Thread Kirill Balunov
>
> On Sun, Feb 4, 2018, 9:50 PM Guido van Rossum  > wrote:
>
> Looks like this is turning into a major flamewar regardless of what I say.
> :-(
> I really don't want to lose the ability to add a hash function to a
> mutable dataclass by flipping a flag in the decorator. I'll explain below.
> But I am fine if this flag has a name that clearly signals it's an unsafe
> thing to do.
>
> I propose to replace the existing (as of 3.7.0b1) hash= keyword for the
> @dataclass decorator with a simpler flag named unsafe_hash=. This would be
> a simple bool (not a tri-state flag like the current hash=None|False|True).
> The default would be False, and the behavior then would be to add a hash
> function automatically only if it's safe (using the same rules as for
> hash=None currently). With unsafe_hash=True, a hash function would always
> be generated that takes all fields into account except those declared using
> field(hash=False). If there's already a `def __hash__` in the function I
> don't care what it does, maybe it should raise rather than quietly doing
> nothing or quietly overwriting it.
>
> Here's my use case.
>
>
May be it is better to provide a special purpose function
`make_unsafe_hash` in
dataclass module which will patch a dataclass, instead of to clutter
@dataclass
API with arguments which are rather special case.

This `unsafe_hash` argument will constantly raise questions among ordinary
users
like me, and will be possibly considered as a non-obvious design - there is
a
public API but it is somehow unsafe. On the other hand, with a function,
when
the user asks how to make a `frozen=False` dataclass hashable, you can
suggest
to use this `make_unsafe_hash` function with all its cautions in its docs
or to try to
implement __hash__ by yourself.

Also taking into account the Python approach for backward compatibility it
is
better to stick with function and if it will be usefull to add a
`unsafe_hash`
argument in Python 3.8. It is easier to add later than to deprecate in the
future.

With kind regards,
-gdg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Dataclasses and correct hashability

2018-02-05 Thread Kirill Balunov
2018-02-05 20:47 GMT+03:00 Guido van Rossum :

> If there's going to be an API for it, it should be in the class, not
> something that mutates the class afterwards.
>


I apologize and don't want to make unnecessary noise. But the already
selected design with decorator @dataclass implies that it will mutate
the freshly created class (which in its turn already limits some
possibilities), or I've missed something? If you meant that everything
should be defined in one place, then I basically understand your desire as
the least of two evils.

With kind regards,
-gdg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Deprecating float.is_integer()

2018-03-22 Thread Kirill Balunov
 I apologize that I get into the discussion. Obviously in some situations
it will be useful to check that a floating-point number is integral, but
from the examples given it is clear that they are very rare. Why the
variant with the inclusion of this functionality into the math module was
not considered at all. If the answer is - consistency upon the numeric
tower - will it go for complex type and what will it mean (there can be two
point of views)?

Is this functionality so often used and practical to be a method of float,
int, ..., and not just to be an auxiliary function?

p.s.: The same thoughts about `as_integer_ratio` discussion.

With kind regards,
-gdg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Deprecating float.is_integer()

2018-03-22 Thread Kirill Balunov
2018-03-22 19:47 GMT+03:00 Tim Peters :

>
> > Is this functionality so often used and practical to be a method of
> float,
> > int, ..., and not just to be an auxiliary function?
> >
> > p.s.: The same thoughts about `as_integer_ratio` discussion.
>
> I would have added them as functions in the `math` module instead.
> perhaps supported by dunder methods (__as_integer_ratio__,
> __is_integer__).  But that's not what happened, and whether or not
> they have double underscores on each end doesn't really make all that
> much difference except to dedicated pedants ;-)
>

Yes, this was my point. In spite of the fact that the pronouncement has
already been made, there may still be an opportunity to influence this
decision. I do not think that this is only a matter of choice, how this
functionality will be accessed through a method or function, in fact these
highly specialized methods heavily pollute the API and open the door for
persistent questions. Given the frequency and  activity of using this
`.is_integer` method the deprecation of this method is unlikely to greatly
affect someone. (for `as_integer_ratio` I think the bar is
higher). Summarizing this thread it seems to me that with deprecation of
`is_integer` method and with addition of `is_integer` function in math
module will make everyone happy:

PROS:

1. Those who do not like this method, and do not want to see it as a
redundant part of `int`, ... will be happy
2. Those who need it will have this functionality through math module
3. Compatible packages do not have to quack louder
4. Cleaner API (no need to add this through numeric tower)
5. Make everyone happy and stop this thread :)

CONS:

1. Backward incompatible change

I do not want to restart this topic, but I think that there is an
opportunity for improvement that can be missed.

With kind regards,
-gdg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Replacing self.__dict__ in __init__

2018-03-24 Thread Kirill Balunov
2018-03-24 17:18 GMT+03:00 Tin Tvrtković :
>
> I've found that, if a class has more than one attribute, instead of
> creating an init like this:
>
> self.a = a
> self.b = b
> self.c = c
>
> it's faster to do this:
>
> self.__dict__ = {'a': a, 'b': b, 'c': c}
>
> i.e. to replace the instance dictionary altogether. On PyPy, their core
> devs inform me this is a bad idea because the instance dictionary is
> special there, so we won't be doing this on PyPy.
>

But why you need to replace it? When you can just update it:

class C:
def __init__(self, a, b, c):
self.__dict__.update({'a': a, 'b': b, 'c': c})

I'm certainly not a developer. Just out of curiosity.

With kind regards,
-gdg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Assignment Expressions

2018-04-22 Thread Kirill Balunov
2018-04-21 4:44 GMT+03:00 Tim Peters :

> [Chris Angelico ]
> > I don't see much value in restricting the assignment target to names
> > only, but if that's what it takes, it can be restricted, at least
> > initially.
>
> I believe this point was made most clearly before by Terry Reedy, but
> it bears repeating :-)  This is from the PEP's motivation:
>
> """
> Naming the result of an expression is an important part of
> programming, allowing a descriptive name to be used in place of a
> longer expression, and permitting reuse.
> """
>
> As "head arguments" go, that's a good one!  But restricting assignment
> expressions to
>
> identifier ":=" expression
>
> satisfies it.  If what's of value is to name the result of an
> expression, that single case handles that and _only_ that.  In a
> sense, it's "the simplest thing that could possibly work", and that's
> generally a good thing to aim for.
>
> Python assignment _statements_ are way more complex than that.
> Besides just giving names to expression results, they can also
> implicitly invoke arbitrarily complex __setitem__ and __setattr__
> methods on targets, rely on all sorts of side effects across chained
> assignments, and support funky syntax for magically iterating over an
> expression's iterable result.
>
> While that can all be useful _in_ an assignment statement, the PEP's
> motivation doesn't say a word about why any of _that_ would also be
> useful buried inside an assignment expression.  There doesn't appear
> to be a good "head argument" for why, besides "why not?".  That's not
> enough.
>

I agree with you. During the discussion on python-ideas there was not
explicitly suggested to limit assignment target to name only but that was
often implicitly implied. So explicit is better than implicit :) The main
reason for such criticism was related to the fact that almost all of the
examples from the PEP use `name := expression` form. Also it was noted that
99% of use-cases where this feature will be _nice_ to have is `while` and
`if` statements (including ternary from). Although one of the prerequisites
for writing this PEP was the use of the assignment expression in the lists,
it will rarely be used in them, and even more rarely it will be a justified
usage of. In addition, in the case of the general assignment expression and
the chosen operator `: =`, which solves the problem of distinctness from
`==`, I see no reason, or more precisely how to explain, why will not other
forms `+=`, `*=`  become expressions either? And then we are faced
with with all the beauty of side effects, sequnce points,  ... And while in
Python it's much easier to resolve this - Python will no longer be
Python. I'm glad that this does not happen.

Since the discussion moves towards a simplified form - `binding
expression`, where assignment target can be name only. Will you be _happy_
with the choice of `:=` operator?  Which is perceived as `=`, but with very
limited capabilities. Therefore, as I see it, with this _limited power_ it
is one of design goals to make the syntax forms of `assignment statement`
and `assignment expression` to be distinct and `:=` does not help with
this. This does not mean that this new syntax form should not be
convenient, but it should be different from the usual `=` form. Otherwise,
the question about  ".1 + .2" will have competitors :-)



> I think it's no coincidence that every example of an _intended_ use is
> of the simple
>
> identifier ":=" expression
>
> form. There are no examples of fancier targets in the PEP, and - more
> importantly - also none I saw in the hundreds of mailing-list messages
> since this started.  Except for a few of mine, where I tried to
> demonstrate why _trying_ fancier targets in examples derived from real
> code made the original "loop and a half" code _worse_  And where other
> people were illustrating how incomprehensibly code _could_ be written
> (which isn't a real interest of mine).



With kind regards,
-gdg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 572: Assignment Expressions

2018-04-22 Thread Kirill Balunov
2018-04-22 14:10 GMT+03:00 Kirill Balunov :

>
> Although one of the prerequisites for writing this PEP was the use of the
> assignment expression in the lists
>

Sorry, typo: in compehensions/generators.


> it will rarely be used in them, and even more rarely it will be a
> justified usage of.
>

With kind regards,
-gdg

>
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] The new and improved PEP 572, same great taste with 75% less complexity!

2018-04-26 Thread Kirill Balunov
2018-04-24 18:31 GMT+03:00 Chris Angelico :

>
> Recommended use-cases
> =
>
> [...]
>
> # Capturing regular expression match objects
> # See, for instance, Lib/pydoc.py, which uses a multiline spelling
> # of this effect
> if match := re.search(pat, text):
> print("Found:", match.group(0))
>
>

Not sure, but if additional motivating examples are required, there is a
common pattern for dynamic attribute lookup (snippet from `copy.py`):

reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error("un(shallow)copyable object of type %s" % cls)

which can with the current `binding expression` syntax simplified to:

if reductor := dispatch_table.get(cls):
rv = reductor(x)
elif reductor := getattr(x, "__reduce_ex__", None):
rv = reductor(4)
elif reductor := getattr(x, "__reduce__", None):
rv = reductor()
else:
raise Error("un(shallow)copyable object of type %s" % cls)

which becomes much clearer, at least in my opinion.

With kind regards,
-gdg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] (name := expression) doesn't fit the narrative of PEP 20

2018-04-26 Thread Kirill Balunov
2018-04-26 13:20 GMT+03:00 Steve Holden :

> On Thu, Apr 26, 2018 at 8:56 AM, Steven D'Aprano 
> wrote:
>
>> On Thu, Apr 26, 2018 at 03:31:13AM -0400, Terry Reedy wrote:
>> > On 4/25/2018 8:20 PM, Chris Angelico wrote:
>> > >On Thu, Apr 26, 2018 at 10:11 AM, Yury Selivanov
>> > > wrote:
>> > >>Just yesterday this snippet was used on python-dev to show how great
>> the
>> > >>new syntax is:
>> > >>
>> > >>   my_func(arg, buffer=(buf := [None]*get_size()),
>> size=len(buf))
>> >
>> > What strikes me as awful about this example is that len(buf) is
>> > get_size(), so the wrong value is being named and saved.
>> > 'size=len(buf)' is, in a sense, backwards.
>>
>> Terry is absolutely right, and I'm to blame for that atrocity. Mea
>> culpa.
>>
>> ​Perhaps a better spelling would be
>
> my_func(arg, buffer=[None]*(buflen := get_size()), size=buflen)
>
>
I know it is non productive and spamy (I promise, this is the last)  since
`as` syntax is dead. In many cases, there is not much difference in
perception between `:=` and `as`. But in several situations, like this one
and as Ethan pointed up-thread - the expression first syntax makes obvious
the intent and linearly readable:

my_func(arg, buffer=[None]*get_size() as buf, size=buf)


In any case, it is rather an anti-pattern than a good example to follow.

p.s.: as Victor Stinner wrote on twitter that previously, there was a
similar PEP in spirit - "PEP 379 -- Adding an Assignment Expression", which
was withdrawn. May be it is worth to make a link to it in the current PEP.


With kind regards,
-gdg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Examples for PEP 572

2018-07-04 Thread Kirill Balunov
Forwarding the reply to the list. Accidentally pressed the wrong button and
sent this message personally to Serhiy. Sorry :)

ср, 4 июл. 2018 г. в 11:57, Serhiy Storchaka :

> > if reductor := dispatch_table.get(cls):
> > rv = reductor(x)
> > elif reductor := getattr(x, "__reduce_ex__", None):
> > rv = reductor(4)
> > elif reductor := getattr(x, "__reduce__", None):
> > rv = reductor()
> > else:
> > raise Error("un(shallow)copyable object of type %s" % cls)
>
> I was going to rewrite this code as
>
>  reductor = dispatch_table.get(cls)
>  if reductor:
>  rv = reductor(x)
>  else:
>  rv = x.__reduce_ex__(4)
>
> There were reasons for the current complex code in Python 2, but now
> classic classes are gone, and every class has the __reduce_ex__ method
> which by default calls __reduce__ which by default is inherited from
> object. With that simplification the benefit of using ":=" in this
> example looks less impressed.
>
>
Yes you are right with this particular snippet (in its current version, it
is an echo from Python 2). But I think you have missed the general idea:
The logic of this code is flat (like a switch) but the visual structure is
pretty nested. That is why (maybe just for me) there is a mental imbalance
in perception. And this type of code is rather common. Therefore, for me,
the main gain from using the assignment expression in these patterns of
code is that the visual syntax emphasizes the semantics. To be honest, I do
not see any benefit of usage of assignment expression outside `if` and
`while` headers, but if others do see let it be so.

With kind regards,
-gdg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com