[issue36827] Overriding __new__ method with itself changes behaviour of the class

2019-05-11 Thread Alexey Muranov


Alexey Muranov  added the comment:

I see that I am not the only one who got bitten by this unexpected behaviour 
(though the others might have not realised it).  There is a question ["Creating 
a singleton in Python"][1] on StackOverflow which was posted in 2011 and by now 
has the total of 737 upvotes.  Here is a code snippet from the question:

class Singleton(object):
_instance = None
def __new__(class_, *args, **kwargs):
if not isinstance(class_._instance, class_):
class_._instance = object.__new__(class_, *args, **kwargs)
return class_._instance

class MyClass(Singleton, BaseClass):
pass

[1]: https://stackoverflow.com/q/6760685

Currently this does not work as expected, try:

class Failed(Singleton):
def __init__(self, _):
pass

Failed(42)  # TypeError: object.__new__() takes exactly one argument ...

There is a similar code snippet in the accepted [answer][2] with 507 upvotes:

class Singleton(object):
_instances = {}
def __new__(class_, *args, **kwargs):
if class_ not in class_._instances:
class_._instances[class_] = super(Singleton, class_).__new__(
class_, *args, **kwargs
)
return class_._instances[class_]

class MyClass(Singleton):
pass

[2]: https://stackoverflow.com/a/6798042

This does not work either, for the same reason.

--

___
Python tracker 
<https://bugs.python.org/issue36827>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36827] Overriding __new__ method with itself changes behaviour of the class

2019-05-07 Thread Alexey Muranov


Alexey Muranov  added the comment:

Here is an example of code where i got surprised by the current behaviour and 
had to apply some (ugly) workaround:

https://gist.github.com/alexeymuranov/04e2807eb5679ac7e36da4454a58fa7e

--

___
Python tracker 
<https://bugs.python.org/issue36827>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32768] object.__new__ does not accept arguments if __bases__ is changed

2019-05-07 Thread Alexey Muranov


Alexey Muranov  added the comment:

There were problems with the use case for mutable bases that i posted (see 
#36827).  Here is an updated version:

https://gist.github.com/alexeymuranov/04e2807eb5679ac7e36da4454a58fa7e

--

___
Python tracker 
<https://bugs.python.org/issue32768>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36827] Overriding __new__ method with itself changes behaviour of the class

2019-05-07 Thread Alexey Muranov


Alexey Muranov  added the comment:

I've noticed some faults in my code examples: `super(__class__, __class__)` 
instead of a more appropriate `super(__class__, cls)`, forgotten `return` 
before `super(__class__, self).foo(*args, **kwarg)`, maybe there are more.  I 
cannot edit previous comments, but this does not affect the main point.

I've stumbled on this behaviour in a situation where it actually poses me a 
problem.  However, here is some analogy: if a calculator returns 0 as the 
result of a multiplication of any number by 1, this cannot be justified by 
saying that no one needs to multiply numbers by 1 anyway.

--

___
Python tracker 
<https://bugs.python.org/issue36827>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36827] Overriding __new__ method with itself changes behaviour of the class

2019-05-07 Thread Alexey Muranov


Alexey Muranov  added the comment:

Incidentally, the documentation gives the following signature of __new__:

object.__new__(cls[, ...])

which suggests a variable number of arguments.

--

___
Python tracker 
<https://bugs.python.org/issue36827>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36827] Overriding __new__ method with itself changes behaviour of the class

2019-05-07 Thread Alexey Muranov


Alexey Muranov  added the comment:

The issue is the following: i expect overriding a method with itself to not 
change behaviour of the class.  I do not see how my understanding of `__new__` 
or its point could be relevant.

Do we agree that overriding a method with itself should not change behaviour?  
Is there a more correct way to do it than

def foo(self, *args, **kwarg):
# possible extensions
# ...
super(__class__, self).foo(*args, **kwarg)

(modified accordingly for class and static methods)?

When I do not override `__new__`, I expect Python to use `object`'s `__new__` 
(or at least pretend that it does). Therefore there should be no difference in 
behaviour.

--

___
Python tracker 
<https://bugs.python.org/issue36827>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36827] Overriding __new__ method with itself changes behaviour of the class

2019-05-07 Thread Alexey Muranov


New submission from Alexey Muranov :

I expect that overriding methods with themselves like in the following example 
should not change the behaviour of the class:

class C:
a = 1

def __init__(self, b):
self.b = b

def f(self, x):
return x*self.a + self.b + 1

@classmethod
def g(cls, y):
return y*cls.a + 2

@staticmethod
def h(z):
return z + 3

class D(C):
def f(self, *args, **kwargs):
return super(__class__, self).f(*args, **kwargs)

@classmethod
def g(cls, *args, **kwargs):
return super(__class__, cls).g(*args, **kwargs)

@staticmethod
def h(*args, **kwargs):
return super(__class__, __class__).h(*args, **kwargs)

c = C(7)
d = D(7)
assert c.f(42) == d.f(42)
assert c.g(42) == d.g(42)
assert c.h(42) == d.h(42)

(Moreover, I expect to be able to extend superclass method this way.)

However, this does not work with `__new__`:

class C:
def __init__(self, x):
self.x = x
print(x)

class D(C):
@staticmethod
def __new__(*args, **kwargs):
return super(__class__, __class__).__new__(*args, **kwargs)

C(7) # fine
D(7) # TypeError: object.__new__() takes exactly one argument

I think this is not a desirable feature.  I would call it a bug.

By the way, I understand why `object`'s `__init__` can complain about a wrong 
number of arguments, but I do not see a point in making `object`'s `__new__` 
complain about it.

Here is my current workaround:

class T:
@staticmethod
def __new__(cls, *_args, **_kwargs):
return object.__new__(cls)

class E(C, T):
@staticmethod
def __new__(*args, **kwargs):
return super(__class__, __class__).__new__(*args, **kwargs)

C(42) # fine
E(42) # fine

A possibly related issue: #32768 (https://bugs.python.org/issue32768)

--
components: Interpreter Core
messages: 341705
nosy: alexey-muranov
priority: normal
severity: normal
status: open
title: Overriding __new__ method with itself changes behaviour of the class
type: behavior
versions: Python 3.7, Python 3.8

___
Python tracker 
<https://bugs.python.org/issue36827>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32768] object.__new__ does not accept arguments if __bases__ is changed

2019-05-07 Thread Alexey Muranov


Alexey Muranov  added the comment:

Here is a use case for writable bases:

https://stackoverflow.com/q/56007866

class Stateful:
"""
Abstract base class for "stateful" classes.

Subclasses must implement InitState mixin.
"""

@staticmethod
def __new__(cls, *args, **kwargs):
super_new = super(__class__, __class__).__new__

# XXX: see https://stackoverflow.com/a/9639512
class CurrentStateProxy(cls.InitState):
@staticmethod
def _set_state(state_cls=cls.InitState):
__class__.__bases__ = (state_cls,)

class Eigenclass(CurrentStateProxy, cls):
@staticmethod
def __new__(cls, *args, **kwargs):
cls.__new__ = None  # just in case
return super_new(cls, *args, **kwargs)

return Eigenclass(*args, **kwargs)

class StatefulThing(Stateful):
class StateA:
"""First state mixin."""

def say_hello(self):
print("Hello!")
self.hello_count += 1
self._set_state(self.StateB)
return True

def say_goodbye(self):
print("Another goodbye?")
return False

class StateB:
"""Second state mixin."""

def say_hello(self):
print("Another hello?")
return False

def say_goodbye(self):
print("Goodbye!")
self.goodbye_count += 1
self._set_state(self.StateA)
return True

# This one is required by Stateful.
class InitState(StateA):
"""Third state mixin -- the initial state."""

def say_goodbye(self):
print("Why?")
return False

def __init__(self):
self.hello_count = self.goodbye_count = 0

def say_hello_followed_by_goodbye(self):
self.say_hello() and self.say_goodbye()

# --
# ## Demo ##
# --
if __name__ == "__main__":
t1 = StatefulThing()
t2 = StatefulThing()
print("> t1, say hello:")
t1.say_hello()
print("> t2, say goodbye:")
t2.say_goodbye()
print("> t2, say hello:")
t2.say_hello()
print("> t1, say hello:")
t1.say_hello()
print("> t1, say hello followed by goodbye:")
t1.say_hello_followed_by_goodbye()
print("> t2, say goodbye:")
t2.say_goodbye()
print("> t2, say hello followed by goodbye:")
t2.say_hello_followed_by_goodbye()
print("> t1, say goodbye:")
t1.say_goodbye()
print("> t2, say hello:")
t2.say_hello()
print("---")
print( "t1 said {} hellos and {} goodbyes."
   .format(t1.hello_count, t1.goodbye_count) )
print( "t2 said {} hellos and {} goodbyes."
   .format(t2.hello_count, t2.goodbye_count) )

# Expected output:
#
# > t1, say hello:
# Hello!
# > t2, say goodbye:
# Why?
# > t2, say hello:
# Hello!
# > t1, say hello:
# Another hello?
# > t1, say hello followed by goodbye:
# Another hello?
# > t2, say goodbye:
# Goodbye!
# > t2, say hello followed by goodbye:
# Hello!
# Goodbye!
# > t1, say goodbye:
# Goodbye!
# > t2, say hello:
# Hello!
# ---
# t1 said 1 hellos and 1 goodbyes.
# t2 said 3 hellos and 2 goodbyes.

--
nosy: +alexey-muranov

___
Python tracker 
<https://bugs.python.org/issue32768>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue32768] object.__new__ does not accept arguments if __bases__ is changed

2019-05-07 Thread Alexey Muranov


Alexey Muranov  added the comment:

IMO "overriding" a method with itself should not change the behaviour. So it 
seems to me that the following is a bug:

class C:
def __init__(self, m):
print(m)

class D:
@staticmethod
def __new__(cls, *args, **kwargs):
return super(__class__, __class__).__new__(cls, *args, **kwargs)

def __init__(self, m):
print(m)

C(42) # fine
D(42) # TypeError: object.__new__() takes exactly one argument

Of course such overriding makes little sense in itself, but forbidding it makes 
even less sense and creates bugs in more complex scenarios.

--

___
Python tracker 
<https://bugs.python.org/issue32768>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-04-03 Thread Alexey Muranov

On mer., Apr 3, 2019 at 6:00 PM, python-list-requ...@python.org wrote:
On Wed, Apr 3, 2019 at 3:55 AM Alexey Muranov 
 wrote:

 I clarified what i meant by an assignment, and i believe it to be a
 usual meaning.

   1. `def` is not an assignment, there is no left-hand side or
 right-hand side. I was talking about the normal assignment by which
 anyone can bind any value to any variable.


Actually, a 'def' statement DOES perform assignment. It does a bit
more than that, but it definitely is assignment. You can easily check
the CPython disassembly:


A command that performs an assignment among other things is not an 
assignment command itself.


Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-04-02 Thread Alexey Muranov



On mar., Apr 2, 2019 at 6:00 PM, python-list-requ...@python.org wrote:
On Tue, Apr 2, 2019 at 1:43 AM Alexey Muranov 


wrote:


 > On Mon, Apr 1, 2019 at 3:52 PM Alexey Muranov  gmail.com>
 > wrote:
 > >
 > > I only see a superficial analogy with `super()`, but perhaps it 
is

 > > because you did not give much details of you suggestion.
 >
 > No, it's because the analogy was not meant to be anything more 
than

 > superficial. Both are constructs of syntactic magic that aid
 > readability at
 > a high level but potentially obscure the details of execution (in
 > relatively unimportant ways) when examined at a low level.

 Since i understand that the "super() magic" is just evaluation in a
 predefined environment, it does not look so very magic.


It's the reason why this doesn't work:

superduper = super

class A:
def f(self):
return 42

class B(A):
def f(self):
return superduper().f()


 B().f()

Traceback (most recent call last):
  File "", line 1, in 
  File "", line 3, in f
RuntimeError: super(): __class__ cell not found

But this does:

class C(A):
def f(self):
return superduper().f()
not super


 C().f()

42

I don't know, seems magical to me.

 Moreover, without this "magic", `super()` would have just produced 
an
 error.  So this magic did not change behaviour of something that 
worked

 before, it made "magically" work something that did not work before
 (but i am still not excited about it).


I'm curious how you feel about this example then (from the CPython 
3.7.2
REPL; results from different Python implementations or from scripts 
that

comprise a single compilation unit may vary)?


 372 is 372

True

 b = 372; b is 372

True

 b = 372
 b is 372

False


 > Maybe it was from my talk of implementing this by replacing the
 > assignment
 > with an equivalent def statement in the AST. Bear in mind that 
the def
 > statement is already just a particular kind of assignment: it 
creates

 > a
 > function and assigns it to a name. The only difference between the
 > original
 > assignment and the def statement that replaces it is in the 
__name__
 > attribute of the function object that gets created. The proposal 
just

 > makes
 > the direct lambda assignment and the def "assignment" to be fully
 > equivalent.

 `def` is not an assignment, it is more than that.


def is an assignment where the target is constrained to a single 
variable

and the expression is constrained to a newly created function object
(optionally "decorated" first with one or more composed function 
calls).

The only ways in which:

@decorate
def foo(blah):
return stuff

is more than:

foo = decorate(lambda blah: stuff)

are: 1) the former syntactically allows statements inside the function
body, not just expressions; 2) the former syntactically allows 
annotations
on the function; and 3) the former syntactically sets a function name 
and
the latter doesn't. In other words, all of the differences ultimately 
boil

