Re: Difference between os.path.isdir and Path.is_dir

2019-12-14 Thread Kirill Balunov
Yeah it is True, for the last two weeks or so I can access bugs.python.org
in normal way. But I totally agree with the site that the best description
of this situation is "Yet".

with kind regards,
-gdg

сб, 14 дек. 2019 г. в 19:46, Terry Reedy :

> On 7/26/2019 3:12 AM, Kirill Balunov wrote:
> > чт, 25 июл. 2019 г. в 20:28, eryk sun :
> >
> >> On 7/25/19, Kirill Balunov  wrote:
> >>>
> >>>>>> import os
> >>>>>> from pathlib import Path
> >>>>>> dummy = " "   # or "" or " "
> >>>>>> os.path.isdir(dummy)
> >>> False
> >>>>>> Path(dummy).is_dir()
> >>> True
> >>
> >> I can't reproduce the above result in either Linux or Windows. The
> >> results should only be different for an empty path string, since
> >> Path('') is the same as Path('.'). The results should be the same for
> >> Path(" "), depending on whether a directory named " " exists (normally
> >> not allowed in Windows, but Linux allows it).
> >>
> >>
> > I need to confirm that it was my fault and for non-empty strings (`" "`
> or `"
> > "`), both `os.path.isdir(...)` and `Path(...).is_dir()` produce the same
> > results.So sorry for the noise.
> >
> > Concerning the case with empty path string, I will open a ticket at the
> bug
> > tracker (but for some reason it is blocked in my country :(
> > https://isitblockedinrussia.com/?host=https%3A%2F%2Fbugs.python.org%2F).
>
> For me, this now returns 'No, https://bugs.python.org is probably not
> blocked in Russia. Yet.'.
>
> > Obviously
> > these are not equivalent forms, so either this should be noted in the
> > documentation or corrected in the code.
>
> --
> Terry Jan Reedy
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


[issue37688] The results from os.path.isdir(...) an Path(...).is_dir() are not equivalent for empty path strings.

2019-07-26 Thread Kirill Balunov

Kirill Balunov  added the comment:

I am reading "equivalence" too strictly (like "as a substitute"), because this 
is part of the documentation :) and I agree that in ordinary speech I would use 
it rather in the sense of “similar”.

In order to make sure, that everyone agrees only on that this requires only a 
documentation change? Because as for me, I think that it will better for 
`os.path.isdir` to raise `ValueError` or `DeprecationWarning` - `False` on 
empty string is not well defined behavior. But I'm fine to be alone with the 
last one.

--

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



[issue37688] The results from os.path.isdir(...) an Path(...).is_dir() are not equivalent for empty path strings.

2019-07-26 Thread Kirill Balunov


Kirill Balunov  added the comment:

I understand the reasons, I only say that it does not correspond to my 
perception of their equivalence, because:

os.path.isdir('') != os.path.isdir('.')

while:

Path('').is_dir() == Path('.').is_dir()

and I can confirm that some libraries rely on os.path.isdir('') -> False 
behavior.

--

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



[issue37688] The results from os.path.isdir(...) an Path(...).is_dir() are not equivalent for empty path strings.

2019-07-26 Thread Kirill Balunov


Kirill Balunov  added the comment:

Forgot to write the result for Path variant:

>>> Path(dummy).is_dir()
 True

--

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



[issue37688] The results from os.path.isdir(...) an Path(...).is_dir() are not equivalent for empty path strings.

2019-07-26 Thread Kirill Balunov


New submission from Kirill Balunov :

In the documentation it is said that os.path.isdir(...) an 
Path(...).is_dir()are equivalent substitutes.
https://docs.python.org/3/library/pathlib.html#correspondence-to-tools-in-the-os-module

But they give different result for empty path strings:
>>> import os
>>> from pathlib import Path
>>> dummy = "" 
>>> os.path.isdir(dummy)
 False

Obviously it's not an equivalence, so either this should be noted in the 
documentation or corrected in the code.

--
assignee: docs@python
components: Documentation, Library (Lib)
messages: 348475
nosy: docs@python, godaygo
priority: normal
severity: normal
status: open
title: The results from os.path.isdir(...) an Path(...).is_dir() are not 
equivalent for empty path strings.
type: behavior

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



Re: Difference between os.path.isdir and Path.is_dir

2019-07-26 Thread Kirill Balunov
чт, 25 июл. 2019 г. в 20:28, eryk sun :

> On 7/25/19, Kirill Balunov  wrote:
> >
> >>>> import os
> >>>> from pathlib import Path
> >>>> dummy = " "   # or "" or " "
> >>>> os.path.isdir(dummy)
> > False
> >>>> Path(dummy).is_dir()
> > True
>
> I can't reproduce the above result in either Linux or Windows. The
> results should only be different for an empty path string, since
> Path('') is the same as Path('.'). The results should be the same for
> Path(" "), depending on whether a directory named " " exists (normally
> not allowed in Windows, but Linux allows it).
>
>
I need to confirm that it was my fault and for non-empty strings (`" "` or `"
"`), both `os.path.isdir(...)` and `Path(...).is_dir()` produce the same
results.So sorry for the noise.

Concerning the case with empty path string, I will open a ticket at the bug
tracker (but for some reason it is blocked in my country :(
https://isitblockedinrussia.com/?host=https%3A%2F%2Fbugs.python.org%2F).
Obviously
these are not equivalent forms, so either this should be noted in the
documentation or corrected in the code.

with kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Difference between os.path.isdir and Path.is_dir

2019-07-25 Thread Kirill Balunov
чт, 25 июл. 2019 г. в 22:58, Chris Angelico :

> On Fri, Jul 26, 2019 at 5:52 AM Kirill Balunov 
> wrote:
> [...]
> > No, it's not just because of curiosity. I will try to tell the
> background, and maybe I went the wrong way initially. There is a very cool
> project https://github.com/3b1b/manim, it allows you to visualize math (I
> don’t know how to describe it better you can see some examples here
> https://www.3blue1brown.com) and it works lovely on Linux. For some
> reason, I need to use it on Windows. Problems began to arise when I tried
> my scripts were some latex was included in the animation.
> >
>
> Ah, I love 3b1b! Great videos. I toyed with manim once (wanting to
> create new Fourier visualizations), but the open source parts weren't
> enough for what I was trying to do. Very cool though.
>
>
If you can tell, what parts did you miss?

with kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Difference between os.path.isdir and Path.is_dir

2019-07-25 Thread Kirill Balunov
чт, 25 июл. 2019 г. в 19:16, Chris Angelico :

> On Fri, Jul 26, 2019 at 1:30 AM Kirill Balunov 
> wrote:
> >
> >  Hi all! It is expected that:
> > ```
> > >>> import os
> > >>> from pathlib import Path
> > >>> dummy = " "   # or "" or " "
> > >>> os.path.isdir(dummy)
> > False
> > >>> Path(dummy).is_dir()
> > True
> > ```
> >
> > or was it overlooked?
> >
> []
> I'm not sure if this is considered an important enough bug to actually
> fix, or
> if it's merely a curiosity that occurs when you trigger undocumented
> behaviour.
>
>
No, it's not just because of curiosity. I will try to tell the background,
and maybe I went the wrong way initially. There is a very cool project
https://github.com/3b1b/manim, it allows you to visualize math (I don’t
know how to describe it better you can see some examples here
https://www.3blue1brown.com) and it works lovely on Linux. For some reason,
I need to use it on Windows. Problems began to arise when I tried my
scripts were some latex was included in the animation.
So I installed TexLive, but it didn't produce any output :) In `manim` it
is invoked through a system call
https://github.com/3b1b/manim/blob/master/manimlib/utils/tex_file_writing.py#L40
like this:

$ latex -interaction=batchmode -halt-on-error -output-directory=...
input.tex > /dev/null

For some reason TexLive does not understand Windows relative paths of this
form -output-directory =".\Output" and  ".\Input\file.tex", but it
understands the absolute paths in Windows form like
"C:\path\to\the\input\file.tex".
I read that Windows allows also to provide paths in the usual form
"./Input/file.tex"
(maybe I'm wrong with my understanding what does it mean on Windows), I've
tested and this worked. But the problem is that Python always inserts '\'
as path separators on Windows and there is no control to set it up. I
decided to rewrite all this stuff with the help of `pathlib` module and to
use `Path`  and `.as_posix` method everywhere. Paths are set here
https://github.com/3b1b/manim/blob/c7e6d9d4742ec47098bd86a9bbb4212cc637206b/manimlib/constants.py#L10
and the author uses  `MEDIA_DIR = ""` as a default unset value, and then
checks  `if not os.path.isdir(MEDIA_DIR)`. The documentation states that
`os.path.isdir(...)` is equivalent to `Path(...).is_dir()` but it is not
true. So I wrote here.

with kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Difference between os.path.isdir and Path.is_dir

2019-07-25 Thread Kirill Balunov
чт, 25 июл. 2019 г. в 20:28, eryk sun :

> On 7/25/19, Kirill Balunov  wrote:
> >
> >>>> import os
> >>>> from pathlib import Path
> >>>> dummy = " "   # or "" or " "
> >>>> os.path.isdir(dummy)
> > False
> >>>> Path(dummy).is_dir()
> > True
>
> I can't reproduce the above result in either Linux or Windows. The
> results should only be different for an empty path string, since
> Path('') is the same as Path('.'). The results should be the same for
> Path(" "), depending on whether a directory named " " exists (normally
> not allowed in Windows, but Linux allows it).
>
>
Heh, something fishy is going on. I also can't reproduce that behavior
(with " " and "   ") at home comp on Windows 10 Python 3.7.4. Tomorrow I'll
check again at work and let you know. I apologize in advance. The main
problem arose огые with an empty line, but then I checked with " " and
apparently made a mistake somewhere.

with kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Difference between os.path.isdir and Path.is_dir

2019-07-25 Thread Kirill Balunov
 Hi all! It is expected that:
```
>>> import os
>>> from pathlib import Path
>>> dummy = " "   # or "" or " "
>>> os.path.isdir(dummy)
False
>>> Path(dummy).is_dir()
True
```

or was it overlooked?

with kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to achieve pyc only deployment for module in python3.6

2018-10-02 Thread Kirill Balunov
On Tue, Oct 2, 2018, 08:42 Chris Angelico  wrote:

> On Tue, Oct 2, 2018 at 12:01 PM Chandana Pattanayak
>  wrote:
> >
> > Hi,
> >
> > I have a requirement to provide basic code protection for a module in our
> > product suite. With python 3.6 the .pyc files are created under pycache ,
> > so if i remove the py file the module is not found anymore.
>
> If you want code protection, the ONLY reliable way to do it is to not
> provide the code *at all*, in any form.
>

I think Cython is a rather reliable way to do it. There is a nice post to
start with “Protecting Python Sources With Cython” @2parrots
https://medium.com/@xpl/protecting-python-sources-using-cython-dcd940bb188e

With kind regards,
-gdg

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


Re: [OT] master/slave debate in Python

2018-09-24 Thread Kirill Balunov
пн, 24 сент. 2018 г. в 22:46, Chris Angelico :

>
> The trouble is that making changes like this with a view to
> eliminating the words "master" and "slave" from all docs and comments
> (rather than making them to improve clarity and accuracy) opens up the
> leverage that SJWs need. "Hey, you changed that because we hate
> slavery - now you'd better eliminate all references to 'black' because
> we hate racism". So clear boundaries need to be set.
>
>
It seems to me that the word "black" has immunity in the next two Python
releases ;)  So do not worry so much!

But honestly, it's not pleasant to see how such holy things spread into the
world of OSS, and this is apparently only the beginning.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


[issue33326] Convert collections (cmp_op, hasconst, hasname and others) in opcode module to more optimal type

2018-04-26 Thread Kirill Balunov

Kirill Balunov <kirill.balu...@gmail.com> added the comment:

I apologize for FutureWarning and __getattr__. I myself do not understand what 
I meant and how it will help in this situation :)

--

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



[issue33326] Convert collections (cmp_op, hasconst, hasname and others) in opcode module to more optimal type

2018-04-26 Thread Kirill Balunov

Kirill Balunov <kirill.balu...@gmail.com> added the comment:

Small risk of breaking is a fair point (maybe some FutureWarning with new 
__getattr__ PEP 562?). I've checked several packages:

---
vstinner/bytecode:: uses:

@staticmethod
def _has_jump(opcode):
return (opcode in _opcode.hasjrel
or opcode in _opcode.hasjabs)

---
maynard:: defines them as sets and does not rely on opcode module.

all_jumps = absolute_jumps | relative_jumps

---
numba:: converts them to frozensets:

JREL_OPS = frozenset(dis.hasjrel)
JABS_OPS = frozenset(dis.hasjabs)
JUMP_OPS = JREL_OPS | JABS_OPS

---
codetransfromer:: uses:

absjmp = opcode in hasjabs
reljmp = opcode in hasjrel

---
anotherassembler.py:: uses

elif opcode in hasjrel or opcode in hasjabs:

---
byteplay:: converts them to set:

hasjrel = set(Opcode(x) for x in opcode.hasjrel)
hasjabs = set(Opcode(x) for x in opcode.hasjabs)
hasjump = hasjrel.union(hasjabs)

---
byterun:: uses:

elif byteCode in dis.hasjrel:
arg = f.f_lasti + intArg
elif byteCode in dis.hasjabs:
arg = intArg

In fact, all of the above indicated does not mean anything, but I have not 
found cases of hasjrel+hasjabs.

Despite the fact that they are small, on average, with sets I gain 5-6x 
speed-up.

--

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



[issue33326] Convert collections (cmp_op, hasconst, hasname and others) in opcode module to more optimal type

2018-04-26 Thread Kirill Balunov

Change by Kirill Balunov <kirill.balu...@gmail.com>:


--
nosy: +larry, serhiy.storchaka

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



[issue32455] PyCompile_OpcodeStackEffect() and dis.stack_effect() are not particularly useful

2018-04-26 Thread Kirill Balunov

Kirill Balunov <kirill.balu...@gmail.com> added the comment:

Sorry if this doesn't fit this issue and needs a separate one.

Since Python switched to 2 byte wordcode, all opcodes which do not imply an 
argument, technically have it - augmented with 0. So it is convenient to 
iterate over bytecode like:

op, arg = instruction.

But there is a check in stack_effect that the second argument for this opcodes 
must be None. 

file::_opcode.c

else if (oparg != Py_None) {
PyErr_SetString(PyExc_ValueError,
"stack_effect: opcode does not permit oparg but oparg was 
specified");
return -1;
}


So you need to perform a somewhat _redundant_ check before calling:

arg = arg if op >= opcode.HAVE_ARGUMENT else None.
st = stack_effect(op, arg)

Maybe it's normal to relax this condition - be None or 0 for opcode < 
opcode.HAVE_ARGUMENT?

--
nosy: +godaygo

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



[issue33326] Convert collections (cmp_op, hasconst, hasname and others) in opcode module to more optimal type

2018-04-21 Thread Kirill Balunov

New submission from Kirill Balunov <kirill.balu...@gmail.com>:

The opcode module contains several collections:

`cmp_op`
`hasconst`
`hasname`
`hasjrel`
...

which are only used for `in` checks. At the same time, they are stored as 
`list`s and `cmp_op` as tuple. Both these types are not optimal for 
`__contains__` checks. Maybe it is worth at least to convert them to 
`frozenset` type after they are filled?

--
components: Library (Lib)
messages: 315576
nosy: godaygo
priority: normal
severity: normal
status: open
title: Convert collections (cmp_op, hasconst, hasname and others) in opcode 
module to more optimal type
type: performance
versions: Python 3.7, Python 3.8

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



[issue27129] Wordcode, part 2

2018-04-13 Thread Kirill Balunov

Kirill Balunov <kirill.balu...@gmail.com> added the comment:

Hello, what is the future of this patch? Such a feeling that the transition to 
wordcode is still in some half-way state.

--
nosy: +godaygo

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



Re: Python aliases under Windows?

2018-04-03 Thread Kirill Balunov
2018-04-03 22:04 GMT+03:00 eryk sun :

> On Tue, Apr 3, 2018 at 3:43 PM, Ian Kelly  wrote:
> >
> > Because py.exe is really meant to solve a slightly different problem.
> > On Unix if you have a .py script and you run it directly, without
> > specifying which interpreter to use, the convention is to start the
> > script with a shebang line, and the kernel will transparently use the
> > interpreter specified there. Windows, however, doesn't respect shebang
> > lines and instead associates programs with files by file extension.
> >
> > Here's the problem: Python 2 files have a .py extension. Python 3
> > files also have a .py extension. Windows doesn't allow both Python
> > binaries to be associated with the same extension. So how can we set
> > things up so that launching a Python file will invoke the correct
> > Python version? To solve this, Python ships with py.exe and associates
> > *that* with the .py extension. py.exe knows what Python versions are
> > installed, and it inspects the shebang line to decide which one to run
> > for this particular script.
> >
> > The fact that py.exe can also intelligently select versions from
> > command line arguments is just an added bonus.
>

Thank you Ian, Terry, Eryk! Now I understand the purpose of py launcher in
general. I don't have Windows near, will `py -3.6 ...` work if Python36 is
not on the Path? If not, it seems to me, that if `python3.exe` and
`python3.6.exe` were provided they would be equivalent, and together they
will complement together and unify UNIX and Windows workflow. Am I missing
something?


> Alternatively, there's the Windows Script Host (WSH) framework
> (cscript.exe console, wscript.exe GUI), which supports a generic WSF
> file extension that allows mixing multiple languages in a single
> script, and integrates with COM, ASP, and native debuggers. PyWin32
> supports WSH. This could have been adapted to support Python 3 as a
> separate Windows scripting engine.
>
> That said, for general use, the py launcher's registration+shebang
> support is more flexible than the WSH registration-only approach. The
> launcher supports virtual Unix shebangs for cross-platform scripts and
> arbitrary executable paths for scripts that depend on virtual
> environments. I use it for the .py[w] file association and creating
> virtual environments. I still prefer `python` on the command line.
> Even on Linux I don't frequently use `python3` or `python3.X`. I do
> very little with the system Python.
>
> If you really miss typing "python3.6", I suggest using relative
> symbolic links (e.g. CMD's `mklink` command) created in the same
> directory as python[w].exe. Using relative symlinks requires
> installing Python on a NTFS volume that supports them, so it's not a
> viable solution for external drives that use FAT32 or exFAT. In the
> latter case, an alternative to batch scripts is to create a
> "python[w]3.6.lnk" shell shortcut to "python[w].exe". Leave the "start
> in" folder empty, so it will inherit the parent's working directory,
> and add .LNK to the system PATHEXT environment variable. One caveat is
> that, unlike symlinks or batch scripts, executing shell shortcuts
> requires ShellExecute[Ex] (called from Explorer, CMD, PowerShell,
> etc). CreateProcess (e.g. subprocess.Popen with shell=False) doesn't
> know anything about .LNK files.
> --
> https://mail.python.org/mailman/listinfo/python-list
>

Thank you for your detailed advice, I'll try to understand. Why under
Windows everything is so complicated... Concerning dealing with `python` vs
`python3` it is a matter of habit, and I find the latter option more
reliable and missing it under Windows.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python aliases under Windows?

2018-04-03 Thread Kirill Balunov
2018-04-03 16:45 GMT+03:00 Paul Moore <p.f.mo...@gmail.com>:

> On 3 April 2018 at 10:24, Kirill Balunov <kirillbalu...@gmail.com> wrote:
> > Perhaps this is a silly question but still...There is PEP 394 "The
> "python"
> > Command on Unix-Like Systems" which I find very reasonable, no matter how
> > it is respected. Why was not _somewhat_ the same done for Windows?
>
> History, mainly. Plus the fact that the Unix convention is *not* that
> reasonable. Why should a system with only Python 3 installed (very
> common on Windows) not use "python" for that interpreter? The
> requirement that "python" must always refer to Python 2 comes from
> historical constraints on how Linux distributions chose to write their
> system scripts, AIUI.
>

I understand that general rules are not possible among the various OSs. If
just `python` suits for Windows it is OK. But I have the same question, why
should a system with Python 3 installed not use both "python" and "python3"
for that interpreter? This `python3` will allow to slightly unify the
workflow on different OSs, while it will be done almost for free. I want to
add that there are plenty of tutorials which use `python3 ...` without
reference to UNIX world, why are these mental overhead with `python3` or
`py -3` necessary?

In fact, I do not really understand why the _py launcher_ way is easier or
better than `python3` or `python3.6` way even on Windows. There are already
`pip.exe`, `pip3.exe`, `pip3.6.exe` which solve the same problem,  but they
are all redundant, when it is better to use `python3.6 -m pip ... ` or
currently `py -3.6 -m pip install ...`.

But debating why things are the way they are isn't that productive.
> It's the reality, so we need to deal with it.
>
> > p.s.: I know there is a `py` launcher under Windows, but is does not help
> > in this situation.
>
> Could you not use an alias?
>
> In [1]: import sys
>...: if sys.platform.startswith('win'):
>...: %alias python3 py -3
>...: else:
>...: %alias python3 python3
>...:
>...: ver = %python3 --version
>...: ver
>...:
> Python 3.6.2


Thank you this works for me!

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python aliases under Windows?

2018-04-03 Thread Kirill Balunov
2018-04-03 16:15 GMT+03:00 Ian Kelly :

> Creating python2.bat and python3.bat instead would take up less
> additional disk space and would not need to be modified every time you
> reinstall a new release of the same minor version.
>
>
Thank you!


> > This
> > copy-rename works for me, but it will not work for someone who does not
> > have administrative rights.
>
> They could put them under their user folder and add the folder to
> their path, although that's creeping into power user territory. Then
> again, they *are* using IPython...
>
> > p.s.: I know there is a `py` launcher under Windows, but is does not help
> > in this situation.
>
> I don't understand. Is 'py -3' that much harder to type than 'python3'
> when running in Windows?
>

IPython is  only one of the examples, instead you can substitute Jupyter,
subprocess. As I wrote before:


> I have two options:
> 1. To wriie a shell script for `py` under Linux.
> 2. To copy-rename to python3 under Windows.
> Both are easy, but a little bit strange to do.
>

which seems unnecessary. There is already `pip.exe`, `pip3.exe`,
`pip3.6.exe` in Scripts sub-folder which in my opinion solve the same
problem.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python aliases under Windows?

2018-04-03 Thread Kirill Balunov
2018-04-03 12:27 GMT+03:00 Chris Angelico :

>
> Why doesn't it? That's what its job is.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>

Because it affects my workflow under Windows and Linux. I have two options:
1. To wriie a shell script for `py` under Linux.
2. To copy-rename to python3 under Windows.

Both are easy, but a little bit strange to do.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Python aliases under Windows?

2018-04-03 Thread Kirill Balunov
Perhaps this is a silly question but still...There is PEP 394 "The "python"
Command on Unix-Like Systems" which I find very reasonable, no matter how
it is respected. Why was not _somewhat_ the same done for Windows?

Sometimes I use, especially in IPython, to run externally:
! python3 -m dis 
! python3 -m timeit ...
! python3 -m pip install ...

And to make this work the same under Windows, the first step which I do
after installation is to copy `python.exe` and rename it to `python3.exe`
(for python 2.7 copy `python.exe` and rename it to `python2.exe`). May be
there is a better way to do this under Windows, I would like to know?  This
copy-rename works for me, but it will not work for someone who does not
have administrative rights.

p.s.: I know there is a `py` launcher under Windows, but is does not help
in this situation.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: check if bytes is all nulls

2018-04-01 Thread Kirill Balunov
2018-04-01 22:03 GMT+03:00 Kirill Balunov <kirillbalu...@gmail.com>:

>
>
> 2018-04-01 20:55 GMT+03:00 Arkadiusz Bulski <arek.bul...@gmail.com>:
>
>> What would be the most performance efficient way of checking if a bytes is
>> all zeros?
>
>
> Try `not any(key)` ;)
>
>
Sorry, I don't timed it before I posted. In reality, it is far from the
fastest, it is 10 times slower than `==`, but I like it:)

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: check if bytes is all nulls

2018-04-01 Thread Kirill Balunov
2018-04-01 20:55 GMT+03:00 Arkadiusz Bulski :

> What would be the most performance efficient way of checking if a bytes is
> all zeros?


Try `not any(key)` ;)

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Do not promote `None` as the first argument to `filter` in documentation.

2018-03-06 Thread Kirill Balunov
2018-03-06 17:55 GMT+03:00 Chris Angelico :

> If the first argument is None, the identity function is assumed. That
> is, all elements of the iterable that are false are removed; it is
> equivalent to (item for item in iterable if item). It is approximately
> equivalent to (but faster than) filter(bool, iterable).
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>

If you look in C source for `filter_next`
https://github.com/python/cpython/blob/5d92647102fac9e116b98ab8bbc632eeed501c34/Python/bltinmodule.c#L593,
there is a line:

int checktrue = lz->func == Py_None || lz->func == (PyObject
*)_Type;

So the only difference between `filter(None, ls`) and `filter(bool, ls)` is
LOAD_NAME vs LOAD_CONST and that `None` is checked before than `bool`.


