Argument Clinic "converters" specify how to convert an individual
argument to the function you're defining. Although a converter could
theoretically represent any sort of conversion, most of the time they
directly represent types like "int" or "double" or "str".
Because there's such variety in argument parsing, the converters are
customizable with parameters. Many of these are common enough that
Argument Clinic suggests some standard names. Examples: "zeroes=True"
for strings and buffers means "permit internal \0 characters", and
"bitwise=True" for unsigned integers means "copy the bits over, even if
there's overflow/underflow, and even if the original is negative".
A third example is "nullable=True", which means "also accept None for
this parameter". This was originally intended for use with strings
(compare the "s" and "z" format units for PyArg_ParseTuple), however it
looks like we'll have a use for "nullable ints" in the ongoing Argument
Clinic conversion work.
Several people have said they found the name "nullable" surprising,
suggesting I use another name like "allow_none" or "noneable". I, in
turn, find their surprise surprising; "nullable" is a term long
associated with exactly this concept. It's used in C# and SQL, and the
term even has its own Wikipedia page:
http://en.wikipedia.org/wiki/Nullable_type
Most amusingly, Vala *used* to have an annotation called "(allow-none)",
but they've broken it out into two annotations, "(nullable)" and
"(optional)".
http://blogs.gnome.org/desrt/2014/05/27/allow-none-is-dead-long-live-nullab…
Before you say "the term 'nullable' will confuse end users", let me
remind you: this is not user-facing. This is a parameter for an
Argument Clinic converter, and will only ever be seen by CPython core
developers. A group which I hope is not so easily confused.
It's my contention that "nullable" is the correct name. But I've been
asked to bring up the topic for discussion, to see if a consensus forms
around this or around some other name.
Let the bike-shedding begin,
//arry/
Here is some proposed wording. Since it is more of a clarification of what
it takes to garner support -- which is just a new section -- rather than a
complete rewrite I'm including just the diff to make it easier to read the
changes.
*diff -r 49d18bb47ebc pep-0011.txt*
*--- a/pep-0011.txt Wed May 14 11:18:22 2014 -0400*
*+++ b/pep-0011.txt Fri May 16 13:48:30 2014 -0400*
@@ -2,22 +2,21 @@
Title: Removing support for little used platforms
Version: $Revision$
Last-Modified: $Date$
-Author: martin(a)v.loewis.de (Martin von Löwis)
+Author: Martin von Löwis <martin(a)v.loewis.de>,
+ Brett Cannon <brett(a)python.org>
Status: Active
Type: Process
Content-Type: text/x-rst
Created: 07-Jul-2002
Post-History: 18-Aug-2007
+ 16-May-2014
Abstract
--------
-This PEP documents operating systems (platforms) which are not
-supported in Python anymore. For some of these systems,
-supporting code might be still part of Python, but will be removed
-in a future release - unless somebody steps forward as a volunteer
-to maintain this code.
+This PEP documents how an operating system (platform) garners
+support in Python as well as documenting past support.
Rationale
@@ -37,16 +36,53 @@
change to the Python source code will work on all supported
platforms.
-To reduce this risk, this PEP proposes a procedure to remove code
-for platforms with no Python users.
+To reduce this risk, this PEP specifies what is required for a
+platform to be considered supported by Python as well as providing a
+procedure to remove code for platforms with little or no Python
+users.
+Supporting platforms
+--------------------
+
+Gaining official platform support requires two things. First, a core
+developer needs to volunteer to maintain platform-specific code. This
+core developer can either already be a member of the Python
+development team or be given contributor rights on the basis of
+maintaining platform support (it is at the discretion of the Python
+development team to decide if a person is ready to have such rights
+even if it is just for supporting a specific platform).
+
+Second, a stable buildbot must be provided [2]_. This guarantees that
+platform support will not be accidentally broken by a Python core
+developer who does not have personal access to the platform. For a
+buildbot to be considered stable it requires that the machine be
+reliably up and functioning (but it is up to the Python core
+developers to decide whether to promote a buildbot to being
+considered stable).
+
+This policy does not disqualify supporting other platforms
+indirectly. Patches which are not platform-specific but still done to
+add platform support will be considered for inclusion. For example,
+if platform-independent changes were necessary in the configure
+script which was motivated to support a specific platform that would
+be accepted. Patches which add platform-specific code such as the
+name of a specific platform to the configure script will generally
+not be accepted without the platform having official support.
+
+CPU architecture and compiler support are viewed in a similar manner
+as platforms. For example, to consider the ARM architecture supported
+a buildbot running on ARM would be required along with support from
+the Python development team. In general it is not required to have
+a CPU architecture run under every possible platform in order to be
+considered supported.
Unsupporting platforms
----------------------
-If a certain platform that currently has special code in it is
-deemed to be without Python users, a note must be posted in this
-PEP that this platform is no longer actively supported. This
+If a certain platform that currently has special code in Python is
+deemed to be without Python users or lacks proper support from the
+Python development team and/or a buildbot, a note must be posted in
+this PEP that this platform is no longer actively supported. This
note must include:
- the name of the system
@@ -69,8 +105,8 @@
forward and offer maintenance.
-Resupporting platforms
-----------------------
+Re-supporting platforms
+-----------------------
If a user of a platform wants to see this platform supported
again, he may volunteer to maintain the platform support. Such an
@@ -101,7 +137,7 @@
release is made. Developers of extension modules will generally need
to use the same Visual Studio release; they are concerned both with
the availability of the versions they need to use, and with keeping
-the zoo of versions small. The Python source tree will keep
+the zoo of versions small. The Python source tree will keep
unmaintained build files for older Visual Studio releases, for which
patches will be accepted. Such build files will be removed from the
source tree 3 years after the extended support for the compiler has
@@ -223,6 +259,7 @@
----------
.. [1] http://support.microsoft.com/lifecycle/
+.. [2] http://buildbot.python.org/3.x.stable/
Copyright
---------
The current memory layout for dictionaries is
unnecessarily inefficient. It has a sparse table of
24-byte entries containing the hash value, key pointer,
and value pointer.
Instead, the 24-byte entries should be stored in a
dense table referenced by a sparse table of indices.
For example, the dictionary:
d = {'timmy': 'red', 'barry': 'green', 'guido': 'blue'}
is currently stored as:
entries = [['--', '--', '--'],
[-8522787127447073495, 'barry', 'green'],
['--', '--', '--'],
['--', '--', '--'],
['--', '--', '--'],
[-9092791511155847987, 'timmy', 'red'],
['--', '--', '--'],
[-6480567542315338377, 'guido', 'blue']]
Instead, the data should be organized as follows:
indices = [None, 1, None, None, None, 0, None, 2]
entries = [[-9092791511155847987, 'timmy', 'red'],
[-8522787127447073495, 'barry', 'green'],
[-6480567542315338377, 'guido', 'blue']]
Only the data layout needs to change. The hash table
algorithms would stay the same. All of the current
optimizations would be kept, including key-sharing
dicts and custom lookup functions for string-only
dicts. There is no change to the hash functions, the
table search order, or collision statistics.
The memory savings are significant (from 30% to 95%
compression depending on the how full the table is).
Small dicts (size 0, 1, or 2) get the most benefit.
For a sparse table of size t with n entries, the sizes are:
curr_size = 24 * t
new_size = 24 * n + sizeof(index) * t
In the above timmy/barry/guido example, the current
size is 192 bytes (eight 24-byte entries) and the new
size is 80 bytes (three 24-byte entries plus eight
1-byte indices). That gives 58% compression.
Note, the sizeof(index) can be as small as a single
byte for small dicts, two bytes for bigger dicts and
up to sizeof(Py_ssize_t) for huge dict.
In addition to space savings, the new memory layout
makes iteration faster. Currently, keys(), values, and
items() loop over the sparse table, skipping-over free
slots in the hash table. Now, keys/values/items can
loop directly over the dense table, using fewer memory
accesses.
Another benefit is that resizing is faster and
touches fewer pieces of memory. Currently, every
hash/key/value entry is moved or copied during a
resize. In the new layout, only the indices are
updated. For the most part, the hash/key/value entries
never move (except for an occasional swap to fill a
hole left by a deletion).
With the reduced memory footprint, we can also expect
better cache utilization.
For those wanting to experiment with the design,
there is a pure Python proof-of-concept here:
http://code.activestate.com/recipes/578375
YMMV: Keep in mind that the above size statics assume a
build with 64-bit Py_ssize_t and 64-bit pointers. The
space savings percentages are a bit different on other
builds. Also, note that in many applications, the size
of the data dominates the size of the container (i.e.
the weight of a bucket of water is mostly the water,
not the bucket).
Raymond
I'm updating the 2.7 release PEP with the following release dates
2.7.9rc1 Nov 22
2.7.9 final December 5
I expect PEPs 476 and 477 can be done by then?
Given that 2.7.9 has had some large changes, having multiple rcs is not
unlikely. Hopefully, we can get a final out by 2015, though.
New package manager from M$... article here
<http://www.neowin.net/news/windows-10-oneget-a-linux-style-package-manageme…>.
It seems doubtful that M$ will eliminate .msi (their obscure, hard to
configure and use, installation format), so it seems doubtful that the
addition of OneGet will _force_ any changes to Python packaging.
However, it does open the question in my mind about whether there will
be any _benefits_ of OneGet that would inspire helpful, useful changes
to Python packaging. They speak of "trusted repositories", and the like,
and it sounds like a the various *nix package managers (apt-get, et
alia), but perhaps allowing multiple repositories rather than just a
single source vendor repository (I'm actually not sure if *nix package
managers allow multiple repositories or not, but from the way people
talk about them, it always sounds like a "distribution" also provides "a
repository" of additional packages).
"trusted repositories" sounds more like Perl's CPAN.
One of the links
<http://blogs.technet.com/b/windowsserver/archive/2014/04/03/windows-managem…>
contains this quote: "This first version of OneGet installs and searches
software from Chocolatey repositories. Support of additional
repositories will come in subsequent versions."
I have no clue what a Chocolatey repository is (yet, will Google), but
unknown others will come, it says... whether it is possible to write a
"repository plugin" such that Perl's CPAN or Python's PyPI or other
preexisting repositories can be accessed is not clear.
The relationship between PowerShell and OneGet is not clear either... is
OneGet written in PowerShell, or is PowerShell just one way to invoke
OneGet, or???
Just a heads up.
Stephen J. Turnbull:
> Python is open source. Nobody is objecting to "somebody else" doing
> this.[1] The problem here is simply that some "somebody elses" are
> trying to throw future work over the wall into python-dev space.
If that's how it's seen at this point, then it sounds like the logical
course of action for CPython-with-MinGW is to demonstrate feasibility
in a fork. Get what currently works as a set of 80-something patches
and PKGBUILD instructions into a single repository that is usable by a
wider variety of people, in more distributions, etc. Set up as much CI as
possible so every patch gets tested in as many configurations as we can.
Experiment with extension compatibility and find out what is actually
achievable, with or without needing to modify MinGW-w64 in the process.
There are people, though evidently not much of python-dev, who have a
need and desire to make this happen. It seems python-dev would rather
have us spend zero time proposing changes that allow CPython itself to
be built differently than today, and all of our time on MinGW extensions.
I personally find 3 of the 4 combinations of how one could build CPython
and how one could build extensions interesting and worth looking into for
different reasons (the one that's uninteresting to me is the currently
used all-MSVC method, due to its many limitations I listed earlier).
Ray for example may only care about using MinGW for everything. Python's
a big community with lots of room for different people to work on
different aspects of the same set of problems.
For the combination of MSVC Python and MinGW extensions that most of you
have recommended we focus on, it would be more productive to engage with
setuptools, distutils-sig, and likely numpy as well, instead of python-dev.
My experience lies more in getting troublesome C codebases to build with
MinGW than it does with the messy intricacies and backwards-compatibility
requirements of Python extensions and package management however, so my
ability to contribute on that side of things is more limited. I'll just
note that every project I've ever had a patch for which improved
functionality with a new compiler (whether GCC, MSVC, clang, icc or ifort,
etc.) reacted with review and thanks for the patches, not "why do you want
to do this?" pushback. If potential contributors have a desire to get it
working in the first place, then they will also be invested in helping
keep it working on an ongoing basis.
Sincerely,
Tony
Hi,
At the end of August, I sent the PEP 475 which I wrote with
Charles-François Natali:
https://mail.python.org/pipermail/python-dev/2014-August/136077.htmlhttps://mail.python.org/pipermail/python-dev/2014-September/136101.html
Antoine Pitrou wrote " I'm +1 on the whole PEP" and R. David Murray
wrote "Personally, I really want Python to handle EINTR for me".
What's the next step? Who wants to handle this PEP? Guido? Antoine?
I will try to answer to questions if previous answers were not enough.
Antoine Pitrou wrote:
>> On Unix, the ``asyncio`` module uses the wakeup file descriptor to
>> wake up its event loop.
> How about Windows?
I modified signal.set_wakeup_fd() in Python 3.5 to support a socket on
Windows. So it becomes possible to support signals with
signal.set_wakeup_fd() on Windows (for SelectorEventLoop and
ProactorEventLoop):
https://code.google.com/p/tulip/issues/detail?id=191
Antoine Pitrou wrote:
>> Some signals are not interesting and should not interrupt the the
>> application. There are two options to only interrupt an application
>> on some signals:
>>
>> * Raise an exception in the signal handler, like ``KeyboardInterrupt`` for
>> ``SIGINT``
>> * Use a I/O multiplexing function like ``select()`` with the Python
>> signal "wakeup" file descriptor: see the function
>> ``signal.set_wakeup_fd()``.
>
> This section looks a bit incomplete. Some calls such as os.read() or
> os.write() will (should) return a partial result when interrupted and
> they already handled >0 bytes. Perhaps other functions have a similar
> behaviour?
In Python 3.4, os.read() is dummy: it only calls the C function read() once.
With the PEP 475, read() is only called again on EINTR if the signal
handler did not raise an exception. When read() returns EINTR, there
is "partial read", the read did not start yet.
So I don't understand what should be added to the PEP. There is no
specific change.
Matthew Woodcraft wrote:
> In any case I think PEP 475 should be explaining what is going to happen
> to signal.siginterrupt(). Will setting flag=True be supported? If so,
> will doing so change the behaviour of those parts of the stdlib which
> have already been modified to retry after EINTR?
In Python 3.4, signal.signal() calls siginterrupt(signum, True):
syscalls raise InterruptedError when interrupted by a signal. Calling
explicitly signal.siginterrupt(signum, True) doesn't change anything.
In Python 3.4, signal.siginterrupt(signum, False) reduces the cases
when InterruptedError is raised, but they are still cases when
InterruptedError is raised. The exact behaviour probably depends on
the operating system or even the version of the operating system. It's
better to not rely on siginterrupt(False) to write portable code in
Python 3.4.
With the PEP, signal.siginterrupt(signum, False) is still supported.
The PEP doesn't change the behaviour when the syscall is directly
restarted by the C library. If the function returns EINTR, the
interrupted syscall is retried if the signal handler didn't raise an
exception.
The main problem of siginterrupt(False) is that the Python signal
handler is *not* called if the C library directly retries the
interrupted syscall.
Note: if signals are blocked, the C signal handlers are not called, so
the PEP doesn't change the behaviour neither.
Victor wrote:
> I think that the stdlib should not handle InterruptedError exception
> anymore in the Python code, to simplify the code.
I modified the PEP to mention that:
https://hg.python.org/peps/rev/627fefe0394f
Victor
I'm several weeks late to this discussion, but I'm glad to see that it
happened. I'm not a Python developer, and barely a user, but I have several
years of daily experience compiling complicated scientific software cross-
platform, particularly with MinGW-w64 for Windows. The Python community,
both core language and scientific package developers and users, needs to
act here. The problem is bad and getting worse. Luckily much of the work
to start solving it has already been done in bits and pieces, it needs
coordination and participation to come to a conclusion.
> Cross compilation is a valid issue, but I hope that build services like
> Appveyor also help out here. There is regular talk about the PSF/PyPI
> providing something similar
AppVeyor is better than nothing (I've been using it since beta), but it's
a far cry from build services and package management as the Linux world
knows them. Obtaining and setting up build dependencies quickly and
repeatably, and finishing the build of a complicated piece of software
such as CPython, or NumPy, SciPy, Julia (where most of my recent expertise
lies), etc. on a small single-core VM with limited memory and a restrictive
time limit is often not possible. These problems are solved within Linux
infrastructure like Koji, Open Build Service, buildd, etc.
MinGW-w64 is a mature, well-tested toolchain that is very capable of cross-
compiling a wide variety of libraries from Linux to Windows, in addition to
building conventionally on Windows for Windows. The MSYS2 collection of
MinGW-w64-compiled packages (https://github.com/Alexpux/MINGW-packages) has
been mentioned. Linux distributions including
- Fedora https://admin.fedoraproject.org/pkgdb/packages/mingw%2A/
- openSUSE https://build.opensuse.org/project/show/windows:mingw:win32
- Arch https://aur.archlinux.org/packages/?K=mingw
and others have projects for providing many hundreds of open-source
packages compiled for Windows. Debian has the cross-compilers available but
not many packages yet (https://packages.debian.org/search?keywords=mingw).
As a developer of a (compiled) open-source library or application, wouldn't
you love to be able to build binaries on Linux for Windows? With some work
and build system patches, you can. For many projects it's a simple matter of
./configure --host=x86_64-w64-mingw32. Not with CPython though. CPython is
only included in 2 of the above MinGW-w64 distribution projects, MSYS2 and
Arch. This is possible with a very, very long set of patches, many of which
have been submitted by Roumen Petrov to the Python bug tracker - see
http://bugs.python.org/issue17605 and other issues linked therein. Roumen
has done a huge amount of work, and he and others who consider the MinGW-w64
compiler important will continue to do so. (Thanks a million Roumen!)
> I could step in as maintainer for Cygwin and builds based on GCC using
> mingw* APIs.
>
> Regards,
> Roumen Petrov
A maintainer has volunteered. Others will help. Can any core developers
please begin reviewing some of his patches? Even if just to say they need
to be rebased. The lack of responses on the bug tracker is disheartening
from an outside perspective. The pile of patches accumulating in external
MinGW packaging projects is tantamount to a fork of CPython. It won't go
away since there are dedicated packagers working to keep their MinGW-w64
builds functional, even in the ad-hoc current state. The patches continue
piling up, making it more difficult for everyone - except for the core
Python developers if they continue to ignore the problem. Bring the people
working on these patches into the fold as contributors. Review the patches.
It would make Python as a language and a community even more diverse and
welcoming.
> Deprecate/remove support for compiling CPython itself with compilers
> other than MSVC on Windows
I'm not alone in thinking that this would be a bad idea. MSVC can continue
to be the default compiler used for Python on Windows, none of Roumen's
patches change that. They would merely open up the choice for packagers and
users to build CPython (and extension modules, thanks to separate patches)
with alternate compilers, in cross-compilation or otherwise.
Sincerely,
Tony