down to syntax.


Sorry, i do not feel like continuing this discussion for much longer, 
or we need to concentrate on some specific statement on which we 
disagree.


I clarified what i meant by an assignment, and i believe it to be a 
usual meaning.


 1. `def` is not an assignment, there is no left-hand side or 
right-hand side. I was talking about the normal assignment by which 
anyone can bind any value to any variable.


 2. If i execute an assignment statement

foo = ...

and instead of evaluating the right-hand side and assigning the 
value to "foo" variable Python does something else, i consider the 
assignment operation ( = ) broken, as it does not do 
assignment (and only assignment). I've said more on this in previous 
messages.


 3. About the examples with `372 is 372`, Python gives no garanties 
about the id's of numerical objects, and about id's of many other types 
of immutable objects. The user is not supposed to rely on their 
equality or inequality.


Anytime Python's interpreter encounter two immutable objects that 
it finds identical, it is free to allocate a single object for both, 
this does not change the guaranteed semantics of the program.


The '__name__' attribute of an object, as well as most (or all) 
other attributes, is a part of object's value/contents, no analogies 
with the id's.


I am sorry, but except maybe for one or two more very specific 
questions, I am probably not going to continue.


Alexey.



--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-04-02 Thread Alexey Muranov
On Mon, Apr 1, 2019 at 3:52 PM Alexey Muranov gmail.com>

