I've received some enthusiastic emails from someone who wants to
revive restricted mode. He started out with a bunch of patches to the
CPython runtime using ctypes, which he attached to an App Engine bug:
http://code.google.com/p/googleappengine/issues/detail?id=671
Based on his code (the file secure.py is all you need, included in
secure.tar.gz) it seems he believes the only security leaks are
__subclasses__, gi_frame and gi_code. (I have since convinced him that
if we add "restricted" guards to these attributes, he doesn't need the
functions added to sys.)
I don't recall the exploits that Samuele once posted that caused the
death of rexec.py -- does anyone recall, or have a pointer to the
threads?
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
Alright, I will re-submit with the contents pasted. I never use double
backquotes as I think them rather ugly; that is the work of an editor
or some automated program in the chain. Plus, it also messed up my
line formatting and now I have lines with one word on them... Anyway,
the contents of PEP 3145:
PEP: 3145
Title: Asynchronous I/O For subprocess.Popen
Author: (James) Eric Pruitt, Charles R. McCreary, Josiah Carlson
Type: Standards Track
Content-Type: text/plain
Created: 04-Aug-2009
Python-Version: 3.2
Abstract:
In its present form, the subprocess.Popen implementation is prone to
dead-locking and blocking of the parent Python script while waiting on data
from the child process.
Motivation:
A search for "python asynchronous subprocess" will turn up numerous
accounts of people wanting to execute a child process and communicate with
it from time to time reading only the data that is available instead of
blocking to wait for the program to produce data [1] [2] [3]. The current
behavior of the subprocess module is that when a user sends or receives
data via the stdin, stderr and stdout file objects, dead locks are common
and documented [4] [5]. While communicate can be used to alleviate some of
the buffering issues, it will still cause the parent process to block while
attempting to read data when none is available to be read from the child
process.
Rationale:
There is a documented need for asynchronous, non-blocking functionality in
subprocess.Popen [6] [7] [2] [3]. Inclusion of the code would improve the
utility of the Python standard library that can be used on Unix based and
Windows builds of Python. Practically every I/O object in Python has a
file-like wrapper of some sort. Sockets already act as such and for
strings there is StringIO. Popen can be made to act like a file by simply
using the methods attached the the subprocess.Popen.stderr, stdout and
stdin file-like objects. But when using the read and write methods of
those options, you do not have the benefit of asynchronous I/O. In the
proposed solution the wrapper wraps the asynchronous methods to mimic a
file object.
Reference Implementation:
I have been maintaining a Google Code repository that contains all of my
changes including tests and documentation [9] as well as blog detailing
the problems I have come across in the development process [10].
I have been working on implementing non-blocking asynchronous I/O in the
subprocess.Popen module as well as a wrapper class for subprocess.Popen
that makes it so that an executed process can take the place of a file by
duplicating all of the methods and attributes that file objects have.
There are two base functions that have been added to the subprocess.Popen
class: Popen.send and Popen._recv, each with two separate implementations,
one for Windows and one for Unix based systems. The Windows
implementation uses ctypes to access the functions needed to control pipes
in the kernel 32 DLL in an asynchronous manner. On Unix based systems,
the Python interface for file control serves the same purpose. The
different implementations of Popen.send and Popen._recv have identical
arguments to make code that uses these functions work across multiple
platforms.
When calling the Popen._recv function, it requires the pipe name be
passed as an argument so there exists the Popen.recv function that passes
selects stdout as the pipe for Popen._recv by default. Popen.recv_err
selects stderr as the pipe by default. "Popen.recv" and "Popen.recv_err"
are much easier to read and understand than "Popen._recv('stdout' ..." and
"Popen._recv('stderr' ..." respectively.
Since the Popen._recv function does not wait on data to be produced
before returning a value, it may return empty bytes. Popen.asyncread
handles this issue by returning all data read over a given time
interval.
The ProcessIOWrapper class uses the asyncread and asyncwrite functions to
allow a process to act like a file so that there are no blocking issues
that can arise from using the stdout and stdin file objects produced from
a subprocess.Popen call.
References:
[1] [ python-Feature Requests-1191964 ] asynchronous Subprocess
http://mail.python.org/pipermail/python-bugs-list/2006-December/
036524.html
[2] Daily Life in an Ivory Basement : /feb-07/problems-with-subprocess
http://ivory.idyll.org/blog/feb-07/problems-with-subprocess
[3] How can I run an external command asynchronously from Python? - Stack
Overflow
http://stackoverflow.com/questions/636561/how-can-i-run-an-external-
command-asynchronously-from-python
[4] 18.1. subprocess - Subprocess management - Python v2.6.2 documentation
http://docs.python.org/library/subprocess.html#subprocess.Popen.wait
[5] 18.1. subprocess - Subprocess management - Python v2.6.2 documentation
http://docs.python.org/library/subprocess.html#subprocess.Popen.kill
[6] Issue 1191964: asynchronous Subprocess - Python tracker
http://bugs.python.org/issue1191964
[7] Module to allow Asynchronous subprocess use on Windows and Posix
platforms - ActiveState Code
http://code.activestate.com/recipes/440554/
[8] subprocess.rst - subprocdev - Project Hosting on Google Code
http://code.google.com/p/subprocdev/source/browse/doc/subprocess.rst?spec=s…
[9] subprocdev - Project Hosting on Google Code
http://code.google.com/p/subprocdev
[10] Python Subprocess Dev
http://subdev.blogspot.com/
Copyright:
This P.E.P. is licensed under the Open Publication License;
http://www.opencontent.org/openpub/.
On Tue, Sep 8, 2009 at 22:56, Benjamin Peterson <benjamin(a)python.org> wrote:
> 2009/9/7 Eric Pruitt <eric.pruitt(a)gmail.com>:
>> Hello all,
>>
>> I have been working on adding asynchronous I/O to the Python
>> subprocess module as part of my Google Summer of Code project. Now
>> that I have finished documenting and pruning the code, I present PEP
>> 3145 for its inclusion into the Python core code. Any and all feedback
>> on the PEP (http://www.python.org/dev/peps/pep-3145/) is appreciated.
>
> Hi Eric,
> One of the reasons you're not getting many response is that you've not
> pasted the contents of the PEP in this message. That makes it really
> easy for people to comment on various sections.
>
> BTW, it seems like you were trying to use reST formatting with the
> text PEP layout. Double backquotes only mean something in reST.
>
>
> --
> Regards,
> Benjamin
>
Hi,
Python code should not depend upon the ordering of items in a dict.
Unfortunately it seems that a number of tests in the standard library do
just that.
Changing PyDict_MINSIZE from 8 to either 4 or 16 causes the following
tests to fail:
test_dis test_email test_inspect test_nntplib test_packaging
test_plistlib test_pprint test_symtable test_trace
test_sys also fails, but this is a legitimate failure in sys.getsizeof()
Changing the collision resolution function from f(n) = 5n + 1 to
f(n) = n + 1 results in the same failures, except for test_packaging and
test_symtable which pass.
Finally, changing the seed in unicode_hash() from (implicit) 0 to an
arbitrary value (12345678) causes the above tests to fail plus:
test_json test_set test_ttk_textonly test_urllib test_urlparse
I think this is a real issue as the unicode_hash() function is likely to
change soon due to http://bugs.python.org/issue13703.
Should I:
1. Submit one big bug report?
2. Submit a bug report for each "failing" test separately?
3. Ignore it, since the tests only fail when I start messing about?
Cheers,
Mark.
In reviewing a fix for the metaclass calculation in __build_class__
[1], I realised that PEP 3115 poses a potential problem for the common
practice of using "type(name, bases, ns)" for dynamic class creation.
Specifically, if one of the base classes has a metaclass with a
significant __prepare__() method, then the current idiom will do the
wrong thing (and most likely fail as a result), since "ns" will
probably be an ordinary dictionary instead of whatever __prepare__()
would have returned.
Initially I was going to suggest making __build_class__ part of the
language definition rather than a CPython implementation detail, but
then I realised that various CPython specific elements in its
signature made that a bad idea.
Instead, I'm thinking along the lines of an
"operator.prepare(metaclass, bases)" function that does the metaclass
calculation dance, invoking __prepare__() and returning the result if
it exists, otherwise returning an ordinary dict. Under the hood we
would refactor this so that operator.prepare and __build_class__ were
using a shared implementation of the functionality at the C level - it
may even be advisable to expose that implementation via the C API as
PyType_PrepareNamespace().
The correct idiom for dynamic type creation in a PEP 3115 world would then be:
from operator import prepare
cls = type(name, bases, prepare(type, bases))
Thoughts?
Cheers,
Nick.
[1] http://bugs.python.org/issue1294232
--
Nick Coghlan | ncoghlan(a)gmail.com | Brisbane, Australia
Does anyone object to me naming myself PEP czar for PEP 3144?
I've collated the objections to the original proposal on a few
different occasions throughout the (long!) PEP review process, and as
noted in the Background section, the latest version of the PEP [1] has
addressed the key concerns that were raised:
- the "strict" flag for Network objects is gone (instead, the
validation differences between IP Network and IP Interface definitions
are handled as different classes with otherwise similar interfaces)
- the factory function naming scheme follows PEP 8
- some properties have been given new names that make it clearer what
kind of object they produce
- the module itself has been given a new name (ipaddress) to avoid
clashing with the existing ipaddr module on PyPI
There's also basic-but-usable module documentation available
(http://code.google.com/p/ipaddr-py/wiki/Using3144).
So, unless there are any new objections, I'd like to:
- approve ipaddress for inclusion in Python 3.3
- grant Peter Moody push access as the module maintainer
- create a tracker issue to cover incorporating the new module into
the standard library, documentation and test suite
(There are still a few places in both the PEP and the preliminary
documentation that say "ipaddr" instead of "ipaddress", but those can
be cleaned up as the module gets integrated).
I don't personally think the module API needs the provisional
disclaimer as the core functionality has been tested for years in
ipaddr and the API changes in ipaddress are just cosmetic ones either
for PEP 8 conformance, or to make the API map more cleanly to the
underlying networking concepts. However, I'd be willing to include
that proviso if anyone else has lingering concerns.
Regards,
Nick.
[1] http://www.python.org/dev/peps/pep-3144/
--
Nick Coghlan | ncoghlan(a)gmail.com | Brisbane, Australia
As requested, I create a PEP and a related issue:
http://www.python.org/dev/peps/pep-0416/http://bugs.python.org/issue14162
The PEP 416 is different from my previous propositions: frozendict
values can be mutable and dict doesn't inherit from frozendict
anymore. But it is still possible to use the PyDict C API on
frozendict (which is more an implementation detail).
TODO:
- write the documentation
- decide if new functions should be added to the C API, maybe a new
PyFrozenDict_New() function? (but would it take a mapping or a list of
tuple?)
--
PEP: 416
Title: Add a frozendict builtin type
Version: $Revision$
Last-Modified: $Date$
Author: Victor Stinner <victor.stinner(a)gmail.com>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 29-February-2012
Python-Version: 3.3
Abstract
========
Add a new frozendict builtin type.
Rationale
=========
A frozendict mapping cannot be changed, but its values can be mutable
(not hashable). A frozendict is hashable and so immutable if all
values are hashable (immutable).
Use cases of frozendict:
* hashable frozendict can be used as a key of a mapping or as a member of set
* frozendict helps optimization because the mapping is constant
* frozendict avoids the need of a lock when the frozendict is shared
by multiple threads or processes, especially hashable frozendict
Constraints
===========
* frozendict has to implement the Mapping abstract base class
* frozendict keys and values can be unorderable
* a frozendict is hashable if all keys and values are hashable
* frozendict hash does not depend on the items creation order
Implementation
==============
* Add a PyFrozenDictObject structure based on PyDictObject with an
extra "Py_hash_t hash;" field
* frozendict.__hash__() is implemented using
hash(frozenset(self.items())) and caches the result in its private
hash attribute
* Register frozendict has a collections.abc.Mapping
* frozendict can be used with PyDict_GetItem(), but PyDict_SetItem()
and PyDict_DelItem() raise a TypeError
Recipe: immutable dict
======================
An immutable mapping can be implemented using frozendict::
import itertools
class immutabledict(frozendict):
def __new__(cls, *args, **kw):
# ensure that all values are immutable
for key, value in itertools.chain(args, kw.items()):
if not isinstance(value, (int, float, complex, str, bytes)):
hash(value)
# frozendict ensures that all keys are immutable
return frozendict.__new__(cls, *args, **kw)
def __repr__(self):
return 'immutabledict' + frozendict.__repr__(self)[10:]
Objections
==========
*namedtuple may fit the requiements of a frozendict.*
A namedtuple is not a mapping, it does not implement the Mapping
abstract base class.
*frozendict can be implemented in Python using descriptors" and
"frozendict just need to be practically constant.*
If frozendict is used to harden Python (security purpose), it must be
implemented in C. A type implemented in C is also faster.
*The PEP 351 was rejected.*
The PEP 351 tries to freeze an object and so may convert a mutable
object to an immutable object (using a different type). frozendict
doesn't convert anything: hash(frozendict) raises a TypeError if a
value is not hashable. Freezing an object is not the purpose of this
PEP.
Links
=====
* PEP 412: Key-Sharing Dictionary (`issue #13903
<http://bugs.python.org/issue13903>`_)
* PEP 351: The freeze protocol
* `The case for immutable dictionaries; and the central
misunderstanding of PEP 351
<http://www.cs.toronto.edu/~tijmen/programming/immutableDictionaries.html>`_
* `Frozen dictionaries (Python recipe 414283)
<http://code.activestate.com/recipes/414283-frozen-dictionaries/>`_ by
Oren Tirosh
Copyright
=========
This document has been placed in the public domain.
Nick Coghlan <ncoghlan <at> gmail.com> writes:
> It reduces the problem (compared to omitting the import and using a
> u() function), but it's still ugly and still involves the "action at a
> distance" of the unicode literals import.
I agree about the action-at-a-distance leading to non-obvious bugs and wasted
head-scratching time caused by such. It could be mitigated somewhat by
project-level conventions, e.g. that all string literals are Unicode on that
project. Then, if you put yourself in the relevant mindset when working on that
project, there are fewer surprises.
It's probably a matter of choosing the lesser among evils, since the proposal
seems to allow mixing of literals with and without u prefixes in 3.x code -
doesn't that also seem ugly?
When this came up earlier (when I think Chris McDonough raised it) the issue of
what to do on 3.2 came up, and though it has been addressed somewhat in the PEP,
it would be nice to see the suggested on-installation hook fleshed out a little
more.
Regards,
Vinay Sajip
Rationale
=========
A frozendict type is a common request from users and there are various
implementations. There are two main Python implementations:
* "blacklist": frozendict inheriting from dict and overriding methods
to raise an exception when trying to modify the frozendict
* "whitelist": frozendict not inheriting from dict and only implement
some dict methods, or implement all dict methods but raise exceptions
when trying to modify the frozendict
The blacklist implementation has a major issue: it is still possible
to call write methods of the dict class (e.g. dict.set(my_frozendict,
key, value)).
The whitelist implementation has an issue: frozendict and dict are not
"compatible", dict is not a subclass of frozendict (and frozendict is
not a subclass of dict).
I propose to add a new frozendict builtin type and make dict type
inherits from it. frozendict would not have methods to modify its
content and values must be immutable.
Constraints
===========
* frozendict values must be immutable, as dict keys
* frozendict can be used with the C API of the dict object (e.g.
PyDict_GetItem) but write methods (e.g. PyDict_SetItem) would fail
with a TypeError ("expect dict, got frozendict")
* frozendict.__hash__() has to be determinist
* frozendict has not the following methods: clear, __delitem__, pop,
popitem, setdefault, __setitem__ and update. As tuple/frozenset has
less methods than list/set.
* issubclass(dict, frozendict) is True, whereas
issubclass(frozendict, dict) is False
Implementation
==============
* Add an hash field to the PyDictObject structure
* Make dict inherits from frozendict
* frozendict values are checked for immutability property by calling
their __hash__ method, with a fast-path for known immutable types
(int, float, bytes, str, tuple, frozenset)
* frozendict.__hash__ computes hash(frozenset(self.items())) and
caches the result is its private hash attribute
Attached patch is a work-in-progress implementation.
TODO
====
* Add a frozendict abstract base class to collections?
* frozendict may not overallocate dictionary buckets?
--
Examples of frozendict implementations:
http://bob.pythonmac.org/archives/2005/03/04/frozendict/http://code.activestate.com/recipes/498072-implementing-an-immutable-dictio…http://code.activestate.com/recipes/414283-frozen-dictionaries/http://corebio.googlecode.com/svn/trunk/apidocs/corebio.utils.frozendict-cl…http://code.google.com/p/lingospot/source/browse/trunk/frozendict/frozendic…http://cmssdt.cern.ch/SDT/doxygen/CMSSW_4_4_2/doc/html/d6/d2f/classfrozendi…
See also the recent discussion on python-list:
http://mail.python.org/pipermail/python-list/2012-February/1287658.html
--
See also the PEP 351.
Victor
Hi,
I just uploaded PEP 414 which proposes am optional 'u' prefix for string
literals for Python 3.
You can read the PEP online: http://www.python.org/dev/peps/pep-0414/
This is a followup to the discussion about this topic here on the
mailinglist and on twitter/IRC over the last few weeks.
Regards,
Armin
State of PEP-3118 (memoryview part)
Hello,
In Python 3.3 most issues with the memoryview object have been fixed
in a recent commit (3f9b3b6f7ff0). Many features have been added, see:
http://docs.python.org/dev/whatsnew/3.3.html
The underlying problems with memoryview were intricate and required
a long discussion (issue #10181) that led to a complete rewrite
of memoryobject.c.
We have several options with regard to 2.7 and 3.2:
1) Won't fix.
2) Backport the changes and disable as much of the new functionality
as possible.
3) Backport all of it (this would be the least amount of work and
could be done relatively quickly).
4) Nick suggested another option: put a module with the new functionality
on PyPI. This would be quite a bit of work, and personally I don't
have time for that.
Options 2) and 3) would ideally entail one backwards incompatible
bugfix: In 2.7 and 3.2 assignment to a memoryview with format 'B'
rejects integers but accepts byte objects, but according to the
struct syntax mandated by the PEP it should be the other way round.
It would be nice to get some opinions and ideas, especially of course
from the release managers.
Stefan Krah