Just a reminder that 3.7.0b3 is almost upon us. Please get your
feature fixes, bug fixes, and documentation updates in before
2018-03-26 ~23:59 Anywhere on Earth (UTC-12:00). That's a little over
3.5 days from now.
IMPORTANT: We are now entering the final phases of 3.7.0. After the
tagging for 3.7.0b3, the intention is that the ABI for 3.7.0 is
frozen. After next week's 3.7.0b3, there will only be two more
opportunities planned for changes prior to 3.7.0 final:
- 2018-04-30 3.7.0 beta 4
- 2018-05-31 3.7.0 release candidate
As I've noted in previous communications, we need to start locking
down 3.7.0 so that our downstream users, that is, third-party package
developers, Python distributors, and end users, can test their code
with confidence that the actual release of 3.7.0 will hold no
unpleasant surprises. So after 3.7.0b3, you should treat the 3.7
branch as if it is already released and in maintenance mode. That
means you should only push the kinds of changes that are appropriate
for a maintenance release: non-ABI-changing bug and feature fixes and
documentation updates. If you find a problem that requires an
ABI-altering or other significant user-facing change (for example,
something likely to introduce an incompatibility with existing users'
code or require rebuilding of user extension modules), please make
sure to set the b.p.o issue to "release blocker" priority and describe
there why you feel the change is necessary. If you are reviewing PRs
for 3.7 (and please do!), be on the lookout for and flag potential
incompatibilities (we've all made them).
Thanks again for all of your hard work towards making 3.7.0 yet
another great release!
nad(a)python.org -- 
As the BDFL-Delegate, I’m happy to announce PEP 541 has been accepted.
PEP 541 has been voted by the packaging-wg (https://wiki.python.org/psf/
- Donald Stufft
- Dustin Ingram
- Ernest W. Durbin III
- Ewa Jodlowska
- Kenneth Reitz
- Mark Mangoba
- Nathaniel J. Smith
- Nick Coghlan
- Nicole Harris
- Sumana Harihareswara
Thank you to the packaging-wg and to everyone that has contributed to PEP
Mark Mangoba | PSF IT Manager | Python Software Foundation |
mmangoba(a)python.org | python.org | Infrastructure Staff:
infrastructure-staff(a)python.org | GPG: 2DE4 D92B 739C 649B EBB8 CCF6 DC05
E024 5F4C A0D1
I searched usages of is_integer() on GitHub and have found that it is
used *only* in silly code like (x/5).is_integer(), (x**0.5).is_integer()
(or even (x**(1/3)).is_integer()) and in loops like:
i = 0
while i < 20:
i += 0.1
(x/5).is_integer() is an awful way of determining the divisibility by 5.
It returns wrong result for large integers and some floats. (x % 5 == 0)
is a more clear and reliable way (or PEP 8 compliant (not x % 5)).
Does anybody know examples of the correct use of float.is_integer() in
real programs? For now it looks just like a bug magnet. I suggest to
deprecate it in 3.7 or 3.8 and remove in 3.9 or 3.10. If you even need
to test if a float is an exact integer, you could use (not x % 1.0). It
is even faster than x.is_integer().
I've made a custom concurrent.futures.Executor mixing the
ProcessPoolExecutor and ThreadPoolExecutor.
I've published it here:
This executor is very similar to a ProcessPoolExecutor, but each process in
the pool have it's own ThreadPoolExecutor inside.
The motivation for this executor is mitigate the problem we have in a
project were we have a very large number of long running IO bounded tasks,
that have to run concurrently. Those long running tasks have sparse CPU
To resolve this problem I considered multiple solutions:
1. Use asyncio to run the IO part as tasks and use a ProcessPoolExecutor
to run the CPU bounded operations with "run_in_executor". Unfortunately the
CPU operations depends on a large memory context, and using a
ProcessPoolExecutor this way force the parent process to picklelize all the
context to send it to the task, and because the context is so large, this
operation is itself very CPU demanding. So it doesn't work.
2. Executing the IO/CPU bounded operations in different processes with
multiprocessing.Process. This actually works, but the number of idle
processes in the system is too large, resulting in a bad memory footprint.
3. Executing the IO/CPU bounded operations in threads. This doesn't work
because the sum of all CPU operations saturate the core where the Python
process is running and the other cores are wasted doing nothing.
So I coded the ThreadedProcessPoolExecutor that helped me maintaining the
number of processes under control (I just have one process per CPU core)
allowing me to have a very high concurrency (hundreds of threads per
I have a couple of questions:
The first one is about the license. Given that I copied the majority of the
code from the concurrent.futures library, I understand that I have to
publish the code under the PSF LICENSE. Is this correct?
My second question is about the package namespace. Given that this is an
concurrent.futures.Executor subclass I understand that more intuitive place
to locate it is under concurrent.futures. Is this a suitable use case for
namespace packages? Is this a good idea?
There is the NEXT_BLOCK() macro in compile.c. It creates a new block,
creates an implicit jump from the current block to the new block, and
sets it as the current block.
But why it is used? All seems working if remove NEXT_BLOCK(). If there
was a need of NEXT_BLOCK() (if it reduces the computational complexity
of compilation or allows some optimizations), it should be documented,
and we should analyze the code and add missed NEXT_BLOCK() where they
are needed, and perhaps add new tests. Otherwise it can be removed.
I found a possible bug with ttk.Treeview widget.
I'm working on program that uses tkinter UI. I use ttk.Treeview to display
some objects and I want to use integer iid of items.
For example, I insert a row with treeview.insert(... iid=0, ...). But I
encountered a problem when I try to get this item from treeview by iid when
There is no item with such iid. This item has autogenerated iid just like
it's not specified.
I investigated problem and found that in ttk.py, Treeview.insert(...
iid=None, ...) in method's body has a check:
res = self.tk.call(self._w, "insert", parent, index,
"-id", iid, *opts)
res = self.tk.call(self._w, "insert", parent, index, *opts)
It means that if iid is "True" then use it else autogenerate it.
Maybe there should be "if iid is not None", not "if iid"? Or there are some
reasons to do check this way?