wrote:
>
> I only see a superficial analogy with `super()`, but perhaps it is
> because you did not give much details of you suggestion.

No, it's because the analogy was not meant to be anything more than
superficial. Both are constructs of syntactic magic that aid 
readability at

a high level but potentially obscure the details of execution (in
relatively unimportant ways) when examined at a low level.


Since i understand that the "super() magic" is just evaluation in a 
predefined environment, it does not look so very magic.  I do not know 
if Python can already manipulate blocks of code and environments as 
first-class objects, but in any case this does not look to be too far 
from the its normal behaviour/semantics.


Moreover, without this "magic", `super()` would have just produced an 
error.  So this magic did not change behaviour of something that worked 
before, it made "magically" work something that did not work before 
(but i am still not excited about it).


On the contrary, i have no idea of how in the current semantics 
executing an assignment can mutate the assigned value.



> On the other hand, i do use assignment in Python, and you seem to
> propose to get rid of assignment or to break it.

I thought the proposal was clear and succinct. "When [lambda 
expressions]
are directly assigned to a variable, Python would use the variable 
name as
the function name." That's all. I don't know where you got the idea I 
was

proposing "to get rid of assignment".


I suppose we use the term "assignment operation" differently.  By 
assignment i mean evaluating the expressions in the right-hand side and 
assigning (binding?) the value to the variable or location described in 
the left-hand side. I believed this was the usual meaning of 
"assignment"...


The behaviour you describe cannot happen during assignment in this 
sense.


Maybe it was from my talk of implementing this by replacing the 
assignment

with an equivalent def statement in the AST. Bear in mind that the def
statement is already just a particular kind of assignment: it creates 
a
function and assigns it to a name. The only difference between the 
original

assignment and the def statement that replaces it is in the __name__
attribute of the function object that gets created. The proposal just 
makes

the direct lambda assignment and the def "assignment" to be fully
equivalent.


`def` is not an assignment, it is more than that.

Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Generator definition syntax (was: Syntax for one-line "nonymous" functions)

2019-04-02 Thread Alexey Muranov

On mar., Apr 2, 2019 at 4:31 AM, python-list-requ...@python.org wrote:
Re: ">> Neither i like how a function magically turns into a 
generator if the

 keyword `yield` appears somewhere within its definition.


 I agree, there should have been a required syntactic element on the 
"def"
 line as well to signal it immediately to the reader. It won't stop 
me from using them, though."


One way to save people looking at the code from having to look 
through a function for a yield statement to see if it is a generator 
would be to add a """doc string""" immediately after the function 
def, saying that it is a generator
and describing what it does.  I realize I'm calling on the programmer 
to address this issue by adding doc strings.  Nonetheless adding doc 
strings is a good habit to get in to.

--- Joseph S.


And even if Python did not have docstrings, the programmer could still 
use comments to tell a fellow programmer what kind of code the fellow 
programmer is looking at. Even languages like Brainfuck have comments 
:).


Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-04-01 Thread Alexey Muranov

On lun., avril 1, 2019 at 6:00 PM, python-list-requ...@python.org wrote:
On Sun, Mar 31, 2019 at 1:09 PM Alexey Muranov 


wrote:


 On dim., Mar 31, 2019 at 6:00 PM, python-list-requ...@python.org 
wrote:

 > On Sat, Mar 30, 2019, 5:32 AM Alexey Muranov
 > 
 > wrote:
 >
 >>
 >>  On ven., Mar 29, 2019 at 4:51 PM, python-list-requ...@python.org
 >> wrote:
 >>  >
 >>  > There could perhaps be a special case for lambda expressions 
such

 >>  >  that,
 >>  > when they are directly assigned to a variable, Python would 
use

 >> the
 >>  > variable name as the function name. I expect this could be
 >>  >  accomplished by
 >>  > a straightforward transformation of the AST, perhaps even by 
