Python-Dev
Threads by month
- ----- 2025 -----
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1999 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
July 2016
- 57 participants
- 42 discussions
https://github.com/python/devguide
I have also moved all issues over as well and hooked up Read The Docs so
that there's a mirror which is always up-to-date (vs.
docs.python.org/devguide which is on a cronjob).
7
8
ACTIVITY SUMMARY (2016-07-22 - 2016-07-29)
Python tracker at http://bugs.python.org/
To view or respond to any of the issues listed below, click on the issue.
Do NOT respond to this message.
Issues counts and deltas:
open 5588 ( +2)
closed 33818 (+56)
total 39406 (+58)
Open issues with patches: 2442
Issues opened (41)
==================
#24773: Implement PEP 495 (Local Time Disambiguation)
http://bugs.python.org/issue24773 reopened by martin.panter
#27593: Deprecate sys.…
[View More]_mercurial and create sys._git
http://bugs.python.org/issue27593 opened by brett.cannon
#27594: Assertion failure when running "test_ast" tests with coverage.
http://bugs.python.org/issue27594 opened by ap
#27595: Document PEP 495 (Local Time Disambiguation) features
http://bugs.python.org/issue27595 opened by belopolsky
#27596: Build failure with Xcode 8 beta on OSX 10.11
http://bugs.python.org/issue27596 opened by ronaldoussoren
#27597: Add usage examples for TracebackException, StackSummary and Fr
http://bugs.python.org/issue27597 opened by cool-RR
#27598: Add SizedIterable to collections.abc and typing
http://bugs.python.org/issue27598 opened by brett.cannon
#27599: Buffer overrun in binascii
http://bugs.python.org/issue27599 opened by serhiy.storchaka
#27602: Enable py launcher to launch repository Python.
http://bugs.python.org/issue27602 opened by terry.reedy
#27603: Migrate IDLE context menu items to shell extension
http://bugs.python.org/issue27603 opened by steve.dower
#27604: More details about `-O` flag
http://bugs.python.org/issue27604 opened by cool-RR
#27605: Inconsistent calls to __eq__ from built-in __contains__
http://bugs.python.org/issue27605 opened by vfaronov
#27606: Android cross-built for armv5te with clang and '-mthumb' crash
http://bugs.python.org/issue27606 opened by xdegaye
#27607: Importing the main module twice leads to two incompatible inst
http://bugs.python.org/issue27607 opened by SylvieLorxu
#27609: IDLE completions: format, factor, and fix
http://bugs.python.org/issue27609 opened by terry.reedy
#27611: test_tix cannot import _default_root after test_idle
http://bugs.python.org/issue27611 opened by martin.panter
#27612: socket.gethostbyname resolving octal IP addresses incorrectly
http://bugs.python.org/issue27612 opened by mattrobenolt
#27613: Empty iterator is rendered as a single bracket ] when using js
http://bugs.python.org/issue27613 opened by altvod
#27614: Race in test_docxmlrpc.py
http://bugs.python.org/issue27614 opened by earl.chew
#27618: docs for threading.Lock claim it's a class (since 3.3), but it
http://bugs.python.org/issue27618 opened by gvanrossum
#27619: getopt should strip whitespace from long arguments
http://bugs.python.org/issue27619 opened by steven.daprano
#27620: IDLE: Add keyboard equivalents for mouse actions.
http://bugs.python.org/issue27620 opened by terry.reedy
#27621: Finish IDLE Query dialog appearance and behavior.
http://bugs.python.org/issue27621 opened by serhiy.storchaka
#27623: int.to_bytes() and int.from_bytes(): raise ValueError when byt
http://bugs.python.org/issue27623 opened by mmarkk
#27627: clang fails to build ctypes on Android armv7
http://bugs.python.org/issue27627 opened by xdegaye
#27628: ipaddress incompatibility with ipaddr: __contains__ between ne
http://bugs.python.org/issue27628 opened by lukasz.langa
#27629: Cannot create ssl.SSLSocket without existing socket
http://bugs.python.org/issue27629 opened by nemunaire
#27630: Generator._encoded_EMTPY misspelling in email package
http://bugs.python.org/issue27630 opened by martin.panter
#27632: build on AIX fails when builddir != srcdir, more than bad path
http://bugs.python.org/issue27632 opened by Michael.Felt
#27635: pickle documentation says that unpickling may not call __new__
http://bugs.python.org/issue27635 opened by july
#27636: Refactor IDLE htest
http://bugs.python.org/issue27636 opened by terry.reedy
#27637: int.to_bytes(-1, ...) should automatically choose required cou
http://bugs.python.org/issue27637 opened by mmarkk
#27638: int.to_bytes() and int.from_bytes() should support 'net' and '
http://bugs.python.org/issue27638 opened by mmarkk
#27639: UserList.__getitem__ doesn't account for slices
http://bugs.python.org/issue27639 opened by staticshock
#27640: add the '--disable-test-suite' option to configure
http://bugs.python.org/issue27640 opened by xdegaye
#27641: Do not build Programs/_freeze_importlib when cross-compiling
http://bugs.python.org/issue27641 opened by thomas.perl
#27643: test_ctypes fails on AIX with xlc
http://bugs.python.org/issue27643 opened by Michael.Felt
#27644: Expand documentation about type aliases and NewType in the typ
http://bugs.python.org/issue27644 opened by michael0x2a
#27645: Supporting native backup facility of SQLite
http://bugs.python.org/issue27645 opened by lelit
#27646: yield from expression can be any iterable
http://bugs.python.org/issue27646 opened by terry.reedy
#27647: Update Windows build to Tcl/Tk 8.6.6
http://bugs.python.org/issue27647 opened by serhiy.storchaka
Most recent 15 issues with no replies (15)
==========================================
#27646: yield from expression can be any iterable
http://bugs.python.org/issue27646
#27636: Refactor IDLE htest
http://bugs.python.org/issue27636
#27635: pickle documentation says that unpickling may not call __new__
http://bugs.python.org/issue27635
#27632: build on AIX fails when builddir != srcdir, more than bad path
http://bugs.python.org/issue27632
#27599: Buffer overrun in binascii
http://bugs.python.org/issue27599
#27597: Add usage examples for TracebackException, StackSummary and Fr
http://bugs.python.org/issue27597
#27595: Document PEP 495 (Local Time Disambiguation) features
http://bugs.python.org/issue27595
#27594: Assertion failure when running "test_ast" tests with coverage.
http://bugs.python.org/issue27594
#27593: Deprecate sys._mercurial and create sys._git
http://bugs.python.org/issue27593
#27589: asyncio doc: issue in as_completed() doc
http://bugs.python.org/issue27589
#27584: New addition of vSockets to the python socket module
http://bugs.python.org/issue27584
#27566: Tools/freeze/winmakemakefile.py clean target should use 'del'
http://bugs.python.org/issue27566
#27565: Offer error context manager for code.interact
http://bugs.python.org/issue27565
#27534: IDLE: Reduce number and time for user process imports
http://bugs.python.org/issue27534
#27530: Non-Critical Compiler WARNING: Python Embedding C++11 does not
http://bugs.python.org/issue27530
Most recent 15 issues waiting for review (15)
=============================================
#27646: yield from expression can be any iterable
http://bugs.python.org/issue27646
#27645: Supporting native backup facility of SQLite
http://bugs.python.org/issue27645
#27644: Expand documentation about type aliases and NewType in the typ
http://bugs.python.org/issue27644
#27641: Do not build Programs/_freeze_importlib when cross-compiling
http://bugs.python.org/issue27641
#27640: add the '--disable-test-suite' option to configure
http://bugs.python.org/issue27640
#27639: UserList.__getitem__ doesn't account for slices
http://bugs.python.org/issue27639
#27629: Cannot create ssl.SSLSocket without existing socket
http://bugs.python.org/issue27629
#27623: int.to_bytes() and int.from_bytes(): raise ValueError when byt
http://bugs.python.org/issue27623
#27621: Finish IDLE Query dialog appearance and behavior.
http://bugs.python.org/issue27621
#27619: getopt should strip whitespace from long arguments
http://bugs.python.org/issue27619
#27614: Race in test_docxmlrpc.py
http://bugs.python.org/issue27614
#27611: test_tix cannot import _default_root after test_idle
http://bugs.python.org/issue27611
#27604: More details about `-O` flag
http://bugs.python.org/issue27604
#27587: Issues, reported by PVS-Studio static analyzer
http://bugs.python.org/issue27587
#27584: New addition of vSockets to the python socket module
http://bugs.python.org/issue27584
Top 10 most discussed issues (10)
=================================
#24773: Implement PEP 495 (Local Time Disambiguation)
http://bugs.python.org/issue24773 29 msgs
#26462: Patch to enhance literal block language declaration
http://bugs.python.org/issue26462 23 msgs
#27612: socket.gethostbyname resolving octal IP addresses incorrectly
http://bugs.python.org/issue27612 18 msgs
#26852: add the '--enable-sourceless-distribution' option to configure
http://bugs.python.org/issue26852 14 msgs
#27546: Integrate tkinter and asyncio (and async)
http://bugs.python.org/issue27546 13 msgs
#27607: Importing the main module twice leads to two incompatible inst
http://bugs.python.org/issue27607 13 msgs
#27604: More details about `-O` flag
http://bugs.python.org/issue27604 12 msgs
#26851: android compilation and link flags
http://bugs.python.org/issue26851 11 msgs
#27619: getopt should strip whitespace from long arguments
http://bugs.python.org/issue27619 11 msgs
#27623: int.to_bytes() and int.from_bytes(): raise ValueError when byt
http://bugs.python.org/issue27623 11 msgs
Issues closed (54)
==================
#7063: Memory errors in array.array
http://bugs.python.org/issue7063 closed by martin.panter
#8623: Aliasing warnings in socketmodule.c
http://bugs.python.org/issue8623 closed by martin.panter
#10036: compiler warnings for various modules on Linux buildslaves
http://bugs.python.org/issue10036 closed by martin.panter
#10965: dev task of documenting undocumented APIs
http://bugs.python.org/issue10965 closed by brett.cannon
#11048: "import ctypes" causes segfault on read-only filesystem
http://bugs.python.org/issue11048 closed by haypo
#13849: Add tests for NUL checking in certain strs
http://bugs.python.org/issue13849 closed by berker.peksag
#14218: include rendered output in addition to markup
http://bugs.python.org/issue14218 closed by brett.cannon
#15661: OS X installer packages should be signed for OS X 10.8 Gatekee
http://bugs.python.org/issue15661 closed by ned.deily
#16930: mention limitations and/or alternatives to hg graft
http://bugs.python.org/issue16930 closed by brett.cannon
#16931: mention work-around to create diffs in default/non-git mode
http://bugs.python.org/issue16931 closed by brett.cannon
#17227: devguide: buggy heading numbers
http://bugs.python.org/issue17227 closed by brett.cannon
#17596: mingw: add wincrypt.h in Python/random.c
http://bugs.python.org/issue17596 closed by martin.panter
#18041: mention issues with code churn in the devguide
http://bugs.python.org/issue18041 closed by brett.cannon
#20851: Update devguide to cover testing from a tarball
http://bugs.python.org/issue20851 closed by brett.cannon
#22645: Unable to install Python 3.4.2 amd64 on Windows 8.1 Update 1
http://bugs.python.org/issue22645 closed by berker.peksag
#23320: devguide should mention rules about "paragraph reflow" in the
http://bugs.python.org/issue23320 closed by brett.cannon
#23951: Update devguide style to use a similar theme as Docs
http://bugs.python.org/issue23951 closed by brett.cannon
#24016: Add a Sprints organization/preparation section to devguide
http://bugs.python.org/issue24016 closed by brett.cannon
#24682: Add Quick Start: Communications section to devguide
http://bugs.python.org/issue24682 closed by brett.cannon
#24689: Add tips for effective online communication to devguide
http://bugs.python.org/issue24689 closed by brett.cannon
#25431: implement address in network in ipaddress module
http://bugs.python.org/issue25431 closed by berker.peksag
#25966: Bug in asyncio.corotuines._format_coroutine
http://bugs.python.org/issue25966 closed by berker.peksag
#26152: A non-breaking space in a source
http://bugs.python.org/issue26152 closed by ncoghlan
#26662: configure/Makefile doesn't check if "python" command works, ne
http://bugs.python.org/issue26662 closed by xdegaye
#26974: Crash in Decimal.from_float
http://bugs.python.org/issue26974 closed by skrah
#27130: zlib: OverflowError while trying to compress 2^32 bytes or mor
http://bugs.python.org/issue27130 closed by martin.panter
#27131: Unit test random shuffle
http://bugs.python.org/issue27131 closed by rhettinger
#27250: Add os.urandom_block()
http://bugs.python.org/issue27250 closed by haypo
#27266: Always use getrandom() in os.random() on Linux and add block=F
http://bugs.python.org/issue27266 closed by haypo
#27404: Misc/NEWS: add [Security] prefix to Python 3.5.2 changelog
http://bugs.python.org/issue27404 closed by haypo
#27454: PyUnicode_InternInPlace can use PyDict_SetDefault
http://bugs.python.org/issue27454 closed by berker.peksag
#27490: Do not run pgen when it is not going to be used (cross-compili
http://bugs.python.org/issue27490 closed by martin.panter
#27493: logging module fails with unclear error when supplied a (Posix
http://bugs.python.org/issue27493 closed by python-dev
#27579: Add a tutorial for AsyncIO in the documentation
http://bugs.python.org/issue27579 closed by haypo
#27581: Fix overflow check in PySequence_Tuple
http://bugs.python.org/issue27581 closed by martin.panter
#27591: multiprocessing: Possible uninitialized pointer use in Windows
http://bugs.python.org/issue27591 closed by berker.peksag
#27592: FIPS_mode() and FIPS_mode_set() functions in Python (ssl)
http://bugs.python.org/issue27592 closed by r.david.murray
#27600: Spam
http://bugs.python.org/issue27600 closed by ebarry
#27601: Minor inaccuracy in hash documentation
http://bugs.python.org/issue27601 closed by magniff
#27608: Something wrong with str.upper().lower() chain?
http://bugs.python.org/issue27608 closed by magniff
#27610: Add PEP 514 metadata to Windows installer
http://bugs.python.org/issue27610 closed by steve.dower
#27615: IDLE's debugger steps into PyShell.py for calls to print() et
http://bugs.python.org/issue27615 closed by terry.reedy
#27616: filedialog.askdirectory inconsistent on Windows between return
http://bugs.python.org/issue27616 closed by serhiy.storchaka
#27617: Compiled bdist_wininst missing from embedded distribution
http://bugs.python.org/issue27617 closed by steve.dower
#27622: int.to_bytes(): docstring is not precise
http://bugs.python.org/issue27622 closed by mmarkk
#27624: unclear documentation on Queue.qsize()
http://bugs.python.org/issue27624 closed by rhettinger
#27625: "make install" fails when no zlib support available
http://bugs.python.org/issue27625 closed by SilentGhost
#27626: Spelling fixes
http://bugs.python.org/issue27626 closed by martin.panter
#27631: .exe is appended to python executable based on filesystem case
http://bugs.python.org/issue27631 closed by ammar2
#27633: Doc: Add missing version info to email.parser
http://bugs.python.org/issue27633 closed by berker.peksag
#27634: selectors.SelectSelectors fails if select.select was patched
http://bugs.python.org/issue27634 closed by brett.cannon
#27642: import and __import__() fails silently without a ImportError a
http://bugs.python.org/issue27642 closed by ebarry
#27648: Message of webbrowser.py something wrong.
http://bugs.python.org/issue27648 closed by r.david.murray
#27649: multiprocessing on Windows does not properly manage class attr
http://bugs.python.org/issue27649 closed by r.david.murray
[View Less]
1
0
Hi all
I'd like to get this PEP approved (status changed to Active, IIUC).
So far (to my knowledge), Anaconda is writing out the new metadata and
Visual Studio is reading it. Any changes to the schema now will require
somewhat public review anyway, so I don't see any harm in approving the
PEP right now.
To reiterate, this doesn't require changing anything about CPython at
all and has no backwards compatibility impact on official releases (but
hopefully it will stop alternative distros …
[View More]from overwriting our
essential metadata and causing problems).
I suppose I look to Guido first, unless he wants to delegate to one of
the other Windows contributors?
Cheers,
Steve
URL: https://www.python.org/dev/peps/pep-0514/
Full text
-------
PEP: 514
Title: Python registration in the Windows registry
Version: $Revision$
Last-Modified: $Date$
Author: Steve Dower <steve.dower(a)python.org>
Status: Draft
Type: Informational
Content-Type: text/x-rst
Created: 02-Feb-2016
Post-History: 02-Feb-2016, 01-Mar-2016
Abstract
========
This PEP defines a schema for the Python registry key to allow third-party
installers to register their installation, and to allow applications to
detect
and correctly display all Python environments on a user's machine. No
implementation changes to Python are proposed with this PEP.
Python environments are not required to be registered unless they want to be
automatically discoverable by external tools.
The schema matches the registry values that have been used by the official
installer since at least Python 2.5, and the resolution behaviour
matches the
behaviour of the official Python releases.
Motivation
==========
When installed on Windows, the official Python installer creates a
registry key
for discovery and detection by other applications. This allows tools such as
installers or IDEs to automatically detect and display a user's Python
installations.
Third-party installers, such as those used by distributions, typically
create
identical keys for the same purpose. Most tools that use the registry to
detect
Python installations only inspect the keys used by the official
installer. As a
result, third-party installations that wish to be discoverable will
overwrite
these values, resulting in users "losing" their Python installation.
By describing a layout for registry keys that allows third-party
installations
to register themselves uniquely, as well as providing tool developers
guidance
for discovering all available Python installations, these collisions
should be
prevented.
Definitions
===========
A "registry key" is the equivalent of a file-system path into the
registry. Each
key may contain "subkeys" (keys nested within keys) and "values" (named and
typed attributes attached to a key).
``HKEY_CURRENT_USER`` is the root of settings for the currently
logged-in user,
and this user can generally read and write all settings under this root.
``HKEY_LOCAL_MACHINE`` is the root of settings for all users. Generally, any
user can read these settings but only administrators can modify them. It is
typical for values under ``HKEY_CURRENT_USER`` to take precedence over
those in
``HKEY_LOCAL_MACHINE``.
On 64-bit Windows, ``HKEY_LOCAL_MACHINE\Software\Wow6432Node`` is a
special key
that 32-bit processes transparently read and write to rather than
accessing the
``Software`` key directly.
Structure
=========
We consider there to be a single collection of Python environments on a
machine,
where the collection may be different for each user of the machine.
There are
three potential registry locations where the collection may be stored
based on
the installation options of each environment::
HKEY_CURRENT_USER\Software\Python\<Company>\<Tag>
HKEY_LOCAL_MACHINE\Software\Python\<Company>\<Tag>
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\<Company>\<Tag>
Environments are uniquely identified by their Company-Tag pair, with two
options
for conflict resolution: include everything, or give priority to user
preferences.
Tools that include every installed environment, even where the
Company-Tag pairs
match, should ensure users can easily identify whether the registration was
per-user or per-machine.
When tools are selecting a single installed environment from all registered
environments, the intent is that user preferences from ``HKEY_CURRENT_USER``
will override matching Company-Tag pairs in ``HKEY_LOCAL_MACHINE``.
Official Python releases use ``PythonCore`` for Company, and the value of
``sys.winver`` for Tag. Other registered environments may use any values for
Company and Tag. Recommendations are made in the following sections.
Python environments are not required to register themselves unless they
want to
be automatically discoverable by external tools.
Backwards Compatibility
-----------------------
Python 3.4 and earlier did not distinguish between 32-bit and 64-bit
builds in
``sys.winver``. As a result, it is possible to have valid side-by-side
installations of both 32-bit and 64-bit interpreters.
To ensure backwards compatibility, applications should treat
environments listed
under the following two registry keys as distinct, even when the Tag
matches::
HKEY_LOCAL_MACHINE\Software\Python\PythonCore\<Tag>
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\PythonCore\<Tag>
Environments listed under ``HKEY_CURRENT_USER`` may be treated as
distinct from
both of the above keys, potentially resulting in three environments
discovered
using the same Tag. Alternatively, a tool may determine whether the per-user
environment is 64-bit or 32-bit and give it priority over the per-machine
environment, resulting in a maximum of two discovered environments.
It is not possible to detect side-by-side installations of both 64-bit and
32-bit versions of Python prior to 3.5 when they have been installed for the
current user. Python 3.5 and later always uses different Tags for 64-bit and
32-bit versions.
Environments registered under other Company names must use distinct Tags to
support side-by-side installations. Tools consuming these registrations are
not required to disambiguate tags other than by preferring the user's
setting.
Company
-------
The Company part of the key is intended to group related environments and to
ensure that Tags are namespaced appropriately. The key name should be
alphanumeric without spaces and likely to be unique. For example, a
trademarked
name, a UUID, or a hostname would be appropriate::
HKEY_CURRENT_USER\Software\Python\ExampleCorp
HKEY_CURRENT_USER\Software\Python\6C465E66-5A8C-4942-9E6A-D29159480C60
HKEY_CURRENT_USER\Software\Python\www.example.com
The company name ``PyLauncher`` is reserved for the PEP 397 launcher
(``py.exe``). It does not follow this convention and should be ignored
by tools.
If a string value named ``DisplayName`` exists, it should be used to
identify
the environment category to users. Otherwise, the name of the key should be
used.
If a string value named ``SupportUrl`` exists, it may be displayed or
otherwise
used to direct users to a web site related to the environment.
A complete example may look like::
HKEY_CURRENT_USER\Software\Python\ExampleCorp
(Default) = (value not set)
DisplayName = "Example Corp"
SupportUrl = "http://www.example.com"
Tag
---
The Tag part of the key is intended to uniquely identify an environment
within
those provided by a single company. The key name should be alphanumeric
without
spaces and stable across installations. For example, the Python language
version, a UUID or a partial/complete hash would be appropriate; an integer
counter that increases for each new environment may not::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\3.6
HKEY_CURRENT_USER\Software\Python\ExampleCorp\6C465E66
If a string value named ``DisplayName`` exists, it should be used to
identify
the environment to users. Otherwise, the name of the key should be used.
If a string value named ``SupportUrl`` exists, it may be displayed or
otherwise
used to direct users to a web site related to the environment.
If a string value named ``Version`` exists, it should be used to
identify the
version of the environment. This is independent from the version of Python
implemented by the environment.
If a string value named ``SysVersion`` exists, it must be in ``x.y`` or
``x.y.z`` format matching the version returned by ``sys.version_info``
in the
interpreter. Otherwise, if the Tag matches this format it is used. If
not, the
Python version is unknown.
Note that each of these values is recommended, but optional. A complete
example
may look like this::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\6C465E66
(Default) = (value not set)
DisplayName = "Distro 3"
SupportUrl = "http://www.example.com/distro-3"
Version = "3.0.12345.0"
SysVersion = "3.6.0"
InstallPath
-----------
Beneath the environment key, an ``InstallPath`` key must be created.
This key is
always named ``InstallPath``, and the default value must match
``sys.prefix``::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\3.6\InstallPath
(Default) = "C:\ExampleCorpPy36"
If a string value named ``ExecutablePath`` exists, it must be a path to the
``python.exe`` (or equivalent) executable. Otherwise, the interpreter
executable
is assumed to be called ``python.exe`` and exist in the directory
referenced by
the default value.
If a string value named ``WindowedExecutablePath`` exists, it must be a
path to
the ``pythonw.exe`` (or equivalent) executable. Otherwise, the windowed
interpreter executable is assumed to be called ``pythonw.exe`` and exist
in the
directory referenced by the default value.
A complete example may look like::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\6C465E66\InstallPath
(Default) = "C:\ExampleDistro30"
ExecutablePath = "C:\ExampleDistro30\ex_python.exe"
WindowedExecutablePath = "C:\ExampleDistro30\ex_pythonw.exe"
Help
----
Beneath the environment key, a ``Help`` key may be created. This key is
always
named ``Help`` if present and has no default value.
Each subkey of ``Help`` specifies a documentation file, tool, or URL
associated
with the environment. The subkey may have any name, and the default
value is a
string appropriate for passing to ``os.startfile`` or equivalent.
If a string value named ``DisplayName`` exists, it should be used to
identify
the help file to users. Otherwise, the key name should be used.
A complete example may look like::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\6C465E66\Help
Python\
(Default) = "C:\ExampleDistro30\python36.chm"
DisplayName = "Python Documentation"
Extras\
(Default) = "http://www.example.com/tutorial"
DisplayName = "Example Distro Online Tutorial"
Other Keys
----------
Some other registry keys are used for defining or inferring search paths
under
certain conditions. A third-party installation is permitted to define
these keys
under their Company-Tag key, however, the interpreter must be modified and
rebuilt in order to read these values. Alternatively, the interpreter may be
modified to not use any registry keys for determining search paths.
Making such
changes is a decision for the third party; this PEP makes no recommendation
either way.
Copyright
=========
This document has been placed in the public domain.
[View Less]
5
15
Hi all,
as I'm going to have a need to use the native `online backup API`__ provided
by SQLite, I looked around for existing solutions and found `sqlitebck`__.
I somewhat dislike the approach taken by that 3rd party module, and I wonder
if the API should/could be exposed by the standard library sqlite module
instead.
Another option would be using ctypes, but as I never used it, I dunno how easy
it is to maintain compatibility between different OSes...
What do you think?
Thanks&bye, …
[View More]lele.
__ https://www.sqlite.org/backup.html
__ https://github.com/husio/python-sqlite3-backup
--
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
lele(a)metapensiero.it | -- Fortunato Depero, 1929.
[View Less]
2
5
Morning all, I'm writing to introduce myself and a port of CPython 3.6
to a CloudABI.
The port is reaching the point where it might be of interest to
others. Namely it ran it's first .py script yesterday during the
EuroPython scripts. Having said that it's still very early days, the
patches do horrible things - particularly to the import machinery.
I writing this to raise awareness, and open discussions. I'd love to
answer any questions/comments you might have.
Background:
# What is …
[View More]CloudABI?
CloudABI is a POSIX-like platform, with Capability based Security
applied. At the syscall/libc layer functions which perform IO or
acquire resources without a pre-existing file descriptor (e.g. open(),
stat(), bind() etc) are removed. All IO operations must be performed
through functions that accept a file descriptor, or a path relative to
an fd.
In this way descriptors server as capability tokens. All such tokens
are provided to a process when it is spawned. If none are provided
then the program in question is limited to just pure computation &
memory allocation. Even stdin, stdout & stderr are not provided by
default.
# Why bother with CloudABI?
It makes it possible to isolate programs from the OS, without
resorting to e.g. containers. Possibly even to run untrusted binaries.
A compromised CloudABI process can only damaged the things it has
access to e.g. a transcoding job can only read the provided input and
write to the provided output. It couldn't read /etc/passwd, or try to
brute force SSH. This kind of isolation is still possible with UNIX,
but it's not the default - which makes it rare.
Personally, I find it interesting. I like the fact that CloudABI
processes can be run by unprivileged users - unlike containers. The
no-default-global-resources nature makes it easier to write code that
can be tested. The fd provided to a webapp doesn't have to be a TCP
socket, it could be a domain socket, or just a file stream.
# What is the state of Python for CloudABI?
Python for CloudABI is a proof of concept. The port takes the form of
a number of patches to CPython 3.6.0a3. These mostly add autoconf &
#ifdef entries for POSIX API functions that CloudABI deliberately does
not support.
A few differences make their way through Python code, for instance
- sys.path is a list of file descriptors, rather than a list of strings
- sys.executable is None
- sys.argv is not present
- The uid and gid entries of stat tuples are set to None (like on Windows)
I got print('Hello World', file=...) working about a month ago, and
executed my first .py file yesterday (commit pending).
The current TODO list is
- Finish script support
- Module execution (python -m) support
- zipimport support for file descriptors
- ssl support
- patch cleanup
- try to run test suite
There is no Python 2.x support, and I don't plan to add any.
# What's the state of CloudABI?
CloudABI runs on FreeBSD, NetBSD, macOS and Linux. For now it requires
a patched kernel on Linux; FreeBSD 11 will include it out the box.
Various libraries/packages have been ported (e.g. curl, libpng, x265,
lua, libressl).
# What's the history of CloudABI?
The project started about 2 years ago. Ed Schouten is the project
leader & creator. I became involved this year, having seen a talk by
Ed at CCC around new year.
# Where can I get more info?
- https://nuxi.nl - CloudABI homepage, including Ed Schouten's CCC talk
- http://slides.com/alexwillmer/cloudabi-capability-security - My EP2016 talk
- https://www.youtube.com/watch?v=wlUtkBa8tK8&feature=youtu.be&t=49m
- https://github.com/NuxiNL/cloudlibc
- https://github.com/NuxiNL/cloudabi-ports
- https://github.com/NuxiNL/cloudabi-ports/tree/master/packages/python
- #cloudabi on Efnet IRC
Regards, Alex
--
Alex Willmer <alex(a)moreati.org.uk>
[View Less]
2
1
PEP 514 is now ready for pronouncement, so this is the last chance for
any feedback (BDFL-delegate Paul has been active on the github PR, so I
don't expect he has a lot of feedback left).
The most major change from the previous post is the addition of some
code examples at the end. Honestly, I don't expect many tools written in
Python to be scanning the registry (since once you're in Python you
probably don't need to find it), but hopefully they'll help clarify the
PEP for people who …
[View More]prefer code.
Full text below.
Cheers,
Steve
----------
PEP: 514
Title: Python registration in the Windows registry
Version: $Revision$
Last-Modified: $Date$
Author: Steve Dower <steve.dower(a)python.org>
Status: Draft
Type: Informational
Content-Type: text/x-rst
Created: 02-Feb-2016
Post-History: 02-Feb-2016, 01-Mar-2016, 18-Jul-2016
Abstract
========
This PEP defines a schema for the Python registry key to allow third-party
installers to register their installation, and to allow tools and
applications
to detect and correctly display all Python environments on a user's
machine. No
implementation changes to Python are proposed with this PEP.
Python environments are not required to be registered unless they want to be
automatically discoverable by external tools. As this relates to Windows
only,
these tools are expected to be predominantly GUI applications. However,
console
applications may also make use of the registered information. This PEP
covers
the information that may be made available, but the actual presentation
and use
of this information is left to the tool designers.
The schema matches the registry values that have been used by the official
installer since at least Python 2.5, and the resolution behaviour
matches the
behaviour of the official Python releases. Some backwards compatibility
rules
are provided to ensure tools can correctly detect versions of CPython
that do
not register full information.
Motivation
==========
When installed on Windows, the official Python installer creates a
registry key
for discovery and detection by other applications. This allows tools such as
installers or IDEs to automatically detect and display a user's Python
installations. For example, the PEP 397 ``py.exe`` launcher and editors
such as
PyCharm and Visual Studio already make use of this information.
Third-party installers, such as those used by distributions, typically
create
identical keys for the same purpose. Most tools that use the registry to
detect
Python installations only inspect the keys used by the official
installer. As a
result, third-party installations that wish to be discoverable will
overwrite
these values, often causing users to "lose" their original Python
installation.
By describing a layout for registry keys that allows third-party
installations
to register themselves uniquely, as well as providing tool developers
guidance
for discovering all available Python installations, these collisions
should be
prevented. We also take the opportunity to add some well-known metadata
so that
more information can be presented to users.
Definitions
===========
A "registry key" is the equivalent of a file-system path into the
registry. Each
key may contain "subkeys" (keys nested within keys) and "values" (named and
typed attributes attached to a key). These are used on Windows to store
settings
in much the same way that directories containing configuration files
would work.
``HKEY_CURRENT_USER`` is the root of settings for the currently
logged-in user,
and this user can generally read and write all settings under this root.
``HKEY_LOCAL_MACHINE`` is the root of settings for all users. Generally, any
user can read these settings but only administrators can modify them. It is
typical for values under ``HKEY_CURRENT_USER`` to take precedence over
those in
``HKEY_LOCAL_MACHINE``.
On 64-bit Windows, ``HKEY_LOCAL_MACHINE\Software\Wow6432Node`` is a
special key
that 32-bit processes transparently read and write to rather than
accessing the
``Software`` key directly.
Further documentation regarding registry redirection on Windows is available
from the MSDN Library [1]_.
Structure
=========
We consider there to be a single collection of Python environments on a
machine,
where the collection may be different for each user of the machine.
There are
three potential registry locations where the collection may be stored
based on
the installation options of each environment::
HKEY_CURRENT_USER\Software\Python\<Company>\<Tag>
HKEY_LOCAL_MACHINE\Software\Python\<Company>\<Tag>
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\<Company>\<Tag>
Official Python releases use ``PythonCore`` for Company, and the value of
``sys.winver`` for Tag. The Company ``PyLauncher`` is reserved. Other
registered
environments may use any values for Company and Tag. Recommendations are
made
later in this document.
Company-Tag pairs are case-insensitive, and uniquely identify each
environment.
Depending on the purpose and intended use of a tool, there are two suggested
approaches for resolving conflicts between Company-Tag pairs.
Tools that list every installed environment may choose to include those
even where the Company-Tag pairs match. They should ensure users can easily
identify whether the registration was per-user or per-machine, and which
registration has the higher priority.
Tools that aim to select a single installed environment from all registered
environments based on the Company-Tag pair, such as the ``py.exe`` launcher,
should always select the environment registered in ``HKEY_CURRENT_USER``
when
than the matching one in ``HKEY_LOCAL_MACHINE``.
Conflicts between ``HKEY_LOCAL_MACHINE\Software\Python`` and
``HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python`` should only occur
when both
64-bit and 32-bit versions of an interpreter have the same Tag. In this
case,
the tool should select whichever is more appropriate for its use.
If a tool is able to determine from the provided information (or lack
thereof)
that it cannot use a registered environment, there is no obligation to
present
it to users.
Except as discussed in the section on backwards compatibility, Company
and Tag
values are considered opaque to tools, and no information about the
interpreter
should be inferred from the text. However, some tools may display the
Company
and Tag values to users, so ideally the Tag will be able to help users
identify
the associated environment.
Python environments are not required to register themselves unless they
want to
be automatically discoverable by external tools.
Backwards Compatibility
-----------------------
Python 3.4 and earlier did not distinguish between 32-bit and 64-bit
builds in
``sys.winver``. As a result, it is not possible to have valid side-by-side
installations of both 32-bit and 64-bit interpreters under this scheme
since it
would result in duplicate Tags.
To ensure backwards compatibility, applications should treat
environments listed
under the following two registry keys as distinct, even when the Tag
matches::
HKEY_LOCAL_MACHINE\Software\Python\PythonCore\<Tag>
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\PythonCore\<Tag>
Environments listed under ``HKEY_CURRENT_USER`` may be treated as
distinct from
both of the above keys, potentially resulting in three environments
discovered
using the same Tag. Alternatively, a tool may determine whether the per-user
environment is 64-bit or 32-bit and give it priority over the per-machine
environment, resulting in a maximum of two discovered environments.
It is not possible to detect side-by-side installations of both 64-bit and
32-bit versions of Python prior to 3.5 when they have been installed for the
current user. Python 3.5 and later always uses different Tags for 64-bit and
32-bit versions.
The following section describe user-visible information that may be
registered.
For Python 3.5 and earlier, none of this information is available, but
alternative defaults are specified for the ``PythonCore`` key.
Environments registered under other Company names have no backward
compatibility
requirements and must use distinct Tags to support side-by-side
installations.
Tools consuming these registrations are not required to disambiguate
tags other
than by preferring the user's setting.
Company
-------
The Company part of the key is intended to group related environments and to
ensure that Tags are namespaced appropriately. The key name should be
alphanumeric without spaces and likely to be unique. For example, a
trademarked
name (preferred), a hostname, or as a last resort, a UUID would be
appropriate::
HKEY_CURRENT_USER\Software\Python\ExampleCorp
HKEY_CURRENT_USER\Software\Python\www.example.com
HKEY_CURRENT_USER\Software\Python\6C465E66-5A8C-4942-9E6A-D29159480C60
The company name ``PyLauncher`` is reserved for the PEP 397 launcher
(``py.exe``). It does not follow this convention and should be ignored
by tools.
If a string value named ``DisplayName`` exists, it should be used to
identify
the environment manufacturer/developer/destributor to users. Otherwise,
the name
of the key should be used. (For ``PythonCore``, the default display name is
"Python Software Foundation".)
If a string value named ``SupportUrl`` exists, it may be displayed or
otherwise
used to direct users to a web site related to the environment. (For
``PythonCore``, the default support URL is "http://www.python.org/".)
A complete example may look like::
HKEY_CURRENT_USER\Software\Python\ExampleCorp
(Default) = (value not set)
DisplayName = "Example Corp"
SupportUrl = "http://www.example.com"
Tag
---
The Tag part of the key is intended to uniquely identify an environment
within
those provided by a single company. The key name should be alphanumeric
without
spaces and stable across installations. For example, the Python language
version, a UUID or a partial/complete hash would be appropriate, while a Tag
based on the install directory or some aspect of the current machine may
not.
For example::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\examplepy
HKEY_CURRENT_USER\Software\Python\ExampleCorp\3.6
HKEY_CURRENT_USER\Software\Python\ExampleCorp\6C465E66
It is expected that some tools will require users to type the Tag into a
command
line, and that the Company may be optional provided the Tag is unique
across all
Python installations. Short, human-readable and easy to type Tags are
recommended, and if possible, select a value likely to be unique across all
other Companies.
If a string value named ``DisplayName`` exists, it should be used to
identify
the environment to users. Otherwise, the name of the key should be used.
(For
``PythonCore``, the default is "Python " followed by the Tag.)
If a string value named ``SupportUrl`` exists, it may be displayed or
otherwise
used to direct users to a web site related to the environment. (For
``PythonCore``, the default is "http://www.python.org/".)
If a string value named ``Version`` exists, it should be used to
identify the
version of the environment. This is independent from the version of Python
implemented by the environment. (For ``PythonCore``, the default is the
first
three characters of the Tag.)
If a string value named ``SysVersion`` exists, it must be in ``x.y`` or
``x.y.z`` format matching the version returned by ``sys.version_info``
in the
interpreter. If omitted, the Python version is unknown. (For ``PythonCore``,
the default is the first three characters of the Tag.)
If a string value named ``SysArchitecture`` exists, it must match the first
element of the tuple returned by ``platform.architecture()``. Typically,
this
will be "32bit" or "64bit". If omitted, the architecture is unknown. (For
``PythonCore``, the architecture is "32bit" when registered under
``HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python`` *or* anywhere on a 32-bit
operating system, "64bit" when registered under
``HKEY_LOCAL_MACHINE\Software\Python`` on a 64-bit machine, and unknown when
registered under ``HKEY_CURRENT_USER``.)
Note that each of these values is recommended, but optional. Omitting
``SysVersion`` or ``SysArchitecture`` may prevent some tools from correctly
supporting the environment. A complete example may look like this::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\examplepy
(Default) = (value not set)
DisplayName = "Example Py Distro 3"
SupportUrl = "http://www.example.com/distro-3"
Version = "3.0.12345.0"
SysVersion = "3.6.0"
SysArchitecture = "64bit"
InstallPath
-----------
Beneath the environment key, an ``InstallPath`` key must be created.
This key is
always named ``InstallPath``, and the default value must match
``sys.prefix``::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\3.6\InstallPath
(Default) = "C:\ExampleCorpPy36"
If a string value named ``ExecutablePath`` exists, it must be the full
path to
the ``python.exe`` (or equivalent) executable. If omitted, the
environment is
not executable. (For ``PythonCore``, the default is the ``python.exe``
file in
the directory referenced by the ``(Default)`` value.)
If a string value named ``ExecutableArguments`` exists, tools should use the
value as the first arguments when executing ``ExecutablePath``. Tools
may add
other arguments following these, and will reasonably expect standard Python
command line options to be available.
If a string value named ``WindowedExecutablePath`` exists, it must be a
path to
the ``pythonw.exe`` (or equivalent) executable. If omitted, the default
is the
value of ``ExecutablePath``, and if that is omitted the environment is not
executable. (For ``PythonCore``, the default is the ``pythonw.exe`` file
in the
directory referenced by the ``(Default)`` value.)
If a string value named ``WindowedExecutableArguments`` exists, tools
should use
the value as the first arguments when executing ``WindowedExecutablePath``.
Tools may add other arguments following these, and will reasonably expect
standard Python command line options to be available.
A complete example may look like::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\examplepy\InstallPath
(Default) = "C:\ExampleDistro30"
ExecutablePath = "C:\ExampleDistro30\ex_python.exe"
ExecutableArguments = "--arg1"
WindowedExecutablePath = "C:\ExampleDistro30\ex_pythonw.exe"
WindowedExecutableArguments = "--arg1"
Help
----
Beneath the environment key, a ``Help`` key may be created. This key is
always
named ``Help`` if present and has no default value.
Each subkey of ``Help`` specifies a documentation file, tool, or URL
associated
with the environment. The subkey may have any name, and the default
value is a
string appropriate for passing to ``os.startfile`` or equivalent.
If a string value named ``DisplayName`` exists, it should be used to
identify
the help file to users. Otherwise, the key name should be used.
A complete example may look like::
HKEY_CURRENT_USER\Software\Python\ExampleCorp\6C465E66\Help
Python\
(Default) = "C:\ExampleDistro30\python36.chm"
DisplayName = "Python Documentation"
Extras\
(Default) = "http://www.example.com/tutorial"
DisplayName = "Example Distro Online Tutorial"
Other Keys
----------
All other subkeys under a Company-Tag pair are available for private use.
Official CPython releases have traditionally used certain keys in this
space to
determine the location of the Python standard library and other installed
modules. This behaviour is retained primarily for backward compatibility.
However, as the code that reads these values is embedded into the
interpreter,
third-party distributions may be affected by values written into
``PythonCore``
if using an unmodified interpreter.
Sample Code
===========
This sample code enumerates the registry and displays the available
Company-Tag
pairs that could be used to launch an environment and the target
executable. It
only shows the most-preferred target for the tag. Backwards-compatible
handling
of ``PythonCore`` is omitted but shown in a later example::
# Display most-preferred environments.
# Assumes a 64-bit operating system
# Does not correctly handle PythonCore compatibility
import winreg
def enum_keys(key):
i = 0
while True:
try:
yield winreg.EnumKey(key, i)
except OSError:
break
i += 1
def get_value(key, value_name):
try:
return winreg.QueryValue(key, value_name)
except FileNotFoundError:
return None
seen = set()
for hive, key, flags in [
(winreg.HKEY_CURRENT_USER, r'Software\Python', 0),
(winreg.HKEY_LOCAL_MACHINE, r'Software\Python',
winreg.KEY_WOW64_64KEY),
(winreg.HKEY_LOCAL_MACHINE, r'Software\Python',
winreg.KEY_WOW64_32KEY),
]:
with winreg.OpenKeyEx(hive, key, access=winreg.KEY_READ |
flags) as root_key:
for comany in enum_keys(root_key):
if company == 'PyLauncher':
continue
with winreg.OpenKey(root_key, company) as company_key:
for tag in enum_keys(company_key):
if (company, tag) in seen:
if company == 'PythonCore':
# TODO: Backwards compatibility handling
pass
continue
seen.add((company, tag))
try:
with winreg.OpenKey(company_key, tag +
r'\InstallPath') as ip_key:
exec_path = get_value(ip_key,
'ExecutablePath')
exec_args = get_value(ip_key,
'ExecutableArguments')
if company == 'PythonCore' and not
exec_path:
# TODO: Backwards compatibility
handling
pass
except OSError:
exec_path, exec_args = None, None
if exec_path:
print('{}\\{} - {} {}'.format(company, tag,
exec_path, exec_args or ''))
else:
print('{}\\{} - (not
executable)'.format(company, tag))
This example only scans ``PythonCore`` entries for the current user.
Where data
is missing, the defaults as described earlier in the PEP are
substituted. Note
that these defaults are only for use under ``PythonCore``; other
registrations
do not have any default values::
# Only lists per-user PythonCore registrations
# Uses fallback values as described in PEP 514
import os
import winreg
def enum_keys(key):
i = 0
while True:
try:
yield winreg.EnumKey(key, i)
except OSError:
break
i += 1
def get_value(key, value_name):
try:
return winreg.QueryValue(key, value_name)
except FileNotFoundError:
return None
with winreg.OpenKey(winreg.HKEY_CURRENT_USER,
r"Software\Python\PythonCore") as company_key:
print('Company:', get_value(company_key, 'DisplayName') or
'Python Software Foundation')
print('Support:', get_value(company_key, 'SupportUrl') or
'http://www.python.org/')
print()
for tag in enum_keys(company_key):
with winreg.OpenKey(company_key, tag) as tag_key:
print('PythonCore\\' + tag)
print('Name:', get_value(tag_key, 'DisplayName') or
('Python ' + tag))
print('Support:', get_value(tag_key, 'SupportUrl') or
'http://www.python.org/')
print('Version:', get_value(tag_key, 'Version') or tag[:3])
print('SysVersion:', get_value(tag_key, 'SysVersion')
or tag[:3])
# Architecture is unknown because we are in HKCU
# Tools may use alternate approaches to determine
architecture when
# the registration does not specify it.
print('SysArchitecture:', get_value(tag_key,
'SysArchitecture') or '(unknown)')
try:
ip_key = winreg.OpenKey(company_key, tag + '\\InstallPath')
except FileNotFoundError:
pass
else:
with ip_key:
ip = get_value(ip_key, None)
exe = get_value(ip_key, 'ExecutablePath') or
os.path.join(ip, 'python.exe')
exew = get_value(ip_key, 'WindowedExecutablePath')
or os.path.join(ip, 'python.exe')
print('InstallPath:', ip)
print('ExecutablePath:', exe)
print('WindowedExecutablePath:', exew)
print()
This example shows a subset of the registration that will be created by a
just-for-me install of 64-bit Python 3.6.0. Other keys may also be created::
HKEY_CURRENT_USER\Software\Python\PythonCore
(Default) = (value not set)
DisplayName = "Python Software Foundation"
SupportUrl = "http://www.python.org/"
HKEY_CURRENT_USER\Software\Python\PythonCore\3.6
(Default) = (value not set)
DisplayName = "Python 3.6 (64-bit)"
SupportUrl = "http://www.python.org/"
Version = "3.6.0"
SysVersion = "3.6"
SysArchitecture = "64bit"
HKEY_CURRENT_USER\Software\Python\PythonCore\3.6\Help\Main Python
Documentation
(Default) =
"C:\Users\Me\AppData\Local\Programs\Python\Python36\Doc\python360.chm"
DisplayName = "Python 3.6.0 Documentation"
HKEY_CURRENT_USER\Software\Python\PythonCore\3.6\InstallPath
(Default) = "C:\Users\Me\AppData\Local\Programs\Python\Python36\"
ExecutablePath =
"C:\Users\Me\AppData\Local\Programs\Python\Python36\python.exe"
WindowedExecutablePath =
"C:\Users\Me\AppData\Local\Programs\Python\Python36\pythonw.exe"
References
==========
.. [1] Registry Redirector (Windows)
(https://msdn.microsoft.com/en-us/library/windows/desktop/aa384232.aspx)
Copyright
=========
This document has been placed in the public domain.
[View Less]
4
5
HI There,
Maybe I should not post this in the dev group, but I think it has some
relationship on the Python core.
I'm using MySQLdb as the MySQL client. Recently I got a weird problem of
this library. After looking into it, I suspect the problem may related to
the conversion from unsigned long to PyLongObject.
Here is the detail, If you are familiar with MySQLdb, the following snippet
is a way to query the data from MySQL:
connection = MySQLdb.connect(...)
connection.autocommit(True)
try:
…
[View More] cursor = connection.cursor()
if not cursor.execute(sql, values) > 0:
return None
row = cursor.fetchone()
finally:
connection.close()
return row[0]
Sometimes the return value of execute method would be 18446744073709552000
even there is no matched data available. I checked the source code of the
library, the underlying implementation is
https://github.com/farcepest/MySQLdb1/blob/master/_mysql.c#L835,
static PyObject *
_mysql_ConnectionObject_affected_rows(
_mysql_ConnectionObject *self,
PyObject *args)
{
if (!PyArg_ParseTuple(args, "")) return NULL;
check_connection(self);
return PyLong_FromUnsignedLongLong(mysql_affected_rows(&(self->
connection)));
}
And here is the official doc for mysql_affected_rows
http://dev.mysql.com/doc/refman/5.7/en/mysql-affected-rows.html.
Let me give a superficial understanding, please correct me if I were wrong.
In a 64-bit system, the mysql_affected_rows is supposed to return a number
of unsigned long, which means the range should be 0 ~ 2^64
(18446744073709551616), How could it be possible the function
PyLong_FromUnsignedLongLong return a converted value larger than 2^64,
that's what I don't understand.
Does anyone have some ideas of it?
The versions of the components I used:
Python: 2.7.6
MySQL 5.7.11
MySQLdb 1.2.5
Thanks
[View Less]
5
7
Somebody did some research and found some bugs in CPython (IIUC). The
published some questionable fragments. If there's a volunteer we could
probably easily fix these. (I know we already have occasional Coverity
scans and there are other tools too (anybody try lgtm yet?) But this
seems honest research (also Python leaves Ruby in the dust :-):
http://www.viva64.com/en/b/0414/
--
--Guido van Rossum (python.org/~guido)
6
7
ACTIVITY SUMMARY (2016-07-15 - 2016-07-22)
Python tracker at http://bugs.python.org/
To view or respond to any of the issues listed below, click on the issue.
Do NOT respond to this message.
Issues counts and deltas:
open 5586 (+24)
closed 33762 (+47)
total 39348 (+71)
Open issues with patches: 2441
Issues opened (42)
==================
#25507: IDLE: user code 'import tkinter; tkinter.font' should fail
http://bugs.python.org/issue25507 reopened by terry.reedy
#27521: …
[View More]Misleading compress level header on files created with gzip
http://bugs.python.org/issue27521 opened by ddorda
#27524: Update os.path for PEP 519/__fspath__()
http://bugs.python.org/issue27524 opened by brett.cannon
#27526: test_venv.TestEnsurePip fails mysteriously when /tmp is too sm
http://bugs.python.org/issue27526 opened by r.david.murray
#27530: Non-Critical Compiler WARNING: Python Embedding C++11 does not
http://bugs.python.org/issue27530 opened by Daniel Lord
#27534: IDLE: Reduce number and time for user process imports
http://bugs.python.org/issue27534 opened by terry.reedy
#27535: Memory leaks when opening tons of files
http://bugs.python.org/issue27535 opened by Александр Карпинский
#27536: Convert readme to reStructuredText
http://bugs.python.org/issue27536 opened by louis.taylor
#27539: negative Fraction ** negative int not normalized
http://bugs.python.org/issue27539 opened by Vedran.Čačić
#27540: msvcrt.ungetwch() calls _ungetch()
http://bugs.python.org/issue27540 opened by arigo
#27541: Repr of collection's subclasses
http://bugs.python.org/issue27541 opened by serhiy.storchaka
#27544: Document the ABCs for instance/subclass checks of dict view ty
http://bugs.python.org/issue27544 opened by story645
#27546: Integrate tkinter and asyncio (and async)
http://bugs.python.org/issue27546 opened by terry.reedy
#27547: Integer Overflow Crash On float(array.array())
http://bugs.python.org/issue27547 opened by pabstersac
#27558: SystemError with bare `raise` in threading or multiprocessing
http://bugs.python.org/issue27558 opened by Romuald
#27561: Warn against subclassing builtins, and overriding their method
http://bugs.python.org/issue27561 opened by Kirk Hansen
#27562: Import error encodings (Windows xp compatibility)
http://bugs.python.org/issue27562 opened by Iovan Irinel
#27564: 2.7.12 Windows Installer package broken.
http://bugs.python.org/issue27564 opened by busfault
#27565: Offer error context manager for code.interact
http://bugs.python.org/issue27565 opened by Claudiu Saftoiu
#27566: Tools/freeze/winmakemakefile.py clean target should use 'del'
http://bugs.python.org/issue27566 opened by David D
#27568: "HTTPoxy", use of HTTP_PROXY flag supplied by attacker in CGI
http://bugs.python.org/issue27568 opened by remram
#27569: Windows install problems
http://bugs.python.org/issue27569 opened by ricardoe
#27570: Avoid memcpy(. . ., NULL, 0) etc calls
http://bugs.python.org/issue27570 opened by martin.panter
#27572: Support bytes-like objects when base is given to int()
http://bugs.python.org/issue27572 opened by xiang.zhang
#27573: code.interact() should print an exit message
http://bugs.python.org/issue27573 opened by steven.daprano
#27574: Faster parsing keyword arguments
http://bugs.python.org/issue27574 opened by serhiy.storchaka
#27575: dict viewkeys intersection slow for large dicts
http://bugs.python.org/issue27575 opened by David Su2
#27576: An unexpected difference between dict and OrderedDict
http://bugs.python.org/issue27576 opened by belopolsky
#27577: Make implementation and doc of tuple and list more compliant
http://bugs.python.org/issue27577 opened by xiang.zhang
#27578: inspect.findsource raises exception with empty __init__.py
http://bugs.python.org/issue27578 opened by Alexander Todorov
#27579: Add a tutorial for AsyncIO in the documentation
http://bugs.python.org/issue27579 opened by matrixise
#27580: CSV Null Byte Error
http://bugs.python.org/issue27580 opened by bobbyocean
#27581: Fix overflow check in PySequence_Tuple
http://bugs.python.org/issue27581 opened by xiang.zhang
#27582: Mispositioned SyntaxError caret for unknown code points
http://bugs.python.org/issue27582 opened by ncoghlan
#27583: configparser: modifying default_section at runtime
http://bugs.python.org/issue27583 opened by rk
#27584: New addition of vSockets to the python socket module
http://bugs.python.org/issue27584 opened by Cathy Avery
#27585: asyncio.Lock deadlock after cancellation
http://bugs.python.org/issue27585 opened by sss
#27587: Issues, reported by PVS-Studio static analyzer
http://bugs.python.org/issue27587 opened by pavel-belikov
#27588: Type (typing) objects are hashable and comparable for equality
http://bugs.python.org/issue27588 opened by Gareth.Rees
#27589: asyncio doc: issue in as_completed() doc
http://bugs.python.org/issue27589 opened by haypo
#27590: tarfile module next() method hides exceptions
http://bugs.python.org/issue27590 opened by JieGhost
#27591: multiprocessing: Possible uninitialized pointer use in Windows
http://bugs.python.org/issue27591 opened by Rosuav
Most recent 15 issues with no replies (15)
==========================================
#27590: tarfile module next() method hides exceptions
http://bugs.python.org/issue27590
#27589: asyncio doc: issue in as_completed() doc
http://bugs.python.org/issue27589
#27588: Type (typing) objects are hashable and comparable for equality
http://bugs.python.org/issue27588
#27584: New addition of vSockets to the python socket module
http://bugs.python.org/issue27584
#27581: Fix overflow check in PySequence_Tuple
http://bugs.python.org/issue27581
#27577: Make implementation and doc of tuple and list more compliant
http://bugs.python.org/issue27577
#27570: Avoid memcpy(. . ., NULL, 0) etc calls
http://bugs.python.org/issue27570
#27566: Tools/freeze/winmakemakefile.py clean target should use 'del'
http://bugs.python.org/issue27566
#27565: Offer error context manager for code.interact
http://bugs.python.org/issue27565
#27534: IDLE: Reduce number and time for user process imports
http://bugs.python.org/issue27534
#27530: Non-Critical Compiler WARNING: Python Embedding C++11 does not
http://bugs.python.org/issue27530
#27526: test_venv.TestEnsurePip fails mysteriously when /tmp is too sm
http://bugs.python.org/issue27526
#27520: Issue when building PGO
http://bugs.python.org/issue27520
#27511: Add PathLike objects support to BZ2File
http://bugs.python.org/issue27511
#27505: Missing documentation for setting module __class__ attribute
http://bugs.python.org/issue27505
Most recent 15 issues waiting for review (15)
=============================================
#27591: multiprocessing: Possible uninitialized pointer use in Windows
http://bugs.python.org/issue27591
#27584: New addition of vSockets to the python socket module
http://bugs.python.org/issue27584
#27582: Mispositioned SyntaxError caret for unknown code points
http://bugs.python.org/issue27582
#27581: Fix overflow check in PySequence_Tuple
http://bugs.python.org/issue27581
#27574: Faster parsing keyword arguments
http://bugs.python.org/issue27574
#27573: code.interact() should print an exit message
http://bugs.python.org/issue27573
#27572: Support bytes-like objects when base is given to int()
http://bugs.python.org/issue27572
#27570: Avoid memcpy(. . ., NULL, 0) etc calls
http://bugs.python.org/issue27570
#27568: "HTTPoxy", use of HTTP_PROXY flag supplied by attacker in CGI
http://bugs.python.org/issue27568
#27558: SystemError with bare `raise` in threading or multiprocessing
http://bugs.python.org/issue27558
#27546: Integrate tkinter and asyncio (and async)
http://bugs.python.org/issue27546
#27544: Document the ABCs for instance/subclass checks of dict view ty
http://bugs.python.org/issue27544
#27539: negative Fraction ** negative int not normalized
http://bugs.python.org/issue27539
#27536: Convert readme to reStructuredText
http://bugs.python.org/issue27536
#27534: IDLE: Reduce number and time for user process imports
http://bugs.python.org/issue27534
Top 10 most discussed issues (10)
=================================
#23951: Update devguide style to use a similar theme as Docs
http://bugs.python.org/issue23951 12 msgs
#27558: SystemError with bare `raise` in threading or multiprocessing
http://bugs.python.org/issue27558 12 msgs
#1621: Do not assume signed integer overflow behavior
http://bugs.python.org/issue1621 9 msgs
#26662: configure/Makefile doesn't check if "python" command works, ne
http://bugs.python.org/issue26662 9 msgs
#27582: Mispositioned SyntaxError caret for unknown code points
http://bugs.python.org/issue27582 9 msgs
#23262: webbrowser module broken with Firefox 36+
http://bugs.python.org/issue23262 8 msgs
#27469: Unicode filename gets crippled on Windows when drag and drop
http://bugs.python.org/issue27469 8 msgs
#27580: CSV Null Byte Error
http://bugs.python.org/issue27580 8 msgs
#24954: No way to generate or parse timezone as produced by datetime.i
http://bugs.python.org/issue24954 7 msgs
#27561: Warn against subclassing builtins, and overriding their method
http://bugs.python.org/issue27561 7 msgs
Issues closed (45)
==================
#19142: Cross-compile fails trying to execute foreign pgen on build ho
http://bugs.python.org/issue19142 closed by martin.panter
#21708: Deprecate nonstandard behavior of a dumbdbm database
http://bugs.python.org/issue21708 closed by serhiy.storchaka
#24034: Make fails Objects/typeslots.inc
http://bugs.python.org/issue24034 closed by martin.panter
#25393: 'resource' module documentation error
http://bugs.python.org/issue25393 closed by python-dev
#26207: distutils msvccompiler fails due to mspdb140.dll error on debu
http://bugs.python.org/issue26207 closed by steve.dower
#26380: Add an http method enum
http://bugs.python.org/issue26380 closed by ethan.furman
#26559: logging.handlers.MemoryHandler flushes on shutdown but not rem
http://bugs.python.org/issue26559 closed by python-dev
#26696: Document collections.abc.ByteString
http://bugs.python.org/issue26696 closed by brett.cannon
#26844: Wrong error message during import
http://bugs.python.org/issue26844 closed by brett.cannon
#27083: PYTHONCASEOK is ignored on Windows
http://bugs.python.org/issue27083 closed by brett.cannon
#27309: Visual Styles support to tk/tkinter file and message dialogs
http://bugs.python.org/issue27309 closed by steve.dower
#27417: Call CoInitializeEx on startup
http://bugs.python.org/issue27417 closed by steve.dower
#27472: add the 'unix_shell' attribute to test.support
http://bugs.python.org/issue27472 closed by xdegaye
#27512: os.fspath is certain to crash when exception raised in __fspat
http://bugs.python.org/issue27512 closed by brett.cannon
#27515: Dotted name re-import does not rebind after deletion
http://bugs.python.org/issue27515 closed by terry.reedy
#27522: Reference cycle in email.feedparser
http://bugs.python.org/issue27522 closed by r.david.murray
#27523: Silence Socket Depreciation Warnings.
http://bugs.python.org/issue27523 closed by Decorater
#27525: Wrong OS header on file created by gzip module
http://bugs.python.org/issue27525 closed by ddorda
#27527: Make not yielding from or awaiting a coroutine a SyntaxError
http://bugs.python.org/issue27527 closed by r.david.murray
#27528: Document that filterwarnings(message=...) matches the start of
http://bugs.python.org/issue27528 closed by martin.panter
#27529: Tkinter memory leak on OS X
http://bugs.python.org/issue27529 closed by ned.deily
#27531: Documentation for assert_not_called() has wrong signature
http://bugs.python.org/issue27531 closed by berker.peksag
#27532: Dictionary iterator has no len()
http://bugs.python.org/issue27532 closed by r.david.murray
#27533: release GIL in nt._isdir
http://bugs.python.org/issue27533 closed by steve.dower
#27537: Segfault Via Resource Exhaustion
http://bugs.python.org/issue27537 closed by ned.deily
#27538: Segfault on error in code object checking
http://bugs.python.org/issue27538 closed by ned.deily
#27542: Segfault in gcmodule.c:360 visit_decref
http://bugs.python.org/issue27542 closed by ned.deily
#27543: from module import function creates package reference to the m
http://bugs.python.org/issue27543 closed by brett.cannon
#27545: missing pyshellext.vcxproj prevents puilding 3.6
http://bugs.python.org/issue27545 closed by python-dev
#27548: Integer Overflow On bin()
http://bugs.python.org/issue27548 closed by serhiy.storchaka
#27549: Integer Overflow Crash On bytearray()
http://bugs.python.org/issue27549 closed by serhiy.storchaka
#27550: Integer Overflow Crash On Arithmetic Operations
http://bugs.python.org/issue27550 closed by serhiy.storchaka
#27551: Integer Overflow On print()
http://bugs.python.org/issue27551 closed by serhiy.storchaka
#27552: Integer Overflow On min()
http://bugs.python.org/issue27552 closed by serhiy.storchaka
#27553: Integer Overflow On unicode()
http://bugs.python.org/issue27553 closed by serhiy.storchaka
#27554: Integer Overflow On dir()
http://bugs.python.org/issue27554 closed by serhiy.storchaka
#27555: Integer Overflow on oct()
http://bugs.python.org/issue27555 closed by serhiy.storchaka
#27556: Integer overflow on hex()
http://bugs.python.org/issue27556 closed by serhiy.storchaka
#27557: Integer Overflow on int()
http://bugs.python.org/issue27557 closed by serhiy.storchaka
#27559: Crash On bytearray()
http://bugs.python.org/issue27559 closed by martin.panter
#27560: Memory overallocation crash and keyboard interrupt stops worki
http://bugs.python.org/issue27560 closed by martin.panter
#27563: docs for `gc.get_referrers` should explain the result format (
http://bugs.python.org/issue27563 closed by cool-RR
#27567: Add constants EPOLLRDHUP and POLLRDHUP to module select.
http://bugs.python.org/issue27567 closed by python-dev
#27571: 3.6 Seems to be ignoring the _sodium pyd file made with pip.
http://bugs.python.org/issue27571 closed by brett.cannon
#27586: Is this a regular expression library bug?
http://bugs.python.org/issue27586 closed by tim.peters
[View Less]
1
0
Hi list,
another round for PEP 487, is there any chance it still makes it into
Python 3.6?
The PEP should be effectively done, I updated the examples in it,
given that I implemented the PEP I could actually test the examples,
so now they work.
The implementation is at http://bugs.python.org/issue27366, including
documentation and tests. Unfortunately nobody has reviewed the patch
yet.
The new version of the PEP is attached.
Greetings
Martin
PEP: 487
Title: Simpler customisation of class …
[View More]creation
Version: $Revision$
Last-Modified: $Date$
Author: Martin Teichmann <lkb.teichmann(a)gmail.com>,
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 27-Feb-2015
Python-Version: 3.6
Post-History: 27-Feb-2015, 5-Feb-2016, 24-Jun-2016, 2-Jul-2016, 13-Jul-2016
Replaces: 422
Abstract
========
Currently, customising class creation requires the use of a custom metaclass.
This custom metaclass then persists for the entire lifecycle of the class,
creating the potential for spurious metaclass conflicts.
This PEP proposes to instead support a wide range of customisation
scenarios through a new ``__init_subclass__`` hook in the class body,
and a hook to initialize attributes.
The new mechanism should be easier to understand and use than
implementing a custom metaclass, and thus should provide a gentler
introduction to the full power of Python's metaclass machinery.
Background
==========
Metaclasses are a powerful tool to customize class creation. They have,
however, the problem that there is no automatic way to combine metaclasses.
If one wants to use two metaclasses for a class, a new metaclass combining
those two needs to be created, typically manually.
This need often occurs as a surprise to a user: inheriting from two base
classes coming from two different libraries suddenly raises the necessity
to manually create a combined metaclass, where typically one is not
interested in those details about the libraries at all. This becomes
even worse if one library starts to make use of a metaclass which it
has not done before. While the library itself continues to work perfectly,
suddenly every code combining those classes with classes from another library
fails.
Proposal
========
While there are many possible ways to use a metaclass, the vast majority
of use cases falls into just three categories: some initialization code
running after class creation, the initalization of descriptors and
keeping the order in which class attributes were defined.
The first two categories can easily be achieved by having simple hooks
into the class creation:
1. An ``__init_subclass__`` hook that initializes
all subclasses of a given class.
2. upon class creation, a ``__set_owner__`` hook is called on all the
attribute (descriptors) defined in the class, and
The third category is the topic of another PEP 520.
As an example, the first use case looks as follows::
>>> class QuestBase:
... # this is implicitly a @classmethod
... def __init_subclass__(cls, swallow, **kwargs):
... cls.swallow = swallow
... super().__init_subclass__(**kwargs)
>>> class Quest(QuestBase, swallow="african"):
... pass
>>> Quest.swallow
'african'
The base class ``object`` contains an empty ``__init_subclass__``
method which serves as an endpoint for cooperative multiple inheritance.
Note that this method has no keyword arguments, meaning that all
methods which are more specialized have to process all keyword
arguments.
This general proposal is not a new idea (it was first suggested for
inclusion in the language definition `more than 10 years ago`_, and a
similar mechanism has long been supported by `Zope's ExtensionClass`_),
but the situation has changed sufficiently in recent years that
the idea is worth reconsidering for inclusion.
The second part of the proposal adds an ``__set_owner__``
initializer for class attributes, especially if they are descriptors.
Descriptors are defined in the body of a
class, but they do not know anything about that class, they do not
even know the name they are accessed with. They do get to know their
owner once ``__get__`` is called, but still they do not know their
name. This is unfortunate, for example they cannot put their
associated value into their object's ``__dict__`` under their name,
since they do not know that name. This problem has been solved many
times, and is one of the most important reasons to have a metaclass in
a library. While it would be easy to implement such a mechanism using
the first part of the proposal, it makes sense to have one solution
for this problem for everyone.
To give an example of its usage, imagine a descriptor representing weak
referenced values::
import weakref
class WeakAttribute:
def __get__(self, instance, owner):
return instance.__dict__[self.name]()
def __set__(self, instance, value):
instance.__dict__[self.name] = weakref.ref(value)
# this is the new initializer:
def __set_owner__(self, owner, name):
self.name = name
While this example looks very trivial, it should be noted that until
now such an attribute cannot be defined without the use of a metaclass.
And given that such a metaclass can make life very hard, this kind of
attribute does not exist yet.
Initializing descriptors could simply be done in the
``__init_subclass__`` hook. But this would mean that descriptors can
only be used in classes that have the proper hook, the generic version
like in the example would not work generally. One could also call
``__set_owner__`` from whithin the base implementation of
``object.__init_subclass__``. But given that it is a common mistake
to forget to call ``super()``, it would happen too often that suddenly
descriptors are not initialized.
Key Benefits
============
Easier inheritance of definition time behaviour
-----------------------------------------------
Understanding Python's metaclasses requires a deep understanding of
the type system and the class construction process. This is legitimately
seen as challenging, due to the need to keep multiple moving parts (the code,
the metaclass hint, the actual metaclass, the class object, instances of the
class object) clearly distinct in your mind. Even when you know the rules,
it's still easy to make a mistake if you're not being extremely careful.
Understanding the proposed implicit class initialization hook only requires
ordinary method inheritance, which isn't quite as daunting a task. The new
hook provides a more gradual path towards understanding all of the phases
involved in the class definition process.
Reduced chance of metaclass conflicts
-------------------------------------
One of the big issues that makes library authors reluctant to use metaclasses
(even when they would be appropriate) is the risk of metaclass conflicts.
These occur whenever two unrelated metaclasses are used by the desired
parents of a class definition. This risk also makes it very difficult to
*add* a metaclass to a class that has previously been published without one.
By contrast, adding an ``__init_subclass__`` method to an existing type poses
a similar level of risk to adding an ``__init__`` method: technically, there
is a risk of breaking poorly implemented subclasses, but when that occurs,
it is recognised as a bug in the subclass rather than the library author
breaching backwards compatibility guarantees.
New Ways of Using Classes
=========================
Subclass registration
---------------------
Especially when writing a plugin system, one likes to register new
subclasses of a plugin baseclass. This can be done as follows::
class PluginBase(Object):
subclasses = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.subclasses.append(cls)
In this example, ``PluginBase.subclasses`` will contain a plain list of all
subclasses in the entire inheritance tree. One should note that this also
works nicely as a mixin class.
Trait descriptors
-----------------
There are many designs of Python descriptors in the wild which, for
example, check boundaries of values. Often those "traits" need some support
of a metaclass to work. This is how this would look like with this
PEP::
class Trait:
def __init__(self, minimum, maximum):
self.minimum = minimum
self.maximum = maximum
def __get__(self, instance, owner):
return instance.__dict__[self.key]
def __set__(self, instance, value):
if self.minimum < value < self.maximum:
instance.__dict__[self.key] = value
else:
raise ValueError("value not in range")
def __set_owner__(self, owner, name):
self.key = name
Implementation Details
======================
For those who prefer reading Python over english, the following is a Python
equivalent of the C API changes proposed in this PEP, where the new ``object``
and ``type`` defined here inherit from the usual ones::
import types
class type(type):
def __new__(cls, *args, **kwargs):
if len(args) == 1:
return super().__new__(cls, args[0])
name, bases, ns = args
init = ns.get('__init_subclass__')
if isinstance(init, types.FunctionType):
ns['__init_subclass__'] = classmethod(init)
self = super().__new__(cls, name, bases, ns)
for k, v in self.__dict__.items():
func = getattr(v, '__set_owner__', None)
if func is not None:
func(self, k)
super(self, self).__init_subclass__(**kwargs)
return self
def __init__(self, name, bases, ns, **kwargs):
super().__init__(name, bases, ns)
class object:
@classmethod
def __init_subclass__(cls):
pass
class object(object, metaclass=type):
pass
In this code, first the ``__set_owner__`` are called on the descriptors, and
then the ``__init_subclass__``. This means that subclass initializers already
see the fully initialized descriptors. This way, ``__init_subclass__`` users
can fix all descriptors again if this is needed.
Another option would have been to call ``__set_owner__`` in the base
implementation of ``object.__init_subclass__``. This way it would be possible
event to prevent ``__set_owner__`` from being called. Most of the times,
however, such a prevention would be accidental, as it often happens that a call
to ``super()`` is forgotten.
Another small change should be noted here: in the current implementation of
CPython, ``type.__init__`` explicitly forbids the use of keyword arguments,
while ``type.__new__`` allows for its attributes to be shipped as keyword
arguments. This is weirdly incoherent, and thus the above code forbids that.
While it would be possible to retain the current behavior, it would be better
if this was fixed, as it is probably not used at all: the only use case would
be that at metaclass calls its ``super().__new__`` with *name*, *bases* and
*dict* (yes, *dict*, not *namespace* or *ns* as mostly used with modern
metaclasses) as keyword arguments. This should not be done.
As a second change, the new ``type.__init__`` just ignores keyword
arguments. Currently, it insists that no keyword arguments are given. This
leads to a (wanted) error if one gives keyword arguments to a class declaration
if the metaclass does not process them. Metaclass authors that do want to
accept keyword arguments must filter them out by overriding ``__init___``.
In the new code, it is not ``__init__`` that complains about keyword arguments,
but ``__init_subclass__``, whose default implementation takes no arguments. In
a classical inheritance scheme using the method resolution order, each
``__init_subclass__`` may take out it's keyword arguments until none are left,
which is checked by the default implementation of ``__init_subclass__``.
Rejected Design Options
=======================
Calling the hook on the class itself
------------------------------------
Adding an ``__autodecorate__`` hook that would be called on the class
itself was the proposed idea of PEP 422. Most examples work the same
way or even better if the hook is called on the subclass. In general,
it is much easier to explicitly call the hook on the class in which it
is defined (to opt-in to such a behavior) than to opt-out, meaning
that one does not want the hook to be called on the class it is
defined in.
This becomes most evident if the class in question is designed as a
mixin: it is very unlikely that the code of the mixin is to be
executed for the mixin class itself, as it is not supposed to be a
complete class on its own.
The original proposal also made major changes in the class
initialization process, rendering it impossible to back-port the
proposal to older Python versions.
More importantly, having a pure Python implementation allows us to
take two preliminary steps before before we actually change the
interpreter, giving us the chance to iron out all possible wrinkles
in the API.
Other variants of calling the hook
----------------------------------
Other names for the hook were presented, namely ``__decorate__`` or
``__autodecorate__``. This proposal opts for ``__init_subclass__`` as
it is very close to the ``__init__`` method, just for the subclass,
while it is not very close to decorators, as it does not return the
class.
Requiring an explicit decorator on ``__init_subclass__``
--------------------------------------------------------
One could require the explicit use of ``@classmethod`` on the
``__init_subclass__`` decorator. It was made implicit since there's no
sensible interpretation for leaving it out, and that case would need
to be detected anyway in order to give a useful error message.
This decision was reinforced after noticing that the user experience of
defining ``__prepare__`` and forgetting the ``@classmethod`` method
decorator is singularly incomprehensible (particularly since PEP 3115
documents it as an ordinary method, and the current documentation doesn't
explicitly say anything one way or the other).
A more ``__new__``-like hook
----------------------------
In PEP 422 the hook worked more like the ``__new__`` method than the
``__init__`` method, meaning that it returned a class instead of
modifying one. This allows a bit more flexibility, but at the cost
of much harder implementation and undesired side effects.
Adding a class attribute with the attribute order
-------------------------------------------------
This got its own PEP 520.
History
=======
This used to be a competing proposal to PEP 422 by Nick Coghlan and Daniel
Urban. PEP 422 intended to achieve the same goals as this PEP, but with a
different way of implementation. In the meantime, PEP 422 has been withdrawn
favouring this approach.
References
==========
.. _more than 10 years ago:
http://mail.python.org/pipermail/python-dev/2001-November/018651.html
.. _Zope's ExtensionClass:
http://docs.zope.org/zope_secrets/extensionclass.html
Copyright
=========
This document has been placed in the public domain.
..
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End:
[View Less]
8
21