With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Do not promote `None` as the first argument to `filter` in documentation.

2018-03-06 Thread Kirill Balunov
2018-03-06 17:55 GMT+03:00 Chris Angelico <ros...@gmail.com>:

> On Wed, Mar 7, 2018 at 1:48 AM, Kirill Balunov <kirillbalu...@gmail.com>
> wrote:
> > Note: For some historical reasons as the first argument you can use None
> > instead of function, in this case the identity function is assumed. That
> > is, all elements of iterable that are false are removed which is
> equivalent
> > to (item for item in iterable if item). Currently, for the same purpose
> the
> > preferred form is `filter(bool, iterable)`.
> >
>
> I'd prefer to word it something like:
>
> If the first argument is None, the identity function is assumed. That
> is, all elements of the iterable that are false are removed; it is
> equivalent to (item for item in iterable if item). It is approximately
> equivalent to (but faster than) filter(bool, iterable).
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>

I do not want to seem rude and stubborn, but how much faster is it to
highlight or emphasize it:

from random import randint
for i in [1, 10, 100, 1000, 1, 10]:
ls = [randint(0,1) for _ in range(i)]
%timeit [*filter(None, ls)]
%timeit [*filter(bool, ls)]
print()

272 ns ± 0.0346 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)
282 ns ± 0.0714 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

