New submission from Jim Jewett <jimjjewett(a)gmail.com>:
> http://hg.python.org/cpython/rev/0b5ce36a7a24
> changeset: 74515:0b5ce36a7a24
> + Casefolding is similar to lowercasing but more aggressive because it is
> + intended to remove all case distinctions in a string. For example, the German
> + lowercase letter ``'ß'`` is equivalent to ``"ss"``. Since it is already
> + lowercase, :meth:`lower` would do nothing to ``'ß'``; :meth:`casefold`
> + converts it to ``"ss"``.
Perhaps add the recommendation to canonicalize as well.
A complete, but possibly too long, try is below:
Casefolding is similar to lowercasing but more aggressive because it is intended to remove all case distinctions in a string. For example, the German lowercase letter ``'ß'`` is equivalent to ``"ss"``. Since it is already lowercase, :meth:`lower` would do nothing to ``'ß'``; :meth:`casefold` converts it to ``"ss"``. Note that most case-insensitive matches should also match compatibility equivalent characters.
The casefolding algorithm is described in section 3.13 of the Unicode Standard. Per D146, a compatibility caseless match can be achieved by
from unicodedata import normalize
def caseless_compat(string):
nfd_string = normalize("NFD", string)
nfkd1_string = normalize("NFKD", nfd_string.casefold())
return normalize("NFKD", nfkd1_string.casefold())
----------
assignee: docs@python
components: Documentation
messages: 151644
nosy: Jim.Jewett, benjamin.peterson, docs@python
priority: normal
severity: normal
status: open
title: Further improve casefold documentation
versions: Python 3.3
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue13828>
_______________________________________
New submission from Stefan Schwarzer:
I recently was confused whether to raise a `PicklingError` or `TypeError` in `__getstate__` if objects of my class can't and shouldn't be pickled. [1]
Terry Reedy advised I should use `TypeError`. [2]
I wonder if the `pickle` module documention should explicitly recommend using `TypeError` if a class wants to say that its objects can't be pickled. What do you think?
[1] https://mail.python.org/pipermail/python-list/2014-April/670987.html
[2] https://mail.python.org/pipermail/python-list/2014-April/671002.html
----------
assignee: docs@python
components: Documentation
messages: 217054
nosy: docs@python, sschwarzer
priority: normal
severity: normal
status: open
title: Document recommended exception for objects that shouldn't be pickled
type: enhancement
versions: Python 3.5
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue21333>
_______________________________________
New submission from Takafumi Arakaki:
Document mentions AsyncResult but there is no such class.
http://docs.python.org/2/library/multiprocessing.html#multiprocessing.pool.…
You can check it by simply running:
python -c 'from multiprocessing.pool import AsyncResult'
I think it means ApplyResult so I made a patch (attached).
Note that there managers.py also uses name 'AsyncResult':
% hg grep AsyncResult
Doc/library/multiprocessing.rst:83232:.. class:: AsyncResult
Lib/multiprocessing/managers.py:81039: 'apply_async': 'AsyncResult',
Lib/multiprocessing/managers.py:81039: 'map_async': 'AsyncResult',
Lib/multiprocessing/managers.py:81039: 'starmap_async': 'AsyncResult',
Lib/multiprocessing/managers.py:81039:SyncManager.register('AsyncResult', create_method=False)
Probably renaming them would be better?
----------
assignee: docs@python
components: Documentation
files: ApplyResult.patch
keywords: patch
messages: 187466
nosy: docs@python, tkf
priority: normal
severity: normal
status: open
title: No such class: multiprocessing.pool.AsyncResult
versions: Python 2.6, Python 2.7, Python 3.1, Python 3.2, Python 3.3, Python 3.4, Python 3.5
Added file: http://bugs.python.org/file29954/ApplyResult.patch
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue17805>
_______________________________________
New submission from Larry Hastings:
CPython API "functions" implemented as macros can expand into either
rvalues or statements. Most expand into statements (often using the
do {} while (0) syntactic sugar trick), but occasionally they're legal
as rvalues.
As of this writing Py_INCREF works as an rvalue. But discussion on
another tracker issue (#17206) proposes changing the implementation
in such a way that it will only be usable as a statement. Although
it's mildly unlikely, it's certainly possible that this will break
somebody's code.
I propose that the documentation make an explicit ruling on whether
macros are usable as rvalues or as statements. Perhaps a blanket
statement would suffice, "all macros are only supported for use as
statements except where explicitly noted", then annotate specific
macros that are supported for use as rvalues. Though that raises the
question of acknowledging in the documentation that some things are
macros--I think the documentation glosses over that fact right now.
Note: I added you three (Georg, Mark, Martin) as I thought you might
have an opinion on this one way or the other. If you're not interested,
my apologies.
----------
assignee: docs@python
components: Documentation
messages: 185646
nosy: Mark.Shannon, docs@python, georg.brandl, larry, loewis
priority: normal
severity: normal
stage: needs patch
status: open
title: Make documentation about macros in C API explicit about rvalue vs statement
type: enhancement
versions: Python 3.4
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue17589>
_______________________________________
New submission from Steve:
PyArg_ParseTuple is defined as returning an "int", but the documentation talks about returning a true/false value, and failling on false. In addition to being inaccurate, considering that most other functions fail on !=0 ("true"), it can lead to confusion.
Doc:
int PyArg_ParseTuple(PyObject *args, const char *format, ...)
Parse the parameters of a function that takes only positional parameters into local variables. Returns true on success; on failure, it returns false and raises the appropriate exception.
----------
assignee: docs@python
components: Documentation
messages: 218536
nosy: Banger, docs@python
priority: normal
severity: normal
status: open
title: C API PyArg_ParseTuple doc is innacurate
type: enhancement
versions: Python 3.3, Python 3.4, Python 3.5
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue21508>
_______________________________________
New submission from Nick Coghlan:
The main C API docs don't clearly explain how to define new types, so people almost always cargo cult an existing legacy type definition instead (I know I do).
The extending and embedding docs have a guide (http://docs.python.org/3/extending/newtypes.html), but that describes the old legacy method based on static type declarations. New code should instead use the dynamic mechanism defined in PEP 384 (http://www.python.org/dev/peps/pep-0384/#type-objects).
See also http://docs.python.org/3/c-api/type.html#PyType_FromSpec
Note that PyType_Spec isn't defined in the C API docs *at all*.
----------
assignee: docs@python
components: Documentation
messages: 207927
nosy: docs@python, ncoghlan
priority: normal
severity: normal
stage: needs patch
status: open
title: C API docs need a clear "defining custom extension types" section
type: enhancement
versions: Python 3.3, Python 3.4, Python 3.5
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue20224>
_______________________________________
New submission from Nick Coghlan:
The sys.argv docs [1] currently contain no mention of the fact that they are Unicode strings decoded from bytes provided by the OS. They also don't explain how to correct a decoding error by reversing Python's implicit conversion and redoing it based on the application's knowledge of the correct encoding, as described at [2]
[1] http://docs.python.org/3/library/sys#sys.argv
[2] http://stackoverflow.com/questions/6981594/sys-argv-as-bytes-in-python-3k/
----------
assignee: docs@python
components: Documentation, Unicode
messages: 181239
nosy: docs@python, ezio.melotti, ncoghlan
priority: normal
severity: normal
stage: needs patch
status: open
title: sys.argv docs should explaining how to handle encoding issues
type: enhancement
versions: Python 3.2, Python 3.3, Python 3.4
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue17110>
_______________________________________
New submission from Dmitry Mugtasimov:
http://docs.python.org/2/tutorial/modules.html should be rewritten.
AS IS
6.1.2. The Module Search Path
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
TO BE
6.1.2. The Module Search Path
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it looks in the containing package (the package of which the current module is a submodule). If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
------
Note that now "6.1.2. The Module Search Path" and "6.4.2. Intra-package References" are contradictary since in 6.4.2 it is said: "In fact, such references are so common that the import statement first looks in the containing package before looking in the standard module search path.", but this is not reflected in 6.1.2.
------
EXAMPLE (for more information see http://stackoverflow.com/questions/14183541/why-python-finds-module-instead… ):
/home/dmugtasimov/tmp/name-res3/xyz
__init__.py
a.py
b.py
t.py
xyz.py
Files init.py, b.py and xyz.py are empty
File a.py:
import os, sys
ROOT_DIRECTORY = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
if not sys.path or ROOT_DIRECTORY not in sys.path:
print 'sys.path is modified in a.py'
sys.path.insert(0, ROOT_DIRECTORY)
else:
print 'sys.path is NOT modified in a.py'
print 'sys.path:', sys.path
print 'BEFORE import xyz.b'
import xyz.b
print 'AFTER import xyz.b'
File t.py:
import os, sys
ROOT_DIRECTORY = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
if not sys.path or ROOT_DIRECTORY not in sys.path:
print 'sys.path is modified in t.py'
sys.path.insert(0, ROOT_DIRECTORY)
else:
print 'sys.path is NOT modified in t.py'
import xyz.a
Run:
python a.py
Output:
sys.path is modified in a.py
sys.path: ['/home/dmugtasimov/tmp/name-res3', '/home/dmugtasimov/tmp/name-res3/xyz',
'/usr/local/lib/python2.7/dist-packages/tornado-2.3-py2.7.egg',
'/home/dmugtasimov/tmp/name-res3/xyz', '/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages',
'/usr/local/lib/python2.7/dist-packages/setuptools-0.6c11-py2.7.egg-info',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/PIL',
'/usr/lib/python2.7/dist-packages/gst-0.10',
'/usr/lib/python2.7/dist-packages/gtk-2.0',
'/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
BEFORE import xyz.b
AFTER import xyz.b
Run:
python -vv a.py
Output:
import xyz # directory /home/dmugtasimov/tmp/name-res3/xyz
# trying /home/dmugtasimov/tmp/name-res3/xyz/__init__.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/__init__module.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/__init__.py
# /home/dmugtasimov/tmp/name-res3/xyz/__init__.pyc matches /home/dmugtasimov/tmp/name-res3/xyz/__init__.py
import xyz # precompiled from /home/dmugtasimov/tmp/name-res3/xyz/__init__.pyc
# trying /home/dmugtasimov/tmp/name-res3/xyz/b.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/bmodule.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/b.py
# /home/dmugtasimov/tmp/name-res3/xyz/b.pyc matches /home/dmugtasimov/tmp/name-res3/xyz/b.py
import xyz.b # precompiled from /home/dmugtasimov/tmp/name-res3/xyz/b.pyc
Run:
python t.py
Output:
sys.path is modified in t.py
sys.path is NOT modified in a.py
sys.path: ['/home/dmugtasimov/tmp/name-res3', '/home/dmugtasimov/tmp/name-res3/xyz',
'/usr/local/lib/python2.7/dist-packages/tornado-2.3-py2.7.egg',
'/home/dmugtasimov/tmp/name-res3/xyz', '/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages',
'/usr/local/lib/python2.7/dist-packages/setuptools-0.6c11-py2.7.egg-info',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/PIL',
'/usr/lib/python2.7/dist-packages/gst-0.10',
'/usr/lib/python2.7/dist-packages/gtk-2.0',
'/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
BEFORE import xyz.b
Traceback (most recent call last):
File "t.py", line 9, in <module>
import xyz.a
File "/home/dmugtasimov/tmp/name-res3/xyz/a.py", line 11, in <module>
import xyz.b
ImportError: No module named b
Run:
python -vv t.py
Output:
import xyz # directory /home/dmugtasimov/tmp/name-res3/xyz
# trying /home/dmugtasimov/tmp/name-res3/xyz/__init__.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/__init__module.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/__init__.py
# /home/dmugtasimov/tmp/name-res3/xyz/__init__.pyc matches /home/dmugtasimov/tmp/name-res3/xyz/__init__.py
import xyz # precompiled from /home/dmugtasimov/tmp/name-res3/xyz/__init__.pyc
# trying /home/dmugtasimov/tmp/name-res3/xyz/a.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/amodule.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/a.py
# /home/dmugtasimov/tmp/name-res3/xyz/a.pyc matches /home/dmugtasimov/tmp/name-res3/xyz/a.py
import xyz.a # precompiled from /home/dmugtasimov/tmp/name-res3/xyz/a.pyc
# trying /home/dmugtasimov/tmp/name-res3/xyz/os.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/osmodule.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/os.py
# trying /home/dmugtasimov/tmp/name-res3/xyz/os.pyc
# trying /home/dmugtasimov/tmp/name-res3/xyz/sys.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/sysmodule.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/sys.py
# trying /home/dmugtasimov/tmp/name-res3/xyz/sys.pyc
# trying /home/dmugtasimov/tmp/name-res3/xyz/xyz.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/xyzmodule.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/xyz.py
# /home/dmugtasimov/tmp/name-res3/xyz/xyz.pyc matches /home/dmugtasimov/tmp/name-res3/xyz/xyz.py
import xyz.xyz # precompiled from /home/dmugtasimov/tmp/name-res3/xyz/xyz.pyc
# clear[2] __file__
# clear[2] __package__
# clear[2] sys
# clear[2] ROOT_DIRECTORY
# clear[2] __name__
# clear[2] os
sys.path is modified in t.py
sys.path is NOT modified in a.py
sys.path: ['/home/dmugtasimov/tmp/name-res3', '/home/dmugtasimov/tmp/name-res3/xyz',
'/usr/local/lib/python2.7/dist-packages/tornado-2.3-py2.7.egg',
'/home/dmugtasimov/tmp/name-res3/xyz', '/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages',
'/usr/local/lib/python2.7/dist-packages/setuptools-0.6c11-py2.7.egg-info',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/PIL',
'/usr/lib/python2.7/dist-packages/gst-0.10',
'/usr/lib/python2.7/dist-packages/gtk-2.0',
'/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
BEFORE import xyz.b
Traceback (most recent call last):
File "t.py", line 9, in <module>
import xyz.a
File "/home/dmugtasimov/tmp/name-res3/xyz/a.py", line 11, in <module>
import xyz.b
ImportError: No module named b
As you see sys.path is the same for both cases:
sys.path: ['/home/dmugtasimov/tmp/name-res3', '/home/dmugtasimov/tmp/name-res3/xyz', '/usr/local/lib/python2.7/dist-packages/tornado-2.3-py2.7.egg', '/home/dmugtasimov/tmp/name-res3/xyz', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/local/lib/python2.7/dist-packages/setuptools-0.6c11-py2.7.egg-info', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
But the behaviour is different. For a.py python searches for package xyz first, and them for module b in it:
import xyz # directory /home/dmugtasimov/tmp/name-res3/xyz
# trying /home/dmugtasimov/tmp/name-res3/xyz/__init__.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/__init__module.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/__init__.py
# /home/dmugtasimov/tmp/name-res3/xyz/__init__.pyc matches /home/dmugtasimov/tmp/name-res3/xyz/__init__.py
import xyz # precompiled from /home/dmugtasimov/tmp/name-res3/xyz/__init__.pyc
# trying /home/dmugtasimov/tmp/name-res3/xyz/b.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/bmodule.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/b.py
# /home/dmugtasimov/tmp/name-res3/xyz/b.pyc matches /home/dmugtasimov/tmp/name-res3/xyz/b.py
import xyz.b # precompiled from /home/dmugtasimov/tmp/name-res3/xyz/b.pyc
In other words:
Search PACKAGE xyz in directory sys.path[0] -> FOUND
Search module b in PACKAGE xyz -> FOUND
Continue execution
For t.py it searches for moduel xyz in the same directory as a.py itself and then fails to find module b in module xyz:
# trying /home/dmugtasimov/tmp/name-res3/xyz/xyz.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/xyzmodule.so
# trying /home/dmugtasimov/tmp/name-res3/xyz/xyz.py
# /home/dmugtasimov/tmp/name-res3/xyz/xyz.pyc matches /home/dmugtasimov/tmp/name-res3/xyz/xyz.py
import xyz.xyz # precompiled from /home/dmugtasimov/tmp/name-res3/xyz/xyz.pyc
In other words:
Search MODULE xyz in directory in the same directory as a.py (or sys.path[1] ?) -> FOUND
Search MODULE b in MODULE xyz -> NOT FOUND
ImportError
So it looks like if "import xyz.b" bahaves different depending on how a.py was initially loaded as a script or imported from another module.
----------
assignee: docs@python
components: Documentation
messages: 179321
nosy: dmugtasimov, docs@python
priority: normal
severity: normal
status: open
title: Fix docs about module search order
type: behavior
versions: Python 2.7
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue16891>
_______________________________________
New submission from anatoly techtonik <techtonik(a)gmail.com>:
http://docs.python.org/library/termios.html is missing documentation for ICANON flag used to put terminal to "raw" mode.
It is also worth to place `termios` raw/canonical mode equivalent on `tty` pages, so that people porting C code to Python could understand the hidden magic.
----------
assignee: docs@python
components: Documentation, IO, Library (Lib)
messages: 150098
nosy: docs@python, techtonik
priority: normal
severity: normal
status: open
title: termios.ICANON is not documented
versions: Python 2.7
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue13649>
_______________________________________
New submission from Serhiy Storchaka:
Some OS functions which returns bytes (os.environb, os.getenvb(), os.getcwdb(), os.listdir(), os.readlink(), os.walk(), os.path.abspath(), os.path.expanduser(), os.path.expandvars(), os.path.realpath() and may be other) can return unusable result on Windows (see for example issue13247 and issue16656). The documentation should contains strong warnings about this.
----------
assignee: docs@python
components: Documentation, Windows
messages: 177613
nosy: docs@python, serhiy.storchaka
priority: normal
severity: normal
stage: needs patch
status: open
title: Document that bytes OS API can returns unusable results on Windows
type: enhancement
versions: Python 2.7, Python 3.2, Python 3.3, Python 3.4
_______________________________________
Python tracker <report(a)bugs.python.org>
<http://bugs.python.org/issue16700>
_______________________________________