just

 >>  >  replacing
 >>  > the assignment with a def statement.
 >>
 >>  If this will happen, that is, if in Python assigning a
 >> lambda-defined
 >>  function to a variable will mutate the function's attributes, or
 >> else,
 >>  if is some "random" syntactically-determined cases
 >>
 >>  f = ...
 >>
 >>  will stop being the same as evaluating the right-hand side and
 >>  assigning the result to "f" variable, it will be a fairly good 
extra

 >>  reason for me to go away from Python.
 >>
 >
 > Is there a particular reason you don't like this? It's not too
 > different
 > from the syntactic magic Python already employs to support the
 > 0-argument
 > form of super().

 I do not want any magic in a programming language i use, especially 
if

 it breaks simple rules.

 I do not like 0-argument `super()` either, but at least I do not 
have

 to use it.


Well, you wouldn't have to use my suggestion either, since it only 
applies

to assignments of the form "f = lambda x: blah". As has already been
stated, the preferred way to do this is with a def statement. So just 
use a
def statement for this, and it wouldn't affect you (unless you 
*really*

want the function's name to be "" for some reason).


I only see a superficial analogy with `super()`, but perhaps it is 
because you did not give much details of you suggestion.


Not only i do not have to use `super()` (i do not have to use Python 
either), but the magic behaviour of `super` is explained by special 
implicit environments in which some blocks of code are executed.  
Though this looks somewhat hackish, it gives me no clue of how your 
idea of mutating objects during assignment is supposed to work.


On the other hand, i do use assignment in Python, and you seem to 
propose to get rid of assignment or to break it.


Note that

   foo.bar = baz

and

   foo[bar] = baz

are not assignments but method calls, but

   foo = bar

it an assignment (if i understand the current model correctly).

Do you propose to desugar it into a method/function call and to get rid 
of assignments in the language completely? Will the user be able to 
override this method? Something like:


   setvar("foo", bar)  # desugaring of foo = bar

Would the assignment operation remain in the language under a different 
name?  Maybe,


   foo <- bar

?

I am so perplexed by the proposed behaviour of `f = lambda...`, that i 
need to ask the followng: am i right to expact that


 1.

 f = lambda x: x,
 g = lambda x: x*x

 2.

 (f, g) = (lambda x: x, lambda x: x*x)

 3.

 (f, g) = _ = (lambda x: x, lambda x: x*x)

 4.

 f = (lambda x: x)(lambda x: x)
 g = (lambda x: x)(lambda x: x*x)

Will all have the same net effect?

I suppose in any case that

   return lambda x: 

and

   result = lambda x: 
   return result

would not return the same result, which is not what i want.

I tried to imagine what semantics of the language could cause your 
proposed behaviour of `f = lambda...` and couldn't think of anything 
short of breaking the language.



That said, that's also the reason why this probably wouldn't happen. 
Why go

to the trouble of fixing people's lambda assignments for them when the
preferred fix would be for them to do it themselves by replacing them 
with

def statements?


It is not fixing, it is breaking.

Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-03-31 Thread Alexey Muranov

On dim., Mar 31, 2019 at 6:00 PM, python-list-requ...@python.org wrote:
On Sat, Mar 30, 2019, 5:32 AM Alexey Muranov 


wrote:



 On ven., Mar 29, 2019 at 4:51 PM, python-list-requ...@python.org 
wrote:

 >
 > There could perhaps be a special case for lambda expressions such
 >  that,
 > when they are directly assigned to a variable, Python would use 
the

 > variable name as the function name. I expect this could be
 >  accomplished by
 > a straightforward transformation of the AST, perhaps even by just
 >  replacing
 > the assignment with a def statement.

 If this will happen, that is, if in Python assigning a 
lambda-defined
 function to a variable will mutate the function's attributes, or 
else,

 if is some "random" syntactically-determined cases

 f = ...

 will stop being the same as evaluating the right-hand side and
 assigning the result to "f" variable, it will be a fairly good extra
 reason for me to go away from Python.



Is there a particular reason you don't like this? It's not too 
different
from the syntactic magic Python already employs to support the 
0-argument

form of super().


I do not want any magic in a programming language i use, especially if 
it breaks simple rules.


I do not like 0-argument `super()` either, but at least I do not have 
to use it. I am suspicious of `__class__` too. But here only 
identifiers are hacked, not the assignment operator. (I suppose the 
hack can be unhacked by using your own meta-class with a custom 
`__prepare__`.)


Neither i like how a function magically turns into a generator if the 
keyword `yield` appears somewhere within its definition.


Those are the things i don't like the most in Python.

Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-03-30 Thread Alexey Muranov



On ven., Mar 29, 2019 at 4:51 PM, python-list-requ...@python.org wrote:
On Thu, Mar 28, 2019 at 2:30 PM Alexey Muranov 


wrote:


 On jeu., mars 28, 2019 at 8:57 PM, Terry Reedy  
wrote:

 > Throwing the name away is foolish.  Testing functions is another
 > situation in which function names are needed for proper report.

 My idea however was to have it as an exact synonyme of an 
assignment of

 a lambda. Assignment is an assignment, it should not modify the
 attributs of the value that is being assigned.


There could perhaps be a special case for lambda expressions such 
that,

when they are directly assigned to a variable, Python would use the
variable name as the function name. I expect this could be 
accomplished by
a straightforward transformation of the AST, perhaps even by just 
replacing

the assignment with a def statement.


If this will happen, that is, if in Python assigning a lambda-defined 
function to a variable will mutate the function's attributes, or else, 
if is some "random" syntactically-determined cases


   f = ...

will stop being the same as evaluating the right-hand side and 
assigning the result to "f" variable, it will be a fairly good extra 
reason for me to go away from Python.


Since this could just as easily be applied to lambda though, I'm 
afraid it

doesn't offer much of a case for the "f(x)" syntactic sugar.


I did not get this. My initial idea was exactly about introducing a 
syntactic sugar for better readability. I've already understood that 
the use cases contradict PEP 8 recommendations.


Alexey.




--
https://mail.python.org/mailman/listinfo/python-list


Re: Python-list Digest, Vol 186, Issue 31

2019-03-30 Thread Alexey Muranov

On ven., Mar 29, 2019 at 4:51 PM, python-list-requ...@python.org wrote:
On Thu, Mar 28, 2019 at 2:30 PM Alexey Muranov 


wrote:


 On jeu., mars 28, 2019 at 8:57 PM, Terry Reedy  