283 ns ± 0.0645 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)
296 ns ± 0.116 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

1.4 µs ± 1.32 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)
1.41 µs ± 4.05 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

14.7 µs ± 40.1 ns per loop (mean ± std. dev. of 7 runs, 10 loops each)
14.7 µs ± 23.2 ns per loop (mean ± std. dev. of 7 runs, 10 loops each)

137 µs ± 186 ns per loop (mean ± std. dev. of 7 runs, 1 loops each)
137 µs ± 24.7 ns per loop (mean ± std. dev. of 7 runs, 1 loops each)

1.32 ms ± 285 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1.32 ms ± 908 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Do not promote `None` as the first argument to `filter` in documentation.

2018-03-06 Thread Kirill Balunov
2018-03-06 16:58 GMT+03:00 Jason Friedman :

>
> as a ordinary Python user I'd be interested in improvements to the
> documentation, including suggestions on real-world usage.
>

I'm just an ordinary user, just like you :)


> Kirill, taking deprecation/removal off the table, what changes would you
> recommend to the documentation?
>

My English is about basic level, so you may need to fix the spelling. But I
would write as follows:


filter(function, iterable)
Construct an iterator from those elements of iterable for which function
returns truthy values. iterable may be either a sequence, a container which
supports iteration, or an iterator.

