Fix lists-in-blockquotes in 0xxx PEPs. Ref: #26914
This commit is contained in:
parent
4d8ea1d0fe
commit
af90430776
144
pep-0302.txt
144
pep-0302.txt
|
@ -34,15 +34,15 @@ The only way to customize the import mechanism is currently to override the
|
|||
built-in ``__import__`` function. However, overriding ``__import__`` has many
|
||||
problems. To begin with:
|
||||
|
||||
* An ``__import__`` replacement needs to *fully* reimplement the entire
|
||||
import mechanism, or call the original ``__import__`` before or after the
|
||||
custom code.
|
||||
* An ``__import__`` replacement needs to *fully* reimplement the entire
|
||||
import mechanism, or call the original ``__import__`` before or after the
|
||||
custom code.
|
||||
|
||||
* It has very complex semantics and responsibilities.
|
||||
* It has very complex semantics and responsibilities.
|
||||
|
||||
* ``__import__`` gets called even for modules that are already in
|
||||
``sys.modules``, which is almost never what you want, unless you're writing
|
||||
some sort of monitoring tool.
|
||||
* ``__import__`` gets called even for modules that are already in
|
||||
``sys.modules``, which is almost never what you want, unless you're writing
|
||||
some sort of monitoring tool.
|
||||
|
||||
The situation gets worse when you need to extend the import mechanism from C:
|
||||
it's currently impossible, apart from hacking Python's ``import.c`` or
|
||||
|
@ -233,61 +233,61 @@ being available in ``sys.modules``.
|
|||
The ``load_module()`` method has a few responsibilities that it must fulfill
|
||||
*before* it runs any code:
|
||||
|
||||
* If there is an existing module object named 'fullname' in ``sys.modules``,
|
||||
the loader must use that existing module. (Otherwise, the ``reload()``
|
||||
builtin will not work correctly.) If a module named 'fullname' does not
|
||||
exist in ``sys.modules``, the loader must create a new module object and
|
||||
add it to ``sys.modules``.
|
||||
* If there is an existing module object named 'fullname' in ``sys.modules``,
|
||||
the loader must use that existing module. (Otherwise, the ``reload()``
|
||||
builtin will not work correctly.) If a module named 'fullname' does not
|
||||
exist in ``sys.modules``, the loader must create a new module object and
|
||||
add it to ``sys.modules``.
|
||||
|
||||
Note that the module object *must* be in ``sys.modules`` before the loader
|
||||
executes the module code. This is crucial because the module code may
|
||||
(directly or indirectly) import itself; adding it to ``sys.modules``
|
||||
beforehand prevents unbounded recursion in the worst case and multiple
|
||||
loading in the best.
|
||||
Note that the module object *must* be in ``sys.modules`` before the loader
|
||||
executes the module code. This is crucial because the module code may
|
||||
(directly or indirectly) import itself; adding it to ``sys.modules``
|
||||
beforehand prevents unbounded recursion in the worst case and multiple
|
||||
loading in the best.
|
||||
|
||||
If the load fails, the loader needs to remove any module it may have
|
||||
inserted into ``sys.modules``. If the module was already in ``sys.modules``
|
||||
then the loader should leave it alone.
|
||||
If the load fails, the loader needs to remove any module it may have
|
||||
inserted into ``sys.modules``. If the module was already in ``sys.modules``
|
||||
then the loader should leave it alone.
|
||||
|
||||
* The ``__file__`` attribute must be set. This must be a string, but it may
|
||||
be a dummy value, for example "<frozen>". The privilege of not having a
|
||||
``__file__`` attribute at all is reserved for built-in modules.
|
||||
* The ``__file__`` attribute must be set. This must be a string, but it may
|
||||
be a dummy value, for example "<frozen>". The privilege of not having a
|
||||
``__file__`` attribute at all is reserved for built-in modules.
|
||||
|
||||
* The ``__name__`` attribute must be set. If one uses ``imp.new_module()``
|
||||
then the attribute is set automatically.
|
||||
* The ``__name__`` attribute must be set. If one uses ``imp.new_module()``
|
||||
then the attribute is set automatically.
|
||||
|
||||
* If it's a package, the ``__path__`` variable must be set. This must be a
|
||||
list, but may be empty if ``__path__`` has no further significance to the
|
||||
importer (more on this later).
|
||||
* If it's a package, the ``__path__`` variable must be set. This must be a
|
||||
list, but may be empty if ``__path__`` has no further significance to the
|
||||
importer (more on this later).
|
||||
|
||||
* The ``__loader__`` attribute must be set to the loader object. This is
|
||||
mostly for introspection and reloading, but can be used for
|
||||
importer-specific extras, for example getting data associated with an
|
||||
importer.
|
||||
* The ``__loader__`` attribute must be set to the loader object. This is
|
||||
mostly for introspection and reloading, but can be used for
|
||||
importer-specific extras, for example getting data associated with an
|
||||
importer.
|
||||
|
||||
* The ``__package__`` attribute [8]_ must be set.
|
||||
* The ``__package__`` attribute [8]_ must be set.
|
||||
|
||||
If the module is a Python module (as opposed to a built-in module or a
|
||||
dynamically loaded extension), it should execute the module's code in the
|
||||
module's global name space (``module.__dict__``).
|
||||
If the module is a Python module (as opposed to a built-in module or a
|
||||
dynamically loaded extension), it should execute the module's code in the
|
||||
module's global name space (``module.__dict__``).
|
||||
|
||||
Here is a minimal pattern for a ``load_module()`` method::
|
||||
Here is a minimal pattern for a ``load_module()`` method::
|
||||
|
||||
# Consider using importlib.util.module_for_loader() to handle
|
||||
# most of these details for you.
|
||||
def load_module(self, fullname):
|
||||
code = self.get_code(fullname)
|
||||
ispkg = self.is_package(fullname)
|
||||
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
|
||||
mod.__file__ = "<%s>" % self.__class__.__name__
|
||||
mod.__loader__ = self
|
||||
if ispkg:
|
||||
mod.__path__ = []
|
||||
mod.__package__ = fullname
|
||||
else:
|
||||
mod.__package__ = fullname.rpartition('.')[0]
|
||||
exec(code, mod.__dict__)
|
||||
return mod
|
||||
# Consider using importlib.util.module_for_loader() to handle
|
||||
# most of these details for you.
|
||||
def load_module(self, fullname):
|
||||
code = self.get_code(fullname)
|
||||
ispkg = self.is_package(fullname)
|
||||
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
|
||||
mod.__file__ = "<%s>" % self.__class__.__name__
|
||||
mod.__loader__ = self
|
||||
if ispkg:
|
||||
mod.__path__ = []
|
||||
mod.__package__ = fullname
|
||||
else:
|
||||
mod.__package__ = fullname.rpartition('.')[0]
|
||||
exec(code, mod.__dict__)
|
||||
return mod
|
||||
|
||||
|
||||
Specification part 2: Registering Hooks
|
||||
|
@ -326,8 +326,8 @@ rescan of ``sys.path_hooks``, it is possible to manually clear all or part of
|
|||
Just like ``sys.path`` itself, the new ``sys`` variables must have specific
|
||||
types:
|
||||
|
||||
* ``sys.meta_path`` and ``sys.path_hooks`` must be Python lists.
|
||||
* ``sys.path_importer_cache`` must be a Python dict.
|
||||
* ``sys.meta_path`` and ``sys.path_hooks`` must be Python lists.
|
||||
* ``sys.path_importer_cache`` must be a Python dict.
|
||||
|
||||
Modifying these variables in place is allowed, as is replacing them with new
|
||||
objects.
|
||||
|
@ -457,26 +457,26 @@ hook.
|
|||
|
||||
There are a number of possible ways to address this problem:
|
||||
|
||||
* "Don't do that". If a package needs to locate data files via its
|
||||
``__path__``, it is not suitable for loading via an import hook. The
|
||||
package can still be located on a directory in ``sys.path``, as at present,
|
||||
so this should not be seen as a major issue.
|
||||
* "Don't do that". If a package needs to locate data files via its
|
||||
``__path__``, it is not suitable for loading via an import hook. The
|
||||
package can still be located on a directory in ``sys.path``, as at present,
|
||||
so this should not be seen as a major issue.
|
||||
|
||||
* Locate data files from a standard location, rather than relative to the
|
||||
module file. A relatively simple approach (which is supported by
|
||||
distutils) would be to locate data files based on ``sys.prefix`` (or
|
||||
``sys.exec_prefix``). For example, looking in
|
||||
``os.path.join(sys.prefix, "data", package_name)``.
|
||||
* Locate data files from a standard location, rather than relative to the
|
||||
module file. A relatively simple approach (which is supported by
|
||||
distutils) would be to locate data files based on ``sys.prefix`` (or
|
||||
``sys.exec_prefix``). For example, looking in
|
||||
``os.path.join(sys.prefix, "data", package_name)``.
|
||||
|
||||
* Import hooks could offer a standard way of getting at data files relative
|
||||
to the module file. The standard ``zipimport`` object provides a method
|
||||
``get_data(name)`` which returns the content of the "file" called ``name``,
|
||||
as a string. To allow modules to get at the importer object, ``zipimport``
|
||||
also adds an attribute ``__loader__`` to the module, containing the
|
||||
``zipimport`` object used to load the module. If such an approach is used,
|
||||
it is important that client code takes care not to break if the
|
||||
``get_data()`` method is not available, so it is not clear that this
|
||||
approach offers a general answer to the problem.
|
||||
* Import hooks could offer a standard way of getting at data files relative
|
||||
to the module file. The standard ``zipimport`` object provides a method
|
||||
``get_data(name)`` which returns the content of the "file" called ``name``,
|
||||
as a string. To allow modules to get at the importer object, ``zipimport``
|
||||
also adds an attribute ``__loader__`` to the module, containing the
|
||||
``zipimport`` object used to load the module. If such an approach is used,
|
||||
it is important that client code takes care not to break if the
|
||||
``get_data()`` method is not available, so it is not clear that this
|
||||
approach offers a general answer to the problem.
|
||||
|
||||
It was suggested on python-dev that it would be useful to be able to receive a
|
||||
list of available modules from an importer and/or a list of available data
|
||||
|
|
12
pep-0327.txt
12
pep-0327.txt
|
@ -499,12 +499,12 @@ From float
|
|||
The initial discussion on this item was what should
|
||||
happen when passing floating point to the constructor:
|
||||
|
||||
1. ``Decimal(1.1) == Decimal('1.1')``
|
||||
1. ``Decimal(1.1) == Decimal('1.1')``
|
||||
|
||||
2. ``Decimal(1.1) ==
|
||||
Decimal('110000000000000008881784197001252...e-51')``
|
||||
2. ``Decimal(1.1) ==
|
||||
Decimal('110000000000000008881784197001252...e-51')``
|
||||
|
||||
3. an exception is raised
|
||||
3. an exception is raised
|
||||
|
||||
Several people alleged that (1) is the better option here, because
|
||||
it's what you expect when writing ``Decimal(1.1)``. And quoting John
|
||||
|
@ -1180,14 +1180,14 @@ Context.
|
|||
|
||||
These are methods that return useful information from the Context:
|
||||
|
||||
- ``Etiny()``: Minimum exponent considering precision.
|
||||
- ``Etiny()``: Minimum exponent considering precision. ::
|
||||
|
||||
>>> c.Emin
|
||||
-999999999
|
||||
>>> c.Etiny()
|
||||
-1000000007
|
||||
|
||||
- ``Etop()``: Maximum exponent considering precision.
|
||||
- ``Etop()``: Maximum exponent considering precision. ::
|
||||
|
||||
>>> c.Emax
|
||||
999999999
|
||||
|
|
102
pep-0339.txt
102
pep-0339.txt
|
@ -428,12 +428,12 @@ Important Files
|
|||
|
||||
+ Parser/
|
||||
|
||||
- Python.asdl
|
||||
ASDL syntax file
|
||||
- Python.asdl
|
||||
ASDL syntax file
|
||||
|
||||
- asdl.py
|
||||
"An implementation of the Zephyr Abstract Syntax Definition
|
||||
Language." Uses SPARK_ to parse the ASDL files.
|
||||
- asdl.py
|
||||
"An implementation of the Zephyr Abstract Syntax Definition
|
||||
Language." Uses SPARK_ to parse the ASDL files.
|
||||
|
||||
- asdl_c.py
|
||||
"Generate C code from an ASDL description." Generates
|
||||
|
@ -444,86 +444,86 @@ Important Files
|
|||
|
||||
+ Python/
|
||||
|
||||
- Python-ast.c
|
||||
Creates C structs corresponding to the ASDL types. Also
|
||||
- Python-ast.c
|
||||
Creates C structs corresponding to the ASDL types. Also
|
||||
contains code for marshaling AST nodes (core ASDL types have
|
||||
marshaling code in asdl.c). "File automatically generated by
|
||||
Parser/asdl_c.py". This file must be committed separately
|
||||
after every grammar change is committed since the __version__
|
||||
value is set to the latest grammar change revision number.
|
||||
after every grammar change is committed since the __version__
|
||||
value is set to the latest grammar change revision number.
|
||||
|
||||
- asdl.c
|
||||
Contains code to handle the ASDL sequence type. Also has code
|
||||
to handle marshalling the core ASDL types, such as number and
|
||||
identifier. used by Python-ast.c for marshaling AST nodes.
|
||||
- asdl.c
|
||||
Contains code to handle the ASDL sequence type. Also has code
|
||||
to handle marshalling the core ASDL types, such as number and
|
||||
identifier. used by Python-ast.c for marshaling AST nodes.
|
||||
|
||||
- ast.c
|
||||
Converts Python's parse tree into the abstract syntax tree.
|
||||
- ast.c
|
||||
Converts Python's parse tree into the abstract syntax tree.
|
||||
|
||||
- ceval.c
|
||||
Executes byte code (aka, eval loop).
|
||||
- ceval.c
|
||||
Executes byte code (aka, eval loop).
|
||||
|
||||
- compile.c
|
||||
Emits bytecode based on the AST.
|
||||
- compile.c
|
||||
Emits bytecode based on the AST.
|
||||
|
||||
- symtable.c
|
||||
- symtable.c
|
||||
Generates a symbol table from AST.
|
||||
|
||||
- pyarena.c
|
||||
Implementation of the arena memory manager.
|
||||
- pyarena.c
|
||||
Implementation of the arena memory manager.
|
||||
|
||||
- import.c
|
||||
Home of the magic number (named ``MAGIC``) for bytecode versioning
|
||||
- import.c
|
||||
Home of the magic number (named ``MAGIC``) for bytecode versioning
|
||||
|
||||
|
||||
+ Include/
|
||||
|
||||
- Python-ast.h
|
||||
Contains the actual definitions of the C structs as generated by
|
||||
Python/Python-ast.c .
|
||||
"Automatically generated by Parser/asdl_c.py".
|
||||
- Python-ast.h
|
||||
Contains the actual definitions of the C structs as generated by
|
||||
Python/Python-ast.c .
|
||||
"Automatically generated by Parser/asdl_c.py".
|
||||
|
||||
- asdl.h
|
||||
Header for the corresponding Python/ast.c .
|
||||
- asdl.h
|
||||
Header for the corresponding Python/ast.c .
|
||||
|
||||
- ast.h
|
||||
Declares PyAST_FromNode() external (from Python/ast.c).
|
||||
- ast.h
|
||||
Declares PyAST_FromNode() external (from Python/ast.c).
|
||||
|
||||
- code.h
|
||||
- code.h
|
||||
Header file for Objects/codeobject.c; contains definition of
|
||||
PyCodeObject.
|
||||
|
||||
- symtable.h
|
||||
- symtable.h
|
||||
Header for Python/symtable.c . struct symtable and
|
||||
PySTEntryObject are defined here.
|
||||
|
||||
- pyarena.h
|
||||
Header file for the corresponding Python/pyarena.c .
|
||||
- pyarena.h
|
||||
Header file for the corresponding Python/pyarena.c .
|
||||
|
||||
- opcode.h
|
||||
Master list of bytecode; if this file is modified you must modify
|
||||
several other files accordingly (see "`Introducing New Bytecode`_")
|
||||
- opcode.h
|
||||
Master list of bytecode; if this file is modified you must modify
|
||||
several other files accordingly (see "`Introducing New Bytecode`_")
|
||||
|
||||
+ Objects/
|
||||
|
||||
- codeobject.c
|
||||
Contains PyCodeObject-related code (originally in
|
||||
Python/compile.c).
|
||||
- codeobject.c
|
||||
Contains PyCodeObject-related code (originally in
|
||||
Python/compile.c).
|
||||
|
||||
+ Lib/
|
||||
|
||||
- opcode.py
|
||||
One of the files that must be modified if Include/opcode.h is.
|
||||
- opcode.py
|
||||
One of the files that must be modified if Include/opcode.h is.
|
||||
|
||||
- compiler/
|
||||
- compiler/
|
||||
|
||||
* pyassem.py
|
||||
One of the files that must be modified if Include/opcode.h is
|
||||
changed.
|
||||
* pyassem.py
|
||||
One of the files that must be modified if Include/opcode.h is
|
||||
changed.
|
||||
|
||||
* pycodegen.py
|
||||
One of the files that must be modified if Include/opcode.h is
|
||||
changed.
|
||||
* pycodegen.py
|
||||
One of the files that must be modified if Include/opcode.h is
|
||||
changed.
|
||||
|
||||
|
||||
Known Compiler-related Experiments
|
||||
|
|
100
pep-0362.txt
100
pep-0362.txt
|
@ -151,32 +151,32 @@ A Parameter object has the following public attributes and methods:
|
|||
Describes how argument values are bound to the parameter.
|
||||
Possible values:
|
||||
|
||||
* ``Parameter.POSITIONAL_ONLY`` - value must be supplied
|
||||
as a positional argument.
|
||||
* ``Parameter.POSITIONAL_ONLY`` - value must be supplied
|
||||
as a positional argument.
|
||||
|
||||
Python has no explicit syntax for defining positional-only
|
||||
parameters, but many built-in and extension module functions
|
||||
(especially those that accept only one or two parameters)
|
||||
accept them.
|
||||
Python has no explicit syntax for defining positional-only
|
||||
parameters, but many built-in and extension module functions
|
||||
(especially those that accept only one or two parameters)
|
||||
accept them.
|
||||
|
||||
* ``Parameter.POSITIONAL_OR_KEYWORD`` - value may be
|
||||
supplied as either a keyword or positional argument
|
||||
(this is the standard binding behaviour for functions
|
||||
implemented in Python.)
|
||||
* ``Parameter.POSITIONAL_OR_KEYWORD`` - value may be
|
||||
supplied as either a keyword or positional argument
|
||||
(this is the standard binding behaviour for functions
|
||||
implemented in Python.)
|
||||
|
||||
* ``Parameter.KEYWORD_ONLY`` - value must be supplied
|
||||
as a keyword argument. Keyword only parameters are those
|
||||
which appear after a "*" or "\*args" entry in a Python
|
||||
function definition.
|
||||
* ``Parameter.KEYWORD_ONLY`` - value must be supplied
|
||||
as a keyword argument. Keyword only parameters are those
|
||||
which appear after a "*" or "\*args" entry in a Python
|
||||
function definition.
|
||||
|
||||
* ``Parameter.VAR_POSITIONAL`` - a tuple of positional
|
||||
arguments that aren't bound to any other parameter.
|
||||
This corresponds to a "\*args" parameter in a Python
|
||||
function definition.
|
||||
* ``Parameter.VAR_POSITIONAL`` - a tuple of positional
|
||||
arguments that aren't bound to any other parameter.
|
||||
This corresponds to a "\*args" parameter in a Python
|
||||
function definition.
|
||||
|
||||
* ``Parameter.VAR_KEYWORD`` - a dict of keyword arguments
|
||||
that aren't bound to any other parameter. This corresponds
|
||||
to a "\*\*kwargs" parameter in a Python function definition.
|
||||
* ``Parameter.VAR_KEYWORD`` - a dict of keyword arguments
|
||||
that aren't bound to any other parameter. This corresponds
|
||||
to a "\*\*kwargs" parameter in a Python function definition.
|
||||
|
||||
Always use ``Parameter.*`` constants for setting and checking
|
||||
value of the ``kind`` attribute.
|
||||
|
@ -271,39 +271,39 @@ a callable object.
|
|||
|
||||
The function implements the following algorithm:
|
||||
|
||||
- If the object is not callable - raise a TypeError
|
||||
- If the object is not callable - raise a TypeError
|
||||
|
||||
- If the object has a ``__signature__`` attribute and if it
|
||||
is not ``None`` - return it
|
||||
- If the object has a ``__signature__`` attribute and if it
|
||||
is not ``None`` - return it
|
||||
|
||||
- If it has a ``__wrapped__`` attribute, return
|
||||
``signature(object.__wrapped__)``
|
||||
- If it has a ``__wrapped__`` attribute, return
|
||||
``signature(object.__wrapped__)``
|
||||
|
||||
- If the object is an instance of ``FunctionType``, construct
|
||||
and return a new ``Signature`` for it
|
||||
- If the object is an instance of ``FunctionType``, construct
|
||||
and return a new ``Signature`` for it
|
||||
|
||||
- If the object is a bound method, construct and return a new ``Signature``
|
||||
object, with its first parameter (usually ``self`` or ``cls``)
|
||||
removed. (``classmethod`` and ``staticmethod`` are supported
|
||||
too. Since both are descriptors, the former returns a bound method,
|
||||
and the latter returns its wrapped function.)
|
||||
- If the object is a bound method, construct and return a new ``Signature``
|
||||
object, with its first parameter (usually ``self`` or ``cls``)
|
||||
removed. (``classmethod`` and ``staticmethod`` are supported
|
||||
too. Since both are descriptors, the former returns a bound method,
|
||||
and the latter returns its wrapped function.)
|
||||
|
||||
- If the object is an instance of ``functools.partial``, construct
|
||||
a new ``Signature`` from its ``partial.func`` attribute, and
|
||||
account for already bound ``partial.args`` and ``partial.kwargs``
|
||||
- If the object is an instance of ``functools.partial``, construct
|
||||
a new ``Signature`` from its ``partial.func`` attribute, and
|
||||
account for already bound ``partial.args`` and ``partial.kwargs``
|
||||
|
||||
- If the object is a class or metaclass:
|
||||
- If the object is a class or metaclass:
|
||||
|
||||
- If the object's type has a ``__call__`` method defined in
|
||||
its MRO, return a Signature for it
|
||||
- If the object's type has a ``__call__`` method defined in
|
||||
its MRO, return a Signature for it
|
||||
|
||||
- If the object has a ``__new__`` method defined in its MRO,
|
||||
return a Signature object for it
|
||||
- If the object has a ``__new__`` method defined in its MRO,
|
||||
return a Signature object for it
|
||||
|
||||
- If the object has a ``__init__`` method defined in its MRO,
|
||||
return a Signature object for it
|
||||
- If the object has a ``__init__`` method defined in its MRO,
|
||||
return a Signature object for it
|
||||
|
||||
- Return ``signature(object.__call__)``
|
||||
- Return ``signature(object.__call__)``
|
||||
|
||||
Note that the ``Signature`` object is created in a lazy manner, and
|
||||
is not automatically cached. However, the user can manually cache a
|
||||
|
@ -323,13 +323,13 @@ The first PEP design had a provision for implicit caching of ``Signature``
|
|||
objects in the ``inspect.signature()`` function. However, this has the
|
||||
following downsides:
|
||||
|
||||
* If the ``Signature`` object is cached then any changes to the function
|
||||
it describes will not be reflected in it. However, If the caching is
|
||||
needed, it can be always done manually and explicitly
|
||||
* If the ``Signature`` object is cached then any changes to the function
|
||||
it describes will not be reflected in it. However, If the caching is
|
||||
needed, it can be always done manually and explicitly
|
||||
|
||||
* It is better to reserve the ``__signature__`` attribute for the cases
|
||||
when there is a need to explicitly set to a ``Signature`` object that
|
||||
is different from the actual one
|
||||
* It is better to reserve the ``__signature__`` attribute for the cases
|
||||
when there is a need to explicitly set to a ``Signature`` object that
|
||||
is different from the actual one
|
||||
|
||||
|
||||
Some functions may not be introspectable
|
||||
|
|
26
pep-0364.txt
26
pep-0364.txt
|
@ -206,23 +206,23 @@ object:
|
|||
Open Issues
|
||||
===========
|
||||
|
||||
- Should there be a command line switch and/or environment variable to
|
||||
disable all remappings?
|
||||
- Should there be a command line switch and/or environment variable to
|
||||
disable all remappings?
|
||||
|
||||
- Should remappings occur recursively?
|
||||
- Should remappings occur recursively?
|
||||
|
||||
- Should we automatically parse package directories for .mv files when
|
||||
the package's __init__.py is loaded? This would allow packages to
|
||||
easily include .mv files for their own remappings. Compare what the
|
||||
email package currently has to do if we place its ``.mv`` file in
|
||||
the email package instead of in the oldlib package::
|
||||
- Should we automatically parse package directories for .mv files when
|
||||
the package's __init__.py is loaded? This would allow packages to
|
||||
easily include .mv files for their own remappings. Compare what the
|
||||
email package currently has to do if we place its ``.mv`` file in
|
||||
the email package instead of in the oldlib package::
|
||||
|
||||
# Expose old names
|
||||
import os, sys
|
||||
sys.stdlib_remapper.read_directory_mv_files(os.path.dirname(__file__))
|
||||
# Expose old names
|
||||
import os, sys
|
||||
sys.stdlib_remapper.read_directory_mv_files(os.path.dirname(__file__))
|
||||
|
||||
I think we should automatically read a package's directory for any
|
||||
``.mv`` files it might contain.
|
||||
I think we should automatically read a package's directory for any
|
||||
``.mv`` files it might contain.
|
||||
|
||||
|
||||
Reference Implementation
|
||||
|
|
|
@ -317,6 +317,7 @@ Copyright
|
|||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
|
@ -325,4 +326,3 @@ This document has been placed in the public domain.
|
|||
fill-column: 70
|
||||
coding: utf-8
|
||||
End:
|
||||
|
||||
|
|
57
pep-0380.txt
57
pep-0380.txt
|
@ -85,35 +85,35 @@ value becomes the value of the ``yield from`` expression.
|
|||
The full semantics of the ``yield from`` expression can be described
|
||||
in terms of the generator protocol as follows:
|
||||
|
||||
* Any values that the iterator yields are passed directly to the
|
||||
caller.
|
||||
* Any values that the iterator yields are passed directly to the
|
||||
caller.
|
||||
|
||||
* Any values sent to the delegating generator using ``send()`` are
|
||||
passed directly to the iterator. If the sent value is None, the
|
||||
iterator's ``__next__()`` method is called. If the sent value
|
||||
is not None, the iterator's ``send()`` method is called. If the
|
||||
call raises StopIteration, the delegating generator is resumed.
|
||||
Any other exception is propagated to the delegating generator.
|
||||
* Any values sent to the delegating generator using ``send()`` are
|
||||
passed directly to the iterator. If the sent value is None, the
|
||||
iterator's ``__next__()`` method is called. If the sent value
|
||||
is not None, the iterator's ``send()`` method is called. If the
|
||||
call raises StopIteration, the delegating generator is resumed.
|
||||
Any other exception is propagated to the delegating generator.
|
||||
|
||||
* Exceptions other than GeneratorExit thrown into the delegating
|
||||
generator are passed to the ``throw()`` method of the iterator.
|
||||
If the call raises StopIteration, the delegating generator is
|
||||
resumed. Any other exception is propagated to the delegating
|
||||
generator.
|
||||
* Exceptions other than GeneratorExit thrown into the delegating
|
||||
generator are passed to the ``throw()`` method of the iterator.
|
||||
If the call raises StopIteration, the delegating generator is
|
||||
resumed. Any other exception is propagated to the delegating
|
||||
generator.
|
||||
|
||||
* If a GeneratorExit exception is thrown into the delegating
|
||||
generator, or the ``close()`` method of the delegating generator
|
||||
is called, then the ``close()`` method of the iterator is called
|
||||
if it has one. If this call results in an exception, it is
|
||||
propagated to the delegating generator. Otherwise,
|
||||
GeneratorExit is raised in the delegating generator.
|
||||
* If a GeneratorExit exception is thrown into the delegating
|
||||
generator, or the ``close()`` method of the delegating generator
|
||||
is called, then the ``close()`` method of the iterator is called
|
||||
if it has one. If this call results in an exception, it is
|
||||
propagated to the delegating generator. Otherwise,
|
||||
GeneratorExit is raised in the delegating generator.
|
||||
|
||||
* The value of the ``yield from`` expression is the first argument
|
||||
to the ``StopIteration`` exception raised by the iterator when
|
||||
it terminates.
|
||||
* The value of the ``yield from`` expression is the first argument
|
||||
to the ``StopIteration`` exception raised by the iterator when
|
||||
it terminates.
|
||||
|
||||
* ``return expr`` in a generator causes ``StopIteration(expr)`` to
|
||||
be raised upon exit from the generator.
|
||||
* ``return expr`` in a generator causes ``StopIteration(expr)`` to
|
||||
be raised upon exit from the generator.
|
||||
|
||||
|
||||
Enhancements to StopIteration
|
||||
|
@ -133,7 +133,7 @@ Python 3 syntax is used in this section.
|
|||
|
||||
RESULT = yield from EXPR
|
||||
|
||||
is semantically equivalent to ::
|
||||
is semantically equivalent to ::
|
||||
|
||||
_i = iter(EXPR)
|
||||
try:
|
||||
|
@ -180,12 +180,12 @@ is semantically equivalent to ::
|
|||
|
||||
return value
|
||||
|
||||
is semantically equivalent to ::
|
||||
is semantically equivalent to ::
|
||||
|
||||
raise StopIteration(value)
|
||||
|
||||
except that, as currently, the exception cannot be caught by
|
||||
``except`` clauses within the returning generator.
|
||||
except that, as currently, the exception cannot be caught by
|
||||
``except`` clauses within the returning generator.
|
||||
|
||||
3. The StopIteration exception behaves as though defined thusly::
|
||||
|
||||
|
@ -469,6 +469,7 @@ Copyright
|
|||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
|
|
20
pep-0382.txt
20
pep-0382.txt
|
@ -117,16 +117,16 @@ No other change to the importing mechanism is made; searching modules
|
|||
encountered. In summary, the process import a package foo works like
|
||||
this:
|
||||
|
||||
1. sys.path is searched for directories foo or foo.pyp, or a file foo.<ext>.
|
||||
If a file is found and no directory, it is treated as a module, and imported.
|
||||
2. If a directory foo is found, a check is made whether it contains __init__.py.
|
||||
If so, the location of the __init__.py is remembered. Otherwise, the directory
|
||||
is skipped. Once an __init__.py is found, further directories called foo are
|
||||
skipped.
|
||||
3. For both directories foo and foo.pyp, the directories are added to the package's
|
||||
__path__.
|
||||
4. If an __init__ module was found, it is imported, with __path__
|
||||
being initialized to the path computed all ``.pyp`` directories.
|
||||
1. sys.path is searched for directories foo or foo.pyp, or a file foo.<ext>.
|
||||
If a file is found and no directory, it is treated as a module, and imported.
|
||||
2. If a directory foo is found, a check is made whether it contains __init__.py.
|
||||
If so, the location of the __init__.py is remembered. Otherwise, the directory
|
||||
is skipped. Once an __init__.py is found, further directories called foo are
|
||||
skipped.
|
||||
3. For both directories foo and foo.pyp, the directories are added to the package's
|
||||
__path__.
|
||||
4. If an __init__ module was found, it is imported, with __path__
|
||||
being initialized to the path computed all ``.pyp`` directories.
|
||||
|
||||
Impact on Import Hooks
|
||||
----------------------
|
||||
|
|
16
pep-0393.txt
16
pep-0393.txt
|
@ -110,10 +110,12 @@ The fields have the following interpretations:
|
|||
- length: number of code points in the string (result of sq_length)
|
||||
- interned: interned-state (SSTATE_*) as in 3.2
|
||||
- kind: form of string
|
||||
+ 00 => str is not initialized (data are in wstr)
|
||||
+ 01 => 1 byte (Latin-1)
|
||||
+ 10 => 2 byte (UCS-2)
|
||||
+ 11 => 4 byte (UCS-4);
|
||||
|
||||
+ 00 => str is not initialized (data are in wstr)
|
||||
+ 01 => 1 byte (Latin-1)
|
||||
+ 10 => 2 byte (UCS-2)
|
||||
+ 11 => 4 byte (UCS-4);
|
||||
|
||||
- compact: the object uses one of the compact representations
|
||||
(implies ready)
|
||||
- ascii: the object uses the PyASCIIObject representation
|
||||
|
@ -189,9 +191,9 @@ PyUnicode_2BYTE_KIND (2), or PyUnicode_4BYTE_KIND (3). PyUnicode_DATA
|
|||
gives the void pointer to the data. Access to individual characters
|
||||
should use PyUnicode_{READ|WRITE}[_CHAR]:
|
||||
|
||||
- PyUnicode_READ(kind, data, index)
|
||||
- PyUnicode_WRITE(kind, data, index, value)
|
||||
- PyUnicode_READ_CHAR(unicode, index)
|
||||
- PyUnicode_READ(kind, data, index)
|
||||
- PyUnicode_WRITE(kind, data, index, value)
|
||||
- PyUnicode_READ_CHAR(unicode, index)
|
||||
|
||||
All these macros assume that the string is in canonical form;
|
||||
callers need to ensure this by calling PyUnicode_READY.
|
||||
|
|
170
pep-0400.txt
170
pep-0400.txt
|
@ -77,72 +77,72 @@ Rationale
|
|||
StreamReader and StreamWriter issues
|
||||
''''''''''''''''''''''''''''''''''''
|
||||
|
||||
* StreamReader is unable to translate newlines.
|
||||
* StreamWriter doesn't support "line buffering" (flush if the input
|
||||
text contains a newline).
|
||||
* StreamReader classes of the CJK encodings (e.g. GB18030) only
|
||||
supports UNIX newlines ('\\n').
|
||||
* StreamReader and StreamWriter are stateful codecs but don't expose
|
||||
functions to control their state (getstate() or setstate()). Each
|
||||
codec has to handle corner cases, see `Appendix A`_.
|
||||
* StreamReader and StreamWriter are very similar to IncrementalReader
|
||||
and IncrementalEncoder, some code is duplicated for stateful codecs
|
||||
(e.g. UTF-16).
|
||||
* Each codec has to reimplement its own StreamReader and StreamWriter
|
||||
class, even if it's trivial (just call the encoder/decoder).
|
||||
* codecs.open(filename, "r") creates a io.TextIOWrapper object.
|
||||
* No codec implements an optimized method in StreamReader or
|
||||
StreamWriter based on the specificities of the codec.
|
||||
* StreamReader is unable to translate newlines.
|
||||
* StreamWriter doesn't support "line buffering" (flush if the input
|
||||
text contains a newline).
|
||||
* StreamReader classes of the CJK encodings (e.g. GB18030) only
|
||||
supports UNIX newlines ('\\n').
|
||||
* StreamReader and StreamWriter are stateful codecs but don't expose
|
||||
functions to control their state (getstate() or setstate()). Each
|
||||
codec has to handle corner cases, see `Appendix A`_.
|
||||
* StreamReader and StreamWriter are very similar to IncrementalReader
|
||||
and IncrementalEncoder, some code is duplicated for stateful codecs
|
||||
(e.g. UTF-16).
|
||||
* Each codec has to reimplement its own StreamReader and StreamWriter
|
||||
class, even if it's trivial (just call the encoder/decoder).
|
||||
* codecs.open(filename, "r") creates a io.TextIOWrapper object.
|
||||
* No codec implements an optimized method in StreamReader or
|
||||
StreamWriter based on the specificities of the codec.
|
||||
|
||||
Issues in the bug tracker:
|
||||
|
||||
* `Issue #5445 <http://bugs.python.org/issue5445>`_ (2009-03-08):
|
||||
codecs.StreamWriter.writelines problem when passed generator
|
||||
* `Issue #7262: <http://bugs.python.org/issue7262>`_ (2009-11-04):
|
||||
codecs.open() + eol (windows)
|
||||
* `Issue #8260 <http://bugs.python.org/issue8260>`_ (2010-03-29):
|
||||
When I use codecs.open(...) and f.readline() follow up by f.read()
|
||||
return bad result
|
||||
* `Issue #8630 <http://bugs.python.org/issue8630>`_ (2010-05-05):
|
||||
Keepends param in codec readline(s)
|
||||
* `Issue #10344 <http://bugs.python.org/issue10344>`_ (2010-11-06):
|
||||
codecs.readline doesn't care buffering
|
||||
* `Issue #11461 <http://bugs.python.org/issue11461>`_ (2011-03-10):
|
||||
Reading UTF-16 with codecs.readline() breaks on surrogate pairs
|
||||
* `Issue #12446 <http://bugs.python.org/issue12446>`_ (2011-06-30):
|
||||
StreamReader Readlines behavior odd
|
||||
* `Issue #12508 <http://bugs.python.org/issue12508>`_ (2011-07-06):
|
||||
Codecs Anomaly
|
||||
* `Issue #12512 <http://bugs.python.org/issue12512>`_ (2011-07-07):
|
||||
codecs: StreamWriter issues with stateful codecs after a seek or
|
||||
with append mode
|
||||
* `Issue #12513 <http://bugs.python.org/issue12513>`_ (2011-07-07):
|
||||
codec.StreamReaderWriter: issues with interlaced read-write
|
||||
* `Issue #5445 <http://bugs.python.org/issue5445>`_ (2009-03-08):
|
||||
codecs.StreamWriter.writelines problem when passed generator
|
||||
* `Issue #7262: <http://bugs.python.org/issue7262>`_ (2009-11-04):
|
||||
codecs.open() + eol (windows)
|
||||
* `Issue #8260 <http://bugs.python.org/issue8260>`_ (2010-03-29):
|
||||
When I use codecs.open(...) and f.readline() follow up by f.read()
|
||||
return bad result
|
||||
* `Issue #8630 <http://bugs.python.org/issue8630>`_ (2010-05-05):
|
||||
Keepends param in codec readline(s)
|
||||
* `Issue #10344 <http://bugs.python.org/issue10344>`_ (2010-11-06):
|
||||
codecs.readline doesn't care buffering
|
||||
* `Issue #11461 <http://bugs.python.org/issue11461>`_ (2011-03-10):
|
||||
Reading UTF-16 with codecs.readline() breaks on surrogate pairs
|
||||
* `Issue #12446 <http://bugs.python.org/issue12446>`_ (2011-06-30):
|
||||
StreamReader Readlines behavior odd
|
||||
* `Issue #12508 <http://bugs.python.org/issue12508>`_ (2011-07-06):
|
||||
Codecs Anomaly
|
||||
* `Issue #12512 <http://bugs.python.org/issue12512>`_ (2011-07-07):
|
||||
codecs: StreamWriter issues with stateful codecs after a seek or
|
||||
with append mode
|
||||
* `Issue #12513 <http://bugs.python.org/issue12513>`_ (2011-07-07):
|
||||
codec.StreamReaderWriter: issues with interlaced read-write
|
||||
|
||||
TextIOWrapper features
|
||||
''''''''''''''''''''''
|
||||
|
||||
* TextIOWrapper supports any kind of newline, including translating
|
||||
newlines (to UNIX newlines), to read and write.
|
||||
* TextIOWrapper reuses codecs incremental encoders and decoders (no
|
||||
duplication of code).
|
||||
* The io module (TextIOWrapper) is faster than the codecs module
|
||||
(StreamReader). It is implemented in C, whereas codecs is
|
||||
implemented in Python.
|
||||
* TextIOWrapper has a readahead algorithm which speeds up small
|
||||
reads: read character by character or line by line (io is 10x
|
||||
through 25x faster than codecs on these operations).
|
||||
* TextIOWrapper has a write buffer.
|
||||
* TextIOWrapper.tell() is optimized.
|
||||
* TextIOWrapper supports random access (read+write) using a single
|
||||
class which permit to optimize interlaced read-write (but no such
|
||||
optimization is implemented).
|
||||
* TextIOWrapper supports any kind of newline, including translating
|
||||
newlines (to UNIX newlines), to read and write.
|
||||
* TextIOWrapper reuses codecs incremental encoders and decoders (no
|
||||
duplication of code).
|
||||
* The io module (TextIOWrapper) is faster than the codecs module
|
||||
(StreamReader). It is implemented in C, whereas codecs is
|
||||
implemented in Python.
|
||||
* TextIOWrapper has a readahead algorithm which speeds up small
|
||||
reads: read character by character or line by line (io is 10x
|
||||
through 25x faster than codecs on these operations).
|
||||
* TextIOWrapper has a write buffer.
|
||||
* TextIOWrapper.tell() is optimized.
|
||||
* TextIOWrapper supports random access (read+write) using a single
|
||||
class which permit to optimize interlaced read-write (but no such
|
||||
optimization is implemented).
|
||||
|
||||
TextIOWrapper issues
|
||||
''''''''''''''''''''
|
||||
|
||||
* `Issue #12215 <http://bugs.python.org/issue12215>`_ (2011-05-30):
|
||||
TextIOWrapper: issues with interlaced read-write
|
||||
* `Issue #12215 <http://bugs.python.org/issue12215>`_ (2011-05-30):
|
||||
TextIOWrapper: issues with interlaced read-write
|
||||
|
||||
Possible improvements of StreamReader and StreamWriter
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
@ -233,29 +233,29 @@ Stateful codecs
|
|||
|
||||
Python supports the following stateful codecs:
|
||||
|
||||
* cp932
|
||||
* cp949
|
||||
* cp950
|
||||
* euc_jis_2004
|
||||
* euc_jisx2003
|
||||
* euc_jp
|
||||
* euc_kr
|
||||
* gb18030
|
||||
* gbk
|
||||
* hz
|
||||
* iso2022_jp
|
||||
* iso2022_jp_1
|
||||
* iso2022_jp_2
|
||||
* iso2022_jp_2004
|
||||
* iso2022_jp_3
|
||||
* iso2022_jp_ext
|
||||
* iso2022_kr
|
||||
* shift_jis
|
||||
* shift_jis_2004
|
||||
* shift_jisx0213
|
||||
* utf_8_sig
|
||||
* utf_16
|
||||
* utf_32
|
||||
* cp932
|
||||
* cp949
|
||||
* cp950
|
||||
* euc_jis_2004
|
||||
* euc_jisx2003
|
||||
* euc_jp
|
||||
* euc_kr
|
||||
* gb18030
|
||||
* gbk
|
||||
* hz
|
||||
* iso2022_jp
|
||||
* iso2022_jp_1
|
||||
* iso2022_jp_2
|
||||
* iso2022_jp_2004
|
||||
* iso2022_jp_3
|
||||
* iso2022_jp_ext
|
||||
* iso2022_kr
|
||||
* shift_jis
|
||||
* shift_jis_2004
|
||||
* shift_jisx0213
|
||||
* utf_8_sig
|
||||
* utf_16
|
||||
* utf_32
|
||||
|
||||
Read and seek(0)
|
||||
''''''''''''''''
|
||||
|
@ -312,13 +312,13 @@ writes a new BOM on the second write (`issue #12512
|
|||
Links
|
||||
=====
|
||||
|
||||
* `PEP 100: Python Unicode Integration
|
||||
<http://www.python.org/dev/peps/pep-0100/>`_
|
||||
* `PEP 3116: New I/O <http://www.python.org/dev/peps/pep-3116/>`_
|
||||
* `Issue #8796: Deprecate codecs.open()
|
||||
<http://bugs.python.org/issue8796>`_
|
||||
* `[python-dev] Deprecate codecs.open() and StreamWriter/StreamReader
|
||||
<http://mail.python.org/pipermail/python-dev/2011-May/111591.html>`_
|
||||
* `PEP 100: Python Unicode Integration
|
||||
<http://www.python.org/dev/peps/pep-0100/>`_
|
||||
* `PEP 3116: New I/O <http://www.python.org/dev/peps/pep-3116/>`_
|
||||
* `Issue #8796: Deprecate codecs.open()
|
||||
<http://bugs.python.org/issue8796>`_
|
||||
* `[python-dev] Deprecate codecs.open() and StreamWriter/StreamReader
|
||||
<http://mail.python.org/pipermail/python-dev/2011-May/111591.html>`_
|
||||
|
||||
|
||||
Copyright
|
||||
|
|
10
pep-0403.txt
10
pep-0403.txt
|
@ -176,11 +176,11 @@ statement, anonymous functions could still be incredibly useful. Consider how
|
|||
many constructs Python has where one expression is responsible for the bulk of
|
||||
the heavy lifting:
|
||||
|
||||
* comprehensions, generator expressions, map(), filter()
|
||||
* key arguments to sorted(), min(), max()
|
||||
* partial function application
|
||||
* provision of callbacks (e.g. for weak references or aysnchronous IO)
|
||||
* array broadcast operations in NumPy
|
||||
* comprehensions, generator expressions, map(), filter()
|
||||
* key arguments to sorted(), min(), max()
|
||||
* partial function application
|
||||
* provision of callbacks (e.g. for weak references or aysnchronous IO)
|
||||
* array broadcast operations in NumPy
|
||||
|
||||
However, adopting Ruby's block syntax directly won't work for Python, since
|
||||
the effectiveness of Ruby's blocks relies heavily on various conventions in
|
||||
|
|
|
@ -32,7 +32,7 @@ Un-release Schedule
|
|||
|
||||
The current un-schedule is:
|
||||
|
||||
- 2.8 final Never
|
||||
- 2.8 final Never
|
||||
|
||||
|
||||
Official pronouncement
|
||||
|
|
114
pep-0410.txt
114
pep-0410.txt
|
@ -32,8 +32,8 @@ Python 2.3 introduced float timestamps to support sub-second resolutions.
|
|||
os.stat() uses float timestamps by default since Python 2.5. Python 3.3
|
||||
introduced functions supporting nanosecond resolutions:
|
||||
|
||||
* os module: futimens(), utimensat()
|
||||
* time module: clock_gettime(), clock_getres(), monotonic(), wallclock()
|
||||
* os module: futimens(), utimensat()
|
||||
* time module: clock_gettime(), clock_getres(), monotonic(), wallclock()
|
||||
|
||||
os.stat() reads nanosecond timestamps but returns timestamps as float.
|
||||
|
||||
|
@ -74,24 +74,24 @@ precision. The clock resolution can also be stored in a Decimal object.
|
|||
|
||||
Add an optional *timestamp* argument to:
|
||||
|
||||
* os module: fstat(), fstatat(), lstat(), stat() (st_atime,
|
||||
st_ctime and st_mtime fields of the stat structure),
|
||||
sched_rr_get_interval(), times(), wait3() and wait4()
|
||||
* resource module: ru_utime and ru_stime fields of getrusage()
|
||||
* signal module: getitimer(), setitimer()
|
||||
* time module: clock(), clock_gettime(), clock_getres(),
|
||||
monotonic(), time() and wallclock()
|
||||
* os module: fstat(), fstatat(), lstat(), stat() (st_atime,
|
||||
st_ctime and st_mtime fields of the stat structure),
|
||||
sched_rr_get_interval(), times(), wait3() and wait4()
|
||||
* resource module: ru_utime and ru_stime fields of getrusage()
|
||||
* signal module: getitimer(), setitimer()
|
||||
* time module: clock(), clock_gettime(), clock_getres(),
|
||||
monotonic(), time() and wallclock()
|
||||
|
||||
The *timestamp* argument value can be float or Decimal, float is still the
|
||||
default for backward compatibility. The following functions support Decimal as
|
||||
input:
|
||||
|
||||
* datetime module: date.fromtimestamp(), datetime.fromtimestamp() and
|
||||
datetime.utcfromtimestamp()
|
||||
* os module: futimes(), futimesat(), lutimes(), utime()
|
||||
* select module: epoll.poll(), kqueue.control(), select()
|
||||
* signal module: setitimer(), sigtimedwait()
|
||||
* time module: ctime(), gmtime(), localtime(), sleep()
|
||||
* datetime module: date.fromtimestamp(), datetime.fromtimestamp() and
|
||||
datetime.utcfromtimestamp()
|
||||
* os module: futimes(), futimesat(), lutimes(), utime()
|
||||
* select module: epoll.poll(), kqueue.control(), select()
|
||||
* signal module: setitimer(), sigtimedwait()
|
||||
* time module: ctime(), gmtime(), localtime(), sleep()
|
||||
|
||||
The os.stat_float_times() function is deprecated: use an explicit cast using
|
||||
int() instead.
|
||||
|
@ -132,22 +132,22 @@ Alternatives: Timestamp types
|
|||
To support timestamps with an arbitrary or nanosecond resolution, the following
|
||||
types have been considered:
|
||||
|
||||
* decimal.Decimal
|
||||
* number of nanoseconds
|
||||
* 128-bits float
|
||||
* datetime.datetime
|
||||
* datetime.timedelta
|
||||
* tuple of integers
|
||||
* timespec structure
|
||||
* decimal.Decimal
|
||||
* number of nanoseconds
|
||||
* 128-bits float
|
||||
* datetime.datetime
|
||||
* datetime.timedelta
|
||||
* tuple of integers
|
||||
* timespec structure
|
||||
|
||||
Criteria:
|
||||
|
||||
* Doing arithmetic on timestamps must be possible
|
||||
* Timestamps must be comparable
|
||||
* An arbitrary resolution, or at least a resolution of one nanosecond without
|
||||
losing precision
|
||||
* It should be possible to coerce the new timestamp to float for backward
|
||||
compatibility
|
||||
* Doing arithmetic on timestamps must be possible
|
||||
* Timestamps must be comparable
|
||||
* An arbitrary resolution, or at least a resolution of one nanosecond without
|
||||
losing precision
|
||||
* It should be possible to coerce the new timestamp to float for backward
|
||||
compatibility
|
||||
|
||||
|
||||
A resolution of one nanosecond is enough to support all current C functions.
|
||||
|
@ -264,39 +264,39 @@ an arbitrary limit like one nanosecond.
|
|||
|
||||
Different formats have been proposed:
|
||||
|
||||
* A: (numerator, denominator)
|
||||
* A: (numerator, denominator)
|
||||
|
||||
* value = numerator / denominator
|
||||
* resolution = 1 / denominator
|
||||
* denominator > 0
|
||||
* value = numerator / denominator
|
||||
* resolution = 1 / denominator
|
||||
* denominator > 0
|
||||
|
||||
* B: (seconds, numerator, denominator)
|
||||
* B: (seconds, numerator, denominator)
|
||||
|
||||
* value = seconds + numerator / denominator
|
||||
* resolution = 1 / denominator
|
||||
* 0 <= numerator < denominator
|
||||
* denominator > 0
|
||||
* value = seconds + numerator / denominator
|
||||
* resolution = 1 / denominator
|
||||
* 0 <= numerator < denominator
|
||||
* denominator > 0
|
||||
|
||||
* C: (intpart, floatpart, base, exponent)
|
||||
* C: (intpart, floatpart, base, exponent)
|
||||
|
||||
* value = intpart + floatpart / base\ :sup:`exponent`
|
||||
* resolution = 1 / base \ :sup:`exponent`
|
||||
* 0 <= floatpart < base \ :sup:`exponent`
|
||||
* base > 0
|
||||
* exponent >= 0
|
||||
* value = intpart + floatpart / base\ :sup:`exponent`
|
||||
* resolution = 1 / base \ :sup:`exponent`
|
||||
* 0 <= floatpart < base \ :sup:`exponent`
|
||||
* base > 0
|
||||
* exponent >= 0
|
||||
|
||||
* D: (intpart, floatpart, exponent)
|
||||
* D: (intpart, floatpart, exponent)
|
||||
|
||||
* value = intpart + floatpart / 10\ :sup:`exponent`
|
||||
* resolution = 1 / 10 \ :sup:`exponent`
|
||||
* 0 <= floatpart < 10 \ :sup:`exponent`
|
||||
* exponent >= 0
|
||||
* value = intpart + floatpart / 10\ :sup:`exponent`
|
||||
* resolution = 1 / 10 \ :sup:`exponent`
|
||||
* 0 <= floatpart < 10 \ :sup:`exponent`
|
||||
* exponent >= 0
|
||||
|
||||
* E: (sec, nsec)
|
||||
* E: (sec, nsec)
|
||||
|
||||
* value = sec + nsec × 10\ :sup:`-9`
|
||||
* resolution = 10 \ :sup:`-9` (nanosecond)
|
||||
* 0 <= nsec < 10 \ :sup:`9`
|
||||
* value = sec + nsec × 10\ :sup:`-9`
|
||||
* resolution = 10 \ :sup:`-9` (nanosecond)
|
||||
* 0 <= nsec < 10 \ :sup:`9`
|
||||
|
||||
All formats support an arbitrary resolution, except of the format (E).
|
||||
|
||||
|
@ -490,11 +490,11 @@ Add new functions
|
|||
|
||||
Add new functions for each type, examples:
|
||||
|
||||
* time.clock_decimal()
|
||||
* time.time_decimal()
|
||||
* os.stat_decimal()
|
||||
* os.stat_timespec()
|
||||
* etc.
|
||||
* time.clock_decimal()
|
||||
* time.time_decimal()
|
||||
* os.stat_decimal()
|
||||
* os.stat_timespec()
|
||||
* etc.
|
||||
|
||||
Adding a new function for each function creating timestamps duplicate a lot of
|
||||
code and would be a pain to maintain.
|
||||
|
|
226
pep-0416.txt
226
pep-0416.txt
|
@ -15,22 +15,22 @@ Rejection Notice
|
|||
|
||||
I'm rejecting this PEP. A number of reasons (not exhaustive):
|
||||
|
||||
* According to Raymond Hettinger, use of frozendict is low. Those
|
||||
that do use it tend to use it as a hint only, such as declaring
|
||||
global or class-level "constants": they aren't really immutable,
|
||||
since anyone can still assign to the name.
|
||||
* There are existing idioms for avoiding mutable default values.
|
||||
* The potential of optimizing code using frozendict in PyPy is
|
||||
unsure; a lot of other things would have to change first. The same
|
||||
holds for compile-time lookups in general.
|
||||
* Multiple threads can agree by convention not to mutate a shared
|
||||
dict, there's no great need for enforcement. Multiple processes
|
||||
can't share dicts.
|
||||
* Adding a security sandbox written in Python, even with a limited
|
||||
scope, is frowned upon by many, due to the inherent difficulty with
|
||||
ever proving that the sandbox is actually secure. Because of this
|
||||
we won't be adding one to the stdlib any time soon, so this use
|
||||
case falls outside the scope of a PEP.
|
||||
* According to Raymond Hettinger, use of frozendict is low. Those
|
||||
that do use it tend to use it as a hint only, such as declaring
|
||||
global or class-level "constants": they aren't really immutable,
|
||||
since anyone can still assign to the name.
|
||||
* There are existing idioms for avoiding mutable default values.
|
||||
* The potential of optimizing code using frozendict in PyPy is
|
||||
unsure; a lot of other things would have to change first. The same
|
||||
holds for compile-time lookups in general.
|
||||
* Multiple threads can agree by convention not to mutate a shared
|
||||
dict, there's no great need for enforcement. Multiple processes
|
||||
can't share dicts.
|
||||
* Adding a security sandbox written in Python, even with a limited
|
||||
scope, is frowned upon by many, due to the inherent difficulty with
|
||||
ever proving that the sandbox is actually secure. Because of this
|
||||
we won't be adding one to the stdlib any time soon, so this use
|
||||
case falls outside the scope of a PEP.
|
||||
|
||||
On the other hand, exposing the existing read-only dict proxy as a
|
||||
built-in type sounds good to me. (It would need to be changed to
|
||||
|
@ -55,46 +55,46 @@ hashable. A frozendict is hashable if and only if all values are hashable.
|
|||
|
||||
Use cases:
|
||||
|
||||
* Immutable global variable like a default configuration.
|
||||
* Default value of a function parameter. Avoid the issue of mutable default
|
||||
arguments.
|
||||
* Implement a cache: frozendict can be used to store function keywords.
|
||||
frozendict can be used as a key of a mapping or as a member of set.
|
||||
* frozendict avoids the need of a lock when the frozendict is shared
|
||||
by multiple threads or processes, especially hashable frozendict. It would
|
||||
also help to prohibe coroutines (generators + greenlets) to modify the
|
||||
global state.
|
||||
* frozendict lookup can be done at compile time instead of runtime because the
|
||||
mapping is read-only. frozendict can be used instead of a preprocessor to
|
||||
remove conditional code at compilation, like code specific to a debug build.
|
||||
* frozendict helps to implement read-only object proxies for security modules.
|
||||
For example, it would be possible to use frozendict type for __builtins__
|
||||
mapping or type.__dict__. This is possible because frozendict is compatible
|
||||
with the PyDict C API.
|
||||
* frozendict avoids the need of a read-only proxy in some cases. frozendict is
|
||||
faster than a proxy because getting an item in a frozendict is a fast lookup
|
||||
whereas a proxy requires a function call.
|
||||
* Immutable global variable like a default configuration.
|
||||
* Default value of a function parameter. Avoid the issue of mutable default
|
||||
arguments.
|
||||
* Implement a cache: frozendict can be used to store function keywords.
|
||||
frozendict can be used as a key of a mapping or as a member of set.
|
||||
* frozendict avoids the need of a lock when the frozendict is shared
|
||||
by multiple threads or processes, especially hashable frozendict. It would
|
||||
also help to prohibe coroutines (generators + greenlets) to modify the
|
||||
global state.
|
||||
* frozendict lookup can be done at compile time instead of runtime because the
|
||||
mapping is read-only. frozendict can be used instead of a preprocessor to
|
||||
remove conditional code at compilation, like code specific to a debug build.
|
||||
* frozendict helps to implement read-only object proxies for security modules.
|
||||
For example, it would be possible to use frozendict type for __builtins__
|
||||
mapping or type.__dict__. This is possible because frozendict is compatible
|
||||
with the PyDict C API.
|
||||
* frozendict avoids the need of a read-only proxy in some cases. frozendict is
|
||||
faster than a proxy because getting an item in a frozendict is a fast lookup
|
||||
whereas a proxy requires a function call.
|
||||
|
||||
|
||||
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
|
||||
* 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 as a collections.abc.Mapping
|
||||
* frozendict can be used with PyDict_GetItem(), but PyDict_SetItem() and
|
||||
PyDict_DelItem() raise a TypeError
|
||||
* 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 as a collections.abc.Mapping
|
||||
* frozendict can be used with PyDict_GetItem(), but PyDict_SetItem() and
|
||||
PyDict_DelItem() raise a TypeError
|
||||
|
||||
|
||||
Recipe: hashable dict
|
||||
|
@ -161,90 +161,90 @@ Existing implementations
|
|||
|
||||
Whitelist approach.
|
||||
|
||||
* `Implementing an Immutable Dictionary (Python recipe 498072)
|
||||
<http://code.activestate.com/recipes/498072/>`_ by Aristotelis Mikropoulos.
|
||||
Similar to frozendict except that it is not truly read-only: it is possible
|
||||
to access to this private internal dict. It does not implement __hash__ and
|
||||
has an implementation issue: it is possible to call again __init__() to
|
||||
modify the mapping.
|
||||
* PyWebmail contains an ImmutableDict type: `webmail.utils.ImmutableDict
|
||||
<http://pywebmail.cvs.sourceforge.net/viewvc/pywebmail/webmail/webmail/utils/ImmutableDict.py?revision=1.2&view=markup>`_.
|
||||
It is hashable if keys and values are hashable. It is not truly read-only:
|
||||
its internal dict is a public attribute.
|
||||
* remember project: `remember.dicts.FrozenDict
|
||||
<https://bitbucket.org/mikegraham/remember/src/tip/remember/dicts.py>`_.
|
||||
It is used to implement a cache: FrozenDict is used to store function callbacks.
|
||||
FrozenDict may be hashable. It has an extra supply_dict() class method to
|
||||
create a FrozenDict from a dict without copying the dict: store the dict as
|
||||
the internal dict. Implementation issue: __init__() can be called to modify
|
||||
the mapping and the hash may differ depending on item creation order. The
|
||||
mapping is not truly read-only: the internal dict is accessible in Python.
|
||||
* `Implementing an Immutable Dictionary (Python recipe 498072)
|
||||
<http://code.activestate.com/recipes/498072/>`_ by Aristotelis Mikropoulos.
|
||||
Similar to frozendict except that it is not truly read-only: it is possible
|
||||
to access to this private internal dict. It does not implement __hash__ and
|
||||
has an implementation issue: it is possible to call again __init__() to
|
||||
modify the mapping.
|
||||
* PyWebmail contains an ImmutableDict type: `webmail.utils.ImmutableDict
|
||||
<http://pywebmail.cvs.sourceforge.net/viewvc/pywebmail/webmail/webmail/utils/ImmutableDict.py?revision=1.2&view=markup>`_.
|
||||
It is hashable if keys and values are hashable. It is not truly read-only:
|
||||
its internal dict is a public attribute.
|
||||
* remember project: `remember.dicts.FrozenDict
|
||||
<https://bitbucket.org/mikegraham/remember/src/tip/remember/dicts.py>`_.
|
||||
It is used to implement a cache: FrozenDict is used to store function callbacks.
|
||||
FrozenDict may be hashable. It has an extra supply_dict() class method to
|
||||
create a FrozenDict from a dict without copying the dict: store the dict as
|
||||
the internal dict. Implementation issue: __init__() can be called to modify
|
||||
the mapping and the hash may differ depending on item creation order. The
|
||||
mapping is not truly read-only: the internal dict is accessible in Python.
|
||||
|
||||
|
||||
Blacklist approach: inherit from dict and override write methods to raise an
|
||||
exception. It is not truly read-only: it is still possible to call dict methods
|
||||
on such "frozen dictionary" to modify it.
|
||||
|
||||
* brownie: `brownie.datastructures.ImmuatableDict
|
||||
<https://github.com/DasIch/brownie/blob/HEAD/brownie/datastructures/mappings.py>`_.
|
||||
It is hashable if keys and values are hashable. werkzeug project has the
|
||||
same code: `werkzeug.datastructures.ImmutableDict
|
||||
<https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/datastructures.py>`_.
|
||||
ImmutableDict is used for global constant (configuration options). The Flask
|
||||
project uses ImmutableDict of werkzeug for its default configuration.
|
||||
* SQLAchemy project: `sqlachemy.util.immutabledict
|
||||
<http://hg.sqlalchemy.org/sqlalchemy/file/tip/lib/sqlalchemy/util/_collections.py>`_.
|
||||
It is not hashable and has an extra method: union(). immutabledict is used
|
||||
for the default value of parameter of some functions expecting a mapping.
|
||||
Example: mapper_args=immutabledict() in SqlSoup.map().
|
||||
* `Frozen dictionaries (Python recipe 414283) <http://code.activestate.com/recipes/414283/>`_
|
||||
by Oren Tirosh. It is hashable if keys and values are hashable. Included in
|
||||
the following projects:
|
||||
* brownie: `brownie.datastructures.ImmuatableDict
|
||||
<https://github.com/DasIch/brownie/blob/HEAD/brownie/datastructures/mappings.py>`_.
|
||||
It is hashable if keys and values are hashable. werkzeug project has the
|
||||
same code: `werkzeug.datastructures.ImmutableDict
|
||||
<https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/datastructures.py>`_.
|
||||
ImmutableDict is used for global constant (configuration options). The Flask
|
||||
project uses ImmutableDict of werkzeug for its default configuration.
|
||||
* SQLAchemy project: `sqlachemy.util.immutabledict
|
||||
<http://hg.sqlalchemy.org/sqlalchemy/file/tip/lib/sqlalchemy/util/_collections.py>`_.
|
||||
It is not hashable and has an extra method: union(). immutabledict is used
|
||||
for the default value of parameter of some functions expecting a mapping.
|
||||
Example: mapper_args=immutabledict() in SqlSoup.map().
|
||||
* `Frozen dictionaries (Python recipe 414283) <http://code.activestate.com/recipes/414283/>`_
|
||||
by Oren Tirosh. It is hashable if keys and values are hashable. Included in
|
||||
the following projects:
|
||||
|
||||
* lingospot: `frozendict/frozendict.py
|
||||
<http://code.google.com/p/lingospot/source/browse/trunk/frozendict/frozendict.py>`_
|
||||
* factor-graphics: frozendict type in `python/fglib/util_ext_frozendict.py
|
||||
<https://github.com/ih/factor-graphics/blob/41006fb71a09377445cc140489da5ce8eeb9c8b1/python/fglib/util_ext_frozendict.py>`_
|
||||
* lingospot: `frozendict/frozendict.py
|
||||
<http://code.google.com/p/lingospot/source/browse/trunk/frozendict/frozendict.py>`_
|
||||
* factor-graphics: frozendict type in `python/fglib/util_ext_frozendict.py
|
||||
<https://github.com/ih/factor-graphics/blob/41006fb71a09377445cc140489da5ce8eeb9c8b1/python/fglib/util_ext_frozendict.py>`_
|
||||
|
||||
* The gsakkis-utils project written by George Sakkis includes a frozendict
|
||||
type: `datastructs.frozendict
|
||||
<http://code.google.com/p/gsakkis-utils/source/browse/trunk/datastructs/frozendict.py>`_
|
||||
* characters: `scripts/python/frozendict.py
|
||||
<https://github.com/JasonGross/characters/blob/15a2af5f7861cd33a0dbce70f1569cda74e9a1e3/scripts/python/frozendict.py#L1>`_.
|
||||
It is hashable. __init__() sets __init__ to None.
|
||||
* Old NLTK (1.x): `nltk.util.frozendict
|
||||
<http://nltk.googlecode.com/svn/trunk/nltk-old/src/nltk/util.py>`_. Keys and
|
||||
values must be hashable. __init__() can be called twice to modify the
|
||||
mapping. frozendict is used to "freeze" an object.
|
||||
* The gsakkis-utils project written by George Sakkis includes a frozendict
|
||||
type: `datastructs.frozendict
|
||||
<http://code.google.com/p/gsakkis-utils/source/browse/trunk/datastructs/frozendict.py>`_
|
||||
* characters: `scripts/python/frozendict.py
|
||||
<https://github.com/JasonGross/characters/blob/15a2af5f7861cd33a0dbce70f1569cda74e9a1e3/scripts/python/frozendict.py#L1>`_.
|
||||
It is hashable. __init__() sets __init__ to None.
|
||||
* Old NLTK (1.x): `nltk.util.frozendict
|
||||
<http://nltk.googlecode.com/svn/trunk/nltk-old/src/nltk/util.py>`_. Keys and
|
||||
values must be hashable. __init__() can be called twice to modify the
|
||||
mapping. frozendict is used to "freeze" an object.
|
||||
|
||||
Hashable dict: inherit from dict and just add an __hash__ method.
|
||||
|
||||
* `pypy.rpython.lltypesystem.lltype.frozendict
|
||||
<https://bitbucket.org/pypy/pypy/src/1f49987cc2fe/pypy/rpython/lltypesystem/lltype.py#cl-86>`_.
|
||||
It is hashable but don't deny modification of the mapping.
|
||||
* factor-graphics: hashabledict type in `python/fglib/util_ext_frozendict.py
|
||||
<https://github.com/ih/factor-graphics/blob/41006fb71a09377445cc140489da5ce8eeb9c8b1/python/fglib/util_ext_frozendict.py>`_
|
||||
* `pypy.rpython.lltypesystem.lltype.frozendict
|
||||
<https://bitbucket.org/pypy/pypy/src/1f49987cc2fe/pypy/rpython/lltypesystem/lltype.py#cl-86>`_.
|
||||
It is hashable but don't deny modification of the mapping.
|
||||
* factor-graphics: hashabledict type in `python/fglib/util_ext_frozendict.py
|
||||
<https://github.com/ih/factor-graphics/blob/41006fb71a09377445cc140489da5ce8eeb9c8b1/python/fglib/util_ext_frozendict.py>`_
|
||||
|
||||
|
||||
Links
|
||||
=====
|
||||
|
||||
* `Issue #14162: PEP 416: Add a builtin frozendict type
|
||||
<http://bugs.python.org/issue14162>`_
|
||||
* 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>`_
|
||||
* `make dictproxy object via ctypes.pythonapi and type() (Python recipe
|
||||
576540) <http://code.activestate.com/recipes/576540/>`_ by Ikkei Shimomura.
|
||||
* Python security modules implementing read-only object proxies using a C
|
||||
extension:
|
||||
* `Issue #14162: PEP 416: Add a builtin frozendict type
|
||||
<http://bugs.python.org/issue14162>`_
|
||||
* 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>`_
|
||||
* `make dictproxy object via ctypes.pythonapi and type() (Python recipe
|
||||
576540) <http://code.activestate.com/recipes/576540/>`_ by Ikkei Shimomura.
|
||||
* Python security modules implementing read-only object proxies using a C
|
||||
extension:
|
||||
|
||||
* `pysandbox <https://github.com/haypo/pysandbox/>`_
|
||||
* `mxProxy <http://www.egenix.com/products/python/mxBase/mxProxy/>`_
|
||||
* `zope.proxy <http://pypi.python.org/pypi/zope.proxy>`_
|
||||
* `zope.security <http://pypi.python.org/pypi/zope.security>`_
|
||||
* `pysandbox <https://github.com/haypo/pysandbox/>`_
|
||||
* `mxProxy <http://www.egenix.com/products/python/mxBase/mxProxy/>`_
|
||||
* `zope.proxy <http://pypi.python.org/pypi/zope.proxy>`_
|
||||
* `zope.security <http://pypi.python.org/pypi/zope.security>`_
|
||||
|
||||
|
||||
Copyright
|
||||
|
|
16
pep-0418.txt
16
pep-0418.txt
|
@ -116,14 +116,14 @@ Get information on the specified clock. Supported clock names:
|
|||
|
||||
Return a ``time.clock_info`` object which has the following attributes:
|
||||
|
||||
* ``implementation`` (str): name of the underlying operating system
|
||||
function. Examples: ``"QueryPerformanceCounter()"``,
|
||||
``"clock_gettime(CLOCK_REALTIME)"``.
|
||||
* ``monotonic`` (bool): True if the clock cannot go backward.
|
||||
* ``adjustable`` (bool): ``True`` if the clock can be changed automatically
|
||||
(e.g. by a NTP daemon) or manually by the system administrator, ``False``
|
||||
otherwise
|
||||
* ``resolution`` (float): resolution in seconds of the clock.
|
||||
* ``implementation`` (str): name of the underlying operating system
|
||||
function. Examples: ``"QueryPerformanceCounter()"``,
|
||||
``"clock_gettime(CLOCK_REALTIME)"``.
|
||||
* ``monotonic`` (bool): True if the clock cannot go backward.
|
||||
* ``adjustable`` (bool): ``True`` if the clock can be changed automatically
|
||||
(e.g. by a NTP daemon) or manually by the system administrator, ``False``
|
||||
otherwise
|
||||
* ``resolution`` (float): resolution in seconds of the clock.
|
||||
|
||||
|
||||
time.monotonic()
|
||||
|
|
28
pep-0426.txt
28
pep-0426.txt
|
@ -868,27 +868,27 @@ should be installed for the specified activities:
|
|||
|
||||
* Implied runtime dependencies:
|
||||
|
||||
* ``run_requires``
|
||||
* ``meta_requires``
|
||||
* ``run_requires``
|
||||
* ``meta_requires``
|
||||
|
||||
* Implied build dependencies:
|
||||
|
||||
* ``build_requires``
|
||||
* If running the distribution's test suite as part of the build process,
|
||||
request the ``:run:``, ``:meta:``, and ``:test:`` extras to also
|
||||
install:
|
||||
|
||||
* ``run_requires``
|
||||
* ``meta_requires``
|
||||
* ``test_requires``
|
||||
|
||||
* Implied development and publication dependencies:
|
||||
* ``build_requires``
|
||||
* If running the distribution's test suite as part of the build process,
|
||||
request the ``:run:``, ``:meta:``, and ``:test:`` extras to also
|
||||
install:
|
||||
|
||||
* ``run_requires``
|
||||
* ``meta_requires``
|
||||
* ``build_requires``
|
||||
* ``test_requires``
|
||||
* ``dev_requires``
|
||||
|
||||
* Implied development and publication dependencies:
|
||||
|
||||
* ``run_requires``
|
||||
* ``meta_requires``
|
||||
* ``build_requires``
|
||||
* ``test_requires``
|
||||
* ``dev_requires``
|
||||
|
||||
The notation described in `Extras (optional dependencies)`_ SHOULD be used
|
||||
to determine exactly what gets installed for various operations.
|
||||
|
|
70
pep-0432.txt
70
pep-0432.txt
|
@ -175,32 +175,50 @@ be able to control the following aspects of the final interpreter state:
|
|||
* Whether or not to enable the import system (required by CPython's
|
||||
build process when freezing the importlib._bootstrap bytecode)
|
||||
* The "Where is Python located?" elements in the ``sys`` module:
|
||||
|
||||
* ``sys.executable``
|
||||
* ``sys.base_exec_prefix``
|
||||
* ``sys.base_prefix``
|
||||
* ``sys.exec_prefix``
|
||||
* ``sys.prefix``
|
||||
|
||||
* The path searched for imports from the filesystem (and other path hooks):
|
||||
|
||||
* ``sys.path``
|
||||
|
||||
* The command line arguments seen by the interpeter:
|
||||
|
||||
* ``sys.argv``
|
||||
|
||||
* The filesystem encoding used by:
|
||||
|
||||
* ``sys.getfsencoding``
|
||||
* ``os.fsencode``
|
||||
* ``os.fsdecode``
|
||||
|
||||
* The IO encoding (if any) and the buffering used by:
|
||||
|
||||
* ``sys.stdin``
|
||||
* ``sys.stdout``
|
||||
* ``sys.stderr``
|
||||
|
||||
* The initial warning system state:
|
||||
|
||||
* ``sys.warnoptions``
|
||||
|
||||
* Arbitrary extended options (e.g. to automatically enable ``faulthandler``):
|
||||
|
||||
* ``sys._xoptions``
|
||||
|
||||
* Whether or not to implicitly cache bytecode files:
|
||||
|
||||
* ``sys.dont_write_bytecode``
|
||||
|
||||
* Whether or not to enforce correct case in filenames on case-insensitive
|
||||
platforms
|
||||
|
||||
* ``os.environ["PYTHONCASEOK"]``
|
||||
|
||||
* The other settings exposed to Python code in ``sys.flags``:
|
||||
|
||||
* ``debug`` (Enable debugging output in the pgen parser)
|
||||
|
@ -738,9 +756,9 @@ incomplete:
|
|||
(typically a zipfile or directory)
|
||||
* otherwise, it will be accurate:
|
||||
|
||||
* the script name if running an ordinary script
|
||||
* ``-c`` if executing a supplied string
|
||||
* ``-`` or the empty string if running from stdin
|
||||
* the script name if running an ordinary script
|
||||
* ``-c`` if executing a supplied string
|
||||
* ``-`` or the empty string if running from stdin
|
||||
|
||||
* the metadata in the ``__main__`` module will still indicate it is a
|
||||
builtin module
|
||||
|
@ -791,24 +809,26 @@ call will take whatever steps are needed to populate ``main_code``:
|
|||
``main_code``.
|
||||
|
||||
* For ``main_path``:
|
||||
* if the supplied path is recognised as a valid ``sys.path`` entry, it
|
||||
is inserted as ``sys.path[0]``, ``main_module`` is set
|
||||
to ``__main__`` and processing continues as for ``main_module`` below.
|
||||
* otherwise, path is read as a CPython bytecode file
|
||||
* if that fails, it is read as a Python source file and compiled
|
||||
* in the latter two cases, the code object is saved to ``main_code``
|
||||
and ``__main__.__file__`` is set appropriately
|
||||
|
||||
* if the supplied path is recognised as a valid ``sys.path`` entry, it
|
||||
is inserted as ``sys.path[0]``, ``main_module`` is set
|
||||
to ``__main__`` and processing continues as for ``main_module`` below.
|
||||
* otherwise, path is read as a CPython bytecode file
|
||||
* if that fails, it is read as a Python source file and compiled
|
||||
* in the latter two cases, the code object is saved to ``main_code``
|
||||
and ``__main__.__file__`` is set appropriately
|
||||
|
||||
* For ``main_module``:
|
||||
* any parent package is imported
|
||||
* the loader for the module is determined
|
||||
* if the loader indicates the module is a package, add ``.__main__`` to
|
||||
the end of ``main_module`` and try again (if the final name segment
|
||||
is already ``.__main__`` then fail immediately)
|
||||
* once the module source code is located, save the compiled module code
|
||||
as ``main_code`` and populate the following attributes in ``__main__``
|
||||
appropriately: ``__name__``, ``__loader__``, ``__file__``,
|
||||
``__cached__``, ``__package__``.
|
||||
|
||||
* any parent package is imported
|
||||
* the loader for the module is determined
|
||||
* if the loader indicates the module is a package, add ``.__main__`` to
|
||||
the end of ``main_module`` and try again (if the final name segment
|
||||
is already ``.__main__`` then fail immediately)
|
||||
* once the module source code is located, save the compiled module code
|
||||
as ``main_code`` and populate the following attributes in ``__main__``
|
||||
appropriately: ``__name__``, ``__loader__``, ``__file__``,
|
||||
``__cached__``, ``__package__``.
|
||||
|
||||
|
||||
(Note: the behaviour described in this section isn't new, it's a write-up
|
||||
|
@ -1222,26 +1242,38 @@ TBD: Cover the initialization of the following in more detail:
|
|||
|
||||
* Completely disabling the import system
|
||||
* The initial warning system state:
|
||||
|
||||
* ``sys.warnoptions``
|
||||
* (-W option, PYTHONWARNINGS)
|
||||
|
||||
* Arbitrary extended options (e.g. to automatically enable ``faulthandler``):
|
||||
|
||||
* ``sys._xoptions``
|
||||
* (-X option)
|
||||
|
||||
* The filesystem encoding used by:
|
||||
|
||||
* ``sys.getfsencoding``
|
||||
* ``os.fsencode``
|
||||
* ``os.fsdecode``
|
||||
|
||||
* The IO encoding and buffering used by:
|
||||
|
||||
* ``sys.stdin``
|
||||
* ``sys.stdout``
|
||||
* ``sys.stderr``
|
||||
* (-u option, PYTHONIOENCODING, PYTHONUNBUFFEREDIO)
|
||||
|
||||
* Whether or not to implicitly cache bytecode files:
|
||||
|
||||
* ``sys.dont_write_bytecode``
|
||||
* (-B option, PYTHONDONTWRITEBYTECODE)
|
||||
|
||||
* Whether or not to enforce correct case in filenames on case-insensitive
|
||||
platforms
|
||||
|
||||
* ``os.environ["PYTHONCASEOK"]``
|
||||
|
||||
* The other settings exposed to Python code in ``sys.flags``:
|
||||
|
||||
* ``debug`` (Enable debugging output in the pgen parser)
|
||||
|
|
407
pep-0433.txt
407
pep-0433.txt
|
@ -18,10 +18,10 @@ Add a new optional *cloexec* parameter on functions creating file
|
|||
descriptors, add different ways to change default values of this
|
||||
parameter, and add four new functions:
|
||||
|
||||
* ``os.get_cloexec(fd)``
|
||||
* ``os.set_cloexec(fd, cloexec=True)``
|
||||
* ``sys.getdefaultcloexec()``
|
||||
* ``sys.setdefaultcloexec(cloexec)``
|
||||
* ``os.get_cloexec(fd)``
|
||||
* ``os.set_cloexec(fd, cloexec=True)``
|
||||
* ``sys.getdefaultcloexec()``
|
||||
* ``sys.setdefaultcloexec(cloexec)``
|
||||
|
||||
|
||||
Rationale
|
||||
|
@ -86,14 +86,14 @@ with "too many files" because files are still open in the child process.
|
|||
|
||||
See also the following issues:
|
||||
|
||||
* `Issue #2320: Race condition in subprocess using stdin
|
||||
<http://bugs.python.org/issue2320>`_ (2008)
|
||||
* `Issue #3006: subprocess.Popen causes socket to remain open after
|
||||
close <http://bugs.python.org/issue3006>`_ (2008)
|
||||
* `Issue #7213: subprocess leaks open file descriptors between Popen
|
||||
instances causing hangs <http://bugs.python.org/issue7213>`_ (2009)
|
||||
* `Issue #12786: subprocess wait() hangs when stdin is closed
|
||||
<http://bugs.python.org/issue12786>`_ (2011)
|
||||
* `Issue #2320: Race condition in subprocess using stdin
|
||||
<http://bugs.python.org/issue2320>`_ (2008)
|
||||
* `Issue #3006: subprocess.Popen causes socket to remain open after
|
||||
close <http://bugs.python.org/issue3006>`_ (2008)
|
||||
* `Issue #7213: subprocess leaks open file descriptors between Popen
|
||||
instances causing hangs <http://bugs.python.org/issue7213>`_ (2009)
|
||||
* `Issue #12786: subprocess wait() hangs when stdin is closed
|
||||
<http://bugs.python.org/issue12786>`_ (2011)
|
||||
|
||||
|
||||
Security
|
||||
|
@ -112,20 +112,20 @@ See also the CERT recommandation:
|
|||
Example of vulnerabilities:
|
||||
|
||||
|
||||
* `OpenSSH Security Advisory: portable-keysign-rand-helper.adv
|
||||
<http://www.openssh.com/txt/portable-keysign-rand-helper.adv>`_
|
||||
(April 2011)
|
||||
* `CWE-403: Exposure of File Descriptor to Unintended Control Sphere
|
||||
<http://cwe.mitre.org/data/definitions/403.html>`_ (2008)
|
||||
* `Hijacking Apache https by mod_php
|
||||
<http://www.securityfocus.com/archive/1/348368>`_ (Dec 2003)
|
||||
* `OpenSSH Security Advisory: portable-keysign-rand-helper.adv
|
||||
<http://www.openssh.com/txt/portable-keysign-rand-helper.adv>`_
|
||||
(April 2011)
|
||||
* `CWE-403: Exposure of File Descriptor to Unintended Control Sphere
|
||||
<http://cwe.mitre.org/data/definitions/403.html>`_ (2008)
|
||||
* `Hijacking Apache https by mod_php
|
||||
<http://www.securityfocus.com/archive/1/348368>`_ (Dec 2003)
|
||||
|
||||
* Apache: `Apr should set FD_CLOEXEC if APR_FOPEN_NOCLEANUP is not set
|
||||
<https://issues.apache.org/bugzilla/show_bug.cgi?id=46425>`_
|
||||
(fixed in 2009)
|
||||
* PHP: `system() (and similar) don't cleanup opened handles of Apache
|
||||
<https://bugs.php.net/bug.php?id=38915>`_ (not fixed in january
|
||||
2013)
|
||||
* Apache: `Apr should set FD_CLOEXEC if APR_FOPEN_NOCLEANUP is not set
|
||||
<https://issues.apache.org/bugzilla/show_bug.cgi?id=46425>`_
|
||||
(fixed in 2009)
|
||||
* PHP: `system() (and similar) don't cleanup opened handles of Apache
|
||||
<https://bugs.php.net/bug.php?id=38915>`_ (not fixed in january
|
||||
2013)
|
||||
|
||||
|
||||
Atomicity
|
||||
|
@ -189,37 +189,37 @@ parameter.
|
|||
|
||||
Add new functions:
|
||||
|
||||
* ``os.get_cloexec(fd:int) -> bool``: get the
|
||||
close-on-exec flag of a file descriptor. Not available on all
|
||||
platforms.
|
||||
* ``os.set_cloexec(fd:int, cloexec:bool=True)``: set or clear the
|
||||
close-on-exec flag on a file descriptor. Not available on all
|
||||
platforms.
|
||||
* ``sys.getdefaultcloexec() -> bool``: get the current default value
|
||||
of the *cloexec* parameter
|
||||
* ``sys.setdefaultcloexec(cloexec: bool)``: set the default value
|
||||
of the *cloexec* parameter
|
||||
* ``os.get_cloexec(fd:int) -> bool``: get the
|
||||
close-on-exec flag of a file descriptor. Not available on all
|
||||
platforms.
|
||||
* ``os.set_cloexec(fd:int, cloexec:bool=True)``: set or clear the
|
||||
close-on-exec flag on a file descriptor. Not available on all
|
||||
platforms.
|
||||
* ``sys.getdefaultcloexec() -> bool``: get the current default value
|
||||
of the *cloexec* parameter
|
||||
* ``sys.setdefaultcloexec(cloexec: bool)``: set the default value
|
||||
of the *cloexec* parameter
|
||||
|
||||
Add a new optional *cloexec* parameter to:
|
||||
|
||||
* ``asyncore.dispatcher.create_socket()``
|
||||
* ``io.FileIO``
|
||||
* ``io.open()``
|
||||
* ``open()``
|
||||
* ``os.dup()``
|
||||
* ``os.dup2()``
|
||||
* ``os.fdopen()``
|
||||
* ``os.open()``
|
||||
* ``os.openpty()``
|
||||
* ``os.pipe()``
|
||||
* ``select.devpoll()``
|
||||
* ``select.epoll()``
|
||||
* ``select.kqueue()``
|
||||
* ``socket.socket()``
|
||||
* ``socket.socket.accept()``
|
||||
* ``socket.socket.dup()``
|
||||
* ``socket.socket.fromfd``
|
||||
* ``socket.socketpair()``
|
||||
* ``asyncore.dispatcher.create_socket()``
|
||||
* ``io.FileIO``
|
||||
* ``io.open()``
|
||||
* ``open()``
|
||||
* ``os.dup()``
|
||||
* ``os.dup2()``
|
||||
* ``os.fdopen()``
|
||||
* ``os.open()``
|
||||
* ``os.openpty()``
|
||||
* ``os.pipe()``
|
||||
* ``select.devpoll()``
|
||||
* ``select.epoll()``
|
||||
* ``select.kqueue()``
|
||||
* ``socket.socket()``
|
||||
* ``socket.socket.accept()``
|
||||
* ``socket.socket.dup()``
|
||||
* ``socket.socket.fromfd``
|
||||
* ``socket.socketpair()``
|
||||
|
||||
The default value of the *cloexec* parameter is
|
||||
``sys.getdefaultcloexec()``.
|
||||
|
@ -241,13 +241,13 @@ must be specified explicitly.
|
|||
|
||||
Drawbacks of the proposal:
|
||||
|
||||
* It is not more possible to know if the close-on-exec flag will be
|
||||
set or not on a newly created file descriptor just by reading the
|
||||
source code.
|
||||
* If the inheritance of a file descriptor matters, the *cloexec*
|
||||
parameter must now be specified explicitly, or the library or the
|
||||
application will not work depending on the default value of the
|
||||
*cloexec* parameter.
|
||||
* It is not more possible to know if the close-on-exec flag will be
|
||||
set or not on a newly created file descriptor just by reading the
|
||||
source code.
|
||||
* If the inheritance of a file descriptor matters, the *cloexec*
|
||||
parameter must now be specified explicitly, or the library or the
|
||||
application will not work depending on the default value of the
|
||||
*cloexec* parameter.
|
||||
|
||||
|
||||
Alternatives
|
||||
|
@ -288,23 +288,23 @@ parameter can be used.
|
|||
|
||||
Advantages of setting close-on-exec flag by default:
|
||||
|
||||
* There are far more programs that are bitten by FD inheritance upon
|
||||
exec (see `Inherited file descriptors issues`_ and `Security`_)
|
||||
than programs relying on it (see `Applications using inheritance of
|
||||
file descriptors`_).
|
||||
* There are far more programs that are bitten by FD inheritance upon
|
||||
exec (see `Inherited file descriptors issues`_ and `Security`_)
|
||||
than programs relying on it (see `Applications using inheritance of
|
||||
file descriptors`_).
|
||||
|
||||
Drawbacks of setting close-on-exec flag by default:
|
||||
|
||||
* It violates the principle of least surprise. Developers using the
|
||||
os module may expect that Python respects the POSIX standard and so
|
||||
that close-on-exec flag is not set by default.
|
||||
* The os module is written as a thin wrapper to system calls (to
|
||||
functions of the C standard library). If atomic flags to set
|
||||
close-on-exec flag are not supported (see `Appendix: Operating
|
||||
system support`_), a single Python function call may call 2 or 3
|
||||
system calls (see `Performances`_ section).
|
||||
* Extra system calls, if any, may slow down Python: see
|
||||
`Performances`_.
|
||||
* It violates the principle of least surprise. Developers using the
|
||||
os module may expect that Python respects the POSIX standard and so
|
||||
that close-on-exec flag is not set by default.
|
||||
* The os module is written as a thin wrapper to system calls (to
|
||||
functions of the C standard library). If atomic flags to set
|
||||
close-on-exec flag are not supported (see `Appendix: Operating
|
||||
system support`_), a single Python function call may call 2 or 3
|
||||
system calls (see `Performances`_ section).
|
||||
* Extra system calls, if any, may slow down Python: see
|
||||
`Performances`_.
|
||||
|
||||
Backward compatibility: only a few programs rely on inheritance of file
|
||||
descriptors, and they only pass a few file descriptors, usually just
|
||||
|
@ -329,20 +329,20 @@ descriptors just after a ``fork()``.
|
|||
|
||||
Drawbacks:
|
||||
|
||||
* It does not solve the problem on Windows: ``fork()`` does not exist
|
||||
on Windows
|
||||
* This alternative does not solve the problem for programs using
|
||||
``exec()`` without ``fork()``.
|
||||
* A third party module may call directly the C function ``fork()``
|
||||
which will not call "atfork" callbacks.
|
||||
* All functions creating file descriptors must be changed to register
|
||||
a callback and then unregister their callback when the file is
|
||||
closed. Or a list of *all* open file descriptors must be
|
||||
maintained.
|
||||
* The operating system is a better place than Python to close
|
||||
automatically file descriptors. For example, it is not easy to
|
||||
avoid a race condition between closing the file and unregistering
|
||||
the callback closing the file.
|
||||
* It does not solve the problem on Windows: ``fork()`` does not exist
|
||||
on Windows
|
||||
* This alternative does not solve the problem for programs using
|
||||
``exec()`` without ``fork()``.
|
||||
* A third party module may call directly the C function ``fork()``
|
||||
which will not call "atfork" callbacks.
|
||||
* All functions creating file descriptors must be changed to register
|
||||
a callback and then unregister their callback when the file is
|
||||
closed. Or a list of *all* open file descriptors must be
|
||||
maintained.
|
||||
* The operating system is a better place than Python to close
|
||||
automatically file descriptors. For example, it is not easy to
|
||||
avoid a race condition between closing the file and unregistering
|
||||
the callback closing the file.
|
||||
|
||||
|
||||
open(): add "e" flag to mode
|
||||
|
@ -363,9 +363,9 @@ flag which uses ``O_NOINHERIT``.
|
|||
Bikeshedding on the name of the new parameter
|
||||
---------------------------------------------
|
||||
|
||||
* ``inherit``, ``inherited``: closer to Windows definition
|
||||
* ``sensitive``
|
||||
* ``sterile``: "Does not produce offspring."
|
||||
* ``inherit``, ``inherited``: closer to Windows definition
|
||||
* ``sensitive``
|
||||
* ``sterile``: "Does not produce offspring."
|
||||
|
||||
|
||||
|
||||
|
@ -400,11 +400,11 @@ the previous child process crashed.
|
|||
Example of programs taking file descriptors from the parent process
|
||||
using a command line option:
|
||||
|
||||
* gpg: ``--status-fd <fd>``, ``--logger-fd <fd>``, etc.
|
||||
* openssl: ``-pass fd:<fd>``
|
||||
* qemu: ``-add-fd <fd>``
|
||||
* valgrind: ``--log-fd=<fd>``, ``--input-fd=<fd>``, etc.
|
||||
* xterm: ``-S <fd>``
|
||||
* gpg: ``--status-fd <fd>``, ``--logger-fd <fd>``, etc.
|
||||
* openssl: ``-pass fd:<fd>``
|
||||
* qemu: ``-add-fd <fd>``
|
||||
* valgrind: ``--log-fd=<fd>``, ``--input-fd=<fd>``, etc.
|
||||
* xterm: ``-S <fd>``
|
||||
|
||||
On Linux, it is possible to use ``"/dev/fd/<fd>"`` filename to pass a
|
||||
file descriptor to a program expecting a filename.
|
||||
|
@ -417,24 +417,24 @@ Setting close-on-exec flag may require additional system calls for
|
|||
each creation of new file descriptors. The number of additional system
|
||||
calls depends on the method used to set the flag:
|
||||
|
||||
* ``O_NOINHERIT``: no additional system call
|
||||
* ``O_CLOEXEC``: one additional system call, but only at the creation
|
||||
of the first file descriptor, to check if the flag is supported. If
|
||||
the flag is not supported, Python has to fallback to the next method.
|
||||
* ``ioctl(fd, FIOCLEX)``: one additional system call per file
|
||||
descriptor
|
||||
* ``fcntl(fd, F_SETFD, flags)``: two additional system calls per file
|
||||
descriptor, one to get old flags and one to set new flags
|
||||
* ``O_NOINHERIT``: no additional system call
|
||||
* ``O_CLOEXEC``: one additional system call, but only at the creation
|
||||
of the first file descriptor, to check if the flag is supported. If
|
||||
the flag is not supported, Python has to fallback to the next method.
|
||||
* ``ioctl(fd, FIOCLEX)``: one additional system call per file
|
||||
descriptor
|
||||
* ``fcntl(fd, F_SETFD, flags)``: two additional system calls per file
|
||||
descriptor, one to get old flags and one to set new flags
|
||||
|
||||
On Linux, setting the close-on-flag has a low overhead on performances.
|
||||
Results of
|
||||
`bench_cloexec.py <http://hg.python.org/peps/file/tip/pep-0433/bench_cloexec.py>`_
|
||||
on Linux 3.6:
|
||||
|
||||
* close-on-flag not set: 7.8 us
|
||||
* ``O_CLOEXEC``: 1% slower (7.9 us)
|
||||
* ``ioctl()``: 3% slower (8.0 us)
|
||||
* ``fcntl()``: 3% slower (8.0 us)
|
||||
* close-on-flag not set: 7.8 us
|
||||
* ``O_CLOEXEC``: 1% slower (7.9 us)
|
||||
* ``ioctl()``: 3% slower (8.0 us)
|
||||
* ``fcntl()``: 3% slower (8.0 us)
|
||||
|
||||
|
||||
Implementation
|
||||
|
@ -522,52 +522,52 @@ instead of two syscalls for fcntl.
|
|||
open()
|
||||
------
|
||||
|
||||
* Windows: ``open()`` with ``O_NOINHERIT`` flag [atomic]
|
||||
* ``open()`` with ``O_CLOEXEC flag`` [atomic]
|
||||
* ``open()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
* Windows: ``open()`` with ``O_NOINHERIT`` flag [atomic]
|
||||
* ``open()`` with ``O_CLOEXEC flag`` [atomic]
|
||||
* ``open()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
|
||||
os.dup()
|
||||
--------
|
||||
|
||||
* Windows: ``DuplicateHandle()`` [atomic]
|
||||
* ``fcntl(fd, F_DUPFD_CLOEXEC)`` [atomic]
|
||||
* ``dup()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
* Windows: ``DuplicateHandle()`` [atomic]
|
||||
* ``fcntl(fd, F_DUPFD_CLOEXEC)`` [atomic]
|
||||
* ``dup()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
|
||||
os.dup2()
|
||||
---------
|
||||
|
||||
* ``fcntl(fd, F_DUP2FD_CLOEXEC, fd2)`` [atomic]
|
||||
* ``dup3()`` with ``O_CLOEXEC`` flag [atomic]
|
||||
* ``dup2()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
* ``fcntl(fd, F_DUP2FD_CLOEXEC, fd2)`` [atomic]
|
||||
* ``dup3()`` with ``O_CLOEXEC`` flag [atomic]
|
||||
* ``dup2()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
|
||||
os.pipe()
|
||||
---------
|
||||
|
||||
* Windows: ``CreatePipe()`` with
|
||||
``SECURITY_ATTRIBUTES.bInheritHandle=TRUE``, or ``_pipe()`` with
|
||||
``O_NOINHERIT`` flag [atomic]
|
||||
* ``pipe2()`` with ``O_CLOEXEC`` flag [atomic]
|
||||
* ``pipe()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
* Windows: ``CreatePipe()`` with
|
||||
``SECURITY_ATTRIBUTES.bInheritHandle=TRUE``, or ``_pipe()`` with
|
||||
``O_NOINHERIT`` flag [atomic]
|
||||
* ``pipe2()`` with ``O_CLOEXEC`` flag [atomic]
|
||||
* ``pipe()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
|
||||
socket.socket()
|
||||
---------------
|
||||
|
||||
* Windows: ``WSASocket()`` with ``WSA_FLAG_NO_HANDLE_INHERIT`` flag
|
||||
[atomic]
|
||||
* ``socket()`` with ``SOCK_CLOEXEC`` flag [atomic]
|
||||
* ``socket()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
* Windows: ``WSASocket()`` with ``WSA_FLAG_NO_HANDLE_INHERIT`` flag
|
||||
[atomic]
|
||||
* ``socket()`` with ``SOCK_CLOEXEC`` flag [atomic]
|
||||
* ``socket()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
|
||||
socket.socketpair()
|
||||
-------------------
|
||||
|
||||
* ``socketpair()`` with ``SOCK_CLOEXEC`` flag [atomic]
|
||||
* ``socketpair()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
* ``socketpair()`` with ``SOCK_CLOEXEC`` flag [atomic]
|
||||
* ``socketpair()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
|
||||
socket.socket.accept()
|
||||
----------------------
|
||||
|
||||
* ``accept4()`` with ``SOCK_CLOEXEC`` flag [atomic]
|
||||
* ``accept()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
* ``accept4()`` with ``SOCK_CLOEXEC`` flag [atomic]
|
||||
* ``accept()`` + ``os.set_cloexec(fd, True)`` [best-effort]
|
||||
|
||||
|
||||
Backward compatibility
|
||||
|
@ -603,8 +603,8 @@ ioctl
|
|||
|
||||
Functions:
|
||||
|
||||
* ``ioctl(fd, FIOCLEX, 0)``: set the close-on-exec flag
|
||||
* ``ioctl(fd, FIONCLEX, 0)``: clear the close-on-exec flag
|
||||
* ``ioctl(fd, FIOCLEX, 0)``: set the close-on-exec flag
|
||||
* ``ioctl(fd, FIONCLEX, 0)``: clear the close-on-exec flag
|
||||
|
||||
Availability: Linux, Mac OS X, QNX, NetBSD, OpenBSD, FreeBSD.
|
||||
|
||||
|
@ -614,10 +614,10 @@ fcntl
|
|||
|
||||
Functions:
|
||||
|
||||
* ``flags = fcntl(fd, F_GETFD); fcntl(fd, F_SETFD, flags | FD_CLOEXEC)``:
|
||||
set the close-on-exec flag
|
||||
* ``flags = fcntl(fd, F_GETFD); fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC)``:
|
||||
clear the close-on-exec flag
|
||||
* ``flags = fcntl(fd, F_GETFD); fcntl(fd, F_SETFD, flags | FD_CLOEXEC)``:
|
||||
set the close-on-exec flag
|
||||
* ``flags = fcntl(fd, F_GETFD); fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC)``:
|
||||
clear the close-on-exec flag
|
||||
|
||||
Availability: AIX, Digital UNIX, FreeBSD, HP-UX, IRIX, Linux, Mac OS
|
||||
X, OpenBSD, Solaris, SunOS, Unicos.
|
||||
|
@ -628,20 +628,20 @@ Atomic flags
|
|||
|
||||
New flags:
|
||||
|
||||
* ``O_CLOEXEC``: available on Linux (2.6.23), FreeBSD (8.3),
|
||||
OpenBSD 5.0, Solaris 11, QNX, BeOS, next NetBSD release (6.1?).
|
||||
This flag is part of POSIX.1-2008.
|
||||
* ``SOCK_CLOEXEC`` flag for ``socket()`` and ``socketpair()``,
|
||||
available on Linux 2.6.27, OpenBSD 5.2, NetBSD 6.0.
|
||||
* ``WSA_FLAG_NO_HANDLE_INHERIT`` flag for ``WSASocket()``: supported
|
||||
on Windows 7 with SP1, Windows Server 2008 R2 with SP1, and later
|
||||
* ``fcntl()``: ``F_DUPFD_CLOEXEC`` flag, available on Linux 2.6.24,
|
||||
OpenBSD 5.0, FreeBSD 9.1, NetBSD 6.0, Solaris 11. This flag is part
|
||||
of POSIX.1-2008.
|
||||
* ``fcntl()``: ``F_DUP2FD_CLOEXEC`` flag, available on FreeBSD 9.1
|
||||
and Solaris 11.
|
||||
* ``recvmsg()``: ``MSG_CMSG_CLOEXEC``, available on Linux 2.6.23,
|
||||
NetBSD 6.0.
|
||||
* ``O_CLOEXEC``: available on Linux (2.6.23), FreeBSD (8.3),
|
||||
OpenBSD 5.0, Solaris 11, QNX, BeOS, next NetBSD release (6.1?).
|
||||
This flag is part of POSIX.1-2008.
|
||||
* ``SOCK_CLOEXEC`` flag for ``socket()`` and ``socketpair()``,
|
||||
available on Linux 2.6.27, OpenBSD 5.2, NetBSD 6.0.
|
||||
* ``WSA_FLAG_NO_HANDLE_INHERIT`` flag for ``WSASocket()``: supported
|
||||
on Windows 7 with SP1, Windows Server 2008 R2 with SP1, and later
|
||||
* ``fcntl()``: ``F_DUPFD_CLOEXEC`` flag, available on Linux 2.6.24,
|
||||
OpenBSD 5.0, FreeBSD 9.1, NetBSD 6.0, Solaris 11. This flag is part
|
||||
of POSIX.1-2008.
|
||||
* ``fcntl()``: ``F_DUP2FD_CLOEXEC`` flag, available on FreeBSD 9.1
|
||||
and Solaris 11.
|
||||
* ``recvmsg()``: ``MSG_CMSG_CLOEXEC``, available on Linux 2.6.23,
|
||||
NetBSD 6.0.
|
||||
|
||||
On Linux older than 2.6.23, ``O_CLOEXEC`` flag is simply ignored. So
|
||||
we have to check that the flag is supported by calling ``fcntl()``. If
|
||||
|
@ -657,9 +657,9 @@ On Windows XPS3, ``WSASocket()`` with with ``WSAEPROTOTYPE`` when
|
|||
|
||||
New functions:
|
||||
|
||||
* ``dup3()``: available on Linux 2.6.27 (and glibc 2.9)
|
||||
* ``pipe2()``: available on Linux 2.6.27 (and glibc 2.9)
|
||||
* ``accept4()``: available on Linux 2.6.28 (and glibc 2.10)
|
||||
* ``dup3()``: available on Linux 2.6.27 (and glibc 2.9)
|
||||
* ``pipe2()``: available on Linux 2.6.27 (and glibc 2.9)
|
||||
* ``accept4()``: available on Linux 2.6.28 (and glibc 2.10)
|
||||
|
||||
If ``accept4()`` is called on Linux older than 2.6.28, ``accept4()``
|
||||
returns ``-1`` (fail) and ``errno`` is set to ``ENOSYS``.
|
||||
|
@ -670,55 +670,55 @@ Links
|
|||
|
||||
Links:
|
||||
|
||||
* `Secure File Descriptor Handling
|
||||
<http://udrepper.livejournal.com/20407.html>`_ (Ulrich Drepper,
|
||||
2008)
|
||||
* `win32_support.py of the Tornado project
|
||||
<https://bitbucket.org/pvl/gaeseries-tornado/src/c2671cea1842/tornado/win32_support.py>`_:
|
||||
emulate fcntl(fd, F_SETFD, FD_CLOEXEC) using
|
||||
``SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 1)``
|
||||
* `LKML: [PATCH] nextfd(2)
|
||||
<https://lkml.org/lkml/2012/4/1/71>`_
|
||||
* `Secure File Descriptor Handling
|
||||
<http://udrepper.livejournal.com/20407.html>`_ (Ulrich Drepper,
|
||||
2008)
|
||||
* `win32_support.py of the Tornado project
|
||||
<https://bitbucket.org/pvl/gaeseries-tornado/src/c2671cea1842/tornado/win32_support.py>`_:
|
||||
emulate fcntl(fd, F_SETFD, FD_CLOEXEC) using
|
||||
``SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 1)``
|
||||
* `LKML: [PATCH] nextfd(2)
|
||||
<https://lkml.org/lkml/2012/4/1/71>`_
|
||||
|
||||
Python issues:
|
||||
|
||||
* `#10115: Support accept4() for atomic setting of flags at socket
|
||||
creation <http://bugs.python.org/issue10115>`_
|
||||
* `#12105: open() does not able to set flags, such as O_CLOEXEC
|
||||
<http://bugs.python.org/issue12105>`_
|
||||
* `#12107: TCP listening sockets created without FD_CLOEXEC flag
|
||||
<http://bugs.python.org/issue12107>`_
|
||||
* `#16500: Add an atfork module
|
||||
<http://bugs.python.org/issue16500>`_
|
||||
* `#16850: Add "e" mode to open(): close-and-exec
|
||||
(O_CLOEXEC) / O_NOINHERIT <http://bugs.python.org/issue16850>`_
|
||||
* `#16860: Use O_CLOEXEC in the tempfile module
|
||||
<http://bugs.python.org/issue16860>`_
|
||||
* `#17036: Implementation of the PEP 433
|
||||
<http://bugs.python.org/issue17036>`_
|
||||
* `#16946: subprocess: _close_open_fd_range_safe() does not set
|
||||
close-on-exec flag on Linux < 2.6.23 if O_CLOEXEC is defined
|
||||
<http://bugs.python.org/issue16946>`_
|
||||
* `#17070: PEP 433: Use the new cloexec to improve security and avoid
|
||||
bugs <http://bugs.python.org/issue17070>`_
|
||||
* `#10115: Support accept4() for atomic setting of flags at socket
|
||||
creation <http://bugs.python.org/issue10115>`_
|
||||
* `#12105: open() does not able to set flags, such as O_CLOEXEC
|
||||
<http://bugs.python.org/issue12105>`_
|
||||
* `#12107: TCP listening sockets created without FD_CLOEXEC flag
|
||||
<http://bugs.python.org/issue12107>`_
|
||||
* `#16500: Add an atfork module
|
||||
<http://bugs.python.org/issue16500>`_
|
||||
* `#16850: Add "e" mode to open(): close-and-exec
|
||||
(O_CLOEXEC) / O_NOINHERIT <http://bugs.python.org/issue16850>`_
|
||||
* `#16860: Use O_CLOEXEC in the tempfile module
|
||||
<http://bugs.python.org/issue16860>`_
|
||||
* `#17036: Implementation of the PEP 433
|
||||
<http://bugs.python.org/issue17036>`_
|
||||
* `#16946: subprocess: _close_open_fd_range_safe() does not set
|
||||
close-on-exec flag on Linux < 2.6.23 if O_CLOEXEC is defined
|
||||
<http://bugs.python.org/issue16946>`_
|
||||
* `#17070: PEP 433: Use the new cloexec to improve security and avoid
|
||||
bugs <http://bugs.python.org/issue17070>`_
|
||||
|
||||
Other languages:
|
||||
|
||||
* Perl sets the close-on-exec flag on newly created file decriptor if
|
||||
their number is greater than ``$SYSTEM_FD_MAX`` (``$^F``).
|
||||
See `$SYSTEM_FD_MAX documentation
|
||||
<http://perldoc.perl.org/perlvar.html#%24SYSTEM_FD_MAX>`_. Perl does
|
||||
this since the creation of Perl (it was already present in Perl 1).
|
||||
* Ruby: `Set FD_CLOEXEC for all fds (except 0, 1, 2)
|
||||
<http://bugs.ruby-lang.org/issues/5041>`_
|
||||
* Ruby: `O_CLOEXEC flag missing for Kernel::open
|
||||
<http://bugs.ruby-lang.org/issues/1291>`_: the
|
||||
`commit was reverted later
|
||||
<http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/31643>`_
|
||||
* OCaml: `PR#5256: Processes opened using Unix.open_process* inherit
|
||||
all opened file descriptors (including sockets)
|
||||
<http://caml.inria.fr/mantis/view.php?id=5256>`_. OCaml has a
|
||||
``Unix.set_close_on_exec`` function.
|
||||
* Perl sets the close-on-exec flag on newly created file decriptor if
|
||||
their number is greater than ``$SYSTEM_FD_MAX`` (``$^F``).
|
||||
See `$SYSTEM_FD_MAX documentation
|
||||
<http://perldoc.perl.org/perlvar.html#%24SYSTEM_FD_MAX>`_. Perl does
|
||||
this since the creation of Perl (it was already present in Perl 1).
|
||||
* Ruby: `Set FD_CLOEXEC for all fds (except 0, 1, 2)
|
||||
<http://bugs.ruby-lang.org/issues/5041>`_
|
||||
* Ruby: `O_CLOEXEC flag missing for Kernel::open
|
||||
<http://bugs.ruby-lang.org/issues/1291>`_: the
|
||||
`commit was reverted later
|
||||
<http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/31643>`_
|
||||
* OCaml: `PR#5256: Processes opened using Unix.open_process* inherit
|
||||
all opened file descriptors (including sockets)
|
||||
<http://caml.inria.fr/mantis/view.php?id=5256>`_. OCaml has a
|
||||
``Unix.set_close_on_exec`` function.
|
||||
|
||||
|
||||
Footnotes
|
||||
|
@ -732,3 +732,18 @@ Footnotes
|
|||
has a descriptor smaller than 3, ``ValueError`` is raised.
|
||||
|
||||
|
||||
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:
|
||||
|
|
74
pep-0437.txt
74
pep-0437.txt
|
@ -313,28 +313,28 @@ The grammar is conflict-free and available in ml-yacc readable BNF form.
|
|||
|
||||
Two tools are available:
|
||||
|
||||
* *printsemant* reads a converter header and a .c file and dumps
|
||||
the semantically checked parse tree to stdout.
|
||||
* *printsemant* reads a converter header and a .c file and dumps
|
||||
the semantically checked parse tree to stdout.
|
||||
|
||||
* *preprocess* reads a converter header and a .c file and dumps
|
||||
the preprocessed .c file to stdout.
|
||||
* *preprocess* reads a converter header and a .c file and dumps
|
||||
the preprocessed .c file to stdout.
|
||||
|
||||
|
||||
Known deficiencies:
|
||||
|
||||
* The Python 'test' expression is not semantically checked. The syntax
|
||||
however is checked since it is part of the grammar.
|
||||
* The Python 'test' expression is not semantically checked. The syntax
|
||||
however is checked since it is part of the grammar.
|
||||
|
||||
* The lexer does not handle triple quoted strings.
|
||||
* The lexer does not handle triple quoted strings.
|
||||
|
||||
* C declarations are parsed in a primitive way. The final implementation
|
||||
should utilize 'declarator' and 'init-declarator' from the C grammar.
|
||||
* C declarations are parsed in a primitive way. The final implementation
|
||||
should utilize 'declarator' and 'init-declarator' from the C grammar.
|
||||
|
||||
* The *preprocess* tool does not emit code for the left-and-right optional
|
||||
arguments case. The *printsemant* tool can deal with this case.
|
||||
* The *preprocess* tool does not emit code for the left-and-right optional
|
||||
arguments case. The *printsemant* tool can deal with this case.
|
||||
|
||||
* Since the *preprocess* tool generates the output from the parse
|
||||
tree, the original indentation of the define block is lost.
|
||||
* Since the *preprocess* tool generates the output from the parse
|
||||
tree, the original indentation of the define block is lost.
|
||||
|
||||
|
||||
Grammar
|
||||
|
@ -350,37 +350,37 @@ Comparison with PEP 436
|
|||
The author of this PEP has the following concerns about the DSL proposed
|
||||
in PEP 436:
|
||||
|
||||
* The whitespace sensitive configuration file like syntax looks out
|
||||
of place in a C file.
|
||||
* The whitespace sensitive configuration file like syntax looks out
|
||||
of place in a C file.
|
||||
|
||||
* The structure of the function definition gets lost in the per-parameter
|
||||
specifications. Keywords like positional-only, required and keyword-only
|
||||
are scattered across too many different places.
|
||||
* The structure of the function definition gets lost in the per-parameter
|
||||
specifications. Keywords like positional-only, required and keyword-only
|
||||
are scattered across too many different places.
|
||||
|
||||
By contrast, in the alternative DSL the structure of the function
|
||||
definition can be understood at a single glance.
|
||||
By contrast, in the alternative DSL the structure of the function
|
||||
definition can be understood at a single glance.
|
||||
|
||||
* The PEP 436 DSL has 14 documented flags and at least one undocumented
|
||||
(allow_fd) flag. Figuring out which of the 2**15 possible combinations
|
||||
are valid places an unnecessary burden on the user.
|
||||
* The PEP 436 DSL has 14 documented flags and at least one undocumented
|
||||
(allow_fd) flag. Figuring out which of the 2**15 possible combinations
|
||||
are valid places an unnecessary burden on the user.
|
||||
|
||||
Experience with the PEP-3118 buffer flags has shown that sorting out
|
||||
(and exhaustively testing!) valid combinations is an extremely tedious
|
||||
task. The PEP-3118 flags are still not well understood by many people.
|
||||
Experience with the PEP-3118 buffer flags has shown that sorting out
|
||||
(and exhaustively testing!) valid combinations is an extremely tedious
|
||||
task. The PEP-3118 flags are still not well understood by many people.
|
||||
|
||||
By contrast, the alternative DSL has a central file Include/converters.h
|
||||
that can be quickly searched for the desired converter. Many of the
|
||||
converters are already known, perhaps even memorized by people (due
|
||||
to frequent use).
|
||||
By contrast, the alternative DSL has a central file Include/converters.h
|
||||
that can be quickly searched for the desired converter. Many of the
|
||||
converters are already known, perhaps even memorized by people (due
|
||||
to frequent use).
|
||||
|
||||
* The PEP 436 DSL allows too much freedom. Types can apparently be omitted,
|
||||
the preprocessor accepts (and ignores) unknown keywords, sometimes adding
|
||||
white space after a docstring results in an assertion error.
|
||||
* The PEP 436 DSL allows too much freedom. Types can apparently be omitted,
|
||||
the preprocessor accepts (and ignores) unknown keywords, sometimes adding
|
||||
white space after a docstring results in an assertion error.
|
||||
|
||||
The alternative DSL on the other hand allows no such freedoms. Omitting
|
||||
converter or return value annotations is plainly a syntax error. The
|
||||
LALR(1) grammar is unambiguous and specified for the complete translation
|
||||
unit.
|
||||
The alternative DSL on the other hand allows no such freedoms. Omitting
|
||||
converter or return value annotations is plainly a syntax error. The
|
||||
LALR(1) grammar is unambiguous and specified for the complete translation
|
||||
unit.
|
||||
|
||||
|
||||
Copyright
|
||||
|
|
40
pep-0446.txt
40
pep-0446.txt
|
@ -330,9 +330,9 @@ flag is missing. On Linux older than 2.6.27, ``socket()`` or
|
|||
|
||||
New functions:
|
||||
|
||||
* ``dup3()``: available on Linux 2.6.27 (and glibc 2.9)
|
||||
* ``pipe2()``: available on Linux 2.6.27 (and glibc 2.9)
|
||||
* ``accept4()``: available on Linux 2.6.28 (and glibc 2.10)
|
||||
* ``dup3()``: available on Linux 2.6.27 (and glibc 2.9)
|
||||
* ``pipe2()``: available on Linux 2.6.27 (and glibc 2.9)
|
||||
* ``accept4()``: available on Linux 2.6.28 (and glibc 2.10)
|
||||
|
||||
On Linux older than 2.6.28, ``accept4()`` fails with ``errno`` set to
|
||||
``ENOSYS``.
|
||||
|
@ -468,23 +468,23 @@ Non-inheritable File Descriptors
|
|||
The following functions are modified to make newly created file
|
||||
descriptors non-inheritable by default:
|
||||
|
||||
* ``asyncore.dispatcher.create_socket()``
|
||||
* ``io.FileIO``
|
||||
* ``io.open()``
|
||||
* ``open()``
|
||||
* ``os.dup()``
|
||||
* ``os.fdopen()``
|
||||
* ``os.open()``
|
||||
* ``os.openpty()``
|
||||
* ``os.pipe()``
|
||||
* ``select.devpoll()``
|
||||
* ``select.epoll()``
|
||||
* ``select.kqueue()``
|
||||
* ``socket.socket()``
|
||||
* ``socket.socket.accept()``
|
||||
* ``socket.socket.dup()``
|
||||
* ``socket.socket.fromfd()``
|
||||
* ``socket.socketpair()``
|
||||
* ``asyncore.dispatcher.create_socket()``
|
||||
* ``io.FileIO``
|
||||
* ``io.open()``
|
||||
* ``open()``
|
||||
* ``os.dup()``
|
||||
* ``os.fdopen()``
|
||||
* ``os.open()``
|
||||
* ``os.openpty()``
|
||||
* ``os.pipe()``
|
||||
* ``select.devpoll()``
|
||||
* ``select.epoll()``
|
||||
* ``select.kqueue()``
|
||||
* ``socket.socket()``
|
||||
* ``socket.socket.accept()``
|
||||
* ``socket.socket.dup()``
|
||||
* ``socket.socket.fromfd()``
|
||||
* ``socket.socketpair()``
|
||||
|
||||
``os.dup2()`` still creates inheritable by default, see below.
|
||||
|
||||
|
|
72
pep-0457.txt
72
pep-0457.txt
|
@ -62,14 +62,14 @@ arguments by name::
|
|||
In addition, there are some functions with particularly
|
||||
interesting semantics:
|
||||
|
||||
* ``range()``, which accepts an optional parameter
|
||||
to the *left* of its required parameter. [#RANGE]_
|
||||
* ``range()``, which accepts an optional parameter
|
||||
to the *left* of its required parameter. [#RANGE]_
|
||||
|
||||
* ``dict()``, whose mapping/iterator parameter is optional and
|
||||
semantically must be positional-only. Any externally
|
||||
visible name for this parameter would occlude
|
||||
that name going into the ``**kwarg`` keyword variadic
|
||||
parameter dict! [#DICT]_
|
||||
* ``dict()``, whose mapping/iterator parameter is optional and
|
||||
semantically must be positional-only. Any externally
|
||||
visible name for this parameter would occlude
|
||||
that name going into the ``**kwarg`` keyword variadic
|
||||
parameter dict! [#DICT]_
|
||||
|
||||
Obviously one can simulate any of these in pure Python code
|
||||
by accepting ``(*args, **kwargs)`` and parsing the arguments
|
||||
|
@ -85,17 +85,17 @@ This PEP does not propose we implement positional-only
|
|||
parameters in Python. The goal of this PEP is simply
|
||||
to define the syntax, so that:
|
||||
|
||||
* Documentation can clearly, unambiguously, and
|
||||
consistently express exactly how the arguments
|
||||
for a function will be interpreted.
|
||||
* Documentation can clearly, unambiguously, and
|
||||
consistently express exactly how the arguments
|
||||
for a function will be interpreted.
|
||||
|
||||
* The syntax is reserved for future use, in case
|
||||
the community decides someday to add positional-only
|
||||
parameters to the language.
|
||||
* The syntax is reserved for future use, in case
|
||||
the community decides someday to add positional-only
|
||||
parameters to the language.
|
||||
|
||||
* Argument Clinic can use a variant of the syntax
|
||||
as part of its input when defining
|
||||
the arguments for built-in functions.
|
||||
* Argument Clinic can use a variant of the syntax
|
||||
as part of its input when defining
|
||||
the arguments for built-in functions.
|
||||
|
||||
=================================================================
|
||||
The Current State Of Documentation For Positional-Only Parameters
|
||||
|
@ -179,28 +179,28 @@ in the following way:
|
|||
|
||||
More semantics of positional-only parameters:
|
||||
|
||||
* Although positional-only parameter technically have names,
|
||||
these names are internal-only; positional-only parameters
|
||||
are *never* externally addressable by name. (Similarly
|
||||
to ``*args`` and ``**kwargs``.)
|
||||
* Although positional-only parameter technically have names,
|
||||
these names are internal-only; positional-only parameters
|
||||
are *never* externally addressable by name. (Similarly
|
||||
to ``*args`` and ``**kwargs``.)
|
||||
|
||||
* It's possible to nest option groups.
|
||||
* It's possible to nest option groups.
|
||||
|
||||
* If there are no required parameters, all option groups behave
|
||||
as if they're to the right of the required parameter group.
|
||||
* If there are no required parameters, all option groups behave
|
||||
as if they're to the right of the required parameter group.
|
||||
|
||||
* For clarity and consistency, the comma for a parameter always
|
||||
comes immediately after the parameter name. It's a syntax error
|
||||
to specify a square bracket between the name of a parameter and
|
||||
the following comma. (This is far more readable than putting
|
||||
the comma outside the square bracket, particularly for nested
|
||||
groups.)
|
||||
* For clarity and consistency, the comma for a parameter always
|
||||
comes immediately after the parameter name. It's a syntax error
|
||||
to specify a square bracket between the name of a parameter and
|
||||
the following comma. (This is far more readable than putting
|
||||
the comma outside the square bracket, particularly for nested
|
||||
groups.)
|
||||
|
||||
* If there are arguments after the ``/``, then you must specify
|
||||
a comma after the ``/``, just as there is a comma
|
||||
after the ``*`` denoting the shift to keyword-only parameters.
|
||||
* If there are arguments after the ``/``, then you must specify
|
||||
a comma after the ``/``, just as there is a comma
|
||||
after the ``*`` denoting the shift to keyword-only parameters.
|
||||
|
||||
* This syntax has no effect on ``*args`` or ``**kwargs``.
|
||||
* This syntax has no effect on ``*args`` or ``**kwargs``.
|
||||
|
||||
It's possible to specify a function prototype where the mapping
|
||||
of arguments to parameters is ambiguous. Consider::
|
||||
|
@ -273,9 +273,9 @@ Unresolved Questions
|
|||
|
||||
There are three types of parameters in Python:
|
||||
|
||||
1. positional-only parameters,
|
||||
2. positional-or-keyword parameters, and
|
||||
3. keyword-only parameters.
|
||||
1. positional-only parameters,
|
||||
2. positional-or-keyword parameters, and
|
||||
3. keyword-only parameters.
|
||||
|
||||
Python allows functions to have both 2 and 3. And some
|
||||
builtins (e.g. range) have both 1 and 3. Does it make
|
||||
|
|
36
pep-0461.txt
36
pep-0461.txt
|
@ -95,22 +95,22 @@ Examples::
|
|||
``%b`` will insert a series of bytes. These bytes are collected in one of two
|
||||
ways::
|
||||
|
||||
- input type supports ``Py_buffer`` [4]_?
|
||||
use it to collect the necessary bytes
|
||||
- input type supports ``Py_buffer`` [4]_?
|
||||
use it to collect the necessary bytes
|
||||
|
||||
- input type is something else?
|
||||
use its ``__bytes__`` method [5]_ ; if there isn't one, raise a ``TypeError``
|
||||
- input type is something else?
|
||||
use its ``__bytes__`` method [5]_ ; if there isn't one, raise a ``TypeError``
|
||||
|
||||
In particular, ``%b`` will not accept numbers nor ``str``. ``str`` is rejected
|
||||
as the string to bytes conversion requires an encoding, and we are refusing to
|
||||
guess; numbers are rejected because:
|
||||
|
||||
- what makes a number is fuzzy (float? Decimal? Fraction? some user type?)
|
||||
- what makes a number is fuzzy (float? Decimal? Fraction? some user type?)
|
||||
|
||||
- allowing numbers would lead to ambiguity between numbers and textual
|
||||
representations of numbers (3.14 vs '3.14')
|
||||
- allowing numbers would lead to ambiguity between numbers and textual
|
||||
representations of numbers (3.14 vs '3.14')
|
||||
|
||||
- given the nature of wire formats, explicit is definitely better than implicit
|
||||
- given the nature of wire formats, explicit is definitely better than implicit
|
||||
|
||||
``%s`` is included as a synonym for ``%b`` for the sole purpose of making 2/3 code
|
||||
bases easier to maintain. Python 3 only code should use ``%b``.
|
||||
|
@ -177,15 +177,15 @@ Proposed variations
|
|||
It has been proposed to automatically use ``.encode('ascii','strict')`` for
|
||||
``str`` arguments to ``%b``.
|
||||
|
||||
- Rejected as this would lead to intermittent failures. Better to have the
|
||||
operation always fail so the trouble-spot can be correctly fixed.
|
||||
- Rejected as this would lead to intermittent failures. Better to have the
|
||||
operation always fail so the trouble-spot can be correctly fixed.
|
||||
|
||||
It has been proposed to have ``%b`` return the ascii-encoded repr when the
|
||||
value is a ``str`` (b'%b' % 'abc' --> b"'abc'").
|
||||
|
||||
- Rejected as this would lead to hard to debug failures far from the problem
|
||||
site. Better to have the operation always fail so the trouble-spot can be
|
||||
easily fixed.
|
||||
- Rejected as this would lead to hard to debug failures far from the problem
|
||||
site. Better to have the operation always fail so the trouble-spot can be
|
||||
easily fixed.
|
||||
|
||||
Originally this PEP also proposed adding format-style formatting, but it was
|
||||
decided that format and its related machinery were all strictly text (aka
|
||||
|
@ -204,12 +204,12 @@ Objections
|
|||
|
||||
The objections raised against this PEP were mainly variations on two themes:
|
||||
|
||||
- the ``bytes`` and ``bytearray`` types are for pure binary data, with no
|
||||
assumptions about encodings
|
||||
- the ``bytes`` and ``bytearray`` types are for pure binary data, with no
|
||||
assumptions about encodings
|
||||
|
||||
- offering %-interpolation that assumes an ASCII encoding will be an
|
||||
attractive nuisance and lead us back to the problems of the Python 2
|
||||
``str``/``unicode`` text model
|
||||
- offering %-interpolation that assumes an ASCII encoding will be an
|
||||
attractive nuisance and lead us back to the problems of the Python 2
|
||||
``str``/``unicode`` text model
|
||||
|
||||
As was seen during the discussion, ``bytes`` and ``bytearray`` are also used
|
||||
for mixed binary data and ASCII-compatible segments: file formats such as
|
||||
|
|
12
pep-0472.txt
12
pep-0472.txt
|
@ -136,12 +136,12 @@ When an indexing operation is performed, ``__getitem__(self, idx)`` is called.
|
|||
Traditionally, the full content between square brackets is turned into a single
|
||||
object passed to argument ``idx``:
|
||||
|
||||
- When a single element is passed, e.g. ``a[2]``, ``idx`` will be ``2``.
|
||||
- When multiple elements are passed, they must be separated by commas: ``a[2, 3]``.
|
||||
In this case, ``idx`` will be a tuple ``(2, 3)``. With ``a[2, 3, "hello", {}]``
|
||||
``idx`` will be ``(2, 3, "hello", {})``.
|
||||
- A slicing notation e.g. ``a[2:10]`` will produce a slice object, or a tuple
|
||||
containing slice objects if multiple values were passed.
|
||||
- When a single element is passed, e.g. ``a[2]``, ``idx`` will be ``2``.
|
||||
- When multiple elements are passed, they must be separated by commas: ``a[2, 3]``.
|
||||
In this case, ``idx`` will be a tuple ``(2, 3)``. With ``a[2, 3, "hello", {}]``
|
||||
``idx`` will be ``(2, 3, "hello", {})``.
|
||||
- A slicing notation e.g. ``a[2:10]`` will produce a slice object, or a tuple
|
||||
containing slice objects if multiple values were passed.
|
||||
|
||||
Except for its unique ability to handle slice notation, the indexing operation
|
||||
has similarities to a plain method call: it acts like one when invoked with
|
||||
|
|
12
pep-0488.txt
12
pep-0488.txt
|
@ -37,9 +37,9 @@ generated -- namely no optimizations beyond the peepholer -- the same
|
|||
is not true for PYO files. To put this in terms of optimization
|
||||
levels and the file extension:
|
||||
|
||||
- 0: ``.pyc``
|
||||
- 1 (``-O``): ``.pyo``
|
||||
- 2 (``-OO``): ``.pyo``
|
||||
- 0: ``.pyc``
|
||||
- 1 (``-O``): ``.pyo``
|
||||
- 2 (``-OO``): ``.pyo``
|
||||
|
||||
The reuse of the ``.pyo`` file extension for both level 1 and 2
|
||||
optimizations means that there is no clear way to tell what
|
||||
|
@ -85,9 +85,9 @@ will be specified in the file name). For example, a source file named
|
|||
based on the interpreter's optimization level (none, ``-O``, and
|
||||
``-OO``):
|
||||
|
||||
- 0: ``foo.cpython-35.pyc`` (i.e., no change)
|
||||
- 1: ``foo.cpython-35.opt-1.pyc``
|
||||
- 2: ``foo.cpython-35.opt-2.pyc``
|
||||
- 0: ``foo.cpython-35.pyc`` (i.e., no change)
|
||||
- 1: ``foo.cpython-35.opt-1.pyc``
|
||||
- 2: ``foo.cpython-35.opt-2.pyc``
|
||||
|
||||
Currently bytecode file names are created by
|
||||
``importlib.util.cache_from_source()``, approximately using the
|
||||
|
|
|
@ -465,9 +465,9 @@ python-ideas discussion
|
|||
|
||||
Most of the discussions on python-ideas [#]_ focused on three issues:
|
||||
|
||||
- How to denote f-strings,
|
||||
- How to specify the location of expressions in f-strings, and
|
||||
- Whether to allow full Python expressions.
|
||||
- How to denote f-strings,
|
||||
- How to specify the location of expressions in f-strings, and
|
||||
- Whether to allow full Python expressions.
|
||||
|
||||
How to denote f-strings
|
||||
***********************
|
||||
|
|
12
pep-0628.txt
12
pep-0628.txt
|
@ -72,12 +72,12 @@ when conceived in terms of ``tau`` rather than ``pi``. If you don't find my
|
|||
specific examples sufficiently persausive, here are some more resources that
|
||||
may be of interest:
|
||||
|
||||
* Michael Hartl is the primary instigator of Tau Day in his `Tau Manifesto`_
|
||||
* Bob Palais, the author of the original mathematics journal article
|
||||
highlighting the problems with ``pi`` has `a page of resources`_ on the
|
||||
topic
|
||||
* For those that prefer videos to written text, `Pi is wrong!`_ and
|
||||
`Pi is (still) wrong`_ are available on YouTube
|
||||
* Michael Hartl is the primary instigator of Tau Day in his `Tau Manifesto`_
|
||||
* Bob Palais, the author of the original mathematics journal article
|
||||
highlighting the problems with ``pi`` has `a page of resources`_ on the
|
||||
topic
|
||||
* For those that prefer videos to written text, `Pi is wrong!`_ and
|
||||
`Pi is (still) wrong`_ are available on YouTube
|
||||
|
||||
.. _Tau Manifesto: http://tauday.com/
|
||||
.. _Pi is (still) wrong: http://www.youtube.com/watch?v=jG7vhMMXagQ
|
||||
|
|
Loading…
Reference in New Issue