wrote:

 > Throwing the name away is foolish.  Testing functions is another
 > situation in which function names are needed for proper report.

 My idea however was to have it as an exact synonyme of an 
assignment of

 a lambda. Assignment is an assignment, it should not modify the
 attributs of the value that is being assigned.


There could perhaps be a special case for lambda expressions such 
that,

when they are directly assigned to a variable, Python would use the
variable name as the function name. I expect this could be 
accomplished by
a straightforward transformation of the AST, perhaps even by just 
replacing

the assignment with a def statement.


If this will happen, that is, if in Python assigning a lambda-defined 
function to a variable will mutate the function's attributes, or else, 
if is some "random" syntactically-determined cases


f = ...

will stop being the same as evaluating the right-hand side and 
assigning the result to "f" variable, it will be a fairly good extra 
reason for me to go away from Python.


Since this could just as easily be applied to lambda though, I'm 
afraid it

doesn't offer much of a case for the "f(x)" syntactic sugar.


I did not get this. My initial idea was exactly about introducing a 
syntactic sugar for better readability. I've already understood that 
the use cases contradict PEP 8 recommendations.


Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-03-28 Thread Alexey Muranov

On jeu., mars 28, 2019 at 5:00 PM, python-list-requ...@python.org wrote:

So documentation of that syntax would 100% be required


Regarding documentation, i believe there would be 3 line to add:


() = 

is a syntactic sugar for

 = lambda : 


Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-03-28 Thread Alexey Muranov

On jeu., mars 28, 2019 at 8:57 PM, Terry Reedy  wrote:

On 3/28/2019 12:29 PM, Alexey Muranov wrote:
On jeu., Mar 28, 2019 at 5:00 PM, python-list-requ...@python.org 
wrote:


So my opinion is that lambda expressions should only be used within 
larger expressions and never directly bound.


It would be however more convenient to be able to write instead 
just


f(x) = x*x


Given my view above, this is, standing alone, strictly an 
abbreviation of the equivalent def statement.  I am presuming 
that a proper implementation would result in f.__name__ == 'f'.




No, after some thought, i think it should be an abbreviation of "f = 
lambda x: x*x", f.__name__ would still be ''.


Throwing the name away is foolish.  Testing functions is another 
situation in which function names are needed for proper report.


My idea however was to have it as an exact synonyme of an assignment of 
a lambda. Assignment is an assignment, it should not modify the 
attributs of the value that is being assigned.




But i see your point about never assigning lambdas directly, it 
makes sense.  But sometimes i do assign short lambdas directly to 
variable.


Is the convenience and (very low) frequency of applicability worth 
the inconvenience of confusing the meaning of '=' and 
complicating the implementation?



I do not see any conflicts with the existing syntax.


It heavily conflicts with existing syntax.  The current meaning of
  target_expression = object_expression
is
1. Evaluate object_expression in the existing namespace to an 
object, prior to any new bindings and independent of the 
target_expression.
2. Evaluate target_expression in the existing namespace to one or 
more targets.
3. Bind object to target or iterate target to bind to multiple 
targets.


I do not thick so.  In "x = 42" the variable x is not evaluated.

All examples of the proposed syntax i can think of are currently 
illegal, so i suppose there is no conflicts. (I would appreciate a 
counterexample, if any.)


You are talking about syntax conflicts, I am talking about semantic 
conflict, which is important for human understanding.


Thanks for the reference to PEP 8, this is indeed an argument 
against.


The situation in which assigning lambda expressions is more tempting 
is when assigning to attributes or dicts.


def double(x): return x*x
C.double = double
d['double'] = double
versus

C.double = lambda x: x*x
d['double'] = lambda x: x*x


These are some of examples i had in mind as well:

   C.double(x) = x*x
   d['double'](x) = x*x

Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-03-28 Thread Alexey Muranov

On jeu., mars 28, 2019 at 8:57 PM, Terry Reedy  wrote:


But i see your point about never assigning lambdas directly, it 
makes sense.  But sometimes i do assign short lambdas directly to 
variable.


Is the convenience and (very low) frequency of applicability worth 
the inconvenience of confusing the meaning of '=' and 
complicating the implementation?



I do not see any conflicts with the existing syntax.


It heavily conflicts with existing syntax.  The current meaning of
  target_expression = object_expression
is
1. Evaluate object_expression in the existing namespace to an 
object, prior to any new bindings and independent of the 
target_expression.
2. Evaluate target_expression in the existing namespace to one or 
more targets.
3. Bind object to target or iterate target to bind to multiple 
targets.


I do not thick so.  In "x = 42" the variable x is not evaluated.

All examples of the proposed syntax i can think of are currently 
illegal, so i suppose there is no conflicts. (I would appreciate a 
counterexample, if any.)


You are talking about syntax conflicts, I am talking about semantic 
conflict, which is important for human understanding.


I believe there is no semantic conflict either, or could you be more 
specific?


Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-03-28 Thread Alexey Muranov

On jeu., mars 28, 2019 at 5:00 PM, python-list-requ...@python.org wrote:

On 2019-03-27 10:42 a.m., Paul Moore wrote:
 On Wed, 27 Mar 2019 at 12:27, Alexey Muranov 
 wrote:
 On mer., mars 27, 2019 at 10:10 AM, Paul Moore 


 wrote:

 On Wed, 27 Mar 2019 at 08:25, Alexey Muranov
  wrote:

  Whey you need a simple function in Python, there is a choice
 between a
  normal function declaration and an assignment of a anonymous
 function
  (defined by a lambda-expression) to a variable:

  def f(x): return x*x

  or

  f = lambda x: x*x

  It would be however more convenient to be able to write instead 
just


  f(x) = x*x
 Why? Is saving a few characters really that helpful? So much so 
that
 it's worth adding a *third* method of defining functions, which 
would

 need documenting, adding to training materials, etc, etc?

 Because i think i would prefer to write it this way.

 That's not likely to be sufficient reason for changing a language
 that's used by literally millions of people.


 (Almost no new documentation or tutorials would be needed IMHO.)
 Documentation would be needed to explain how the new construct 
worked,

 for people who either wanted to use it or encountered it in other
 people's code. While it may be obvious to you how it works, it 
likely
 won't be to others, and there will probably be edge cases you 
haven't

 considered that others will find and ask about.


For what it's worth, if I encountered "f(x) = x * x" in code, my first
thought would be that Python somehow added a way to return an 
assignable
reference from a function, rather than this being an anonymous 
function