Note that filter(function, iterable) is equivalent to the generator
expression (item for item in iterable if function(item)). In cases when
function corresponds to a simple lambda function a generator expression
should be preferred. For example, when it is necessary to eliminate all
multiples of three (x for x in range(100) if x % 3) should be used, instead
of filter(lambda x: x % 3, range(100))

See itertools.filterfalse() for the complementary function that returns
elements of iterable for which function returns false.

Note: For some historical reasons as the first argument you can use None
instead of function, in this case the identity function is assumed. That
is, all elements of iterable that are false are removed which is equivalent
to (item for item in iterable if item). Currently, for the same purpose the
preferred form is `filter(bool, iterable)`.

p.s.:
maybe _function_ should be changed to _callable_.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Do not promote `None` as the first argument to `filter` in documentation.

2018-03-06 Thread Kirill Balunov
2018-03-06 16:35 GMT+03:00 Chris Green :

> It's 'deprecation', depreciation is something quite different.  People
> replying have spelt it correctly so you might possibly have noticed I
> thought/hoped.
>
> ... and it does matter a bit because it's not just a mis-spelling, the
> word you are using has its own meaning and could thus cause confusion.
>
> ... and, yes, I know it's a very common and easily made mistake. :-)
>
>
I did not ;) Thank you!

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Do not promote `None` as the first argument to `filter` in documentation.

2018-03-06 Thread Kirill Balunov
2018-03-06 16:51 GMT+03:00 Chris Angelico <ros...@gmail.com>:

> On Wed, Mar 7, 2018 at 12:23 AM, Kirill Balunov <kirillbalu...@gmail.com>
> wrote:
> > Filter is generally faster than list comprehension or generators.
> >
> > %timeit [*filter(lambda x: x % 3, range(1000))]
> > 100 µs ± 16.4 ns per loop (mean ± std. dev. of 7 runs, 1 loops each)
> >
> > f = lambda x: x % 3
> >
> > %timeit [*(f(i) for i in range(1000))]
> > 132 µs ± 73.5 ns per loop (mean ± std. dev. of 7 runs, 1 loops each)
> >
> > %timeit [f(i) for i in range(1000)]
> > 107 µs ± 179 ns per loop (mean ± std. dev. of 7 runs, 1 loops each)
> >
>
> These don't do the same thing, though. A more comparable comprehension is:
>
> [i for i in range(1000) if i % 3]
>
> rosuav@sikorsky:~$ python3 -m timeit '[i for i in range(1000) if i % 3]'
> 1 loops, best of 5: 34.5 usec per loop
> rosuav@sikorsky:~$ python3 -m timeit '[*filter(lambda x: x % 3,
> range(1000))]'
> 5000 loops, best of 5: 81.1 usec per loop
>
> And my point about comprehensions was that you do NOT use a pointless
> function for them - you just have inline code. If there is a
> pre-existing function, sure! Use it. But when you use filter or map
> with a lambda function, you should probably use a comprehension
> instead.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>

Thank you, I did not understand you at first, now everything is clear. In
this sense of `x % 3`, I fully agree with you.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Do not promote `None` as the first argument to `filter` in documentation.

2018-03-06 Thread Kirill Balunov
2018-03-06 13:18 GMT+03:00 Chris Angelico :

> The identity function is:
>
> filter(lambda x: x, range(10))
>
> How is it consistent with truthiness? Exactly the same way the
> underlying object is. There's no requirement for the predicate
> function to return True or False - it's perfectly acceptable, for
> instance, to do this:
>
> filter(lambda x: x % 3, range(10))
>
> to eliminate all multiples of three.
>

Yes there is no reason to return True and False, but in the case of `None`
and `bool` under the hood there will be no difference and the form with
`bool` is much more readable.


>
> That said, though, any use of filter() that involves a lambda function
> should probably become list comps or genexps, so filter itself should
> only be used when there really IS a pre-existing function that does
> the job.


Filter is generally faster than list comprehension or generators.

%timeit [*filter(lambda x: x % 3, range(1000))]
100 µs ± 16.4 ns per loop (mean ± std. dev. of 7 runs, 1 loops each)

f = lambda x: x % 3

%timeit [*(f(i) for i in range(1000))]
132 µs ± 73.5 ns per loop (mean ± std. dev. of 7 runs, 1 loops each)

%timeit [f(i) for i in range(1000)]
107 µs ± 179 ns per loop (mean ± std. dev. of 7 runs, 1 loops each)


> So, for instance, you could strip out every occurrence of the
> string "0" with:
>
> filter(int, list_of_strings)
>
> And that still depends on the normal Python rules for boolification.
> If that's valid, then it should be just as viable to say
> "filter(identity-function, ...)", which is spelled "filter(None,
> ...)".
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Do not promote `None` as the first argument to `filter` in documentation.

2018-03-06 Thread Kirill Balunov
2018-03-06 14:17 GMT+03:00 Steven D'Aprano <
steve+comp.lang.pyt...@pearwood.info>:

> On Tue, 06 Mar 2018 11:52:22 +0300, Kirill Balunov wrote:
>
> > I propose to delete all references in the `filter` documentation that
> > the first argument can be `None`, with possible depreciation of `None`
> > as the the first argument - FutureWarning in Python 3.8+ and deleting
> > this option in Python 4.
>
> Even if we agreed that it is unfortunate that filter accepts None as an
> argument, since it does (and has done since Python 1.0) there is nothing
> to be gained by deprecating and removing it.
>
> Deprecating and removing it will break code that currently works, for no
> good reason; removing the documentation is unacceptable, as that makes it
> too difficult for people to find out what `filter(None, values)` does.
>

As I wrote, __possible depreciation__, I also do not see the point of just
breaking someone's code. But I didn't see any benefit to explicitly promote
`filter(None, iterable)` form in the documentation as a good style.


> > Instead, it is better to show an example with using
> > `filter(bool, iterable)` which is absolutely
> > equivalent, more readable, but a little bit slower.
>
> So long as `filter(None, ...)` is still documented, I don't mind what
> example is given.
>
> But the idiom `filter(None, ...)` is an old, common idiom, very familiar
> to many people who have a background in functional programming.
>

While this form familiar and common idiom for those who are familiar with
Python from versions < 2.3, before `bool` type was introduced. It looks
kinky for newcomers and not obvious at a glance. In functional programming
we use a predicate, and `None` does not match predicate definition, while
`bool` does!


> It is unfortunate that filter takes the arguments in the order it does.
> Perhaps it would have been better to write it like this:
>
> def filter(iterable, predicate=None):
> ...
>
>
> Then `filter(values, None)` would be a standard Python idiom, explicitly
> saying to use the default predicate function. There is no difference to
> `filter(None, values)` except the order is (sadly) reversed.
>

If such a form was in Python, I probably would agree with you. Although in
its present form I like it a lot more and find it more intuitive.

> Currently documentation for `None` case uses `identity function is
> > assumed`, what is this `identity` and how it is consistent with
> > truthfulness?
>
> The identity function is a mathematical term for a function that returns
> its argument unchanged:
>
> def identity(x):
> return x
>
> So `filter(func, values)` filters according to func(x); using None
> instead filters according to x alone, without the expense of calling a do-
> nothing function:
>
> # slow because it has to call the lambda function each time;
> filter(lambda x: x, values)
>
> # fast because filter takes an optimized path
> filter(None, values)
>


> Since filter filters according to the truthy or falsey value of x, it
> isn't actually necessary to call bool(x). In Python, all values are
> automatically considered either truthy or falsey. The reason to call
> bool() is to ensure you have a canonical True/False value, and there's no
> need for that here.


I went over a bit with the question what is identity function :) But I have
a feeling that I perceive all of the above quite the contrary in the
context of a `filter` function. And since filter filters according to the
truthy or falsey value of x. `None` and `bool` should behave totally
equivalent under the hood and I'm 99% sure that it is so.


> So the identity function should be preferred to bool,
> for those who understand two things:
>
> - the identity function (using None as the predicate function)
>   returns x unchanged;
>

Sorry, but how does the above relates to the `filter` discussion?


>
> - and that x, like all values, automatically has a truthy value in a
>   boolean context (which includes filter).
>
>
Yes, and that is why there is no point to `None` since they will do the
same thing in context of `filter` function.


> > In addition, this change makes the perception of `map` and `filter` more
> > consistent,with the rule that first argument must be `callable`.
>
> I consider that a flaw in map. map should also accept None as the
> identity function, so that map(None, iterable) returns the values of
> iterable unchanged.
>
> def map(function=None, *iterables):
> if len(iterables) == 0:
> raise TypeError("map() must have at least two arguments.")
> if function is None:
> if len(iterables) > 1:
> return zip(*iterables)
> else:
>

Re: Ways to make a free variable local to a function?

2018-03-06 Thread Kirill Balunov
 2018-03-05 21:44 GMT+03:00 Terry Reedy :

> Yes, what we really want for this sort of thing are unrebindable local
> constants.  A simple syntax change could do it.
>
>  def func_local_1(numb; int = int, float = float, range = range):
>
> The binding after ';' belong in the header because they should be done
> once.
>
> They'd then
>> be bound at either compile time or function definition time (by
>> default the former, I think, but the latter would be more useful), and
>> be looked up as quickly as locals. I'm not sure how useful this would
>> be, though.
>>
>
> I believe that the occasional practice of re-binding built-in names to
> locals can be shown to speed up loops run enough times.


Yes "_unrebindable local constants_" it is what I was thinking about. But I
do not agree that they must be passed through arguments, because they
should be somewhat static for a function, and could not be changed by any
means after function is compiled.
Alternative option, more dynamic - to allow injecting local variables into
the function via some interface. Currently, there is no such _feature_ in
Python, at least I do not know. There was _somewhat_ related discussion
about how to change the locals of a frame (https://bugs.python.org/
issue1654367) by making `frame.f_locals` writable, but it seems that it is
dead.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Ways to make a free variable local to a function?

2018-03-06 Thread Kirill Balunov
2018-03-05 17:34 GMT+03:00 Chris Angelico :

> In theory, the CPython bytecode compiler (don't know about other
> Python implementations) could just add these as constants. They'd then
> be bound at either compile time or function definition time (by
> default the former, I think, but the latter would be more useful), and
> be looked up as quickly as locals. I'm not sure how useful this would
> be, though.
>

With some assumptions, It will be useful for every function call:-)

If PEP 572 [1] were to be accepted, you could do something like this:
>
> def func(numb):
> if ((int as int), (float as float)):
> res = []
> for i in range(numb):
> res.append(int(i) + float(i))
> return res
>
> Syntactically a bit clunky, but keeps everything inside the function,
> and DOES create local variables. Not sure it's better than your other
> options, but it is another option.
>

While I'm +0.5 on yours PEP 572 idea, especially in `while` and `if`
statements, this example is an overuse of the proposed syntax ;-) Also it
will add an overhead on every function call, and as you said  -
"Syntactically a bit clunky".

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Do not promote `None` as the first argument to `filter` in documentation.

2018-03-06 Thread Kirill Balunov
This thought occurred to me several times, but I could not decide to write.
And since `filter` is a builtin, I think this change should be discussed
here, before opening an issue on bug tracker.

I propose to delete all references in the `filter` documentation that the
first argument can be `None`, with possible depreciation of `None` as the
the first argument - FutureWarning in Python 3.8+ and deleting this option
in Python 4. Personally, regarding the last point - depreciation, I do not
see this as a great necessity, but I do not find that the option with `None`
should be offered and suggested through the documentation. Instead, it is
better to show an example with using `filter(bool, iterable)` which is
absolutely
equivalent, more readable, but a little bit slower.

%timeit [*filter(None, range(10))]
503 ns ± 0.259 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit [*filter(bool, range(10))]
512 ns ± 1.09 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

Currently documentation for `None` case uses `identity function is
assumed`, what is this `identity` and how it is consistent with
truthfulness?

In addition, this change makes the perception of `map` and `filter` more
consistent,with the rule that first argument must be `callable`.

I see only one moment with `None`, since `None` is a keyword, the behavior
of `filter(None, iterable)` is alsways guaranteed, but with `bool` it is
not. Nevertheless, we are all adults here.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Ways to make a free variable local to a function?

2018-03-05 Thread Kirill Balunov
Hi,

At the moment, in order to slightly speed up the function in Python, free
variables are passed as local variables to the function, thereby getting
rid of extra look ups. For example, for the following function, I
especially do not use list comprehension) and therefore maybe it's not the
best example:

def func(numb):
res = []
for i in range(numb):
res.append(int(i) + float(i))
return res

You can get rid of additional look ups, in the following ways:


# 1. By passing through local variable's default values

def func_local_1(numb, _int = int, _float = float, _range = range):
res = []
for i in _range(numb):
res.append(_int(i) + _float(i))
return res


# 2. Through importing them into the function scope

def func_local_2(numb):
from builtins import int, float, range
res = []
for i in range(numb):
res.append(int(i) + float(i))
return res


# 3. With the help of various types of closures, version 1

def func_closure_1(numb):
_int = int
_float = float
_range = range
def inner(numb):
res = []
for i in _range(numb):
res.append(_int(i) + _float(i))
return res
return inner(numb)


# 4. With the help of various types of closures, version 2

def func_closure_2(numb):
from builtins import int, float, range
def inner(numb):
res = []
for i in range(numb):
res.append(int(i) + float(i))
return res
return inner(numb)

Option 1 allows you to achieve the maximum result for both small and a
large `numb` values. Option 2 yields a significant overhead, when it is
required to call function many times with a small number of iterations. For
option 3 and 4, notes are the same, but since they are implemented through
closures they give additional small overhead. In case of big `numb` (many
iterations, many look ups) these options give a gain of ~10%.

Option 1 and 3 I do not like because:
 - syntax highlighting stops working
 - the signature function is greatly distorted
 - additional typing (especially with type annotations)

I like options 2 and 4, but they yield a significant overhead, for a small
number of iterations.

Actually, I have the following question:

1. Is there any other way to make the variable local to the function?
 a. When you compile (define) a function...
 b. Inject into an already existing function through decorator...(is it
possible?)

p.s.:

I had the following idea, maybe it was already discussed, the possibility
of setting _static_ variables for functions, with the following syntax:

def func(numb):
static int, float, range
res = []
for i in range(numb):
res.append(int(i) + float(i))
return res

Where identifiers for `static` should correspond to free variables for a
function, they must be defined at compile time (like for default arguments)
and can not be changed inside the function scope.

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there are good DRY fix for this painful design pattern?

2018-02-27 Thread Kirill Balunov
Of course you can do the same without annotations, but with the
introduction of private attribute while your API it is under active
development:

from functools import wraps
def validate(func):
@wraps(func)
def _wrap(self, *args, **kwargs):
variables = self._vars   # Here
kwargs.update(zip(variables, args))
for var in variables - kwargs.keys():
kwargs[var] = getattr(self, var)
return func(self, **kwargs)
return _wrap

class Foo:
def __init__(self, bashful, doc, dopey, grumpy,
   happy, sleepy, sneezy):
self.bashful = bashful
self.doc = doc
self.dopey = dopey
self.grumpy = grumpy
self.happy = happy
self.sleepy = sleepy
self.sneezy = sneezy
self._vars = set(v for v in self.__dict__ if not
v.startswith('_'))   # should be deleted when finish

@validate
def spam(self, bashful=None, doc=None, dopey=None,
   grumpy=None, happy=None, sleepy=None,
   sneezy=None):

return bashful, doc, dopey, grumpy, happy, sleepy, sneezy

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there are good DRY fix for this painful design pattern?

2018-02-27 Thread Kirill Balunov
This validation can be also done with the use of annotations, while I find
it super awful, I put this for one more example:

from functools import wraps
def validate(func):
@wraps(func)
def _wrap(self, *args, **kwargs):
variables = func.__annotations__.keys()
kwargs.update(zip(variables, args))
for var in variables - kwargs.keys():
kwargs[var] = getattr(self, var)
return func(self, **kwargs)
return _wrap


class Foo:
def __init__(self, bashful, doc, dopey, grumpy,
   happy, sleepy, sneezy):
self.bashful = bashful
self.doc = doc
self.dopey = dopey
self.grumpy = grumpy
self.happy = happy
self.sleepy = sleepy
self.sneezy = sneezy

@validate
def spam(self, bashful:'Any'=None, doc:'Any'=None, dopey:'Any'=None,
   grumpy:'Any'=None, happy:'Any'=None, sleepy:'Any'=None,
   sneezy:'Any'=None):

return bashful, doc, dopey, grumpy, happy, sleepy, sneezy


a = Foo(1,2,3,4,5,6,7)

a.spam(grumpy='Hello')

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Questions about `locals` builtin

2018-02-27 Thread Kirill Balunov
 2018-02-27 14:59 GMT+03:00 Ned Batchelder <n...@nedbatchelder.com>:

> On 2/27/18 3:52 AM, Kirill Balunov wrote:
>
>> a.  Is this restriction for locals desirable in the implementation of
>> CPython in Python 3?
>> b.  Or is it the result of temporary fixes for Python 2?
>>
>
> My understanding is that the behavior of locals() is determined mostly by
> what is convenient for the implementors, so that they can keep regular code
> running as quickly as possible.  The answer to the question, "why can't we
> make locals() work more like I expect?" is, "because that would make things
> slower."
>

Ok, but I in this case what is the benefit in Python 3.3+ in returning a
copy of dict instead of MappingProxy?

Personally, I find the convenient functionality to update the local symbol
>> table inside a function, similar to `globals`.
>>
>
> Can you show us an example of why you would want to update locals through
> locals()?  There might be more natural ways to solve your problem.
>
>
The example from "Is there are good DRY fix for this painful design
pattern?" https://mail.python.org/pipermail/python-list/2018-
February/731218.html

class Foo:
def __init__(self, bashful, doc, dopey, grumpy,
   happy, sleepy, sneezy):
self.bashful = bashful  # etc

def spam(self, bashful=None, doc=None, dopey=None,
   grumpy=None, happy=None, sleepy=None,
   sneezy=None):
if bashful is None:
bashful = self.bashful
if doc is None:
doc = self.doc
if dopey is None:
dopey = self.dopey
if grumpy is None:
grumpy = self.grumpy
if happy is None:
happy = self.happy
if sleepy is None:
sleepy = self.sleepy
if sneezy is None:
sneezy = self.sneezy
# now do the real work...

def eggs(self, bashful=None, # etc...
   ):
if bashful is None:
bashful = self.bashful
# and so on

and with the possibility to update  `locals` the `spam` can be rewritten
with:

def spam(self, bashful=None, doc=None, dopey=None,
   grumpy=None, happy=None, sleepy=None,
   sneezy=None):
loc = locals()
for key, val in loc.items():
if val is None:
loc[key] = getattr(self, key)

In fact, I do not have a strict opinion on this matter. And I'd rather be
glad that Pнthon was less dynamic in some moments in favor of some
optimizations.


With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Questions about `locals` builtin

2018-02-27 Thread Kirill Balunov
 2018-02-27 2:57 GMT+03:00 Terry Reedy :

> The point of point 3 is that terminology and details would likely be
> different if Python were freshly designed more or less as it is today, and
> some things only make more or less sense in historical context. Learn what
> you need to know to write code that works.
>

Thank you, I'm fairly familiar with the scope and namespace concepts in
Python 3, and they are also very well described in the "Execution model"
https://docs.python.org/3/reference/executionmodel.html#execution-model,
for this special thanks to the person who wrote it ;-)

I started using Python with СPython 3.5 and I'm not familiar with the
Python 2 features. But since Python 2 got into our discussion, I still have
a question:

a.  Is this restriction for locals desirable in the implementation of
CPython in Python 3?
b.  Or is it the result of temporary fixes for Python 2?

Personally, I find the convenient functionality to update the local symbol
table inside a function, similar to `globals`. Of course, I do not have the
full picture and the difficulties with the flaws in implementing such
functionality in CPython3. On the other hand, I understand that this
additional dynamism as a whole may not be beneficial, and that local and
global variables are determined at function compilation time. At this
point, I only know one way to achieve this: `exec ('% s =% s'% (var_name,
var_val))`, which I find clumsy enough. Funny, contradictory thoughts in my
head :)

Calling surrounding function local names collectively 'nonlocals' is the
> result of months of bikeshedding.
>

Yes `nonlocals` is a cool fix in Python3.

  2018-02-27 3:25 GMT+03:00 Steven D'Aprano :

> Mostly because locals() predates MappingProxyType by many years, and also
> because that restriction doesn't apply to other implementations of Python
> such as Jython and IronPython.
>
> In CPython, the dict returned by locals() is a copy of the local
> namespace, so modifying the dict doesn't modify the real local variables.
>
> (Well, sometimes it does, but not always. The story in Python 2 is really
> complex.)

Yes, I understand all the more the documentation specifies *New in version
3.3: class.MappingProxyType.* I'm not saying that this should be a standard
for the Python language, especially in the context of what I wrote above.
But the Python documentation already contains links to the features of the
CPython implementation, (`id` for example). If the answer to the previous
question is "Yes, such a restriction is desirable in CPython because,
because, because ... and thereafter it is not planned to be changed." Then
I do not see why it can not be made more explicit by changing `dict` to`
types.MappingProxyType`. With the following change in the documentation:

"Note
The contents of this dictionary should be perceived as read-only mapping
and should not be modified; The returned mapping type is
implementation-dependent: changes may not affect the values of local
variables used by the interpreter or the returned object may not support
item assignment.

CPython implementation detail: The returned object is
`types.MappingProxyType` a read-only proxy of the current local symbol
table."

p.s.: Steven, this question was somewhat inspired by yours "Is there are
good DRY fix for this painful design pattern?"

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Implicit conversion to str in str.join method?

2018-02-26 Thread Kirill Balunov
>
> print(*iterable, sep=", ")


Thanks, I apologize :-) and why I always manage to find complicated ways...

With kind regards,
-gdg

2018-02-26 22:43 GMT+03:00 Chris Angelico <ros...@gmail.com>:

> On Tue, Feb 27, 2018 at 6:38 AM, Kirill Balunov <kirillbalu...@gmail.com>
> wrote:
> > Currently `str.join` raises `TypeError` if there are any non-string
> values
> > in iterable, including `bytes` objects. Is it an awful idea to implicitly
> > _cast_ elements in iterable to their `str` or `repr` representation? Was
> > this question adressed before?
> >
> > As for me there are two valid points: On one hand "Explicit is beter than
> > implicit" and on the other "Practicality beats purity". May be I'm the
> only
> > one who finds that it is rather boring to write somehting like:
> >
> > ", ".join(str(i) for i in iterable)
> >
> > when iterable contains non-string values, instead of:
> >
> > ", ".join(iterable)
> >
> > I don't know how much overhead will yield for the case when iterable
> > contains only strings...and if it is possible to optimize this case. This
> > change is backward compatible, but as I wrote above, it can be perceived
> > badly and yield a huge overhead for general case that it is not even
> worth
> > discussing. What do you think?
>
> This would be a perfect job for map.
>
> ", ".join(map(str, iterable))
>
> If this is for display, you could also just print the values directly:
>
> print(*iterable, sep=", ")
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Implicit conversion to str in str.join method?

2018-02-26 Thread Kirill Balunov
Currently `str.join` raises `TypeError` if there are any non-string values
in iterable, including `bytes` objects. Is it an awful idea to implicitly
_cast_ elements in iterable to their `str` or `repr` representation? Was
this question adressed before?

As for me there are two valid points: On one hand "Explicit is beter than
implicit" and on the other "Practicality beats purity". May be I'm the only
one who finds that it is rather boring to write somehting like:

", ".join(str(i) for i in iterable)

when iterable contains non-string values, instead of:

", ".join(iterable)

I don't know how much overhead will yield for the case when iterable
contains only strings...and if it is possible to optimize this case. This
change is backward compatible, but as I wrote above, it can be perceived
badly and yield a huge overhead for general case that it is not even worth
discussing. What do you think?

With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Questions about `locals` builtin

2018-02-26 Thread Kirill Balunov
Hi,

I am a little bit confused with `locals` builtin in these moments:

1. The documentation says that _free varaibles_ are returned, which seems
incorrect description. In my mind the term free variable refers to
variables used in a function that are not local variables nor parameters of
that function.

In docs: "Update and return a dictionary representing the current local
symbol table. Free variables are returned by `locals()` when it is called
in function blocks, but not in class blocks."

>>> def func():

b = 12

print(locals(), ' : ', id(locals))

c = 13

print(locals(), ' : ', id(locals))


>>> print("Free variables: ", func.__code__.co_names)
>>> print("Local variables: ", func.__code__.co_varnames)

Free variables: ('print', 'locals', 'id')
Local variables: ('b', 'c')


2. The documentation has a note that "The contents of this dictionary
should not be modified". Which implies that it is a read only mapping. So
the question why it is `dict` instead of `types.MappingProxyType`?

3. There is one more moment: local variables had been determined when
function was compiled. But `locals` returns _some_ current runtime copy. I
find this also confusing:


>>> def func1():

loc = locals()

b = 12

return loc


>>> def func2():

b = 12

loc = locals()

return loc


>>> func1()
{ }
>>> func2()
{'b': 12}


With kind regards,
-gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


[issue32910] venv: Deactivate.ps1 is not created when Activate.ps1 was used

2018-02-22 Thread Kirill Balunov

Kirill Balunov <kirill.balu...@gmail.com> added the comment:

Yes, I agree, I did not understand the documentation correctly. It seems to me 
that the problem in the perception arose because of the fact that "deactivate" 
is not formatted as shell command, while `Deactivate.ps1` and others are. So I 
think simple formatting will be enough.

Also, it is not mentioned in the documentation that it is possible to activate 
environment in Powershell with "Drive:\> \Scripts\activate", but maybe 
it's not always true and I have nowhere to check.