declaration.

So documentation of that syntax would 100% be required

Alex



The thing to the right of the assignment symbol represents a value (an 
object), but the thing to the left does not represent a value, it 
represents a place for a value.


What would an "assignable reference" mean? Say, variable "x" holds an 
"assignable reference", what can be done next?


Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-03-28 Thread Alexey Muranov

On jeu., Mar 28, 2019 at 5:00 PM, python-list-requ...@python.org wrote:


So my opinion is that lambda expressions should only be used within 
larger expressions and never directly bound.



It would be however more convenient to be able to write instead just

f(x) = x*x


Given my view above, this is, standing alone, strictly an 
abbreviation of the equivalent def statement.  I am presuming that a 
proper implementation would result in f.__name__ == 'f'.




No, after some thought, i think it should be an abbreviation of "f = 
lambda x: x*x", f.__name__ would still be ''.


But i see your point about never assigning lambdas directly, it makes 
sense.  But sometimes i do assign short lambdas directly to variable.


Is the convenience and (very low) frequency of applicability worth 
the inconvenience of confusing the meaning of '=' and complicating 
the implementation?



I do not see any conflicts with the existing syntax.


It heavily conflicts with existing syntax.  The current meaning of
  target_expression = object_expression
is
1. Evaluate object_expression in the existing namespace to an object, 
prior to any new bindings and independent of the target_expression.
2. Evaluate target_expression in the existing namespace to one or 
more targets.
3. Bind object to target or iterate target to bind to multiple 
targets.


I do not thick so.  In "x = 42" the variable x is not evaluated.

All examples of the proposed syntax i can think of are currently 
illegal, so i suppose there is no conflicts. (I would appreciate a 
counterexample, if any.)


Thanks for the reference to PEP 8, this is indeed an argument against.

Alexey.



--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-03-27 Thread Alexey Muranov

On mer., Mar 27, 2019 at 5:00 PM, python-list-requ...@python.org wrote:

On 27/03/19 09:21, Alexey Muranov wrote:
 Whey you need a simple function in Python, there is a choice 
between a
 normal function declaration and an assignment of a anonymous 
function

 (defined by a lambda-expression) to a variable:

def f(x): return x*x

 or

f = lambda x: x*x

 It would be however more convenient to be able to write instead just

f(x) = x*x

 (like in Haskell and such).

 Have this idea been discussed before?

 I do not see any conflicts with the existing syntax.   The following
 would also work:


I don't know. Something like the following is already legal:

f(x)[n] = x * n

And it does something completly different.



Thanks for pointing out this example, but so far i do not see any issue 
with this.


Of course assignment (to an identifier) is a completely different type 
of operation than in-place mutation (of an object) with __setitem__, 
etc.


In

   <...> [<...>] = <...>

the part to the left of "[<...>]=" is an expression that is to be 
evaluated, and only its value matters.  Here "[]=" can be viewed as a 
method call, which is distinguished by the context from "[]" method 
call (__getitem__).


In

= <...>

the  is not evaluated.

I still think that

   ()...() = <...>

is unambiguous.  The following seems possible too:

   a[m][n](x)(y) = m*x + n*y

It would be the same as

   a[m][n] = lambda x: lambda y: m*x + n*y

Here a[m] is evaluated, and on the result the method "[]=" 
(__setitem__) is called.


Basically, "()...()=" seems to technically fit all contexts where "=" 
fits...


Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Syntax for one-line "nonymous" functions in "declaration style"

2019-03-27 Thread Alexey Muranov




On mer., mars 27, 2019 at 10:10 AM, Paul Moore  
wrote:
On Wed, 27 Mar 2019 at 08:25, Alexey Muranov 
 wrote:


 Whey you need a simple function in Python, there is a choice 
between a
 normal function declaration and an assignment of a anonymous 
function

 (defined by a lambda-expression) to a variable:

 def f(x): return x*x

 or

 f = lambda x: x*x

 It would be however more convenient to be able to write instead just

 f(x) = x*x


Why? Is saving a few characters really that helpful? So much so that
it's worth adding a *third* method of defining functions, which would
need documenting, adding to training materials, etc, etc?



Because i think i would prefer to write it this way.

(Almost no new documentation or tutorials would be needed IMHO.)

Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Syntax for one-line "nonymous" functions in "declaration style"

2019-03-27 Thread Alexey Muranov
Whey you need a simple function in Python, there is a choice between a 
normal function declaration and an assignment of a anonymous function 
(defined by a lambda-expression) to a variable:


   def f(x): return x*x

or

   f = lambda x: x*x

It would be however more convenient to be able to write instead just

   f(x) = x*x

(like in Haskell and such).

Have this idea been discussed before?

I do not see any conflicts with the existing syntax.   The following 
would also work:


   incrementer(m)(n) = n + m

instead of

   incrementer = lambda m: lambda n: n + m

Alexey.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Problem/bug with class definition inside function definition

2018-05-08 Thread Alexey Muranov
Sorry, i was confused.  I would say that this mostly works as expected, 
though the difference between


   x = 42

   class C:
   x = x  # Works

and

   def f2(a):
   class D:
   a = a  # Does not work <<<<<
   return D

is still surprising to me.

Otherwise, probably the solution with

   def f(a):
   _a = a
   class D:
   a = _a
   return D

is good enough, if Python does not allow to refer "simultaneously" to 
variables from different scopes if they have the same name.


Alexey.


On Tue, 8 May, 2018 at 12:21 AM, Alexey Muranov 
<alexey.mura...@gmail.com> wrote:

To be more exact, i do see a few workarounds, for example:


   def f4(a):
   b = a
   class D:
   a = b  # Works
   return D

But this is not what i was hoping for.

Alexey.

On Tue, 8 May, 2018 at 12:02 AM, Alexey Muranov 
<alexey.mura...@gmail.com> wrote:
I have discovered the following bug or problem: it looks like i am 
forced to choose different names for class attributes and function 
arguments, and i see no workaround.  Am i missing some special 
syntax feature ?


Alexey.

---
x = 42

class C1:
   y = x  # Works

class C2:
   x = x  # Works

# ---
def f1(a):
   class D:
   b = a  # Works
   return D

def f2(a):
   class D:
   a = a  # Does not work <<<<<
   return D

def f3(a):
   class D:
   nonlocal a
   a = a  # Does not work either <<<<<
   return D