--

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



[issue32910] venv: Deactivate.ps1 is not created when Activate.ps1 was used

2018-02-22 Thread Kirill Balunov

Kirill Balunov <kirill.balu...@gmail.com> added the comment:

Sorry, `deactivate` works in both cases `Scripts/Activate.ps1` and 
`Scripts/activate`. Only `Deactivate.ps1` is not created for the former, but 
the docs says that it should.

--

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



[issue32910] venv: Deactivate.ps1 is not created when Activate.ps1 was used

2018-02-22 Thread Kirill Balunov

New submission from Kirill Balunov <kirill.balu...@gmail.com>:

There was a related issue, which was closed https://bugs.python.org/issue26715.

If virtual environment was activated using Powershell script - Activate.ps1, 
the Deactivate.ps1 was not created, while the documentation says that it should.

"You can deactivate a virtual environment by typing “deactivate” in your shell. 
The exact mechanism is platform-specific: for example, the Bash activation 
script defines a “deactivate” function, whereas on Windows there are separate 
scripts called deactivate.bat and Deactivate.ps1 which are installed when the 
virtual environment is created."

Way to reproduce under Windows 10, Python 3.6.4

1. Open elevated Powershell (Administrator access).
2. Activate virtual environment using Activate.ps1.
3. There is no Deactivate.ps1

Also, when the environment was activated with Activate.ps1, `deactivate` will 
not work. On the other hand, if the environment was activated simply with 
`activate` (it works) in Powershell, `deactivate` will also work.

--
components: Windows
messages: 312551
nosy: godaygo, paul.moore, steve.dower, tim.golden, zach.ware
priority: normal
severity: normal
status: open
title: venv: Deactivate.ps1 is not created when Activate.ps1 was used
type: behavior
versions: Python 3.6

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



Re: Python on Android?

2018-02-18 Thread Kirill Balunov
To mention another way to use Python on Android is Termux project
.  From their site - Termux is an *Android terminal
emulator and Linux environment app* that works directly with no rooting or
setup required and Python is a side-effect. There are still some
restrictions but in general you can install everything you want. I even ran
Jupyter notebook, but on the phone it is certainly a mockery :)

With kine regards,
-gdg

2018-02-18 19:57 GMT+03:00 Johannes Findeisen :

> On Sun, 18 Feb 2018 20:57:02 +1100
> Chris Angelico wrote:
>
> > Does anyone have experience with running Python scripts on Android
> > phones? I have a brother (honestly! I'm not actually using a phone
> > myself!) who's trying to run one of my scripts in QPython, which
> > claims to be version 3.2.2. I think that really truly is a Python 3.2
> > implementation - probing for newer features suggests that it actually
> > doesn't even support the u"..." syntax that came (back) in with Python
> > 3.3. So... does anyone know of a Python interpreter that's compatible
> > with 3.4 or better and runs on Android?
> >
>
> There is an App for Android called "Pydroid 3". You can find it in
> the Google Play Store [0]. It provides a Python interpreter in version
> 3.6.2 in its current release.
>
> The Python binary is installed under
>
> /data/user/0/ru.iiec.pydroid3/files/arm-linux-androideabi/bin/python
>
> but I can not access it in a normal terminal without being user "root"
> but it is usable from within the terminal included in the Pydroid App.
>
> I do only execute some basic Python stuff for fun and learning when
> traveling but that should work as you can open and save your code from
> the integrated editor.
>
> Johannes
>
> [0] https://play.google.com/store/apps/details?id=ru.iiec.pydroid3
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


[issue28685] Optimizing list.sort() by performing safety checks in advance

2018-01-28 Thread Kirill Balunov

Kirill Balunov <kirill.balu...@gmail.com> added the comment:

What is the current status of this issue and will it go into Python 3.7?

--
nosy: +godaygo

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



Re: python to C code generator

2018-01-23 Thread Kirill Balunov
You can look at SymPy code generator
http://docs.sympy.org/latest/modules/utilities/codegen.html
Perhaps this is exactly what you need.

With kind regards,
-gdg

2018-01-23 17:00 GMT+03:00 Ned Batchelder :

> On 1/23/18 8:48 AM, kushal bhattacharya wrote:
>
>> On Tuesday, January 23, 2018 at 7:05:02 PM UTC+5:30, bartc wrote:
>>
>>> On 23/01/2018 13:23, kushal bhattacharya wrote:
>>>
 On Wednesday, January 17, 2018 at 4:34:23 PM UTC+5:30, kushal
 bhattacharya wrote:

> Hi,
> Is there any python framework or any tool as  which can generate C
> code from python code as it is .
>
> Thanks,
> Kushal
>
 yes i have but it generates a complex C code with python dependencies.I
 want to call the generated function from another C code but i Cant figure
 out how to do that

>>> Because the translation isn't simply defined.
>>>
>>> I've just tried nuitka on the Python code 'a=b+c', and it generates 2400
>>> lines of C. The main purpose seems to be to generate a self-contained
>>> executable corresponding to the Python, but generating first a C
>>> equivalent then using a C compiler and linker.
>>>
>>> This equivalent code may just contain all the bits in CPython needed to
>>> do the job, but bypassing all the stuff to do with executing actual
>>> byte-code. But it also seems to do some optimisations (in the generated
>>> C before it uses C compiler optimisations), so that if static types can
>>> be inferred it might make use of that info.
>>>
>>> Perhaps you simply want to use Python syntax to write C code? That would
>>> be a different kind of translator. And a simpler one, as 'a=b+c'
>>> translates to 'a+b+c;' in C.
>>>
>>> --
>>> bartc
>>>
>>
>> This is exactly what i meant to say.My goal is to translate the python
>> code into its C equivalent with function name as it is.
>>
>
> The best way to do that is to read the Python code, understand what it
> does, and re-write it in C.  You won't find an automatic tool that can do
> the job you want.  The semantics of Python and C are too different.
>
> --Ned.
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Creation of a metaclass for dataclass.

2017-12-29 Thread Kirill Balunov
I'm studying the meta-programming topic in Python, and as an exercise I'm
trying to make a somewhat simplified version of dataclass. My goal in this
exercise is to make the difference between annotated variables and usual
ones to be as much transparent as possible. So I come with this code to
obtain initial fields. It does not catch corner cases and as much as
possible undressed to be short. So my question is there any visible
pitfalls or am I doing something wrong from the early beginning?

Two helpful functions not to clutter `__annotations__`:

from typing import Any
AnyType = Any

def _is_not_dunder(name):
return not ((len(name) > 4) and (name[:2] == name[-2:] == '__'))

def _is_not_descriptor(obj):
return not (hasattr(obj, '__get__') or
hasattr(obj, '__set__') or
hasattr(obj, '__delete__'))

The special dict (class namespace) to inject usual variables in `
__annotations__` with default typehint - `AnyType`, and also keep their
ordered appearance in the class body.

class SpecialDict(dict):
def __init__(self):
super().__init__()
super().__setitem__('__annotations__', {})

def __setitem__(self, key, value):
if not (key in self) and _is_not_dunder(key) and
_is_not_descriptor(value):
self['__annotations__'][key] = AnyType
super().__setitem__(key, value)

Data meta-class which defines `__fields` from `__annotations__`:

class DataMeta(type):
@classmethod
def __prepare__(metacls, cls, bases, **kwargs):
_dict = SpecialDict()
return _dict

def __init__(cls, *args , **kwargs):
super().__init__(*args)

def __new__(metacls, cls, bases, clsdict):
clsdict['__fields'] = tuple(clsdict['__annotations__'].items())
_cls = type.__new__(metacls, cls, bases, clsdict)
return _cls

And test class:

class MyClass(metaclass=DataMeta):
a: float
barattr: int = 2
jik = 12
bzik: int =14

def foo(self, param):
pass

data = MyClass()

a.__fields   # (('a', float), ('barattr', int), ('jik', typing.Any),
('bzik', int))


Thank you!

With kind regards, -gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Default annotations for variables

2017-12-27 Thread Kirill Balunov
2017-12-27 14:19 GMT+03:00 Kirill Balunov <kirillbalu...@gmail.com>:

> Here I was a bit knocked down by the IPython console. Strangely, but the `
> __annotations__` is not initialized to a an empty dict when you start it,
> while in Python console it is.
>

In addition, there are some imbalance without IPython. Since modules and
classes define namespaces it is strange that:

empty `module` -> has `__annotations__` defined to {}.
empty `class` -> does not have `__annotations__` raises AttributeError.

With kind regards, -gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Default annotations for variables

2017-12-27 Thread Kirill Balunov
2017-12-27 13:54 GMT+03:00 Chris Angelico :

> This won't work. When you say "a.__type__", it means "take the *value*
> referenced by a, and look up its __type__ attribute". So it's
> equivalent to writing:
>
> (11).__type__
> (12).__type__
>

Thank you for clarification, I understand that names don't have attributes
:). But I did not find the right words to describe the idea.