# ---
def g1(a):
   def h():
   b = a  # Works
   return b
   return h

def g2(a):
   def h():
   a = a  # Does not work (as expected)
   return a
   return h

def g3(a):
   def h():
   nonlocal a
   a = a  # Works
   return a
   return h

# ---
if __name__ == "__main__":
   assert C1.y == 42
   assert C2.x == 42

   assert f1(13).b == 13

   try:
   f2(13)  # NameError
   except NameError:
   pass
   except Exception as e:
   raise Exception( 'Unexpected exception raised: '
'{}'.format(type(e).__name__) )
   else:
   raise Exception('No exception')

   try:
   f3(13).a  # AttributeError
   except AttributeError:
   pass
   except Exception as e:
   raise Exception( 'Unexpected exception raised: '
'{}'.format(type(e).__name__) )
   else:
   raise Exception('No exception')

   assert g1(13)() == 13

   try:
   g2(13)()  # UnboundLocalError
   except UnboundLocalError:
   pass
   except Exception as e:
   raise Exception( 'Unexpected exception raised: '
'{}'.format(type(e).__name__) )
   else:
   raise Exception('No exception')

   assert g3(13)() == 13





--
https://mail.python.org/mailman/listinfo/python-list


Re: Problem/bug with class definition inside function definition

2018-05-07 Thread Alexey Muranov

To be more exact, i do see a few workarounds, for example:


   def f4(a):
   b = a
   class D:
   a = b  # Works
   return D

But this is not what i was hoping for.

Alexey.

On Tue, 8 May, 2018 at 12:02 AM, Alexey Muranov 
<alexey.mura...@gmail.com> wrote:
I have discovered the following bug or problem: it looks like i am 
forced to choose different names for class attributes and function 
arguments, and i see no workaround.  Am i missing some special syntax 
feature ?


Alexey.

---
x = 42

class C1:
   y = x  # Works

class C2:
   x = x  # Works

# ---
def f1(a):
   class D:
   b = a  # Works
   return D

def f2(a):
   class D:
   a = a  # Does not work <<<<<
   return D

def f3(a):
   class D:
   nonlocal a
   a = a  # Does not work either <<<<<
   return D

# ---
def g1(a):
   def h():
   b = a  # Works
   return b
   return h

def g2(a):
   def h():
   a = a  # Does not work (as expected)
   return a
   return h

def g3(a):
   def h():
   nonlocal a
   a = a  # Works
   return a
   return h

# ---
if __name__ == "__main__":
   assert C1.y == 42
   assert C2.x == 42

   assert f1(13).b == 13

   try:
   f2(13)  # NameError
   except NameError:
   pass
   except Exception as e:
   raise Exception( 'Unexpected exception raised: '
'{}'.format(type(e).__name__) )
   else:
   raise Exception('No exception')

   try:
   f3(13).a  # AttributeError
   except AttributeError:
   pass
   except Exception as e:
   raise Exception( 'Unexpected exception raised: '
'{}'.format(type(e).__name__) )
   else:
   raise Exception('No exception')

   assert g1(13)() == 13

   try:
   g2(13)()  # UnboundLocalError
   except UnboundLocalError:
   pass
   except Exception as e:
   raise Exception( 'Unexpected exception raised: '
'{}'.format(type(e).__name__) )
   else:
   raise Exception('No exception')

   assert g3(13)() == 13



--
https://mail.python.org/mailman/listinfo/python-list


Problem/bug with class definition inside function definition

2018-05-07 Thread Alexey Muranov
I have discovered the following bug or problem: it looks like i am 
forced to choose different names for class attributes and function 
arguments, and i see no workaround.  Am i missing some special syntax 
feature ?


Alexey.

---
x = 42

class C1:
   y = x  # Works

class C2:
   x = x  # Works

# ---
def f1(a):
   class D:
   b = a  # Works
   return D

def f2(a):
   class D:
   a = a  # Does not work <
   return D

def f3(a):
   class D:
   nonlocal a
   a = a  # Does not work either <
   return D

# ---
def g1(a):
   def h():
   b = a  # Works
   return b
   return h

def g2(a):
   def h():
   a = a  # Does not work (as expected)
   return a
   return h

def g3(a):
   def h():
   nonlocal a
   a = a  # Works
   return a
   return h

# ---
if __name__ == "__main__":
   assert C1.y == 42
   assert C2.x == 42

   assert f1(13).b == 13

   try:
   f2(13)  # NameError
   except NameError:
   pass
   except Exception as e:
   raise Exception( 'Unexpected exception raised: '
'{}'.format(type(e).__name__) )
   else:
   raise Exception('No exception')

   try:
   f3(13).a  # AttributeError
   except AttributeError:
   pass
   except Exception as e:
   raise Exception( 'Unexpected exception raised: '
'{}'.format(type(e).__name__) )
   else:
   raise Exception('No exception')

   assert g1(13)() == 13

   try:
   g2(13)()  # UnboundLocalError
   except UnboundLocalError:
   pass
   except Exception as e:
   raise Exception( 'Unexpected exception raised: '
'{}'.format(type(e).__name__) )
   else:
   raise Exception('No exception')

   assert g3(13)() == 13

--
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-03 Thread Alexey Muranov

On Fri, 2017-11-03 at 22:03 +1100, Chris Angelico wrote:
> On Fri, Nov 3, 2017 at 8:48 PM, Alexey Muranov <alexey.muranov@gmail.
> com> wrote:
> > 'Then' describes what happens next indeed, unless some
> > extraordinary
> > situation prevents it from happening, for example:
> >
> > try:
> > go_to_the_bakery()
> > then:
> > buy_croissants(2)
> > except BakeryClosed:
> > go_to_the_grociery()
> > buy_baguette(1)
> > finally:
> > come_back()
> >
> > I know this is a poor program example (why not to use a boolean
> > return value
> > instead of an exception, etc.), and i know that currently in Python
> > `except`
> > must precede `else`, it is just to illustrate the choice of terms.
>
> What is the semantic difference between that code and the same
> without the "then:"?

Chris,

the semantic difference is that their meanings/behaviours are not 
identical (i imply that `then` here does what `else` currently does).  
I agree however that from practical viewpoint the difference will 
probably never be observable (unless the person enters the bakery and 
asks for croissants, but during this time the baker exits the bakery 
and closes it to go on vacation).


I can try to think of a better example if you give me any good use-case 
for `else` in `try`.  I have searched on-line, and on StackOverflow in 
particular, but didn't find anything better that this:


 * https://stackoverflow.com/a/6051978

People seem very shy when it comes to giving a real-life example of 
`else` in `try`.


Alexey.

--
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-03 Thread Alexey Muranov

On Thu, 2017-11-02 at 16:31 +, Jon Ribbens wrote:

> On 2017-11-02, Steve D'Aprano  wrote:

> > On Fri, 3 Nov 2017 12:39 am, Jon Ribbens wrote:

> > > Why would we want to make the language worse? It is fairly
> > > obvious
> > > what 'else' means,

> >
> > Yes, obvious and WRONG.

>
> Nope, obvious and right.
>


I suppose that to continue this way we'd need at some point define 
somehow the meaning of "obvious."





> > > whereas 'then' has an obvious meaning that is in
> > > fact the opposite of what it would actually do.

> >
> > Er... is today opposite day? Because 'then' describes precisely
> > what it
> > actually does.

>
> No, 'then' describes the opposite of what it does. The word 'then'
> implies something that always happens next, whereas 'else' conveys
> the correct meaning, which is something that happens if the course
> of the preceding piece of code did not go as expected.
>


Jon, i get from this that for you, when there is no exception in `try`, 
or no `break` in a loop, the things did not go as expected.  Either we 
need to agree that what is "expected" is subjective, or agree on some 
kind of formal or informal common meaning for it, because i would not 
have put it this way.


'Then' describes what happens next indeed, unless some extraordinary 
situation prevents it from happening, for example:


   try:
   go_to_the_bakery()
   then:
   buy_croissants(2)
   except BakeryClosed:
   go_to_the_grociery()
   buy_baguette(1)
   finally:
   come_back()

I know this is a poor program example (why not to use a boolean return 
value instead of an exception, etc.), and i know that currently in 
Python `except` must precede `else`, it is just to illustrate the 
choice of terms.


Best regards,

Alexey.

--
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-02 Thread Alexey Muranov

On Thu, 2017-11-02 at 08:21 +1100, Chris Angelico wrote:

>
>
With try/except/else, it's "do this, and if an exception happens, do 
this, else do this". So else makes perfect sense.


Indeed, i forgot about `except`.  I agree that 
"try/then/except/finally" would be better than 
"try/except/then/finally", but "try/except/else/finally" does not make 
a perfect sense IMHO.


Alexey.

--
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-02 Thread Alexey Muranov

On Wed, 2017-11-01 at 21:30 +, Stefan Ram wrote:

>
>   In languages like Algol 68, »then« is used for a clause
>   that is to be executed when the main condition of an
>   if-statement /is/ true, so this might cause some confusion.
>


sure, and `else` is used for a clause that is to be executed when the 
main condition of `if` is false.


So, in

   try:
   do_something
   except:
   catch_exception
   else:
   continue_doing_something

when no exception occurs in `do_something`, is `do_something` more 
true, or more false?


Alexey.

--
https://mail.python.org/mailman/listinfo/python-list


Re: replacing `else` with `then` in `for` and `try`

2017-11-02 Thread Alexey Muranov

On Thu, 2017-11-02 at 08:29 +1100, Chris Angelico wrote:
> On Thu, Nov 2, 2017 at 8:23 AM, Ned Batchelder 
 > wrote:

> >
> >
> > Apart from the questions of backward compatibility etc (Python is
> > unlikely
> > to ever go through another shift like the 2/3 breakage), are you
> > sure "then"
> > is what you mean?  This won't print "end":
> >
> > for i in range(10):
> > print(i)
> > else:
> > print(end)

>
> Well, it'll bomb with NameError when it tries to look up the *name*
> end. But it will run that line of code - if you quote it, it will
> work.


You see how people are confused over "for ... else".

Alexey.

--
https://mail.python.org/mailman/listinfo/python-list


replacing `else` with `then` in `for` and `try`

2017-11-01 Thread Alexey Muranov

Hello,

what do you think about the idea of replacing "`else`" with "`then`" in 
the contexts of `for` and `try`?


It seems clear that it should be rather "then" than "else."  Compare 
also "try ... then ... finally" with "try ... else ... finally".


Currently, with "else", it is almost impossible to guess the meaning 
without looking into the documentation.


Off course, it should not be changed in Python 3, maybe in Python 4 or 
5, but in Python 3 `then` could be an alias of `else` in these contexts.


Alexey.

--
https://mail.python.org/mailman/listinfo/python-list


[issue26645] argparse prints help messages to stdout instead of stderr by default

2016-03-27 Thread Alexey Muranov

Alexey Muranov added the comment:

My grep man page says

  --help  Print a brief help message.

but indeed there is no `--help` in usage message.  Maybe this is a bug of the 
man page.

Thanks for the explanation.

--

___
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue26645>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26645] argparse prints help messages to stdout instead of stderr by default

2016-03-26 Thread Alexey Muranov

Alexey Muranov added the comment:

Thanks for the explanation, this makes sense.  I did not notice that argparse 
outputs to stderr if command line arguments are wrong, i was probably wrong 
when said it prints error messages to stdout.  I did not notice indeed that 
there were no `-h` option in git.

However, my grep version 2.5.1-FreeBSD outputs help to stderr even with 
`--help` option.

--

___
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue26645>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26645] argparse prints help messages to stdout instead of stderr by default

2016-03-26 Thread Alexey Muranov

New submission from Alexey Muranov:

I believe that printing help and usage messages to stdout is a design error.

In stdout i expect to find the output of my program, not help or diagnostic 
messages.  It is strange to see nothing printed on the screen (where stderr 
usually goes), and then to find help, usage, or *error* messages in the file 
where stdout was sent.  (Yes, argparse prints even error messages to stdout by 
default).

This issue has been discussed before because the implementation did not agree 
with the documentation: http://bugs.python.org/issue10728
I believe that the conclusion to adjust the documentation to the implementation 
was a mistake.

P.S. Compare with the direction of the output of `grep -h` or `git -h`.

--
components: Library (Lib)
messages: 262491
nosy: Alexey Muranov
priority: normal
severity: normal
status: open
title: argparse prints help messages to stdout instead of stderr by default
type: behavior
versions: Python 3.5

___
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue26645>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com