> To query something about the *variable*, you have to look at its
> enclosing namespace. If these are at top level, you'd be looking at
> the module-level __annotations__ dictionary. That's also where
> x.__type__ would be - it's actually stored in __annotations__["x"].
>

Here I was a bit knocked down by the IPython console. Strangely, but the `
__annotations__` is not initialized to a an empty dict when you start it,
while in Python console it is.


> There is definitely room to ask the question "can we get default
> annotations for any global or class-level name that gets assigned to
> without an annotation?". I fully expect that thread to be one of those
> gigantic ones, but have fun :)
>

Yes this is exactly what I was about to ask :)

With kind regards, -gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Default annotations for variables

2017-12-27 Thread Kirill Balunov
Will there be any implications (or is it possible) if all variables will
have an attribute *something like* `__type__` which by default will be
initialized to *something like* `AnyType`. So in the case `x = 12` will be
equivalent to `x: AnyType = 12`.

x: int
x = 12
x.__type__ # int

a, b = 11, 12
a.__type__  # AnyType
b.__type__  # AnyType

And also in this case:

class Dummy:
a: int
b: float
c = []

Dummy.__annotations__  # will be {'a': int, 'b': float, 'c': AnyType}


While I ask purely out of curiosity, I think this is not an off-topic for
python-list.

With kind regards, -gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Using the variable type annotation syntax as a placeholder in a nonlocal scope?

2017-12-22 Thread Kirill Balunov
Any suggestions? Thank you.

With kind regards, -gdg

On Dec 20, 2017 22:43, "Kirill Balunov" <kirillbalu...@gmail.com> wrote:

> I've asked the same question on StackOverflow, but it seems to me that it
> is opinion based and will be ignored. So I ask for advice here:
>
> Since PEP 526 -- Syntax for Variable Annotations
> <https://www.python.org/dev/peps/pep-0526/>  was approved, in Python 3.6+
> it is possible to provide type hint information in the form *x: int*,
> also the PEP says "However, annotating a local variable will cause the
> interpreter to always make it local to the scope and leaves the variable
> uninitialized". Therefore in Python 3.6+ it is syntactically legal to
> write:
>
> def outer():
> x: int
> def inner():
> nonlocal x
> x = 10
> inner()
> print(x)
>
> while the above snippet is semantically more equivalent to:
>
> def outer():
> #x
> def inner():
> nonlocal x
> x = 10
> inner()
> print(x)
>
> Which is obviously a *SyntaxError: no binding for nonlocal 'x' found`*,
> sorry for the pun. Also there is nothing said about this style in PEP 8 and
> Python 3.6 docs. So should I consider this as a bug, or an implementation
> detail (side effect), or a wart, or a feature?
>
> To clarify the purpose of the question - we can not come to a consensus
> and I would like to hear your opinion and possible pitfalls, if any, if we
> choose to use this form in our codebase.
>
> With kind regards, -gdg
>
>
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Problem with assignment. Python error or mine?

2017-12-21 Thread Kirill Balunov
2017-12-21 22:06 GMT+03:00 John Ladasky :

> On Thursday, December 21, 2017 at 7:37:39 AM UTC-8, MRAB wrote:
>
> > Python never makes a copy unless you ask it to.
> >
> > What x1=X does is make the name x1 refer to the same object that X
> > refers to. No copying.
>
> Well, except with very simple, mutable data types like scalars... compare
> this:
>

No copy means no copy, it is the rule! What you see is really new binding
operation under the hood.
'x=1; x += 1', means calculate x+1 and bind it to the same name. Compare it
to this example:


>>> tpl = ((1,2),(3,4))
>>> tpl += ((1,2),)
>>> tpl

((1, 2), (3, 4), (1, 2))


No copy, new binding to the same name :)


With kind regards, -gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Fwd: property decorator?

2017-12-21 Thread Kirill Balunov
2017-12-21 2:56 GMT+03:00 Irv Kalb :

> My questions about this are really historical.  From my reading, it looks
> like using an @property decorator is a reference to an older approach using
> a built in "property" function.  But here goes:
>
> 1) Why were these decorator names chosen?  These two names @property and
> @.setter don't seem to be very clear to me.  At a minimum, they don't
> match.  Wouldn't decorator names like @.getter and @.setter
> have been better - more explicit?
>
> 2)  Alternatively, if the getter was going to use the @property decorator,
> then it would seem complimentary  to have the decorator name for the
> associated setter function to have the word "property" in its also,
> something like @propertySetter.
>
> 3)  If I create a method with the @property decorator, is there anything
> else that is implied about the name of the method other than you can now
> refer to the . - which calls the appropriate method?  My
> guess/understanding is that in my example above, "salary" is considered the
> property name, which is how you would refer to it outside of the object.
> Inside the class, you use the property name as the name of both the setter
> and the getter methods.  Is that the right way to think about it?
>

There are nothing special with decorators, the are simply functions which
take at least one argument (of course they can be implemented as classes,
but lets make things simple), and *`@decorator*` is a syntactic sugar
for *`func
= decorator(func)`*. As I see it, the primary idea to introduce them in
Python was readability, and possibility for special syntax highlighting and
nothing more. To sum it up, while* `property*` is often used as a
decorator, the `*property`* built-in is actually a class. So it is not "*an
older approach using a built in "property" function*" but in reality it is
the same class as it was but can be applied with new decorator syntax. And
defined in stdlib as *`class property(fget=None, fset=None, fdel=None,
doc=None)`*.


Finally, it seems very odd to me that when you use the @property decorator
> and the @.setter, that both of the methods that are decorated
> need to have the same name (but of course different set of parameters.)  As
> a teacher, this seems like it would be an extremely difficult concept to
> get across to students, as this does not work the same way as other Python
> functions (and methods).  Without a decorator, the second function of the
> same name overrides an earlier function of the same name, as in this simple
> example:
>


This is not true, actually they all work the same way following *descriptor
protocol* - the mechanism behind properties, methods, static methods, and
others. It is not simple topic, but it essential, I will provide some
references which can help you to grasp:

Descriptor HowTo Guide 
brilliant tutorial by Raymond Hettinger, which is a part of official
documentation. It is very well written, but if you need more on this topic
this books helped me a lot:

"*Python in a Nutshell, 2E by Alex Martelli*" while this book covers Python
2.5, the key idea of descriptors was introduced as a part of new style
classes in Python 2.2.

"*Python Cookbook, 3E by David Beazley and Brian K. Jones*" covers Python 3
with a lot of practical examples.

"*Fluent Python by Luciano Ramalho*" especially Chapter 20, but my advise
to read the book sequentially.

With kind regards, -gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Using the variable type annotation syntax as a placeholder in a nonlocal scope?

2017-12-20 Thread Kirill Balunov
I've asked the same question on StackOverflow, but it seems to me that it
is opinion based and will be ignored. So I ask for advice here:

Since PEP 526 -- Syntax for Variable Annotations
  was approved, in Python 3.6+
it is possible to provide type hint information in the form *x: int*, also
the PEP says "However, annotating a local variable will cause the
interpreter to always make it local to the scope and leaves the variable
uninitialized". Therefore in Python 3.6+ it is syntactically legal to
write:

def outer():
x: int
def inner():
nonlocal x
x = 10
inner()
print(x)

while the above snippet is semantically more equivalent to:

def outer():
#x
def inner():
nonlocal x
x = 10
inner()
print(x)

Which is obviously a *SyntaxError: no binding for nonlocal 'x' found`*,
sorry for the pun. Also there is nothing said about this style in PEP 8 and
Python 3.6 docs. So should I consider this as a bug, or an implementation
detail (side effect), or a wart, or a feature?

To clarify the purpose of the question - we can not come to a consensus and
I would like to hear your opinion and possible pitfalls, if any, if we
choose to use this form in our codebase.

With kind regards, -gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


What is the future of the PEP 467?

2017-11-10 Thread Kirill Balunov
What is the future of the PEP 467 ("Minor API improvements for binary
sequences")? It was not accepted and was not rejected, although there was a
rather active discussion.

In addition to what is stated in the PEP, I would like to know your opinion
on the additional issue:
At present, the repr() and str() of bytes return the same thing - which
looks  more as "binary string". May be it is better if the repr() will
return "binary sequence" -> only escaped hex values. While the str()
representation would return the same thing as now (some ascii analogue)?

- with kind regards, gdg
-- 
https://mail.python.org/mailman/listinfo/python-list


Performance of map vs starmap.

2017-10-30 Thread Kirill Balunov
Sometime ago I asked this question at SO [1], and among the responses
received was paragraph:

 - `zip` re-uses the returned `tuple` if it has a reference count of 1 when
the `__next__` call is made.
 - `map` build a new `tuple` that is passed to the mapped function every
time a `__next__` call is made.

Why can not `map` use the same approach as `zip`?

Also it turns out that a faster solution looks not reasonable, since it
requires additional calculations..

[1] https://stackoverflow.com/questions/46172018/perfomance-
of-map-vs-starmap

Thanks,
- gdg
-- 
https://mail.python.org/mailman/listinfo/python-list